OLD | NEW |
1 /* | 1 /* |
2 * Key Derivation that doesn't use PKCS11 | 2 * Key Derivation that doesn't use PKCS11 |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 /* $Id$ */ | 7 /* $Id$ */ |
8 | 8 |
9 #include "ssl.h" /* prereq to sslimpl.h */ | 9 #include "ssl.h" /* prereq to sslimpl.h */ |
10 #include "certt.h" /* prereq to sslimpl.h */ | 10 #include "certt.h" /* prereq to sslimpl.h */ |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; | 75 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; |
76 unsigned char * key_block = pwSpec->key_block; | 76 unsigned char * key_block = pwSpec->key_block; |
77 unsigned char * key_block2 = NULL; | 77 unsigned char * key_block2 = NULL; |
78 unsigned int block_bytes = 0; | 78 unsigned int block_bytes = 0; |
79 unsigned int block_needed = 0; | 79 unsigned int block_needed = 0; |
80 unsigned int i; | 80 unsigned int i; |
81 unsigned int keySize; /* actual size of cipher keys */ | 81 unsigned int keySize; /* actual size of cipher keys */ |
82 unsigned int effKeySize; /* effective size of cipher keys */ | 82 unsigned int effKeySize; /* effective size of cipher keys */ |
83 unsigned int macSize; /* size of MAC secret */ | 83 unsigned int macSize; /* size of MAC secret */ |
84 unsigned int IVSize; /* size of IV */ | 84 unsigned int IVSize; /* size of IV */ |
| 85 PRBool explicitIV = PR_FALSE; |
85 SECStatus rv = SECFailure; | 86 SECStatus rv = SECFailure; |
86 SECStatus status = SECSuccess; | 87 SECStatus status = SECSuccess; |
87 PRBool isFIPS = PR_FALSE; | 88 PRBool isFIPS = PR_FALSE; |
| 89 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; |
88 | 90 |
89 SECItem srcr; | 91 SECItem srcr; |
90 SECItem crsr; | 92 SECItem crsr; |
91 | 93 |
92 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; | 94 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; |
93 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; | 95 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
94 PRUint64 md5buf[22]; | 96 PRUint64 md5buf[22]; |
95 PRUint64 shabuf[40]; | 97 PRUint64 shabuf[40]; |
96 | 98 |
97 #define md5Ctx ((MD5Context *)md5buf) | 99 #define md5Ctx ((MD5Context *)md5buf) |
(...skipping 11 matching lines...) Expand all Loading... |
109 pwSpec->msItem.len)); | 111 pwSpec->msItem.len)); |
110 | 112 |
111 /* figure out how much is needed */ | 113 /* figure out how much is needed */ |
112 macSize = pwSpec->mac_size; | 114 macSize = pwSpec->mac_size; |
113 keySize = cipher_def->key_size; | 115 keySize = cipher_def->key_size; |
114 effKeySize = cipher_def->secret_key_size; | 116 effKeySize = cipher_def->secret_key_size; |
115 IVSize = cipher_def->iv_size; | 117 IVSize = cipher_def->iv_size; |
116 if (keySize == 0) { | 118 if (keySize == 0) { |
117 effKeySize = IVSize = 0; /* only MACing */ | 119 effKeySize = IVSize = 0; /* only MACing */ |
118 } | 120 } |
119 block_needed = 2 * (macSize + effKeySize + ((!isExport) * IVSize)); | 121 if (cipher_def->type == type_block && |
| 122 » pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { |
| 123 » /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ |
| 124 » explicitIV = PR_TRUE; |
| 125 } |
| 126 block_needed = |
| 127 » 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * IVSize)); |
120 | 128 |
121 /* | 129 /* |
122 * clear out our returned keys so we can recover on failure | 130 * clear out our returned keys so we can recover on failure |
123 */ | 131 */ |
124 pwSpec->client.write_key_item = zed; | 132 pwSpec->client.write_key_item = zed; |
125 pwSpec->client.write_mac_key_item = zed; | 133 pwSpec->client.write_mac_key_item = zed; |
126 pwSpec->server.write_key_item = zed; | 134 pwSpec->server.write_key_item = zed; |
127 pwSpec->server.write_mac_key_item = zed; | 135 pwSpec->server.write_mac_key_item = zed; |
128 | 136 |
129 /* initialize the server random, client random block */ | 137 /* initialize the server random, client random block */ |
(...skipping 14 matching lines...) Expand all Loading... |
144 /* | 152 /* |
145 * generate the key material: | 153 * generate the key material: |
146 */ | 154 */ |
147 if (isTLS) { | 155 if (isTLS) { |
148 SECItem keyblk; | 156 SECItem keyblk; |
149 | 157 |
150 keyblk.type = siBuffer; | 158 keyblk.type = siBuffer; |
151 keyblk.data = key_block; | 159 keyblk.data = key_block; |
152 keyblk.len = block_needed; | 160 keyblk.len = block_needed; |
153 | 161 |
154 » status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk, | 162 » if (isTLS12) { |
155 » » » isFIPS); | 163 » status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem, |
| 164 » » » » "key expansion", &srcr, &keyblk, isFIPS); |
| 165 » } else { |
| 166 » status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk, |
| 167 » » » isFIPS); |
| 168 » } |
156 if (status != SECSuccess) { | 169 if (status != SECSuccess) { |
157 goto key_and_mac_derive_fail; | 170 goto key_and_mac_derive_fail; |
158 } | 171 } |
159 block_bytes = keyblk.len; | 172 block_bytes = keyblk.len; |
160 } else { | 173 } else { |
161 /* key_block = | 174 /* key_block = |
162 * MD5(master_secret + SHA('A' + master_secret + | 175 * MD5(master_secret + SHA('A' + master_secret + |
163 * ServerHello.random + ClientHello.random)) + | 176 * ServerHello.random + ClientHello.random)) + |
164 * MD5(master_secret + SHA('BB' + master_secret + | 177 * MD5(master_secret + SHA('BB' + master_secret + |
165 * ServerHello.random + ClientHello.random)) + | 178 * ServerHello.random + ClientHello.random)) + |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 i += keySize; | 246 i += keySize; |
234 | 247 |
235 /* | 248 /* |
236 ** server_write_key[CipherSpec.key_material] | 249 ** server_write_key[CipherSpec.key_material] |
237 */ | 250 */ |
238 buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, \ | 251 buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, \ |
239 "Domestic Server Write Key"); | 252 "Domestic Server Write Key"); |
240 i += keySize; | 253 i += keySize; |
241 | 254 |
242 if (IVSize > 0) { | 255 if (IVSize > 0) { |
243 » /* | 256 » if (explicitIV) { |
244 » ** client_write_IV[CipherSpec.IV_size] | 257 » » static unsigned char zero_block[32]; |
245 » */ | 258 » » PORT_Assert(IVSize <= sizeof zero_block); |
246 » buildSSLKey(&key_block[i], IVSize, &pwSpec->client.write_iv_item, \ | 259 » » buildSSLKey(&zero_block[0], IVSize, \ |
247 » "Domestic Client Write IV"); | 260 » » » &pwSpec->client.write_iv_item, \ |
248 » i += IVSize; | 261 » » » "Domestic Client Write IV"); |
| 262 » » buildSSLKey(&zero_block[0], IVSize, \ |
| 263 » » » &pwSpec->server.write_iv_item, \ |
| 264 » » » "Domestic Server Write IV"); |
| 265 » } else { |
| 266 » » /* |
| 267 » » ** client_write_IV[CipherSpec.IV_size] |
| 268 » » */ |
| 269 » » buildSSLKey(&key_block[i], IVSize, \ |
| 270 » » » &pwSpec->client.write_iv_item, \ |
| 271 » » » "Domestic Client Write IV"); |
| 272 » » i += IVSize; |
249 | 273 |
250 » /* | 274 » » /* |
251 » ** server_write_IV[CipherSpec.IV_size] | 275 » » ** server_write_IV[CipherSpec.IV_size] |
252 » */ | 276 » » */ |
253 » buildSSLKey(&key_block[i], IVSize, &pwSpec->server.write_iv_item, \ | 277 » » buildSSLKey(&key_block[i], IVSize, \ |
254 » "Domestic Server Write IV"); | 278 » » » &pwSpec->server.write_iv_item, \ |
255 » i += IVSize; | 279 » » » "Domestic Server Write IV"); |
| 280 » » i += IVSize; |
| 281 » } |
256 } | 282 } |
257 PORT_Assert(i <= block_bytes); | 283 PORT_Assert(i <= block_bytes); |
258 | |
259 } else if (!isTLS) { | 284 } else if (!isTLS) { |
260 /* | 285 /* |
261 ** Generate SSL3 Export write keys and IVs. | 286 ** Generate SSL3 Export write keys and IVs. |
262 */ | 287 */ |
263 unsigned int outLen; | 288 unsigned int outLen; |
264 | 289 |
265 /* | 290 /* |
266 ** client_write_key[CipherSpec.key_material] | 291 ** client_write_key[CipherSpec.key_material] |
267 ** final_client_write_key = MD5(client_write_key + | 292 ** final_client_write_key = MD5(client_write_key + |
268 ** ClientHello.random + ServerHello.random); | 293 ** ClientHello.random + ServerHello.random); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 ssl3CipherSpec * pwSpec, | 436 ssl3CipherSpec * pwSpec, |
412 const unsigned char * cr, | 437 const unsigned char * cr, |
413 const unsigned char * sr, | 438 const unsigned char * sr, |
414 const SECItem * pms, | 439 const SECItem * pms, |
415 PRBool isTLS, | 440 PRBool isTLS, |
416 PRBool isRSA) | 441 PRBool isRSA) |
417 { | 442 { |
418 unsigned char * key_block = pwSpec->key_block; | 443 unsigned char * key_block = pwSpec->key_block; |
419 SECStatus rv = SECSuccess; | 444 SECStatus rv = SECSuccess; |
420 PRBool isFIPS = PR_FALSE; | 445 PRBool isFIPS = PR_FALSE; |
| 446 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; |
421 | 447 |
422 SECItem crsr; | 448 SECItem crsr; |
423 | 449 |
424 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; | 450 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
425 PRUint64 md5buf[22]; | 451 PRUint64 md5buf[22]; |
426 PRUint64 shabuf[40]; | 452 PRUint64 shabuf[40]; |
427 | 453 |
428 #define md5Ctx ((MD5Context *)md5buf) | 454 #define md5Ctx ((MD5Context *)md5buf) |
429 #define shaCtx ((SHA1Context *)shabuf) | 455 #define shaCtx ((SHA1Context *)shabuf) |
430 | 456 |
(...skipping 15 matching lines...) Expand all Loading... |
446 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); | 472 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); |
447 PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); | 473 PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); |
448 | 474 |
449 /* finally do the key gen */ | 475 /* finally do the key gen */ |
450 if (isTLS) { | 476 if (isTLS) { |
451 SECItem master = { siBuffer, NULL, 0 }; | 477 SECItem master = { siBuffer, NULL, 0 }; |
452 | 478 |
453 master.data = key_block; | 479 master.data = key_block; |
454 master.len = SSL3_MASTER_SECRET_LENGTH; | 480 master.len = SSL3_MASTER_SECRET_LENGTH; |
455 | 481 |
456 » rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS); | 482 » if (isTLS12) { |
| 483 » rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr, |
| 484 » » » &master, isFIPS); |
| 485 » } else { |
| 486 » rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS); |
| 487 » } |
457 if (rv != SECSuccess) { | 488 if (rv != SECSuccess) { |
458 PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); | 489 PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
459 } | 490 } |
460 } else { | 491 } else { |
461 int i; | 492 int i; |
462 unsigned int made = 0; | 493 unsigned int made = 0; |
463 for (i = 0; i < 3; i++) { | 494 for (i = 0; i < 3; i++) { |
464 unsigned int outLen; | 495 unsigned int outLen; |
465 unsigned char sha_out[SHA1_LENGTH]; | 496 unsigned char sha_out[SHA1_LENGTH]; |
466 | 497 |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 if (srvPubkey) { | 888 if (srvPubkey) { |
858 SECKEY_DestroyPublicKey(srvPubkey); | 889 SECKEY_DestroyPublicKey(srvPubkey); |
859 srvPubkey = NULL; | 890 srvPubkey = NULL; |
860 } | 891 } |
861 | 892 |
862 | 893 |
863 return rv; | 894 return rv; |
864 #endif /* NO_PKCS11_BYPASS */ | 895 #endif /* NO_PKCS11_BYPASS */ |
865 } | 896 } |
866 | 897 |
OLD | NEW |