Botan  2.13.0
Crypto and TLS for C++11
p11_ecdsa.cpp
Go to the documentation of this file.
1 /*
2 * PKCS#11 ECDSA
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_ecdsa.h>
10 
11 #if defined(BOTAN_HAS_ECDSA)
12 
13 #include <botan/internal/p11_mechanism.h>
14 #include <botan/pk_ops.h>
15 #include <botan/keypair.h>
16 #include <botan/rng.h>
17 
18 namespace Botan {
19 namespace PKCS11 {
20 
21 ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key() const
22  {
23  return ECDSA_PublicKey(domain(), public_point());
24  }
25 
26 bool PKCS11_ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
27  {
28  if(!public_point().on_the_curve())
29  {
30  return false;
31  }
32 
33  if(!strong)
34  {
35  return true;
36  }
37 
38  ECDSA_PublicKey pubkey(domain(), public_point());
39  return KeyPair::signature_consistency_check(rng, *this, pubkey, "EMSA1(SHA-256)");
40  }
41 
42 ECDSA_PrivateKey PKCS11_ECDSA_PrivateKey::export_key() const
43  {
44  auto priv_key = get_attribute_value(AttributeType::Value);
45 
46  Null_RNG rng;
47  return ECDSA_PrivateKey(rng, domain(), BigInt::decode(priv_key));
48  }
49 
50 secure_vector<uint8_t> PKCS11_ECDSA_PrivateKey::private_key_bits() const
51  {
52  return export_key().private_key_bits();
53  }
54 
55 namespace {
56 
57 class PKCS11_ECDSA_Signature_Operation final : public PK_Ops::Signature
58  {
59  public:
60  PKCS11_ECDSA_Signature_Operation(const PKCS11_EC_PrivateKey& key, const std::string& emsa)
61  : PK_Ops::Signature(), m_key(key), m_order(key.domain().get_order()), m_mechanism(MechanismWrapper::create_ecdsa_mechanism(emsa))
62  {}
63 
64  void update(const uint8_t msg[], size_t msg_len) override
65  {
66  if(!m_initialized)
67  {
68  // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
69  m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
70  m_initialized = true;
71  m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
72  return;
73  }
74 
75  if(!m_first_message.empty())
76  {
77  // second call to update: start multiple-part operation
78  m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
79  m_first_message.clear();
80  }
81 
82  m_key.module()->C_SignUpdate(m_key.session().handle(), const_cast<Byte*>(msg), static_cast<Ulong>(msg_len));
83  }
84 
85  secure_vector<uint8_t> sign(RandomNumberGenerator&) override
86  {
87  secure_vector<uint8_t> signature;
88  if(!m_first_message.empty())
89  {
90  // single call to update: perform single-part operation
91  m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
92  m_first_message.clear();
93  }
94  else
95  {
96  // multiple calls to update (or none): finish multiple-part operation
97  m_key.module()->C_SignFinal(m_key.session().handle(), signature);
98  }
99  m_initialized = false;
100  return signature;
101  }
102 
103  size_t signature_length() const override { return 2*m_order.bytes(); }
104 
105  private:
106  const PKCS11_EC_PrivateKey& m_key;
107  const BigInt& m_order;
108  MechanismWrapper m_mechanism;
109  secure_vector<uint8_t> m_first_message;
110  bool m_initialized = false;
111  };
112 
113 
114 class PKCS11_ECDSA_Verification_Operation final : public PK_Ops::Verification
115  {
116  public:
117  PKCS11_ECDSA_Verification_Operation(const PKCS11_EC_PublicKey& key, const std::string& emsa)
118  : PK_Ops::Verification(), m_key(key), m_order(key.domain().get_order()), m_mechanism(MechanismWrapper::create_ecdsa_mechanism(emsa))
119  {}
120 
121  void update(const uint8_t msg[], size_t msg_len) override
122  {
123  if(!m_initialized)
124  {
125  // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
126  m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
127  m_initialized = true;
128  m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
129  return;
130  }
131 
132  if(!m_first_message.empty())
133  {
134  // second call to update: start multiple-part operation
135  m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
136  m_first_message.clear();
137  }
138 
139  m_key.module()->C_VerifyUpdate(m_key.session().handle(), const_cast<Byte*>(msg), static_cast<Ulong>(msg_len));
140  }
141 
142  bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
143  {
145  if(!m_first_message.empty())
146  {
147  // single call to update: perform single-part operation
148  m_key.module()->C_Verify(m_key.session().handle(),
149  m_first_message.data(), static_cast<Ulong>(m_first_message.size()),
150  const_cast<Byte*>(sig), static_cast<Ulong>(sig_len),
151  &return_value);
152  m_first_message.clear();
153  }
154  else
155  {
156  // multiple calls to update (or none): finish multiple-part operation
157  m_key.module()->C_VerifyFinal(m_key.session().handle(), const_cast<Byte*>(sig), static_cast<Ulong>(sig_len), &return_value);
158  }
159  m_initialized = false;
160  if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid)
161  {
162  throw PKCS11_ReturnError(return_value);
163  }
164  return return_value == ReturnValue::OK;
165  }
166 
167  private:
168  const PKCS11_EC_PublicKey& m_key;
169  const BigInt& m_order;
170  MechanismWrapper m_mechanism;
171  secure_vector<uint8_t> m_first_message;
172  bool m_initialized = false;
173  };
174 
175 }
176 
177 std::unique_ptr<PK_Ops::Verification>
178 PKCS11_ECDSA_PublicKey::create_verification_op(const std::string& params,
179  const std::string& /*provider*/) const
180  {
181  return std::unique_ptr<PK_Ops::Verification>(new PKCS11_ECDSA_Verification_Operation(*this, params));
182  }
183 
184 std::unique_ptr<PK_Ops::Signature>
185 PKCS11_ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
186  const std::string& params,
187  const std::string& /*provider*/) const
188  {
189  return std::unique_ptr<PK_Ops::Signature>(new PKCS11_ECDSA_Signature_Operation(*this, params));
190  }
191 
192 PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props,
193  const EC_PrivateKeyGenerationProperties& priv_props)
194  {
195  ObjectHandle pub_key_handle = 0;
196  ObjectHandle priv_key_handle = 0;
197 
198  Mechanism mechanism = { static_cast<CK_MECHANISM_TYPE>(MechanismType::EcKeyPairGen), nullptr, 0 };
199 
200  session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
201  pub_props.data(), static_cast<Ulong>(pub_props.count()),
202  priv_props.data(), static_cast<Ulong>(priv_props.count()),
203  &pub_key_handle, &priv_key_handle);
204 
205  return std::make_pair(PKCS11_ECDSA_PublicKey(session, pub_key_handle), PKCS11_ECDSA_PrivateKey(session,
206  priv_key_handle));
207  }
208 
209 }
210 
211 }
212 
213 #endif
CK_ULONG CK_MECHANISM_TYPE
Definition: pkcs11t.h:583
int(* final)(unsigned char *, CTX *)
CK_ULONG Ulong
Definition: p11.h:836
CK_BYTE Byte
Definition: p11.h:847
bool signature_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, const std::string &padding)
Definition: keypair.cpp:49
Definition: alg_id.cpp:13
CK_OBJECT_HANDLE ObjectHandle
Definition: p11.h:846
int(* update)(CTX *, const void *, CC_LONG len)
static BigInt decode(const uint8_t buf[], size_t length)
Definition: bigint.h:798
CK_MECHANISM Mechanism
Definition: p11.h:839