diff options
author | Adam Langley <agl@google.com> | 2015-05-13 20:30:31 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-05-13 20:30:31 +0000 |
commit | 838711c53f430e0ef95d5dc5a476e19731365837 (patch) | |
tree | 6e43e34595ecf887c26c32b86d8ab097fe8cac64 /src/ssl/t1_enc.c | |
parent | f48ecc4b1c648ebf747dfdf1d1ebd9171838ce07 (diff) | |
parent | 02d138cf70e3aa194b2e12187622e666a54858d3 (diff) | |
download | external_boringssl-838711c53f430e0ef95d5dc5a476e19731365837.zip external_boringssl-838711c53f430e0ef95d5dc5a476e19731365837.tar.gz external_boringssl-838711c53f430e0ef95d5dc5a476e19731365837.tar.bz2 |
am 02d138cf: am e9ada863: external/boringssl: bump revision.
* commit '02d138cf70e3aa194b2e12187622e666a54858d3':
external/boringssl: bump revision.
Diffstat (limited to 'src/ssl/t1_enc.c')
-rw-r--r-- | src/ssl/t1_enc.c | 141 |
1 files changed, 50 insertions, 91 deletions
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c index 014bc88..3eaffe7 100644 --- a/src/ssl/t1_enc.c +++ b/src/ssl/t1_enc.c @@ -133,8 +133,9 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ -#include <stdio.h> #include <assert.h> +#include <stdio.h> +#include <string.h> #include <openssl/err.h> #include <openssl/evp.h> @@ -144,7 +145,7 @@ #include <openssl/obj.h> #include <openssl/rand.h> -#include "ssl_locl.h" +#include "internal.h" /* tls1_P_hash computes the TLS P_<hash> function as described in RFC 5246, @@ -225,7 +226,7 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, const uint8_t *seed2, size_t seed2_len) { size_t idx, len, count, i; const uint8_t *S1; - long m; + uint32_t m; const EVP_MD *md; int ret = 0; uint8_t *tmp; @@ -243,7 +244,7 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, /* Count number of digests and partition |secret| evenly. */ count = 0; - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) { if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) { count++; } @@ -258,7 +259,7 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret, } S1 = secret; memset(out, 0, out_len); - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) { if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) { /* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into * two halves with an overlapping byte. */ @@ -340,14 +341,12 @@ static int tls1_change_cipher_state_aead(SSL *s, char is_read, } aead_ctx = s->aead_read_ctx; } else { - /* When updating the cipher state for DTLS, we do not wish to overwrite the - * old ones because DTLS stores pointers to them in order to implement - * retransmission. See dtls1_hm_fragment_free. - * - * TODO(davidben): Simplify aead_write_ctx ownership, probably by just - * forbidding DTLS renego. */ - if (SSL_IS_DTLS(s)) { - s->aead_write_ctx = NULL; + if (SSL_IS_DTLS(s) && s->aead_write_ctx != NULL) { + /* DTLS renegotiation is unsupported, so a CCS can only switch away from + * the NULL cipher. This simplifies renegotiation. */ + OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, + ERR_R_INTERNAL_ERROR); + return 0; } if (!tls1_aead_ctx_init(&s->aead_write_ctx)) { return 0; @@ -355,8 +354,9 @@ static int tls1_change_cipher_state_aead(SSL *s, char is_read, aead_ctx = s->aead_write_ctx; } - if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len, - EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */)) { + if (!EVP_AEAD_CTX_init_with_direction( + &aead_ctx->ctx, aead, key, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH, + is_read ? evp_aead_open : evp_aead_seal)) { OPENSSL_free(aead_ctx); if (is_read) { s->aead_read_ctx = NULL; @@ -578,7 +578,7 @@ int tls1_enc(SSL *s, int send) { aead = s->aead_read_ctx; } - if (s->session == NULL || aead == NULL) { + if (aead == NULL) { /* Handle the initial NULL cipher. */ memmove(rec->data, rec->input, rec->length); rec->input = rec->data; @@ -598,13 +598,9 @@ int tls1_enc(SSL *s, int send) { memcpy(p, &seq[2], 6); memcpy(ad, dtlsseq, 8); } else { - int i; memcpy(ad, seq, 8); - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) { - break; - } + if (!ssl3_record_sequence_update(seq, 8)) { + return 0; } } @@ -739,7 +735,10 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) { } EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_copy_ex(&ctx, d); + if (!EVP_MD_CTX_copy_ex(&ctx, d)) { + EVP_MD_CTX_cleanup(&ctx); + return 0; + } EVP_DigestFinal_ex(&ctx, out, &ret); EVP_MD_CTX_cleanup(&ctx); @@ -756,11 +755,11 @@ int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) { EVP_MD_CTX ctx; int err = 0, len = 0; size_t i; - long mask; + uint32_t mask; EVP_MD_CTX_init(&ctx); - for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { + for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) { size_t hash_size; unsigned int digest_len; EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i]; @@ -863,82 +862,42 @@ int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, return SSL3_MASTER_SECRET_SIZE; } -int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen, - const char *label, size_t llen, - const uint8_t *context, size_t contextlen, +int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len, + const char *label, size_t label_len, + const uint8_t *context, size_t context_len, int use_context) { - uint8_t *val = NULL; - size_t vallen, currentvalpos; - int ret; - - /* construct PRF arguments we construct the PRF argument ourself rather than - * passing separate values into the TLS PRF to ensure that the concatenation - * of values does not create a prohibited label. */ - vallen = llen + SSL3_RANDOM_SIZE * 2; - if (use_context) { - vallen += 2 + contextlen; - } - - val = OPENSSL_malloc(vallen); - if (val == NULL) { - goto err2; + if (!s->s3->have_version || s->version == SSL3_VERSION) { + OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; } - currentvalpos = 0; - memcpy(val + currentvalpos, (uint8_t *)label, llen); - currentvalpos += llen; - memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); - currentvalpos += SSL3_RANDOM_SIZE; - memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); - currentvalpos += SSL3_RANDOM_SIZE; - + size_t seed_len = 2 * SSL3_RANDOM_SIZE; if (use_context) { - val[currentvalpos] = (contextlen >> 8) & 0xff; - currentvalpos++; - val[currentvalpos] = contextlen & 0xff; - currentvalpos++; - if (contextlen > 0 || context != NULL) { - memcpy(val + currentvalpos, context, contextlen); + if (context_len >= 1u << 16) { + OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_OVERFLOW); + return 0; } + seed_len += 2 + context_len; } - - /* disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited - * label len) = 15, so size of val > max(prohibited label len) = 15 and the - * comparisons won't have buffer overflow. */ - if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, - TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0 || - memcmp(val, TLS_MD_SERVER_FINISH_CONST, - TLS_MD_SERVER_FINISH_CONST_SIZE) == 0 || - memcmp(val, TLS_MD_MASTER_SECRET_CONST, - TLS_MD_MASTER_SECRET_CONST_SIZE) == 0 || - memcmp(val, TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) { - goto err1; + uint8_t *seed = OPENSSL_malloc(seed_len); + if (seed == NULL) { + OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE); + return 0; } - /* SSL_export_keying_material is not implemented for SSLv3, so passing - * everything through the label parameter works. */ - assert(s->version != SSL3_VERSION); - ret = s->enc_method->prf(s, out, olen, s->session->master_key, - s->session->master_key_length, (const char *)val, - vallen, NULL, 0, NULL, 0); - goto out; - -err1: - OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, - SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); - ret = 0; - goto out; - -err2: - OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE); - ret = 0; - -out: - if (val != NULL) { - OPENSSL_free(val); + memcpy(seed, s->s3->client_random, SSL3_RANDOM_SIZE); + memcpy(seed + SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE); + if (use_context) { + seed[2 * SSL3_RANDOM_SIZE] = (uint8_t)(context_len >> 8); + seed[2 * SSL3_RANDOM_SIZE + 1] = (uint8_t)context_len; + memcpy(seed + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); } + int ret = s->enc_method->prf(s, out, out_len, s->session->master_key, + s->session->master_key_length, label, label_len, + seed, seed_len, NULL, 0); + OPENSSL_free(seed); return ret; } |