Botan  2.4.0
Crypto and TLS for C++11
p11_ecdh.cpp
Go to the documentation of this file.
1 /*
2 * PKCS#11 ECDH
3 * (C) 2016 Daniel Neus, Sirrix AG
4 * (C) 2016 Philipp Weber, Sirrix AG
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/p11_ecdh.h>
10 
11 #if defined(BOTAN_HAS_ECDH)
12 
13 #include <botan/internal/p11_mechanism.h>
14 #include <botan/der_enc.h>
15 #include <botan/pk_ops.h>
16 #include <botan/rng.h>
17 
18 namespace Botan {
19 
20 namespace PKCS11 {
21 
22 ECDH_PublicKey PKCS11_ECDH_PublicKey::export_key() const
23  {
24  return ECDH_PublicKey(domain(), public_point());
25  }
26 
27 ECDH_PrivateKey PKCS11_ECDH_PrivateKey::export_key() const
28  {
29  auto priv_key = get_attribute_value(AttributeType::Value);
30 
31  Null_RNG rng;
32  return ECDH_PrivateKey(rng, domain(), BigInt::decode(priv_key));
33  }
34 
35 secure_vector<uint8_t> PKCS11_ECDH_PrivateKey::private_key_bits() const
36  {
37  return export_key().private_key_bits();
38  }
39 
40 namespace {
41 class PKCS11_ECDH_KA_Operation final : public PK_Ops::Key_Agreement
42  {
43  public:
44  PKCS11_ECDH_KA_Operation(const PKCS11_EC_PrivateKey& key, const std::string& params)
45  : PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(params))
46  {}
47 
48 
49  /// The encoding in V2.20 was not specified and resulted in different implementations choosing different encodings.
50  /// Applications relying only on a V2.20 encoding (e.g. the DER variant) other than the one specified now (raw) may not work with all V2.30 compliant tokens.
51  secure_vector<uint8_t> agree(size_t key_len, const uint8_t other_key[], size_t other_key_len, const uint8_t salt[],
52  size_t salt_len) override
53  {
54  std::vector<uint8_t> der_encoded_other_key;
55  if(m_key.point_encoding() == PublicPointEncoding::Der)
56  {
57  der_encoded_other_key = DER_Encoder().encode(other_key, other_key_len, OCTET_STRING).get_contents_unlocked();
58  m_mechanism.set_ecdh_other_key(der_encoded_other_key.data(), der_encoded_other_key.size());
59  }
60  else
61  {
62  m_mechanism.set_ecdh_other_key(other_key, other_key_len);
63  }
64 
65  if(salt != nullptr && salt_len > 0)
66  {
67  m_mechanism.set_ecdh_salt(salt, salt_len);
68  }
69 
70  ObjectHandle secret_handle = 0;
71  AttributeContainer attributes;
72  attributes.add_bool(AttributeType::Sensitive, false);
73  attributes.add_bool(AttributeType::Extractable, true);
74  attributes.add_numeric(AttributeType::Class, static_cast< CK_OBJECT_CLASS >(ObjectClass::SecretKey));
75  attributes.add_numeric(AttributeType::KeyType, static_cast< CK_KEY_TYPE >(KeyType::GenericSecret));
76  attributes.add_numeric(AttributeType::ValueLen, key_len);
77  m_key.module()->C_DeriveKey(m_key.session().handle(), m_mechanism.data(), m_key.handle(), attributes.data(),
78  attributes.count(), &secret_handle);
79 
80  Object secret_object(m_key.session(), secret_handle);
81  secure_vector<uint8_t> secret = secret_object.get_attribute_value(AttributeType::Value);
82  if(secret.size() < key_len)
83  {
84  throw PKCS11_Error("ECDH key derivation secret length is too short");
85  }
86  secret.resize(key_len);
87  return secret;
88  }
89 
90  private:
91  const PKCS11_EC_PrivateKey& m_key;
92  MechanismWrapper m_mechanism;
93  };
94 
95 }
96 
97 std::unique_ptr<PK_Ops::Key_Agreement>
98 PKCS11_ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator&,
99  const std::string& params,
100  const std::string& /*provider*/) const
101  {
102  return std::unique_ptr<PK_Ops::Key_Agreement>(new PKCS11_ECDH_KA_Operation(*this, params));
103  }
104 
105 PKCS11_ECDH_KeyPair generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props,
106  const EC_PrivateKeyGenerationProperties& priv_props)
107  {
108  ObjectHandle pub_key_handle = 0;
109  ObjectHandle priv_key_handle = 0;
110 
111  Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::EcKeyPairGen), nullptr, 0 };
112 
113  session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
114  pub_props.data(), pub_props.count(), priv_props.data(), priv_props.count(),
115  &pub_key_handle, &priv_key_handle);
116 
117  return std::make_pair(PKCS11_ECDH_PublicKey(session, pub_key_handle), PKCS11_ECDH_PrivateKey(session, priv_key_handle));
118  }
119 
120 }
121 }
122 
123 #endif
CK_ULONG CK_MECHANISM_TYPE
Definition: pkcs11t.h:583
size_t salt_len
Definition: x509_obj.cpp:25
Definition: alg_id.cpp:13
CK_OBJECT_HANDLE ObjectHandle
Definition: p11.h:846
static BigInt decode(const uint8_t buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:114