This is in preparation for GOST MAC support. GOST MAC takes a 256 bit key
and produces a 32 bit signature. Hence there needs to be an API for
querying the key length as well.

Signed-off-by: Heiko Hund <heiko.h...@sophos.com>
---
 src/openvpn/crypto.c          |   45 +++++++++++++++++++++--------------------
 src/openvpn/crypto.h          |    1 +
 src/openvpn/crypto_backend.h  |    9 +++++++++
 src/openvpn/crypto_openssl.c  |    7 +++++++
 src/openvpn/crypto_polarssl.c |    8 ++++++++
 src/openvpn/openvpn.h         |    2 +-
 6 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index 7fdbb95..f86c83a 100644
--- a/src/openvpn/crypto.c
+++ b/src/openvpn/crypto.c
@@ -430,6 +430,7 @@ init_key_type (struct key_type *kt, const char *ciphername,
     {
       kt->digest = md_kt_get (authname);
       kt->hmac_length = md_kt_size (kt->digest);
+      kt->hmac_key_length = hmac_key_size (kt->digest);
     }
   else
     {
@@ -465,17 +466,17 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
           cipher_kt_block_size(kt->cipher),
           cipher_kt_iv_size(kt->cipher));
     }
-  if (kt->digest && kt->hmac_length > 0)
+  if (kt->digest && kt->hmac_key_length > 0)
     {
       ALLOC_OBJ(ctx->hmac, hmac_ctx_t);
-      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest);
+      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_key_length, kt->digest);

       msg (D_HANDSHAKE,
       "%s: Using %d bit message hash '%s' for HMAC authentication",
       prefix, md_kt_size(kt->digest) * 8, md_kt_name(kt->digest));

       dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
-         format_hex (key->hmac, kt->hmac_length, 0, &gc));
+         format_hex (key->hmac, kt->hmac_key_length, 0, &gc));

       dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
        prefix,
