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

Side by Side Diff: content/child/webcrypto/shared_crypto_unittest.cc

Issue 491763002: [webcrypto] Implement AES-CTR using BoringSSL. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <string> 6 #include <string>
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // TODO(eroman): Exclude version test for OS_CHROMEOS 115 // TODO(eroman): Exclude version test for OS_CHROMEOS
116 #if defined(USE_NSS) 116 #if defined(USE_NSS)
117 if (!NSS_VersionCheck("3.16.2")) 117 if (!NSS_VersionCheck("3.16.2"))
118 return false; 118 return false;
119 #endif 119 #endif
120 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); 120 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
121 return !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP); 121 return !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP);
122 #endif 122 #endif
123 } 123 }
124 124
125 bool SupportsAesCtr() {
126 #if defined(USE_OPENSSL)
127 return true;
128 #else
129 return false;
130 #endif
131 }
132
125 bool SupportsRsaKeyImport() { 133 bool SupportsRsaKeyImport() {
126 // TODO(eroman): Exclude version test for OS_CHROMEOS 134 // TODO(eroman): Exclude version test for OS_CHROMEOS
127 #if defined(USE_NSS) 135 #if defined(USE_NSS)
128 crypto::EnsureNSSInit(); 136 crypto::EnsureNSSInit();
129 if (!NSS_VersionCheck("3.16.2")) { 137 if (!NSS_VersionCheck("3.16.2")) {
130 LOG(WARNING) << "RSA key import is not supported by this version of NSS. " 138 LOG(WARNING) << "RSA key import is not supported by this version of NSS. "
131 "Skipping some tests"; 139 "Skipping some tests";
132 return false; 140 return false;
133 } 141 }
134 #endif 142 #endif
(...skipping 27 matching lines...) Expand all
162 } 170 }
163 171
164 // Creates an AES-CBC algorithm. 172 // Creates an AES-CBC algorithm.
165 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm( 173 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(
166 const std::vector<uint8_t>& iv) { 174 const std::vector<uint8_t>& iv) {
167 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( 175 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
168 blink::WebCryptoAlgorithmIdAesCbc, 176 blink::WebCryptoAlgorithmIdAesCbc,
169 new blink::WebCryptoAesCbcParams(vector_as_array(&iv), iv.size())); 177 new blink::WebCryptoAesCbcParams(vector_as_array(&iv), iv.size()));
170 } 178 }
171 179
180 // Creates an AES-CTR algorithm for encryption/decryption.
181 blink::WebCryptoAlgorithm CreateAesCtrAlgorithm(
182 const std::vector<uint8_t>& counter,
183 uint8_t length_bits) {
184 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
185 blink::WebCryptoAlgorithmIdAesCtr,
186 new blink::WebCryptoAesCtrParams(
187 length_bits, vector_as_array(&counter), counter.size()));
188 }
189
172 // Creates an AES-GCM algorithm. 190 // Creates an AES-GCM algorithm.
173 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( 191 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm(
174 const std::vector<uint8_t>& iv, 192 const std::vector<uint8_t>& iv,
175 const std::vector<uint8_t>& additional_data, 193 const std::vector<uint8_t>& additional_data,
176 unsigned int tag_length_bits) { 194 unsigned int tag_length_bits) {
177 EXPECT_TRUE(SupportsAesGcm()); 195 EXPECT_TRUE(SupportsAesGcm());
178 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( 196 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
179 blink::WebCryptoAlgorithmIdAesGcm, 197 blink::WebCryptoAlgorithmIdAesGcm,
180 new blink::WebCryptoAesGcmParams(vector_as_array(&iv), 198 new blink::WebCryptoAesGcmParams(vector_as_array(&iv),
181 iv.size(), 199 iv.size(),
(...skipping 4671 matching lines...) Expand 10 before | Expand all | Expand 10 after
4853 unwrapped_private_key, 4871 unwrapped_private_key,
4854 &unwrapped_private_key_pkcs8)); 4872 &unwrapped_private_key_pkcs8));
4855 4873
4856 EXPECT_EQ(public_key_spki, unwrapped_public_key_spki); 4874 EXPECT_EQ(public_key_spki, unwrapped_public_key_spki);
4857 EXPECT_EQ(private_key_pkcs8, unwrapped_private_key_pkcs8); 4875 EXPECT_EQ(private_key_pkcs8, unwrapped_private_key_pkcs8);
4858 4876
4859 EXPECT_NE(public_key_spki, wrapped_public_key); 4877 EXPECT_NE(public_key_spki, wrapped_public_key);
4860 EXPECT_NE(private_key_pkcs8, wrapped_private_key); 4878 EXPECT_NE(private_key_pkcs8, wrapped_private_key);
4861 } 4879 }
4862 4880
4881 TEST(WebCryptoAesCtrTest, EncryptDecryptKnownAnswer) {
4882 if (!SupportsAesCtr()) {
4883 LOG(WARNING) << "Skipping test because AES-CTR is not supported";
4884 return;
4885 }
4886
4887 scoped_ptr<base::ListValue> tests;
4888 ASSERT_TRUE(ReadJsonTestFileToList("aes_ctr.json", &tests));
4889
4890 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
4891 SCOPED_TRACE(test_index);
4892 base::DictionaryValue* test;
4893 ASSERT_TRUE(tests->GetDictionary(test_index, &test));
4894
4895 std::vector<uint8_t> test_key = GetBytesFromHexString(test, "key");
4896 std::vector<uint8_t> test_counter = GetBytesFromHexString(test, "counter");
4897 int counter_length_bits = 0;
4898 ASSERT_TRUE(test->GetInteger("length", &counter_length_bits));
4899
4900 std::vector<uint8_t> test_plain_text =
4901 GetBytesFromHexString(test, "plain_text");
4902 std::vector<uint8_t> test_cipher_text =
4903 GetBytesFromHexString(test, "cipher_text");
4904
4905 blink::WebCryptoKey key = ImportSecretKeyFromRaw(
4906 test_key,
4907 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
4908 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
4909
4910 EXPECT_EQ(test_key.size() * 8, key.algorithm().aesParams()->lengthBits());
4911
4912 std::vector<uint8_t> output;
4913
4914 // Test encryption.
4915 EXPECT_EQ(Status::Success(),
4916 Encrypt(CreateAesCtrAlgorithm(test_counter, counter_length_bits),
4917 key,
4918 CryptoData(test_plain_text),
4919 &output));
4920 EXPECT_BYTES_EQ(test_cipher_text, output);
4921
4922 // Test decryption.
4923 EXPECT_EQ(Status::Success(),
4924 Decrypt(CreateAesCtrAlgorithm(test_counter, counter_length_bits),
4925 key,
4926 CryptoData(test_cipher_text),
4927 &output));
4928 EXPECT_BYTES_EQ(test_plain_text, output);
4929 }
4930 }
4931
4932 // The counter block must be exactly 16 bytes.
4933 TEST(WebCryptoAesCtrTest, InvalidCounterBlockLength) {
4934 if (!SupportsAesCtr()) {
4935 LOG(WARNING) << "Skipping test because AES-CTR is not supported";
4936 return;
4937 }
4938
4939 const unsigned int kBadCounterBlockLengthBytes[] = {0, 15, 17};
4940
4941 blink::WebCryptoKey key = ImportSecretKeyFromRaw(
4942 std::vector<uint8>(16), // 128-bit key of all zeros.
4943 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
4944 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
4945
4946 std::vector<uint8_t> input(32);
4947 std::vector<uint8_t> output;
4948
4949 for (size_t i = 0; i < arraysize(kBadCounterBlockLengthBytes); ++i) {
4950 std::vector<uint8_t> bad_counter(kBadCounterBlockLengthBytes[i]);
4951
4952 EXPECT_EQ(Status::ErrorIncorrectSizeAesCtrCounter(),
4953 Encrypt(CreateAesCtrAlgorithm(bad_counter, 128),
4954 key,
4955 CryptoData(input),
4956 &output));
4957
4958 EXPECT_EQ(Status::ErrorIncorrectSizeAesCtrCounter(),
4959 Decrypt(CreateAesCtrAlgorithm(bad_counter, 128),
4960 key,
4961 CryptoData(input),
4962 &output));
4963 }
4964 }
4965
4966 // The counter length cannot be less than 1 or greater than 128.
4967 TEST(WebCryptoAesCtrTest, InvalidCounterLength) {
4968 if (!SupportsAesCtr()) {
4969 LOG(WARNING) << "Skipping test because AES-CTR is not supported";
4970 return;
4971 }
4972
4973 const uint8_t kBadCounterLengthBits[] = {0, 129};
4974
4975 blink::WebCryptoKey key = ImportSecretKeyFromRaw(
4976 std::vector<uint8>(16), // 128-bit key of all zeros.
4977 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
4978 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
4979
4980 std::vector<uint8_t> counter(16);
4981 std::vector<uint8_t> input(32);
4982 std::vector<uint8_t> output;
4983
4984 for (size_t i = 0; i < arraysize(kBadCounterLengthBits); ++i) {
4985 uint8_t bad_counter_length_bits = kBadCounterLengthBits[i];
4986
4987 EXPECT_EQ(Status::ErrorInvalidAesCtrCounterLength(),
4988 Encrypt(CreateAesCtrAlgorithm(counter, bad_counter_length_bits),
4989 key,
4990 CryptoData(input),
4991 &output));
4992
4993 EXPECT_EQ(Status::ErrorInvalidAesCtrCounterLength(),
4994 Decrypt(CreateAesCtrAlgorithm(counter, bad_counter_length_bits),
4995 key,
4996 CryptoData(input),
4997 &output));
4998 }
4999 }
5000
5001 // Tests wrap-around using a 4-bit counter.
5002 //
5003 // Wrap-around is allowed, however if the counter repeats itself an error should
5004 // be thrown.
5005 //
5006 // Using a 4-bit counter it is possible to encrypt 16 blocks. However the 17th
5007 // block would end up wrapping back to the starting value.
5008 TEST(WebCryptoAesCtrTest, OverflowAndRepeatCounter) {
5009 if (!SupportsAesCtr()) {
5010 LOG(WARNING) << "Skipping test because AES-CTR is not supported";
5011 return;
5012 }
5013
5014 const uint8_t kCounterLengthBits = 4;
5015 const uint8_t kStartCounter[] = {0, 1, 15};
5016
5017 blink::WebCryptoKey key = ImportSecretKeyFromRaw(
5018 std::vector<uint8>(16), // 128-bit key of all zeros.
5019 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCtr),
5020 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
5021
5022 std::vector<uint8_t> buffer(272);
5023
5024 // 16 and 17 AES blocks worth of data respectively (AES blocks are 16 bytes
5025 // long).
5026 CryptoData input_16(vector_as_array(&buffer), 256);
5027 CryptoData input_17(vector_as_array(&buffer), 272);
5028
5029 std::vector<uint8_t> output;
5030
5031 for (size_t i = 0; i < arraysize(kStartCounter); ++i) {
5032 std::vector<uint8_t> counter(16);
5033 counter[15] = kStartCounter[i];
5034
5035 // Baseline test: Encrypting 16 blocks should work (don't bother to check
5036 // output, the known answer tests already do that).
5037 EXPECT_EQ(Status::Success(),
5038 Encrypt(CreateAesCtrAlgorithm(counter, kCounterLengthBits),
5039 key,
5040 input_16,
5041 &output));
5042
5043 // Encrypting/Decrypting 17 however should fail.
5044 EXPECT_EQ(Status::ErrorAesCtrInputTooLongCounterRepeated(),
5045 Encrypt(CreateAesCtrAlgorithm(counter, kCounterLengthBits),
5046 key,
5047 input_17,
5048 &output));
5049 EXPECT_EQ(Status::ErrorAesCtrInputTooLongCounterRepeated(),
5050 Decrypt(CreateAesCtrAlgorithm(counter, kCounterLengthBits),
5051 key,
5052 input_17,
5053 &output));
5054 }
5055 }
5056
4863 } // namespace 5057 } // namespace
4864 5058
4865 } // namespace webcrypto 5059 } // namespace webcrypto
4866 5060
4867 } // namespace content 5061 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698