9#include <botan/p11_ecdsa.h>
11#if defined(BOTAN_HAS_ECDSA)
13 #include <botan/p11_mechanism.h>
14 #include <botan/pk_ops.h>
15 #include <botan/rng.h>
16 #include <botan/internal/keypair.h>
17 #include <botan/internal/scan_name.h>
21ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key()
const {
22 return ECDSA_PublicKey(domain(), _public_ec_point());
25bool PKCS11_ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng,
bool strong)
const {
30 const ECDSA_PublicKey pubkey(domain(), public_ec_point());
34ECDSA_PrivateKey PKCS11_ECDSA_PrivateKey::export_key()
const {
42 return export_key().private_key_bits();
45std::unique_ptr<Public_Key> PKCS11_ECDSA_PrivateKey::public_key()
const {
46 return std::make_unique<ECDSA_PublicKey>(domain(), public_ec_point());
54std::string canonical_ecdsa_hash(std::string_view hash) {
55 const SCAN_Name req((std::string(hash)));
56 if(req.algo_name() ==
"EMSA1" && req.arg_count() == 1) {
59 return std::string(hash);
62class PKCS11_ECDSA_Signature_Operation final :
public PK_Ops::Signature {
64 PKCS11_ECDSA_Signature_Operation(
const PKCS11_ECDSA_PrivateKey& key, std::string_view hash) :
67 m_order_bytes(key.domain().get_order_bytes()),
68 m_mechanism(MechanismWrapper::create_ecdsa_mechanism(hash)),
69 m_hash(canonical_ecdsa_hash(hash)) {}
71 void update(std::span<const uint8_t> input)
override {
74 m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
76 m_first_message.assign(input.begin(), input.end());
77 m_has_first_message =
true;
81 if(m_has_first_message) {
83 m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
84 m_first_message.clear();
85 m_has_first_message =
false;
88 m_key.module()->C_SignUpdate(m_key.session().handle(), input.data(),
checked_ulong_cast(input.size()));
91 std::vector<uint8_t> sign(RandomNumberGenerator& )
override {
94 m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
96 m_has_first_message =
true;
98 std::vector<uint8_t> signature;
99 if(m_has_first_message) {
101 m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
102 m_first_message.clear();
103 m_has_first_message =
false;
106 m_key.module()->C_SignFinal(m_key.session().handle(), signature);
108 m_initialized =
false;
112 size_t signature_length()
const override {
return 2 * m_order_bytes; }
114 AlgorithmIdentifier algorithm_identifier()
const override;
116 std::string hash_function()
const override {
return m_hash; }
119 const PKCS11_ECDSA_PrivateKey m_key;
120 const size_t m_order_bytes;
121 MechanismWrapper m_mechanism;
122 const std::string m_hash;
123 secure_vector<uint8_t> m_first_message;
124 bool m_initialized =
false;
125 bool m_has_first_message =
false;
128AlgorithmIdentifier PKCS11_ECDSA_Signature_Operation::algorithm_identifier()
const {
129 const std::string full_name =
"ECDSA/" + hash_function();
134class PKCS11_ECDSA_Verification_Operation final :
public PK_Ops::Verification {
136 PKCS11_ECDSA_Verification_Operation(
const PKCS11_ECDSA_PublicKey& key, std::string_view hash) :
137 PK_Ops::Verification(),
139 m_mechanism(MechanismWrapper::create_ecdsa_mechanism(hash)),
140 m_hash(canonical_ecdsa_hash(hash)) {}
142 void update(std::span<const uint8_t> input)
override {
145 m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
146 m_initialized =
true;
147 m_first_message.assign(input.begin(), input.end());
148 m_has_first_message =
true;
152 if(m_has_first_message) {
154 m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
155 m_first_message.clear();
156 m_has_first_message =
false;
159 m_key.module()->C_VerifyUpdate(m_key.session().handle(), input.data(),
checked_ulong_cast(input.size()));
162 bool is_valid_signature(std::span<const uint8_t> sig)
override {
165 m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
166 m_initialized =
true;
167 m_has_first_message =
true;
169 ReturnValue return_value = ReturnValue::SignatureInvalid;
170 if(m_has_first_message) {
172 m_key.module()->C_Verify(m_key.session().handle(),
173 m_first_message.data(),
178 m_first_message.clear();
179 m_has_first_message =
false;
182 m_key.module()->C_VerifyFinal(
185 m_initialized =
false;
186 if(return_value == ReturnValue::SignatureInvalid || return_value == ReturnValue::SignatureLenRange) {
188 }
else if(return_value == ReturnValue::OK) {
191 throw PKCS11_ReturnError(return_value);
195 std::string hash_function()
const override {
return m_hash; }
198 const PKCS11_ECDSA_PublicKey m_key;
199 MechanismWrapper m_mechanism;
200 const std::string m_hash;
201 secure_vector<uint8_t> m_first_message;
202 bool m_initialized =
false;
203 bool m_has_first_message =
false;
208std::unique_ptr<PK_Ops::Verification> PKCS11_ECDSA_PublicKey::create_verification_op(
209 std::string_view params, std::string_view )
const {
210 return std::make_unique<PKCS11_ECDSA_Verification_Operation>(*
this, params);
213std::unique_ptr<PK_Ops::Signature> PKCS11_ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& ,
214 std::string_view params,
215 std::string_view )
const {
216 return std::make_unique<PKCS11_ECDSA_Signature_Operation>(*
this, params);
219PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(
Session& session,
220 const EC_PublicKeyGenerationProperties& pub_props,
221 const EC_PrivateKeyGenerationProperties& priv_props) {
227 session.module()->C_GenerateKeyPair(session.handle(),
236 return std::make_pair(PKCS11_ECDSA_PublicKey(session, pub_key_handle),
237 PKCS11_ECDSA_PrivateKey(session, priv_key_handle));
static BigInt from_bytes(std::span< const uint8_t > bytes)
static OID from_string(std::string_view str)
Represents a PKCS#11 session.
bool signature_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, std::string_view padding)
Ulong checked_ulong_cast(size_t v)
CK_OBJECT_HANDLE ObjectHandle
std::vector< T, secure_allocator< T > > secure_vector
CK_ULONG CK_MECHANISM_TYPE