added HMAC SHA384 and SHA512 support, bug fix to allow shorter HMAC key lengths than...
authorMichael Rash <mbr@cipherdyne.org>
Sun, 10 Mar 2013 04:27:08 +0000 (23:27 -0500)
committerMichael Rash <mbr@cipherdyne.org>
Sun, 10 Mar 2013 04:27:08 +0000 (23:27 -0500)
client/fwknop.c
lib/fko_hmac.c
lib/fko_util.c
lib/fko_util.h
lib/hmac.c
lib/hmac.h

index f29dda2..90b45eb 100644 (file)
@@ -1051,8 +1051,8 @@ display_ctx(fko_ctx_t ctx)
     printf("     Nat Access: %s\n", nat_access == NULL ? "<NULL>" : nat_access);
     printf("    Server Auth: %s\n", server_auth == NULL ? "<NULL>" : server_auth);
     printf(" Client Timeout: %u\n", client_timeout);
-    printf("    Digest Type: %d\n", digest_type);
-    printf("      HMAC Type: %d\n", hmac_type);
+    printf("    Digest Type: %d (%s)\n", digest_type, digest_inttostr(digest_type));
+    printf("      HMAC Type: %d (%s)\n", hmac_type, digest_inttostr(hmac_type));
     printf("Encryption Mode: %d\n", encryption_mode);
     printf("\n   Encoded Data: %s\n", enc_data == NULL ? "<NULL>" : enc_data);
     printf("SPA Data Digest: %s\n", spa_digest == NULL ? "<NULL>" : spa_digest);
index 8d69859..955f4b6 100644 (file)
@@ -178,7 +178,7 @@ int fko_calculate_hmac(fko_ctx_t ctx,
         return(FKO_ERROR_MEMORY_ALLOCATION);
 
     hmac_sha256(ctx->encrypted_msg,
-        ctx->encrypted_msg_len, hmac, hmac_key);
+        ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
 
     b64_encode(hmac, hmac_base64, SHA256_DIGEST_LEN);
     strip_b64_eq(hmac_base64);
index 099c30a..62cc67f 100644 (file)
@@ -80,6 +80,25 @@ hmac_digest_strtoint(const char *dt_str)
         return(-1);
 }
 
+/* Return digest string representation
+*/
+const char *
+digest_inttostr(const int type)
+{
+    if(type == FKO_DIGEST_MD5 || type == FKO_HMAC_MD5)
+        return("MD5");
+    else if(type == FKO_DIGEST_SHA1 || type == FKO_HMAC_SHA1)
+        return("SHA1");
+    else if(type == FKO_DIGEST_SHA256 || type == FKO_HMAC_SHA256)
+        return("SHA256");
+    else if(type == FKO_DIGEST_SHA384 || type == FKO_HMAC_SHA384)
+        return("SHA384");
+    else if(type == FKO_DIGEST_SHA512 || type == FKO_HMAC_SHA512)
+        return("SHA512");
+
+    return("Unknown digest type");
+}
+
 /* Validate plaintext input size
 */
 int
index a1e8850..99fb9c1 100644 (file)
@@ -40,6 +40,7 @@ int enc_mode_strtoint(const char *enc_mode_str);
 int strtol_wrapper(const char * const str, const int min,
     const int max, const int exit_upon_err, int *is_err);
 short digest_strtoint(const char *dt_str);
+const char * digest_inttostr(const int type);
 short hmac_digest_strtoint(const char *dt_str);
 
 size_t strlcat(char *dst, const char *src, size_t siz);
index d38dd34..5857b11 100644 (file)
@@ -39,16 +39,44 @@ typedef struct {
     unsigned char block_outer_pad[SHA256_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];
+} 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];
+} hmac_sha512_ctx;
+
+/* Begin SHA256 HMAC functions
+*/
 static void
-hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key)
+hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key, const int key_len)
 {
     int i = 0;
 
-    for (i=0; i < (int) SHA256_BLOCK_LEN; i++) {
+    for (i=0; i < key_len; i++) {
         ctx->block_inner_pad[i] = key[i] ^ 0x36;
         ctx->block_outer_pad[i] = key[i] ^ 0x5c;
     }
 
+    if(i < SHA256_BLOCK_LEN)
+    {
+        while(i < SHA256_BLOCK_LEN)
+        {
+            ctx->block_inner_pad[i] = 0x36;
+            ctx->block_outer_pad[i] = 0x5c;
+            i++;
+        }
+    }
+
     SHA256_Init(&ctx->ctx_inside);
     SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN);
 
@@ -80,17 +108,148 @@ hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac)
 
 void
 hmac_sha256(const char *msg, const unsigned int msg_len,
-    unsigned char *hmac, const char *hmac_key)
+    unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
 {
     hmac_sha256_ctx ctx;
 
     memset(&ctx, 0, sizeof(&ctx));
 
-    hmac_sha256_init(&ctx, hmac_key);
+    hmac_sha256_init(&ctx, hmac_key, hmac_key_len);
     hmac_sha256_update(&ctx, msg, msg_len);
     hmac_sha256_final(&ctx, hmac);
 
     return;
 }
 
