[libfko] bug fix to maintain OpenSSL compatibility for HMAC keys longer than associat...
authorMichael Rash <mbr@cipherdyne.org>
Wed, 13 Mar 2013 02:17:41 +0000 (22:17 -0400)
committerMichael Rash <mbr@cipherdyne.org>
Wed, 13 Mar 2013 02:17:41 +0000 (22:17 -0400)
lib/hmac.c
lib/hmac.h

index e4f62f7..51625b6 100644 (file)
@@ -35,63 +35,88 @@ typedef struct {
     MD5Context ctx_inside;
     MD5Context ctx_outside;
 
-    unsigned char block_inner_pad[MD5_BLOCK_LEN];
-    unsigned char block_outer_pad[MD5_BLOCK_LEN];
+    unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
+    unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
 } hmac_md5_ctx;
 
 typedef struct {
     SHA1_INFO ctx_inside;
     SHA1_INFO ctx_outside;
 
-    unsigned char block_inner_pad[SHA1_BLOCK_LEN];
-    unsigned char block_outer_pad[SHA1_BLOCK_LEN];
+    unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
+    unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
 } hmac_sha1_ctx;
 
 typedef struct {
     SHA256_CTX ctx_inside;
     SHA256_CTX ctx_outside;
 
-    unsigned char block_inner_pad[SHA256_BLOCK_LEN];
-    unsigned char block_outer_pad[SHA256_BLOCK_LEN];
+    unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
+    unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
 } hmac_sha256_ctx;
 
 typedef struct {
     SHA384_CTX ctx_inside;
     SHA384_CTX ctx_outside;
 
-    unsigned char block_inner_pad[SHA384_BLOCK_LEN];
-    unsigned char block_outer_pad[SHA384_BLOCK_LEN];
+    unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
+    unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
 } hmac_sha384_ctx;
 
 typedef struct {
     SHA512_CTX ctx_inside;
     SHA512_CTX ctx_outside;
 
-    unsigned char block_inner_pad[SHA512_BLOCK_LEN];
-    unsigned char block_outer_pad[SHA512_BLOCK_LEN];
+    unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
+    unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
 } hmac_sha512_ctx;
 
-/* Begin MD5 HMAC functions
-*/
 static void
