summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdriaan de Jong <dejong@fox-it.com>2011-06-23 17:18:32 +0200
committerDavid Sommerseth <davids@redhat.com>2011-10-19 22:13:25 +0200
commite8c950f12dfd6187f084fb06b6fe6e57c030bdad (patch)
tree15e115f4a19d45c189d8435a018c9df8c05cffcb
parentd5f4461779899dc13be3fc7d41e0f0ac308ffa73 (diff)
downloadopenvpn-e8c950f12dfd6187f084fb06b6fe6e57c030bdad.tar.gz
openvpn-e8c950f12dfd6187f084fb06b6fe6e57c030bdad.tar.xz
openvpn-e8c950f12dfd6187f084fb06b6fe6e57c030bdad.zip
Refactored HMAC functions
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>
-rw-r--r--crypto.c57
-rw-r--r--crypto_backend.h60
-rw-r--r--crypto_openssl.c73
-rw-r--r--ntlm.c15
4 files changed, 155 insertions, 50 deletions
diff --git a/crypto.c b/crypto.c
index 4c16979..cf1c8be 100644
--- 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;
}
}
diff --git a/crypto_backend.h b/crypto_backend.h
index b6fd996..ae3e7fb 100644
--- a/crypto_backend.h
+++ b/crypto_backend.h
@@ -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_ */
diff --git a/crypto_openssl.c b/crypto_openssl.c
index 12c4392..55d88db 100644
--- a/crypto_openssl.c
+++ b/crypto_openssl.c
@@ -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 512c26f..30d5d11 100644
--- 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