Botan 3.6.1
Crypto and TLS for C&
p11_ecc_key.cpp
Go to the documentation of this file.
1/*
2* PKCS#11 ECC
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_ecc_key.h>
10
11#include <botan/pk_keys.h>
12
13#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
14
15 #include <botan/ber_dec.h>
16 #include <botan/internal/ec_key_data.h>
17 #include <botan/internal/workfactor.h>
18
19namespace Botan::PKCS11 {
20
21namespace {
22
23/// Converts a DER-encoded ANSI X9.62 ECPoint to EC_Point
24EC_AffinePoint decode_public_point(const EC_Group& group, std::span<const uint8_t> ec_point_data) {
25 std::vector<uint8_t> ec_point;
26 BER_Decoder(ec_point_data).decode(ec_point, ASN1_Type::OctetString);
27 // Throws if invalid
28 return EC_AffinePoint(group, ec_point);
29}
30
31} // namespace
32
33EC_PublicKeyGenerationProperties::EC_PublicKeyGenerationProperties(const std::vector<uint8_t>& ec_params) :
34 PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params) {
35 add_binary(AttributeType::EcParams, m_ec_params);
36}
37
38EC_PublicKeyImportProperties::EC_PublicKeyImportProperties(const std::vector<uint8_t>& ec_params,
39 const std::vector<uint8_t>& ec_point) :
40 PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_ec_point(ec_point) {
41 add_binary(AttributeType::EcParams, m_ec_params);
42 add_binary(AttributeType::EcPoint, m_ec_point);
43}
44
45PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle) : Object(session, handle) {
46 auto ec_parameters = get_attribute_value(AttributeType::EcParams);
47 auto pt_bytes = get_attribute_value(AttributeType::EcPoint);
48
49 EC_Group group(ec_parameters);
50 auto pt = decode_public_point(group, pt_bytes);
51 m_public_key = std::make_shared<EC_PublicKey_Data>(std::move(group), std::move(pt));
52}
53
54PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props) :
55 Object(session, props) {
56 EC_Group group(props.ec_params());
57 auto pt = decode_public_point(group, props.ec_point());
58 m_public_key = std::make_shared<EC_PublicKey_Data>(std::move(group), std::move(pt));
59}
60
61EC_PrivateKeyImportProperties::EC_PrivateKeyImportProperties(const std::vector<uint8_t>& ec_params,
62 const BigInt& value) :
63 PrivateKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_value(value) {
64 add_binary(AttributeType::EcParams, m_ec_params);
65 add_binary(AttributeType::Value, m_value.serialize());
66}
67
68PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle) : Object(session, handle) {
69 secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
70 m_domain_params = EC_Group(unlock(ec_parameters));
71}
72
73PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props) :
74 Object(session, props) {
75 m_domain_params = EC_Group(props.ec_params());
76}
77
78PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session,
79 const std::vector<uint8_t>& ec_params,
80 const EC_PrivateKeyGenerationProperties& props) :
81 Object(session) {
82 m_domain_params = EC_Group(ec_params);
83
84 EC_PublicKeyGenerationProperties pub_key_props(ec_params);
85 pub_key_props.set_verify(true);
86 pub_key_props.set_private(false);
87 pub_key_props.set_token(false); // don't create a persistent public key object
88
89 ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
90 ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
91 Mechanism mechanism = {CKM_EC_KEY_PAIR_GEN, nullptr, 0};
92 session.module()->C_GenerateKeyPair(session.handle(),
93 &mechanism,
94 pub_key_props.data(),
95 static_cast<Ulong>(pub_key_props.count()),
96 props.data(),
97 static_cast<Ulong>(props.count()),
98 &pub_key_handle,
99 &priv_key_handle);
100
101 this->reset_handle(priv_key_handle);
102 Object public_key(session, pub_key_handle);
103
104 auto pt_bytes = public_key.get_attribute_value(AttributeType::EcPoint);
105 m_public_key = decode_public_point(m_domain_params, pt_bytes).to_legacy_point();
106}
107
108size_t PKCS11_EC_PrivateKey::key_length() const {
109 return m_domain_params.get_order_bits();
110}
111
112std::vector<uint8_t> PKCS11_EC_PrivateKey::raw_public_key_bits() const {
113 return public_point().encode(EC_Point_Format::Compressed);
114}
115
116std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const {
117 return public_point().encode(EC_Point_Format::Compressed);
118}
119
120size_t PKCS11_EC_PrivateKey::estimated_strength() const {
121 return ecp_work_factor(key_length());
122}
123
124bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
125 return m_public_key.on_the_curve();
126}
127
128AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const {
129 return AlgorithmIdentifier(object_identifier(), domain().DER_encode());
130}
131} // namespace Botan::PKCS11
132
133#endif
CK_MECHANISM Mechanism
Definition p11.h:819
CK_OBJECT_HANDLE ObjectHandle
Definition p11.h:826
CK_ULONG Ulong
Definition p11.h:816
size_t ecp_work_factor(size_t bits)
std::vector< T > unlock(const secure_vector< T > &in)
Definition secmem.h:75
#define CK_INVALID_HANDLE
Definition pkcs11t.h:75
#define CKM_EC_KEY_PAIR_GEN
Definition pkcs11t.h:889