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

Side by Side Diff: content/renderer/webcrypto/platform_crypto_nss.cc

Issue 171503006: [style] Run webcrypto files through clang-format. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 10 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/renderer/webcrypto/platform_crypto.h" 5 #include "content/renderer/webcrypto/platform_crypto.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <sechash.h> 9 #include <sechash.h>
10 10
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 struct CK_GCM_PARAMS { 50 struct CK_GCM_PARAMS {
51 CK_BYTE_PTR pIv; 51 CK_BYTE_PTR pIv;
52 CK_ULONG ulIvLen; 52 CK_ULONG ulIvLen;
53 CK_BYTE_PTR pAAD; 53 CK_BYTE_PTR pAAD;
54 CK_ULONG ulAADLen; 54 CK_ULONG ulAADLen;
55 CK_ULONG ulTagBits; 55 CK_ULONG ulTagBits;
56 }; 56 };
57 #endif // !defined(CKM_AES_GCM) 57 #endif // !defined(CKM_AES_GCM)
58 58
59 // Signature for PK11_Encrypt and PK11_Decrypt. 59 // Signature for PK11_Encrypt and PK11_Decrypt.
60 typedef SECStatus 60 typedef SECStatus (*PK11_EncryptDecryptFunction)(PK11SymKey*,
61 (*PK11_EncryptDecryptFunction)( 61 CK_MECHANISM_TYPE,
62 PK11SymKey*, CK_MECHANISM_TYPE, SECItem*, 62 SECItem*,
63 unsigned char*, unsigned int*, unsigned int, 63 unsigned char*,
64 const unsigned char*, unsigned int); 64 unsigned int*,
65 unsigned int,
66 const unsigned char*,
67 unsigned int);
65 68
66 // Singleton to abstract away dynamically loading libnss3.so 69 // Singleton to abstract away dynamically loading libnss3.so
67 class AesGcmSupport { 70 class AesGcmSupport {
68 public: 71 public:
69 bool IsSupported() const { 72 bool IsSupported() const { return pk11_encrypt_func_ && pk11_decrypt_func_; }
70 return pk11_encrypt_func_ && pk11_decrypt_func_;
71 }
72 73
73 // Returns NULL if unsupported. 74 // Returns NULL if unsupported.
74 PK11_EncryptDecryptFunction pk11_encrypt_func() const { 75 PK11_EncryptDecryptFunction pk11_encrypt_func() const {
75 return pk11_encrypt_func_; 76 return pk11_encrypt_func_;
76 } 77 }
77 78
78 // Returns NULL if unsupported. 79 // Returns NULL if unsupported.
79 PK11_EncryptDecryptFunction pk11_decrypt_func() const { 80 PK11_EncryptDecryptFunction pk11_decrypt_func() const {
80 return pk11_decrypt_func_; 81 return pk11_decrypt_func_;
81 } 82 }
82 83
83 private: 84 private:
84 friend struct base::DefaultLazyInstanceTraits<AesGcmSupport>; 85 friend struct base::DefaultLazyInstanceTraits<AesGcmSupport>;
85 86
86 AesGcmSupport() { 87 AesGcmSupport() {
87 #if !defined(USE_NSS) 88 #if !defined(USE_NSS)
88 // Using a bundled version of NSS that is guaranteed to have this symbol. 89 // Using a bundled version of NSS that is guaranteed to have this symbol.
89 pk11_encrypt_func_ = PK11_Encrypt; 90 pk11_encrypt_func_ = PK11_Encrypt;
90 pk11_decrypt_func_ = PK11_Decrypt; 91 pk11_decrypt_func_ = PK11_Decrypt;
91 #else 92 #else
92 // Using system NSS libraries and PCKS #11 modules, which may not have the 93 // Using system NSS libraries and PCKS #11 modules, which may not have the
93 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). 94 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM).
94 95
95 // If PK11_Encrypt() was successfully resolved, then NSS will support 96 // If PK11_Encrypt() was successfully resolved, then NSS will support
96 // AES-GCM directly. This was introduced in NSS 3.15. 97 // AES-GCM directly. This was introduced in NSS 3.15.
97 pk11_encrypt_func_ = 98 pk11_encrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>(
98 reinterpret_cast<PK11_EncryptDecryptFunction>( 99 dlsym(RTLD_DEFAULT, "PK11_Encrypt"));
99 dlsym(RTLD_DEFAULT, "PK11_Encrypt")); 100 pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>(
100 pk11_decrypt_func_ = 101 dlsym(RTLD_DEFAULT, "PK11_Decrypt"));
101 reinterpret_cast<PK11_EncryptDecryptFunction>(
102 dlsym(RTLD_DEFAULT, "PK11_Decrypt"));
103 #endif 102 #endif
104 } 103 }
105 104
106 PK11_EncryptDecryptFunction pk11_encrypt_func_; 105 PK11_EncryptDecryptFunction pk11_encrypt_func_;
107 PK11_EncryptDecryptFunction pk11_decrypt_func_; 106 PK11_EncryptDecryptFunction pk11_decrypt_func_;
108 }; 107 };
109 108
110 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support = 109 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support =
111 LAZY_INSTANCE_INITIALIZER; 110 LAZY_INSTANCE_INITIALIZER;
112 111
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 }; 164 };
166 165
167 namespace { 166 namespace {
168 167
169 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so 168 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so
170 // |buffer| should outlive the SECItem. 169 // |buffer| should outlive the SECItem.
171 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { 170 SECItem MakeSECItemForBuffer(const CryptoData& buffer) {
172 SECItem item = { 171 SECItem item = {
173 siBuffer, 172 siBuffer,
174 // NSS requires non-const data even though it is just for input. 173 // NSS requires non-const data even though it is just for input.
175 const_cast<unsigned char*>(buffer.bytes()), 174 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()};
176 buffer.byte_length()
177 };
178 return item; 175 return item;
179 } 176 }
180 177
181 HASH_HashType WebCryptoAlgorithmToNSSHashType( 178 HASH_HashType WebCryptoAlgorithmToNSSHashType(
182 blink::WebCryptoAlgorithmId algorithm) { 179 blink::WebCryptoAlgorithmId algorithm) {
183 switch (algorithm) { 180 switch (algorithm) {
184 case blink::WebCryptoAlgorithmIdSha1: 181 case blink::WebCryptoAlgorithmIdSha1:
185 return HASH_AlgSHA1; 182 return HASH_AlgSHA1;
186 case blink::WebCryptoAlgorithmIdSha224: 183 case blink::WebCryptoAlgorithmIdSha224:
187 return HASH_AlgSHA224; 184 return HASH_AlgSHA224;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 return Status::Error(); 276 return Status::Error();
280 } 277 }
281 278
282 ShrinkBuffer(buffer, final_output_chunk_len + output_len); 279 ShrinkBuffer(buffer, final_output_chunk_len + output_len);
283 return Status::Success(); 280 return Status::Success();
284 } 281 }
285 282
286 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is 283 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is
287 // the concatenation of the ciphertext and the authentication tag. Similarly, 284 // the concatenation of the ciphertext and the authentication tag. Similarly,
288 // this is the expectation for the input to decryption. 285 // this is the expectation for the input to decryption.
289 Status AesGcmEncryptDecrypt( 286 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
290 EncryptOrDecrypt mode, 287 SymKey* key,
291 SymKey* key, 288 const CryptoData& data,
292 const CryptoData& data, 289 const CryptoData& iv,
293 const CryptoData& iv, 290 const CryptoData& additional_data,
294 const CryptoData& additional_data, 291 unsigned int tag_length_bits,
295 unsigned int tag_length_bits, 292 blink::WebArrayBuffer* buffer) {
296 blink::WebArrayBuffer* buffer) {
297 if (!g_aes_gcm_support.Get().IsSupported()) 293 if (!g_aes_gcm_support.Get().IsSupported())
298 return Status::ErrorUnsupported(); 294 return Status::ErrorUnsupported();
299 295
300 // TODO(eroman): Is this necessary? 296 // TODO(eroman): Is this necessary?
301 if ((tag_length_bits % 8) != 0) 297 if ((tag_length_bits % 8) != 0)
302 return Status::ErrorInvalidAesGcmTagLength(); 298 return Status::ErrorInvalidAesGcmTagLength();
303 unsigned int tag_length_bytes = tag_length_bits / 8; 299 unsigned int tag_length_bytes = tag_length_bits / 8;
304 300
305 CK_GCM_PARAMS gcm_params = {0}; 301 CK_GCM_PARAMS gcm_params = {0};
306 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); 302 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes());
(...skipping 29 matching lines...) Expand all
336 // From the analysis of that bug it looks like it might be safe to pass a 332 // From the analysis of that bug it looks like it might be safe to pass a
337 // correctly sized buffer but lie about its size. Since resizing the 333 // correctly sized buffer but lie about its size. Since resizing the
338 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. 334 // WebCryptoArrayBuffer is expensive that hack may be worth looking into.
339 buffer_size = data.byte_length(); 335 buffer_size = data.byte_length();
340 } 336 }
341 337
342 *buffer = blink::WebArrayBuffer::create(buffer_size, 1); 338 *buffer = blink::WebArrayBuffer::create(buffer_size, 1);
343 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); 339 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data());
344 340
345 PK11_EncryptDecryptFunction func = 341 PK11_EncryptDecryptFunction func =
346 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func() : 342 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func()
347 g_aes_gcm_support.Get().pk11_decrypt_func(); 343 : g_aes_gcm_support.Get().pk11_decrypt_func();
348 344
349 unsigned int output_len = 0; 345 unsigned int output_len = 0;
350 SECStatus result = func(key->key(), CKM_AES_GCM, &param, 346 SECStatus result = func(key->key(),
351 buffer_data, &output_len, buffer->byteLength(), 347 CKM_AES_GCM,
352 data.bytes(), data.byte_length()); 348 &param,
349 buffer_data,
350 &output_len,
351 buffer->byteLength(),
352 data.bytes(),
353 data.byte_length());
353 354
354 if (result != SECSuccess) 355 if (result != SECSuccess)
355 return Status::Error(); 356 return Status::Error();
356 357
357 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug 358 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug
358 // above). 359 // above).
359 ShrinkBuffer(buffer, output_len); 360 ShrinkBuffer(buffer, output_len);
360 361
361 return Status::Success(); 362 return Status::Success();
362 } 363 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 399 }
399 400
400 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) { 401 bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) {
401 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || 402 return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
402 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep || 403 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep ||
403 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; 404 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
404 } 405 }
405 406
406 } // namespace 407 } // namespace
407 408
408 Status ImportKeyRaw( 409 Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm,
409 const blink::WebCryptoAlgorithm& algorithm, 410 const CryptoData& key_data,
410 const CryptoData& key_data, 411 bool extractable,
411 bool extractable, 412 blink::WebCryptoKeyUsageMask usage_mask,
412 blink::WebCryptoKeyUsageMask usage_mask, 413 blink::WebCryptoKey* key) {
413 blink::WebCryptoKey* key) {
414 414
415 DCHECK(!algorithm.isNull()); 415 DCHECK(!algorithm.isNull());
416 416
417 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. 417 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys.
418 // Currently only supporting symmetric. 418 // Currently only supporting symmetric.
419 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; 419 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
420 // Flags are verified at the Blink layer; here the flags are set to all 420 // Flags are verified at the Blink layer; here the flags are set to all
421 // possible operations for this key type. 421 // possible operations for this key type.
422 CK_FLAGS flags = 0; 422 CK_FLAGS flags = 0;
423 423
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 return Status::Error(); 475 return Status::Error();
476 476
477 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), 477 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()),
478 blink::WebCryptoKeyTypeSecret, 478 blink::WebCryptoKeyTypeSecret,
479 extractable, 479 extractable,
480 algorithm, 480 algorithm,
481 usage_mask); 481 usage_mask);
482 return Status::Success(); 482 return Status::Success();
483 } 483 }
484 484
485 Status ExportKeyRaw( 485 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) {
486 SymKey* key,
487 blink::WebArrayBuffer* buffer) {
488 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) 486 if (PK11_ExtractKeyValue(key->key()) != SECSuccess)
489 return Status::Error(); 487 return Status::Error();
490 488
491 const SECItem* key_data = PK11_GetKeyData(key->key()); 489 const SECItem* key_data = PK11_GetKeyData(key->key());
492 if (!key_data) 490 if (!key_data)
493 return Status::Error(); 491 return Status::Error();
494 492
495 *buffer = CreateArrayBuffer(key_data->data, key_data->len); 493 *buffer = CreateArrayBuffer(key_data->data, key_data->len);
496 494
497 return Status::Success(); 495 return Status::Success();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 // TODO(padolph): Handle other key types. 527 // TODO(padolph): Handle other key types.
530 break; 528 break;
531 default: 529 default:
532 break; 530 break;
533 } 531 }
534 return blink::WebCryptoAlgorithm::createNull(); 532 return blink::WebCryptoAlgorithm::createNull();
535 } 533 }
536 534
537 } // namespace 535 } // namespace
538 536
539 Status ImportKeySpki( 537 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null,
540 const blink::WebCryptoAlgorithm& algorithm_or_null, 538 const CryptoData& key_data,
541 const CryptoData& key_data, 539 bool extractable,
542 bool extractable, 540 blink::WebCryptoKeyUsageMask usage_mask,
543 blink::WebCryptoKeyUsageMask usage_mask, 541 blink::WebCryptoKey* key) {
544 blink::WebCryptoKey* key) {
545 542
546 DCHECK(key); 543 DCHECK(key);
547 544
548 if (!key_data.byte_length()) 545 if (!key_data.byte_length())
549 return Status::ErrorImportEmptyKeyData(); 546 return Status::ErrorImportEmptyKeyData();
550 DCHECK(key_data.bytes()); 547 DCHECK(key_data.bytes());
551 548
552 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject 549 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
553 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. 550 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
554 SECItem spki_item = MakeSECItemForBuffer(key_data); 551 SECItem spki_item = MakeSECItemForBuffer(key_data);
555 const ScopedCERTSubjectPublicKeyInfo spki( 552 const ScopedCERTSubjectPublicKeyInfo spki(
556 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 553 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
557 if (!spki) 554 if (!spki)
558 return Status::Error(); 555 return Status::Error();
559 556
560 crypto::ScopedSECKEYPublicKey sec_public_key( 557 crypto::ScopedSECKEYPublicKey sec_public_key(
561 SECKEY_ExtractPublicKey(spki.get())); 558 SECKEY_ExtractPublicKey(spki.get()));
562 if (!sec_public_key) 559 if (!sec_public_key)
563 return Status::Error(); 560 return Status::Error();
564 561
565 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); 562 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
566 blink::WebCryptoAlgorithm algorithm = 563 blink::WebCryptoAlgorithm algorithm =
567 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); 564 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null);
568 if (algorithm.isNull()) 565 if (algorithm.isNull())
569 return Status::Error(); 566 return Status::Error();
570 567
571 *key = blink::WebCryptoKey::create( 568 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()),
572 new PublicKey(sec_public_key.Pass()), 569 blink::WebCryptoKeyTypePublic,
573 blink::WebCryptoKeyTypePublic, 570 extractable,
574 extractable, 571 algorithm,
575 algorithm, 572 usage_mask);
576 usage_mask);
577 573
578 return Status::Success(); 574 return Status::Success();
579 } 575 }
580 576
581 Status ExportKeySpki( 577 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) {
582 PublicKey* key,
583 blink::WebArrayBuffer* buffer) {
584 const crypto::ScopedSECItem spki_der( 578 const crypto::ScopedSECItem spki_der(
585 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); 579 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key()));
586 if (!spki_der) 580 if (!spki_der)
587 return Status::Error(); 581 return Status::Error();
588 582
589 DCHECK(spki_der->data); 583 DCHECK(spki_der->data);
590 DCHECK(spki_der->len); 584 DCHECK(spki_der->len);
591 585
592 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); 586 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len);
593 587
594 return Status::Success(); 588 return Status::Success();
595 } 589 }
596 590
597 Status ImportKeyPkcs8( 591 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm_or_null,
598 const blink::WebCryptoAlgorithm& algorithm_or_null, 592 const CryptoData& key_data,
599 const CryptoData& key_data, 593 bool extractable,
600 bool extractable, 594 blink::WebCryptoKeyUsageMask usage_mask,
601 blink::WebCryptoKeyUsageMask usage_mask, 595 blink::WebCryptoKey* key) {
602 blink::WebCryptoKey* key) {
603 596
604 DCHECK(key); 597 DCHECK(key);
605 598
606 if (!key_data.byte_length()) 599 if (!key_data.byte_length())
607 return Status::ErrorImportEmptyKeyData(); 600 return Status::ErrorImportEmptyKeyData();
608 DCHECK(key_data.bytes()); 601 DCHECK(key_data.bytes());
609 602
610 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 603 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8
611 // private key info object. 604 // private key info object.
612 SECItem pki_der = MakeSECItemForBuffer(key_data); 605 SECItem pki_der = MakeSECItemForBuffer(key_data);
613 606
614 SECKEYPrivateKey* seckey_private_key = NULL; 607 SECKEYPrivateKey* seckey_private_key = NULL;
615 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); 608 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
616 if (PK11_ImportDERPrivateKeyInfoAndReturnKey( 609 if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(),
617 slot.get(), 610 &pki_der,
618 &pki_der, 611 NULL, // nickname
619 NULL, // nickname 612 NULL, // publicValue
620 NULL, // publicValue 613 false, // isPerm
621 false, // isPerm 614 false, // isPrivate
622 false, // isPrivate 615 KU_ALL, // usage
623 KU_ALL, // usage 616 &seckey_private_key,
624 &seckey_private_key, 617 NULL) != SECSuccess) {
625 NULL) != SECSuccess) {
626 return Status::Error(); 618 return Status::Error();
627 } 619 }
628 DCHECK(seckey_private_key); 620 DCHECK(seckey_private_key);
629 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); 621 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key);
630 622
631 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); 623 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get());
632 blink::WebCryptoAlgorithm algorithm = 624 blink::WebCryptoAlgorithm algorithm =
633 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); 625 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null);
634 if (algorithm.isNull()) 626 if (algorithm.isNull())
635 return Status::Error(); 627 return Status::Error();
636 628
637 *key = blink::WebCryptoKey::create( 629 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()),
638 new PrivateKey(private_key.Pass()), 630 blink::WebCryptoKeyTypePrivate,
639 blink::WebCryptoKeyTypePrivate, 631 extractable,
640 extractable, 632 algorithm,
641 algorithm, 633 usage_mask);
642 usage_mask);
643 634
644 return Status::Success(); 635 return Status::Success();
645 } 636 }
646 637
647 // ----------------------------------- 638 // -----------------------------------
648 // Hmac 639 // Hmac
649 // ----------------------------------- 640 // -----------------------------------
650 641
651 Status SignHmac( 642 Status SignHmac(SymKey* key,
652 SymKey* key, 643 const blink::WebCryptoAlgorithm& hash,
653 const blink::WebCryptoAlgorithm& hash, 644 const CryptoData& data,
654 const CryptoData& data, 645 blink::WebArrayBuffer* buffer) {
655 blink::WebArrayBuffer* buffer) {
656 DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash)); 646 DCHECK_EQ(PK11_GetMechanism(key->key()), WebCryptoHashToHMACMechanism(hash));
657 647
658 SECItem param_item = { siBuffer, NULL, 0 }; 648 SECItem param_item = {siBuffer, NULL, 0};
659 SECItem data_item = MakeSECItemForBuffer(data); 649 SECItem data_item = MakeSECItemForBuffer(data);
660 // First call is to figure out the length. 650 // First call is to figure out the length.
661 SECItem signature_item = { siBuffer, NULL, 0 }; 651 SECItem signature_item = {siBuffer, NULL, 0};
662 652
663 if (PK11_SignWithSymKey(key->key(), 653 if (PK11_SignWithSymKey(key->key(),
664 PK11_GetMechanism(key->key()), 654 PK11_GetMechanism(key->key()),
665 &param_item, 655 &param_item,
666 &signature_item, 656 &signature_item,
667 &data_item) != SECSuccess) { 657 &data_item) != SECSuccess) {
668 return Status::Error(); 658 return Status::Error();
669 } 659 }
670 660
671 DCHECK_NE(0u, signature_item.len); 661 DCHECK_NE(0u, signature_item.len);
(...skipping 10 matching lines...) Expand all
682 } 672 }
683 673
684 DCHECK_EQ(buffer->byteLength(), signature_item.len); 674 DCHECK_EQ(buffer->byteLength(), signature_item.len);
685 return Status::Success(); 675 return Status::Success();
686 } 676 }
687 677
688 // ----------------------------------- 678 // -----------------------------------
689 // RsaEsPkcs1v1_5 679 // RsaEsPkcs1v1_5
690 // ----------------------------------- 680 // -----------------------------------
691 681
692 Status EncryptRsaEsPkcs1v1_5( 682 Status EncryptRsaEsPkcs1v1_5(PublicKey* key,
693 PublicKey* key, 683 const CryptoData& data,
694 const CryptoData& data, 684 blink::WebArrayBuffer* buffer) {
695 blink::WebArrayBuffer* buffer) {
696 const unsigned int encrypted_length_bytes = 685 const unsigned int encrypted_length_bytes =
697 SECKEY_PublicKeyStrength(key->key()); 686 SECKEY_PublicKeyStrength(key->key());
698 687
699 // RSAES can operate on messages up to a length of k - 11, where k is the 688 // RSAES can operate on messages up to a length of k - 11, where k is the
700 // octet length of the RSA modulus. 689 // octet length of the RSA modulus.
701 if (encrypted_length_bytes < 11 || 690 if (encrypted_length_bytes < 11 ||
702 encrypted_length_bytes - 11 < data.byte_length()) 691 encrypted_length_bytes - 11 < data.byte_length())
703 return Status::ErrorDataTooLarge(); 692 return Status::ErrorDataTooLarge();
704 693
705 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); 694 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1);
706 unsigned char* const buffer_data = 695 unsigned char* const buffer_data =
707 reinterpret_cast<unsigned char*>(buffer->data()); 696 reinterpret_cast<unsigned char*>(buffer->data());
708 697
709 if (PK11_PubEncryptPKCS1(key->key(), 698 if (PK11_PubEncryptPKCS1(key->key(),
710 buffer_data, 699 buffer_data,
711 const_cast<unsigned char*>(data.bytes()), 700 const_cast<unsigned char*>(data.bytes()),
712 data.byte_length(), 701 data.byte_length(),
713 NULL) != SECSuccess) { 702 NULL) != SECSuccess) {
714 return Status::Error(); 703 return Status::Error();
715 } 704 }
716 return Status::Success(); 705 return Status::Success();
717 } 706 }
718 707
719 Status DecryptRsaEsPkcs1v1_5( 708 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
720 PrivateKey* key, 709 const CryptoData& data,
721 const CryptoData& data, 710 blink::WebArrayBuffer* buffer) {
722 blink::WebArrayBuffer* buffer) {
723 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); 711 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key());
724 if (modulus_length_bytes <= 0) 712 if (modulus_length_bytes <= 0)
725 return Status::ErrorUnexpected(); 713 return Status::ErrorUnexpected();
726 const unsigned int max_output_length_bytes = modulus_length_bytes; 714 const unsigned int max_output_length_bytes = modulus_length_bytes;
727 715
728 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); 716 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1);
729 unsigned char* const buffer_data = 717 unsigned char* const buffer_data =
730 reinterpret_cast<unsigned char*>(buffer->data()); 718 reinterpret_cast<unsigned char*>(buffer->data());
731 719
732 unsigned int output_length_bytes = 0; 720 unsigned int output_length_bytes = 0;
733 if (PK11_PrivDecryptPKCS1(key->key(), 721 if (PK11_PrivDecryptPKCS1(key->key(),
734 buffer_data, 722 buffer_data,
735 &output_length_bytes, 723 &output_length_bytes,
736 max_output_length_bytes, 724 max_output_length_bytes,
737 const_cast<unsigned char*>(data.bytes()), 725 const_cast<unsigned char*>(data.bytes()),
738 data.byte_length()) != SECSuccess) { 726 data.byte_length()) != SECSuccess) {
739 return Status::Error(); 727 return Status::Error();
740 } 728 }
741 DCHECK_LE(output_length_bytes, max_output_length_bytes); 729 DCHECK_LE(output_length_bytes, max_output_length_bytes);
742 ShrinkBuffer(buffer, output_length_bytes); 730 ShrinkBuffer(buffer, output_length_bytes);
743 return Status::Success(); 731 return Status::Success();
744 } 732 }
745 733
746 // ----------------------------------- 734 // -----------------------------------
747 // RsaSsaPkcs1v1_5 735 // RsaSsaPkcs1v1_5
748 // ----------------------------------- 736 // -----------------------------------
749 737
750 Status SignRsaSsaPkcs1v1_5( 738 Status SignRsaSsaPkcs1v1_5(PrivateKey* key,
751 PrivateKey* key, 739 const blink::WebCryptoAlgorithm& hash,
752 const blink::WebCryptoAlgorithm& hash, 740 const CryptoData& data,
753 const CryptoData& data, 741 blink::WebArrayBuffer* buffer) {
754 blink::WebArrayBuffer* buffer) {
755 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the 742 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
756 // inner hash of the input Web Crypto algorithm. 743 // inner hash of the input Web Crypto algorithm.
757 SECOidTag sign_alg_tag; 744 SECOidTag sign_alg_tag;
758 switch (hash.id()) { 745 switch (hash.id()) {
759 case blink::WebCryptoAlgorithmIdSha1: 746 case blink::WebCryptoAlgorithmIdSha1:
760 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 747 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
761 break; 748 break;
762 case blink::WebCryptoAlgorithmIdSha224: 749 case blink::WebCryptoAlgorithmIdSha224:
763 sign_alg_tag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; 750 sign_alg_tag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION;
764 break; 751 break;
(...skipping 16 matching lines...) Expand all
781 data.byte_length(), 768 data.byte_length(),
782 key->key(), 769 key->key(),
783 sign_alg_tag) != SECSuccess) { 770 sign_alg_tag) != SECSuccess) {
784 return Status::Error(); 771 return Status::Error();
785 } 772 }
786 773
787 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); 774 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len);
788 return Status::Success(); 775 return Status::Success();
789 } 776 }
790 777
791 Status VerifyRsaSsaPkcs1v1_5( 778 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key,
792 PublicKey* key, 779 const blink::WebCryptoAlgorithm& hash,
793 const blink::WebCryptoAlgorithm& hash, 780 const CryptoData& signature,
794 const CryptoData& signature, 781 const CryptoData& data,
795 const CryptoData& data, 782 bool* signature_match) {
796 bool* signature_match) {
797 const SECItem signature_item = MakeSECItemForBuffer(signature); 783 const SECItem signature_item = MakeSECItemForBuffer(signature);
798 784
799 SECOidTag hash_alg_tag; 785 SECOidTag hash_alg_tag;
800 switch (hash.id()) { 786 switch (hash.id()) {
801 case blink::WebCryptoAlgorithmIdSha1: 787 case blink::WebCryptoAlgorithmIdSha1:
802 hash_alg_tag = SEC_OID_SHA1; 788 hash_alg_tag = SEC_OID_SHA1;
803 break; 789 break;
804 case blink::WebCryptoAlgorithmIdSha224: 790 case blink::WebCryptoAlgorithmIdSha224:
805 hash_alg_tag = SEC_OID_SHA224; 791 hash_alg_tag = SEC_OID_SHA224;
806 break; 792 break;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 blink::WebArrayBuffer* buffer) { 833 blink::WebArrayBuffer* buffer) {
848 // TODO(eroman): Inline. 834 // TODO(eroman): Inline.
849 return AesGcmEncryptDecrypt( 835 return AesGcmEncryptDecrypt(
850 mode, key, data, iv, additional_data, tag_length_bits, buffer); 836 mode, key, data, iv, additional_data, tag_length_bits, buffer);
851 } 837 }
852 838
853 // ----------------------------------- 839 // -----------------------------------
854 // Key generation 840 // Key generation
855 // ----------------------------------- 841 // -----------------------------------
856 842
857 Status GenerateRsaKeyPair( 843 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm,
858 const blink::WebCryptoAlgorithm& algorithm, 844 bool extractable,
859 bool extractable, 845 blink::WebCryptoKeyUsageMask usage_mask,
860 blink::WebCryptoKeyUsageMask usage_mask, 846 blink::WebCryptoKey* public_key,
861 blink::WebCryptoKey* public_key, 847 blink::WebCryptoKey* private_key) {
862 blink::WebCryptoKey* private_key) {
863 const blink::WebCryptoRsaKeyGenParams* const params = 848 const blink::WebCryptoRsaKeyGenParams* const params =
864 algorithm.rsaKeyGenParams(); 849 algorithm.rsaKeyGenParams();
865 DCHECK(params); 850 DCHECK(params);
866 851
867 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); 852 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
868 if (!slot) 853 if (!slot)
869 return Status::Error(); 854 return Status::Error();
870 855
871 unsigned long public_exponent; 856 unsigned long public_exponent;
872 if (!params->modulusLengthBits()) 857 if (!params->modulusLengthBits())
873 return Status::ErrorGenerateRsaZeroModulus(); 858 return Status::ErrorGenerateRsaZeroModulus();
874 859
875 if (!BigIntegerToLong(params->publicExponent().data(), 860 if (!BigIntegerToLong(params->publicExponent().data(),
876 params->publicExponent().size(), 861 params->publicExponent().size(),
877 &public_exponent) || !public_exponent) { 862 &public_exponent) ||
863 !public_exponent) {
878 return Status::ErrorGenerateKeyPublicExponent(); 864 return Status::ErrorGenerateKeyPublicExponent();
879 } 865 }
880 866
881 PK11RSAGenParams rsa_gen_params; 867 PK11RSAGenParams rsa_gen_params;
882 rsa_gen_params.keySizeInBits = params->modulusLengthBits(); 868 rsa_gen_params.keySizeInBits = params->modulusLengthBits();
883 rsa_gen_params.pe = public_exponent; 869 rsa_gen_params.pe = public_exponent;
884 870
885 // Flags are verified at the Blink layer; here the flags are set to all 871 // Flags are verified at the Blink layer; here the flags are set to all
886 // possible operations for the given key type. 872 // possible operations for the given key type.
887 CK_FLAGS operation_flags; 873 CK_FLAGS operation_flags;
888 switch (algorithm.id()) { 874 switch (algorithm.id()) {
889 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: 875 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
890 case blink::WebCryptoAlgorithmIdRsaOaep: 876 case blink::WebCryptoAlgorithmIdRsaOaep:
891 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; 877 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
892 break; 878 break;
893 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: 879 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
894 operation_flags = CKF_SIGN | CKF_VERIFY; 880 operation_flags = CKF_SIGN | CKF_VERIFY;
895 break; 881 break;
896 default: 882 default:
897 NOTREACHED(); 883 NOTREACHED();
898 return Status::ErrorUnexpected(); 884 return Status::ErrorUnexpected();
899 } 885 }
900 const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT | 886 const CK_FLAGS operation_flags_mask =
901 CKF_SIGN | CKF_VERIFY | CKF_WRAP | 887 CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_WRAP | CKF_UNWRAP;
902 CKF_UNWRAP;
903 const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags. 888 const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags.
904 889
905 // Note: NSS does not generate an sec_public_key if the call below fails, 890 // Note: NSS does not generate an sec_public_key if the call below fails,
906 // so there is no danger of a leaked sec_public_key. 891 // so there is no danger of a leaked sec_public_key.
907 SECKEYPublicKey* sec_public_key; 892 SECKEYPublicKey* sec_public_key;
908 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key( 893 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key(
909 PK11_GenerateKeyPairWithOpFlags(slot.get(), 894 PK11_GenerateKeyPairWithOpFlags(slot.get(),
910 CKM_RSA_PKCS_KEY_PAIR_GEN, 895 CKM_RSA_PKCS_KEY_PAIR_GEN,
911 &rsa_gen_params, 896 &rsa_gen_params,
912 &sec_public_key, 897 &sec_public_key,
913 attribute_flags, 898 attribute_flags,
914 operation_flags, 899 operation_flags,
915 operation_flags_mask, 900 operation_flags_mask,
916 NULL)); 901 NULL));
917 if (!private_key) 902 if (!private_key)
918 return Status::Error(); 903 return Status::Error();
919 904
920 *public_key = blink::WebCryptoKey::create( 905 *public_key = blink::WebCryptoKey::create(
921 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), 906 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)),
922 blink::WebCryptoKeyTypePublic, 907 blink::WebCryptoKeyTypePublic,
923 true, 908 true,
924 algorithm, 909 algorithm,
925 usage_mask); 910 usage_mask);
926 *private_key = blink::WebCryptoKey::create( 911 *private_key =
927 new PrivateKey(scoped_sec_private_key.Pass()), 912 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()),
928 blink::WebCryptoKeyTypePrivate, 913 blink::WebCryptoKeyTypePrivate,
929 extractable, 914 extractable,
930 algorithm, 915 algorithm,
931 usage_mask); 916 usage_mask);
932 917
933 return Status::Success(); 918 return Status::Success();
934 } 919 }
935 920
936 void Init() { 921 void Init() { crypto::EnsureNSSInit(); }
937 crypto::EnsureNSSInit();
938 }
939 922
940 Status DigestSha( 923 Status DigestSha(blink::WebCryptoAlgorithmId algorithm,
941 blink::WebCryptoAlgorithmId algorithm, 924 const CryptoData& data,
942 const CryptoData& data, 925 blink::WebArrayBuffer* buffer) {
943 blink::WebArrayBuffer* buffer) {
944 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); 926 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm);
945 if (hash_type == HASH_AlgNULL) 927 if (hash_type == HASH_AlgNULL)
946 return Status::ErrorUnsupported(); 928 return Status::ErrorUnsupported();
947 929
948 HASHContext* context = HASH_Create(hash_type); 930 HASHContext* context = HASH_Create(hash_type);
949 if (!context) 931 if (!context)
950 return Status::Error(); 932 return Status::Error();
951 933
952 HASH_Begin(context); 934 HASH_Begin(context);
953 935
954 HASH_Update(context, data.bytes(), data.byte_length()); 936 HASH_Update(context, data.bytes(), data.byte_length());
955 937
956 unsigned int hash_result_length = HASH_ResultLenContext(context); 938 unsigned int hash_result_length = HASH_ResultLenContext(context);
957 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); 939 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX));
958 940
959 *buffer = blink::WebArrayBuffer::create(hash_result_length, 1); 941 *buffer = blink::WebArrayBuffer::create(hash_result_length, 1);
960 942
961 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); 943 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data());
962 944
963 unsigned int result_length = 0; 945 unsigned int result_length = 0;
964 HASH_End(context, digest, &result_length, hash_result_length); 946 HASH_End(context, digest, &result_length, hash_result_length);
965 947
966 HASH_Destroy(context); 948 HASH_Destroy(context);
967 949
968 if (result_length != hash_result_length) 950 if (result_length != hash_result_length)
969 return Status::ErrorUnexpected(); 951 return Status::ErrorUnexpected();
970 return Status::Success(); 952 return Status::Success();
971 } 953 }
972 954
973 Status GenerateSecretKey( 955 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
974 const blink::WebCryptoAlgorithm& algorithm, 956 bool extractable,
975 bool extractable, 957 blink::WebCryptoKeyUsageMask usage_mask,
976 blink::WebCryptoKeyUsageMask usage_mask, 958 unsigned keylen_bytes,
977 unsigned keylen_bytes, 959 blink::WebCryptoKey* key) {
978 blink::WebCryptoKey* key) {
979 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); 960 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm);
980 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; 961 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret;
981 962
982 if (mech == CKM_INVALID_MECHANISM) 963 if (mech == CKM_INVALID_MECHANISM)
983 return Status::ErrorUnsupported(); 964 return Status::ErrorUnsupported();
984 965
985 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); 966 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
986 if (!slot) 967 if (!slot)
987 return Status::Error(); 968 return Status::Error();
988 969
989 crypto::ScopedPK11SymKey pk11_key( 970 crypto::ScopedPK11SymKey pk11_key(
990 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); 971 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL));
991 972
992 if (!pk11_key) 973 if (!pk11_key)
993 return Status::Error(); 974 return Status::Error();
994 975
995 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), 976 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()),
996 key_type, 977 key_type,
997 extractable, 978 extractable,
998 algorithm, 979 algorithm,
999 usage_mask); 980 usage_mask);
1000 return Status::Success(); 981 return Status::Success();
1001 } 982 }
1002 983
1003 Status ImportRsaPublicKey( 984 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm,
1004 const blink::WebCryptoAlgorithm& algorithm, 985 bool extractable,
1005 bool extractable, 986 blink::WebCryptoKeyUsageMask usage_mask,
1006 blink::WebCryptoKeyUsageMask usage_mask, 987 const CryptoData& modulus_data,
1007 const CryptoData& modulus_data, 988 const CryptoData& exponent_data,
1008 const CryptoData& exponent_data, 989 blink::WebCryptoKey* key) {
1009 blink::WebCryptoKey* key) {
1010 990
1011 if (!modulus_data.byte_length()) 991 if (!modulus_data.byte_length())
1012 return Status::ErrorImportRsaEmptyModulus(); 992 return Status::ErrorImportRsaEmptyModulus();
1013 993
1014 if (!exponent_data.byte_length()) 994 if (!exponent_data.byte_length())
1015 return Status::ErrorImportRsaEmptyExponent(); 995 return Status::ErrorImportRsaEmptyExponent();
1016 996
1017 DCHECK(modulus_data.bytes()); 997 DCHECK(modulus_data.bytes());
1018 DCHECK(exponent_data.bytes()); 998 DCHECK(exponent_data.bytes());
1019 999
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 algorithm, 1038 algorithm,
1059 usage_mask); 1039 usage_mask);
1060 return Status::Success(); 1040 return Status::Success();
1061 } 1041 }
1062 1042
1063 } // namespace platform 1043 } // namespace platform
1064 1044
1065 } // namespace webcrypto 1045 } // namespace webcrypto
1066 1046
1067 } // namespace content 1047 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/webcrypto/platform_crypto.h ('k') | content/renderer/webcrypto/platform_crypto_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698