Botan 3.6.1
Crypto and TLS for C&
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/der_enc.h>
14 #include <botan/pk_ops.h>
15 #include <botan/rng.h>
16 #include <botan/internal/p11_mechanism.h>
17
18namespace Botan::PKCS11 {
19
20ECDH_PublicKey PKCS11_ECDH_PublicKey::export_key() const {
21 return ECDH_PublicKey(domain(), public_point());
22}
23
24ECDH_PrivateKey PKCS11_ECDH_PrivateKey::export_key() const {
25 auto priv_key = get_attribute_value(AttributeType::Value);
26
27 Null_RNG rng;
28 return ECDH_PrivateKey(rng, domain(), BigInt::from_bytes(priv_key));
29}
30
31std::unique_ptr<Public_Key> PKCS11_ECDH_PrivateKey::public_key() const {
32 return std::make_unique<ECDH_PublicKey>(domain(), public_point());
33}
34
35secure_vector<uint8_t> PKCS11_ECDH_PrivateKey::private_key_bits() const {
36 return export_key().private_key_bits();
37}
38
39namespace {
40class PKCS11_ECDH_KA_Operation final : public PK_Ops::Key_Agreement {
41 public:
42 PKCS11_ECDH_KA_Operation(const PKCS11_EC_PrivateKey& key, std::string_view params) :
43 PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(params)) {}
44
45 size_t agreed_value_size() const override { return m_key.domain().get_p_bytes(); }
46
47 /// The encoding in V2.20 was not specified and resulted in different implementations choosing different encodings.
48 /// 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.
49 secure_vector<uint8_t> agree(size_t key_len,
50 std::span<const uint8_t> other_key,
51 std::span<const uint8_t> salt) override {
52 std::vector<uint8_t> der_encoded_other_key;
53 if(m_key.point_encoding() == PublicPointEncoding::Der) {
54 DER_Encoder(der_encoded_other_key).encode(other_key.data(), other_key.size(), ASN1_Type::OctetString);
55 m_mechanism.set_ecdh_other_key(der_encoded_other_key.data(), der_encoded_other_key.size());
56 } else {
57 m_mechanism.set_ecdh_other_key(other_key.data(), other_key.size());
58 }
59
60 if(!salt.empty()) {
61 m_mechanism.set_ecdh_salt(salt.data(), salt.size());
62 }
63
64 ObjectHandle secret_handle = 0;
65 AttributeContainer attributes;
66 attributes.add_bool(AttributeType::Sensitive, false);
67 attributes.add_bool(AttributeType::Extractable, true);
68 attributes.add_numeric(AttributeType::Class, static_cast<CK_OBJECT_CLASS>(ObjectClass::SecretKey));
69 attributes.add_numeric(AttributeType::KeyType, static_cast<CK_KEY_TYPE>(KeyType::GenericSecret));
70 attributes.add_numeric(AttributeType::ValueLen, static_cast<CK_ULONG>(key_len));
71 m_key.module()->C_DeriveKey(m_key.session().handle(),
72 m_mechanism.data(),
73 m_key.handle(),
74 attributes.data(),
75 static_cast<Ulong>(attributes.count()),
76 &secret_handle);
77
78 Object secret_object(m_key.session(), secret_handle);
79 secure_vector<uint8_t> secret = secret_object.get_attribute_value(AttributeType::Value);
80 if(secret.size() < key_len) {
81 throw PKCS11_Error("ECDH key derivation secret length is too short");
82 }
83 secret.resize(key_len);
84 return secret;
85 }
86
87 private:
88 const PKCS11_EC_PrivateKey& m_key;
89 MechanismWrapper m_mechanism;
90};
91
92} // namespace
93
94std::unique_ptr<PK_Ops::Key_Agreement> PKCS11_ECDH_PrivateKey::create_key_agreement_op(
95 RandomNumberGenerator& /*rng*/, std::string_view params, std::string_view /*provider*/) const {
96 return std::make_unique<PKCS11_ECDH_KA_Operation>(*this, params);
97}
98
99PKCS11_ECDH_KeyPair generate_ecdh_keypair(Session& session,
100 const EC_PublicKeyGenerationProperties& pub_props,
101 const EC_PrivateKeyGenerationProperties& priv_props) {
102 ObjectHandle pub_key_handle = 0;
103 ObjectHandle priv_key_handle = 0;
104
105 Mechanism mechanism = {static_cast<CK_MECHANISM_TYPE>(MechanismType::EcKeyPairGen), nullptr, 0};
106
107 session.module()->C_GenerateKeyPair(session.handle(),
108 &mechanism,
109 pub_props.data(),
110 static_cast<Ulong>(pub_props.count()),
111 priv_props.data(),
112 static_cast<Ulong>(priv_props.count()),
113 &pub_key_handle,
114 &priv_key_handle);
115
116 return std::make_pair(PKCS11_ECDH_PublicKey(session, pub_key_handle),
117 PKCS11_ECDH_PrivateKey(session, priv_key_handle));
118}
119
120} // namespace Botan::PKCS11
121
122#endif
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:95
int(* final)(unsigned char *, CTX *)
CK_MECHANISM Mechanism
Definition p11.h:819
CK_OBJECT_HANDLE ObjectHandle
Definition p11.h:826
CK_ULONG Ulong
Definition p11.h:816
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
unsigned long int CK_ULONG
Definition pkcs11t.h:48
CK_ULONG CK_OBJECT_CLASS
Definition pkcs11t.h:307
CK_ULONG CK_KEY_TYPE
Definition pkcs11t.h:336
CK_ULONG CK_MECHANISM_TYPE
Definition pkcs11t.h:583