int tls1_setup_key_block(SSL *s) { unsigned char *p1,*p2=NULL; const EVP_CIPHER *c; const EVP_MD *hash; int num; SSL_COMP *comp; int mac_type= NID_undef,mac_secret_size=0; int ret=0; #ifdef KSSL_DEBUG TINYCLR_SSL_PRINTF ("tls1_setup_key_block()\n"); #endif /* KSSL_DEBUG */ if (s->s3->tmp.key_block_length != 0) return(1); if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp)) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); } s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; s->s3->tmp.new_mac_pkey_type = mac_type; s->s3->tmp.new_mac_secret_size = mac_secret_size; num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); if ((p1=(unsigned char *)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; if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); goto err; } #ifdef TLS_DEBUG TINYCLR_SSL_PRINTF("client random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) TINYCLR_SSL_PRINTF("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } TINYCLR_SSL_PRINTF("server random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) TINYCLR_SSL_PRINTF("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } TINYCLR_SSL_PRINTF("pre-master\n"); { int z; for (z=0; z<s->session->master_key_length; z++) TINYCLR_SSL_PRINTF("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif if (!tls1_generate_key_block(s,p1,p2,num)) goto err; #ifdef TLS_DEBUG TINYCLR_SSL_PRINTF("\nkey block\n"); { int z; for (z=0; z<num; z++) TINYCLR_SSL_PRINTF("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } #endif if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { /* enable vulnerability countermeasure for CBC ciphers with * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ s->s3->need_empty_fragments = 1; if (s->session->cipher != NULL) { if (s->session->cipher->algorithm_enc == SSL_eNULL) s->s3->need_empty_fragments = 0; #ifndef OPENSSL_NO_RC4 if (s->session->cipher->algorithm_enc == SSL_RC4) s->s3->need_empty_fragments = 0; #endif } } ret = 1; err: if (p2) { OPENSSL_cleanse(p2,num); OPENSSL_free(p2); } return(ret); }
int tls1_setup_key_block(SSL *s) { uint8_t *p; const EVP_AEAD *aead = NULL; int ret = 0; size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len; size_t key_block_len; if (s->s3->tmp.key_block_length != 0) { return 1; } if (s->session->cipher == NULL) { goto cipher_unavailable_err; } if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, s->session->cipher, ssl3_version_from_wire(s, s->version))) { goto cipher_unavailable_err; } key_len = EVP_AEAD_key_length(aead); variable_iv_len = EVP_AEAD_nonce_length(aead); if (mac_secret_len > 0) { /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the * key length reported by |EVP_AEAD_key_length| will include the MAC key * bytes and initial implicit IV. */ if (key_len < mac_secret_len + fixed_iv_len) { OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR); return 0; } key_len -= mac_secret_len + fixed_iv_len; } else { /* The nonce is split into a fixed portion and a variable portion. */ if (variable_iv_len < fixed_iv_len) { OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR); return 0; } variable_iv_len -= fixed_iv_len; } assert(mac_secret_len < 256); assert(fixed_iv_len < 256); assert(variable_iv_len < 256); s->s3->tmp.new_aead = aead; s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len; key_block_len = key_len + mac_secret_len + fixed_iv_len; key_block_len *= 2; ssl3_cleanup_key_block(s); p = (uint8_t *)OPENSSL_malloc(key_block_len); if (p == NULL) { OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_MALLOC_FAILURE); goto err; } s->s3->tmp.key_block_length = key_block_len; s->s3->tmp.key_block = p; if (!tls1_generate_key_block(s, p, key_block_len)) { goto err; } if (!SSL_USE_EXPLICIT_IV(s) && (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) { /* enable vulnerability countermeasure for CBC ciphers with known-IV * problem (http://www.openssl.org/~bodo/tls-cbc.txt). */ s->s3->need_record_splitting = 1; if (s->session->cipher != NULL && s->session->cipher->algorithm_enc == SSL_RC4) { s->s3->need_record_splitting = 0; } } ret = 1; err: return ret; cipher_unavailable_err: OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return 0; }
int tls1_setup_key_block(SSL *s) { uint8_t *p; const EVP_AEAD *aead = NULL; int ret = 0; size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len; size_t key_block_len; if (s->s3->tmp.key_block_length != 0) { return 1; } if (s->session->cipher == NULL) { goto cipher_unavailable_err; } if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, s->session->cipher, ssl3_version_from_wire(s, s->version))) { goto cipher_unavailable_err; } key_len = EVP_AEAD_key_length(aead); variable_iv_len = EVP_AEAD_nonce_length(aead); if (mac_secret_len > 0) { /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the * key length reported by |EVP_AEAD_key_length| will include the MAC key * bytes and initial implicit IV. */ if (key_len < mac_secret_len + fixed_iv_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } key_len -= mac_secret_len + fixed_iv_len; } else { /* The nonce is split into a fixed portion and a variable portion. */ if (variable_iv_len < fixed_iv_len) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return 0; } variable_iv_len -= fixed_iv_len; } assert(mac_secret_len < 256); assert(fixed_iv_len < 256); assert(variable_iv_len < 256); s->s3->tmp.new_aead = aead; s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len; key_block_len = key_len + mac_secret_len + fixed_iv_len; key_block_len *= 2; ssl3_cleanup_key_block(s); p = (uint8_t *)OPENSSL_malloc(key_block_len); if (p == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } s->s3->tmp.key_block_length = key_block_len; s->s3->tmp.key_block = p; if (!tls1_generate_key_block(s, p, key_block_len)) { goto err; } ret = 1; err: return ret; cipher_unavailable_err: OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return 0; }
int tls1_setup_key_block(SSL *s) { unsigned char *p1,*p2; const EVP_CIPHER *c; const EVP_MD *hash; int num; SSL_COMP *comp; if (s->s3->tmp.key_block_length != 0) return(1); if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); } s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) goto err; if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) goto err; s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p1; #ifdef TLS_DEBUG printf("client random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } printf("server random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } printf("pre-master\n"); { int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif tls1_generate_key_block(s,p1,p2,num); memset(p2,0,num); OPENSSL_free(p2); #ifdef TLS_DEBUG printf("\nkey block\n"); { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } #endif /* enable vulnerability countermeasure for CBC ciphers with * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ s->s3->need_empty_fragments = 1; #ifndef NO_RC4 if ((s->session->cipher != NULL) && ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)) s->s3->need_empty_fragments = 0; #endif return(1); err: SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); return(0); }