Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1085)

Unified Diff: content/child/webcrypto/test/ecdh_unittest.cc

Issue 749183004: WebCrypto: Implement crypto.subtle.deriveKey (chromium-side). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ecdh
Patch Set: rebase Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/child/webcrypto/openssl/ecdh_openssl.cc ('k') | content/child/webcrypto/webcrypto_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/test/ecdh_unittest.cc
diff --git a/content/child/webcrypto/test/ecdh_unittest.cc b/content/child/webcrypto/test/ecdh_unittest.cc
index 56af8b4106f11a1c167ede7cce903651dc01bfe2..b49aaa8d2e2d54e3ae1f2e93809e3bcd81afe269 100644
--- a/content/child/webcrypto/test/ecdh_unittest.cc
+++ b/content/child/webcrypto/test/ecdh_unittest.cc
@@ -42,7 +42,41 @@ blink::WebCryptoAlgorithm CreateEcdhDeriveParams(
new blink::WebCryptoEcdhKeyDeriveParams(public_key));
}
-TEST(WebCryptoEcdhTest, VerifyKnownAnswer) {
+blink::WebCryptoAlgorithm CreateAesGcmDerivedKeyParams(
+ unsigned short length_bits) {
+ return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
+ blink::WebCryptoAlgorithmIdAesGcm,
+ new blink::WebCryptoAesDerivedKeyParams(length_bits));
+}
+
+// Helper that loads a "public_key" and "private_key" from the test data.
+void ImportKeysFromTest(const base::DictionaryValue* test,
+ blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key) {
+ // Import the public key.
+ const base::DictionaryValue* public_key_json = NULL;
+ EXPECT_TRUE(test->GetDictionary("public_key", &public_key_json));
+ blink::WebCryptoNamedCurve curve =
+ GetCurveNameFromDictionary(public_key_json, "crv");
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(*public_key_json)),
+ CreateEcdhImportAlgorithm(curve), true, 0, public_key));
+
+ // Import the private key.
+ const base::DictionaryValue* private_key_json = NULL;
+ EXPECT_TRUE(test->GetDictionary("private_key", &private_key_json));
+ curve = GetCurveNameFromDictionary(private_key_json, "crv");
+ ASSERT_EQ(Status::Success(),
+ ImportKey(blink::WebCryptoKeyFormatJwk,
+ CryptoData(MakeJsonVector(*private_key_json)),
+ CreateEcdhImportAlgorithm(curve), true,
+ blink::WebCryptoKeyUsageDeriveBits |
+ blink::WebCryptoKeyUsageDeriveKey,
+ private_key));
+}
+
+TEST(WebCryptoEcdhTest, DeriveBitsKnownAnswer) {
if (!SupportsEcdh())
return;
@@ -55,28 +89,10 @@ TEST(WebCryptoEcdhTest, VerifyKnownAnswer) {
const base::DictionaryValue* test;
ASSERT_TRUE(tests->GetDictionary(test_index, &test));
- // Import the public key.
- const base::DictionaryValue* public_key_json = NULL;
- EXPECT_TRUE(test->GetDictionary("public_key", &public_key_json));
- blink::WebCryptoNamedCurve curve =
- GetCurveNameFromDictionary(public_key_json, "crv");
+ // Import the keys.
blink::WebCryptoKey public_key;
- ASSERT_EQ(
- Status::Success(),
- ImportKey(blink::WebCryptoKeyFormatJwk,
- CryptoData(MakeJsonVector(*public_key_json)),
- CreateEcdhImportAlgorithm(curve), true, 0, &public_key));
-
- // Import the private key.
- const base::DictionaryValue* private_key_json = NULL;
- EXPECT_TRUE(test->GetDictionary("private_key", &private_key_json));
- curve = GetCurveNameFromDictionary(private_key_json, "crv");
blink::WebCryptoKey private_key;
- ASSERT_EQ(Status::Success(),
- ImportKey(blink::WebCryptoKeyFormatJwk,
- CryptoData(MakeJsonVector(*private_key_json)),
- CreateEcdhImportAlgorithm(curve), true,
- blink::WebCryptoKeyUsageDeriveBits, &private_key));
+ ImportKeysFromTest(test, &public_key, &private_key);
// Now try to derive bytes.
std::vector<uint8_t> derived_bytes;
@@ -100,6 +116,199 @@ TEST(WebCryptoEcdhTest, VerifyKnownAnswer) {
}
}
+// Loads up a test ECDH public and private key for P-521. The keys
+// come from different key pairs, and can be used for key derivation of up to
+// 528 bits.
+void LoadTestKeys(blink::WebCryptoKey* public_key,
+ blink::WebCryptoKey* private_key) {
+ // Assume that the 7th key in the test data is for P-521.
+ scoped_ptr<base::ListValue> tests;
+ ASSERT_TRUE(ReadJsonTestFileToList("ecdh.json", &tests));
+
+ const base::DictionaryValue* test;
+ ASSERT_TRUE(tests->GetDictionary(6, &test));
+
+ ImportKeysFromTest(test, public_key, private_key);
+
+ ASSERT_EQ(blink::WebCryptoNamedCurveP521,
+ public_key->algorithm().ecParams()->namedCurve());
+}
+
+// Try deriving an AES key of length 129 bits.
+TEST(WebCryptoEcdhTest, DeriveKeyBadAesLength) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ ASSERT_EQ(Status::ErrorGetAesKeyLength(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ CreateAesGcmDerivedKeyParams(129), true,
+ blink::WebCryptoKeyUsageEncrypt, &derived_key));
+}
+
+// Try deriving an AES key of length 192 bits.
+TEST(WebCryptoEcdhTest, DeriveKeyUnsupportedAesLength) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ ASSERT_EQ(Status::ErrorAes192BitUnsupported(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ CreateAesGcmDerivedKeyParams(192), true,
+ blink::WebCryptoKeyUsageEncrypt, &derived_key));
+}
+
+// Try deriving an HMAC key of length 0 bits.
+TEST(WebCryptoEcdhTest, DeriveKeyZeroLengthHmac) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0);
+
+ ASSERT_EQ(Status::ErrorGetHmacKeyLengthZero(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+}
+
+// Derive an HMAC key of length 19 bits.
+TEST(WebCryptoEcdhTest, DeriveKeyHmac19Bits) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1, 19);
+
+ ASSERT_EQ(Status::Success(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdHmac, derived_key.algorithm().id());
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdSha1,
+ derived_key.algorithm().hmacParams()->hash().id());
+ ASSERT_EQ(19u, derived_key.algorithm().hmacParams()->lengthBits());
+
+ // Export the key and verify its contents.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, derived_key, &raw_key));
+ EXPECT_EQ(3u, raw_key.size());
+ // The last 7 bits of the key should be zero.
+ EXPECT_EQ(0, raw_key[raw_key.size() - 1] & 0x1f);
+}
+
+// Derive an HMAC key with no specified length (just the hash of SHA-256).
+TEST(WebCryptoEcdhTest, DeriveKeyHmacSha256NoLength) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha256);
+
+ ASSERT_EQ(Status::Success(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdHmac, derived_key.algorithm().id());
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdSha256,
+ derived_key.algorithm().hmacParams()->hash().id());
+ ASSERT_EQ(512u, derived_key.algorithm().hmacParams()->lengthBits());
+
+ // Export the key and verify its contents.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, derived_key, &raw_key));
+ EXPECT_EQ(64u, raw_key.size());
+}
+
+// Derive an HMAC key with no specified length (just the hash of SHA-512).
+//
+// This fails, because ECDH using P-521 can only generate 528 bits, however HMAC
+// SHA-512 requires 1024 bits.
+//
+// In practice, authors won't be directly generating keys from key agreement
+// schemes, as that is frequently insecure, and instead be using KDFs to expand
+// and generate keys. For simplicity of testing, however, test using an HMAC
+// key.
+TEST(WebCryptoEcdhTest, DeriveKeyHmacSha512NoLength) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ const blink::WebCryptoAlgorithm import_algorithm =
+ CreateHmacImportAlgorithmNoLength(blink::WebCryptoAlgorithmIdSha512);
+
+ ASSERT_EQ(Status::ErrorEcdhLengthTooBig(528),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ import_algorithm, import_algorithm, true,
+ blink::WebCryptoKeyUsageSign, &derived_key));
+}
+
+// Try deriving an AES key of length 128 bits.
+TEST(WebCryptoEcdhTest, DeriveKeyAes128) {
+ if (!SupportsEcdh())
+ return;
+
+ blink::WebCryptoKey public_key;
+ blink::WebCryptoKey base_key;
+ LoadTestKeys(&public_key, &base_key);
+
+ blink::WebCryptoKey derived_key;
+
+ ASSERT_EQ(Status::Success(),
+ DeriveKey(CreateEcdhDeriveParams(public_key), base_key,
+ CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
+ CreateAesGcmDerivedKeyParams(128), true,
+ blink::WebCryptoKeyUsageEncrypt, &derived_key));
+
+ ASSERT_EQ(blink::WebCryptoAlgorithmIdAesGcm, derived_key.algorithm().id());
+ ASSERT_EQ(128, derived_key.algorithm().aesParams()->lengthBits());
+
+ // Export the key and verify its contents.
+ std::vector<uint8_t> raw_key;
+ EXPECT_EQ(Status::Success(),
+ ExportKey(blink::WebCryptoKeyFormatRaw, derived_key, &raw_key));
+ EXPECT_EQ(16u, raw_key.size());
+}
+
} // namespace
} // namespace webcrypto
« no previous file with comments | « content/child/webcrypto/openssl/ecdh_openssl.cc ('k') | content/child/webcrypto/webcrypto_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698