+/* Begin SHA384 HMAC functions
+*/
+static void
+hmac_sha384_init(hmac_sha384_ctx *ctx, const char *key, const int key_len)
+{
+
+    int i = 0;
+
+    for (i=0; i < key_len; i++) {
+        ctx->block_inner_pad[i] = key[i] ^ 0x36;
+        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
+    }
+
+    if(i < SHA384_BLOCK_LEN)
+    {
+        while(i < SHA384_BLOCK_LEN)
+        {
+            ctx->block_inner_pad[i] = 0x36;
+            ctx->block_outer_pad[i] = 0x5c;
+            i++;
+        }
+    }
+
+    SHA384_Init(&ctx->ctx_inside);
+    SHA384_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA384_BLOCK_LEN);
+
+    SHA384_Init(&ctx->ctx_outside);
+    SHA384_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA384_BLOCK_LEN);
+
+    return;
+}
+
+static void
+hmac_sha384_update(hmac_sha384_ctx *ctx, const char *msg,
+    unsigned int msg_len)
+{
+    SHA384_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
+    return;
+}
+
+static void
+hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *hmac)
+{
+    unsigned char digest_inside[SHA384_DIGEST_LEN];
+
+    SHA384_Final(digest_inside, &ctx->ctx_inside);
+    SHA384_Update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_LEN);
+    SHA384_Final(hmac, &ctx->ctx_outside);
+
+    return;
+}
+
+void
+hmac_sha384(const char *msg, const unsigned int msg_len,
+    unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
+{
+    hmac_sha384_ctx ctx;
+
+    memset(&ctx, 0, sizeof(&ctx));
+
+    hmac_sha384_init(&ctx, hmac_key, hmac_key_len);
+    hmac_sha384_update(&ctx, msg, msg_len);
+    hmac_sha384_final(&ctx, hmac);
+
+    return;
+}
+
+/* Begin SHA512 HMAC functions
+*/
+static void
+hmac_sha512_init(hmac_sha512_ctx *ctx, const char *key, const int key_len)
+{
+    int i = 0;
+
+    for (i=0; i < key_len; i++) {
+        ctx->block_inner_pad[i] = key[i] ^ 0x36;
+        ctx->block_outer_pad[i] = key[i] ^ 0x5c;
+    }
+
+    if(i < SHA512_BLOCK_LEN)
+    {
+        while(i < SHA512_BLOCK_LEN)
+        {
+            ctx->block_inner_pad[i] = 0x36;
+            ctx->block_outer_pad[i] = 0x5c;
+            i++;
+        }
+    }
+
+    SHA512_Init(&ctx->ctx_inside);
+    SHA512_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA512_BLOCK_LEN);
+
+    SHA512_Init(&ctx->ctx_outside);
+    SHA512_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA512_BLOCK_LEN);
+
+    return;
+}
+
+static void
+hmac_sha512_update(hmac_sha512_ctx *ctx, const char *msg,
+    unsigned int msg_len)
+{
+    SHA512_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
+    return;
+}
 
+static void
+hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *hmac)
+{
+    unsigned char digest_inside[SHA512_DIGEST_LEN];
+
+    SHA512_Final(digest_inside, &ctx->ctx_inside);
+    SHA512_Update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_LEN);
+    SHA512_Final(hmac, &ctx->ctx_outside);
+
+    return;
+}
+
+void
+hmac_sha512(const char *msg, const unsigned int msg_len,
+    unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
+{
+    hmac_sha512_ctx ctx;
+
+    memset(&ctx, 0, sizeof(&ctx));
+
+    hmac_sha512_init(&ctx, hmac_key, hmac_key_len);
+    hmac_sha512_update(&ctx, msg, msg_len);
+    hmac_sha512_final(&ctx, hmac);
+
+    return;
+}
index 7fd2644..b853a4f 100644 (file)
 #include "digest.h"
 
 void hmac_sha256(const char *msg, const unsigned int msg_len,
-        unsigned char *hmac, const char *hmac_key);
+        unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
+void hmac_sha384(const char *msg, const unsigned int msg_len,
+        unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
+void hmac_sha512(const char *msg, const unsigned int msg_len,
+        unsigned char *hmac, const char *hmac_key, const int hmac_key_len);
 
 #endif /* HMAC_H */