]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored HMAC functions
authorAdriaan de Jong <dejong@fox-it.com>
Thu, 23 Jun 2011 15:18:32 +0000 (17:18 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 19 Oct 2011 20:13:25 +0000 (22:13 +0200)
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
crypto.c
crypto_backend.h
crypto_openssl.c
ntlm.c

index 4c16979d89606474df22cd92ff9c08c08ebf69f2..cf1c8be61440f92447e15008d4b01bedfe7ab92b 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -174,15 +174,13 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
       /* HMAC the ciphertext (or plaintext if !cipher) */
       if (ctx->hmac)
        {
-         int hmac_len;
-         uint8_t *output;
+         uint8_t *output = NULL;
 
-         HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL);
-         HMAC_Update (ctx->hmac, BPTR (&work), BLEN (&work));
-         output = buf_prepend (&work, HMAC_size (ctx->hmac));
+         hmac_ctx_reset (ctx->hmac);
+         hmac_ctx_update (ctx->hmac, BPTR(&work), BLEN(&work));
+         output = buf_prepend (&work, hmac_ctx_size(ctx->hmac));
          ASSERT (output);
-         HMAC_Final (ctx->hmac, output, (unsigned int *)&hmac_len);
-         ASSERT (hmac_len == HMAC_size (ctx->hmac));
+         hmac_ctx_final (ctx->hmac, output);
        }
 
       *buf = work;
@@ -226,21 +224,18 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
        {
          int hmac_len;
          uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */
-         int in_hmac_len;
 
-         HMAC_Init_ex (ctx->hmac, NULL, 0, NULL, NULL);
+         hmac_ctx_reset(ctx->hmac);
 
          /* Assume the length of the input HMAC */
-         hmac_len = HMAC_size (ctx->hmac);
+         hmac_len = hmac_ctx_size (ctx->hmac);
 
          /* Authentication fails if insufficient data in packet for HMAC */
          if (buf->len < hmac_len)
            CRYPT_ERROR ("missing authentication info");
 
-         HMAC_Update (ctx->hmac, BPTR (buf) + hmac_len,
-                      BLEN (buf) - hmac_len);
-         HMAC_Final (ctx->hmac, local_hmac, (unsigned int *)&in_hmac_len);
-         ASSERT (hmac_len == in_hmac_len);
+         hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len);
+         hmac_ctx_final (ctx->hmac, local_hmac);
 
          /* Compare locally computed HMAC with packet HMAC */
          if (memcmp (local_hmac, BPTR (buf), hmac_len))
@@ -439,31 +434,6 @@ init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
   gc_free (&gc);
 }
 
-static void
-init_hmac (HMAC_CTX *ctx, const EVP_MD *digest,
-          struct key *key, const struct key_type *kt, const char *prefix)
-{
-  struct gc_arena gc = gc_new ();
-
-  HMAC_CTX_init (ctx);
-  HMAC_Init_ex (ctx, key->hmac, kt->hmac_length, digest, NULL);
-  msg (D_HANDSHAKE,
-       "%s: Using %d bit message hash '%s' for HMAC authentication",
-       prefix, HMAC_size (ctx) * 8, OBJ_nid2sn (EVP_MD_type (digest)));
-
-  /* make sure we used a big enough key */
-  ASSERT (HMAC_size (ctx) <= kt->hmac_length);
-
-  dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
-       format_hex (key->hmac, kt->hmac_length, 0, &gc));
-  dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
-       prefix,
-       EVP_MD_size (digest),
-       EVP_MD_block_size (digest));
-
-  gc_free (&gc);
-}
-
 /*
  * Build a struct key_type.
  */
@@ -547,8 +517,9 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
     }
   if (kt->digest && kt->hmac_length > 0)
     {
-      ALLOC_OBJ (ctx->hmac, HMAC_CTX);
-      init_hmac (ctx->hmac, kt->digest, key, kt, prefix);
+      ALLOC_OBJ(ctx->hmac, hmac_ctx_t);
+      hmac_ctx_init (ctx->hmac, key->hmac, kt->hmac_length, kt->digest,
+         prefix);
     }
 }
 
@@ -563,8 +534,8 @@ free_key_ctx (struct key_ctx *ctx)
     }
   if (ctx->hmac)
     {
-      HMAC_CTX_cleanup (ctx->hmac);
-      free (ctx->hmac);
+      hmac_ctx_cleanup(ctx->hmac);
+      free(ctx->hmac);
       ctx->hmac = NULL;
     }
 }
index b6fd996c2a3d240785751107bf99e69866a1f6f8..ae3e7fbf4681a7eb428555c064a57ae163ffd237 100644 (file)
@@ -264,4 +264,64 @@ void md_ctx_update (md_ctx_t *ctx, const uint8_t *src, int src_len);
 void md_ctx_final (md_ctx_t *ctx, uint8_t *dst);
 
 
