Bug 1050202 - Take length parameter into account when deriving HMAC keys r=rbarnes,smaug

This commit is contained in:
Tim Taubert 2014-08-07 12:52:28 +02:00
Родитель a908862519
Коммит e51e01cadd
3 изменённых файлов: 51 добавлений и 8 удалений

Просмотреть файл

@ -202,8 +202,8 @@ MapHashAlgorithmNameToBlockSize(const nsString& aName)
}
inline nsresult
GetKeySizeForAlgorithm(JSContext* aCx, const ObjectOrString& aAlgorithm,
size_t& aLength)
GetKeyLengthForAlgorithm(JSContext* aCx, const ObjectOrString& aAlgorithm,
size_t& aLength)
{
aLength = 0;
@ -218,7 +218,7 @@ GetKeySizeForAlgorithm(JSContext* aCx, const ObjectOrString& aAlgorithm,
algName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR) ||
algName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM) ||
algName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
RootedDictionary<AesKeyGenParams> params(aCx);
RootedDictionary<AesDerivedKeyParams> params(aCx);
if (NS_FAILED(Coerce(aCx, params, aAlgorithm)) ||
!params.mLength.WasPassed()) {
return NS_ERROR_DOM_SYNTAX_ERR;
@ -233,19 +233,27 @@ GetKeySizeForAlgorithm(JSContext* aCx, const ObjectOrString& aAlgorithm,
return NS_OK;
}
// Determine HMAC key length as the block size of the given hash.
// Read HMAC key length from given algorithm object or
// determine key length as the block size of the given hash.
if (algName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) {
RootedDictionary<HmacImportParams> params(aCx);
RootedDictionary<HmacDerivedKeyParams> params(aCx);
if (NS_FAILED(Coerce(aCx, params, aAlgorithm)) ||
!params.mHash.WasPassed()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
// Return the passed length, if any.
if (params.mLength.WasPassed()) {
aLength = params.mLength.Value();
return NS_OK;
}
nsString hashName;
if (NS_FAILED(GetAlgorithmName(aCx, params.mHash.Value(), hashName))) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
// Return the given hash algorithm's block size as the key length.
size_t length = MapHashAlgorithmNameToBlockSize(hashName);
if (length == 0) {
return NS_ERROR_DOM_SYNTAX_ERR;
@ -1942,7 +1950,7 @@ public:
algName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR) ||
algName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM) ||
algName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
mEarlyRv = GetKeySizeForAlgorithm(aCx, aAlgorithm, mLength);
mEarlyRv = GetKeyLengthForAlgorithm(aCx, aAlgorithm, mLength);
if (NS_FAILED(mEarlyRv)) {
return;
}
@ -2267,7 +2275,7 @@ public:
: mSymKey(aKey.GetSymKey())
{
size_t length;
mEarlyRv = GetKeySizeForAlgorithm(aCx, aTargetAlgorithm, length);
mEarlyRv = GetKeyLengthForAlgorithm(aCx, aTargetAlgorithm, length);
if (NS_SUCCEEDED(mEarlyRv)) {
Init(aCx, aAlgorithm, aKey, length);
@ -2426,7 +2434,7 @@ public:
CryptoKey& aKey, const ObjectOrString& aTargetAlgorithm)
: mPrivKey(aKey.GetPrivateKey())
{
mEarlyRv = GetKeySizeForAlgorithm(aCx, aTargetAlgorithm, mLength);
mEarlyRv = GetKeyLengthForAlgorithm(aCx, aTargetAlgorithm, mLength);
if (NS_SUCCEEDED(mEarlyRv)) {
Init(aCx, aAlgorithm, aKey);
}

Просмотреть файл

@ -1143,6 +1143,33 @@ TestArray.addTest(
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"Import raw PBKDF2 key and derive a new key using HMAC-SHA-1 with custom length",
function() {
var that = this;
function doDerive(x) {
var alg = {
name: "PBKDF2",
hash: "SHA-1",
salt: tv.pbkdf2_sha1.salt,
iterations: tv.pbkdf2_sha1.iterations
};
var algDerived = {name: "HMAC", hash: "SHA-1", length: 128};
return crypto.subtle.deriveKey(alg, x, algDerived, false, ["sign"]);
}
var password = crypto.getRandomValues(new Uint8Array(8));
crypto.subtle.importKey("raw", password, "PBKDF2", false, ["deriveKey"])
.then(doDerive)
.then(complete(that, function (x) {
return hasKeyFields(x) && x.algorithm.length == 128;
}), error(that));
}
);
// -----------------------------------------------------------------------------
/*TestArray.addTest(
"Import raw PBKDF2 key and derive bits using HMAC-SHA-256",

Просмотреть файл

@ -114,6 +114,14 @@ dictionary EcKeyGenParams : Algorithm {
NamedCurve namedCurve;
};
dictionary AesDerivedKeyParams : Algorithm {
[EnforceRange] unsigned long length;
};
dictionary HmacDerivedKeyParams : HmacImportParams {
[EnforceRange] unsigned long length;
};
dictionary EcdhKeyDeriveParams : Algorithm {
CryptoKey public;
};