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 3 // found in the LICENSE file. 4 5 #include "content/child/webcrypto/nss/util_nss.h" 6 7 #include "base/lazy_instance.h" 8 #include "content/child/webcrypto/crypto_data.h" 9 #include "content/child/webcrypto/platform_crypto.h" 10 #include "crypto/nss_util.h" 11 #include "crypto/scoped_nss_types.h" 12 13 #if defined(USE_NSS) 14 #include <dlfcn.h> 15 #include <secoid.h> 16 #endif 17 18 namespace content { 19 20 namespace webcrypto { 21 22 namespace { 23 base::LazyInstance<NssRuntimeSupport>::Leaky g_nss_runtime_support = 24 LAZY_INSTANCE_INITIALIZER; 25 } // namespace 26 27 // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so 28 // |buffer| should outlive the SECItem. 29 SECItem MakeSECItemForBuffer(const CryptoData& buffer) { 30 SECItem item = { 31 siBuffer, 32 // NSS requires non-const data even though it is just for input. 33 const_cast<unsigned char*>(buffer.bytes()), buffer.byte_length()}; 34 return item; 35 } 36 37 CryptoData SECItemToCryptoData(const SECItem& item) { 38 return CryptoData(item.data, item.len); 39 } 40 41 NssRuntimeSupport* NssRuntimeSupport::Get() { 42 return &g_nss_runtime_support.Get(); 43 } 44 45 NssRuntimeSupport::NssRuntimeSupport() : internal_slot_does_oaep_(false) { 46 #if !defined(USE_NSS) 47 // Using a bundled version of NSS that is guaranteed to have this symbol. 48 pk11_encrypt_func_ = PK11_Encrypt; 49 pk11_decrypt_func_ = PK11_Decrypt; 50 pk11_pub_encrypt_func_ = PK11_PubEncrypt; 51 pk11_priv_decrypt_func_ = PK11_PrivDecrypt; 52 internal_slot_does_oaep_ = true; 53 #else 54 // Using system NSS libraries and PCKS #11 modules, which may not have the 55 // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). 56 57 // If PK11_Encrypt() was successfully resolved, then NSS will support 58 // AES-GCM directly. This was introduced in NSS 3.15. 59 pk11_encrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( 60 dlsym(RTLD_DEFAULT, "PK11_Encrypt")); 61 pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>( 62 dlsym(RTLD_DEFAULT, "PK11_Decrypt")); 63 64 // Even though NSS's pk11wrap layer may support 65 // PK11_PubEncrypt/PK11_PubDecrypt (introduced in NSS 3.16.2), it may have 66 // loaded a softoken that does not include OAEP support. 67 pk11_pub_encrypt_func_ = reinterpret_cast<PK11_PubEncryptFunction>( 68 dlsym(RTLD_DEFAULT, "PK11_PubEncrypt")); 69 pk11_priv_decrypt_func_ = reinterpret_cast<PK11_PrivDecryptFunction>( 70 dlsym(RTLD_DEFAULT, "PK11_PrivDecrypt")); 71 if (pk11_priv_decrypt_func_ && pk11_pub_encrypt_func_) { 72 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); 73 internal_slot_does_oaep_ = 74 !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP); 75 } 76 #endif 77 } 78 79 void PlatformInit() { 80 crypto::EnsureNSSInit(); 81 } 82 83 AlgorithmImplementation* CreatePlatformAesCtrImplementation() { 84 // TODO(eroman): http://crbug.com/399084 85 return NULL; 86 } 87 88 } // namespace webcrypto 89 90 } // namespace content 91