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

Side by Side Diff: trunk/src/content/child/webcrypto/shared_crypto.cc

Issue 252213003: Revert 266798 "[webcrypto] Make operations run on a background t..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 7 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 "content/child/webcrypto/shared_crypto.h" 5 #include "content/child/webcrypto/shared_crypto.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/child/webcrypto/crypto_data.h" 8 #include "content/child/webcrypto/crypto_data.h"
9 #include "content/child/webcrypto/jwk.h" 9 #include "content/child/webcrypto/jwk.h"
10 #include "content/child/webcrypto/platform_crypto.h" 10 #include "content/child/webcrypto/platform_crypto.h"
11 #include "content/child/webcrypto/status.h" 11 #include "content/child/webcrypto/status.h"
12 #include "content/child/webcrypto/webcrypto_util.h" 12 #include "content/child/webcrypto/webcrypto_util.h"
13 #include "crypto/secure_util.h" 13 #include "crypto/secure_util.h"
14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" 14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
16 #include "third_party/WebKit/public/platform/WebCryptoKey.h" 16 #include "third_party/WebKit/public/platform/WebCryptoKey.h"
17 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 17 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
18 18
19 namespace content { 19 namespace content {
20 20
21 namespace webcrypto { 21 namespace webcrypto {
22 22
23 // ------------
24 // Threading:
25 // ------------
26 //
27 // All functions in this file are called from the webcrypto worker pool except
28 // for:
29 //
30 // * SerializeKeyForClone()
31 // * DeserializeKeyForClone()
32 // * ImportKey() // TODO(eroman): Change this.
33
34 namespace { 23 namespace {
35 24
36 // TODO(eroman): Move this helper to WebCryptoKey. 25 // TODO(eroman): Move this helper to WebCryptoKey.
37 bool KeyUsageAllows(const blink::WebCryptoKey& key, 26 bool KeyUsageAllows(const blink::WebCryptoKey& key,
38 const blink::WebCryptoKeyUsage usage) { 27 const blink::WebCryptoKeyUsage usage) {
39 return ((key.usages() & usage) != 0); 28 return ((key.usages() & usage) != 0);
40 } 29 }
41 30
42 bool IsValidAesKeyLengthBits(unsigned int length_bits) { 31 bool IsValidAesKeyLengthBits(unsigned int length_bits) {
43 return length_bits == 128 || length_bits == 192 || length_bits == 256; 32 return length_bits == 128 || length_bits == 192 || length_bits == 256;
(...skipping 26 matching lines...) Expand all
70 return Status::ErrorUnexpectedKeyType(); 59 return Status::ErrorUnexpectedKeyType();
71 return Status::Success(); 60 return Status::Success();
72 } 61 }
73 62
74 const size_t kAesBlockSizeBytes = 16; 63 const size_t kAesBlockSizeBytes = 16;
75 64
76 Status EncryptDecryptAesCbc(EncryptOrDecrypt mode, 65 Status EncryptDecryptAesCbc(EncryptOrDecrypt mode,
77 const blink::WebCryptoAlgorithm& algorithm, 66 const blink::WebCryptoAlgorithm& algorithm,
78 const blink::WebCryptoKey& key, 67 const blink::WebCryptoKey& key,
79 const CryptoData& data, 68 const CryptoData& data,
80 std::vector<uint8>* buffer) { 69 blink::WebArrayBuffer* buffer) {
81 platform::SymKey* sym_key; 70 platform::SymKey* sym_key;
82 Status status = ToPlatformSymKey(key, &sym_key); 71 Status status = ToPlatformSymKey(key, &sym_key);
83 if (status.IsError()) 72 if (status.IsError())
84 return status; 73 return status;
85 74
86 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); 75 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams();
87 if (!params) 76 if (!params)
88 return Status::ErrorUnexpected(); 77 return Status::ErrorUnexpected();
89 78
90 CryptoData iv(params->iv().data(), params->iv().size()); 79 CryptoData iv(params->iv().data(), params->iv().size());
91 if (iv.byte_length() != kAesBlockSizeBytes) 80 if (iv.byte_length() != kAesBlockSizeBytes)
92 return Status::ErrorIncorrectSizeAesCbcIv(); 81 return Status::ErrorIncorrectSizeAesCbcIv();
93 82
94 return platform::EncryptDecryptAesCbc(mode, sym_key, data, iv, buffer); 83 return platform::EncryptDecryptAesCbc(mode, sym_key, data, iv, buffer);
95 } 84 }
96 85
97 Status EncryptDecryptAesGcm(EncryptOrDecrypt mode, 86 Status EncryptDecryptAesGcm(EncryptOrDecrypt mode,
98 const blink::WebCryptoAlgorithm& algorithm, 87 const blink::WebCryptoAlgorithm& algorithm,
99 const blink::WebCryptoKey& key, 88 const blink::WebCryptoKey& key,
100 const CryptoData& data, 89 const CryptoData& data,
101 std::vector<uint8>* buffer) { 90 blink::WebArrayBuffer* buffer) {
102 platform::SymKey* sym_key; 91 platform::SymKey* sym_key;
103 Status status = ToPlatformSymKey(key, &sym_key); 92 Status status = ToPlatformSymKey(key, &sym_key);
104 if (status.IsError()) 93 if (status.IsError())
105 return status; 94 return status;
106 95
107 const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams(); 96 const blink::WebCryptoAesGcmParams* params = algorithm.aesGcmParams();
108 if (!params) 97 if (!params)
109 return Status::ErrorUnexpected(); 98 return Status::ErrorUnexpected();
110 99
111 unsigned int tag_length_bits = 128; 100 unsigned int tag_length_bits = 128;
(...skipping 11 matching lines...) Expand all
123 data, 112 data,
124 CryptoData(params->iv()), 113 CryptoData(params->iv()),
125 CryptoData(params->optionalAdditionalData()), 114 CryptoData(params->optionalAdditionalData()),
126 tag_length_bits, 115 tag_length_bits,
127 buffer); 116 buffer);
128 } 117 }
129 118
130 Status EncryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, 119 Status EncryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
131 const blink::WebCryptoKey& key, 120 const blink::WebCryptoKey& key,
132 const CryptoData& data, 121 const CryptoData& data,
133 std::vector<uint8>* buffer) { 122 blink::WebArrayBuffer* buffer) {
134 platform::PublicKey* public_key; 123 platform::PublicKey* public_key;
135 Status status = ToPlatformPublicKey(key, &public_key); 124 Status status = ToPlatformPublicKey(key, &public_key);
136 if (status.IsError()) 125 if (status.IsError())
137 return status; 126 return status;
138 127
139 // RSAES encryption does not support empty input 128 // RSAES encryption does not support empty input
140 if (!data.byte_length()) 129 if (!data.byte_length())
141 return Status::ErrorDataTooSmall(); 130 return Status::ErrorDataTooSmall();
142 131
143 return platform::EncryptRsaEsPkcs1v1_5(public_key, data, buffer); 132 return platform::EncryptRsaEsPkcs1v1_5(public_key, data, buffer);
144 } 133 }
145 134
146 Status DecryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, 135 Status DecryptRsaEsPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
147 const blink::WebCryptoKey& key, 136 const blink::WebCryptoKey& key,
148 const CryptoData& data, 137 const CryptoData& data,
149 std::vector<uint8>* buffer) { 138 blink::WebArrayBuffer* buffer) {
150 platform::PrivateKey* private_key; 139 platform::PrivateKey* private_key;
151 Status status = ToPlatformPrivateKey(key, &private_key); 140 Status status = ToPlatformPrivateKey(key, &private_key);
152 if (status.IsError()) 141 if (status.IsError())
153 return status; 142 return status;
154 143
155 // RSAES decryption does not support empty input 144 // RSAES decryption does not support empty input
156 if (!data.byte_length()) 145 if (!data.byte_length())
157 return Status::ErrorDataTooSmall(); 146 return Status::ErrorDataTooSmall();
158 147
159 return platform::DecryptRsaEsPkcs1v1_5(private_key, data, buffer); 148 return platform::DecryptRsaEsPkcs1v1_5(private_key, data, buffer);
160 } 149 }
161 150
162 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, 151 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm,
163 const blink::WebCryptoKey& key, 152 const blink::WebCryptoKey& key,
164 const CryptoData& data, 153 const CryptoData& data,
165 std::vector<uint8>* buffer) { 154 blink::WebArrayBuffer* buffer) {
166 platform::SymKey* sym_key; 155 platform::SymKey* sym_key;
167 Status status = ToPlatformSymKey(key, &sym_key); 156 Status status = ToPlatformSymKey(key, &sym_key);
168 if (status.IsError()) 157 if (status.IsError())
169 return status; 158 return status;
170 159
171 return platform::SignHmac( 160 return platform::SignHmac(
172 sym_key, key.algorithm().hmacParams()->hash(), data, buffer); 161 sym_key, key.algorithm().hmacParams()->hash(), data, buffer);
173 } 162 }
174 163
175 Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm, 164 Status VerifyHmac(const blink::WebCryptoAlgorithm& algorithm,
176 const blink::WebCryptoKey& key, 165 const blink::WebCryptoKey& key,
177 const CryptoData& signature, 166 const CryptoData& signature,
178 const CryptoData& data, 167 const CryptoData& data,
179 bool* signature_match) { 168 bool* signature_match) {
180 std::vector<uint8> result; 169 blink::WebArrayBuffer result;
181 Status status = SignHmac(algorithm, key, data, &result); 170 Status status = SignHmac(algorithm, key, data, &result);
182 if (status.IsError()) 171 if (status.IsError())
183 return status; 172 return status;
184 173
185 // Do not allow verification of truncated MACs. 174 // Do not allow verification of truncated MACs.
186 *signature_match = 175 *signature_match =
187 result.size() == signature.byte_length() && 176 result.byteLength() == signature.byte_length() &&
188 crypto::SecureMemEqual( 177 crypto::SecureMemEqual(
189 Uint8VectorStart(result), signature.bytes(), signature.byte_length()); 178 result.data(), signature.bytes(), signature.byte_length());
190 179
191 return Status::Success(); 180 return Status::Success();
192 } 181 }
193 182
194 Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, 183 Status SignRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
195 const blink::WebCryptoKey& key, 184 const blink::WebCryptoKey& key,
196 const CryptoData& data, 185 const CryptoData& data,
197 std::vector<uint8>* buffer) { 186 blink::WebArrayBuffer* buffer) {
198 platform::PrivateKey* private_key; 187 platform::PrivateKey* private_key;
199 Status status = ToPlatformPrivateKey(key, &private_key); 188 Status status = ToPlatformPrivateKey(key, &private_key);
200 if (status.IsError()) 189 if (status.IsError())
201 return status; 190 return status;
202 191
203 return platform::SignRsaSsaPkcs1v1_5( 192 return platform::SignRsaSsaPkcs1v1_5(
204 private_key, key.algorithm().rsaHashedParams()->hash(), data, buffer); 193 private_key, key.algorithm().rsaHashedParams()->hash(), data, buffer);
205 } 194 }
206 195
207 Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm, 196 Status VerifyRsaSsaPkcs1v1_5(const blink::WebCryptoAlgorithm& algorithm,
208 const blink::WebCryptoKey& key, 197 const blink::WebCryptoKey& key,
209 const CryptoData& signature, 198 const CryptoData& signature,
210 const CryptoData& data, 199 const CryptoData& data,
211 bool* signature_match) { 200 bool* signature_match) {
212 platform::PublicKey* public_key; 201 platform::PublicKey* public_key;
213 Status status = ToPlatformPublicKey(key, &public_key); 202 Status status = ToPlatformPublicKey(key, &public_key);
214 if (status.IsError()) 203 if (status.IsError())
215 return status; 204 return status;
216 205
217 return platform::VerifyRsaSsaPkcs1v1_5( 206 return platform::VerifyRsaSsaPkcs1v1_5(
218 public_key, 207 public_key,
219 key.algorithm().rsaHashedParams()->hash(), 208 key.algorithm().rsaHashedParams()->hash(),
220 signature, 209 signature,
221 data, 210 data,
222 signature_match); 211 signature_match);
223 } 212 }
224 213
225 // Note that this function may be called from the target Blink thread.
226 Status ImportKeyRaw(const CryptoData& key_data, 214 Status ImportKeyRaw(const CryptoData& key_data,
227 const blink::WebCryptoAlgorithm& algorithm, 215 const blink::WebCryptoAlgorithm& algorithm,
228 bool extractable, 216 bool extractable,
229 blink::WebCryptoKeyUsageMask usage_mask, 217 blink::WebCryptoKeyUsageMask usage_mask,
230 blink::WebCryptoKey* key) { 218 blink::WebCryptoKey* key) {
231 switch (algorithm.id()) { 219 switch (algorithm.id()) {
232 case blink::WebCryptoAlgorithmIdAesCtr: 220 case blink::WebCryptoAlgorithmIdAesCtr:
233 case blink::WebCryptoAlgorithmIdAesCbc: 221 case blink::WebCryptoAlgorithmIdAesCbc:
234 case blink::WebCryptoAlgorithmIdAesGcm: 222 case blink::WebCryptoAlgorithmIdAesGcm:
235 case blink::WebCryptoAlgorithmIdAesKw: 223 case blink::WebCryptoAlgorithmIdAesKw:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 return blink::WebCryptoAlgorithm::createNull(); 266 return blink::WebCryptoAlgorithm::createNull();
279 } 267 }
280 268
281 // There is some duplicated information in the serialized format used by 269 // There is some duplicated information in the serialized format used by
282 // structured clone (since the KeyAlgorithm is serialized separately from the 270 // structured clone (since the KeyAlgorithm is serialized separately from the
283 // key data). Use this extra information to further validate what was 271 // key data). Use this extra information to further validate what was
284 // deserialized from the key data. 272 // deserialized from the key data.
285 // 273 //
286 // A failure here implies either a bug in the code, or that the serialized data 274 // A failure here implies either a bug in the code, or that the serialized data
287 // was corrupted. 275 // was corrupted.
288 bool ValidateDeserializedKey(const blink::WebCryptoKey& key, 276 Status ValidateDeserializedKey(const blink::WebCryptoKey& key,
289 const blink::WebCryptoKeyAlgorithm& algorithm, 277 const blink::WebCryptoKeyAlgorithm& algorithm,
290 blink::WebCryptoKeyType type) { 278 blink::WebCryptoKeyType type) {
291 if (algorithm.id() != key.algorithm().id()) 279 if (algorithm.id() != key.algorithm().id())
292 return false; 280 return Status::ErrorUnexpected();
293 281
294 if (key.type() != type) 282 if (key.type() != type)
295 return false; 283 return Status::ErrorUnexpected();
296 284
297 switch (algorithm.paramsType()) { 285 switch (algorithm.paramsType()) {
298 case blink::WebCryptoKeyAlgorithmParamsTypeAes: 286 case blink::WebCryptoKeyAlgorithmParamsTypeAes:
299 if (algorithm.aesParams()->lengthBits() != 287 if (algorithm.aesParams()->lengthBits() !=
300 key.algorithm().aesParams()->lengthBits()) 288 key.algorithm().aesParams()->lengthBits())
301 return false; 289 return Status::ErrorUnexpected();
302 break; 290 break;
303 case blink::WebCryptoKeyAlgorithmParamsTypeRsa: 291 case blink::WebCryptoKeyAlgorithmParamsTypeRsa:
304 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed: 292 case blink::WebCryptoKeyAlgorithmParamsTypeRsaHashed:
305 if (algorithm.rsaParams()->modulusLengthBits() != 293 if (algorithm.rsaParams()->modulusLengthBits() !=
306 key.algorithm().rsaParams()->modulusLengthBits()) 294 key.algorithm().rsaParams()->modulusLengthBits())
307 return false; 295 return Status::ErrorUnexpected();
308 if (algorithm.rsaParams()->publicExponent().size() != 296 if (algorithm.rsaParams()->publicExponent().size() !=
309 key.algorithm().rsaParams()->publicExponent().size()) 297 key.algorithm().rsaParams()->publicExponent().size())
310 return false; 298 return Status::ErrorUnexpected();
311 if (memcmp(algorithm.rsaParams()->publicExponent().data(), 299 if (memcmp(algorithm.rsaParams()->publicExponent().data(),
312 key.algorithm().rsaParams()->publicExponent().data(), 300 key.algorithm().rsaParams()->publicExponent().data(),
313 key.algorithm().rsaParams()->publicExponent().size()) != 0) 301 key.algorithm().rsaParams()->publicExponent().size()) != 0)
314 return false; 302 return Status::ErrorUnexpected();
315 break; 303 break;
316 case blink::WebCryptoKeyAlgorithmParamsTypeNone: 304 case blink::WebCryptoKeyAlgorithmParamsTypeNone:
317 case blink::WebCryptoKeyAlgorithmParamsTypeHmac: 305 case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
318 break; 306 break;
319 } 307 }
320 308
321 return true; 309 return Status::Success();
322 } 310 }
323 311
324 // Validates the size of data input to AES-KW. AES-KW requires the input data 312 // Validates the size of data input to AES-KW. AES-KW requires the input data
325 // size to be at least 24 bytes and a multiple of 8 bytes. 313 // size to be at least 24 bytes and a multiple of 8 bytes.
326 Status CheckAesKwInputSize(const CryptoData& aeskw_input_data) { 314 Status CheckAesKwInputSize(const CryptoData& aeskw_input_data) {
327 if (aeskw_input_data.byte_length() < 24) 315 if (aeskw_input_data.byte_length() < 24)
328 return Status::ErrorDataTooSmall(); 316 return Status::ErrorDataTooSmall();
329 if (aeskw_input_data.byte_length() % 8) 317 if (aeskw_input_data.byte_length() % 8)
330 return Status::ErrorInvalidAesKwDataLength(); 318 return Status::ErrorInvalidAesKwDataLength();
331 return Status::Success(); 319 return Status::Success();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 key); 359 key);
372 } 360 }
373 default: 361 default:
374 return Status::ErrorUnsupported(); 362 return Status::ErrorUnsupported();
375 } 363 }
376 } 364 }
377 365
378 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key, 366 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key,
379 const blink::WebCryptoKey& key_to_wrap, 367 const blink::WebCryptoKey& key_to_wrap,
380 const blink::WebCryptoAlgorithm& wrapping_algorithm, 368 const blink::WebCryptoAlgorithm& wrapping_algorithm,
381 std::vector<uint8>* buffer) { 369 blink::WebArrayBuffer* buffer) {
382 // A raw key is always a symmetric key. 370 // A raw key is always a symmetric key.
383 platform::SymKey* platform_key; 371 platform::SymKey* platform_key;
384 Status status = ToPlatformSymKey(key_to_wrap, &platform_key); 372 Status status = ToPlatformSymKey(key_to_wrap, &platform_key);
385 if (status.IsError()) 373 if (status.IsError())
386 return status; 374 return status;
387 375
388 // TODO(padolph): Handle other wrapping algorithms 376 // TODO(padolph): Handle other wrapping algorithms
389 switch (wrapping_algorithm.id()) { 377 switch (wrapping_algorithm.id()) {
390 case blink::WebCryptoAlgorithmIdAesKw: { 378 case blink::WebCryptoAlgorithmIdAesKw: {
391 platform::SymKey* platform_wrapping_key; 379 platform::SymKey* platform_wrapping_key;
(...skipping 12 matching lines...) Expand all
404 platform_wrapping_key, platform_key, buffer); 392 platform_wrapping_key, platform_key, buffer);
405 } 393 }
406 default: 394 default:
407 return Status::ErrorUnsupported(); 395 return Status::ErrorUnsupported();
408 } 396 }
409 } 397 }
410 398
411 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm, 399 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm,
412 const blink::WebCryptoKey& key, 400 const blink::WebCryptoKey& key,
413 const CryptoData& data, 401 const CryptoData& data,
414 std::vector<uint8>* buffer) { 402 blink::WebArrayBuffer* buffer) {
415 platform::SymKey* sym_key; 403 platform::SymKey* sym_key;
416 Status status = ToPlatformSymKey(key, &sym_key); 404 Status status = ToPlatformSymKey(key, &sym_key);
417 if (status.IsError()) 405 if (status.IsError())
418 return status; 406 return status;
419 status = CheckAesKwInputSize(data); 407 status = CheckAesKwInputSize(data);
420 if (status.IsError()) 408 if (status.IsError())
421 return status; 409 return status;
422 return platform::DecryptAesKw(sym_key, data, buffer); 410 return platform::DecryptAesKw(sym_key, data, buffer);
423 } 411 }
424 412
425 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm, 413 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm,
426 const blink::WebCryptoKey& key, 414 const blink::WebCryptoKey& key,
427 const CryptoData& data, 415 const CryptoData& data,
428 std::vector<uint8>* buffer) { 416 blink::WebArrayBuffer* buffer) {
429 if (algorithm.id() != key.algorithm().id()) 417 if (algorithm.id() != key.algorithm().id())
430 return Status::ErrorUnexpected(); 418 return Status::ErrorUnexpected();
431 switch (algorithm.id()) { 419 switch (algorithm.id()) {
432 case blink::WebCryptoAlgorithmIdAesCbc: 420 case blink::WebCryptoAlgorithmIdAesCbc:
433 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer); 421 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer);
434 case blink::WebCryptoAlgorithmIdAesGcm: 422 case blink::WebCryptoAlgorithmIdAesGcm:
435 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); 423 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer);
436 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: 424 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
437 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); 425 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer);
438 case blink::WebCryptoAlgorithmIdAesKw: 426 case blink::WebCryptoAlgorithmIdAesKw:
439 return DecryptAesKw(algorithm, key, data, buffer); 427 return DecryptAesKw(algorithm, key, data, buffer);
440 default: 428 default:
441 return Status::ErrorUnsupported(); 429 return Status::ErrorUnsupported();
442 } 430 }
443 } 431 }
444 432
445 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, 433 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm,
446 const blink::WebCryptoKey& key, 434 const blink::WebCryptoKey& key,
447 const CryptoData& data, 435 const CryptoData& data,
448 std::vector<uint8>* buffer) { 436 blink::WebArrayBuffer* buffer) {
449 if (algorithm.id() != key.algorithm().id()) 437 if (algorithm.id() != key.algorithm().id())
450 return Status::ErrorUnexpected(); 438 return Status::ErrorUnexpected();
451 switch (algorithm.id()) { 439 switch (algorithm.id()) {
452 case blink::WebCryptoAlgorithmIdAesCbc: 440 case blink::WebCryptoAlgorithmIdAesCbc:
453 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); 441 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer);
454 case blink::WebCryptoAlgorithmIdAesGcm: 442 case blink::WebCryptoAlgorithmIdAesGcm:
455 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); 443 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer);
456 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: 444 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
457 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); 445 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer);
458 default: 446 default:
459 return Status::ErrorUnsupported(); 447 return Status::ErrorUnsupported();
460 } 448 }
461 } 449 }
462 450
463 Status UnwrapKeyDecryptAndImport( 451 Status UnwrapKeyDecryptAndImport(
464 blink::WebCryptoKeyFormat format, 452 blink::WebCryptoKeyFormat format,
465 const CryptoData& wrapped_key_data, 453 const CryptoData& wrapped_key_data,
466 const blink::WebCryptoKey& wrapping_key, 454 const blink::WebCryptoKey& wrapping_key,
467 const blink::WebCryptoAlgorithm& wrapping_algorithm, 455 const blink::WebCryptoAlgorithm& wrapping_algorithm,
468 const blink::WebCryptoAlgorithm& algorithm, 456 const blink::WebCryptoAlgorithm& algorithm,
469 bool extractable, 457 bool extractable,
470 blink::WebCryptoKeyUsageMask usage_mask, 458 blink::WebCryptoKeyUsageMask usage_mask,
471 blink::WebCryptoKey* key) { 459 blink::WebCryptoKey* key) {
472 std::vector<uint8> buffer; 460 blink::WebArrayBuffer buffer;
473 Status status = DecryptDontCheckKeyUsage( 461 Status status = DecryptDontCheckKeyUsage(
474 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); 462 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer);
475 if (status.IsError()) 463 if (status.IsError())
476 return status; 464 return status;
477 status = ImportKey( 465 status = ImportKey(
478 format, CryptoData(buffer), algorithm, extractable, usage_mask, key); 466 format, CryptoData(buffer), algorithm, extractable, usage_mask, key);
479 // NOTE! Returning the details of any ImportKey() failure here would leak 467 // NOTE! Returning the details of any ImportKey() failure here would leak
480 // information about the plaintext internals of the encrypted key. Instead, 468 // information about the plaintext internals of the encrypted key. Instead,
481 // collapse any error into the generic Status::OperationError(). 469 // collapse any error into the generic Status::OperationError().
482 return status.IsError() ? Status::OperationError() : Status::Success(); 470 return status.IsError() ? Status::OperationError() : Status::Success();
483 } 471 }
484 472
485 Status WrapKeyExportAndEncrypt( 473 Status WrapKeyExportAndEncrypt(
486 blink::WebCryptoKeyFormat format, 474 blink::WebCryptoKeyFormat format,
487 const blink::WebCryptoKey& wrapping_key, 475 const blink::WebCryptoKey& wrapping_key,
488 const blink::WebCryptoKey& key_to_wrap, 476 const blink::WebCryptoKey& key_to_wrap,
489 const blink::WebCryptoAlgorithm& wrapping_algorithm, 477 const blink::WebCryptoAlgorithm& wrapping_algorithm,
490 std::vector<uint8>* buffer) { 478 blink::WebArrayBuffer* buffer) {
491 std::vector<uint8> exported_data; 479 blink::WebArrayBuffer exported_data;
492 Status status = ExportKey(format, key_to_wrap, &exported_data); 480 Status status = ExportKey(format, key_to_wrap, &exported_data);
493 if (status.IsError()) 481 if (status.IsError())
494 return status; 482 return status;
495 return EncryptDontCheckUsage( 483 return EncryptDontCheckUsage(
496 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer); 484 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer);
497 } 485 }
498 486
499 // Returns the internal block size for SHA-* 487 // Returns the internal block size for SHA-*
500 unsigned int ShaBlockSizeBytes(blink::WebCryptoAlgorithmId hash_id) { 488 unsigned int ShaBlockSizeBytes(blink::WebCryptoAlgorithmId hash_id) {
501 switch (hash_id) { 489 switch (hash_id) {
502 case blink::WebCryptoAlgorithmIdSha1: 490 case blink::WebCryptoAlgorithmIdSha1:
503 case blink::WebCryptoAlgorithmIdSha256: 491 case blink::WebCryptoAlgorithmIdSha256:
504 return 64; 492 return 64;
505 case blink::WebCryptoAlgorithmIdSha384: 493 case blink::WebCryptoAlgorithmIdSha384:
506 case blink::WebCryptoAlgorithmIdSha512: 494 case blink::WebCryptoAlgorithmIdSha512:
507 return 128; 495 return 128;
508 default: 496 default:
509 NOTREACHED(); 497 NOTREACHED();
510 return 0; 498 return 0;
511 } 499 }
512 } 500 }
513 501
514 } // namespace 502 } // namespace
515 503
516 void Init() { platform::Init(); } 504 void Init() { platform::Init(); }
517 505
518 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, 506 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
519 const blink::WebCryptoKey& key, 507 const blink::WebCryptoKey& key,
520 const CryptoData& data, 508 const CryptoData& data,
521 std::vector<uint8>* buffer) { 509 blink::WebArrayBuffer* buffer) {
522 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) 510 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt))
523 return Status::ErrorUnexpected(); 511 return Status::ErrorUnexpected();
524 return EncryptDontCheckUsage(algorithm, key, data, buffer); 512 return EncryptDontCheckUsage(algorithm, key, data, buffer);
525 } 513 }
526 514
527 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, 515 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
528 const blink::WebCryptoKey& key, 516 const blink::WebCryptoKey& key,
529 const CryptoData& data, 517 const CryptoData& data,
530 std::vector<uint8>* buffer) { 518 blink::WebArrayBuffer* buffer) {
531 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) 519 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt))
532 return Status::ErrorUnexpected(); 520 return Status::ErrorUnexpected();
533 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); 521 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer);
534 } 522 }
535 523
536 Status Digest(const blink::WebCryptoAlgorithm& algorithm, 524 Status Digest(const blink::WebCryptoAlgorithm& algorithm,
537 const CryptoData& data, 525 const CryptoData& data,
538 std::vector<uint8>* buffer) { 526 blink::WebArrayBuffer* buffer) {
539 switch (algorithm.id()) { 527 switch (algorithm.id()) {
540 case blink::WebCryptoAlgorithmIdSha1: 528 case blink::WebCryptoAlgorithmIdSha1:
541 case blink::WebCryptoAlgorithmIdSha256: 529 case blink::WebCryptoAlgorithmIdSha256:
542 case blink::WebCryptoAlgorithmIdSha384: 530 case blink::WebCryptoAlgorithmIdSha384:
543 case blink::WebCryptoAlgorithmIdSha512: 531 case blink::WebCryptoAlgorithmIdSha512:
544 return platform::DigestSha(algorithm.id(), data, buffer); 532 return platform::DigestSha(algorithm.id(), data, buffer);
545 default: 533 default:
546 return Status::ErrorUnsupported(); 534 return Status::ErrorUnsupported();
547 } 535 }
548 } 536 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 publicExponent, 619 publicExponent,
632 hash_or_null, 620 hash_or_null,
633 public_key, 621 public_key,
634 private_key); 622 private_key);
635 } 623 }
636 default: 624 default:
637 return Status::ErrorUnsupported(); 625 return Status::ErrorUnsupported();
638 } 626 }
639 } 627 }
640 628
641 // Note that this function may be called from the target Blink thread.
642 Status ImportKey(blink::WebCryptoKeyFormat format, 629 Status ImportKey(blink::WebCryptoKeyFormat format,
643 const CryptoData& key_data, 630 const CryptoData& key_data,
644 const blink::WebCryptoAlgorithm& algorithm, 631 const blink::WebCryptoAlgorithm& algorithm,
645 bool extractable, 632 bool extractable,
646 blink::WebCryptoKeyUsageMask usage_mask, 633 blink::WebCryptoKeyUsageMask usage_mask,
647 blink::WebCryptoKey* key) { 634 blink::WebCryptoKey* key) {
648 switch (format) { 635 switch (format) {
649 case blink::WebCryptoKeyFormatRaw: 636 case blink::WebCryptoKeyFormatRaw:
650 return ImportKeyRaw(key_data, algorithm, extractable, usage_mask, key); 637 return ImportKeyRaw(key_data, algorithm, extractable, usage_mask, key);
651 case blink::WebCryptoKeyFormatSpki: 638 case blink::WebCryptoKeyFormatSpki:
652 return platform::ImportKeySpki( 639 return platform::ImportKeySpki(
653 algorithm, key_data, extractable, usage_mask, key); 640 algorithm, key_data, extractable, usage_mask, key);
654 case blink::WebCryptoKeyFormatPkcs8: 641 case blink::WebCryptoKeyFormatPkcs8:
655 return platform::ImportKeyPkcs8( 642 return platform::ImportKeyPkcs8(
656 algorithm, key_data, extractable, usage_mask, key); 643 algorithm, key_data, extractable, usage_mask, key);
657 case blink::WebCryptoKeyFormatJwk: 644 case blink::WebCryptoKeyFormatJwk:
658 return ImportKeyJwk(key_data, algorithm, extractable, usage_mask, key); 645 return ImportKeyJwk(key_data, algorithm, extractable, usage_mask, key);
659 default: 646 default:
660 return Status::ErrorUnsupported(); 647 return Status::ErrorUnsupported();
661 } 648 }
662 } 649 }
663 650
664 // TODO(eroman): Move this to anonymous namespace. 651 // TODO(eroman): Move this to anonymous namespace.
665 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, 652 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
666 const blink::WebCryptoKey& key, 653 const blink::WebCryptoKey& key,
667 std::vector<uint8>* buffer) { 654 blink::WebArrayBuffer* buffer) {
668 switch (format) { 655 switch (format) {
669 case blink::WebCryptoKeyFormatRaw: { 656 case blink::WebCryptoKeyFormatRaw: {
670 platform::SymKey* sym_key; 657 platform::SymKey* sym_key;
671 Status status = ToPlatformSymKey(key, &sym_key); 658 Status status = ToPlatformSymKey(key, &sym_key);
672 if (status.IsError()) 659 if (status.IsError())
673 return status; 660 return status;
674 return platform::ExportKeyRaw(sym_key, buffer); 661 return platform::ExportKeyRaw(sym_key, buffer);
675 } 662 }
676 case blink::WebCryptoKeyFormatSpki: { 663 case blink::WebCryptoKeyFormatSpki: {
677 platform::PublicKey* public_key; 664 platform::PublicKey* public_key;
(...skipping 11 matching lines...) Expand all
689 } 676 }
690 case blink::WebCryptoKeyFormatJwk: 677 case blink::WebCryptoKeyFormatJwk:
691 return ExportKeyJwk(key, buffer); 678 return ExportKeyJwk(key, buffer);
692 default: 679 default:
693 return Status::ErrorUnsupported(); 680 return Status::ErrorUnsupported();
694 } 681 }
695 } 682 }
696 683
697 Status ExportKey(blink::WebCryptoKeyFormat format, 684 Status ExportKey(blink::WebCryptoKeyFormat format,
698 const blink::WebCryptoKey& key, 685 const blink::WebCryptoKey& key,
699 std::vector<uint8>* buffer) { 686 blink::WebArrayBuffer* buffer) {
700 if (!key.extractable()) 687 if (!key.extractable())
701 return Status::ErrorKeyNotExtractable(); 688 return Status::ErrorKeyNotExtractable();
702 return ExportKeyDontCheckExtractability(format, key, buffer); 689 return ExportKeyDontCheckExtractability(format, key, buffer);
703 } 690 }
704 691
705 Status Sign(const blink::WebCryptoAlgorithm& algorithm, 692 Status Sign(const blink::WebCryptoAlgorithm& algorithm,
706 const blink::WebCryptoKey& key, 693 const blink::WebCryptoKey& key,
707 const CryptoData& data, 694 const CryptoData& data,
708 std::vector<uint8>* buffer) { 695 blink::WebArrayBuffer* buffer) {
709 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign)) 696 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign))
710 return Status::ErrorUnexpected(); 697 return Status::ErrorUnexpected();
711 if (algorithm.id() != key.algorithm().id()) 698 if (algorithm.id() != key.algorithm().id())
712 return Status::ErrorUnexpected(); 699 return Status::ErrorUnexpected();
713 700
714 switch (algorithm.id()) { 701 switch (algorithm.id()) {
715 case blink::WebCryptoAlgorithmIdHmac: 702 case blink::WebCryptoAlgorithmIdHmac:
716 return SignHmac(algorithm, key, data, buffer); 703 return SignHmac(algorithm, key, data, buffer);
717 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: 704 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
718 return SignRsaSsaPkcs1v1_5(algorithm, key, data, buffer); 705 return SignRsaSsaPkcs1v1_5(algorithm, key, data, buffer);
(...skipping 28 matching lines...) Expand all
747 algorithm, key, signature, data, signature_match); 734 algorithm, key, signature, data, signature_match);
748 default: 735 default:
749 return Status::ErrorUnsupported(); 736 return Status::ErrorUnsupported();
750 } 737 }
751 } 738 }
752 739
753 Status WrapKey(blink::WebCryptoKeyFormat format, 740 Status WrapKey(blink::WebCryptoKeyFormat format,
754 const blink::WebCryptoKey& wrapping_key, 741 const blink::WebCryptoKey& wrapping_key,
755 const blink::WebCryptoKey& key_to_wrap, 742 const blink::WebCryptoKey& key_to_wrap,
756 const blink::WebCryptoAlgorithm& wrapping_algorithm, 743 const blink::WebCryptoAlgorithm& wrapping_algorithm,
757 std::vector<uint8>* buffer) { 744 blink::WebArrayBuffer* buffer) {
758 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) 745 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey))
759 return Status::ErrorUnexpected(); 746 return Status::ErrorUnexpected();
760 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) 747 if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
761 return Status::ErrorUnexpected(); 748 return Status::ErrorUnexpected();
762 749
763 switch (format) { 750 switch (format) {
764 case blink::WebCryptoKeyFormatRaw: 751 case blink::WebCryptoKeyFormatRaw:
765 return WrapKeyRaw(wrapping_key, key_to_wrap, wrapping_algorithm, buffer); 752 return WrapKeyRaw(wrapping_key, key_to_wrap, wrapping_algorithm, buffer);
766 case blink::WebCryptoKeyFormatJwk: 753 case blink::WebCryptoKeyFormatJwk:
767 return WrapKeyExportAndEncrypt( 754 return WrapKeyExportAndEncrypt(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 key); 795 key);
809 case blink::WebCryptoKeyFormatSpki: 796 case blink::WebCryptoKeyFormatSpki:
810 case blink::WebCryptoKeyFormatPkcs8: 797 case blink::WebCryptoKeyFormatPkcs8:
811 return Status::ErrorUnsupported(); // TODO(padolph) 798 return Status::ErrorUnsupported(); // TODO(padolph)
812 default: 799 default:
813 NOTREACHED(); 800 NOTREACHED();
814 return Status::ErrorUnsupported(); 801 return Status::ErrorUnsupported();
815 } 802 }
816 } 803 }
817 804
818 // Note that this function is called from the target Blink thread. 805 Status SerializeKeyForClone(const blink::WebCryptoKey& key,
819 bool SerializeKeyForClone(const blink::WebCryptoKey& key, 806 blink::WebVector<unsigned char>* data) {
820 blink::WebVector<uint8>* key_data) { 807 blink::WebArrayBuffer buffer;
821 return static_cast<webcrypto::platform::Key*>(key.handle()) 808 Status status = ExportKeyDontCheckExtractability(
822 ->ThreadSafeSerializeForClone(key_data); 809 GetCloneFormatForKeyType(key.type()), key, &buffer);
810 if (status.IsError())
811 return status;
812 data->assign(
813 reinterpret_cast<unsigned char*>(buffer.data()), buffer.byteLength());
814 return Status::Success();
823 } 815 }
824 816
825 // Note that this function is called from the target Blink thread. 817 Status DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm,
826 bool DeserializeKeyForClone(const blink::WebCryptoKeyAlgorithm& algorithm, 818 blink::WebCryptoKeyType type,
827 blink::WebCryptoKeyType type, 819 bool extractable,
828 bool extractable, 820 blink::WebCryptoKeyUsageMask usage_mask,
829 blink::WebCryptoKeyUsageMask usage_mask, 821 const CryptoData& key_data,
830 const CryptoData& key_data, 822 blink::WebCryptoKey* key) {
831 blink::WebCryptoKey* key) {
832 // TODO(eroman): This should not call into the platform crypto layer.
833 // Otherwise it runs the risk of stalling while the NSS/OpenSSL global locks
834 // are held.
835 //
836 // An alternate approach is to defer the key import until the key is used.
837 // However this means that any deserialization errors would have to be
838 // surfaced as WebCrypto errors, leading to slightly different behaviors. For
839 // instance you could clone a key which fails to be deserialized.
840 Status status = ImportKey(GetCloneFormatForKeyType(type), 823 Status status = ImportKey(GetCloneFormatForKeyType(type),
841 key_data, 824 key_data,
842 KeyAlgorithmToImportAlgorithm(algorithm), 825 KeyAlgorithmToImportAlgorithm(algorithm),
843 extractable, 826 extractable,
844 usage_mask, 827 usage_mask,
845 key); 828 key);
846 if (status.IsError()) 829 if (status.IsError())
847 return false; 830 return status;
831
848 return ValidateDeserializedKey(*key, algorithm, type); 832 return ValidateDeserializedKey(*key, algorithm, type);
849 } 833 }
850 834
851 } // namespace webcrypto 835 } // namespace webcrypto
852 836
853 } // namespace content 837 } // namespace content
OLDNEW
« no previous file with comments | « trunk/src/content/child/webcrypto/shared_crypto.h ('k') | trunk/src/content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698