X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_enc.c;h=6e56441d0fba2ec50d20298772aadae420b558ec;hp=906029c8fc4aca1b1170fbb3e794559980b39a34;hb=9021a5dfb37fd3a6f7726f07ef0f27dcb71048e2;hpb=6938c954b072c1ddddeb0ec9f6a151df0d2cd925 diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 906029c8fc..6e56441d0f 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -1,4 +1,3 @@ -/* ssl/t1_enc.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -137,183 +136,79 @@ #include #include "ssl_locl.h" -#ifndef OPENSSL_NO_COMP -# include -#endif +#include #include -#include -#include +#include #include -/* seed1 through seed5 are virtually concatenated */ -static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, - int sec_len, - const void *seed1, int seed1_len, - const void *seed2, int seed2_len, - const void *seed3, int seed3_len, - const void *seed4, int seed4_len, - const void *seed5, int seed5_len, - unsigned char *out, int olen) -{ - int chunk; - size_t j; - EVP_MD_CTX ctx, ctx_tmp, ctx_init; - EVP_PKEY *mac_key; - unsigned char A1[EVP_MAX_MD_SIZE]; - size_t A1_len; - int ret = 0; - - chunk = EVP_MD_size(md); - OPENSSL_assert(chunk >= 0); - - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_init(&ctx_tmp); - EVP_MD_CTX_init(&ctx_init); - EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); - if (!mac_key) - goto err; - if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key)) - goto err; - if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) - goto err; - if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) - goto err; - if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) - goto err; - if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) - goto err; - if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) - goto err; - if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) - goto err; - if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) - goto err; - - for (;;) { - /* Reinit mac contexts */ - if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) - goto err; - if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) - goto err; - if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) - goto err; - if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) - goto err; - if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) - goto err; - if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) - goto err; - if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) - goto err; - if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) - goto err; - - if (olen > chunk) { - if (!EVP_DigestSignFinal(&ctx, out, &j)) - goto err; - out += j; - olen -= j; - /* calc the next A1 value */ - if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) - goto err; - } else { /* last one */ - - if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) - goto err; - memcpy(out, A1, olen); - break; - } - } - ret = 1; - err: - EVP_PKEY_free(mac_key); - EVP_MD_CTX_cleanup(&ctx); - EVP_MD_CTX_cleanup(&ctx_tmp); - EVP_MD_CTX_cleanup(&ctx_init); - OPENSSL_cleanse(A1, sizeof(A1)); - return ret; -} - -/* seed1 through seed5 are virtually concatenated */ -static int tls1_PRF(long digest_mask, +/* seed1 through seed5 are concatenated */ +static int tls1_PRF(SSL *s, const void *seed1, int seed1_len, const void *seed2, int seed2_len, const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, int slen, - unsigned char *out1, unsigned char *out2, int olen) + unsigned char *out, int olen) { - int len, i, idx, count; - const unsigned char *S1; - long m; - const EVP_MD *md; + const EVP_MD *md = ssl_prf_md(s); + EVP_PKEY_CTX *pctx = NULL; + int ret = 0; + size_t outlen = olen; - /* Count number of digests and partition sec evenly */ - count = 0; - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { - if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) - count++; - } - if (!count) { + if (md == NULL) { /* Should never happen */ SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); - goto err; - } - len = slen / count; - if (count == 1) - slen = 0; - S1 = sec; - memset(out1, 0, olen); - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { - if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { - if (!md) { - SSLerr(SSL_F_TLS1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE); - goto err; - } - if (!tls1_P_hash(md, S1, len + (slen & 1), - seed1, seed1_len, seed2, seed2_len, seed3, - seed3_len, seed4, seed4_len, seed5, seed5_len, - out2, olen)) - goto err; - S1 += len; - for (i = 0; i < olen; i++) { - out1[i] ^= out2[i]; - } - } + return 0; } + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); + if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0 + || EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) <= 0 + || EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, slen) <= 0) + goto err; + + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len) <= 0) + goto err; + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len) <= 0) + goto err; + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len) <= 0) + goto err; + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed4, seed4_len) <= 0) + goto err; + if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed5, seed5_len) <= 0) + goto err; + + if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) + goto err; ret = 1; - err: + + err: + EVP_PKEY_CTX_free(pctx); return ret; } -static int tls1_generate_key_block(SSL *s, unsigned char *km, - unsigned char *tmp, int num) +static int tls1_generate_key_block(SSL *s, unsigned char *km, int num) { int ret; - ret = tls1_PRF(ssl_get_algorithm2(s), + ret = tls1_PRF(s, TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, NULL, 0, s->session->master_key, - s->session->master_key_length, km, tmp, num); + s->session->master_key_length, km, num); return ret; } int tls1_change_cipher_state(SSL *s, int which) { - static const unsigned char empty[] = ""; unsigned char *p, *mac_secret; - unsigned char *exp_label; unsigned char tmp1[EVP_MAX_KEY_LENGTH]; unsigned char tmp2[EVP_MAX_KEY_LENGTH]; unsigned char iv1[EVP_MAX_IV_LENGTH * 2]; unsigned char iv2[EVP_MAX_IV_LENGTH * 2]; unsigned char *ms, *key, *iv; - int client_write; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP @@ -324,10 +219,9 @@ int tls1_change_cipher_state(SSL *s, int which) int *mac_secret_size; EVP_MD_CTX *mac_ctx; EVP_PKEY *mac_key; - int is_export, n, i, j, k, exp_label_len, cl; + int n, i, j, k, cl; int reuse_dd = 0; - is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c = s->s3->tmp.new_sym_enc; m = s->s3->tmp.new_hash; mac_type = s->s3->tmp.new_mac_pkey_type; @@ -343,14 +237,13 @@ int tls1_change_cipher_state(SSL *s, int which) if (s->enc_read_ctx != NULL) reuse_dd = 1; - else if ((s->enc_read_ctx = - OPENSSL_malloc(sizeof(*s->enc_read_ctx))) == NULL) + else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) goto err; else /* * make sure it's intialized in case we exit later with an error */ - EVP_CIPHER_CTX_init(s->enc_read_ctx); + EVP_CIPHER_CTX_reset(s->enc_read_ctx); dd = s->enc_read_ctx; mac_ctx = ssl_replace_hash(&s->read_hash, NULL); if (mac_ctx == NULL) @@ -365,8 +258,6 @@ int tls1_change_cipher_state(SSL *s, int which) SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } - if (!RECORD_LAYER_setup_comp_buffer(&s->rlayer)) - goto err; } #endif /* @@ -387,7 +278,7 @@ int tls1_change_cipher_state(SSL *s, int which) goto err; dd = s->enc_write_ctx; if (SSL_IS_DTLS(s)) { - mac_ctx = EVP_MD_CTX_create(); + mac_ctx = EVP_MD_CTX_new(); if (mac_ctx == NULL) goto err; s->write_hash = mac_ctx; @@ -418,14 +309,13 @@ int tls1_change_cipher_state(SSL *s, int which) } if (reuse_dd) - EVP_CIPHER_CTX_cleanup(dd); + EVP_CIPHER_CTX_reset(dd); p = s->s3->tmp.key_block; i = *mac_secret_size = s->s3->tmp.new_mac_secret_size; cl = EVP_CIPHER_key_length(c); - j = is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? - cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; + j = cl; /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ /* If GCM/CCM mode only part of IV comes from PRF */ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) @@ -442,9 +332,6 @@ int tls1_change_cipher_state(SSL *s, int which) n += j + j; iv = &(p[n]); n += k + k; - exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; - exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; - client_write = 1; } else { n = i; ms = &(p[n]); @@ -453,9 +340,6 @@ int tls1_change_cipher_state(SSL *s, int which) n += j + k; iv = &(p[n]); n += k; - exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; - exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; - client_write = 0; } if (n > s->s3->tmp.key_block_length) { @@ -476,7 +360,7 @@ int tls1_change_cipher_state(SSL *s, int which) } EVP_PKEY_free(mac_key); } -#ifdef TLS_DEBUG +#ifdef SSL_DEBUG printf("which = %04X\nmac key=", which); { int z; @@ -484,33 +368,6 @@ int tls1_change_cipher_state(SSL *s, int which) printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n'); } #endif - if (is_export) { - /* - * In here I set both the read and write key/iv to the same value - * since only the correct one will be used :-). - */ - if (!tls1_PRF(ssl_get_algorithm2(s), - exp_label, exp_label_len, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, - key, j, tmp1, tmp2, EVP_CIPHER_key_length(c))) - goto err2; - key = tmp1; - - if (k > 0) { - if (!tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, empty, 0, iv1, iv2, k * 2)) - goto err2; - if (client_write) - iv = iv1; - else - iv = &(iv1[k]); - } - } if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) @@ -565,7 +422,7 @@ int tls1_change_cipher_state(SSL *s, int which) } #endif -#ifdef TLS_DEBUG +#ifdef SSL_DEBUG printf("which = %04X\nkey=", which); { int z; @@ -598,7 +455,7 @@ int tls1_change_cipher_state(SSL *s, int which) int tls1_setup_key_block(SSL *s) { - unsigned char *p1, *p2 = NULL; + unsigned char *p; const EVP_CIPHER *c; const EVP_MD *hash; int num; @@ -626,20 +483,15 @@ int tls1_setup_key_block(SSL *s) ssl3_cleanup_key_block(s); - if ((p1 = OPENSSL_malloc(num)) == NULL) { + if ((p = OPENSSL_malloc(num)) == NULL) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); goto err; } s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p1; + s->s3->tmp.key_block = p; - if ((p2 = OPENSSL_malloc(num)) == NULL) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - OPENSSL_free(p1); - goto err; - } -#ifdef TLS_DEBUG +#ifdef SSL_DEBUG printf("client random\n"); { int z; @@ -662,14 +514,14 @@ int tls1_setup_key_block(SSL *s) ((z + 1) % 16) ? ' ' : '\n'); } #endif - if (!tls1_generate_key_block(s, p1, p2, num)) + if (!tls1_generate_key_block(s, p, num)) goto err; -#ifdef TLS_DEBUG +#ifdef SSL_DEBUG printf("\nkey block\n"); { int z; for (z = 0; z < num; z++) - printf("%02X%c", p1[z], ((z + 1) % 16) ? ' ' : '\n'); + printf("%02X%c", p[z], ((z + 1) % 16) ? ' ' : '\n'); } #endif @@ -694,7 +546,6 @@ int tls1_setup_key_block(SSL *s) ret = 1; err: - OPENSSL_clear_free(p2, num); return (ret); } @@ -702,8 +553,7 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out) { int hashlen; - unsigned char hash[2 * EVP_MAX_MD_SIZE]; - unsigned char buf2[12]; + unsigned char hash[EVP_MAX_MD_SIZE]; if (!ssl3_digest_cached_records(s, 0)) return 0; @@ -713,21 +563,17 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, if (hashlen == 0) return 0; - if (!tls1_PRF(ssl_get_algorithm2(s), - str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, + if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, s->session->master_key, s->session->master_key_length, - out, buf2, sizeof buf2)) + out, TLS1_FINISH_MAC_LENGTH)) return 0; OPENSSL_cleanse(hash, hashlen); - OPENSSL_cleanse(buf2, sizeof(buf2)); - return sizeof(buf2); + return TLS1_FINISH_MAC_LENGTH; } int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, int len) { - unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; - if (s->session->flags & SSL_SESS_FLAG_EXTMS) { unsigned char hash[EVP_MAX_MD_SIZE * 2]; int hashlen; @@ -743,24 +589,25 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, fprintf(stderr, "Handshake hashes:\n"); BIO_dump_fp(stderr, (char *)hash, hashlen); #endif - tls1_PRF(ssl_get_algorithm2(s), + tls1_PRF(s, TLS_MD_EXTENDED_MASTER_SECRET_CONST, TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, hash, hashlen, NULL, 0, NULL, 0, - NULL, 0, p, len, s->session->master_key, buff, sizeof buff); + NULL, 0, p, len, s->session->master_key, + SSL3_MASTER_SECRET_SIZE); OPENSSL_cleanse(hash, hashlen); } else { - tls1_PRF(ssl_get_algorithm2(s), + tls1_PRF(s, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0, s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, p, len, s->session->master_key, buff, sizeof buff); + NULL, 0, p, len, s->session->master_key, + SSL3_MASTER_SECRET_SIZE); } - OPENSSL_cleanse(buff, sizeof buff); #ifdef SSL_DEBUG fprintf(stderr, "Premaster Secret:\n"); BIO_dump_fp(stderr, (char *)p, len); @@ -797,15 +644,10 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *context, size_t contextlen, int use_context) { - unsigned char *buff; unsigned char *val = NULL; size_t vallen = 0, currentvalpos; int rv; - buff = OPENSSL_malloc(olen); - if (buff == NULL) - goto err2; - /* * construct PRF arguments we construct the PRF argument ourself rather * than passing separate values into the TLS PRF to ensure that the @@ -858,14 +700,14 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1; - rv = tls1_PRF(ssl_get_algorithm2(s), + rv = tls1_PRF(s, val, vallen, NULL, 0, NULL, 0, NULL, 0, NULL, 0, s->session->master_key, s->session->master_key_length, - out, buff, olen); + out, olen); goto ret; err1: @@ -877,8 +719,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); rv = 0; ret: - CRYPTO_clear_free(val, vallen); - CRYPTO_clear_free(buff, olen); + OPENSSL_clear_free(val, vallen); return (rv); } @@ -947,6 +788,8 @@ int tls1_alert_code(int code) return (TLS1_AD_UNKNOWN_PSK_IDENTITY); case SSL_AD_INAPPROPRIATE_FALLBACK: return (TLS1_AD_INAPPROPRIATE_FALLBACK); + case SSL_AD_NO_APPLICATION_PROTOCOL: + return (TLS1_AD_NO_APPLICATION_PROTOCOL); default: return (-1); }