-hmac_md5_init(hmac_md5_ctx *ctx, const char *key, const int key_len)
+pad_init(unsigned char *inner_pad, unsigned char *outer_pad,
+        const unsigned char *key, const int key_len)
 {
     int i = 0;
 
-    for (i=0; i < MD5_BLOCK_LEN && i < key_len; i++) {
-        ctx->block_inner_pad[i] = key[i] ^ 0x36;
-        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
+    for (i=0; i < MAX_DIGEST_BLOCK_LEN && i < key_len; i++) {
+        inner_pad[i] = key[i] ^ 0x36;
+        outer_pad[i] = key[i] ^ 0x5c;
     }
 
-    if(i < MD5_BLOCK_LEN)
+    if(i < MAX_DIGEST_BLOCK_LEN)
     {
-        while(i < MD5_BLOCK_LEN)
+        while(i < MAX_DIGEST_BLOCK_LEN)
         {
-            ctx->block_inner_pad[i] = 0x36;
-            ctx->block_outer_pad[i] = 0x5c;
+            inner_pad[i] = 0x36;
+            outer_pad[i] = 0x5c;
             i++;
         }
     }
+    return;
+}
+
+/* Begin MD5 HMAC functions
+*/
+static void
+hmac_md5_init(hmac_md5_ctx *ctx, const char *key, const int key_len)
+{
+    unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
+    unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
+
+    memset(final_key, 0x00, MAX_DIGEST_BLOCK_LEN);
+    memcpy(init_key, key, key_len);
+
+    if(MD5_BLOCK_LEN < key_len)
+    {
+        /* Calculate the digest of the key
+        */
+        md5(final_key, init_key, key_len);
+    }
+    else
+    {
+        memcpy(final_key, init_key, key_len);
+    }
+
+    pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, key_len);
 
     MD5Init(&ctx->ctx_inside);
     MD5Update(&ctx->ctx_inside, ctx->block_inner_pad, MD5_BLOCK_LEN);
@@ -142,23 +167,25 @@ hmac_md5(const char *msg, const unsigned int msg_len,
 static void
 hmac_sha1_init(hmac_sha1_ctx *ctx, const char *key, const int key_len)
 {
-    int i = 0;
+    unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
+    unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
 
-    for (i=0; i < SHA1_BLOCK_LEN && i < key_len; i++) {
-        ctx->block_inner_pad[i] = key[i] ^ 0x36;
-        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
-    }
+    memset(final_key, 0x00, MAX_DIGEST_BLOCK_LEN);
+    memcpy(init_key, key, key_len);
 
-    if(i < SHA1_BLOCK_LEN)
+    if(SHA1_BLOCK_LEN < key_len)
     {
-        while(i < SHA1_BLOCK_LEN)
-        {
-            ctx->block_inner_pad[i] = 0x36;
-            ctx->block_outer_pad[i] = 0x5c;
-            i++;
-        }
+        /* Calculate the digest of the key
+        */
+        sha1(final_key, init_key, key_len);
+    }
+    else
+    {
+        memcpy(final_key, init_key, key_len);
     }
 
+    pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, key_len);
+
     sha1_init(&ctx->ctx_inside);
     sha1_update(&ctx->ctx_inside, ctx->block_inner_pad, SHA1_BLOCK_LEN);
 
@@ -208,22 +235,24 @@ hmac_sha1(const char *msg, const unsigned int msg_len,
 static void
 hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key, const int key_len)
 {
-    int i = 0;
+    unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
+    unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
 
-    for (i=0; i < SHA256_BLOCK_LEN && i < key_len; i++) {
-        ctx->block_inner_pad[i] = key[i] ^ 0x36;
-        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
-    }
+    memset(final_key, 0x00, MAX_DIGEST_BLOCK_LEN);
+    memcpy(init_key, key, key_len);
 
-    if(i < SHA256_BLOCK_LEN)
+    if(SHA256_BLOCK_LEN < key_len)
     {
-        while(i < SHA256_BLOCK_LEN)
-        {
-            ctx->block_inner_pad[i] = 0x36;
-            ctx->block_outer_pad[i] = 0x5c;
-            i++;
-        }
+        /* Calculate the digest of the key
+        */
+        sha256(final_key, init_key, key_len);
     }
+    else
+    {
+        memcpy(final_key, init_key, key_len);
+    }
+
+    pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, key_len);
 
     SHA256_Init(&ctx->ctx_inside);
     SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN);
@@ -274,24 +303,25 @@ hmac_sha256(const char *msg, const unsigned int msg_len,
 static void
 hmac_sha384_init(hmac_sha384_ctx *ctx, const char *key, const int key_len)
 {
+    unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
+    unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
 
-    int i = 0;
+    memset(final_key, 0x00, MAX_DIGEST_BLOCK_LEN);
+    memcpy(init_key, key, key_len);
 
-    for (i=0; i < SHA384_BLOCK_LEN && i < key_len; i++) {
-        ctx->block_inner_pad[i] = key[i] ^ 0x36;
-        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
+    if(SHA384_BLOCK_LEN < key_len)
+    {
+        /* Calculate the digest of the key
+        */
+        sha384(final_key, init_key, key_len);
     }
-
-    if(i < SHA384_BLOCK_LEN)
+    else
     {
-        while(i < SHA384_BLOCK_LEN)
-        {
-            ctx->block_inner_pad[i] = 0x36;
-            ctx->block_outer_pad[i] = 0x5c;
-            i++;
-        }
+        memcpy(final_key, init_key, key_len);
     }
 
+    pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, key_len);
+
     SHA384_Init(&ctx->ctx_inside);
     SHA384_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA384_BLOCK_LEN);
 
@@ -341,22 +371,24 @@ hmac_sha384(const char *msg, const unsigned int msg_len,
 static void
 hmac_sha512_init(hmac_sha512_ctx *ctx, const char *key, const int key_len)
 {
-    int i = 0;
+    unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
+    unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
 
-    for (i=0; i < SHA512_BLOCK_LEN && i < key_len; i++) {
-        ctx->block_inner_pad[i] = key[i] ^ 0x36;
-        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
-    }
+    memset(final_key, 0x00, MAX_DIGEST_BLOCK_LEN);
+    memcpy(init_key, key, key_len);
 
-    if(i < SHA512_BLOCK_LEN)
+    if(SHA512_BLOCK_LEN < key_len)
     {
-        while(i < SHA512_BLOCK_LEN)
-        {
-            ctx->block_inner_pad[i] = 0x36;
-            ctx->block_outer_pad[i] = 0x5c;
-            i++;
-        }
+        /* Calculate the digest of the key
+        */
+        sha512(final_key, init_key, key_len);
     }
+    else
+    {
+        memcpy(final_key, init_key, key_len);
+    }
+
+    pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, key_len);
 
     SHA512_Init(&ctx->ctx_inside);
     SHA512_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA512_BLOCK_LEN);
index 3aaded3..292fbc7 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "digest.h"
 
+#define MAX_DIGEST_BLOCK_LEN    SHA512_BLOCK_LEN
+
 void hmac_md5(const char *msg, const unsigned int msg_len,
         unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
 void hmac_sha1(const char *msg, const unsigned int msg_len,