summaryrefslogtreecommitdiff
path: root/chromium/components/webcrypto/nss/util_nss.cc
blob: 784a98016caca92a2bbc68e4f8ad4a0c0659b857 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// 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 <dlfcn.h>
#include <secoid.h>
#endif

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_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<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;
}

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