diff options
author | nelson%bolyard.com <devnull@localhost> | 2006-04-25 06:33:04 +0000 |
---|---|---|
committer | nelson%bolyard.com <devnull@localhost> | 2006-04-25 06:33:04 +0000 |
commit | b09621cd3dc727c8ef8332246444f59050c22296 (patch) | |
tree | b63d804928239db463530d471dee78355be471ca | |
parent | 088813a32af089cf06382728a9ec3bb9f01b0c5d (diff) | |
download | nss-hg-b09621cd3dc727c8ef8332246444f59050c22296.tar.gz |
Don't compute excessive key material for SSL3/TLS. Bug 274512.
r=julien.pierre, wtchang
-rw-r--r-- | security/nss/lib/softoken/pkcs11c.c | 139 |
1 files changed, 62 insertions, 77 deletions
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index be6202d8f..ca893afa3 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -4722,7 +4722,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, case CKM_SSL3_MASTER_KEY_DERIVE_DH: { CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master; - SSL3RSAPreMasterSecret *rsa_pms; + SSL3RSAPreMasterSecret * rsa_pms; + unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; + if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH)) isDH = PR_TRUE; @@ -4749,10 +4751,15 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, break; } - /* finally do the key gen */ ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) pMechanism->pParameter; + + PORT_Memcpy(crsrdata, + ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + if (ssl3_master->pVersion) { SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue; @@ -4775,23 +4782,16 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, } if (isTLS) { - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - SECItem crsr = { siBuffer, NULL, 0 }; - SECItem master = { siBuffer, NULL, 0 }; - SECItem pms = { siBuffer, NULL, 0 }; SECStatus status; + SECItem crsr = { siBuffer, crsrdata, sizeof crsrdata }; + SECItem master = { siBuffer, key_block, SSL3_MASTER_SECRET_LENGTH}; + SECItem pms = { siBuffer }; - pms.data = (unsigned char*)att->attrib.pValue; - pms.len = att->attrib.ulValueLen; - master.data = key_block; - master.len = SSL3_MASTER_SECRET_LENGTH; - crsr.data = crsrdata; - crsr.len = sizeof(crsrdata); - - PORT_Memcpy(crsrdata, ssl3_master->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + /* HPUX won't let a structure member be initialized with the + * value of a variable, but the address of a local variable. :-/ + */ + pms.data = (unsigned char*)att->attrib.pValue; + pms.len = att->attrib.ulValueLen; status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); if (status != SECSuccess) { @@ -4816,12 +4816,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); - SHA1_Update(sha, ssl3_master->RandomInfo.pClientRandom, - ssl3_master->RandomInfo.ulClientRandomLen); - SHA1_Update(sha, ssl3_master->RandomInfo.pServerRandom, - ssl3_master->RandomInfo.ulServerRandomLen); + SHA1_Update(sha, crsrdata, sizeof crsrdata); SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); PORT_Assert(outLen == SHA1_LENGTH); + MD5_Begin(md5); MD5_Update(md5, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); @@ -4862,6 +4860,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; CK_SSL3_KEY_MAT_OUT * ssl3_keys_out; CK_ULONG effKeySize; + unsigned int block_needed; + unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; + unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; crv = sftk_DeriveSensitiveCheck(sourceKey,key); if (crv != CKR_OK) break; @@ -4890,6 +4891,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, break; } ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter; + + PORT_Memcpy(srcrdata, + ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, + ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + + PORT_Memcpy(crsrdata, + ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + /* * clear out our returned keys so we can recover on failure */ @@ -4900,29 +4912,33 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ssl3_keys_out->hServerKey = CK_INVALID_HANDLE; /* + * How much key material do we need? + */ + macSize = ssl3_keys->ulMacSizeInBits/8; + effKeySize = ssl3_keys->ulKeySizeInBits/8; + IVSize = ssl3_keys->ulIVSizeInBits/8; + if (keySize == 0) { + effKeySize = keySize; + } + block_needed = 2 * (macSize + effKeySize + + ((!ssl3_keys->bIsExport) * IVSize)); + PORT_Assert(block_needed <= sizeof key_block); + if (block_needed > sizeof key_block) + block_needed = sizeof key_block; + + /* * generate the key material: This looks amazingly similar to the * PMS code, and is clearly crying out for a function to provide it. */ if (isTLS) { SECStatus status; - SECItem master = { siBuffer, NULL, 0 }; - SECItem srcr = { siBuffer, NULL, 0 }; - SECItem keyblk = { siBuffer, NULL, 0 }; - unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; + SECItem srcr = { siBuffer, srcrdata, sizeof srcrdata }; + SECItem keyblk = { siBuffer, key_block }; + SECItem master = { siBuffer }; + keyblk.len = block_needed; master.data = (unsigned char*)att->attrib.pValue; - master.len = att->attrib.ulValueLen; - srcr.data = srcrdata; - srcr.len = sizeof srcrdata; - keyblk.data = key_block; - keyblk.len = sizeof key_block; - - PORT_Memcpy(srcrdata, - ssl3_keys->RandomInfo.pServerRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); + master.len = att->attrib.ulValueLen; status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, isFIPS); @@ -4930,6 +4946,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, goto key_and_mac_derive_fail; } } else { + unsigned int block_bytes = 0; /* key_block = * MD5(master_secret + SHA('A' + master_secret + * ServerHello.random + ClientHello.random)) + @@ -4939,15 +4956,12 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, * ServerHello.random + ClientHello.random)) + * [...]; */ - for (i = 0; i < NUM_MIXERS; i++) { + for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) { SHA1_Begin(sha); SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); - SHA1_Update(sha, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - SHA1_Update(sha, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + SHA1_Update(sha, srcrdata, sizeof srcrdata); SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); PORT_Assert(outLen == SHA1_LENGTH); MD5_Begin(md5); @@ -4956,6 +4970,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, MD5_Update(md5, sha_out, outLen); MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH); PORT_Assert(outLen == MD5_LENGTH); + block_bytes += outLen; } } @@ -4963,12 +4978,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, * Put the key material where it goes. */ i = 0; /* now shows how much consumed */ - macSize = ssl3_keys->ulMacSizeInBits/8; - effKeySize = ssl3_keys->ulKeySizeInBits/8; - IVSize = ssl3_keys->ulIVSizeInBits/8; - if (keySize == 0) { - effKeySize = keySize; - } /* * The key_block is partitioned as follows: @@ -5043,10 +5052,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ MD5_Begin(md5); MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); + MD5_Update(md5, crsrdata, sizeof crsrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); i += effKeySize; crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, @@ -5062,10 +5068,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ MD5_Begin(md5); MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + MD5_Update(md5, srcrdata, sizeof srcrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); i += effKeySize; crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, @@ -5079,10 +5082,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ** MD5(ClientHello.random + ServerHello.random); */ MD5_Begin(md5); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); + MD5_Update(md5, crsrdata, sizeof crsrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize); @@ -5091,10 +5091,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ** MD5(ServerHello.random + ClientHello.random); */ MD5_Begin(md5); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + MD5_Update(md5, srcrdata, sizeof srcrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize); @@ -5105,20 +5102,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ SECStatus status; SECItem secret = { siBuffer, NULL, 0 }; - SECItem crsr = { siBuffer, NULL, 0 }; + SECItem crsr = { siBuffer, crsrdata, sizeof crsrdata }; SECItem keyblk = { siBuffer, NULL, 0 }; - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - - crsr.data = crsrdata; - crsr.len = sizeof crsrdata; - - PORT_Memcpy(crsrdata, - ssl3_keys->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pServerRandom, - SSL3_RANDOM_LENGTH); - /* ** client_write_key[CipherSpec.key_material] |