Home | History | Annotate | Download | only in nss
      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