From: Adriaan de Jong Date: Mon, 27 Jun 2011 07:22:08 +0000 (+0200) Subject: Refactored TLS_PRF to new hmac and md primitives X-Git-Tag: v2.3-alpha1~158 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eab0cf2df1b1f1f73a657384c0fdb201508c0399;p=thirdparty%2Fopenvpn.git Refactored TLS_PRF to new hmac and md primitives Signed-off-by: Adriaan de Jong Acked-by: Gert Doering Acked-by: James Yonan Signed-off-by: David Sommerseth --- diff --git a/ssl.c b/ssl.c index 6bef044a9..c658441aa 100644 --- 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);