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 |