+/*
+ *
+ * Generic HMAC functions
+ *
+ */
+
+/*
+ * Initialises the given HMAC context, using the given digest
+ * and key.
+ *
+ * @param ctx          HMAC context to intialise
+ * @param key          The key to use for the HMAC
+ * @param key_len      The key length to use
+ * @param kt           Static message digest parameters
+ * @param prefix       Prefix to use when printing debug information.
+ *
+ */
+void hmac_ctx_init (hmac_ctx_t *ctx, const uint8_t *key, int key_length,
+    const md_kt_t *kt, const char *prefix);
+
+/*
+ * Free the given HMAC context.
+ *
+ * @param ctx          HMAC context
+ */
+void hmac_ctx_cleanup(hmac_ctx_t *ctx);
+
+/*
+ * Returns the size of the HMAC output by the given HMAC Context
+ *
+ * @param ctx          HMAC context.
+ *
+ * @return             Size of the HMAC, or \0 if ctx is NULL.
+ */
+int hmac_ctx_size (const hmac_ctx_t *ctx);
+
+/*
+ * Resets the given HMAC context, preserving the associated key information
+ *
+ * @param ctx          HMAC context. May not be NULL.
+ */
+void hmac_ctx_reset (hmac_ctx_t *ctx);
+
+/*
+ * Process the given data for use in the HMAC.
+ *
+ * @param ctx          HMAC context. May not be NULL.
+ * @param src          The buffer to HMAC. May not be NULL.
+ * @param src_len      The length of the incoming buffer.
+ */
+void hmac_ctx_update (hmac_ctx_t *ctx, const uint8_t *src, int src_len);
+
+/*
+ * Output the HMAC to the given buffer.
+ *
+ * @param ctx          HMAC context. May not be NULL.
+ * @param dst          buffer to write the HMAC to. May not be NULL.
+ */
+void hmac_ctx_final (hmac_ctx_t *ctx, uint8_t *dst);
+
 #endif /* CRYPTO_BACKEND_H_ */
index 12c4392beb01c3c8a3d04f62e49a9677bdc0b72c..55d88db1e2387c33bb1ad338fee3493be4b9a7a3 100644 (file)
@@ -551,3 +551,76 @@ md_ctx_final (EVP_MD_CTX *ctx, uint8_t *dst)
 
   EVP_DigestFinal(ctx, dst, &in_md_len);
 }
+
+
+/*
+ *
+ * Generic HMAC functions
+ *
+ */
+
+
+void
+hmac_ctx_init (HMAC_CTX *ctx, const uint8_t *key, int key_len,
+    const EVP_MD *kt, const char *prefix)
+{
+  struct gc_arena gc = gc_new ();
+
+  ASSERT(NULL != kt && NULL != ctx);
+
+  CLEAR(*ctx);
+
+  HMAC_CTX_init (ctx);
+  HMAC_Init_ex (ctx, key, key_len, kt, NULL);
+
+  if (prefix)
+    msg (D_HANDSHAKE,
+       "%s: Using %d bit message hash '%s' for HMAC authentication",
+       prefix, HMAC_size (ctx) * 8, OBJ_nid2sn (EVP_MD_type (kt)));
+
+  /* make sure we used a big enough key */
+  ASSERT (HMAC_size (ctx) <= key_len);
+
+  if (prefix)
+    dmsg (D_SHOW_KEYS, "%s: HMAC KEY: %s", prefix,
+       format_hex (key, key_len, 0, &gc));
+  if (prefix)
+    dmsg (D_CRYPTO_DEBUG, "%s: HMAC size=%d block_size=%d",
+       prefix,
+       EVP_MD_size (kt),
+       EVP_MD_block_size (kt));
+
+  gc_free (&gc);
+}
+
+void
+hmac_ctx_cleanup(HMAC_CTX *ctx)
+{
+  HMAC_CTX_cleanup (ctx);
+}
+
+int
+hmac_ctx_size (const HMAC_CTX *ctx)
+{
+  return HMAC_size (ctx);
+}
+
+void
+hmac_ctx_reset (HMAC_CTX *ctx)
+{
+  HMAC_Init_ex (ctx, NULL, 0, NULL, NULL);
+}
+
+void
+hmac_ctx_update (HMAC_CTX *ctx, const uint8_t *src, int src_len)
+{
+  HMAC_Update (ctx, src, src_len);
+}
+
+void
+hmac_ctx_final (HMAC_CTX *ctx, uint8_t *dst)
+{
+  unsigned int in_hmac_len = 0;
+
+  HMAC_Final (ctx, dst, &in_hmac_len);
+}
diff --git a/ntlm.c b/ntlm.c
index 512c26fbb8e832432ac4066a111274fdd0cba733..30d5d117198b73d4940e5c1139b469e7826ed458 100644 (file)
--- a/ntlm.c
+++ b/ntlm.c
@@ -80,13 +80,14 @@ gen_md4_hash (const char* data, int data_len, char *result)
 static void
 gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result)
 {
-       unsigned int len;
-
-       HMAC_CTX c;
-       HMAC_Init (&c, key, key_len, EVP_md5());
-       HMAC_Update (&c, (const unsigned char *)data, data_len);
-       HMAC_Final (&c, (unsigned char *)result, &len);
-       HMAC_CTX_cleanup(&c);
+       const md_kt_t *md5_kt = md_kt_get("MD5");
+       hmac_ctx_t hmac_ctx;
+       CLEAR(hmac_ctx);
+
+       hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt, NULL);
+       hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
+       hmac_ctx_final(&hmac_ctx, (unsigned char *)result);
+       hmac_ctx_cleanup(&hmac_ctx);
 }
 
 static void