bug 1271350 - work around PK11_CreatePBEV2AlgorithmID generating a random salt when it shouldn't r?ttaubert
MozReview-Commit-ID: KHjiwPg2SBb
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -2779,16 +2779,28 @@ private:
{
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!arena) {
return NS_ERROR_DOM_OPERATION_ERR;
}
SECItem salt = { siBuffer, nullptr, 0 };
ATTEMPT_BUFFER_TO_SECITEM(arena, &salt, mSalt);
+ // PK11_CreatePBEV2AlgorithmID will "helpfully" create PBKDF2 parameters
+ // with a random salt if given a SECItem* that is either null or has a null
+ // data pointer. This obviously isn't what we want, so we have to fake it
+ // out by passing in a SECItem* with a non-null data pointer but with zero
+ // length.
+ if (!salt.data) {
+ MOZ_ASSERT(salt.len == 0);
+ salt.data = reinterpret_cast<unsigned char*>(PORT_ArenaAlloc(arena, 1));
+ if (!salt.data) {
+ return NS_ERROR_DOM_UNKNOWN_ERR;
+ }
+ }
// Always pass in cipherAlg=SEC_OID_HMAC_SHA1 (i.e. PBMAC1) as this
// parameter is unused for key generation. It is currently only used
// for PBKDF2 authentication or key (un)wrapping when specifying an
// encryption algorithm (PBES2).
ScopedSECAlgorithmID alg_id(PK11_CreatePBEV2AlgorithmID(
SEC_OID_PKCS5_PBKDF2, SEC_OID_HMAC_SHA1, mHashOidTag,
mLength, mIterations, &salt));
--- a/dom/crypto/test/test-vectors.js
+++ b/dom/crypto/test/test-vectors.js
@@ -644,16 +644,26 @@ tv = {
length: 40 * 8,
derived: util.hex2abv(
"348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1" +
"c635518c7dac47e9"
)
},
+ pbkdf2_sha256_no_salt: {
+ password: util.hex2abv(
+ "9c13a23bc58a52be8bb4fa1a2cbdff01747265736f7269745f64625f7265636f72645f6964"),
+ length: 32 * 8,
+ iterations: 1,
+
+ derived: util.hex2abv(
+ "ef29dd382fa66a83a95be7ccfb71f1ccfee494977855a4c260d90c2f8c91e062")
+ },
+
broken_pkcs8: {
// A DH key with parameters p and g, and a private value.
// This currently fails the key import due to the missing public value.
// <https://stackoverflow.com/questions/6032675/diffie-hellman-test-vectors>
dh: util.hex2abv(
"308201340201003082011506072a8648ce3e02013082010802818100da3a8085" +
"d372437805de95b88b675122f575df976610c6a844de99f1df82a06848bf7a42" +
"f18895c97402e81118e01a00d0855d51922f434c022350861d58ddf60d65bc69" +
--- a/dom/crypto/test/test_WebCrypto_PBKDF2.html
+++ b/dom/crypto/test/test_WebCrypto_PBKDF2.html
@@ -227,16 +227,45 @@ TestArray.addTest(
}
function fail(x) { console.log("failing"); error(that)(x); }
crypto.subtle.importKey("raw", key, alg, false, ["deriveBits"])
.then( doDerive, fail )
.then( memcmp_complete(that, tv.pbkdf2_sha256.derived), fail );
}
);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Import raw PBKDF2 key and derive bits using HMAC-SHA-256 with zero-length salt",
+ function() {
+ var that = this;
+ var importAlg = { name: "PBKDF2", hash: "SHA-256" };
+ var key = tv.pbkdf2_sha256_no_salt.password;
+
+ function doDerive(x) {
+ if (!hasKeyFields(x)) {
+ throw "Invalid key; missing field(s)";
+ }
+
+ var deriveAlg = {
+ name: "PBKDF2",
+ hash: "SHA-256",
+ salt: new Uint8Array(0),
+ iterations: tv.pbkdf2_sha256_no_salt.iterations
+ };
+ return crypto.subtle.deriveBits(deriveAlg, x, tv.pbkdf2_sha256_no_salt.length);
+ }
+ function fail(x) { console.log("failing"); error(that)(x); }
+
+ crypto.subtle.importKey("raw", key, importAlg, false, ["deriveBits"])
+ .then( doDerive, fail )
+ .then( memcmp_complete(that, tv.pbkdf2_sha256_no_salt.derived), fail );
+ }
+);
/*]]>*/</script>
</head>
<body>
<div id="content">
<div id="head">
<b>Web</b>Crypto<br>