// 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 "content/child/webcrypto/nss/util_nss.h"
#include "base/lazy_instance.h"
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/platform_crypto.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
#if defined(USE_NSS)
#include <dlfcn.h>
#include <secoid.h>
#endif
namespace content {
namespace webcrypto {
namespace {
base::LazyInstance<NssRuntimeSupport>::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<unsigned char*>(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)
// 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<PK11_EncryptDecryptFunction>(
dlsym(RTLD_DEFAULT, "PK11_Encrypt"));
pk11_decrypt_func_ = reinterpret_cast<PK11_EncryptDecryptFunction>(
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<PK11_PubEncryptFunction>(
dlsym(RTLD_DEFAULT, "PK11_PubEncrypt"));
pk11_priv_decrypt_func_ = reinterpret_cast<PK11_PrivDecryptFunction>(
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;
}
} // namespace webcrypto
} // namespace content