Botan 3.4.0
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/workfactor.h>
17
18namespace Botan::PKCS11 {
19namespace {
20/// Converts a DER-encoded ANSI X9.62 ECPoint to EC_Point
21EC_Point decode_public_point(const secure_vector<uint8_t>& ec_point_data, const EC_Group& group) {
22 secure_vector<uint8_t> ec_point;
23 BER_Decoder(ec_point_data).decode(ec_point, ASN1_Type::OctetString);
24 return group.OS2ECP(ec_point);
25}
26} // namespace
27
28EC_PublicKeyGenerationProperties::EC_PublicKeyGenerationProperties(const std::vector<uint8_t>& ec_params) :
29 PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params) {
30 add_binary(AttributeType::EcParams, m_ec_params);
31}
32
33EC_PublicKeyImportProperties::EC_PublicKeyImportProperties(const std::vector<uint8_t>& ec_params,
34 const std::vector<uint8_t>& ec_point) :
35 PublicKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_ec_point(ec_point) {
36 add_binary(AttributeType::EcParams, m_ec_params);
37 add_binary(AttributeType::EcPoint, m_ec_point);
38}
39
40PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, ObjectHandle handle) : Object(session, handle) {
41 secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
42 m_domain_params = EC_Group(unlock(ec_parameters));
43 m_public_key = decode_public_point(get_attribute_value(AttributeType::EcPoint), m_domain_params);
44 m_domain_encoding = EC_Group_Encoding::Explicit;
45}
46
47PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props) :
48 Object(session, props) {
49 m_domain_params = EC_Group(props.ec_params());
50
51 secure_vector<uint8_t> ec_point;
52 BER_Decoder(props.ec_point()).decode(ec_point, ASN1_Type::OctetString);
53 m_public_key = m_domain_params.OS2ECP(ec_point);
54 m_domain_encoding = EC_Group_Encoding::Explicit;
55}
56
57EC_PrivateKeyImportProperties::EC_PrivateKeyImportProperties(const std::vector<uint8_t>& ec_params,
58 const BigInt& value) :
59 PrivateKeyProperties(KeyType::Ec), m_ec_params(ec_params), m_value(value) {
60 add_binary(AttributeType::EcParams, m_ec_params);
61 add_binary(AttributeType::Value, BigInt::encode(m_value));
62}
63
64PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, ObjectHandle handle) :
65 Object(session, handle), m_domain_params(), m_public_key() {
66 secure_vector<uint8_t> ec_parameters = get_attribute_value(AttributeType::EcParams);
67 m_domain_params = EC_Group(unlock(ec_parameters));
68}
69
70PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props) :
71 Object(session, props) {
72 m_domain_params = EC_Group(props.ec_params());
73}
74
75PKCS11_EC_PrivateKey::PKCS11_EC_PrivateKey(Session& session,
76 const std::vector<uint8_t>& ec_params,
77 const EC_PrivateKeyGenerationProperties& props) :
78 Object(session) {
79 m_domain_params = EC_Group(ec_params);
80
81 EC_PublicKeyGenerationProperties pub_key_props(ec_params);
82 pub_key_props.set_verify(true);
83 pub_key_props.set_private(false);
84 pub_key_props.set_token(false); // don't create a persistent public key object
85
86 ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
87 ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
88 Mechanism mechanism = {CKM_EC_KEY_PAIR_GEN, nullptr, 0};
89 session.module()->C_GenerateKeyPair(session.handle(),
90 &mechanism,
91 pub_key_props.data(),
92 static_cast<Ulong>(pub_key_props.count()),
93 props.data(),
94 static_cast<Ulong>(props.count()),
95 &pub_key_handle,
96 &priv_key_handle);
97
98 this->reset_handle(priv_key_handle);
99
100 Object public_key(session, pub_key_handle);
101 m_public_key = decode_public_point(public_key.get_attribute_value(AttributeType::EcPoint), m_domain_params);
102}
103
104size_t PKCS11_EC_PrivateKey::key_length() const {
105 return m_domain_params.get_order().bits();
106}
107
108std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const {
109 return public_point().encode(EC_Point_Format::Compressed);
110}
111
112size_t PKCS11_EC_PrivateKey::estimated_strength() const {
113 return ecp_work_factor(key_length());
114}
115
116bool PKCS11_EC_PrivateKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
117 return m_public_key.on_the_curve();
118}
119
120AlgorithmIdentifier PKCS11_EC_PrivateKey::algorithm_identifier() const {
121 return AlgorithmIdentifier(object_identifier(), domain().DER_encode(EC_Group_Encoding::Explicit));
122}
123} // namespace Botan::PKCS11
124
125#endif
CK_MECHANISM Mechanism
Definition p11.h:817
CK_OBJECT_HANDLE ObjectHandle
Definition p11.h:824
CK_ULONG Ulong
Definition p11.h:814
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