1c8cb9881b5f8e9f4e3089cd4225f5bf131febe0
[platform/framework/web/crosswalk.git] / src / content / renderer / webcrypto / webcrypto_impl_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/webcrypto/webcrypto_impl.h"
6
7 #include <algorithm>
8 #include <string>
9 #include <vector>
10
11 #include "base/basictypes.h"
12 #include "base/json/json_writer.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "content/public/renderer/content_renderer_client.h"
17 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
18 #include "content/renderer/webcrypto/webcrypto_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/WebKit/public/platform/WebArrayBuffer.h"
21 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
22 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
23 #include "third_party/WebKit/public/platform/WebCryptoKey.h"
24
25 // The OpenSSL implementation of WebCrypto is less complete, so don't run all of
26 // the tests: http://crbug.com/267888
27 #if defined(USE_OPENSSL)
28 #define MAYBE(test_name) DISABLED_##test_name
29 #else
30 #define MAYBE(test_name) test_name
31 #endif
32
33 namespace content {
34
35 namespace {
36
37 // Returns a slightly modified version of the input vector.
38 //
39 //  - For non-empty inputs a single bit is inverted.
40 //  - For empty inputs, a byte is added.
41 std::vector<uint8> Corrupted(const std::vector<uint8>& input) {
42   std::vector<uint8> corrupted_data(input);
43   if (corrupted_data.empty())
44     corrupted_data.push_back(0);
45   corrupted_data[corrupted_data.size() / 2] ^= 0x01;
46   return corrupted_data;
47 }
48
49 std::vector<uint8> HexStringToBytes(const std::string& hex) {
50   std::vector<uint8> bytes;
51   base::HexStringToBytes(hex, &bytes);
52   return bytes;
53 }
54
55 void ExpectArrayBufferMatchesHex(const std::string& expected_hex,
56                                  const blink::WebArrayBuffer& array_buffer) {
57   EXPECT_STRCASEEQ(
58       expected_hex.c_str(),
59       base::HexEncode(array_buffer.data(), array_buffer.byteLength()).c_str());
60 }
61
62 void ExpectVectorMatchesHex(const std::string& expected_hex,
63                             const std::vector<uint8>& bytes) {
64   EXPECT_STRCASEEQ(
65       expected_hex.c_str(),
66       base::HexEncode(webcrypto::Uint8VectorStart(bytes),
67           bytes.size()).c_str());
68 }
69
70 std::vector<uint8> MakeJsonVector(const std::string& json_string) {
71   return std::vector<uint8>(json_string.begin(), json_string.end());
72 }
73
74 std::vector<uint8> MakeJsonVector(const base::DictionaryValue& dict) {
75   std::string json;
76   base::JSONWriter::Write(&dict, &json);
77   return MakeJsonVector(json);
78 }
79
80 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON
81 // dictionary to a good state
82 void RestoreJwkOctDictionary(base::DictionaryValue* dict) {
83   dict->Clear();
84   dict->SetString("kty", "oct");
85   dict->SetString("alg", "A128CBC");
86   dict->SetString("use", "enc");
87   dict->SetBoolean("extractable", false);
88   dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
89 }
90
91 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
92     const std::vector<uint8>& iv,
93     const std::vector<uint8>& additional_data,
94     unsigned tag_length_bits) {
95   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
96       blink::WebCryptoAlgorithmIdAesGcm,
97       new blink::WebCryptoAesGcmParams(
98           webcrypto::Uint8VectorStart(iv), iv.size(),
99           true,
100           webcrypto::Uint8VectorStart(additional_data),
101           additional_data.size(),
102           true, tag_length_bits));
103 }
104
105 // Helper for ImportJwkRsaFailures. Restores the JWK JSON
106 // dictionary to a good state
107 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) {
108   dict->Clear();
109   dict->SetString("kty", "RSA");
110   dict->SetString("alg", "RSA1_5");
111   dict->SetString("use", "enc");
112   dict->SetBoolean("extractable", false);
113   dict->SetString("n",
114       "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk"
115       "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm"
116       "e7PUJHYW1PW6ENTP0ibeiNOfFvs");
117   dict->SetString("e", "AQAB");
118 }
119
120 blink::WebCryptoAlgorithm CreateRsaAlgorithmWithInnerHash(
121     blink::WebCryptoAlgorithmId algorithm_id,
122     blink::WebCryptoAlgorithmId hash_id) {
123   DCHECK(algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
124          algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep);
125   DCHECK(webcrypto::IsHashAlgorithm(hash_id));
126   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
127       algorithm_id,
128       new blink::WebCryptoRsaSsaParams(webcrypto::CreateAlgorithm(hash_id)));
129 }
130
131 // Determines if two ArrayBuffers have identical content.
132 bool ArrayBuffersEqual(
133     const blink::WebArrayBuffer& a,
134     const blink::WebArrayBuffer& b) {
135   return a.byteLength() == b.byteLength() &&
136          memcmp(a.data(), b.data(), a.byteLength()) == 0;
137 }
138
139 // Given a vector of WebArrayBuffers, determines if there are any copies.
140 bool CopiesExist(std::vector<blink::WebArrayBuffer> bufs) {
141   for (size_t i = 0; i < bufs.size(); ++i) {
142     for (size_t j = i + 1; j < bufs.size(); ++j) {
143       if (ArrayBuffersEqual(bufs[i], bufs[j]))
144         return true;
145     }
146   }
147   return false;
148 }
149
150 blink::WebCryptoAlgorithm CreateAesKeyGenAlgorithm(
151     blink::WebCryptoAlgorithmId aes_alg_id,
152     unsigned short length) {
153   return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
154       aes_alg_id, new blink::WebCryptoAesKeyGenParams(length));
155 }
156
157 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
158     unsigned short key_length_bits) {
159   return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc,
160                                   key_length_bits);
161 }
162
163 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm(
164     unsigned short key_length_bits) {
165   return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm,
166                                   key_length_bits);
167 }
168
169 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm(
170     unsigned short key_length_bits) {
171   return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw,
172                                   key_length_bits);
173 }
174
175 // The following key pair is comprised of the SPKI (public key) and PKCS#8
176 // (private key) representations of the key pair provided in Example 1 of the
177 // NIST test vectors at
178 // ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt
179 const unsigned kModulusLength = 1024;
180 const char* const kPublicKeySpkiDerHex =
181     "30819f300d06092a864886f70d010101050003818d0030818902818100a5"
182     "6e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad9"
183     "91d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfc"
184     "e0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e"
185     "6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cf"
186     "fb2249bd9a21370203010001";
187 const char* const kPrivateKeyPkcs8DerHex =
188     "30820275020100300d06092a864886f70d01010105000482025f3082025b"
189     "02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52"
190     "a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab"
191     "7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921c"
192     "b23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef"
193     "22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d"
194     "4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c"
195     "568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee"
196     "896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31"
197     "b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b3"
198     "25024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e8629"
199     "6b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b"
200     "3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde12"
201     "3fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc72"
202     "3e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca"
203     "5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8d"
204     "d3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa71"
205     "2049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd"
206     "48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027"
207     "156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319"
208     "584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24"
209     "a79f4d";
210
211 }  // namespace
212
213 class WebCryptoImplTest : public testing::Test {
214  protected:
215   blink::WebCryptoKey ImportSecretKeyFromRawHexString(
216       const std::string& key_hex,
217       const blink::WebCryptoAlgorithm& algorithm,
218       blink::WebCryptoKeyUsageMask usage) {
219     std::vector<uint8> key_raw = HexStringToBytes(key_hex);
220
221     blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
222     bool extractable = true;
223     EXPECT_TRUE(crypto_.ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
224                                           webcrypto::Uint8VectorStart(key_raw),
225                                           key_raw.size(),
226                                           algorithm,
227                                           extractable,
228                                           usage,
229                                           &key));
230
231     EXPECT_FALSE(key.isNull());
232     EXPECT_TRUE(key.handle());
233     EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
234     EXPECT_EQ(algorithm.id(), key.algorithm().id());
235     EXPECT_EQ(extractable, key.extractable());
236     EXPECT_EQ(usage, key.usages());
237     return key;
238   }
239
240   void ImportRsaKeyPair(
241       const std::string& spki_der_hex,
242       const std::string& pkcs8_der_hex,
243       const blink::WebCryptoAlgorithm& algorithm,
244       bool extractable,
245       blink::WebCryptoKeyUsageMask usage_mask,
246       blink::WebCryptoKey* public_key,
247       blink::WebCryptoKey* private_key) {
248     EXPECT_TRUE(ImportKeyInternal(
249         blink::WebCryptoKeyFormatSpki,
250         HexStringToBytes(spki_der_hex),
251         algorithm,
252         true,
253         usage_mask,
254         public_key));
255     EXPECT_FALSE(public_key->isNull());
256     EXPECT_TRUE(public_key->handle());
257     EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key->type());
258     EXPECT_EQ(algorithm.id(), public_key->algorithm().id());
259     EXPECT_EQ(extractable, extractable);
260     EXPECT_EQ(usage_mask, public_key->usages());
261
262     EXPECT_TRUE(ImportKeyInternal(
263         blink::WebCryptoKeyFormatPkcs8,
264         HexStringToBytes(pkcs8_der_hex),
265         algorithm,
266         extractable,
267         usage_mask,
268         private_key));
269     EXPECT_FALSE(private_key->isNull());
270     EXPECT_TRUE(private_key->handle());
271     EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type());
272     EXPECT_EQ(algorithm.id(), private_key->algorithm().id());
273     EXPECT_EQ(extractable, extractable);
274     EXPECT_EQ(usage_mask, private_key->usages());
275   }
276
277   // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a
278   // runtime dependency. Test it by trying to import a key.
279   bool SupportsAesGcm() {
280     std::vector<uint8> key_raw(16, 0);
281
282     blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
283     return crypto_.ImportKeyInternal(
284         blink::WebCryptoKeyFormatRaw,
285         webcrypto::Uint8VectorStart(key_raw),
286         key_raw.size(),
287         webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
288         true,
289         blink::WebCryptoKeyUsageEncrypt,
290         &key);
291   }
292
293   bool AesGcmEncrypt(const blink::WebCryptoKey& key,
294                      const std::vector<uint8>& iv,
295                      const std::vector<uint8>& additional_data,
296                      unsigned tag_length_bits,
297                      const std::vector<uint8>& plain_text,
298                      std::vector<uint8>* cipher_text,
299                      std::vector<uint8>* authentication_tag) {
300     blink::WebCryptoAlgorithm algorithm = CreateAesGcmAlgorithm(
301         iv, additional_data, tag_length_bits);
302
303     blink::WebArrayBuffer output;
304     if (!EncryptInternal(algorithm, key, plain_text, &output))
305       return false;
306
307     if (output.byteLength() * 8 < tag_length_bits) {
308       EXPECT_TRUE(false);
309       return false;
310     }
311
312     // The encryption result is cipher text with authentication tag appended.
313     cipher_text->assign(
314         static_cast<uint8*>(output.data()),
315         static_cast<uint8*>(output.data()) +
316             (output.byteLength() - tag_length_bits / 8));
317     authentication_tag->assign(
318         static_cast<uint8*>(output.data()) + cipher_text->size(),
319         static_cast<uint8*>(output.data()) + output.byteLength());
320
321     return true;
322   }
323
324   bool AesGcmDecrypt(const blink::WebCryptoKey& key,
325                      const std::vector<uint8>& iv,
326                      const std::vector<uint8>& additional_data,
327                      unsigned tag_length_bits,
328                      const std::vector<uint8>& cipher_text,
329                      const std::vector<uint8>& authentication_tag,
330                      blink::WebArrayBuffer* plain_text) {
331     blink::WebCryptoAlgorithm algorithm = CreateAesGcmAlgorithm(
332         iv, additional_data, tag_length_bits);
333
334     // Join cipher text and authentication tag.
335     std::vector<uint8> cipher_text_with_tag;
336     cipher_text_with_tag.reserve(
337         cipher_text.size() + authentication_tag.size());
338     cipher_text_with_tag.insert(
339         cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end());
340     cipher_text_with_tag.insert(
341         cipher_text_with_tag.end(), authentication_tag.begin(),
342         authentication_tag.end());
343
344     return DecryptInternal(algorithm, key, cipher_text_with_tag, plain_text);
345   }
346
347   // Forwarding methods to gain access to protected methods of
348   // WebCryptoImpl.
349
350   bool DigestInternal(
351       const blink::WebCryptoAlgorithm& algorithm,
352       const std::vector<uint8>& data,
353       blink::WebArrayBuffer* buffer) {
354     return crypto_.DigestInternal(
355         algorithm, webcrypto::Uint8VectorStart(data), data.size(), buffer);
356   }
357
358   bool GenerateKeyInternal(
359       const blink::WebCryptoAlgorithm& algorithm,
360       blink::WebCryptoKey* key) {
361     bool extractable = true;
362     blink::WebCryptoKeyUsageMask usage_mask = 0;
363     return crypto_.GenerateKeyInternal(algorithm, extractable, usage_mask, key);
364   }
365
366   bool GenerateKeyPairInternal(
367       const blink::WebCryptoAlgorithm& algorithm,
368       bool extractable,
369       blink::WebCryptoKeyUsageMask usage_mask,
370       blink::WebCryptoKey* public_key,
371       blink::WebCryptoKey* private_key) {
372     return crypto_.GenerateKeyPairInternal(
373         algorithm, extractable, usage_mask, public_key, private_key);
374   }
375
376   bool ImportKeyInternal(
377       blink::WebCryptoKeyFormat format,
378       const std::vector<uint8>& key_data,
379       const blink::WebCryptoAlgorithm& algorithm,
380       bool extractable,
381       blink::WebCryptoKeyUsageMask usage_mask,
382       blink::WebCryptoKey* key) {
383     return crypto_.ImportKeyInternal(format,
384                                      webcrypto::Uint8VectorStart(key_data),
385                                      key_data.size(),
386                                      algorithm,
387                                      extractable,
388                                      usage_mask,
389                                      key);
390   }
391
392   bool ExportKeyInternal(
393       blink::WebCryptoKeyFormat format,
394       const blink::WebCryptoKey& key,
395       blink::WebArrayBuffer* buffer) {
396     return crypto_.ExportKeyInternal(format, key, buffer);
397   }
398
399   bool SignInternal(
400       const blink::WebCryptoAlgorithm& algorithm,
401       const blink::WebCryptoKey& key,
402       const std::vector<uint8>& data,
403       blink::WebArrayBuffer* buffer) {
404     return crypto_.SignInternal(
405         algorithm, key, webcrypto::Uint8VectorStart(data), data.size(), buffer);
406   }
407
408   bool VerifySignatureInternal(
409       const blink::WebCryptoAlgorithm& algorithm,
410       const blink::WebCryptoKey& key,
411       const unsigned char* signature,
412       unsigned signature_size,
413       const std::vector<uint8>& data,
414       bool* signature_match) {
415     return crypto_.VerifySignatureInternal(algorithm,
416                                            key,
417                                            signature,
418                                            signature_size,
419                                            webcrypto::Uint8VectorStart(data),
420                                            data.size(),
421                                            signature_match);
422   }
423
424   bool VerifySignatureInternal(
425       const blink::WebCryptoAlgorithm& algorithm,
426       const blink::WebCryptoKey& key,
427       const std::vector<uint8>& signature,
428       const std::vector<uint8>& data,
429       bool* signature_match) {
430     return crypto_.VerifySignatureInternal(
431         algorithm,
432         key,
433         webcrypto::Uint8VectorStart(signature),
434         signature.size(),
435         webcrypto::Uint8VectorStart(data),
436         data.size(),
437         signature_match);
438   }
439
440   bool EncryptInternal(
441       const blink::WebCryptoAlgorithm& algorithm,
442       const blink::WebCryptoKey& key,
443       const unsigned char* data,
444       unsigned data_size,
445       blink::WebArrayBuffer* buffer) {
446     return crypto_.EncryptInternal(algorithm, key, data, data_size, buffer);
447   }
448
449   bool EncryptInternal(
450       const blink::WebCryptoAlgorithm& algorithm,
451       const blink::WebCryptoKey& key,
452       const std::vector<uint8>& data,
453       blink::WebArrayBuffer* buffer) {
454     return crypto_.EncryptInternal(
455         algorithm, key, webcrypto::Uint8VectorStart(data), data.size(), buffer);
456   }
457
458   bool DecryptInternal(
459       const blink::WebCryptoAlgorithm& algorithm,
460       const blink::WebCryptoKey& key,
461       const unsigned char* data,
462       unsigned data_size,
463       blink::WebArrayBuffer* buffer) {
464     return crypto_.DecryptInternal(algorithm, key, data, data_size, buffer);
465   }
466
467   bool DecryptInternal(
468       const blink::WebCryptoAlgorithm& algorithm,
469       const blink::WebCryptoKey& key,
470       const std::vector<uint8>& data,
471       blink::WebArrayBuffer* buffer) {
472     return crypto_.DecryptInternal(
473         algorithm, key, webcrypto::Uint8VectorStart(data), data.size(), buffer);
474   }
475
476   bool ImportKeyJwk(
477       const std::vector<uint8>& key_data,
478       const blink::WebCryptoAlgorithm& algorithm,
479       bool extractable,
480       blink::WebCryptoKeyUsageMask usage_mask,
481       blink::WebCryptoKey* key) {
482     return crypto_.ImportKeyJwk(webcrypto::Uint8VectorStart(key_data),
483                                 key_data.size(),
484                                 algorithm,
485                                 extractable,
486                                 usage_mask,
487                                 key);
488   }
489
490  private:
491   WebCryptoImpl crypto_;
492 };
493
494 TEST_F(WebCryptoImplTest, DigestSampleSets) {
495   // The results are stored here in hex format for readability.
496   //
497   // TODO(bryaneyler): Eventually, all these sample test sets should be replaced
498   // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03
499   //
500   // Results were generated using the command sha{1,224,256,384,512}sum.
501   struct TestCase {
502     blink::WebCryptoAlgorithmId algorithm;
503     const std::string hex_input;
504     const char* hex_result;
505   };
506
507   const TestCase kTests[] = {
508     { blink::WebCryptoAlgorithmIdSha1, "",
509       "da39a3ee5e6b4b0d3255bfef95601890afd80709"
510     },
511     { blink::WebCryptoAlgorithmIdSha224, "",
512       "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"
513     },
514     { blink::WebCryptoAlgorithmIdSha256, "",
515       "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
516     },
517     { blink::WebCryptoAlgorithmIdSha384, "",
518       "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274e"
519       "debfe76f65fbd51ad2f14898b95b"
520     },
521     { blink::WebCryptoAlgorithmIdSha512, "",
522       "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0"
523       "d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
524     },
525     { blink::WebCryptoAlgorithmIdSha1, "00",
526       "5ba93c9db0cff93f52b521d7420e43f6eda2784f",
527     },
528     { blink::WebCryptoAlgorithmIdSha224, "00",
529       "fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073",
530     },
531     { blink::WebCryptoAlgorithmIdSha256, "00",
532       "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d",
533     },
534     { blink::WebCryptoAlgorithmIdSha384, "00",
535       "bec021b4f368e3069134e012c2b4307083d3a9bdd206e24e5f0d86e13d6636655933"
536       "ec2b413465966817a9c208a11717",
537     },
538     { blink::WebCryptoAlgorithmIdSha512, "00",
539       "b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a"
540       "802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee",
541     },
542     { blink::WebCryptoAlgorithmIdSha1, "000102030405",
543       "868460d98d09d8bbb93d7b6cdd15cc7fbec676b9",
544     },
545     { blink::WebCryptoAlgorithmIdSha224, "000102030405",
546       "7d92e7f1cad1818ed1d13ab41f04ebabfe1fef6bb4cbeebac34c29bc",
547     },
548     { blink::WebCryptoAlgorithmIdSha256, "000102030405",
549       "17e88db187afd62c16e5debf3e6527cd006bc012bc90b51a810cd80c2d511f43",
550     },
551     { blink::WebCryptoAlgorithmIdSha384, "000102030405",
552       "79f4738706fce9650ac60266675c3cd07298b09923850d525604d040e6e448adc7dc"
553       "22780d7e1b95bfeaa86a678e4552",
554     },
555     { blink::WebCryptoAlgorithmIdSha512, "000102030405",
556       "2f3831bccc94cf061bcfa5f8c23c1429d26e3bc6b76edad93d9025cb91c903af6cf9"
557       "c935dc37193c04c2c66e7d9de17c358284418218afea2160147aaa912f4c",
558     },
559   };
560
561   for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
562        ++test_index) {
563     SCOPED_TRACE(test_index);
564     const TestCase& test = kTests[test_index];
565
566     blink::WebCryptoAlgorithm algorithm =
567         webcrypto::CreateAlgorithm(test.algorithm);
568     std::vector<uint8> input = HexStringToBytes(test.hex_input);
569
570     blink::WebArrayBuffer output;
571     ASSERT_TRUE(DigestInternal(algorithm, input, &output));
572     ExpectArrayBufferMatchesHex(test.hex_result, output);
573   }
574 }
575
576 TEST_F(WebCryptoImplTest, HMACSampleSets) {
577   struct TestCase {
578     blink::WebCryptoAlgorithmId algorithm;
579     const char* key;
580     const char* message;
581     const char* mac;
582   };
583
584   const TestCase kTests[] = {
585     // Empty sets.  Result generated via OpenSSL commandline tool.  These
586     // particular results are also posted on the Wikipedia page examples:
587     // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
588     {
589       blink::WebCryptoAlgorithmIdSha1,
590       "",
591       "",
592       // openssl dgst -sha1 -hmac "" < /dev/null
593       "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d",
594     },
595     {
596       blink::WebCryptoAlgorithmIdSha256,
597       "",
598       "",
599       // openssl dgst -sha256 -hmac "" < /dev/null
600       "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad",
601     },
602     // For this data, see http://csrc.nist.gov/groups/STM/cavp/index.html#07
603     // Download:
604     // http://csrc.nist.gov/groups/STM/cavp/documents/mac/hmactestvectors.zip
605     // L=20 set 45
606     {
607       blink::WebCryptoAlgorithmIdSha1,
608       // key
609       "59785928d72516e31272",
610       // message
611       "a3ce8899df1022e8d2d539b47bf0e309c66f84095e21438ec355bf119ce5fdcb4e73a6"
612       "19cdf36f25b369d8c38ff419997f0c59830108223606e31223483fd39edeaa4d3f0d21"
613       "198862d239c9fd26074130ff6c86493f5227ab895c8f244bd42c7afce5d147a20a5907"
614       "98c68e708e964902d124dadecdbda9dbd0051ed710e9bf",
615       // mac
616       "3c8162589aafaee024fc9a5ca50dd2336fe3eb28",
617     },
618     // L=20 set 299
619     {
620       blink::WebCryptoAlgorithmIdSha1,
621       // key
622       "ceb9aedf8d6efcf0ae52bea0fa99a9e26ae81bacea0cff4d5eecf201e3bca3c3577480"
623       "621b818fd717ba99d6ff958ea3d59b2527b019c343bb199e648090225867d994607962"
624       "f5866aa62930d75b58f6",
625       // message
626       "99958aa459604657c7bf6e4cdfcc8785f0abf06ffe636b5b64ecd931bd8a4563055924"
627       "21fc28dbcccb8a82acea2be8e54161d7a78e0399a6067ebaca3f2510274dc9f92f2c8a"
628       "e4265eec13d7d42e9f8612d7bc258f913ecb5a3a5c610339b49fb90e9037b02d684fc6"
629       "0da835657cb24eab352750c8b463b1a8494660d36c3ab2",
630       // mac
631       "4ac41ab89f625c60125ed65ffa958c6b490ea670",
632     },
633     // L=32, set 30
634     {
635       blink::WebCryptoAlgorithmIdSha256,
636       // key
637       "9779d9120642797f1747025d5b22b7ac607cab08e1758f2f3a46c8be1e25c53b8c6a8f"
638       "58ffefa176",
639       // message
640       "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
641       "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
642       "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
643       "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e",
644       // mac
645       "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b",
646     },
647     // L=32, set 224
648     {
649       blink::WebCryptoAlgorithmIdSha256,
650       // key
651       "4b7ab133efe99e02fc89a28409ee187d579e774f4cba6fc223e13504e3511bef8d4f63"
652       "8b9aca55d4a43b8fbd64cf9d74dcc8c9e8d52034898c70264ea911a3fd70813fa73b08"
653       "3371289b",
654       // message
655       "138efc832c64513d11b9873c6fd4d8a65dbf367092a826ddd587d141b401580b798c69"
656       "025ad510cff05fcfbceb6cf0bb03201aaa32e423d5200925bddfadd418d8e30e18050e"
657       "b4f0618eb9959d9f78c1157d4b3e02cd5961f138afd57459939917d9144c95d8e6a94c"
658       "8f6d4eef3418c17b1ef0b46c2a7188305d9811dccb3d99",
659       // mac
660       "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b",
661     },
662     // L=28, Count=71
663     {
664       blink::WebCryptoAlgorithmIdSha224,
665       // key
666       "6c2539f4d0453efbbacc137794930413aeb392e029e0724715f9d943d6dcf7cdcc7fc19"
667       "7333df4fc476d5737ac3940d40eae",
668       // message
669       "1f207b3fa6c905529c9f9f7894b8941b616974df2c0cc482c400f50734f293139b5bbf9"
670       "7384adfafc56494ca0629ed0ca179daf03056e33295eb19ec8dcd4dff898281b4b9409c"
671       "a369f662d49091a225a678b1ebb75818dcb6278a2d136319f78f9ba9df5031a4f6305ee"
672       "fde5b761d2f196ee318e89bcc4acebc2e11ed3b5dc4",
673       // mac
674       "4a7d9d13705b0faba0db75356c8ee0635afff1544911c69c2fbb1ab2"
675     },
676     // L=48, Count=50
677     {
678       blink::WebCryptoAlgorithmIdSha384,
679       // key
680       "d137f3e6cc4af28554beb03ba7a97e60c9d3959cd3bb08068edbf68d402d0498c6ee0ae"
681       "9e3a20dc7d8586e5c352f605cee19",
682       // message
683       "64a884670d1c1dff555483dcd3da305dfba54bdc4d817c33ccb8fe7eb2ebf6236241031"
684       "09ec41644fa078491900c59a0f666f0356d9bc0b45bcc79e5fc9850f4543d96bc680090"
685       "44add0838ac1260e80592fbc557b2ddaf5ed1b86d3ed8f09e622e567f1d39a340857f6a"
686       "850cceef6060c48dac3dd0071fe68eb4ed2ed9aca01",
687       // mac
688       "c550fa53514da34f15e7f98ea87226ab6896cdfae25d3ec2335839f755cdc9a4992092e"
689       "70b7e5bd422784380b6396cf5"
690     },
691     // L=64, Count=65
692     {
693       blink::WebCryptoAlgorithmIdSha512,
694       // key
695       "c367aeb5c02b727883ffe2a4ceebf911b01454beb328fb5d57fc7f11bf744576aba421e2"
696       "a63426ea8109bd28ff21f53cd2bf1a11c6c989623d6ec27cdb0bbf458250857d819ff844"
697       "08b4f3dce08b98b1587ee59683af8852a0a5f55bda3ab5e132b4010e",
698       // message
699       "1a7331c8ff1b748e3cee96952190fdbbe4ee2f79e5753bbb368255ee5b19c05a4ed9f1b2"
700       "c72ff1e9b9cb0348205087befa501e7793770faf0606e9c901836a9bc8afa00d7db94ee2"
701       "9eb191d5cf3fc3e8da95a0f9f4a2a7964289c3129b512bd890de8700a9205420f28a8965"
702       "b6c67be28ba7fe278e5fcd16f0f22cf2b2eacbb9",
703       // mac
704       "4459066109cb11e6870fa9c6bfd251adfa304c0a2928ca915049704972edc560cc7c0bc3"
705       "8249e9101aae2f7d4da62eaff83fb07134efc277de72b9e4ab360425"
706     },
707   };
708
709   for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
710        ++test_index) {
711     SCOPED_TRACE(test_index);
712     const TestCase& test = kTests[test_index];
713
714     blink::WebCryptoAlgorithm algorithm =
715         webcrypto::CreateHmacAlgorithmByHashId(test.algorithm);
716
717     blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
718         test.key, algorithm, blink::WebCryptoKeyUsageSign);
719
720     // Verify exported raw key is identical to the imported data
721     blink::WebArrayBuffer raw_key;
722     EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
723     ExpectArrayBufferMatchesHex(test.key, raw_key);
724
725     std::vector<uint8> message_raw = HexStringToBytes(test.message);
726
727     blink::WebArrayBuffer output;
728
729     ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
730
731     ExpectArrayBufferMatchesHex(test.mac, output);
732
733     bool signature_match = false;
734     EXPECT_TRUE(VerifySignatureInternal(
735         algorithm,
736         key,
737         static_cast<const unsigned char*>(output.data()),
738         output.byteLength(),
739         message_raw,
740         &signature_match));
741     EXPECT_TRUE(signature_match);
742
743     // Ensure truncated signature does not verify by passing one less byte.
744     EXPECT_TRUE(VerifySignatureInternal(
745         algorithm,
746         key,
747         static_cast<const unsigned char*>(output.data()),
748         output.byteLength() - 1,
749         message_raw,
750         &signature_match));
751     EXPECT_FALSE(signature_match);
752
753     // Ensure extra long signature does not cause issues and fails.
754     const unsigned char kLongSignature[1024] = { 0 };
755     EXPECT_TRUE(VerifySignatureInternal(
756         algorithm,
757         key,
758         kLongSignature,
759         sizeof(kLongSignature),
760         message_raw,
761         &signature_match));
762     EXPECT_FALSE(signature_match);
763   }
764 }
765
766 TEST_F(WebCryptoImplTest, AesCbcFailures) {
767   const std::string key_hex = "2b7e151628aed2a6abf7158809cf4f3c";
768   blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
769       key_hex,
770       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
771       blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
772
773   // Verify exported raw key is identical to the imported data
774   blink::WebArrayBuffer raw_key;
775   EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
776   ExpectArrayBufferMatchesHex(key_hex, raw_key);
777
778   blink::WebArrayBuffer output;
779
780   // Use an invalid |iv| (fewer than 16 bytes)
781   {
782     std::vector<uint8> input(32);
783     std::vector<uint8> iv;
784     EXPECT_FALSE(EncryptInternal(
785         webcrypto::CreateAesCbcAlgorithm(iv), key, input, &output));
786     EXPECT_FALSE(DecryptInternal(
787         webcrypto::CreateAesCbcAlgorithm(iv), key, input, &output));
788   }
789
790   // Use an invalid |iv| (more than 16 bytes)
791   {
792     std::vector<uint8> input(32);
793     std::vector<uint8> iv(17);
794     EXPECT_FALSE(EncryptInternal(
795         webcrypto::CreateAesCbcAlgorithm(iv), key, input, &output));
796     EXPECT_FALSE(DecryptInternal(
797         webcrypto::CreateAesCbcAlgorithm(iv), key, input, &output));
798   }
799
800   // Give an input that is too large (would cause integer overflow when
801   // narrowing to an int).
802   {
803     std::vector<uint8> iv(16);
804
805     // Pretend the input is large. Don't pass data pointer as NULL in case that
806     // is special cased; the implementation shouldn't actually dereference the
807     // data.
808     const unsigned char* input = &iv[0];
809     unsigned input_len = INT_MAX - 3;
810
811     EXPECT_FALSE(EncryptInternal(
812         webcrypto::CreateAesCbcAlgorithm(iv), key, input, input_len, &output));
813     EXPECT_FALSE(DecryptInternal(
814         webcrypto::CreateAesCbcAlgorithm(iv), key, input, input_len, &output));
815   }
816
817   // Fail importing the key (too few bytes specified)
818   {
819     std::vector<uint8> key_raw(1);
820     std::vector<uint8> iv(16);
821
822     blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
823     EXPECT_FALSE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
824                                    key_raw,
825                                    webcrypto::CreateAesCbcAlgorithm(iv),
826                                    true,
827                                    blink::WebCryptoKeyUsageEncrypt,
828                                    &key));
829   }
830
831   // Fail exporting the key in SPKI and PKCS#8 formats (not allowed for secret
832   // keys).
833   EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
834   EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatPkcs8, key, &output));
835 }
836
837 TEST_F(WebCryptoImplTest, MAYBE(AesCbcSampleSets)) {
838   struct TestCase {
839     const char* key;
840     const char* iv;
841     const char* plain_text;
842     const char* cipher_text;
843   };
844
845   TestCase kTests[] = {
846     // F.2.1 (CBC-AES128.Encrypt)
847     // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
848     {
849       // key
850       "2b7e151628aed2a6abf7158809cf4f3c",
851
852       // iv
853       "000102030405060708090a0b0c0d0e0f",
854
855       // plain_text
856       "6bc1bee22e409f96e93d7e117393172a"
857       "ae2d8a571e03ac9c9eb76fac45af8e51"
858       "30c81c46a35ce411e5fbc1191a0a52ef"
859       "f69f2445df4f9b17ad2b417be66c3710",
860
861       // cipher_text
862       "7649abac8119b246cee98e9b12e9197d"
863       "5086cb9b507219ee95db113a917678b2"
864       "73bed6b8e3c1743b7116e69e22229516"
865       "3ff1caa1681fac09120eca307586e1a7"
866       // Padding block: encryption of {0x10, 0x10, ... 0x10}) (not given by the
867       // NIST test vector)
868       "8cb82807230e1321d3fae00d18cc2012"
869     },
870
871     // F.2.6 CBC-AES256.Decrypt [*]
872     // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
873     //
874     // [*] Truncated 3 bytes off the plain text, so block 4 differs from the
875     // NIST vector.
876     {
877       // key
878       "603deb1015ca71be2b73aef0857d7781"
879       "1f352c073b6108d72d9810a30914dff4",
880
881       // iv
882       "000102030405060708090a0b0c0d0e0f",
883
884       // plain_text
885       "6bc1bee22e409f96e93d7e117393172a"
886       "ae2d8a571e03ac9c9eb76fac45af8e51"
887       "30c81c46a35ce411e5fbc1191a0a52ef"
888       // Truncated this last block to make it more interesting.
889       "f69f2445df4f9b17ad2b417be6",
890
891       // cipher_text
892       "f58c4c04d6e5f1ba779eabfb5f7bfbd6"
893       "9cfc4e967edb808d679f777bc6702c7d"
894       "39f23369a9d9bacfa530e26304231461"
895       // This block differs from source vector (due to truncation)
896       "c9aaf02a6a54e9e242ccbf48c59daca6"
897     },
898
899     // Taken from encryptor_unittest.cc (EncryptorTest.EmptyEncrypt())
900     {
901       // key
902       "3132383d5369787465656e4279746573",
903
904       // iv
905       "5377656574205369787465656e204956",
906
907       // plain_text
908       "",
909
910       // cipher_text
911       "8518b8878d34e7185e300d0fcc426396"
912     },
913   };
914
915   for (size_t index = 0; index < ARRAYSIZE_UNSAFE(kTests); index++) {
916     SCOPED_TRACE(index);
917     const TestCase& test = kTests[index];
918
919     blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
920         test.key,
921         webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
922         blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
923
924     // Verify exported raw key is identical to the imported data
925     blink::WebArrayBuffer raw_key;
926     EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
927     ExpectArrayBufferMatchesHex(test.key, raw_key);
928
929     std::vector<uint8> plain_text = HexStringToBytes(test.plain_text);
930     std::vector<uint8> iv = HexStringToBytes(test.iv);
931
932     blink::WebArrayBuffer output;
933
934     // Test encryption.
935     EXPECT_TRUE(EncryptInternal(webcrypto::CreateAesCbcAlgorithm(iv),
936                                 key,
937                                 plain_text,
938                                 &output));
939     ExpectArrayBufferMatchesHex(test.cipher_text, output);
940
941     // Test decryption.
942     std::vector<uint8> cipher_text = HexStringToBytes(test.cipher_text);
943     EXPECT_TRUE(DecryptInternal(webcrypto::CreateAesCbcAlgorithm(iv),
944                                 key,
945                                 cipher_text,
946                                 &output));
947     ExpectArrayBufferMatchesHex(test.plain_text, output);
948
949     const unsigned kAesCbcBlockSize = 16;
950
951     // Decrypt with a padding error by stripping the last block. This also ends
952     // up testing decryption over empty cipher text.
953     if (cipher_text.size() >= kAesCbcBlockSize) {
954       EXPECT_FALSE(DecryptInternal(webcrypto::CreateAesCbcAlgorithm(iv),
955                                    key,
956                                    &cipher_text[0],
957                                    cipher_text.size() - kAesCbcBlockSize,
958                                    &output));
959     }
960
961     // Decrypt cipher text which is not a multiple of block size by stripping
962     // a few bytes off the cipher text.
963     if (cipher_text.size() > 3) {
964       EXPECT_FALSE(DecryptInternal(webcrypto::CreateAesCbcAlgorithm(iv),
965                                    key,
966                                    &cipher_text[0],
967                                    cipher_text.size() - 3,
968                                    &output));
969     }
970   }
971 }
972
973 TEST_F(WebCryptoImplTest, MAYBE(GenerateKeyAes)) {
974   // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each
975   // allowed key length.
976   std::vector<blink::WebCryptoAlgorithm> algorithm;
977   const unsigned short kKeyLength[] = {128, 192, 256};
978   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) {
979     algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i]));
980     algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i]));
981     algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i]));
982   }
983   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
984   std::vector<blink::WebArrayBuffer> keys;
985   blink::WebArrayBuffer key_bytes;
986   for (size_t i = 0; i < algorithm.size(); ++i) {
987     SCOPED_TRACE(i);
988     // Generate a small sample of keys.
989     keys.clear();
990     for (int j = 0; j < 16; ++j) {
991       ASSERT_TRUE(GenerateKeyInternal(algorithm[i], &key));
992       EXPECT_TRUE(key.handle());
993       EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
994       ASSERT_TRUE(
995           ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &key_bytes));
996       keys.push_back(key_bytes);
997     }
998     // Ensure all entries in the key sample set are unique. This is a simplistic
999     // estimate of whether the generated keys appear random.
1000     EXPECT_FALSE(CopiesExist(keys));
1001   }
1002 }
1003
1004 TEST_F(WebCryptoImplTest, MAYBE(GenerateKeyAesBadLength)) {
1005   const unsigned short kKeyLen[] = {0, 127, 257};
1006   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1007   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) {
1008     SCOPED_TRACE(i);
1009     EXPECT_FALSE(GenerateKeyInternal(
1010         CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), &key));
1011     EXPECT_FALSE(GenerateKeyInternal(
1012         CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), &key));
1013     EXPECT_FALSE(GenerateKeyInternal(
1014         CreateAesKwKeyGenAlgorithm(kKeyLen[i]), &key));
1015   }
1016 }
1017
1018 TEST_F(WebCryptoImplTest, MAYBE(GenerateKeyHmac)) {
1019   // Generate a small sample of HMAC keys.
1020   std::vector<blink::WebArrayBuffer> keys;
1021   for (int i = 0; i < 16; ++i) {
1022     blink::WebArrayBuffer key_bytes;
1023     blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1024     blink::WebCryptoAlgorithm algorithm = webcrypto::CreateHmacKeyGenAlgorithm(
1025         blink::WebCryptoAlgorithmIdSha1, 64);
1026     ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
1027     EXPECT_FALSE(key.isNull());
1028     EXPECT_TRUE(key.handle());
1029     EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
1030     EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
1031
1032     blink::WebArrayBuffer raw_key;
1033     ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
1034     EXPECT_EQ(64U, raw_key.byteLength());
1035     keys.push_back(raw_key);
1036   }
1037   // Ensure all entries in the key sample set are unique. This is a simplistic
1038   // estimate of whether the generated keys appear random.
1039   EXPECT_FALSE(CopiesExist(keys));
1040 }
1041
1042 // If the key length is not provided, then the block size is used.
1043 TEST_F(WebCryptoImplTest, MAYBE(GenerateKeyHmacNoLength)) {
1044   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1045   blink::WebCryptoAlgorithm algorithm =
1046       webcrypto::CreateHmacKeyGenAlgorithm(blink::WebCryptoAlgorithmIdSha1, 0);
1047   ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
1048   EXPECT_TRUE(key.handle());
1049   EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
1050   blink::WebArrayBuffer raw_key;
1051   ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
1052   EXPECT_EQ(64U, raw_key.byteLength());
1053
1054   // The block size for HMAC SHA-512 is larger.
1055   algorithm = webcrypto::CreateHmacKeyGenAlgorithm(
1056       blink::WebCryptoAlgorithmIdSha512, 0);
1057   ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
1058   ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
1059   EXPECT_EQ(128U, raw_key.byteLength());
1060 }
1061
1062 TEST_F(WebCryptoImplTest, MAYBE(ImportSecretKeyNoAlgorithm)) {
1063   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1064
1065   // This fails because the algorithm is null.
1066   EXPECT_FALSE(ImportKeyInternal(
1067       blink::WebCryptoKeyFormatRaw,
1068       HexStringToBytes("00000000000000000000"),
1069       blink::WebCryptoAlgorithm::createNull(),
1070       true,
1071       blink::WebCryptoKeyUsageEncrypt,
1072       &key));
1073 }
1074
1075
1076 TEST_F(WebCryptoImplTest, ImportJwkFailures) {
1077
1078   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1079   blink::WebCryptoAlgorithm algorithm =
1080       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
1081   blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
1082
1083   // Baseline pass: each test below breaks a single item, so we start with a
1084   // passing case to make sure each failure is caused by the isolated break.
1085   // Each breaking subtest below resets the dictionary to this passing case when
1086   // complete.
1087   base::DictionaryValue dict;
1088   RestoreJwkOctDictionary(&dict);
1089   EXPECT_TRUE(ImportKeyJwk(
1090       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1091
1092   // Fail on empty JSON.
1093   EXPECT_FALSE(ImportKeyJwk(
1094       MakeJsonVector(""), algorithm, false, usage_mask, &key));
1095
1096   // Fail on invalid JSON.
1097   const std::vector<uint8> bad_json_vec = MakeJsonVector(
1098       "{"
1099         "\"kty\"         : \"oct\","
1100         "\"alg\"         : \"HS256\","
1101         "\"use\"         : "
1102   );
1103   EXPECT_FALSE(ImportKeyJwk(bad_json_vec, algorithm, false, usage_mask, &key));
1104
1105   // Fail on JWK alg present but unrecognized.
1106   dict.SetString("alg", "A127CBC");
1107   EXPECT_FALSE(ImportKeyJwk(
1108       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1109   RestoreJwkOctDictionary(&dict);
1110
1111   // Fail on both JWK and input algorithm missing.
1112   dict.Remove("alg", NULL);
1113   EXPECT_FALSE(ImportKeyJwk(MakeJsonVector(dict),
1114                             blink::WebCryptoAlgorithm::createNull(),
1115                             false,
1116                             usage_mask,
1117                             &key));
1118   RestoreJwkOctDictionary(&dict);
1119
1120   // Fail on invalid kty.
1121   dict.SetString("kty", "foo");
1122   EXPECT_FALSE(ImportKeyJwk(
1123       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1124   RestoreJwkOctDictionary(&dict);
1125
1126   // Fail on missing kty.
1127   dict.Remove("kty", NULL);
1128   EXPECT_FALSE(ImportKeyJwk(
1129       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1130   RestoreJwkOctDictionary(&dict);
1131
1132   // Fail on invalid use.
1133   dict.SetString("use", "foo");
1134   EXPECT_FALSE(ImportKeyJwk(
1135       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1136   RestoreJwkOctDictionary(&dict);
1137 }
1138
1139 TEST_F(WebCryptoImplTest, ImportJwkOctFailures) {
1140
1141   base::DictionaryValue dict;
1142   RestoreJwkOctDictionary(&dict);
1143   blink::WebCryptoAlgorithm algorithm =
1144       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
1145   blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
1146   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1147
1148   // Baseline pass.
1149   EXPECT_TRUE(ImportKeyJwk(
1150       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1151   EXPECT_EQ(algorithm.id(), key.algorithm().id());
1152   EXPECT_FALSE(key.extractable());
1153   EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
1154   EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
1155
1156   // The following are specific failure cases for when kty = "oct".
1157
1158   // Fail on missing k.
1159   dict.Remove("k", NULL);
1160   EXPECT_FALSE(ImportKeyJwk(
1161       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1162   RestoreJwkOctDictionary(&dict);
1163
1164   // Fail on bad b64 encoding for k.
1165   dict.SetString("k", "Qk3f0DsytU8lfza2au #$% Htaw2xpop9GYyTuH0p5GghxTI=");
1166   EXPECT_FALSE(ImportKeyJwk(
1167       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1168   RestoreJwkOctDictionary(&dict);
1169
1170   // Fail on empty k.
1171   dict.SetString("k", "");
1172   EXPECT_FALSE(ImportKeyJwk(
1173       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1174   RestoreJwkOctDictionary(&dict);
1175
1176   // Fail on k actual length (120 bits) inconsistent with the embedded JWK alg
1177   // value (128) for an AES key.
1178   dict.SetString("k", "AVj42h0Y5aqGtE3yluKL");
1179   EXPECT_FALSE(ImportKeyJwk(
1180       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1181   RestoreJwkOctDictionary(&dict);
1182 }
1183
1184 TEST_F(WebCryptoImplTest, MAYBE(ImportJwkRsaFailures)) {
1185
1186   base::DictionaryValue dict;
1187   RestoreJwkRsaDictionary(&dict);
1188   blink::WebCryptoAlgorithm algorithm =
1189       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
1190   blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt;
1191   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1192
1193   // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent)
1194   // entry, while an RSA private key must have those plus at least a "d"
1195   // (private exponent) entry.
1196   // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18,
1197   // section 6.3.
1198
1199   // Baseline pass.
1200   EXPECT_TRUE(ImportKeyJwk(
1201       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1202   EXPECT_EQ(algorithm.id(), key.algorithm().id());
1203   EXPECT_FALSE(key.extractable());
1204   EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
1205   EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type());
1206
1207   // The following are specific failure cases for when kty = "RSA".
1208
1209   // Fail if either "n" or "e" is not present or malformed.
1210   const std::string kKtyParmName[] = {"n", "e"};
1211   for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) {
1212
1213     // Fail on missing parameter.
1214     dict.Remove(kKtyParmName[idx], NULL);
1215     EXPECT_FALSE(ImportKeyJwk(
1216         MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1217     RestoreJwkRsaDictionary(&dict);
1218
1219     // Fail on bad b64 parameter encoding.
1220     dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0");
1221     EXPECT_FALSE(ImportKeyJwk(
1222         MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1223     RestoreJwkRsaDictionary(&dict);
1224
1225     // Fail on empty parameter.
1226     dict.SetString(kKtyParmName[idx], "");
1227     EXPECT_FALSE(ImportKeyJwk(
1228         MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1229     RestoreJwkRsaDictionary(&dict);
1230   }
1231
1232   // Fail if "d" parameter is present, implying the JWK is a private key, which
1233   // is not supported.
1234   dict.SetString("d", "Qk3f0Dsyt");
1235   EXPECT_FALSE(ImportKeyJwk(
1236       MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1237   RestoreJwkRsaDictionary(&dict);
1238 }
1239
1240 TEST_F(WebCryptoImplTest, MAYBE(ImportJwkInputConsistency)) {
1241   // The Web Crypto spec says that if a JWK value is present, but is
1242   // inconsistent with the input value, the operation must fail.
1243
1244   // Consistency rules when JWK value is not present: Inputs should be used.
1245   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1246   bool extractable = false;
1247   blink::WebCryptoAlgorithm algorithm =
1248       webcrypto::CreateHmacAlgorithmByHashId(blink::WebCryptoAlgorithmIdSha256);
1249   blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageVerify;
1250   base::DictionaryValue dict;
1251   dict.SetString("kty", "oct");
1252   dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
1253   std::vector<uint8> json_vec = MakeJsonVector(dict);
1254   EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
1255   EXPECT_TRUE(key.handle());
1256   EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
1257   EXPECT_EQ(extractable, key.extractable());
1258   EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, key.algorithm().id());
1259   EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256,
1260             key.algorithm().hmacParams()->hash().id());
1261   EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages());
1262   key = blink::WebCryptoKey::createNull();
1263
1264   // Consistency rules when JWK value exists: Fail if inconsistency is found.
1265
1266   // Pass: All input values are consistent with the JWK values.
1267   dict.Clear();
1268   dict.SetString("kty", "oct");
1269   dict.SetString("alg", "HS256");
1270   dict.SetString("use", "sig");
1271   dict.SetBoolean("extractable", false);
1272   dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
1273   json_vec = MakeJsonVector(dict);
1274   EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
1275
1276   // Extractable cases:
1277   // 1. input=T, JWK=F ==> fail (inconsistent)
1278   // 4. input=F, JWK=F ==> pass, result extractable is F
1279   // 2. input=T, JWK=T ==> pass, result extractable is T
1280   // 3. input=F, JWK=T ==> pass, result extractable is F
1281   EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, true, usage_mask, &key));
1282   EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
1283   EXPECT_FALSE(key.extractable());
1284   dict.SetBoolean("extractable", true);
1285   EXPECT_TRUE(
1286       ImportKeyJwk(MakeJsonVector(dict), algorithm, true, usage_mask, &key));
1287   EXPECT_TRUE(key.extractable());
1288   EXPECT_TRUE(
1289       ImportKeyJwk(MakeJsonVector(dict), algorithm, false, usage_mask, &key));
1290   EXPECT_FALSE(key.extractable());
1291   dict.SetBoolean("extractable", true);  // restore previous value
1292
1293   // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value
1294   // (HMAC SHA256).
1295   EXPECT_FALSE(ImportKeyJwk(
1296       json_vec,
1297       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
1298       extractable,
1299       usage_mask,
1300       &key));
1301
1302   // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value
1303   // (HMAC SHA256).
1304   EXPECT_FALSE(ImportKeyJwk(
1305       json_vec,
1306       webcrypto::CreateHmacAlgorithmByHashId(blink::WebCryptoAlgorithmIdSha1),
1307       extractable,
1308       usage_mask,
1309       &key));
1310
1311   // Pass: JWK alg valid but input algorithm isNull: use JWK algorithm value.
1312   EXPECT_TRUE(ImportKeyJwk(json_vec,
1313                            blink::WebCryptoAlgorithm::createNull(),
1314                            extractable,
1315                            usage_mask,
1316                            &key));
1317   EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id());
1318
1319   // Pass: JWK alg missing but input algorithm specified: use input value
1320   dict.Remove("alg", NULL);
1321   EXPECT_TRUE(ImportKeyJwk(
1322       MakeJsonVector(dict),
1323       webcrypto::CreateHmacAlgorithmByHashId(blink::WebCryptoAlgorithmIdSha256),
1324       extractable,
1325       usage_mask,
1326       &key));
1327   EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id());
1328   dict.SetString("alg", "HS256");
1329
1330   // Fail: Input usage_mask (encrypt) is not a subset of the JWK value
1331   // (sign|verify)
1332   EXPECT_FALSE(ImportKeyJwk(
1333       json_vec, algorithm, extractable, blink::WebCryptoKeyUsageEncrypt, &key));
1334
1335   // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK
1336   // value (sign|verify)
1337   usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign |
1338                blink::WebCryptoKeyUsageVerify;
1339   EXPECT_FALSE(
1340       ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
1341   usage_mask = blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify;
1342
1343   // TODO(padolph): kty vs alg consistency tests: Depending on the kty value,
1344   // only certain alg values are permitted. For example, when kty = "RSA" alg
1345   // must be of the RSA family, or when kty = "oct" alg must be symmetric
1346   // algorithm.
1347 }
1348
1349 TEST_F(WebCryptoImplTest, MAYBE(ImportJwkHappy)) {
1350
1351   // This test verifies the happy path of JWK import, including the application
1352   // of the imported key material.
1353
1354   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1355   bool extractable = false;
1356   blink::WebCryptoAlgorithm algorithm =
1357       webcrypto::CreateHmacAlgorithmByHashId(blink::WebCryptoAlgorithmIdSha256);
1358   blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign;
1359
1360   // Import a symmetric key JWK and HMAC-SHA256 sign()
1361   // Uses the first SHA256 test vector from the HMAC sample set above.
1362
1363   base::DictionaryValue dict;
1364   dict.SetString("kty", "oct");
1365   dict.SetString("alg", "HS256");
1366   dict.SetString("use", "sig");
1367   dict.SetBoolean("extractable", false);
1368   dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
1369   std::vector<uint8> json_vec = MakeJsonVector(dict);
1370
1371   ASSERT_TRUE(ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
1372
1373   const std::vector<uint8> message_raw = HexStringToBytes(
1374       "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
1375       "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
1376       "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
1377       "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e");
1378
1379   blink::WebArrayBuffer output;
1380
1381   ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
1382
1383   const std::string mac_raw =
1384       "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b";
1385
1386   ExpectArrayBufferMatchesHex(mac_raw, output);
1387
1388   // TODO(padolph): Import an RSA public key JWK and use it
1389 }
1390
1391 TEST_F(WebCryptoImplTest, MAYBE(ImportExportSpki)) {
1392   // Passing case: Import a valid RSA key in SPKI format.
1393   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1394   ASSERT_TRUE(ImportKeyInternal(
1395       blink::WebCryptoKeyFormatSpki,
1396       HexStringToBytes(kPublicKeySpkiDerHex),
1397       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5),
1398       true,
1399       blink::WebCryptoKeyUsageEncrypt,
1400       &key));
1401   EXPECT_TRUE(key.handle());
1402   EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type());
1403   EXPECT_TRUE(key.extractable());
1404   EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
1405
1406   // Failing case: Empty SPKI data
1407   EXPECT_FALSE(ImportKeyInternal(
1408       blink::WebCryptoKeyFormatSpki,
1409       std::vector<uint8>(),
1410       blink::WebCryptoAlgorithm::createNull(),
1411       true,
1412       blink::WebCryptoKeyUsageEncrypt,
1413       &key));
1414
1415   // Failing case: Import RSA key with NULL input algorithm. This is not
1416   // allowed because the SPKI ASN.1 format for RSA keys is not specific enough
1417   // to map to a Web Crypto algorithm.
1418   EXPECT_FALSE(ImportKeyInternal(
1419       blink::WebCryptoKeyFormatSpki,
1420       HexStringToBytes(kPublicKeySpkiDerHex),
1421       blink::WebCryptoAlgorithm::createNull(),
1422       true,
1423       blink::WebCryptoKeyUsageEncrypt,
1424       &key));
1425
1426   // Failing case: Bad DER encoding.
1427   EXPECT_FALSE(ImportKeyInternal(
1428       blink::WebCryptoKeyFormatSpki,
1429       HexStringToBytes("618333c4cb"),
1430       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5),
1431       true,
1432       blink::WebCryptoKeyUsageEncrypt,
1433       &key));
1434
1435   // Failing case: Import RSA key but provide an inconsistent input algorithm.
1436   EXPECT_FALSE(ImportKeyInternal(
1437       blink::WebCryptoKeyFormatSpki,
1438       HexStringToBytes(kPublicKeySpkiDerHex),
1439       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
1440       true,
1441       blink::WebCryptoKeyUsageEncrypt,
1442       &key));
1443
1444   // Passing case: Export a previously imported RSA public key in SPKI format
1445   // and compare to original data.
1446   blink::WebArrayBuffer output;
1447   ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
1448   ExpectArrayBufferMatchesHex(kPublicKeySpkiDerHex, output);
1449
1450   // Failing case: Try to export a previously imported RSA public key in raw
1451   // format (not allowed for a public key).
1452   EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &output));
1453
1454   // Failing case: Try to export a non-extractable key
1455   ASSERT_TRUE(ImportKeyInternal(
1456       blink::WebCryptoKeyFormatSpki,
1457       HexStringToBytes(kPublicKeySpkiDerHex),
1458       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5),
1459       false,
1460       blink::WebCryptoKeyUsageEncrypt,
1461       &key));
1462   EXPECT_TRUE(key.handle());
1463   EXPECT_FALSE(key.extractable());
1464   EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
1465 }
1466
1467 TEST_F(WebCryptoImplTest, MAYBE(ImportPkcs8)) {
1468   // Passing case: Import a valid RSA key in PKCS#8 format.
1469   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
1470   ASSERT_TRUE(ImportKeyInternal(
1471       blink::WebCryptoKeyFormatPkcs8,
1472       HexStringToBytes(kPrivateKeyPkcs8DerHex),
1473       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
1474       true,
1475       blink::WebCryptoKeyUsageSign,
1476       &key));
1477   EXPECT_TRUE(key.handle());
1478   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, key.type());
1479   EXPECT_TRUE(key.extractable());
1480   EXPECT_EQ(blink::WebCryptoKeyUsageSign, key.usages());
1481
1482   // Failing case: Empty PKCS#8 data
1483   EXPECT_FALSE(ImportKeyInternal(
1484       blink::WebCryptoKeyFormatPkcs8,
1485       std::vector<uint8>(),
1486       blink::WebCryptoAlgorithm::createNull(),
1487       true,
1488       blink::WebCryptoKeyUsageSign,
1489       &key));
1490
1491   // Failing case: Import RSA key with NULL input algorithm. This is not
1492   // allowed because the PKCS#8 ASN.1 format for RSA keys is not specific enough
1493   // to map to a Web Crypto algorithm.
1494   EXPECT_FALSE(ImportKeyInternal(
1495       blink::WebCryptoKeyFormatPkcs8,
1496       HexStringToBytes(kPrivateKeyPkcs8DerHex),
1497       blink::WebCryptoAlgorithm::createNull(),
1498       true,
1499       blink::WebCryptoKeyUsageSign,
1500       &key));
1501
1502   // Failing case: Bad DER encoding.
1503   EXPECT_FALSE(ImportKeyInternal(
1504       blink::WebCryptoKeyFormatPkcs8,
1505       HexStringToBytes("618333c4cb"),
1506       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5),
1507       true,
1508       blink::WebCryptoKeyUsageSign,
1509       &key));
1510
1511   // Failing case: Import RSA key but provide an inconsistent input algorithm.
1512   EXPECT_FALSE(ImportKeyInternal(
1513       blink::WebCryptoKeyFormatPkcs8,
1514       HexStringToBytes(kPrivateKeyPkcs8DerHex),
1515       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
1516       true,
1517       blink::WebCryptoKeyUsageSign,
1518       &key));
1519 }
1520
1521 TEST_F(WebCryptoImplTest, MAYBE(GenerateKeyPairRsa)) {
1522   // Note: using unrealistic short key lengths here to avoid bogging down tests.
1523
1524   // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation.
1525   const unsigned modulus_length = 256;
1526   const std::vector<uint8> public_exponent = HexStringToBytes("010001");
1527   blink::WebCryptoAlgorithm algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1528       blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
1529       modulus_length,
1530       public_exponent);
1531   bool extractable = false;
1532   const blink::WebCryptoKeyUsageMask usage_mask = 0;
1533   blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1534   blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
1535   EXPECT_TRUE(GenerateKeyPairInternal(
1536       algorithm, extractable, usage_mask, &public_key, &private_key));
1537   EXPECT_FALSE(public_key.isNull());
1538   EXPECT_FALSE(private_key.isNull());
1539   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
1540   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
1541   EXPECT_EQ(true, public_key.extractable());
1542   EXPECT_EQ(extractable, private_key.extractable());
1543   EXPECT_EQ(usage_mask, public_key.usages());
1544   EXPECT_EQ(usage_mask, private_key.usages());
1545
1546   // Fail with bad modulus.
1547   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1548       blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 0, public_exponent);
1549   EXPECT_FALSE(GenerateKeyPairInternal(
1550       algorithm, extractable, usage_mask, &public_key, &private_key));
1551
1552   // Fail with bad exponent: larger than unsigned long.
1553   unsigned exponent_length = sizeof(unsigned long) + 1;  // NOLINT
1554   const std::vector<uint8> long_exponent(exponent_length, 0x01);
1555   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1556       blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
1557       modulus_length,
1558       long_exponent);
1559   EXPECT_FALSE(GenerateKeyPairInternal(
1560       algorithm, extractable, usage_mask, &public_key, &private_key));
1561
1562   // Fail with bad exponent: empty.
1563   const std::vector<uint8> empty_exponent;
1564   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1565       blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
1566       modulus_length,
1567       empty_exponent);
1568   EXPECT_FALSE(GenerateKeyPairInternal(
1569       algorithm, extractable, usage_mask, &public_key, &private_key));
1570
1571   // Fail with bad exponent: all zeros.
1572   std::vector<uint8> exponent_with_leading_zeros(15, 0x00);
1573   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1574       blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
1575       modulus_length,
1576       exponent_with_leading_zeros);
1577   EXPECT_FALSE(GenerateKeyPairInternal(
1578       algorithm, extractable, usage_mask, &public_key, &private_key));
1579
1580   // Key generation success using exponent with leading zeros.
1581   exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(),
1582                                      public_exponent.begin(),
1583                                      public_exponent.end());
1584   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1585       blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5,
1586       modulus_length,
1587       exponent_with_leading_zeros);
1588   EXPECT_TRUE(GenerateKeyPairInternal(
1589       algorithm, extractable, usage_mask, &public_key, &private_key));
1590   EXPECT_FALSE(public_key.isNull());
1591   EXPECT_FALSE(private_key.isNull());
1592   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
1593   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
1594   EXPECT_EQ(true, public_key.extractable());
1595   EXPECT_EQ(extractable, private_key.extractable());
1596   EXPECT_EQ(usage_mask, public_key.usages());
1597   EXPECT_EQ(usage_mask, private_key.usages());
1598
1599   // Successful WebCryptoAlgorithmIdRsaOaep key generation.
1600   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1601       blink::WebCryptoAlgorithmIdRsaOaep, modulus_length, public_exponent);
1602   EXPECT_TRUE(GenerateKeyPairInternal(
1603       algorithm, extractable, usage_mask, &public_key, &private_key));
1604   EXPECT_FALSE(public_key.isNull());
1605   EXPECT_FALSE(private_key.isNull());
1606   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
1607   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
1608   EXPECT_EQ(true, public_key.extractable());
1609   EXPECT_EQ(extractable, private_key.extractable());
1610   EXPECT_EQ(usage_mask, public_key.usages());
1611   EXPECT_EQ(usage_mask, private_key.usages());
1612
1613   // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation.
1614   algorithm = webcrypto::CreateRsaKeyGenAlgorithm(
1615       blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
1616       modulus_length,
1617       public_exponent);
1618   EXPECT_TRUE(GenerateKeyPairInternal(
1619       algorithm, extractable, usage_mask, &public_key, &private_key));
1620   EXPECT_FALSE(public_key.isNull());
1621   EXPECT_FALSE(private_key.isNull());
1622   EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type());
1623   EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type());
1624   EXPECT_EQ(true, public_key.extractable());
1625   EXPECT_EQ(extractable, private_key.extractable());
1626   EXPECT_EQ(usage_mask, public_key.usages());
1627   EXPECT_EQ(usage_mask, private_key.usages());
1628
1629   // Fail SPKI export of private key. This is an ExportKey test, but do it here
1630   // since it is expensive to generate an RSA key pair and we already have a
1631   // private key here.
1632   blink::WebArrayBuffer output;
1633   EXPECT_FALSE(
1634       ExportKeyInternal(blink::WebCryptoKeyFormatSpki, private_key, &output));
1635 }
1636
1637 TEST_F(WebCryptoImplTest, MAYBE(RsaEsRoundTrip)) {
1638   // Import a key pair.
1639   blink::WebCryptoAlgorithm algorithm =
1640       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
1641   blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1642   blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
1643   ImportRsaKeyPair(
1644       kPublicKeySpkiDerHex,
1645       kPrivateKeyPkcs8DerHex,
1646       algorithm,
1647       false,
1648       blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
1649       &public_key,
1650       &private_key);
1651
1652   // Make a maximum-length data message. RSAES can operate on messages up to
1653   // length of k - 11 bytes, where k is the octet length of the RSA modulus.
1654   const unsigned kMaxMsgSizeBytes = kModulusLength / 8 - 11;
1655   // There are two hex chars for each byte.
1656   const unsigned kMsgHexSize = kMaxMsgSizeBytes * 2;
1657   char max_data_hex[kMsgHexSize+1];
1658   std::fill(&max_data_hex[0], &max_data_hex[0] + kMsgHexSize, 'a');
1659   max_data_hex[kMsgHexSize] = '\0';
1660
1661   // Verify encrypt / decrypt round trip on a few messages. Note that RSA
1662   // encryption does not support empty input.
1663   algorithm =
1664       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
1665   const char* const kTestDataHex[] = {
1666       "ff",
1667       "0102030405060708090a0b0c0d0e0f",
1668       max_data_hex
1669   };
1670   blink::WebArrayBuffer encrypted_data;
1671   blink::WebArrayBuffer decrypted_data;
1672   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestDataHex); ++i) {
1673     SCOPED_TRACE(i);
1674     ASSERT_TRUE(EncryptInternal(
1675         algorithm,
1676         public_key,
1677         HexStringToBytes(kTestDataHex[i]),
1678         &encrypted_data));
1679     EXPECT_EQ(kModulusLength/8, encrypted_data.byteLength());
1680     ASSERT_TRUE(DecryptInternal(
1681         algorithm,
1682         private_key,
1683         reinterpret_cast<const unsigned char*>(encrypted_data.data()),
1684         encrypted_data.byteLength(),
1685         &decrypted_data));
1686     ExpectArrayBufferMatchesHex(kTestDataHex[i], decrypted_data);
1687   }
1688 }
1689
1690 TEST_F(WebCryptoImplTest, MAYBE(RsaEsKnownAnswer)) {
1691   // Because the random data in PKCS1.5 padding makes the encryption output non-
1692   // deterministic, we cannot easily do a typical known-answer test for RSA
1693   // encryption / decryption. Instead we will take a known-good encrypted
1694   // message, decrypt it, re-encrypt it, then decrypt again, verifying that the
1695   // original known cleartext is the result.
1696
1697   // The RSA public and private keys used for this test are produced by the
1698   // openssl command line:
1699   // % openssl genrsa -out pair.pem 1024
1700   // % openssl rsa -in pair.pem -out spki.der -outform DER -pubout
1701   // % openssl pkcs8 -topk8 -inform PEM -outform DER -in pair.pem -out
1702   //     pkcs8.der -nocrypt
1703   // % xxd -p spki.der
1704   // % xxd -p pkcs8.der
1705   const std::string rsa_spki_der_hex =
1706       "30819f300d06092a864886f70d010101050003818d0030818902818100a8"
1707       "d30894b93f376f7822229bfd2483e50da944c4ab803ca31979e0f47e70bf"
1708       "683c687c6b3e80f280a237cea3643fd1f7f10f7cc664dbc2ecd45be53e1c"
1709       "9b15a53c37dbdad846c0f8340c472abc7821e4aa7df185867bf38228ac3e"
1710       "cc1d97d3c8b57e21ea6ba57b2bc3814a436e910ee8ab64a0b7743a927e94"
1711       "4d3420401f7dd50203010001";
1712   const std::string rsa_pkcs8_der_hex =
1713       "30820276020100300d06092a864886f70d0101010500048202603082025c"
1714       "02010002818100a8d30894b93f376f7822229bfd2483e50da944c4ab803c"
1715       "a31979e0f47e70bf683c687c6b3e80f280a237cea3643fd1f7f10f7cc664"
1716       "dbc2ecd45be53e1c9b15a53c37dbdad846c0f8340c472abc7821e4aa7df1"
1717       "85867bf38228ac3ecc1d97d3c8b57e21ea6ba57b2bc3814a436e910ee8ab"
1718       "64a0b7743a927e944d3420401f7dd5020301000102818100896cdffb50a0"
1719       "691bd00ad9696933243a7c5861a64684e8d74b91aed0d76c28234da9303e"
1720       "8c6ea2f89b141a9d5ea9a4ddd3d8eb9503dcf05ba0b1fd76060b281e3ae4"
1721       "b9d497fb5519bdf1127db8ad412d6a722686c78df3e3002acca960c6b2a2"
1722       "42a83ace5410693c03ce3d74cb9c9a7bacc8e271812920d1f53fee9312ef"
1723       "4eb1024100d09c14418ce92af7cc62f7cdc79836d8c6e3d0d33e7229cc11"
1724       "d732cbac75aa4c56c92e409a3ccbe75d4ce63ac5adca33080690782c6371"
1725       "e3628134c3534ca603024100cf2d3206f6deea2f39b70351c51f85436200"
1726       "5aa8f643e49e22486736d536e040dc30a2b4f9be3ab212a88d1891280874"
1727       "b9a170cdeb22eaf61c27c4b082c7d1470240638411a5b3b307ec6e744802"
1728       "c2d4ba556f8bfe72c7b76e790b89bd91ac13f5c9b51d04138d80b3450c1d"
1729       "4337865601bf96748b36c8f627be719f71ac3c70b441024065ce92cfe34e"
1730       "a58bf173a2b8f3024b4d5282540ac581957db3e11a7f528535ec098808dc"
1731       "a0013ffcb3b88a25716757c86c540e07d2ad8502cdd129118822c30f0240"
1732       "420a4983040e9db46eb29f1315a0d7b41cf60428f7460fce748e9a1a7d22"
1733       "d7390fa328948e7e9d1724401374e99d45eb41474781201378a4330e8e80"
1734       "8ce63551";
1735
1736   // Similarly, the cleartext and public key encrypted ciphertext for this test
1737   // are also produced by openssl. Note that since we are using a 1024-bit key,
1738   // the cleartext size must be less than or equal to 117 bytes (modulusLength /
1739   // 8 - 11).
1740   // % openssl rand -out cleartext.bin 64
1741   // % openssl rsautl -encrypt -inkey spki.der -keyform DER -pubin -in
1742   //     cleartext.bin -out ciphertext.bin
1743   // % xxd -p cleartext.bin
1744   // % xxd -p ciphertext.bin
1745   const std::string cleartext_hex =
1746       "ec358ed141c45d7e03d4c6338aebad718e8bcbbf8f8ee6f8d9f4b9ef06d8"
1747       "84739a398c6bcbc688418b2ff64761dc0ccd40e7d52bed03e06946d0957a"
1748       "eef9e822";
1749   const std::string ciphertext_hex =
1750       "6106441c2b7a4b1a16260ed1ae4fe6135247345dc8e674754bbda6588c6c"
1751       "0d95a3d4d26bb34cdbcbe327723e80343bd7a15cd4c91c3a44e6cb9c6cd6"
1752       "7ad2e8bf41523188d9b36dc364a838642dcbc2c25e85dfb2106ba47578ca"
1753       "3bbf8915055aea4fa7c3cbfdfbcc163f04c234fb6d847f39bab9612ecbee"
1754       "04626e945c3ccf42";
1755
1756   // Import the key pair.
1757   blink::WebCryptoAlgorithm algorithm =
1758       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
1759   blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1760   blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
1761   ImportRsaKeyPair(
1762       rsa_spki_der_hex,
1763       rsa_pkcs8_der_hex,
1764       algorithm,
1765       false,
1766       blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
1767       &public_key,
1768       &private_key);
1769
1770   // Decrypt the known-good ciphertext with the private key. As a check we must
1771   // get the known original cleartext.
1772   blink::WebArrayBuffer decrypted_data;
1773   ASSERT_TRUE(DecryptInternal(
1774       algorithm,
1775       private_key,
1776       HexStringToBytes(ciphertext_hex),
1777       &decrypted_data));
1778   EXPECT_FALSE(decrypted_data.isNull());
1779   ExpectArrayBufferMatchesHex(cleartext_hex, decrypted_data);
1780
1781   // Encrypt this decrypted data with the public key.
1782   blink::WebArrayBuffer encrypted_data;
1783   ASSERT_TRUE(EncryptInternal(
1784       algorithm,
1785       public_key,
1786       reinterpret_cast<const unsigned char*>(decrypted_data.data()),
1787       decrypted_data.byteLength(),
1788       &encrypted_data));
1789   EXPECT_EQ(128u, encrypted_data.byteLength());
1790
1791   // Finally, decrypt the newly encrypted result with the private key, and
1792   // compare to the known original cleartext.
1793   decrypted_data.reset();
1794   ASSERT_TRUE(DecryptInternal(
1795       algorithm,
1796       private_key,
1797       reinterpret_cast<const unsigned char*>(encrypted_data.data()),
1798       encrypted_data.byteLength(),
1799       &decrypted_data));
1800   EXPECT_FALSE(decrypted_data.isNull());
1801   ExpectArrayBufferMatchesHex(cleartext_hex, decrypted_data);
1802 }
1803
1804 TEST_F(WebCryptoImplTest, MAYBE(RsaEsFailures)) {
1805   // Import a key pair.
1806   blink::WebCryptoAlgorithm algorithm =
1807       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
1808   blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1809   blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
1810   ImportRsaKeyPair(
1811       kPublicKeySpkiDerHex,
1812       kPrivateKeyPkcs8DerHex,
1813       algorithm,
1814       false,
1815       blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
1816       &public_key,
1817       &private_key);
1818
1819   // Fail encrypt with a private key.
1820   blink::WebArrayBuffer encrypted_data;
1821   const std::string message_hex_str("0102030405060708090a0b0c0d0e0f");
1822   const std::vector<uint8> message_hex(HexStringToBytes(message_hex_str));
1823   EXPECT_FALSE(
1824       EncryptInternal(algorithm, private_key, message_hex, &encrypted_data));
1825
1826   // Fail encrypt with empty message.
1827   EXPECT_FALSE(EncryptInternal(
1828       algorithm, public_key, std::vector<uint8>(), &encrypted_data));
1829
1830   // Fail encrypt with message too large. RSAES can operate on messages up to
1831   // length of k - 11 bytes, where k is the octet length of the RSA modulus.
1832   const unsigned kMaxMsgSizeBytes = kModulusLength / 8 - 11;
1833   EXPECT_FALSE(EncryptInternal(algorithm,
1834                                public_key,
1835                                std::vector<uint8>(kMaxMsgSizeBytes + 1, '0'),
1836                                &encrypted_data));
1837
1838   // Generate encrypted data.
1839   EXPECT_TRUE(
1840       EncryptInternal(algorithm, public_key, message_hex, &encrypted_data));
1841
1842   // Fail decrypt with a public key.
1843   blink::WebArrayBuffer decrypted_data;
1844   EXPECT_FALSE(DecryptInternal(
1845       algorithm,
1846       public_key,
1847       reinterpret_cast<const unsigned char*>(encrypted_data.data()),
1848       encrypted_data.byteLength(),
1849       &decrypted_data));
1850
1851   // Corrupt encrypted data; ensure decrypt fails because padding was disrupted.
1852   std::vector<uint8> corrupted_data(
1853       static_cast<uint8*>(encrypted_data.data()),
1854       static_cast<uint8*>(encrypted_data.data()) + encrypted_data.byteLength());
1855   corrupted_data[corrupted_data.size() / 2] ^= 0x01;
1856   EXPECT_FALSE(
1857       DecryptInternal(algorithm, private_key, corrupted_data, &decrypted_data));
1858
1859   // TODO(padolph): Are there other specific data corruption scenarios to
1860   // consider?
1861
1862   // Do a successful decrypt with good data just for confirmation.
1863   EXPECT_TRUE(DecryptInternal(
1864       algorithm,
1865       private_key,
1866       reinterpret_cast<const unsigned char*>(encrypted_data.data()),
1867       encrypted_data.byteLength(),
1868       &decrypted_data));
1869   ExpectArrayBufferMatchesHex(message_hex_str, decrypted_data);
1870 }
1871
1872 TEST_F(WebCryptoImplTest, MAYBE(RsaSsaSignVerifyFailures)) {
1873   // Import a key pair.
1874   blink::WebCryptoAlgorithm algorithm = CreateRsaAlgorithmWithInnerHash(
1875       blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
1876       blink::WebCryptoAlgorithmIdSha1);
1877   blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1878   blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
1879   ImportRsaKeyPair(
1880       kPublicKeySpkiDerHex,
1881       kPrivateKeyPkcs8DerHex,
1882       algorithm,
1883       false,
1884       blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
1885       &public_key,
1886       &private_key);
1887
1888   blink::WebArrayBuffer signature;
1889   bool signature_match;
1890
1891   // Compute a signature.
1892   const std::vector<uint8> data = HexStringToBytes("010203040506070809");
1893   ASSERT_TRUE(SignInternal(algorithm, private_key, data, &signature));
1894
1895   // Ensure truncated signature does not verify by passing one less byte.
1896   EXPECT_TRUE(VerifySignatureInternal(
1897       algorithm,
1898       public_key,
1899       static_cast<const unsigned char*>(signature.data()),
1900       signature.byteLength() - 1,
1901       data,
1902       &signature_match));
1903   EXPECT_FALSE(signature_match);
1904
1905   // Ensure corrupted signature does not verify.
1906   std::vector<uint8> corrupt_sig(
1907       static_cast<uint8*>(signature.data()),
1908       static_cast<uint8*>(signature.data()) + signature.byteLength());
1909   corrupt_sig[corrupt_sig.size() / 2] ^= 0x1;
1910   EXPECT_TRUE(VerifySignatureInternal(
1911       algorithm,
1912       public_key,
1913       webcrypto::Uint8VectorStart(corrupt_sig),
1914       corrupt_sig.size(),
1915       data,
1916       &signature_match));
1917   EXPECT_FALSE(signature_match);
1918
1919   // Ensure signatures that are greater than the modulus size fail.
1920   const unsigned long_message_size_bytes = 1024;
1921   DCHECK_GT(long_message_size_bytes, kModulusLength/8);
1922   const unsigned char kLongSignature[long_message_size_bytes] = { 0 };
1923   EXPECT_TRUE(VerifySignatureInternal(
1924       algorithm,
1925       public_key,
1926       kLongSignature,
1927       sizeof(kLongSignature),
1928       data,
1929       &signature_match));
1930   EXPECT_FALSE(signature_match);
1931
1932   // Ensure that verifying using a private key, rather than a public key, fails.
1933   EXPECT_FALSE(VerifySignatureInternal(
1934       algorithm,
1935       private_key,
1936       static_cast<const unsigned char*>(signature.data()),
1937       signature.byteLength(),
1938       data,
1939       &signature_match));
1940
1941   // Ensure that signing using a public key, rather than a private key, fails.
1942   EXPECT_FALSE(SignInternal(algorithm, public_key, data, &signature));
1943
1944   // Ensure that signing and verifying with an incompatible algorithm fails.
1945   algorithm =
1946       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5);
1947   EXPECT_FALSE(SignInternal(algorithm, private_key, data, &signature));
1948   EXPECT_FALSE(VerifySignatureInternal(
1949       algorithm,
1950       public_key,
1951       static_cast<const unsigned char*>(signature.data()),
1952       signature.byteLength(),
1953       data,
1954       &signature_match));
1955
1956   // Some crypto libraries (NSS) can automatically select the RSA SSA inner hash
1957   // based solely on the contents of the input signature data. In the Web Crypto
1958   // implementation, the inner hash should be specified uniquely by the input
1959   // algorithm parameter. To validate this behavior, call Verify with a computed
1960   // signature that used one hash type (SHA-1), but pass in an algorithm with a
1961   // different inner hash type (SHA-256). If the hash type is determined by the
1962   // signature itself (undesired), the verify will pass, while if the hash type
1963   // is specified by the input algorithm (desired), the verify will fail.
1964
1965   // Compute a signature using SHA-1 as the inner hash.
1966   EXPECT_TRUE(SignInternal(CreateRsaAlgorithmWithInnerHash(
1967                                blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
1968                                blink::WebCryptoAlgorithmIdSha1),
1969                            private_key,
1970                            data,
1971                            &signature));
1972
1973   // Now verify using an algorithm whose inner hash is SHA-256, not SHA-1. The
1974   // signature should not verify.
1975   // NOTE: public_key was produced by generateKey, and so its associated
1976   // algorithm has WebCryptoRsaKeyGenParams and not WebCryptoRsaSsaParams. Thus
1977   // it has no inner hash to conflict with the input algorithm.
1978   bool is_match;
1979   EXPECT_TRUE(VerifySignatureInternal(
1980       CreateRsaAlgorithmWithInnerHash(
1981           blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
1982           blink::WebCryptoAlgorithmIdSha256),
1983       public_key,
1984       static_cast<const unsigned char*>(signature.data()),
1985       signature.byteLength(),
1986       data,
1987       &is_match));
1988   EXPECT_FALSE(is_match);
1989 }
1990
1991 TEST_F(WebCryptoImplTest, MAYBE(RsaSignVerifyKnownAnswer)) {
1992   // Use the NIST test vectors from Example 1 of
1993   // ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt
1994   // These vectors are known answers for RSA PKCS#1 v1.5 Signature with a SHA-1
1995   // digest, using a predefined key pair.
1996
1997   struct TestCase {
1998     const std::string message_hex;
1999     const std::string signature_hex;
2000   };
2001
2002   // The following data are the input messages and corresponding computed RSA
2003   // PKCS#1 v1.5 signatures from the NIST link above.
2004   const TestCase kTests[] = {
2005       // PKCS#1 v1.5 Signature Example 1.1
2006       {"cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b6"
2007        "2371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb76"
2008        "9757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb0"
2009        "61a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d61"
2010        "93c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c"
2011        "296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16"
2012        "be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0",
2013        "6bc3a06656842930a247e30d5864b4d819236ba7c68965862ad7dbc4e24af28e"
2014        "86bb531f03358be5fb74777c6086f850caef893f0d6fcc2d0c91ec013693b4ea"
2015        "00b80cd49aac4ecb5f8911afe539ada4a8f3823d1d13e472d1490547c659c761"
2016        "7f3d24087ddb6f2b72096167fc097cab18e9a458fcb634cdce8ee35894c484d7"},
2017       // PKCS#1 v1.5 Signature Example 1.2
2018       {"851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f"
2019        "71a1cca582d43ecc72b1bca16dfc7013226b9e",
2020        "84fd2ce734ec1da828d0f15bf49a8707c15d05948136de537a3db421384167c8"
2021        "6fae022587ee9e137daee754738262932d271c744c6d3a189ad4311bdb020492"
2022        "e322fbddc40406ea860d4e8ea2a4084aa98b9622a446756fdb740ddb3d91db76"
2023        "70e211661bbf8709b11c08a70771422d1a12def29f0688a192aebd89e0f896f8"},
2024       // PKCS#1 v1.5 Signature Example1.3
2025       {"a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef"
2026        "8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955"
2027        "fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c7"
2028        "45e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4"
2029        "564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c"
2030        "031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa"
2031        "299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef4169713"
2032        "38e7d470",
2033        "0b1f2e5180e5c7b4b5e672929f664c4896e50c35134b6de4d5a934252a3a245f"
2034        "f48340920e1034b7d5a5b524eb0e1cf12befef49b27b732d2c19e1c43217d6e1"
2035        "417381111a1d36de6375cf455b3c9812639dbc27600c751994fb61799ecf7da6"
2036        "bcf51540afd0174db4033188556675b1d763360af46feeca5b60f882829ee7b2"},
2037       // PKCS#1 v1.5 Signature Example 1.4
2038       {"bc656747fa9eafb3f0",
2039        "45607ad611cf5747a41ac94d0ffec878bdaf63f6b57a4b088bf36e34e109f840"
2040        "f24b742ada16102dabf951cbc44f8982e94ed4cd09448d20ec0efa73545f80b6"
2041        "5406bed6194a61c340b4ad1568cbb75851049f11af1734964076e02029aee200"
2042        "e40e80be0f4361f69841c4f92a4450a2286d43289b405554c54d25c6ecb584f4"},
2043       // PKCS#1 v1.5 Signature Example 1.5
2044       {"b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776"
2045        "c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575"
2046        "480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f"
2047        "32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc"
2048        "5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4",
2049        "54be9d90877515f450279c15b5f61ad6f15ecc95f18cbed82b65b1667a575809"
2050        "587994668044f3bc2ae7f884501f64f0b43f588cfa205a6ab704328c2d4ab92a"
2051        "7ae13440614d3e085f401da9ad28e2105e4a0edb681a6424df047388ce051ee9"
2052        "df7bc2163fe347520ad51ccd518064383e741acad3cbdc2cb5a7c68e868464c2"},
2053       // PKCS#1 v1.5 Signature Example 1.6
2054       {"10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec"
2055        "74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4"
2056        "352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b7"
2057        "05a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb87"
2058        "94c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373"
2059        "d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb"
2060        "3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6"
2061        "138d144f8ce4e2da73",
2062        "0e6ff63a856b9cbd5dbe423183122047dd39d6f76d1b2310e546fe9ee73b33ef"
2063        "a7c78f9474455c9e5b88cb383aafc3698668e7b7a59a9cbb5b0897b6c5afb7f8"
2064        "bac4b924e98d760a15fc43d2814ab2d5187f79bed9915a93397ebc22a7677506"
2065        "a02e076d3ffdc0441dbd4db00453dc28d830e0573f77b817b505c38b4a4bb5d0"},
2066       // PKCS#1 v1.5 Signature Example 1.7
2067       {"efb5da1b4d1e6d9a5dff92d0184da7e31f877d1281ddda625664869e8379e67a"
2068        "d3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8b34"
2069        "66f5ab15d69553952939ec23e61d58497fac76aa1c0bb5a3cb4a54383587c7bb"
2070        "78d13eefda205443e6ce4365802df55c64713497984e7ca96722b3edf84d56",
2071        "8385d58533a995f72df262b70f40b391ddf515f464b9d2cc2d66398fc05689d8"
2072        "11632946d62eabdca7a31fcf6cd6c981d28bbc29083e4a6d5b2b378ca4e540f0"
2073        "60b96d53ad2693f82178b94e2e2f86b9accfa02025107e062ab7080175684501"
2074        "028f676461d81c008fe4750671649970878fc175cf98e96b2ecbf6874d77dacb"},
2075       // PKCS#1 v1.5 Signature Example 1.8
2076       {"53bb58ce42f1984940552657233b14969af365c0a561a4132af18af39432280e"
2077        "3e437082434b19231837184f02cf2b2e726bebf74d7ae3256d8b72f3eafdb134"
2078        "d33de06f2991d299d59f5468d43b9958d6a968f5969edbbc6e7185cbc716c7c9"
2079        "45dafa9cc71ddfaaa01094a452ddf5e2407320400bf05ea9729cafbf0600e788"
2080        "07ef9462e3fde32ed7d981a56f4751ef64fb4549910ecc911d728053b3994300"
2081        "4740e6f5821fe8d75c0617bf2c6b24bbfc34013fc95f0dedf5ba297f504fb833"
2082        "da2a436d1d8ff1cc5193e2a64389fced918e7feb6716330f66801db9497549cf"
2083        "1d3bd97cf1bc6255",
2084        "8e1f3d26ec7c6bbb8c54c5d25f3120587803af6d3c2b99a37ced6a3657d4ae54"
2085        "266f63fffde660c866d65d0ab0589e1d12d9ce6054b05c8668ae127171ccaae7"
2086        "f1cd409677f52157b6123ab227f27a00966d1439b42a32169d1070394026fc8b"
2087        "c93545b1ac252d0f7da751c02e33a47831fbd71514c2bbbd3adb6740c0fd68ad"},
2088       // PKCS#1 v1.5 Signature Example 1.9
2089       {"27cadc698450945f204ec3cf8c6cbd8ceb4cc0cbe312274fa96b04deac855160"
2090        "c0e04e4ac5d38210c27c",
2091        "7b63f9223356f35f6117f68c8f8220034fc2384ab5dc6904141f139314d6ee89"
2092        "f54ec6ffd18c413a23c5931c7fbb13c555ccfd590e0eaa853c8c94d2520cd425"
2093        "0d9a05a193b65dc749b82478af0156ee1de55ddad33ec1f0099cad6c891a3617"
2094        "c7393d05fbfbbb00528a001df0b204ebdf1a341090dea89f870a877458427f7b"},
2095       // PKCS#1 v1.5 Signature Example 1.10
2096       {"716407e901b9ef92d761b013fd13eb7ad72aed",
2097        "2a22dbe3774d5b297201b55a0f17f42dce63b7845cb325cfe951d0badb5c5a14"
2098        "472143d896c86cc339f83671164215abc97862f2151654e75a3b357c37311b3d"
2099        "7268cab540202e23bee52736f2cd86cce0c7dbde95e1c600a47395dc5eb0a472"
2100        "153fbc4fb21b643e0c04ae14dd37e97e617a7567c89652219781001ba6f83298"},
2101       // PKCS#1 v1.5 Signature Example 1.11
2102       {"46c24e4103001629c712dd4ce8d747ee595d6c744ccc4f71347d9b8abf49d1b8"
2103        "fb2ef91b95dc899d4c0e3d2997e638f4cf3f68e0498de5aabd13f0dfe02ff26b"
2104        "a4379104e78ffa95ffbd15067ef8cbd7eb7860fecc71abe13d5c720a66851f2d"
2105        "efd4e795054d7bec024bb422a46a7368b56d95b47aebafbeadd612812593a70d"
2106        "b9f96d451ee15edb299308d777f4bb68ed3377c32156b41b7a9c92a14c8b8114"
2107        "4399c56a5a432f4f770aa97da8415d0bda2e813206031e70620031c881d616bf"
2108        "fd5f03bf147c1e73766c26246208",
2109        "12235b0b406126d9d260d447e923a11051fb243079f446fd73a70181d53634d7"
2110        "a0968e4ee27777eda63f6e4a3a91ad5985998a4848da59ce697b24bb332fa2ad"
2111        "9ce462ca4affdc21dab908e8ce15af6eb9105b1abcf39142aa17b34c4c092386"
2112        "a7abbfe028afdbebc14f2ce26fbee5edeca11502d39a6b7403154843d98a62a7"},
2113       // PKCS#1 v1.5 Signature Example 1.12
2114       {"bc99a932aa16d622bfff79c50b4c42358673261129e28d6a918ff1b0f1c4f46a"
2115        "d8afa98b0ca0f56f967975b0a29be882e93b6cd3fc33e1faef72e52b2ae0a3f1"
2116        "2024506e25690e902e782982145556532284cf505789738f4da31fa1333d3af8"
2117        "62b2ba6b6ce7ab4cce6aba",
2118        "872ec5ad4f1846256f17e9936ac50e43e9963ea8c1e76f15879b7874d77d122a"
2119        "609dc8c561145b94bf4ffdffdeb17e6e76ffc6c10c0747f5e37a9f434f5609e7"
2120        "9da5250215a457afdf12c6507cc1551f54a28010595826a2c9b97fa0aa851cc6"
2121        "8b705d7a06d720ba027e4a1c0b019500fb63b78071684dcfa9772700b982dc66"},
2122       // PKCS#1 v1.5 Signature Example 1.13
2123       {"731e172ac063992c5b11ba170dfb23bb000d47ba195329cf278061037381514c"
2124        "146064c5285db130dd5bae98b772225950eab05d3ea996f6fffb9a8c8622913f"
2125        "279914c89ada4f3dd77666a868bfcbff2b95b7daf453d4e2c9d75beee7f8e709"
2126        "05e4066a4f73aecc67f956aa5a3292b8488c917d317cfdc86253e690381e15ab",
2127        "76204eacc1d63ec1d6ad5bd0692e1a2f686df6e64ca945c77a824de212efa6d9"
2128        "782d81b4591403ff4020620298c07ebd3a8a61c5bf4dad62cbfc4ae6a03937be"
2129        "4b49a216d570fc6e81872937876e27bd19cf601effc30ddca573c9d56cd4569b"
2130        "db4851c450c42cb21e738cdd61027b8be5e9b410fc46aa3f29e4be9e64451346"},
2131       // PKCS#1 v1.5 Signature Example 1.14
2132       {"0211382683a74d8d2a2cb6a06550563be1c26ca62821e4ff163b720464fc3a28"
2133        "d91bedddc62749a5538eaf41fbe0c82a77e06ad99383c9e985ffb8a93fd4d7c5"
2134        "8db51ad91ba461d69a8fd7ddabe2496757a0c49122c1a79a85cc0553e8214d03"
2135        "6dfe0185efa0d05860c612fa0882c82d246e5830a67355dff18a2c36b732f988"
2136        "cfedc562264c6254b40fcabb97b760947568dcd6a17cda6ee8855bddbab93702"
2137        "471aa0cfb1bed2e13118eba1175b73c96253c108d0b2aba05ab8e17e84392e20"
2138        "085f47404d8365527dc3fb8f2bb48a50038e71361ccf973407",
2139        "525500918331f1042eae0c5c2054aa7f92deb26991b5796634f229daf9b49eb2"
2140        "054d87319f3cfa9b466bd075ef6699aea4bd4a195a1c52968b5e2b75e092d846"
2141        "ea1b5cc27905a8e1d5e5de0edfdb21391ebb951864ebd9f0b0ec35b654287136"
2142        "0a317b7ef13ae06af684e38e21b1e19bc7298e5d6fe0013a164bfa25d3e7313d"},
2143       // PKCS#1 v1.5 Signature Example 1.15
2144       {"fc6b700d22583388ab2f8dafcaf1a05620698020da4bae44dafbd0877b501250"
2145        "6dc3181d5c66bf023f348b41fd9f94795ab96452a4219f2d39d72af359cf1956"
2146        "51c7",
2147        "4452a6cc2626b01e95ab306df0d0cc7484fbab3c22e9703283567f66eadc248d"
2148        "bda58fce7dd0c70cce3f150fca4b369dff3b6237e2b16281ab55b53fb13089c8"
2149        "5cd265056b3d62a88bfc2135b16791f7fbcab9fd2dc33becb617be419d2c0461"
2150        "42a4d47b338314552edd4b6fe9ce1104ecec4a9958d7331e930fc09bf08a6e64"},
2151       // PKCS#1 v1.5 Signature Example 1.16
2152       {"13ba086d709cfa5fedaa557a89181a6140f2300ed6d7c3febb6cf68abebcbc67"
2153        "8f2bca3dc2330295eec45bb1c4075f3ada987eae88b39c51606cb80429e649d9"
2154        "8acc8441b1f8897db86c5a4ce0abf28b1b81dca3667697b850696b74a5ebd85d"
2155        "ec56c90f8abe513efa857853720be319607921bca947522cd8fac8cace5b827c"
2156        "3e5a129e7ee57f6b84932f14141ac4274e8cbb46e6912b0d3e2177d499d1840c"
2157        "d47d4d7ae0b4cdc4d3",
2158        "1f3b5a87db72a2c97bb3eff2a65a301268eacd89f42abc1098c1f2de77b0832a"
2159        "65d7815feb35070063f221bb3453bd434386c9a3fde18e3ca1687fb649e86c51"
2160        "d658619dde5debb86fe15491ff77ab748373f1be508880d66ea81e870e91cdf1"
2161        "704875c17f0b10103188bc64eef5a3551b414c733670215b1a22702562581ab1"},
2162       // PKCS#1 v1.5 Signature Example 1.17
2163       {"eb1e5935",
2164        "370cb9839ae6074f84b2acd6e6f6b7921b4b523463757f6446716140c4e6c0e7"
2165        "5bec6ad0197ebfa86bf46d094f5f6cd36dca3a5cc73c8bbb70e2c7c9ab5d964e"
2166        "c8e3dfde481b4a1beffd01b4ad15b31ae7aebb9b70344a9411083165fdf9c375"
2167        "4bbb8b94dd34bd4813dfada1f6937de4267d5597ca09a31e83d7f1a79dd19b5e"},
2168       // PKCS#1 v1.5 Signature Example 1.18
2169       {"6346b153e889c8228209630071c8a57783f368760b8eb908cfc2b276",
2170        "2479c975c5b1ae4c4e940f473a9045b8bf5b0bfca78ec29a38dfbedc8a749b7a"
2171        "2692f7c52d5bc7c831c7232372a00fed3b6b49e760ec99e074ff2eead5134e83"
2172        "05725dfa39212b84bd4b8d80bc8bc17a512823a3beb18fc08e45ed19c26c8177"
2173        "07d67fb05832ef1f12a33e90cd93b8a780319e2963ca25a2af7b09ad8f595c21"},
2174       // PKCS#1 v1.5 Signature Example 1.19
2175       {"64702db9f825a0f3abc361974659f5e9d30c3aa4f56feac69050c72905e77fe0"
2176        "c22f88a378c21fcf45fe8a5c717302093929",
2177        "152f3451c858d69594e6567dfb31291c1ee7860b9d15ebd5a5edd276ac3e6f7a"
2178        "8d1480e42b3381d2be023acf7ebbdb28de3d2163ae44259c6df98c335d045b61"
2179        "dac9dba9dbbb4e6ab4a083cd76b580cbe472206a1a9fd60680ceea1a570a29b0"
2180        "881c775eaef5525d6d2f344c28837d0aca422bbb0f1aba8f6861ae18bd73fe44"},
2181       // PKCS#1 v1.5 Signature Example 1.20
2182       {"941921de4a1c9c1618d6f3ca3c179f6e29bae6ddf9a6a564f929e3ce82cf3265"
2183        "d7837d5e692be8dcc9e86c",
2184        "7076c287fc6fff2b20537435e5a3107ce4da10716186d01539413e609d27d1da"
2185        "6fd952c61f4bab91c045fa4f8683ecc4f8dde74227f773cff3d96db84718c494"
2186        "4b06affeba94b725f1b07d3928b2490a85c2f1abf492a9177a7cd2ea0c966875"
2187        "6f825bbec900fa8ac3824e114387ef573780ca334882387b94e5aad7a27a28dc"}};
2188
2189   // Import the key pair.
2190   blink::WebCryptoAlgorithm algorithm = CreateRsaAlgorithmWithInnerHash(
2191       blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
2192       blink::WebCryptoAlgorithmIdSha1);
2193   blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
2194   blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
2195   ImportRsaKeyPair(
2196       kPublicKeySpkiDerHex,
2197       kPrivateKeyPkcs8DerHex,
2198       algorithm,
2199       false,
2200       blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify,
2201       &public_key,
2202       &private_key);
2203
2204   // Validate the signatures are computed and verified as expected.
2205   blink::WebArrayBuffer signature;
2206   for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kTests); ++idx) {
2207     SCOPED_TRACE(idx);
2208     const TestCase& test = kTests[idx];
2209     const std::vector<uint8> message = HexStringToBytes(test.message_hex);
2210
2211     signature.reset();
2212     ASSERT_TRUE(SignInternal(algorithm, private_key, message, &signature));
2213     ExpectArrayBufferMatchesHex(test.signature_hex, signature);
2214
2215     bool is_match = false;
2216     ASSERT_TRUE(VerifySignatureInternal(
2217         algorithm,
2218         public_key,
2219         HexStringToBytes(test.signature_hex),
2220         message,
2221         &is_match));
2222     EXPECT_TRUE(is_match);
2223   }
2224 }
2225
2226 TEST_F(WebCryptoImplTest, MAYBE(AesKwKeyImport)) {
2227   blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
2228   blink::WebCryptoAlgorithm algorithm =
2229       webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw);
2230
2231   // Import a 128-bit Key Encryption Key (KEK)
2232   std::string key_raw_hex_in = "025a8cf3f08b4f6c5f33bbc76a471939";
2233   ASSERT_TRUE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2234                                 HexStringToBytes(key_raw_hex_in),
2235                                 algorithm,
2236                                 true,
2237                                 blink::WebCryptoKeyUsageWrapKey,
2238                                 &key));
2239   blink::WebArrayBuffer key_raw_out;
2240   EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw,
2241                                 key,
2242                                 &key_raw_out));
2243   ExpectArrayBufferMatchesHex(key_raw_hex_in, key_raw_out);
2244
2245   // Import a 192-bit KEK
2246   key_raw_hex_in = "c0192c6466b2370decbb62b2cfef4384544ffeb4d2fbc103";
2247   ASSERT_TRUE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2248                                 HexStringToBytes(key_raw_hex_in),
2249                                 algorithm,
2250                                 true,
2251                                 blink::WebCryptoKeyUsageWrapKey,
2252                                 &key));
2253   EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw,
2254                                 key,
2255                                 &key_raw_out));
2256   ExpectArrayBufferMatchesHex(key_raw_hex_in, key_raw_out);
2257
2258   // Import a 256-bit Key Encryption Key (KEK)
2259   key_raw_hex_in =
2260       "e11fe66380d90fa9ebefb74e0478e78f95664d0c67ca20ce4a0b5842863ac46f";
2261   ASSERT_TRUE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2262                                 HexStringToBytes(key_raw_hex_in),
2263                                 algorithm,
2264                                 true,
2265                                 blink::WebCryptoKeyUsageWrapKey,
2266                                 &key));
2267   EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw,
2268                                 key,
2269                                 &key_raw_out));
2270   ExpectArrayBufferMatchesHex(key_raw_hex_in, key_raw_out);
2271
2272   // Fail import of 0 length key
2273   EXPECT_FALSE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2274                                  HexStringToBytes(""),
2275                                  algorithm,
2276                                  true,
2277                                  blink::WebCryptoKeyUsageWrapKey,
2278                                  &key));
2279
2280   // Fail import of 124-bit KEK
2281   key_raw_hex_in = "3e4566a2bdaa10cb68134fa66c15ddb";
2282   EXPECT_FALSE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2283                                  HexStringToBytes(key_raw_hex_in),
2284                                  algorithm,
2285                                  true,
2286                                  blink::WebCryptoKeyUsageWrapKey,
2287                                  &key));
2288
2289   // Fail import of 200-bit KEK
2290   key_raw_hex_in = "0a1d88608a5ad9fec64f1ada269ebab4baa2feeb8d95638c0e";
2291   EXPECT_FALSE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2292                                  HexStringToBytes(key_raw_hex_in),
2293                                  algorithm,
2294                                  true,
2295                                  blink::WebCryptoKeyUsageWrapKey,
2296                                  &key));
2297
2298   // Fail import of 260-bit KEK
2299   key_raw_hex_in =
2300       "72d4e475ff34215416c9ad9c8281247a4d730c5f275ac23f376e73e3bce8d7d5a";
2301   EXPECT_FALSE(ImportKeyInternal(blink::WebCryptoKeyFormatRaw,
2302                                  HexStringToBytes(key_raw_hex_in),
2303                                  algorithm,
2304                                  true,
2305                                  blink::WebCryptoKeyUsageWrapKey,
2306                                  &key));
2307 }
2308
2309 // TODO(eroman):
2310 //   * Test decryption when the tag length exceeds input size
2311 //   * Test decryption with empty input
2312 //   * Test decryption with tag length of 0.
2313 TEST_F(WebCryptoImplTest, MAYBE(AesGcmSampleSets)) {
2314   // Some Linux test runners may not have a new enough version of NSS.
2315   if (!SupportsAesGcm()) {
2316     LOG(WARNING) << "AES GCM not supported, skipping tests";
2317     return;
2318   }
2319
2320   struct TestCase {
2321     const char* key;
2322     const char* iv;
2323     const char* plain_text;
2324     const char* cipher_text;
2325     const char* additional_data;
2326     const char* authentication_tag;
2327   };
2328
2329   // These tests come from the NIST GCM test vectors:
2330   // http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
2331   //
2332   // Both encryption and decryption are expected to work.
2333   TestCase kTests[] = {
2334     // [Keylen = 128]
2335     // [IVlen = 96]
2336     // [PTlen = 0]
2337     // [AADlen = 0]
2338     // [Taglen = 128]
2339     {
2340       // key
2341       "cf063a34d4a9a76c2c86787d3f96db71",
2342       // iv
2343       "113b9785971864c83b01c787",
2344       // plain_text
2345       "",
2346       // cipher_text
2347       "",
2348       // additional_data
2349       "",
2350       // authentication_tag
2351       "72ac8493e3a5228b5d130a69d2510e42",
2352     },
2353
2354     // [Keylen = 128]
2355     // [IVlen = 96]
2356     // [PTlen = 0]
2357     // [AADlen = 128]
2358     // [Taglen = 120]
2359     {
2360       // key
2361       "6dfa1a07c14f978020ace450ad663d18",
2362       // iv
2363       "34edfa462a14c6969a680ec1",
2364       // plain_text
2365       "",
2366       // cipher_text
2367       "",
2368       // additional_data
2369       "2a35c7f5f8578e919a581c60500c04f6",
2370       // authentication_tag
2371       "751f3098d59cf4ea1d2fb0853bde1c"
2372     },
2373
2374     // [Keylen = 128]
2375     // [IVlen = 96]
2376     // [PTlen = 128]
2377     // [AADlen = 128]
2378     // [Taglen = 112]
2379     {
2380       // key
2381       "ed6cd876ceba555706674445c229c12d",
2382       // iv
2383       "92ecbf74b765bc486383ca2e",
2384       // plain_text
2385       "bfaaaea3880d72d4378561e2597a9b35",
2386       // cipher_text
2387       "bdd2ed6c66fa087dce617d7fd1ff6d93",
2388       // additional_data
2389       "95bd10d77dbe0e87fb34217f1a2e5efe",
2390       // authentication_tag
2391       "ba82e49c55a22ed02ca67da4ec6f"
2392     },
2393
2394     // [Keylen = 192]
2395     // [IVlen = 96]
2396     // [PTlen = 128]
2397     // [AADlen = 384]
2398     // [Taglen = 112]
2399     {
2400       // key
2401       "ae7972c025d7f2ca3dd37dcc3d41c506671765087c6b61b8",
2402       // iv
2403       "984c1379e6ba961c828d792d",
2404       // plain_text
2405       "d30b02c343487105219d6fa080acc743",
2406       // cipher_text
2407       "c4489fa64a6edf80e7e6a3b8855bc37c",
2408       // additional_data
2409       "edd8f630f9bbc31b0acf122998f15589d6e6e3e1a3ec89e0c6a6ece751610e"
2410       "bbf57fdfb9d82028ff1d9faebe37a268c1",
2411       // authentication_tag
2412       "772ee7de0f91a981c36c93a35c88"
2413     }
2414   };
2415
2416   // Note that WebCrypto appends the authentication tag to the ciphertext.
2417   for (size_t index = 0; index < ARRAYSIZE_UNSAFE(kTests); index++) {
2418     SCOPED_TRACE(index);
2419     const TestCase& test = kTests[index];
2420
2421     blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
2422         test.key,
2423         webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm),
2424         blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
2425
2426     // Verify exported raw key is identical to the imported data
2427     blink::WebArrayBuffer raw_key;
2428     EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
2429     ExpectArrayBufferMatchesHex(test.key, raw_key);
2430
2431     const std::vector<uint8> test_iv = HexStringToBytes(test.iv);
2432     const std::vector<uint8> test_additional_data =
2433         HexStringToBytes(test.additional_data);
2434     const std::vector<uint8> test_plain_text =
2435         HexStringToBytes(test.plain_text);
2436     const std::vector<uint8> test_authentication_tag =
2437         HexStringToBytes(test.authentication_tag);
2438     const unsigned test_tag_size_bits = test_authentication_tag.size() * 8;
2439     const std::vector<uint8> test_cipher_text =
2440         HexStringToBytes(test.cipher_text);
2441
2442     // Test encryption.
2443     std::vector<uint8> cipher_text;
2444     std::vector<uint8> authentication_tag;
2445     EXPECT_TRUE(AesGcmEncrypt(key, test_iv, test_additional_data,
2446                               test_tag_size_bits, test_plain_text,
2447                               &cipher_text, &authentication_tag));
2448
2449     ExpectVectorMatchesHex(test.cipher_text, cipher_text);
2450     ExpectVectorMatchesHex(test.authentication_tag, authentication_tag);
2451
2452     // Test decryption.
2453     blink::WebArrayBuffer plain_text;
2454     EXPECT_TRUE(AesGcmDecrypt(key, test_iv, test_additional_data,
2455                               test_tag_size_bits, test_cipher_text,
2456                               test_authentication_tag, &plain_text));
2457     ExpectArrayBufferMatchesHex(test.plain_text, plain_text);
2458
2459     // Decryption should fail if any of the inputs are tampered with.
2460     EXPECT_FALSE(AesGcmDecrypt(key, Corrupted(test_iv), test_additional_data,
2461                                test_tag_size_bits, test_cipher_text,
2462                                test_authentication_tag, &plain_text));
2463     EXPECT_FALSE(AesGcmDecrypt(key, test_iv, Corrupted(test_additional_data),
2464                                test_tag_size_bits, test_cipher_text,
2465                                test_authentication_tag, &plain_text));
2466     EXPECT_FALSE(AesGcmDecrypt(key, test_iv, test_additional_data,
2467                                test_tag_size_bits, Corrupted(test_cipher_text),
2468                                test_authentication_tag, &plain_text));
2469     EXPECT_FALSE(AesGcmDecrypt(key, test_iv, test_additional_data,
2470                                test_tag_size_bits, test_cipher_text,
2471                                Corrupted(test_authentication_tag),
2472                                &plain_text));
2473
2474     // Try different incorrect tag lengths
2475     uint8 kAlternateTagLengths[] = {8, 96, 120, 128, 160, 255};
2476     for (size_t tag_i = 0; tag_i < arraysize(kAlternateTagLengths); ++tag_i) {
2477       unsigned wrong_tag_size_bits = kAlternateTagLengths[tag_i];
2478       if (test_tag_size_bits == wrong_tag_size_bits)
2479         continue;
2480       EXPECT_FALSE(AesGcmDecrypt(key, test_iv, test_additional_data,
2481                                  wrong_tag_size_bits, test_cipher_text,
2482                                  test_authentication_tag, &plain_text));
2483     }
2484   }
2485 }
2486
2487 }  // namespace content