| 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {} | 270 explicit PrivateKey(crypto::ScopedSECKEYPrivateKey key) : key_(key.Pass()) {} |
| 271 | 271 |
| 272 crypto::ScopedSECKEYPrivateKey key_; | 272 crypto::ScopedSECKEYPrivateKey key_; |
| 273 std::vector<uint8> serialized_key_; | 273 std::vector<uint8> serialized_key_; |
| 274 | 274 |
| 275 DISALLOW_COPY_AND_ASSIGN(PrivateKey); | 275 DISALLOW_COPY_AND_ASSIGN(PrivateKey); |
| 276 }; | 276 }; |
| 277 | 277 |
| 278 namespace { | 278 namespace { |
| 279 | 279 |
| 280 Status NssSupportsAesGcm() { |
| 281 if (g_nss_runtime_support.Get().IsAesGcmSupported()) |
| 282 return Status::Success(); |
| 283 return Status::ErrorUnsupported( |
| 284 "NSS version doesn't support AES-GCM. Try using version 3.15 or later"); |
| 285 } |
| 286 |
| 287 Status NssSupportsRsaOaep() { |
| 288 if (g_nss_runtime_support.Get().IsRsaOaepSupported()) |
| 289 return Status::Success(); |
| 290 return Status::ErrorUnsupported( |
| 291 "NSS version doesn't support RSA-OAEP. Try using version 3.16.2 or " |
| 292 "later"); |
| 293 } |
| 294 |
| 280 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so | 295 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so |
| 281 // |buffer| should outlive the SECItem. | 296 // |buffer| should outlive the SECItem. |
| 282 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { | 297 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { |
| 283 SECItem item = { | 298 SECItem item = { |
| 284 siBuffer, | 299 siBuffer, |
| 285 // NSS requires non-const data even though it is just for input. | 300 // NSS requires non-const data even though it is just for input. |
| 286 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()}; | 301 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()}; |
| 287 return item; | 302 return item; |
| 288 } | 303 } |
| 289 | 304 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is | 456 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is |
| 442 // the concatenation of the ciphertext and the authentication tag. Similarly, | 457 // the concatenation of the ciphertext and the authentication tag. Similarly, |
| 443 // this is the expectation for the input to decryption. | 458 // this is the expectation for the input to decryption. |
| 444 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, | 459 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, |
| 445 SymKey* key, | 460 SymKey* key, |
| 446 const CryptoData& data, | 461 const CryptoData& data, |
| 447 const CryptoData& iv, | 462 const CryptoData& iv, |
| 448 const CryptoData& additional_data, | 463 const CryptoData& additional_data, |
| 449 unsigned int tag_length_bits, | 464 unsigned int tag_length_bits, |
| 450 std::vector<uint8>* buffer) { | 465 std::vector<uint8>* buffer) { |
| 451 if (!g_nss_runtime_support.Get().IsAesGcmSupported()) | 466 Status status = NssSupportsAesGcm(); |
| 452 return Status::ErrorUnsupported(); | 467 if (status.IsError()) |
| 468 return status; |
| 453 | 469 |
| 454 unsigned int tag_length_bytes = tag_length_bits / 8; | 470 unsigned int tag_length_bytes = tag_length_bits / 8; |
| 455 | 471 |
| 456 CK_GCM_PARAMS gcm_params = {0}; | 472 CK_GCM_PARAMS gcm_params = {0}; |
| 457 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); | 473 gcm_params.pIv = const_cast<unsigned char*>(iv.bytes()); |
| 458 gcm_params.ulIvLen = iv.byte_length(); | 474 gcm_params.ulIvLen = iv.byte_length(); |
| 459 | 475 |
| 460 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); | 476 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); |
| 461 gcm_params.ulAADLen = additional_data.byte_length(); | 477 gcm_params.ulAADLen = additional_data.byte_length(); |
| 462 | 478 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 *mechanism = CKM_AES_CBC; | 606 *mechanism = CKM_AES_CBC; |
| 591 *flags = CKF_ENCRYPT | CKF_DECRYPT; | 607 *flags = CKF_ENCRYPT | CKF_DECRYPT; |
| 592 return Status::Success(); | 608 return Status::Success(); |
| 593 } | 609 } |
| 594 case blink::WebCryptoAlgorithmIdAesKw: { | 610 case blink::WebCryptoAlgorithmIdAesKw: { |
| 595 *mechanism = CKM_NSS_AES_KEY_WRAP; | 611 *mechanism = CKM_NSS_AES_KEY_WRAP; |
| 596 *flags = CKF_WRAP | CKF_WRAP; | 612 *flags = CKF_WRAP | CKF_WRAP; |
| 597 return Status::Success(); | 613 return Status::Success(); |
| 598 } | 614 } |
| 599 case blink::WebCryptoAlgorithmIdAesGcm: { | 615 case blink::WebCryptoAlgorithmIdAesGcm: { |
| 600 if (!g_nss_runtime_support.Get().IsAesGcmSupported()) | 616 Status status = NssSupportsAesGcm(); |
| 601 return Status::ErrorUnsupported(); | 617 if (status.IsError()) |
| 618 return status; |
| 602 *mechanism = CKM_AES_GCM; | 619 *mechanism = CKM_AES_GCM; |
| 603 *flags = CKF_ENCRYPT | CKF_DECRYPT; | 620 *flags = CKF_ENCRYPT | CKF_DECRYPT; |
| 604 return Status::Success(); | 621 return Status::Success(); |
| 605 } | 622 } |
| 606 default: | 623 default: |
| 607 return Status::ErrorUnsupported(); | 624 return Status::ErrorUnsupported(); |
| 608 } | 625 } |
| 609 } | 626 } |
| 610 | 627 |
| 611 Status DoUnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, | 628 Status DoUnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 | 1247 |
| 1231 // ----------------------------------- | 1248 // ----------------------------------- |
| 1232 // RsaOaep | 1249 // RsaOaep |
| 1233 // ----------------------------------- | 1250 // ----------------------------------- |
| 1234 | 1251 |
| 1235 Status EncryptRsaOaep(PublicKey* key, | 1252 Status EncryptRsaOaep(PublicKey* key, |
| 1236 const blink::WebCryptoAlgorithm& hash, | 1253 const blink::WebCryptoAlgorithm& hash, |
| 1237 const CryptoData& label, | 1254 const CryptoData& label, |
| 1238 const CryptoData& data, | 1255 const CryptoData& data, |
| 1239 std::vector<uint8>* buffer) { | 1256 std::vector<uint8>* buffer) { |
| 1240 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) | 1257 Status status = NssSupportsRsaOaep(); |
| 1241 return Status::ErrorUnsupported(); | 1258 if (status.IsError()) |
| 1259 return status; |
| 1242 | 1260 |
| 1243 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; | 1261 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; |
| 1244 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) | 1262 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) |
| 1245 return Status::ErrorUnsupported(); | 1263 return Status::ErrorUnsupported(); |
| 1246 | 1264 |
| 1247 SECItem param; | 1265 SECItem param; |
| 1248 param.type = siBuffer; | 1266 param.type = siBuffer; |
| 1249 param.data = reinterpret_cast<unsigned char*>(&oaep_params); | 1267 param.data = reinterpret_cast<unsigned char*>(&oaep_params); |
| 1250 param.len = sizeof(oaep_params); | 1268 param.len = sizeof(oaep_params); |
| 1251 | 1269 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1267 DCHECK_LE(output_len, buffer->size()); | 1285 DCHECK_LE(output_len, buffer->size()); |
| 1268 buffer->resize(output_len); | 1286 buffer->resize(output_len); |
| 1269 return Status::Success(); | 1287 return Status::Success(); |
| 1270 } | 1288 } |
| 1271 | 1289 |
| 1272 Status DecryptRsaOaep(PrivateKey* key, | 1290 Status DecryptRsaOaep(PrivateKey* key, |
| 1273 const blink::WebCryptoAlgorithm& hash, | 1291 const blink::WebCryptoAlgorithm& hash, |
| 1274 const CryptoData& label, | 1292 const CryptoData& label, |
| 1275 const CryptoData& data, | 1293 const CryptoData& data, |
| 1276 std::vector<uint8>* buffer) { | 1294 std::vector<uint8>* buffer) { |
| 1277 if (!g_nss_runtime_support.Get().IsRsaOaepSupported()) | 1295 Status status = NssSupportsRsaOaep(); |
| 1278 return Status::ErrorUnsupported(); | 1296 if (status.IsError()) |
| 1297 return status; |
| 1279 | 1298 |
| 1280 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; | 1299 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0}; |
| 1281 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) | 1300 if (!InitializeRsaOaepParams(hash, label, &oaep_params)) |
| 1282 return Status::ErrorUnsupported(); | 1301 return Status::ErrorUnsupported(); |
| 1283 | 1302 |
| 1284 SECItem param; | 1303 SECItem param; |
| 1285 param.type = siBuffer; | 1304 param.type = siBuffer; |
| 1286 param.data = reinterpret_cast<unsigned char*>(&oaep_params); | 1305 param.data = reinterpret_cast<unsigned char*>(&oaep_params); |
| 1287 param.len = sizeof(oaep_params); | 1306 param.len = sizeof(oaep_params); |
| 1288 | 1307 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 // ----------------------------------- | 1435 // ----------------------------------- |
| 1417 | 1436 |
| 1418 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 1437 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
| 1419 bool extractable, | 1438 bool extractable, |
| 1420 blink::WebCryptoKeyUsageMask public_key_usage_mask, | 1439 blink::WebCryptoKeyUsageMask public_key_usage_mask, |
| 1421 blink::WebCryptoKeyUsageMask private_key_usage_mask, | 1440 blink::WebCryptoKeyUsageMask private_key_usage_mask, |
| 1422 unsigned int modulus_length_bits, | 1441 unsigned int modulus_length_bits, |
| 1423 unsigned long public_exponent, | 1442 unsigned long public_exponent, |
| 1424 blink::WebCryptoKey* public_key, | 1443 blink::WebCryptoKey* public_key, |
| 1425 blink::WebCryptoKey* private_key) { | 1444 blink::WebCryptoKey* private_key) { |
| 1426 if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep && | 1445 if (algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep) { |
| 1427 !g_nss_runtime_support.Get().IsRsaOaepSupported()) { | 1446 Status status = NssSupportsRsaOaep(); |
| 1428 return Status::ErrorUnsupported(); | 1447 if (status.IsError()) |
| 1448 return status; |
| 1429 } | 1449 } |
| 1430 | 1450 |
| 1431 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1451 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| 1432 if (!slot) | 1452 if (!slot) |
| 1433 return Status::OperationError(); | 1453 return Status::OperationError(); |
| 1434 | 1454 |
| 1435 PK11RSAGenParams rsa_gen_params; | 1455 PK11RSAGenParams rsa_gen_params; |
| 1436 rsa_gen_params.keySizeInBits = modulus_length_bits; | 1456 rsa_gen_params.keySizeInBits = modulus_length_bits; |
| 1437 rsa_gen_params.pe = public_exponent; | 1457 rsa_gen_params.pe = public_exponent; |
| 1438 | 1458 |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1848 std::vector<uint8>* buffer) { | 1868 std::vector<uint8>* buffer) { |
| 1849 return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer) | 1869 return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer) |
| 1850 : DecryptAesKw(wrapping_key, data, buffer); | 1870 : DecryptAesKw(wrapping_key, data, buffer); |
| 1851 } | 1871 } |
| 1852 | 1872 |
| 1853 } // namespace platform | 1873 } // namespace platform |
| 1854 | 1874 |
| 1855 } // namespace webcrypto | 1875 } // namespace webcrypto |
| 1856 | 1876 |
| 1857 } // namespace content | 1877 } // namespace content |
| OLD | NEW |