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 void*, | |
80 unsigned char*, | |
81 unsigned int*, | |
82 unsigned int, | |
83 const unsigned char*, | |
84 unsigned int); | |
85 | |
86 // Signature for PK11_PubDecrypt | |
87 typedef SECStatus (*PK11_PubDecryptFunction)(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_pub_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_PubDecryptFunction pk11_pub_decrypt_func() const { | |
125 return pk11_pub_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_pub_decrypt_func_ = PK11_PubDecrypt; | |
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_pub_decrypt_func_ = reinterpret_cast<PK11_PubDecryptFunction>( | |
156 dlsym(RTLD_DEFAULT, "PK11_PubDecrypt")); | |
157 if (pk11_pub_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); | |
eroman
2014/05/16 20:29:51
Is the double negative intentional? Does PRBool no
| |
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_PubDecryptFunction pk11_pub_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. | |
eroman
2014/05/16 20:29:51
This comment is ambiguous, please be more specific
| |
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 NULL, | |
1320 buffer_data, | |
1321 &output_len, | |
1322 buffer->size(), | |
1323 data.bytes(), | |
1324 data.byte_length()) != | |
1325 SECSuccess) { | |
1326 return Status::OperationError(); | |
1327 } | |
1328 | |
1329 DCHECK_LE(output_len, buffer->size()); | |
1330 buffer->resize(output_len); | |
1331 return Status::Success(); | |
1332 } | |
1333 | |
1334 Status DecryptRsaOaep(PrivateKey* key, | |
1335 const blink::WebCryptoAlgorithm& hash, | |
1336 const CryptoData& label, | |
1337 const CryptoData& data, | |
1338 std::vector<uint8>* buffer) { | |
1339 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) | |
1340 return Status::ErrorUnsupported(); | |
1341 | |
1342 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; | |
1343 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) | |
1344 return Status::ErrorUnsupported(); | |
1345 | |
1346 SECItem param; | |
1347 param.type = siBuffer; | |
1348 param.data = reinterpret_cast<unsigned char*>(&oaep_params); | |
1349 param.len = sizeof(oaep_params); | |
1350 | |
1351 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); | |
1352 if (modulus_length_bytes <= 0) | |
1353 return Status::ErrorUnexpected(); | |
1354 | |
1355 buffer->resize(modulus_length_bytes); | |
1356 | |
1357 unsigned char* buffer_data = Uint8VectorStart(buffer); | |
1358 unsigned int output_len; | |
1359 if (g_nss_runtime_support.Get().pk11_pub_decrypt_func()(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()) != | |
1367 SECSuccess) { | |
1368 return Status::OperationError(); | |
1369 } | |
1370 | |
1371 DCHECK_LE(output_len, buffer->size()); | |
1372 buffer->resize(output_len); | |
1373 return Status::Success(); | |
1374 } | |
1375 | |
1376 // ----------------------------------- | |
1179 // RsaSsaPkcs1v1_5 | 1377 // RsaSsaPkcs1v1_5 |
1180 // ----------------------------------- | 1378 // ----------------------------------- |
1181 | 1379 |
1182 Status SignRsaSsaPkcs1v1_5(PrivateKey* key, | 1380 Status SignRsaSsaPkcs1v1_5(PrivateKey* key, |
1183 const blink::WebCryptoAlgorithm& hash, | 1381 const blink::WebCryptoAlgorithm& hash, |
1184 const CryptoData& data, | 1382 const CryptoData& data, |
1185 std::vector<uint8>* buffer) { | 1383 std::vector<uint8>* buffer) { |
1186 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the | 1384 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the |
1187 // inner hash of the input Web Crypto algorithm. | 1385 // inner hash of the input Web Crypto algorithm. |
1188 SECOidTag sign_alg_tag; | 1386 SECOidTag sign_alg_tag; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1280 // ----------------------------------- | 1478 // ----------------------------------- |
1281 | 1479 |
1282 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 1480 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
1283 bool extractable, | 1481 bool extractable, |
1284 blink::WebCryptoKeyUsageMask usage_mask, | 1482 blink::WebCryptoKeyUsageMask usage_mask, |
1285 unsigned int modulus_length_bits, | 1483 unsigned int modulus_length_bits, |
1286 const CryptoData& public_exponent, | 1484 const CryptoData& public_exponent, |
1287 const blink::WebCryptoAlgorithm& hash_or_null, | 1485 const blink::WebCryptoAlgorithm& hash_or_null, |
1288 blink::WebCryptoKey* public_key, | 1486 blink::WebCryptoKey* public_key, |
1289 blink::WebCryptoKey* private_key) { | 1487 blink::WebCryptoKey* private_key) { |
1488 if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep && | |
1489 !g_nss_runtime_support.Get().IsRsaOaepSupported()) { | |
1490 return Status::ErrorUnsupported(); | |
eroman
2014/05/16 20:29:51
Do the same thing for import/unwrap key?
| |
1491 } | |
1492 | |
1290 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1493 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
1291 if (!slot) | 1494 if (!slot) |
1292 return Status::OperationError(); | 1495 return Status::OperationError(); |
1293 | 1496 |
1294 unsigned long public_exponent_long; | 1497 unsigned long public_exponent_long; |
1295 if (!BigIntegerToLong(public_exponent.bytes(), | 1498 if (!BigIntegerToLong(public_exponent.bytes(), |
1296 public_exponent.byte_length(), | 1499 public_exponent.byte_length(), |
1297 &public_exponent_long) || | 1500 &public_exponent_long) || |
1298 !public_exponent_long) { | 1501 !public_exponent_long) { |
1299 return Status::ErrorGenerateKeyPublicExponent(); | 1502 return Status::ErrorGenerateKeyPublicExponent(); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1675 key_algorithm, | 1878 key_algorithm, |
1676 usage_mask); | 1879 usage_mask); |
1677 return Status::Success(); | 1880 return Status::Success(); |
1678 } | 1881 } |
1679 | 1882 |
1680 } // namespace platform | 1883 } // namespace platform |
1681 | 1884 |
1682 } // namespace webcrypto | 1885 } // namespace webcrypto |
1683 | 1886 |
1684 } // namespace content | 1887 } // namespace content |
OLD | NEW |