diff options
author | jsing <> | 2014-06-13 16:08:03 +0000 |
---|---|---|
committer | jsing <> | 2014-06-13 16:08:03 +0000 |
commit | 95f7ba79c246b7e31433247366b64c9529c435cd (patch) | |
tree | 7ece12b760d2820c75dfd9fda36f85a158569e5b /src | |
parent | 6b49885bdd145ec910f4078d363c2027f1d5b67a (diff) | |
download | openbsd-95f7ba79c246b7e31433247366b64c9529c435cd.tar.gz openbsd-95f7ba79c246b7e31433247366b64c9529c435cd.tar.bz2 openbsd-95f7ba79c246b7e31433247366b64c9529c435cd.zip |
Overhaul the keyblock handling in ssl3_change_cipher_state(). Use
meaningful variable names with use with pointer arithmitic rather than
complex array indexing.
Diffstat (limited to 'src')
-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)); |