// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/webcrypto/nss/util_nss.h" #include "base/lazy_instance.h" #include "components/webcrypto/crypto_data.h" #include "components/webcrypto/platform_crypto.h" #include "crypto/nss_util.h" #include "crypto/scoped_nss_types.h" #if defined(USE_NSS_CERTS) #include #include #endif namespace webcrypto { namespace { base::LazyInstance::Leaky g_nss_runtime_support = LAZY_INSTANCE_INITIALIZER; } // namespace // Creates a SECItem for the data in |buffer|. This does NOT make a copy, so // |buffer| should outlive the SECItem. SECItem MakeSECItemForBuffer(const CryptoData& buffer) { SECItem item = { siBuffer, // NSS requires non-const data even though it is just for input. const_cast(buffer.bytes()), buffer.byte_length()}; return item; } CryptoData SECItemToCryptoData(const SECItem& item) { return CryptoData(item.data, item.len); } NssRuntimeSupport* NssRuntimeSupport::Get() { return &g_nss_runtime_support.Get(); } NssRuntimeSupport::NssRuntimeSupport() : internal_slot_does_oaep_(false) { #if !defined(USE_NSS_CERTS) // Using a bundled version of NSS that is guaranteed to have this symbol. pk11_encrypt_func_ = PK11_Encrypt; pk11_decrypt_func_ = PK11_Decrypt; pk11_pub_encrypt_func_ = PK11_PubEncrypt; pk11_priv_decrypt_func_ = PK11_PrivDecrypt; internal_slot_does_oaep_ = true; #else // Using system NSS libraries and PCKS #11 modules, which may not have the // necessary function (PK11_Encrypt) or mechanism support (CKM_AES_GCM). // If PK11_Encrypt() was successfully resolved, then NSS will support // AES-GCM directly. This was introduced in NSS 3.15. pk11_encrypt_func_ = reinterpret_cast( dlsym(RTLD_DEFAULT, "PK11_Encrypt")); pk11_decrypt_func_ = reinterpret_cast( dlsym(RTLD_DEFAULT, "PK11_Decrypt")); // Even though NSS's pk11wrap layer may support // PK11_PubEncrypt/PK11_PubDecrypt (introduced in NSS 3.16.2), it may have // loaded a softoken that does not include OAEP support. pk11_pub_encrypt_func_ = reinterpret_cast( dlsym(RTLD_DEFAULT, "PK11_PubEncrypt")); pk11_priv_decrypt_func_ = reinterpret_cast( dlsym(RTLD_DEFAULT, "PK11_PrivDecrypt")); if (pk11_priv_decrypt_func_ && pk11_pub_encrypt_func_) { crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); internal_slot_does_oaep_ = !!PK11_DoesMechanism(slot.get(), CKM_RSA_PKCS_OAEP); } #endif } void PlatformInit() { crypto::EnsureNSSInit(); } AlgorithmImplementation* CreatePlatformAesCtrImplementation() { // TODO(eroman): http://crbug.com/399084 return NULL; } AlgorithmImplementation* CreatePlatformRsaPssImplementation() { // TODO(eroman): http://crbug.com/399090 return NULL; } AlgorithmImplementation* CreatePlatformEcdsaImplementation() { // TODO(eroman): http://crbug.com/399094 return NULL; } AlgorithmImplementation* CreatePlatformEcdhImplementation() { // TODO(eroman): http://crbug.com/399093 return NULL; } AlgorithmImplementation* CreatePlatformHkdfImplementation() { // HKDF is only being imlemented for BoringSSL. return NULL; } AlgorithmImplementation* CreatePlatformPbkdf2Implementation() { // PBKDF2 will only be implemented for BoringSSL, since the NSS // implementation is being deprecated. return NULL; } } // namespace webcrypto