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

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

Issue 335463002: [webcrypto] Remove a special case for AES-KW wrapping/unwrapping. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Try to placate a compiler warning Created 6 years, 6 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
« no previous file with comments | « content/child/webcrypto/platform_crypto_openssl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 case blink::WebCryptoKeyAlgorithmParamsTypeNone: 301 case blink::WebCryptoKeyAlgorithmParamsTypeNone:
302 case blink::WebCryptoKeyAlgorithmParamsTypeHmac: 302 case blink::WebCryptoKeyAlgorithmParamsTypeHmac:
303 break; 303 break;
304 default: 304 default:
305 return false; 305 return false;
306 } 306 }
307 307
308 return true; 308 return true;
309 } 309 }
310 310
311 // Validates the size of data input to AES-KW. AES-KW requires the input data 311 Status EncryptDecryptAesKw(EncryptOrDecrypt mode,
312 // size to be at least 24 bytes and a multiple of 8 bytes. 312 const blink::WebCryptoAlgorithm& algorithm,
313 Status CheckAesKwInputSize(const CryptoData& aeskw_input_data) { 313 const blink::WebCryptoKey& key,
314 if (aeskw_input_data.byte_length() < 24) 314 const CryptoData& data,
315 return Status::ErrorDataTooSmall(); 315 std::vector<uint8>* buffer) {
316 if (aeskw_input_data.byte_length() % 8)
317 return Status::ErrorInvalidAesKwDataLength();
318 return Status::Success();
319 }
320
321 Status UnwrapKeyRaw(const CryptoData& wrapped_key_data,
322 const blink::WebCryptoKey& wrapping_key,
323 const blink::WebCryptoAlgorithm& wrapping_algorithm,
324 const blink::WebCryptoAlgorithm& algorithm,
325 bool extractable,
326 blink::WebCryptoKeyUsageMask usage_mask,
327 blink::WebCryptoKey* key) {
328 // TODO(padolph): Handle other wrapping algorithms
329 switch (wrapping_algorithm.id()) {
330 case blink::WebCryptoAlgorithmIdAesKw: {
331 platform::SymKey* platform_wrapping_key;
332 Status status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key);
333 if (status.IsError())
334 return status;
335 status = CheckAesKwInputSize(wrapped_key_data);
336 if (status.IsError())
337 return status;
338 return platform::UnwrapSymKeyAesKw(wrapped_key_data,
339 platform_wrapping_key,
340 algorithm,
341 extractable,
342 usage_mask,
343 key);
344 }
345 default:
346 return Status::ErrorUnsupported();
347 }
348 }
349
350 Status WrapKeyRaw(const blink::WebCryptoKey& key_to_wrap,
351 const blink::WebCryptoKey& wrapping_key,
352 const blink::WebCryptoAlgorithm& wrapping_algorithm,
353 std::vector<uint8>* buffer) {
354 // A raw key is always a symmetric key.
355 platform::SymKey* platform_key;
356 Status status = ToPlatformSymKey(key_to_wrap, &platform_key);
357 if (status.IsError())
358 return status;
359
360 // TODO(padolph): Handle other wrapping algorithms
361 switch (wrapping_algorithm.id()) {
362 case blink::WebCryptoAlgorithmIdAesKw: {
363 platform::SymKey* platform_wrapping_key;
364 status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key);
365 if (status.IsError())
366 return status;
367 return platform::WrapSymKeyAesKw(
368 platform_key, platform_wrapping_key, buffer);
369 }
370 default:
371 return Status::ErrorUnsupported();
372 }
373 }
374
375 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm,
376 const blink::WebCryptoKey& key,
377 const CryptoData& data,
378 std::vector<uint8>* buffer) {
379 platform::SymKey* sym_key; 316 platform::SymKey* sym_key;
380 Status status = ToPlatformSymKey(key, &sym_key); 317 Status status = ToPlatformSymKey(key, &sym_key);
381 if (status.IsError()) 318 if (status.IsError())
382 return status; 319 return status;
383 status = CheckAesKwInputSize(data); 320
321 unsigned int min_length = mode == ENCRYPT ? 16 : 24;
322
323 if (data.byte_length() < min_length)
324 return Status::ErrorDataTooSmall();
325 if (data.byte_length() % 8)
326 return Status::ErrorInvalidAesKwDataLength();
327
384 if (status.IsError()) 328 if (status.IsError())
385 return status; 329 return status;
386 return platform::DecryptAesKw(sym_key, data, buffer); 330 return platform::EncryptDecryptAesKw(mode, sym_key, data, buffer);
387 } 331 }
388 332
389 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm, 333 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm,
390 const blink::WebCryptoKey& key, 334 const blink::WebCryptoKey& key,
391 const CryptoData& data, 335 const CryptoData& data,
392 std::vector<uint8>* buffer) { 336 std::vector<uint8>* buffer) {
393 if (algorithm.id() != key.algorithm().id()) 337 if (algorithm.id() != key.algorithm().id())
394 return Status::ErrorUnexpected(); 338 return Status::ErrorUnexpected();
395 switch (algorithm.id()) { 339 switch (algorithm.id()) {
396 case blink::WebCryptoAlgorithmIdAesCbc: 340 case blink::WebCryptoAlgorithmIdAesCbc:
397 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer); 341 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer);
398 case blink::WebCryptoAlgorithmIdAesGcm: 342 case blink::WebCryptoAlgorithmIdAesGcm:
399 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); 343 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer);
400 case blink::WebCryptoAlgorithmIdRsaOaep: 344 case blink::WebCryptoAlgorithmIdRsaOaep:
401 return DecryptRsaOaep(algorithm, key, data, buffer); 345 return DecryptRsaOaep(algorithm, key, data, buffer);
402 case blink::WebCryptoAlgorithmIdAesKw: 346 case blink::WebCryptoAlgorithmIdAesKw:
403 return DecryptAesKw(algorithm, key, data, buffer); 347 return EncryptDecryptAesKw(DECRYPT, algorithm, key, data, buffer);
404 default: 348 default:
405 return Status::ErrorUnsupported(); 349 return Status::ErrorUnsupported();
406 } 350 }
407 } 351 }
408 352
409 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, 353 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm,
410 const blink::WebCryptoKey& key, 354 const blink::WebCryptoKey& key,
411 const CryptoData& data, 355 const CryptoData& data,
412 std::vector<uint8>* buffer) { 356 std::vector<uint8>* buffer) {
413 if (algorithm.id() != key.algorithm().id()) 357 if (algorithm.id() != key.algorithm().id())
414 return Status::ErrorUnexpected(); 358 return Status::ErrorUnexpected();
415 switch (algorithm.id()) { 359 switch (algorithm.id()) {
416 case blink::WebCryptoAlgorithmIdAesCbc: 360 case blink::WebCryptoAlgorithmIdAesCbc:
417 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); 361 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer);
418 case blink::WebCryptoAlgorithmIdAesGcm: 362 case blink::WebCryptoAlgorithmIdAesGcm:
419 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); 363 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer);
364 case blink::WebCryptoAlgorithmIdAesKw:
365 return EncryptDecryptAesKw(ENCRYPT, algorithm, key, data, buffer);
420 case blink::WebCryptoAlgorithmIdRsaOaep: 366 case blink::WebCryptoAlgorithmIdRsaOaep:
421 return EncryptRsaOaep(algorithm, key, data, buffer); 367 return EncryptRsaOaep(algorithm, key, data, buffer);
422 default: 368 default:
423 return Status::ErrorUnsupported(); 369 return Status::ErrorUnsupported();
424 } 370 }
425 } 371 }
426 372
427 Status UnwrapKeyDecryptAndImport( 373 Status UnwrapKeyDecryptAndImport(
428 blink::WebCryptoKeyFormat format, 374 blink::WebCryptoKeyFormat format,
429 const CryptoData& wrapped_key_data, 375 const CryptoData& wrapped_key_data,
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 Status WrapKey(blink::WebCryptoKeyFormat format, 831 Status WrapKey(blink::WebCryptoKeyFormat format,
886 const blink::WebCryptoKey& key_to_wrap, 832 const blink::WebCryptoKey& key_to_wrap,
887 const blink::WebCryptoKey& wrapping_key, 833 const blink::WebCryptoKey& wrapping_key,
888 const blink::WebCryptoAlgorithm& wrapping_algorithm, 834 const blink::WebCryptoAlgorithm& wrapping_algorithm,
889 std::vector<uint8>* buffer) { 835 std::vector<uint8>* buffer) {
890 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) 836 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey))
891 return Status::ErrorUnexpected(); 837 return Status::ErrorUnexpected();
892 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) 838 if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
893 return Status::ErrorUnexpected(); 839 return Status::ErrorUnexpected();
894 840
895 if (format == blink::WebCryptoKeyFormatRaw &&
896 wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) {
897 // AES-KW is a special case, due to NSS's implementation only
898 // supporting C_Wrap/C_Unwrap with AES-KW
899 return WrapKeyRaw(key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
900 }
901
902 return WrapKeyExportAndEncrypt( 841 return WrapKeyExportAndEncrypt(
903 format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer); 842 format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer);
904 } 843 }
905 844
906 Status UnwrapKey(blink::WebCryptoKeyFormat format, 845 Status UnwrapKey(blink::WebCryptoKeyFormat format,
907 const CryptoData& wrapped_key_data, 846 const CryptoData& wrapped_key_data,
908 const blink::WebCryptoKey& wrapping_key, 847 const blink::WebCryptoKey& wrapping_key,
909 const blink::WebCryptoAlgorithm& wrapping_algorithm, 848 const blink::WebCryptoAlgorithm& wrapping_algorithm,
910 const blink::WebCryptoAlgorithm& algorithm, 849 const blink::WebCryptoAlgorithm& algorithm,
911 bool extractable, 850 bool extractable,
912 blink::WebCryptoKeyUsageMask usage_mask, 851 blink::WebCryptoKeyUsageMask usage_mask,
913 blink::WebCryptoKey* key) { 852 blink::WebCryptoKey* key) {
914 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) 853 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey))
915 return Status::ErrorUnexpected(); 854 return Status::ErrorUnexpected();
916 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) 855 if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
917 return Status::ErrorUnexpected(); 856 return Status::ErrorUnexpected();
918 857
919 // Fail-fast if the key usages don't make sense. This avoids decrypting the 858 // Fail-fast if the key usages don't make sense. This avoids decrypting the
920 // key only to then have import fail. It is "best effort" because when 859 // key only to then have import fail. It is "best effort" because when
921 // unwrapping JWK for asymmetric algorithms the key type isn't known yet. 860 // unwrapping JWK for asymmetric algorithms the key type isn't known yet.
922 Status status = 861 Status status =
923 BestEffortCheckKeyUsagesForImport(algorithm.id(), format, usage_mask); 862 BestEffortCheckKeyUsagesForImport(algorithm.id(), format, usage_mask);
924 if (status.IsError()) 863 if (status.IsError())
925 return status; 864 return status;
926 865
927 if (format == blink::WebCryptoKeyFormatRaw &&
928 wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) {
929 // AES-KW is a special case, due to NSS's implementation only
930 // supporting C_Wrap/C_Unwrap with AES-KW
931 return UnwrapKeyRaw(wrapped_key_data,
932 wrapping_key,
933 wrapping_algorithm,
934 algorithm,
935 extractable,
936 usage_mask,
937 key);
938 }
939
940 return UnwrapKeyDecryptAndImport(format, 866 return UnwrapKeyDecryptAndImport(format,
941 wrapped_key_data, 867 wrapped_key_data,
942 wrapping_key, 868 wrapping_key,
943 wrapping_algorithm, 869 wrapping_algorithm,
944 algorithm, 870 algorithm,
945 extractable, 871 extractable,
946 usage_mask, 872 usage_mask,
947 key); 873 key);
948 } 874 }
949 875
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 if (!ContainsKeyUsages(GetValidKeyUsagesForKeyType(algorithm, key_type), 938 if (!ContainsKeyUsages(GetValidKeyUsagesForKeyType(algorithm, key_type),
1013 usages)) 939 usages))
1014 return Status::ErrorCreateKeyBadUsages(); 940 return Status::ErrorCreateKeyBadUsages();
1015 941
1016 return Status::Success(); 942 return Status::Success();
1017 } 943 }
1018 944
1019 } // namespace webcrypto 945 } // namespace webcrypto
1020 946
1021 } // namespace content 947 } // namespace content
OLDNEW
« no previous file with comments | « content/child/webcrypto/platform_crypto_openssl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698