diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/src/ssl/s3_enc.c | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/src/lib/libssl/src/ssl/s3_enc.c b/src/lib/libssl/src/ssl/s3_enc.c index 8e004fbe46..c039e7ee71 100644 --- a/src/lib/libssl/src/ssl/s3_enc.c +++ b/src/lib/libssl/src/ssl/s3_enc.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: s3_enc.c,v 1.47 2014/06/13 16:04:13 jsing Exp $ */ | 1 | /* $OpenBSD: s3_enc.c,v 1.48 2014/06/13 16:08:03 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -214,16 +214,19 @@ ssl3_generate_key_block(SSL *s, unsigned char *km, int num) | |||
| 214 | int | 214 | int |
| 215 | ssl3_change_cipher_state(SSL *s, int which) | 215 | ssl3_change_cipher_state(SSL *s, int which) |
| 216 | { | 216 | { |
| 217 | unsigned char *p, *mac_secret; | 217 | const unsigned char *client_write_mac_secret, *server_write_mac_secret; |
| 218 | const unsigned char *client_write_key, *server_write_key; | ||
| 219 | const unsigned char *client_write_iv, *server_write_iv; | ||
| 220 | const unsigned char *mac_secret, *key, *iv; | ||
| 221 | unsigned char *key_block, *er1, *er2; | ||
| 218 | unsigned char export_key[EVP_MAX_KEY_LENGTH]; | 222 | unsigned char export_key[EVP_MAX_KEY_LENGTH]; |
| 219 | unsigned char export_iv[EVP_MAX_IV_LENGTH]; | 223 | unsigned char export_iv[EVP_MAX_IV_LENGTH]; |
| 220 | unsigned char *ms, *key, *iv, *er1, *er2; | 224 | int is_export, mac_len, key_len, iv_len; |
| 225 | char is_read, use_client_keys; | ||
| 221 | EVP_CIPHER_CTX *cipher_ctx; | 226 | EVP_CIPHER_CTX *cipher_ctx; |
| 222 | const EVP_CIPHER *cipher; | 227 | const EVP_CIPHER *cipher; |
| 223 | EVP_MD_CTX mac_ctx; | 228 | EVP_MD_CTX mac_ctx; |
| 224 | const EVP_MD *mac; | 229 | const EVP_MD *mac; |
| 225 | int is_export, n, mac_len, key_len, iv_len; | ||
| 226 | char is_read; | ||
| 227 | 230 | ||
| 228 | #ifndef OPENSSL_NO_COMP | 231 | #ifndef OPENSSL_NO_COMP |
| 229 | const SSL_COMP *comp; | 232 | const SSL_COMP *comp; |
| @@ -243,6 +246,14 @@ ssl3_change_cipher_state(SSL *s, int which) | |||
| 243 | */ | 246 | */ |
| 244 | is_read = (which & SSL3_CC_READ) != 0; | 247 | is_read = (which & SSL3_CC_READ) != 0; |
| 245 | 248 | ||
| 249 | /* | ||
| 250 | * use_client_keys is true if we wish to use the keys for the "client | ||
| 251 | * write" direction. This is the case if we're a client sending a | ||
| 252 | * ChangeCipherSpec, or a server reading a client's ChangeCipherSpec. | ||
| 253 | */ | ||
| 254 | use_client_keys = ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || | ||
| 255 | (which == SSL3_CHANGE_CIPHER_SERVER_READ)); | ||
| 256 | |||
| 246 | #ifndef OPENSSL_NO_COMP | 257 | #ifndef OPENSSL_NO_COMP |
| 247 | comp = s->s3->tmp.new_compression; | 258 | comp = s->s3->tmp.new_compression; |
| 248 | if (is_read) { | 259 | if (is_read) { |
| @@ -288,9 +299,6 @@ ssl3_change_cipher_state(SSL *s, int which) | |||
| 288 | 299 | ||
| 289 | if (ssl_replace_hash(&s->read_hash, mac) == NULL) | 300 | if (ssl_replace_hash(&s->read_hash, mac) == NULL) |
| 290 | goto err; | 301 | goto err; |
| 291 | |||
| 292 | memset(s->s3->read_sequence, 0, SSL3_SEQUENCE_SIZE); | ||
| 293 | mac_secret = &(s->s3->read_mac_secret[0]); | ||
| 294 | } else { | 302 | } else { |
| 295 | EVP_CIPHER_CTX_free(s->enc_write_ctx); | 303 | EVP_CIPHER_CTX_free(s->enc_write_ctx); |
| 296 | s->enc_write_ctx = NULL; | 304 | s->enc_write_ctx = NULL; |
| @@ -300,12 +308,10 @@ ssl3_change_cipher_state(SSL *s, int which) | |||
| 300 | 308 | ||
| 301 | if (ssl_replace_hash(&s->write_hash, mac) == NULL) | 309 | if (ssl_replace_hash(&s->write_hash, mac) == NULL) |
| 302 | goto err; | 310 | goto err; |
| 303 | |||
| 304 | memset(s->s3->write_sequence, 0, SSL3_SEQUENCE_SIZE); | ||
| 305 | mac_secret = &(s->s3->write_mac_secret[0]); | ||
| 306 | } | 311 | } |
| 307 | 312 | ||
| 308 | p = s->s3->tmp.key_block; | 313 | memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, |
| 314 | 0, SSL3_SEQUENCE_SIZE); | ||
| 309 | 315 | ||
| 310 | mac_len = EVP_MD_size(mac); | 316 | mac_len = EVP_MD_size(mac); |
| 311 | key_len = EVP_CIPHER_key_length(cipher); | 317 | key_len = EVP_CIPHER_key_length(cipher); |
| @@ -317,36 +323,44 @@ ssl3_change_cipher_state(SSL *s, int which) | |||
| 317 | if (is_export && | 323 | if (is_export && |
| 318 | key_len > SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) | 324 | key_len > SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) |
| 319 | key_len = SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher); | 325 | key_len = SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher); |
| 320 | 326 | ||
| 321 | if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || | 327 | key_block = s->s3->tmp.key_block; |
| 322 | (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { | 328 | client_write_mac_secret = key_block; |
| 323 | ms = &(p[0]); | 329 | key_block += mac_len; |
| 324 | n = mac_len + mac_len; | 330 | server_write_mac_secret = key_block; |
| 325 | key = &(p[n]); | 331 | key_block += mac_len; |
| 326 | n += key_len + key_len; | 332 | client_write_key = key_block; |
| 327 | iv = &(p[n]); | 333 | key_block += key_len; |
| 328 | n += iv_len + iv_len; | 334 | server_write_key = key_block; |
| 335 | key_block += key_len; | ||
| 336 | client_write_iv = key_block; | ||
| 337 | key_block += iv_len; | ||
| 338 | server_write_iv = key_block; | ||
| 339 | key_block += iv_len; | ||
| 340 | |||
| 341 | if (use_client_keys) { | ||
| 342 | mac_secret = client_write_mac_secret; | ||
| 343 | key = client_write_key; | ||
| 344 | iv = client_write_iv; | ||
| 329 | er1 = s->s3->client_random; | 345 | er1 = s->s3->client_random; |
| 330 | er2 = s->s3->server_random; | 346 | er2 = s->s3->server_random; |
| 331 | } else { | 347 | } else { |
| 332 | n = mac_len; | 348 | mac_secret = server_write_mac_secret; |
| 333 | ms = &(p[n]); | 349 | key = server_write_key; |
| 334 | n += mac_len + key_len; | 350 | iv = server_write_iv; |
| 335 | key = &(p[n]); | ||
| 336 | n += key_len + iv_len; | ||
| 337 | iv = &(p[n]); | ||
| 338 | n += iv_len; | ||
| 339 | er1 = s->s3->server_random; | 351 | er1 = s->s3->server_random; |
| 340 | er2 = s->s3->client_random; | 352 | er2 = s->s3->client_random; |
| 341 | } | 353 | } |
| 342 | 354 | ||
| 343 | if (n > s->s3->tmp.key_block_length) { | 355 | if (key_block - s->s3->tmp.key_block != s->s3->tmp.key_block_length) { |
| 344 | SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); | 356 | SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); |
| 345 | goto err2; | 357 | goto err2; |
| 346 | } | 358 | } |
| 347 | 359 | ||
| 360 | memcpy(is_read ? s->s3->read_mac_secret : s->s3->write_mac_secret, | ||
| 361 | mac_secret, mac_len); | ||
| 362 | |||
| 348 | EVP_MD_CTX_init(&mac_ctx); | 363 | EVP_MD_CTX_init(&mac_ctx); |
| 349 | memcpy(mac_secret, ms, mac_len); | ||
| 350 | if (is_export) { | 364 | if (is_export) { |
| 351 | /* In here I set both the read and write key/iv to the | 365 | /* In here I set both the read and write key/iv to the |
| 352 | * same value since only the correct one will be used :-). | 366 | * same value since only the correct one will be used :-). |
| @@ -367,8 +381,7 @@ ssl3_change_cipher_state(SSL *s, int which) | |||
| 367 | } | 381 | } |
| 368 | } | 382 | } |
| 369 | 383 | ||
| 370 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, | 384 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); |
| 371 | (which & SSL3_CC_WRITE)); | ||
| 372 | 385 | ||
| 373 | if (is_export) { | 386 | if (is_export) { |
| 374 | OPENSSL_cleanse(export_key, sizeof(export_key)); | 387 | OPENSSL_cleanse(export_key, sizeof(export_key)); |
