OLD | NEW |
| (Empty) |
1 From d7f9af2d2682bc41e7bf1d669cda60f04630b04d Mon Sep 17 00:00:00 2001 | |
2 From: Adam Langley <agl@chromium.org> | |
3 Date: Thu, 25 Jul 2013 14:57:38 -0400 | |
4 Subject: [PATCH 39/50] tls1_change_cipher_state_rewrite | |
5 | |
6 The previous version of the function made adding AEAD changes very | |
7 difficult. This change should be a semantic no-op - it should be purely | |
8 a cleanup. | |
9 --- | |
10 ssl/ssl.h | 1 + | |
11 ssl/ssl_err.c | 2 +- | |
12 ssl/t1_enc.c | 445 +++++++++++++++++++++++++++++++--------------------------- | |
13 3 files changed, 240 insertions(+), 208 deletions(-) | |
14 | |
15 diff --git a/ssl/ssl.h b/ssl/ssl.h | |
16 index 68e5648..672f3eb 100644 | |
17 --- a/ssl/ssl.h | |
18 +++ b/ssl/ssl.h | |
19 @@ -2439,6 +2439,7 @@ void ERR_load_SSL_strings(void); | |
20 #define SSL_F_SSL_WRITE 208 | |
21 #define SSL_F_TLS1_CERT_VERIFY_MAC 286 | |
22 #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 | |
23 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER 338 | |
24 #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 | |
25 #define SSL_F_TLS1_ENC 210 | |
26 #define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 | |
27 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c | |
28 index fc98e6c..97b2a0d 100644 | |
29 --- a/ssl/ssl_err.c | |
30 +++ b/ssl/ssl_err.c | |
31 @@ -280,7 +280,7 @@ static ERR_STRING_DATA SSL_str_functs[]= | |
32 {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "SSL_VERIFY_CERT_CHAIN"}, | |
33 {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, | |
34 {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, | |
35 -{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"}, | |
36 +{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER), "TLS1_CHANGE_CIPHER_STAT
E_CIPHER"}, | |
37 {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_
TLSEXT"}, | |
38 {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, | |
39 {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "TLS1_EXPORT_KEYING_MATERIAL"}, | |
40 diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c | |
41 index 3649544..e1f91ba 100644 | |
42 --- a/ssl/t1_enc.c | |
43 +++ b/ssl/t1_enc.c | |
44 @@ -316,56 +316,30 @@ static int tls1_generate_key_block(SSL *s, unsigned char *
km, | |
45 return ret; | |
46 } | |
47 | |
48 -int tls1_change_cipher_state(SSL *s, int which) | |
49 +/* tls1_change_cipher_state_cipher performs the work needed to switch cipher | |
50 + * states when using EVP_CIPHER. The argument |is_read| is true iff this | |
51 + * function is being called due to reading, as opposed to writing, a | |
52 + * ChangeCipherSpec message. In order to support export ciphersuites, | |
53 + * use_client_keys indicates whether the key material provided is in the | |
54 + * "client write" direction. */ | |
55 +static int tls1_change_cipher_state_cipher( | |
56 + SSL *s, char is_read, char use_client_keys, | |
57 + const unsigned char *mac_secret, unsigned mac_secret_len, | |
58 + const unsigned char *key, unsigned key_len, | |
59 + const unsigned char *iv, unsigned iv_len) | |
60 { | |
61 - static const unsigned char empty[]=""; | |
62 - unsigned char *p,*mac_secret; | |
63 - unsigned char *exp_label; | |
64 - unsigned char tmp1[EVP_MAX_KEY_LENGTH]; | |
65 - unsigned char tmp2[EVP_MAX_KEY_LENGTH]; | |
66 - unsigned char iv1[EVP_MAX_IV_LENGTH*2]; | |
67 - unsigned char iv2[EVP_MAX_IV_LENGTH*2]; | |
68 - unsigned char *ms,*key,*iv; | |
69 - int client_write; | |
70 - EVP_CIPHER_CTX *dd; | |
71 - const EVP_CIPHER *c; | |
72 -#ifndef OPENSSL_NO_COMP | |
73 - const SSL_COMP *comp; | |
74 -#endif | |
75 - const EVP_MD *m; | |
76 - int mac_type; | |
77 - int *mac_secret_size; | |
78 + const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc; | |
79 + const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0; | |
80 + EVP_CIPHER_CTX *cipher_ctx; | |
81 EVP_MD_CTX *mac_ctx; | |
82 - EVP_PKEY *mac_key; | |
83 - int is_export,n,i,j,k,exp_label_len,cl; | |
84 - int reuse_dd = 0; | |
85 + char is_aead_cipher; | |
86 | |
87 - is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); | |
88 - c=s->s3->tmp.new_sym_enc; | |
89 - m=s->s3->tmp.new_hash; | |
90 - mac_type = s->s3->tmp.new_mac_pkey_type; | |
91 -#ifndef OPENSSL_NO_COMP | |
92 - comp=s->s3->tmp.new_compression; | |
93 -#endif | |
94 + unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; | |
95 + unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; | |
96 + unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2]; | |
97 + unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2]; | |
98 | |
99 -#ifdef KSSL_DEBUG | |
100 - printf("tls1_change_cipher_state(which= %d) w/\n", which); | |
101 - printf("\talg= %ld/%ld, comp= %p\n", | |
102 - s->s3->tmp.new_cipher->algorithm_mkey, | |
103 - s->s3->tmp.new_cipher->algorithm_auth, | |
104 - comp); | |
105 - printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); | |
106 - printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", | |
107 - c->nid,c->block_size,c->key_len,c->iv_len); | |
108 - printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); | |
109 - { | |
110 - int i; | |
111 - for (i=0; i<s->s3->tmp.key_block_length; i++) | |
112 - printf("%02x", s->s3->tmp.key_block[i]); printf("\n"); | |
113 - } | |
114 -#endif /* KSSL_DEBUG */ | |
115 - | |
116 - if (which & SSL3_CC_READ) | |
117 + if (is_read) | |
118 { | |
119 if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | |
120 s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | |
121 @@ -373,206 +347,257 @@ int tls1_change_cipher_state(SSL *s, int which) | |
122 s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | |
123 | |
124 if (s->enc_read_ctx != NULL) | |
125 - reuse_dd = 1; | |
126 + EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); | |
127 else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))
) == NULL) | |
128 goto err; | |
129 else | |
130 /* make sure it's intialized in case we exit later with
an error */ | |
131 EVP_CIPHER_CTX_init(s->enc_read_ctx); | |
132 - dd= s->enc_read_ctx; | |
133 - mac_ctx=ssl_replace_hash(&s->read_hash,NULL); | |
134 -#ifndef OPENSSL_NO_COMP | |
135 - if (s->expand != NULL) | |
136 - { | |
137 - COMP_CTX_free(s->expand); | |
138 - s->expand=NULL; | |
139 - } | |
140 - if (comp != NULL) | |
141 - { | |
142 - s->expand=COMP_CTX_new(comp->method); | |
143 - if (s->expand == NULL) | |
144 - { | |
145 - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMP
RESSION_LIBRARY_ERROR); | |
146 - goto err2; | |
147 - } | |
148 - if (s->s3->rrec.comp == NULL) | |
149 - s->s3->rrec.comp=(unsigned char *) | |
150 - OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LEN
GTH); | |
151 - if (s->s3->rrec.comp == NULL) | |
152 - goto err; | |
153 - } | |
154 -#endif | |
155 - /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ | |
156 - if (s->version != DTLS1_VERSION) | |
157 - memset(&(s->s3->read_sequence[0]),0,8); | |
158 - mac_secret= &(s->s3->read_mac_secret[0]); | |
159 - mac_secret_size=&(s->s3->read_mac_secret_size); | |
160 + | |
161 + cipher_ctx = s->enc_read_ctx; | |
162 + mac_ctx = ssl_replace_hash(&s->read_hash, NULL); | |
163 + | |
164 + memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len); | |
165 + s->s3->read_mac_secret_size = mac_secret_len; | |
166 } | |
167 else | |
168 { | |
169 if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) | |
170 s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | |
171 - else | |
172 + else | |
173 s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | |
174 + | |
175 if (s->enc_write_ctx != NULL) | |
176 - reuse_dd = 1; | |
177 + EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); | |
178 else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)
)) == NULL) | |
179 goto err; | |
180 else | |
181 /* make sure it's intialized in case we exit later with
an error */ | |
182 EVP_CIPHER_CTX_init(s->enc_write_ctx); | |
183 - dd= s->enc_write_ctx; | |
184 - mac_ctx = ssl_replace_hash(&s->write_hash,NULL); | |
185 -#ifndef OPENSSL_NO_COMP | |
186 - if (s->compress != NULL) | |
187 - { | |
188 - COMP_CTX_free(s->compress); | |
189 - s->compress=NULL; | |
190 - } | |
191 - if (comp != NULL) | |
192 - { | |
193 - s->compress=COMP_CTX_new(comp->method); | |
194 - if (s->compress == NULL) | |
195 - { | |
196 - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMP
RESSION_LIBRARY_ERROR); | |
197 - goto err2; | |
198 - } | |
199 - } | |
200 -#endif | |
201 - /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ | |
202 - if (s->version != DTLS1_VERSION) | |
203 - memset(&(s->s3->write_sequence[0]),0,8); | |
204 - mac_secret= &(s->s3->write_mac_secret[0]); | |
205 - mac_secret_size = &(s->s3->write_mac_secret_size); | |
206 - } | |
207 - | |
208 - if (reuse_dd) | |
209 - EVP_CIPHER_CTX_cleanup(dd); | |
210 | |
211 - p=s->s3->tmp.key_block; | |
212 - i=*mac_secret_size=s->s3->tmp.new_mac_secret_size; | |
213 + cipher_ctx = s->enc_write_ctx; | |
214 + mac_ctx = ssl_replace_hash(&s->write_hash, NULL); | |
215 | |
216 - cl=EVP_CIPHER_key_length(c); | |
217 - j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? | |
218 - cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; | |
219 - /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ | |
220 - /* If GCM mode only part of IV comes from PRF */ | |
221 - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) | |
222 - k = EVP_GCM_TLS_FIXED_IV_LEN; | |
223 - else | |
224 - k=EVP_CIPHER_iv_length(c); | |
225 - if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || | |
226 - (which == SSL3_CHANGE_CIPHER_SERVER_READ)) | |
227 - { | |
228 - ms= &(p[ 0]); n=i+i; | |
229 - key= &(p[ n]); n+=j+j; | |
230 - iv= &(p[ n]); n+=k+k; | |
231 - exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; | |
232 - exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; | |
233 - client_write=1; | |
234 - } | |
235 - else | |
236 - { | |
237 - n=i; | |
238 - ms= &(p[ n]); n+=i+j; | |
239 - key= &(p[ n]); n+=j+k; | |
240 - iv= &(p[ n]); n+=k; | |
241 - exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; | |
242 - exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; | |
243 - client_write=0; | |
244 + memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len); | |
245 + s->s3->write_mac_secret_size = mac_secret_len; | |
246 } | |
247 | |
248 - if (n > s->s3->tmp.key_block_length) | |
249 - { | |
250 - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); | |
251 - goto err2; | |
252 - } | |
253 - | |
254 - memcpy(mac_secret,ms,i); | |
255 - | |
256 - if (!(EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER)) | |
257 - { | |
258 - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, | |
259 - mac_secret,*mac_secret_size); | |
260 - EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key); | |
261 - EVP_PKEY_free(mac_key); | |
262 - } | |
263 -#ifdef TLS_DEBUG | |
264 -printf("which = %04X\nmac key=",which); | |
265 -{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } | |
266 -#endif | |
267 if (is_export) | |
268 { | |
269 /* In here I set both the read and write key/iv to the | |
270 * same value since only the correct one will be used :-). | |
271 */ | |
272 + const unsigned char *label; | |
273 + unsigned label_len; | |
274 + | |
275 + if (use_client_keys) | |
276 + { | |
277 + label = (const unsigned char*) TLS_MD_CLIENT_WRITE_KEY_C
ONST; | |
278 + label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; | |
279 + } | |
280 + else | |
281 + { | |
282 + label = (const unsigned char*) TLS_MD_SERVER_WRITE_KEY_C
ONST; | |
283 + label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; | |
284 + } | |
285 + | |
286 if (!tls1_PRF(ssl_get_algorithm2(s), | |
287 - exp_label,exp_label_len, | |
288 - s->s3->client_random,SSL3_RANDOM_SIZE, | |
289 - s->s3->server_random,SSL3_RANDOM_SIZE, | |
290 - NULL,0,NULL,0, | |
291 - key,j,tmp1,tmp2,EVP_CIPHER_key_length(c))) | |
292 - goto err2; | |
293 - key=tmp1; | |
294 + label, label_len, | |
295 + s->s3->client_random, SSL3_RANDOM_SIZE, | |
296 + s->s3->server_random, SSL3_RANDOM_SIZE, | |
297 + NULL, 0, NULL, 0, | |
298 + key /* secret */, key_len /* secret length */, | |
299 + export_tmp1 /* output */, | |
300 + export_tmp2 /* scratch space */, | |
301 + EVP_CIPHER_key_length(s->s3->tmp.new_sym_enc) /*
output length */)) | |
302 + return 0; | |
303 + key = export_tmp1; | |
304 | |
305 - if (k > 0) | |
306 + if (iv_len > 0) | |
307 { | |
308 + static const unsigned char empty[] = ""; | |
309 + | |
310 if (!tls1_PRF(ssl_get_algorithm2(s), | |
311 - TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CO
NST_SIZE, | |
312 - s->s3->client_random,SSL3_RANDOM_SIZE, | |
313 - s->s3->server_random,SSL3_RANDOM_SIZE, | |
314 - NULL,0,NULL,0, | |
315 - empty,0,iv1,iv2,k*2)) | |
316 - goto err2; | |
317 - if (client_write) | |
318 - iv=iv1; | |
319 + TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_C
ONST_SIZE, | |
320 + s->s3->client_random, SSL3_RANDOM_SIZE, | |
321 + s->s3->server_random, SSL3_RANDOM_SIZE, | |
322 + NULL, 0, NULL, 0, | |
323 + empty /* secret */ ,0 /* secret length *
/, | |
324 + export_iv1 /* output */, | |
325 + export_iv2 /* scratch space */, | |
326 + iv_len * 2 /* output length */)) | |
327 + return 0; | |
328 + | |
329 + if (use_client_keys) | |
330 + iv = export_iv1; | |
331 else | |
332 - iv= &(iv1[k]); | |
333 + iv = &export_iv1[iv_len]; | |
334 } | |
335 } | |
336 | |
337 - s->session->key_arg_length=0; | |
338 -#ifdef KSSL_DEBUG | |
339 - { | |
340 - int i; | |
341 - printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); | |
342 - printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]); | |
343 - printf("\n"); | |
344 - printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]); | |
345 - printf("\n"); | |
346 - } | |
347 -#endif /* KSSL_DEBUG */ | |
348 + /* is_aead_cipher indicates whether the EVP_CIPHER implements an AEAD | |
349 + * interface. This is different from the newer EVP_AEAD interface. */ | |
350 + is_aead_cipher = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
!= 0; | |
351 | |
352 - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) | |
353 + if (!is_aead_cipher) | |
354 { | |
355 - EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE)); | |
356 - EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv); | |
357 + EVP_PKEY *mac_key = | |
358 + EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, | |
359 + NULL, mac_secret, mac_secret_len); | |
360 + if (!mac_key) | |
361 + return 0; | |
362 + EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac
_key); | |
363 + EVP_PKEY_free(mac_key); | |
364 } | |
365 - else | |
366 - EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); | |
367 + | |
368 + if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) | |
369 + { | |
370 + EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, | |
371 + NULL /* iv */, !is_read); | |
372 + EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, iv_le
n, (void*) iv); | |
373 + } | |
374 + else | |
375 + EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv
, !is_read); | |
376 | |
377 /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ | |
378 - if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size) | |
379 - EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY, | |
380 - *mac_secret_size,mac_secret); | |
381 - | |
382 -#ifdef TLS_DEBUG | |
383 -printf("which = %04X\nkey=",which); | |
384 -{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+
1)%16)?' ':'\n'); } | |
385 -printf("\niv="); | |
386 -{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } | |
387 -printf("\n"); | |
388 -#endif | |
389 - | |
390 - OPENSSL_cleanse(tmp1,sizeof(tmp1)); | |
391 - OPENSSL_cleanse(tmp2,sizeof(tmp1)); | |
392 - OPENSSL_cleanse(iv1,sizeof(iv1)); | |
393 - OPENSSL_cleanse(iv2,sizeof(iv2)); | |
394 - return(1); | |
395 + if (is_aead_cipher && mac_secret_len > 0) | |
396 + EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, | |
397 + mac_secret_len, (void*) mac_secret); | |
398 + | |
399 + if (is_export) | |
400 + { | |
401 + OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1)); | |
402 + OPENSSL_cleanse(export_tmp2, sizeof(export_tmp1)); | |
403 + OPENSSL_cleanse(export_iv1, sizeof(export_iv1)); | |
404 + OPENSSL_cleanse(export_iv2, sizeof(export_iv2)); | |
405 + } | |
406 + | |
407 + return 1; | |
408 + | |
409 +err: | |
410 + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE); | |
411 + return 0; | |
412 + } | |
413 + | |
414 +int tls1_change_cipher_state(SSL *s, int which) | |
415 + { | |
416 + /* is_read is true if we have just read a ChangeCipherSpec message - | |
417 + * i.e. we need to update the read cipherspec. Otherwise we have just | |
418 + * written one. */ | |
419 + const char is_read = (which & SSL3_CC_READ) != 0; | |
420 + /* use_client_keys is true if we wish to use the keys for the "client | |
421 + * write" direction. This is the case if we're a client sending a | |
422 + * ChangeCipherSpec, or a server reading a client's ChangeCipherSpec. */ | |
423 + const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE || | |
424 + which == SSL3_CHANGE_CIPHER_SERVER_READ; | |
425 + const unsigned char *client_write_mac_secret, *server_write_mac_secret,
*mac_secret; | |
426 + const unsigned char *client_write_key, *server_write_key, *key; | |
427 + const unsigned char *client_write_iv, *server_write_iv, *iv; | |
428 + const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc; | |
429 + unsigned key_len, iv_len, mac_secret_len; | |
430 + const unsigned char *key_data; | |
431 + const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0; | |
432 + | |
433 + /* Update compression contexts. */ | |
434 +#ifndef OPENSSL_NO_COMP | |
435 + const SSL_COMP *comp = s->s3->tmp.new_compression; | |
436 + | |
437 + if (is_read) | |
438 + { | |
439 + if (s->expand != NULL) | |
440 + { | |
441 + COMP_CTX_free(s->expand); | |
442 + s->expand = NULL; | |
443 + } | |
444 + if (comp != NULL) | |
445 + { | |
446 + s->expand=COMP_CTX_new(comp->method); | |
447 + if (s->expand == NULL) | |
448 + { | |
449 + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMP
RESSION_LIBRARY_ERROR); | |
450 + return 0; | |
451 + } | |
452 + if (s->s3->rrec.comp == NULL) | |
453 + s->s3->rrec.comp = | |
454 + (unsigned char *)OPENSSL_malloc(SSL3_RT_
MAX_ENCRYPTED_LENGTH); | |
455 + if (s->s3->rrec.comp == NULL) | |
456 + goto err; | |
457 + } | |
458 + } | |
459 + else | |
460 + { | |
461 + if (s->compress != NULL) | |
462 + { | |
463 + COMP_CTX_free(s->compress); | |
464 + s->compress = NULL; | |
465 + } | |
466 + if (comp != NULL) | |
467 + { | |
468 + s->compress = COMP_CTX_new(comp->method); | |
469 + if (s->compress == NULL) | |
470 + { | |
471 + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMP
RESSION_LIBRARY_ERROR); | |
472 + return 0; | |
473 + } | |
474 + } | |
475 + } | |
476 +#endif /* OPENSSL_NO_COMP */ | |
477 + | |
478 + /* Reset sequence number to zero. */ | |
479 + memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8); | |
480 + | |
481 + /* key_arg is used for SSLv2. We don't need it for TLS. */ | |
482 + s->session->key_arg_length = 0; | |
483 + | |
484 + mac_secret_len = s->s3->tmp.new_mac_secret_size; | |
485 + | |
486 + key_len = EVP_CIPHER_key_length(cipher); | |
487 + if (is_export && key_len > SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)
) | |
488 + key_len = SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher); | |
489 + | |
490 + if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) | |
491 + iv_len = EVP_GCM_TLS_FIXED_IV_LEN; | |
492 + else | |
493 + iv_len = EVP_CIPHER_iv_length(cipher); | |
494 + | |
495 + key_data = s->s3->tmp.key_block; | |
496 + client_write_mac_secret = key_data; key_data += mac_secret_len; | |
497 + server_write_mac_secret = key_data; key_data += mac_secret_len; | |
498 + client_write_key = key_data; key_data += key_len; | |
499 + server_write_key = key_data; key_data += key_len; | |
500 + client_write_iv = key_data; key_data += iv_len; | |
501 + server_write_iv = key_data; key_data += iv_len; | |
502 + | |
503 + if (use_client_keys) | |
504 + { | |
505 + mac_secret = client_write_mac_secret; | |
506 + key = client_write_key; | |
507 + iv = client_write_iv; | |
508 + } | |
509 + else | |
510 + { | |
511 + mac_secret = server_write_mac_secret; | |
512 + key = server_write_key; | |
513 + iv = server_write_iv; | |
514 + } | |
515 + | |
516 + if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) | |
517 + { | |
518 + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); | |
519 + return 0; | |
520 + } | |
521 + | |
522 + if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys, | |
523 + mac_secret, mac_secret_len, | |
524 + key, key_len, | |
525 + iv, iv_len)) { | |
526 + return 0; | |
527 + } | |
528 + | |
529 + return 1; | |
530 err: | |
531 - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); | |
532 -err2: | |
533 - return(0); | |
534 + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); | |
535 + return 0; | |
536 } | |
537 | |
538 int tls1_setup_key_block(SSL *s) | |
539 @@ -584,6 +609,7 @@ int tls1_setup_key_block(SSL *s) | |
540 SSL_COMP *comp; | |
541 int mac_type= NID_undef,mac_secret_size=0; | |
542 int ret=0; | |
543 + int iv_len; | |
544 | |
545 #ifdef KSSL_DEBUG | |
546 printf ("tls1_setup_key_block()\n"); | |
547 @@ -598,11 +624,16 @@ int tls1_setup_key_block(SSL *s) | |
548 return(0); | |
549 } | |
550 | |
551 + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) | |
552 + iv_len = EVP_GCM_TLS_FIXED_IV_LEN; | |
553 + else | |
554 + iv_len = EVP_CIPHER_iv_length(c); | |
555 + | |
556 s->s3->tmp.new_sym_enc=c; | |
557 s->s3->tmp.new_hash=hash; | |
558 s->s3->tmp.new_mac_pkey_type = mac_type; | |
559 s->s3->tmp.new_mac_secret_size = mac_secret_size; | |
560 - num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c); | |
561 + num=EVP_CIPHER_key_length(c)+mac_secret_size+iv_len; | |
562 num*=2; | |
563 | |
564 ssl3_cleanup_key_block(s); | |
565 -- | |
566 1.8.4.1 | |
567 | |
OLD | NEW |