| 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 |