| OLD | NEW |
| 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/platform_crypto.h" | 5 #include "content/child/webcrypto/platform_crypto.h" |
| 6 | 6 |
| 7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
| 8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
| 9 #include <secerr.h> | 9 #include <secerr.h> |
| 10 #include <sechash.h> | 10 #include <sechash.h> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 struct CK_GCM_PARAMS { | 54 struct CK_GCM_PARAMS { |
| 55 CK_BYTE_PTR pIv; | 55 CK_BYTE_PTR pIv; |
| 56 CK_ULONG ulIvLen; | 56 CK_ULONG ulIvLen; |
| 57 CK_BYTE_PTR pAAD; | 57 CK_BYTE_PTR pAAD; |
| 58 CK_ULONG ulAADLen; | 58 CK_ULONG ulAADLen; |
| 59 CK_ULONG ulTagBits; | 59 CK_ULONG ulTagBits; |
| 60 }; | 60 }; |
| 61 #endif // !defined(CKM_AES_GCM) | 61 #endif // !defined(CKM_AES_GCM) |
| 62 | 62 |
| 63 namespace { |
| 64 |
| 63 // Signature for PK11_Encrypt and PK11_Decrypt. | 65 // Signature for PK11_Encrypt and PK11_Decrypt. |
| 64 typedef SECStatus (*PK11_EncryptDecryptFunction)(PK11SymKey*, | 66 typedef SECStatus (*PK11_EncryptDecryptFunction)(PK11SymKey*, |
| 65 CK_MECHANISM_TYPE, | 67 CK_MECHANISM_TYPE, |
| 66 SECItem*, | 68 SECItem*, |
| 67 unsigned char*, | 69 unsigned char*, |
| 68 unsigned int*, | 70 unsigned int*, |
| 69 unsigned int, | 71 unsigned int, |
| 70 const unsigned char*, | 72 const unsigned char*, |
| 71 unsigned int); | 73 unsigned int); |
| 72 | 74 |
| 75 // Signature for PK11_PubEncrypt |
| 76 typedef SECStatus (*PK11_PubEncryptFunction)(SECKEYPublicKey*, |
| 77 CK_MECHANISM_TYPE, |
| 78 SECItem*, |
| 79 unsigned char*, |
| 80 unsigned int*, |
| 81 unsigned int, |
| 82 const unsigned char*, |
| 83 unsigned int, |
| 84 void*); |
| 85 |
| 86 // Signature for PK11_PrivDecrypt |
| 87 typedef SECStatus (*PK11_PrivDecryptFunction)(SECKEYPrivateKey*, |
| 88 CK_MECHANISM_TYPE, |
| 89 SECItem*, |
| 90 unsigned char*, |
| 91 unsigned int*, |
| 92 unsigned int, |
| 93 const unsigned char*, |
| 94 unsigned int); |
| 95 |
| 73 // Singleton to abstract away dynamically loading libnss3.so | 96 // Singleton to abstract away dynamically loading libnss3.so |
| 74 class AesGcmSupport { | 97 class NssRuntimeSupport { |
| 75 public: | 98 public: |
| 76 bool IsSupported() const { return pk11_encrypt_func_ && pk11_decrypt_func_; } | 99 bool IsAesGcmSupported() const { |
| 100 return pk11_encrypt_func_ && pk11_decrypt_func_; |
| 101 } |
| 102 |
| 103 bool IsRsaOaepSupported() const { |
| 104 return pk11_pub_encrypt_func_ && pk11_priv_decrypt_func_ && |
| 105 internal_slot_does_oaep_; |
| 106 } |
| 77 | 107 |
| 78 // Returns NULL if unsupported. | 108 // Returns NULL if unsupported. |
| 79 PK11_EncryptDecryptFunction pk11_encrypt_func() const { | 109 PK11_EncryptDecryptFunction pk11_encrypt_func() const { |
| 80 return pk11_encrypt_func_; | 110 return pk11_encrypt_func_; |
| 81 } | 111 } |
| 82 | 112 |
| 83 // Returns NULL if unsupported. | 113 // Returns NULL if unsupported. |
| 84 PK11_EncryptDecryptFunction pk11_decrypt_func() const { | 114 PK11_EncryptDecryptFunction pk11_decrypt_func() const { |
| 85 return pk11_decrypt_func_; | 115 return pk11_decrypt_func_; |
| 86 } | 116 } |
| 87 | 117 |
| 118 // Returns NULL if unsupported. |
| 119 PK11_PubEncryptFunction pk11_pub_encrypt_func() const { |
| 120 return pk11_pub_encrypt_func_; |
| 121 } |
| 122 |
| 123 // Returns NULL if unsupported. |
| 124 PK11_PrivDecryptFunction pk11_priv_decrypt_func() const { |
| 125 return pk11_priv_decrypt_func_; |
| 126 } |
| 127 |
| 88 private: | 128 private: |
| 89 friend struct base::DefaultLazyInstanceTraits<AesGcmSupport>; | 129 friend struct base::DefaultLazyInstanceTraits<NssRuntimeSupport>; |
| 90 | 130 |
| 91 AesGcmSupport() { | 131 NssRuntimeSupport() : internal_slot_does_oaep_(false) { |
| 92 #if !defined(USE_NSS) | 132 #if !defined(USE_NSS) |
| 93 // Using a bundled version of NSS that is guaranteed to have this symbol. | 133 // Using a bundled version of NSS that is guaranteed to have this symbol. |
| 94 pk11_encrypt_func_ = PK11_Encrypt; | 134 pk11_encrypt_func_ = PK11_Encrypt; |
| 95 pk11_decrypt_func_ = PK11_Decrypt; | 135 pk11_decrypt_func_ = PK11_Decrypt; |
| 136 pk11_pub_encrypt_func_ = PK11_PubEncrypt; |
| 137 pk11_priv_decrypt_func_ = PK11_PrivDecrypt; |
| 138 internal_slot_does_oaep_ = true; |
| 96 #else | 139 #else |
| 97 // Using system NSS libraries and PCKS #11 modules, which may not have the | 140 // Using system NSS libraries and PCKS #11 modules, which may not have the |
| 98 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). | 141 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). |
| 99 | 142 |
| 100 // If PK11_Encrypt() was successfully resolved, then NSS will support | 143 // If PK11_Encrypt() was successfully resolved, then NSS will support |
| 101 // AES-GCM directly. This was introduced in NSS 3.15. | 144 // AES-GCM directly. This was introduced in NSS 3.15. |
| 102 pk11_encrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( | 145 pk11_encrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( |
| 103 dlsym(RTLD_DEFAULT, "PK11_Encrypt")); | 146 dlsym(RTLD_DEFAULT, "PK11_Encrypt")); |
| 104 pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( | 147 pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( |
| 105 dlsym(RTLD_DEFAULT, "PK11_Decrypt")); | 148 dlsym(RTLD_DEFAULT, "PK11_Decrypt")); |
| 149 |
| 150 // Even though NSS's pk11wrap layer may support |
| 151 // PK11_PubEncrypt/PK11_PubDecrypt (introduced in NSS 3.16.2), it may have |
| 152 // loaded a softoken that does not include OAEP support. |
| 153 pk11_pub_encrypt_func_ = reinterpret_cast<PK11_PubEncryptFunction>( |
| 154 dlsym(RTLD_DEFAULT, "PK11_PubEncrypt")); |
| 155 pk11_priv_decrypt_func_ = reinterpret_cast<PK11_PrivDecryptFunction>( |
| 156 dlsym(RTLD_DEFAULT, "PK11_PrivDecrypt")); |
| 157 if (pk11_priv_decrypt_func_ && pk11_pub_encrypt_func_) { |
| 158 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| 159 internal_slot_does_oaep_ = |
| 160 !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP); |
| 161 } |
| 106 #endif | 162 #endif |
| 107 } | 163 } |
| 108 | 164 |
| 109 PK11_EncryptDecryptFunction pk11_encrypt_func_; | 165 PK11_EncryptDecryptFunction pk11_encrypt_func_; |
| 110 PK11_EncryptDecryptFunction pk11_decrypt_func_; | 166 PK11_EncryptDecryptFunction pk11_decrypt_func_; |
| 167 PK11_PubEncryptFunction pk11_pub_encrypt_func_; |
| 168 PK11_PrivDecryptFunction pk11_priv_decrypt_func_; |
| 169 bool internal_slot_does_oaep_; |
| 111 }; | 170 }; |
| 112 | 171 |
| 113 base::LazyInstance<AesGcmSupport>::Leaky g_aes_gcm_support = | 172 base::LazyInstance<NssRuntimeSupport>::Leaky g_nss_runtime_support = |
| 114 LAZY_INSTANCE_INITIALIZER; | 173 LAZY_INSTANCE_INITIALIZER; |
| 115 | 174 |
| 175 } // namespace |
| 176 |
| 116 namespace content { | 177 namespace content { |
| 117 | 178 |
| 118 namespace webcrypto { | 179 namespace webcrypto { |
| 119 | 180 |
| 120 namespace platform { | 181 namespace platform { |
| 121 | 182 |
| 122 // Each key maintains a copy of its serialized form | 183 // Each key maintains a copy of its serialized form |
| 123 // in either 'raw', 'pkcs8', or 'spki' format. This is to allow | 184 // in either 'raw', 'pkcs8', or 'spki' format. This is to allow |
| 124 // structured cloning of keys synchronously from the target Blink | 185 // structured cloning of keys synchronously from the target Blink |
| 125 // thread without having to lock access to the key. | 186 // thread without having to lock access to the key. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 case blink::WebCryptoAlgorithmIdSha384: | 314 case blink::WebCryptoAlgorithmIdSha384: |
| 254 return CKM_SHA384_HMAC; | 315 return CKM_SHA384_HMAC; |
| 255 case blink::WebCryptoAlgorithmIdSha512: | 316 case blink::WebCryptoAlgorithmIdSha512: |
| 256 return CKM_SHA512_HMAC; | 317 return CKM_SHA512_HMAC; |
| 257 default: | 318 default: |
| 258 // Not a supported algorithm. | 319 // Not a supported algorithm. |
| 259 return CKM_INVALID_MECHANISM; | 320 return CKM_INVALID_MECHANISM; |
| 260 } | 321 } |
| 261 } | 322 } |
| 262 | 323 |
| 324 CK_MECHANISM_TYPE WebCryptoHashToDigestMechanism( |
| 325 const blink::WebCryptoAlgorithm& algorithm) { |
| 326 switch (algorithm.id()) { |
| 327 case blink::WebCryptoAlgorithmIdSha1: |
| 328 return CKM_SHA_1; |
| 329 case blink::WebCryptoAlgorithmIdSha256: |
| 330 return CKM_SHA256; |
| 331 case blink::WebCryptoAlgorithmIdSha384: |
| 332 return CKM_SHA384; |
| 333 case blink::WebCryptoAlgorithmIdSha512: |
| 334 return CKM_SHA512; |
| 335 default: |
| 336 // Not a supported algorithm. |
| 337 return CKM_INVALID_MECHANISM; |
| 338 } |
| 339 } |
| 340 |
| 341 CK_MECHANISM_TYPE WebCryptoHashToMGFMechanism( |
| 342 const blink::WebCryptoAlgorithm& algorithm) { |
| 343 switch (algorithm.id()) { |
| 344 case blink::WebCryptoAlgorithmIdSha1: |
| 345 return CKG_MGF1_SHA1; |
| 346 case blink::WebCryptoAlgorithmIdSha256: |
| 347 return CKG_MGF1_SHA256; |
| 348 case blink::WebCryptoAlgorithmIdSha384: |
| 349 return CKG_MGF1_SHA384; |
| 350 case blink::WebCryptoAlgorithmIdSha512: |
| 351 return CKG_MGF1_SHA512; |
| 352 default: |
| 353 return CKM_INVALID_MECHANISM; |
| 354 } |
| 355 } |
| 356 |
| 357 bool InitializeRsaOaepParams(const blink::WebCryptoAlgorithm& hash, |
| 358 const CryptoData& label, |
| 359 CK_RSA_PKCS_OAEP_PARAMS* oaep_params) { |
| 360 oaep_params->source = CKZ_DATA_SPECIFIED; |
| 361 oaep_params->pSourceData = const_cast<unsigned char*>(label.bytes()); |
| 362 oaep_params->ulSourceDataLen = label.byte_length(); |
| 363 oaep_params->mgf = WebCryptoHashToMGFMechanism(hash); |
| 364 oaep_params->hashAlg = WebCryptoHashToDigestMechanism(hash); |
| 365 |
| 366 if (oaep_params->mgf == CKM_INVALID_MECHANISM || |
| 367 oaep_params->hashAlg == CKM_INVALID_MECHANISM) { |
| 368 return false; |
| 369 } |
| 370 |
| 371 return true; |
| 372 } |
| 373 |
| 263 Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode, | 374 Status AesCbcEncryptDecrypt(EncryptOrDecrypt mode, |
| 264 SymKey* key, | 375 SymKey* key, |
| 265 const CryptoData& iv, | 376 const CryptoData& iv, |
| 266 const CryptoData& data, | 377 const CryptoData& data, |
| 267 std::vector<uint8>* buffer) { | 378 std::vector<uint8>* buffer) { |
| 268 CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT; | 379 CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT; |
| 269 | 380 |
| 270 SECItem iv_item = MakeSECItemForBuffer(iv); | 381 SECItem iv_item = MakeSECItemForBuffer(iv); |
| 271 | 382 |
| 272 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); | 383 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is | 441 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is |
| 331 // the concatenation of the ciphertext and the authentication tag. Similarly, | 442 // the concatenation of the ciphertext and the authentication tag. Similarly, |
| 332 // this is the expectation for the input to decryption. | 443 // this is the expectation for the input to decryption. |
| 333 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, | 444 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, |
| 334 SymKey* key, | 445 SymKey* key, |
| 335 const CryptoData& data, | 446 const CryptoData& data, |
| 336 const CryptoData& iv, | 447 const CryptoData& iv, |
| 337 const CryptoData& additional_data, | 448 const CryptoData& additional_data, |
| 338 unsigned int tag_length_bits, | 449 unsigned int tag_length_bits, |
| 339 std::vector<uint8>* buffer) { | 450 std::vector<uint8>* buffer) { |
| 340 if (!g_aes_gcm_support.Get().IsSupported()) | 451 if (!g_nss_runtime_support.Get().IsAesGcmSupported()) |
| 341 return Status::ErrorUnsupported(); | 452 return Status::ErrorUnsupported(); |
| 342 | 453 |
| 343 unsigned int tag_length_bytes = tag_length_bits / 8; | 454 unsigned int tag_length_bytes = tag_length_bits / 8; |
| 344 | 455 |
| 345 CK_GCM_PARAMS gcm_params = {0}; | 456 CK_GCM_PARAMS gcm_params = {0}; |
| 346 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); | 457 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); |
| 347 gcm_params.ulIvLen = iv.byte_length(); | 458 gcm_params.ulIvLen = iv.byte_length(); |
| 348 | 459 |
| 349 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); | 460 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); |
| 350 gcm_params.ulAADLen = additional_data.byte_length(); | 461 gcm_params.ulAADLen = additional_data.byte_length(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 376 // From the analysis of that bug it looks like it might be safe to pass a | 487 // From the analysis of that bug it looks like it might be safe to pass a |
| 377 // correctly sized buffer but lie about its size. Since resizing the | 488 // correctly sized buffer but lie about its size. Since resizing the |
| 378 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. | 489 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. |
| 379 buffer_size = data.byte_length(); | 490 buffer_size = data.byte_length(); |
| 380 } | 491 } |
| 381 | 492 |
| 382 buffer->resize(buffer_size); | 493 buffer->resize(buffer_size); |
| 383 unsigned char* buffer_data = Uint8VectorStart(buffer); | 494 unsigned char* buffer_data = Uint8VectorStart(buffer); |
| 384 | 495 |
| 385 PK11_EncryptDecryptFunction func = | 496 PK11_EncryptDecryptFunction func = |
| 386 (mode == ENCRYPT) ? g_aes_gcm_support.Get().pk11_encrypt_func() | 497 (mode == ENCRYPT) ? g_nss_runtime_support.Get().pk11_encrypt_func() |
| 387 : g_aes_gcm_support.Get().pk11_decrypt_func(); | 498 : g_nss_runtime_support.Get().pk11_decrypt_func(); |
| 388 | 499 |
| 389 unsigned int output_len = 0; | 500 unsigned int output_len = 0; |
| 390 SECStatus result = func(key->key(), | 501 SECStatus result = func(key->key(), |
| 391 CKM_AES_GCM, | 502 CKM_AES_GCM, |
| 392 ¶m, | 503 ¶m, |
| 393 buffer_data, | 504 buffer_data, |
| 394 &output_len, | 505 &output_len, |
| 395 buffer->size(), | 506 buffer->size(), |
| 396 data.bytes(), | 507 data.bytes(), |
| 397 data.byte_length()); | 508 data.byte_length()); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 *mechanism = CKM_AES_CBC; | 626 *mechanism = CKM_AES_CBC; |
| 516 *flags = CKF_ENCRYPT | CKF_DECRYPT; | 627 *flags = CKF_ENCRYPT | CKF_DECRYPT; |
| 517 break; | 628 break; |
| 518 } | 629 } |
| 519 case blink::WebCryptoAlgorithmIdAesKw: { | 630 case blink::WebCryptoAlgorithmIdAesKw: { |
| 520 *mechanism = CKM_NSS_AES_KEY_WRAP; | 631 *mechanism = CKM_NSS_AES_KEY_WRAP; |
| 521 *flags = CKF_WRAP | CKF_WRAP; | 632 *flags = CKF_WRAP | CKF_WRAP; |
| 522 break; | 633 break; |
| 523 } | 634 } |
| 524 case blink::WebCryptoAlgorithmIdAesGcm: { | 635 case blink::WebCryptoAlgorithmIdAesGcm: { |
| 525 if (!g_aes_gcm_support.Get().IsSupported()) | 636 if (!g_nss_runtime_support.Get().IsAesGcmSupported()) |
| 526 return Status::ErrorUnsupported(); | 637 return Status::ErrorUnsupported(); |
| 527 *mechanism = CKM_AES_GCM; | 638 *mechanism = CKM_AES_GCM; |
| 528 *flags = CKF_ENCRYPT | CKF_DECRYPT; | 639 *flags = CKF_ENCRYPT | CKF_DECRYPT; |
| 529 break; | 640 break; |
| 530 } | 641 } |
| 531 default: | 642 default: |
| 532 return Status::ErrorUnsupported(); | 643 return Status::ErrorUnsupported(); |
| 533 } | 644 } |
| 534 return Status::Success(); | 645 return Status::Success(); |
| 535 } | 646 } |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 if (modulus->empty() || public_exponent->empty()) | 1077 if (modulus->empty() || public_exponent->empty()) |
| 967 return Status::ErrorUnexpected(); | 1078 return Status::ErrorUnexpected(); |
| 968 return Status::Success(); | 1079 return Status::Success(); |
| 969 } | 1080 } |
| 970 | 1081 |
| 971 Status ExportKeyPkcs8(PrivateKey* key, | 1082 Status ExportKeyPkcs8(PrivateKey* key, |
| 972 const blink::WebCryptoKeyAlgorithm& key_algorithm, | 1083 const blink::WebCryptoKeyAlgorithm& key_algorithm, |
| 973 std::vector<uint8>* buffer) { | 1084 std::vector<uint8>* buffer) { |
| 974 // TODO(eroman): Support other RSA key types as they are added to Blink. | 1085 // TODO(eroman): Support other RSA key types as they are added to Blink. |
| 975 if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 && | 1086 if (key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 && |
| 976 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5) | 1087 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 && |
| 1088 key_algorithm.id() != blink::WebCryptoAlgorithmIdRsaOaep) |
| 977 return Status::ErrorUnsupported(); | 1089 return Status::ErrorUnsupported(); |
| 978 | 1090 |
| 1091 // TODO(rsleevi): Implement OAEP support according to the spec. |
| 1092 |
| 979 #if defined(USE_NSS) | 1093 #if defined(USE_NSS) |
| 980 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. | 1094 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. |
| 981 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; | 1095 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; |
| 982 const int kPrivateKeyInfoVersion = 0; | 1096 const int kPrivateKeyInfoVersion = 0; |
| 983 | 1097 |
| 984 SECKEYPrivateKeyInfo private_key_info = {}; | 1098 SECKEYPrivateKeyInfo private_key_info = {}; |
| 985 RSAPrivateKey rsa_private_key = {}; | 1099 RSAPrivateKey rsa_private_key = {}; |
| 986 scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key( | 1100 scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key( |
| 987 &rsa_private_key); | 1101 &rsa_private_key); |
| 988 | 1102 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 const_cast<unsigned char*>(data.bytes()), | 1283 const_cast<unsigned char*>(data.bytes()), |
| 1170 data.byte_length()) != SECSuccess) { | 1284 data.byte_length()) != SECSuccess) { |
| 1171 return Status::OperationError(); | 1285 return Status::OperationError(); |
| 1172 } | 1286 } |
| 1173 DCHECK_LE(output_length_bytes, max_output_length_bytes); | 1287 DCHECK_LE(output_length_bytes, max_output_length_bytes); |
| 1174 buffer->resize(output_length_bytes); | 1288 buffer->resize(output_length_bytes); |
| 1175 return Status::Success(); | 1289 return Status::Success(); |
| 1176 } | 1290 } |
| 1177 | 1291 |
| 1178 // ----------------------------------- | 1292 // ----------------------------------- |
| 1293 // RsaOaep |
| 1294 // ----------------------------------- |
| 1295 |
| 1296 Status EncryptRsaOaep(PublicKey* key, |
| 1297 const blink::WebCryptoAlgorithm& hash, |
| 1298 const CryptoData& label, |
| 1299 const CryptoData& data, |
| 1300 std::vector<uint8>* buffer) { |
| 1301 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) |
| 1302 return Status::ErrorUnsupported(); |
| 1303 |
| 1304 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; |
| 1305 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) |
| 1306 return Status::ErrorUnsupported(); |
| 1307 |
| 1308 SECItem param; |
| 1309 param.type = siBuffer; |
| 1310 param.data = reinterpret_cast<unsigned char*>(&oaep_params); |
| 1311 param.len = sizeof(oaep_params); |
| 1312 |
| 1313 buffer->resize(SECKEY_PublicKeyStrength(key->key())); |
| 1314 unsigned char* buffer_data = Uint8VectorStart(buffer); |
| 1315 unsigned int output_len; |
| 1316 if (g_nss_runtime_support.Get().pk11_pub_encrypt_func()(key->key(), |
| 1317 CKM_RSA_PKCS_OAEP, |
| 1318 ¶m, |
| 1319 buffer_data, |
| 1320 &output_len, |
| 1321 buffer->size(), |
| 1322 data.bytes(), |
| 1323 data.byte_length(), |
| 1324 NULL) != SECSuccess) { |
| 1325 return Status::OperationError(); |
| 1326 } |
| 1327 |
| 1328 DCHECK_LE(output_len, buffer->size()); |
| 1329 buffer->resize(output_len); |
| 1330 return Status::Success(); |
| 1331 } |
| 1332 |
| 1333 Status DecryptRsaOaep(PrivateKey* key, |
| 1334 const blink::WebCryptoAlgorithm& hash, |
| 1335 const CryptoData& label, |
| 1336 const CryptoData& data, |
| 1337 std::vector<uint8>* buffer) { |
| 1338 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) |
| 1339 return Status::ErrorUnsupported(); |
| 1340 |
| 1341 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; |
| 1342 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) |
| 1343 return Status::ErrorUnsupported(); |
| 1344 |
| 1345 SECItem param; |
| 1346 param.type = siBuffer; |
| 1347 param.data = reinterpret_cast<unsigned char*>(&oaep_params); |
| 1348 param.len = sizeof(oaep_params); |
| 1349 |
| 1350 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); |
| 1351 if (modulus_length_bytes <= 0) |
| 1352 return Status::ErrorUnexpected(); |
| 1353 |
| 1354 buffer->resize(modulus_length_bytes); |
| 1355 |
| 1356 unsigned char* buffer_data = Uint8VectorStart(buffer); |
| 1357 unsigned int output_len; |
| 1358 if (g_nss_runtime_support.Get().pk11_priv_decrypt_func()( |
| 1359 key->key(), |
| 1360 CKM_RSA_PKCS_OAEP, |
| 1361 ¶m, |
| 1362 buffer_data, |
| 1363 &output_len, |
| 1364 buffer->size(), |
| 1365 data.bytes(), |
| 1366 data.byte_length()) != SECSuccess) { |
| 1367 return Status::OperationError(); |
| 1368 } |
| 1369 |
| 1370 DCHECK_LE(output_len, buffer->size()); |
| 1371 buffer->resize(output_len); |
| 1372 return Status::Success(); |
| 1373 } |
| 1374 |
| 1375 // ----------------------------------- |
| 1179 // RsaSsaPkcs1v1_5 | 1376 // RsaSsaPkcs1v1_5 |
| 1180 // ----------------------------------- | 1377 // ----------------------------------- |
| 1181 | 1378 |
| 1182 Status SignRsaSsaPkcs1v1_5(PrivateKey* key, | 1379 Status SignRsaSsaPkcs1v1_5(PrivateKey* key, |
| 1183 const blink::WebCryptoAlgorithm& hash, | 1380 const blink::WebCryptoAlgorithm& hash, |
| 1184 const CryptoData& data, | 1381 const CryptoData& data, |
| 1185 std::vector<uint8>* buffer) { | 1382 std::vector<uint8>* buffer) { |
| 1186 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the | 1383 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the |
| 1187 // inner hash of the input Web Crypto algorithm. | 1384 // inner hash of the input Web Crypto algorithm. |
| 1188 SECOidTag sign_alg_tag; | 1385 SECOidTag sign_alg_tag; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 // ----------------------------------- | 1477 // ----------------------------------- |
| 1281 | 1478 |
| 1282 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 1479 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
| 1283 bool extractable, | 1480 bool extractable, |
| 1284 blink::WebCryptoKeyUsageMask usage_mask, | 1481 blink::WebCryptoKeyUsageMask usage_mask, |
| 1285 unsigned int modulus_length_bits, | 1482 unsigned int modulus_length_bits, |
| 1286 const CryptoData& public_exponent, | 1483 const CryptoData& public_exponent, |
| 1287 const blink::WebCryptoAlgorithm& hash_or_null, | 1484 const blink::WebCryptoAlgorithm& hash_or_null, |
| 1288 blink::WebCryptoKey* public_key, | 1485 blink::WebCryptoKey* public_key, |
| 1289 blink::WebCryptoKey* private_key) { | 1486 blink::WebCryptoKey* private_key) { |
| 1487 if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep && |
| 1488 !g_nss_runtime_support.Get().IsRsaOaepSupported()) { |
| 1489 return Status::ErrorUnsupported(); |
| 1490 } |
| 1491 |
| 1290 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1492 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| 1291 if (!slot) | 1493 if (!slot) |
| 1292 return Status::OperationError(); | 1494 return Status::OperationError(); |
| 1293 | 1495 |
| 1294 unsigned long public_exponent_long; | 1496 unsigned long public_exponent_long; |
| 1295 if (!BigIntegerToLong(public_exponent.bytes(), | 1497 if (!BigIntegerToLong(public_exponent.bytes(), |
| 1296 public_exponent.byte_length(), | 1498 public_exponent.byte_length(), |
| 1297 &public_exponent_long) || | 1499 &public_exponent_long) || |
| 1298 !public_exponent_long) { | 1500 !public_exponent_long) { |
| 1299 return Status::ErrorGenerateKeyPublicExponent(); | 1501 return Status::ErrorGenerateKeyPublicExponent(); |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1675 key_algorithm, | 1877 key_algorithm, |
| 1676 usage_mask); | 1878 usage_mask); |
| 1677 return Status::Success(); | 1879 return Status::Success(); |
| 1678 } | 1880 } |
| 1679 | 1881 |
| 1680 } // namespace platform | 1882 } // namespace platform |
| 1681 | 1883 |
| 1682 } // namespace webcrypto | 1884 } // namespace webcrypto |
| 1683 | 1885 |
| 1684 } // namespace content | 1886 } // namespace content |
| OLD | NEW |