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>
20ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key()
const {
21 return ECDSA_PublicKey(domain(), _public_ec_point());
24bool PKCS11_ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng,
bool strong)
const {
29 ECDSA_PublicKey pubkey(domain(), public_ec_point());
33ECDSA_PrivateKey PKCS11_ECDSA_PrivateKey::export_key()
const {
41 return export_key().private_key_bits();
44std::unique_ptr<Public_Key> PKCS11_ECDSA_PrivateKey::public_key()
const {
45 return std::make_unique<ECDSA_PublicKey>(domain(), public_ec_point());
50class PKCS11_ECDSA_Signature_Operation
final :
public PK_Ops::Signature {
52 PKCS11_ECDSA_Signature_Operation(
const PKCS11_ECDSA_PrivateKey& key, std::string_view hash) :
55 m_order_bytes(key.domain().get_order_bytes()),
56 m_mechanism(MechanismWrapper::create_ecdsa_mechanism(hash)),
59 void update(std::span<const uint8_t> input)
override {
62 m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
64 m_first_message.assign(input.begin(), input.end());
68 if(!m_first_message.empty()) {
70 m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
71 m_first_message.clear();
74 m_key.module()->C_SignUpdate(m_key.session().handle(), input.data(),
static_cast<Ulong>(input.size()));
77 std::vector<uint8_t> sign(RandomNumberGenerator& )
override {
78 std::vector<uint8_t> signature;
79 if(!m_first_message.empty()) {
81 m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
82 m_first_message.clear();
85 m_key.module()->C_SignFinal(m_key.session().handle(), signature);
87 m_initialized =
false;
91 size_t signature_length()
const override {
return 2 * m_order_bytes; }
93 AlgorithmIdentifier algorithm_identifier()
const override;
95 std::string hash_function()
const override {
return m_hash; }
98 const PKCS11_ECDSA_PrivateKey m_key;
99 const size_t m_order_bytes;
100 MechanismWrapper m_mechanism;
101 const std::string m_hash;
102 secure_vector<uint8_t> m_first_message;
103 bool m_initialized =
false;
106AlgorithmIdentifier PKCS11_ECDSA_Signature_Operation::algorithm_identifier()
const {
107 const std::string full_name =
"ECDSA/" + hash_function();
112class PKCS11_ECDSA_Verification_Operation
final :
public PK_Ops::Verification {
114 PKCS11_ECDSA_Verification_Operation(
const PKCS11_ECDSA_PublicKey& key, std::string_view hash) :
115 PK_Ops::Verification(),
117 m_mechanism(MechanismWrapper::create_ecdsa_mechanism(hash)),
120 void update(std::span<const uint8_t> input)
override {
123 m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
124 m_initialized =
true;
125 m_first_message.assign(input.begin(), input.end());
129 if(!m_first_message.empty()) {
131 m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
132 m_first_message.clear();
135 m_key.module()->C_VerifyUpdate(m_key.session().handle(), input.data(),
static_cast<Ulong>(input.size()));
138 bool is_valid_signature(std::span<const uint8_t> sig)
override {
139 ReturnValue return_value = ReturnValue::SignatureInvalid;
140 if(!m_first_message.empty()) {
142 m_key.module()->C_Verify(m_key.session().handle(),
143 m_first_message.data(),
144 static_cast<Ulong>(m_first_message.size()),
146 static_cast<Ulong>(sig.size()),
148 m_first_message.clear();
151 m_key.module()->C_VerifyFinal(
152 m_key.session().handle(), sig.data(),
static_cast<Ulong>(sig.size()), &return_value);
154 m_initialized =
false;
155 if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid) {
156 throw PKCS11_ReturnError(return_value);
158 return return_value == ReturnValue::OK;
161 std::string hash_function()
const override {
return m_hash; }
164 const PKCS11_ECDSA_PublicKey m_key;
165 MechanismWrapper m_mechanism;
166 const std::string m_hash;
167 secure_vector<uint8_t> m_first_message;
168 bool m_initialized =
false;
173std::unique_ptr<PK_Ops::Verification> PKCS11_ECDSA_PublicKey::create_verification_op(
174 std::string_view params, std::string_view )
const {
175 return std::make_unique<PKCS11_ECDSA_Verification_Operation>(*
this, params);
178std::unique_ptr<PK_Ops::Signature> PKCS11_ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& ,
179 std::string_view params,
180 std::string_view )
const {
181 return std::make_unique<PKCS11_ECDSA_Signature_Operation>(*
this, params);
184PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(Session& session,
185 const EC_PublicKeyGenerationProperties& pub_props,
186 const EC_PrivateKeyGenerationProperties& priv_props) {
192 session.module()->C_GenerateKeyPair(session.handle(),
195 static_cast<Ulong>(pub_props.count()),
197 static_cast<Ulong>(priv_props.count()),
201 return std::make_pair(PKCS11_ECDSA_PublicKey(session, pub_key_handle),
202 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)
int(* update)(CTX *, const void *, CC_LONG len)
int(* final)(unsigned char *, CTX *)
bool signature_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, std::string_view padding)
CK_OBJECT_HANDLE ObjectHandle
std::vector< T, secure_allocator< T > > secure_vector
CK_ULONG CK_MECHANISM_TYPE