@@ -610,7 +611,7 @@ void
 generate_key_random (struct key *key, const struct key_type *kt)
 {
   int cipher_len = MAX_CIPHER_KEY_LENGTH;
-  int hmac_len = MAX_HMAC_KEY_LENGTH;
+  int hmac_key_len = MAX_HMAC_KEY_LENGTH;

   struct gc_arena gc = gc_new ();

@@ -621,15 +622,15 @@ generate_key_random (struct key *key, const struct 
key_type *kt)
        if (kt->cipher && kt->cipher_length > 0 && kt->cipher_length <= 
cipher_len)
          cipher_len = kt->cipher_length;

-       if (kt->digest && kt->hmac_length > 0 && kt->hmac_length <= hmac_len)
-         hmac_len = kt->hmac_length;
+       if (kt->digest && kt->hmac_key_length > 0 && kt->hmac_key_length <= 
hmac_key_len)
+         hmac_key_len = kt->hmac_key_length;
       }
     if (!rand_bytes (key->cipher, cipher_len)
-       || !rand_bytes (key->hmac, hmac_len))
+       || !rand_bytes (key->hmac, hmac_key_len))
       msg (M_FATAL, "ERROR: Random number generator cannot obtain entropy for 
key generation");

     dmsg (D_SHOW_KEY_SOURCE, "Cipher source entropy: %s", format_hex 
(key->cipher, cipher_len, 0, &gc));
-    dmsg (D_SHOW_KEY_SOURCE, "HMAC source entropy: %s", format_hex (key->hmac, 
hmac_len, 0, &gc));
+    dmsg (D_SHOW_KEY_SOURCE, "HMAC source entropy: %s", format_hex (key->hmac, 
hmac_key_len, 0, &gc));

     if (kt)
       fixup_key (key, kt);
@@ -654,13 +655,13 @@ key2_print (const struct key2* k,
        format_hex (k->keys[0].cipher, kt->cipher_length, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "%s (hmac): %s",
        prefix0,
-       format_hex (k->keys[0].hmac, kt->hmac_length, 0, &gc));
+       format_hex (k->keys[0].hmac, kt->hmac_key_length, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "%s (cipher): %s",
        prefix1,
        format_hex (k->keys[1].cipher, kt->cipher_length, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "%s (hmac): %s",
        prefix1,
-       format_hex (k->keys[1].hmac, kt->hmac_length, 0, &gc));
+       format_hex (k->keys[1].hmac, kt->hmac_key_length, 0, &gc));
   gc_free (&gc);
 }

@@ -727,7 +728,7 @@ get_tls_handshake_key (const struct key_type *key_type,
                       const int key_direction,
                       const unsigned int flags)
 {
-  if (passphrase_file && key_type->hmac_length)
+  if (passphrase_file && key_type->hmac_key_length)
     {
       struct key2 key2;
       struct key_type kt = *key_type;
@@ -762,16 +763,16 @@ get_tls_handshake_key (const struct key_type *key_type,
          }
        else
          {
-           int hash_size;
+           int hash_key_size;

            CLEAR (key2);

            /* failed, now try to get hash from a freeform file */
-           hash_size = read_passphrase_hash (passphrase_file,
+           hash_key_size = read_passphrase_hash (passphrase_file,
                                              kt.digest,
                                              key2.keys[0].hmac,
                                              MAX_HMAC_KEY_LENGTH);
-           ASSERT (hash_size == kt.hmac_length);
+           ASSERT (hash_key_size == kt.hmac_key_length);

            /* suceeded */
            key2.n = 1;
@@ -1223,15 +1224,15 @@ write_key (const struct key *key, const struct key_type 
*kt,
           struct buffer *buf)
 {
   ASSERT (kt->cipher_length <= MAX_CIPHER_KEY_LENGTH
-         && kt->hmac_length <= MAX_HMAC_KEY_LENGTH);
+         && kt->hmac_key_length <= MAX_HMAC_KEY_LENGTH);

   if (!buf_write (buf, &kt->cipher_length, 1))
     return false;
-  if (!buf_write (buf, &kt->hmac_length, 1))
+  if (!buf_write (buf, &kt->hmac_key_length, 1))
     return false;
   if (!buf_write (buf, key->cipher, kt->cipher_length))
     return false;
-  if (!buf_write (buf, key->hmac, kt->hmac_length))
+  if (!buf_write (buf, key->hmac, kt->hmac_key_length))
     return false;

   return true;
@@ -1247,20 +1248,20 @@ int
 read_key (struct key *key, const struct key_type *kt, struct buffer *buf)
 {
   uint8_t cipher_length;
-  uint8_t hmac_length;
+  uint8_t hmac_key_length;

   CLEAR (*key);
   if (!buf_read (buf, &cipher_length, 1))
     goto read_err;
-  if (!buf_read (buf, &hmac_length, 1))
+  if (!buf_read (buf, &hmac_key_length, 1))
     goto read_err;

   if (!buf_read (buf, key->cipher, cipher_length))
     goto read_err;
-  if (!buf_read (buf, key->hmac, hmac_length))
+  if (!buf_read (buf, key->hmac, hmac_key_length))
     goto read_err;

-  if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length)
+  if (cipher_length != kt->cipher_length || hmac_key_length != 
kt->hmac_key_length)
     goto key_len_err;

   return 1;
@@ -1272,7 +1273,7 @@ read_err:
 key_len_err:
   msg (D_TLS_ERRORS,
        "TLS Error: key length mismatch, local cipher/hmac %d/%d, remote 
cipher/hmac %d/%d",
-       kt->cipher_length, kt->hmac_length, cipher_length, hmac_length);
+       kt->cipher_length, kt->hmac_key_length, cipher_length, hmac_key_length);
   return 0;
 }

diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index 5c34597..6f91b6f 100644
--- a/src/openvpn/crypto.h
+++ b/src/openvpn/crypto.h
@@ -47,6 +47,7 @@ struct key_type
 {
   uint8_t cipher_length;       /**< Cipher length, in bytes */
   uint8_t hmac_length;         /**< HMAC length, in bytes */
+  uint8_t hmac_key_length;      /**< HMAC key length, in bytes */
   const cipher_kt_t *cipher;   /**< Cipher static parameters */
   const md_kt_t *digest;       /**< Message digest static parameters */
 };
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 4b68687..deff011 100644
--- a/src/openvpn/crypto_backend.h
+++ b/src/openvpn/crypto_backend.h
@@ -443,6 +443,15 @@ void md_ctx_final (md_ctx_t *ctx, uint8_t *dst);
  */

 /*
+ * Returns the size of the HMAC key by the given message digest.
+ *
+ * @param ctx           Message digest context. May not be NULL.
+ *
+ * @return              Size of the HMAC key in bytes.
+ */
+int hmac_key_size (const md_kt_t *ctx);
+
+/*
  * Initialises the given HMAC context, using the given digest
  * and key.
  *
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index deaf0ca..5665e29 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -714,6 +714,13 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
  *
  */

+int
+hmac_key_size (const EVP_MD *kt)
+{
+  if (NULL == kt)
+    return 0;
+  return md_kt_size (kt);
+}

 void
 hmac_ctx_init (HMAC_CTX *ctx, const uint8_t *key, int key_len,
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
index 6b1193a..b44ea12 100644
--- a/src/openvpn/crypto_polarssl.c
+++ b/src/openvpn/crypto_polarssl.c
@@ -546,6 +546,14 @@ md_ctx_final (md_context_t *ctx, uint8_t *dst)
 /*
  * TODO: re-enable dmsg for crypto debug
  */
+int
+hmac_key_size (const md_info_t *kt)
+{
+  if (NULL == kt)
+    return 0;
+  return md_get_size (kt);
+}
+
 void
 hmac_ctx_init (md_context_t *ctx, const uint8_t *key, int key_len, const 
md_info_t *kt)
 {
diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h
index 0732d0f..3ff5470 100644
--- a/src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -572,7 +572,7 @@ struct context
 #define PROTO_DUMP(buf, gc) protocol_dump((buf), \
                                      PROTO_DUMP_FLAGS | \
                                      (c->c2.tls_multi ? PD_TLS : 0) | \
-                                     (c->options.tls_auth_file ? 
c->c1.ks.key_type.hmac_length : 0), \
+                                     (c->options.tls_auth_file ? 
c->c1.ks.key_type.hmac_key_length : 0), \
                                      gc)
 #else
 #define TLS_MODE(c) (false)
-- 
1.7.9.5


Reply via email to