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