]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored TLS_PRF to new hmac and md primitives
authorAdriaan de Jong <dejong@fox-it.com>
Mon, 27 Jun 2011 07:22:08 +0000 (09:22 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 19 Oct 2011 20:31:46 +0000 (22:31 +0200)
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
ssl.c

diff --git a/ssl.c b/ssl.c
index 6bef044a9ac3e20dfbd940bdb75398f433921994..c658441aa4f0a3bc5a585447b0ae3e68b83a1c32 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -3488,7 +3488,7 @@ swap_hmac (struct buffer *buf, const struct crypto_options *co, bool incoming)
 
   {
     /* hmac + packet_id (8 bytes) */
-    const int hmac_size = HMAC_size (ctx->hmac) + packet_id_size (true);
+    const int hmac_size = hmac_ctx_size (ctx->hmac) + packet_id_size (true);
 
     /* opcode + session_id */
     const int osid_size = 1 + SID_SIZE;
@@ -3640,27 +3640,18 @@ key_source2_print (const struct key_source2 *k)
 }
 
 /*
- * Use the TLS PRF function for generating data channel keys.
- * This code is taken from the OpenSSL library.
- *
- * TLS generates keys as such:
- *
- * master_secret[48] = PRF(pre_master_secret[48], "master secret",
- *                         ClientHello.random[32] + ServerHello.random[32])
- *
- * key_block[] = PRF(SecurityParameters.master_secret[48],
- *                 "key expansion",
- *                 SecurityParameters.server_random[32] +
- *                 SecurityParameters.client_random[32]);
+ * Generate the hash required by for the \c tls1_PRF function.
  *
- * Notes:
- *
- * (1) key_block contains a full set of 4 keys.
- * (2) The pre-master secret is generated by the client.
+ * @param md_kt                Message digest to use
+ * @param sec          Secret to base the hash on
+ * @param sec_len      Length of the secret
+ * @param seed         Seed to hash
+ * @param seed_len     Length of the seed
+ * @param out          Output buffer
+ * @param olen         Length of the output buffer
  */
-
-static void
-tls1_P_hash(const EVP_MD *md,
+void
+tls1_P_hash(const md_kt_t *md_kt,
            const uint8_t *sec,
            int sec_len,
            const uint8_t *seed,
@@ -3671,59 +3662,81 @@ tls1_P_hash(const EVP_MD *md,
   struct gc_arena gc = gc_new ();
   int chunk,n;
   unsigned int j;
-  HMAC_CTX ctx;
-  HMAC_CTX ctx_tmp;
-  uint8_t A1[EVP_MAX_MD_SIZE];
+  hmac_ctx_t ctx;
+  hmac_ctx_t ctx_tmp;
+  uint8_t A1[MAX_HMAC_KEY_LENGTH];
   unsigned int A1_len;
 
 #ifdef ENABLE_DEBUG
   const int olen_orig = olen;
   const uint8_t *out_orig = out;
 #endif
-       
+
+  CLEAR(ctx);
+  CLEAR(ctx_tmp);
+
   dmsg (D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex (sec, sec_len, 0, &gc));
   dmsg (D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex (seed, seed_len, 0, &gc));
 
-  chunk=EVP_MD_size(md);
+  chunk = md_kt_size(md_kt);
+  A1_len = md_kt_size(md_kt);
 
-  HMAC_CTX_init(&ctx);
-  HMAC_CTX_init(&ctx_tmp);
-  HMAC_Init_ex(&ctx,sec,sec_len,md, NULL);
-  HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL);
-  HMAC_Update(&ctx,seed,seed_len);
-  HMAC_Final(&ctx,A1,&A1_len);
+  hmac_ctx_init(&ctx, sec, sec_len, md_kt, NULL);
+  hmac_ctx_init(&ctx_tmp, sec, sec_len, md_kt, NULL);
+
+  hmac_ctx_update(&ctx,seed,seed_len);
+  hmac_ctx_final(&ctx, A1);
 
   n=0;
   for (;;)
     {
-      HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */
-      HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */
-      HMAC_Update(&ctx,A1,A1_len);
-      HMAC_Update(&ctx_tmp,A1,A1_len);
-      HMAC_Update(&ctx,seed,seed_len);
+      hmac_ctx_reset(&ctx);
+      hmac_ctx_reset(&ctx_tmp);
+      hmac_ctx_update(&ctx,A1,A1_len);
+      hmac_ctx_update(&ctx_tmp,A1,A1_len);
+      hmac_ctx_update(&ctx,seed,seed_len);
 
       if (olen > chunk)
        {
-         HMAC_Final(&ctx,out,&j);
-         out+=j;
-         olen-=j;
-         HMAC_Final(&ctx_tmp,A1,&A1_len); /* calc the next A1 value */
+         hmac_ctx_final(&ctx, out);
+         out+=chunk;
+         olen-=chunk;
+         hmac_ctx_final(&ctx_tmp, A1); /* calc the next A1 value */
        }
       else     /* last one */
        {
-         HMAC_Final(&ctx,A1,&A1_len);
+         hmac_ctx_final(&ctx, A1);
          memcpy(out,A1,olen);
          break;
        }
     }
-  HMAC_CTX_cleanup(&ctx);
-  HMAC_CTX_cleanup(&ctx_tmp);
+  hmac_ctx_cleanup(&ctx);
+  hmac_ctx_cleanup(&ctx_tmp);
   CLEAR (A1);
 
   dmsg (D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex (out_orig, olen_orig, 0, &gc));
   gc_free (&gc);
 }
 
+/*
+ * Use the TLS PRF function for generating data channel keys.
+ * This code is based on the OpenSSL library.
+ *
+ * TLS generates keys as such:
+ *
+ * master_secret[48] = PRF(pre_master_secret[48], "master secret",
+ *                         ClientHello.random[32] + ServerHello.random[32])
+ *
+ * key_block[] = PRF(SecurityParameters.master_secret[48],
+ *                 "key expansion",
+ *                 SecurityParameters.server_random[32] +
+ *                 SecurityParameters.client_random[32]);
+ *
+ * Notes:
+ *
+ * (1) key_block contains a full set of 4 keys.
+ * (2) The pre-master secret is generated by the client.
+ */
 static void
 tls1_PRF(uint8_t *label,
         int label_len,
@@ -3733,8 +3746,8 @@ tls1_PRF(uint8_t *label,
         int olen)
 {
   struct gc_arena gc = gc_new ();
-  const EVP_MD *md5 = EVP_md5();
-  const EVP_MD *sha1 = EVP_sha1();
+  const md_kt_t *md5 = md_kt_get("MD5");
+  const md_kt_t *sha1 = md_kt_get("SHA1");
   int len,i;
   const uint8_t *S1,*S2;
   uint8_t *out2;
@@ -3746,7 +3759,6 @@ tls1_PRF(uint8_t *label,
   S2= &(sec[len]);
   len+=(slen&1); /* add for odd, make longer */
 
-       
   tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen);
   tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);