• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.23
/src/lib/prov/pkcs11/p11_ecdsa.cpp
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/rng.h>
14
   #include <botan/internal/keypair.h>
15
   #include <botan/internal/p11_mechanism.h>
16
   #include <botan/internal/pk_ops.h>
17

18
namespace Botan::PKCS11 {
19

20
ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key() const {
1✔
21
   return ECDSA_PublicKey(domain(), public_point());
1✔
22
}
23

24
bool PKCS11_ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const {
2✔
25
   if(!public_point().on_the_curve()) {
2✔
26
      return false;
27
   }
28

29
   if(!strong) {
2✔
30
      return true;
31
   }
32

33
   ECDSA_PublicKey pubkey(domain(), public_point());
×
34
   return KeyPair::signature_consistency_check(rng, *this, pubkey, "SHA-256");
×
35
}
2✔
36

37
ECDSA_PrivateKey PKCS11_ECDSA_PrivateKey::export_key() const {
1✔
38
   auto priv_key = get_attribute_value(AttributeType::Value);
1✔
39

40
   Null_RNG rng;
1✔
41
   return ECDSA_PrivateKey(rng, domain(), BigInt::decode(priv_key));
3✔
42
}
2✔
43

44
secure_vector<uint8_t> PKCS11_ECDSA_PrivateKey::private_key_bits() const {
×
45
   return export_key().private_key_bits();
×
46
}
47

48
std::unique_ptr<Public_Key> PKCS11_ECDSA_PrivateKey::public_key() const {
×
49
   return std::make_unique<ECDSA_PublicKey>(domain(), public_point());
×
50
}
51

52
namespace {
53

54
class PKCS11_ECDSA_Signature_Operation final : public PK_Ops::Signature {
×
55
   public:
56
      PKCS11_ECDSA_Signature_Operation(const PKCS11_EC_PrivateKey& key, std::string_view hash) :
4✔
57
            PK_Ops::Signature(),
58
            m_key(key),
4✔
59
            m_order(key.domain().get_order()),
4✔
60
            m_mechanism(MechanismWrapper::create_ecdsa_mechanism(hash)),
4✔
61
            m_hash(hash) {}
12✔
62

63
      void update(const uint8_t msg[], size_t msg_len) override {
4✔
64
         if(!m_initialized) {
4✔
65
            // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
66
            m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
4✔
67
            m_initialized = true;
4✔
68
            m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
4✔
69
            return;
4✔
70
         }
71

72
         if(!m_first_message.empty()) {
×
73
            // second call to update: start multiple-part operation
74
            m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
×
75
            m_first_message.clear();
×
76
         }
77

78
         m_key.module()->C_SignUpdate(m_key.session().handle(), msg, static_cast<Ulong>(msg_len));
×
79
      }
80

81
      secure_vector<uint8_t> sign(RandomNumberGenerator& /*rng*/) override {
4✔
82
         secure_vector<uint8_t> signature;
4✔
83
         if(!m_first_message.empty()) {
4✔
84
            // single call to update: perform single-part operation
85
            m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
4✔
86
            m_first_message.clear();
4✔
87
         } else {
88
            // multiple calls to update (or none): finish multiple-part operation
89
            m_key.module()->C_SignFinal(m_key.session().handle(), signature);
×
90
         }
91
         m_initialized = false;
4✔
92
         return signature;
4✔
93
      }
×
94

95
      size_t signature_length() const override { return 2 * m_order.bytes(); }
×
96

97
      AlgorithmIdentifier algorithm_identifier() const override;
98

99
      std::string hash_function() const override { return m_hash; }
×
100

101
   private:
102
      const PKCS11_EC_PrivateKey& m_key;
103
      const BigInt& m_order;
104
      MechanismWrapper m_mechanism;
105
      const std::string m_hash;
106
      secure_vector<uint8_t> m_first_message;
107
      bool m_initialized = false;
108
};
109

110
AlgorithmIdentifier PKCS11_ECDSA_Signature_Operation::algorithm_identifier() const {
×
111
   const std::string full_name = "ECDSA/" + hash_function();
×
112
   const OID oid = OID::from_string(full_name);
×
113
   return AlgorithmIdentifier(oid, AlgorithmIdentifier::USE_EMPTY_PARAM);
×
114
}
×
115

116
class PKCS11_ECDSA_Verification_Operation final : public PK_Ops::Verification {
×
117
   public:
118
      PKCS11_ECDSA_Verification_Operation(const PKCS11_EC_PublicKey& key, std::string_view hash) :
8✔
119
            PK_Ops::Verification(),
120
            m_key(key),
8✔
121
            m_order(key.domain().get_order()),
8✔
122
            m_mechanism(MechanismWrapper::create_ecdsa_mechanism(hash)),
8✔
123
            m_hash(hash) {}
24✔
124

125
      void update(const uint8_t msg[], size_t msg_len) override {
8✔
126
         if(!m_initialized) {
8✔
127
            // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
128
            m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
8✔
129
            m_initialized = true;
8✔
130
            m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
8✔
131
            return;
8✔
132
         }
133

134
         if(!m_first_message.empty()) {
×
135
            // second call to update: start multiple-part operation
136
            m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
×
137
            m_first_message.clear();
×
138
         }
139

140
         m_key.module()->C_VerifyUpdate(m_key.session().handle(), msg, static_cast<Ulong>(msg_len));
×
141
      }
142

143
      bool is_valid_signature(const uint8_t sig[], size_t sig_len) override {
8✔
144
         ReturnValue return_value = ReturnValue::SignatureInvalid;
8✔
145
         if(!m_first_message.empty()) {
8✔
146
            // single call to update: perform single-part operation
147
            m_key.module()->C_Verify(m_key.session().handle(),
8✔
148
                                     m_first_message.data(),
8✔
149
                                     static_cast<Ulong>(m_first_message.size()),
8✔
150
                                     sig,
151
                                     static_cast<Ulong>(sig_len),
152
                                     &return_value);
153
            m_first_message.clear();
8✔
154
         } else {
155
            // multiple calls to update (or none): finish multiple-part operation
156
            m_key.module()->C_VerifyFinal(m_key.session().handle(), sig, static_cast<Ulong>(sig_len), &return_value);
×
157
         }
158
         m_initialized = false;
8✔
159
         if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid) {
8✔
160
            throw PKCS11_ReturnError(return_value);
×
161
         }
162
         return return_value == ReturnValue::OK;
8✔
163
      }
164

165
      std::string hash_function() const override { return m_hash; }
×
166

167
   private:
168
      const PKCS11_EC_PublicKey& m_key;
169
      const BigInt& m_order;
170
      MechanismWrapper m_mechanism;
171
      const std::string m_hash;
172
      secure_vector<uint8_t> m_first_message;
173
      bool m_initialized = false;
174
};
175

176
}  // namespace
177

178
std::unique_ptr<PK_Ops::Verification> PKCS11_ECDSA_PublicKey::create_verification_op(
8✔
179
   std::string_view params, std::string_view /*provider*/) const {
180
   return std::make_unique<PKCS11_ECDSA_Verification_Operation>(*this, params);
8✔
181
}
182

183
std::unique_ptr<PK_Ops::Signature> PKCS11_ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
4✔
184
                                                                                std::string_view params,
185
                                                                                std::string_view /*provider*/) const {
186
   return std::make_unique<PKCS11_ECDSA_Signature_Operation>(*this, params);
4✔
187
}
188

189
PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(Session& session,
6✔
190
                                            const EC_PublicKeyGenerationProperties& pub_props,
191
                                            const EC_PrivateKeyGenerationProperties& priv_props) {
192
   ObjectHandle pub_key_handle = 0;
6✔
193
   ObjectHandle priv_key_handle = 0;
6✔
194

195
   Mechanism mechanism = {static_cast<CK_MECHANISM_TYPE>(MechanismType::EcKeyPairGen), nullptr, 0};
6✔
196

197
   session.module()->C_GenerateKeyPair(session.handle(),
6✔
198
                                       &mechanism,
199
                                       pub_props.data(),
200
                                       static_cast<Ulong>(pub_props.count()),
6✔
201
                                       priv_props.data(),
202
                                       static_cast<Ulong>(priv_props.count()),
6✔
203
                                       &pub_key_handle,
204
                                       &priv_key_handle);
205

206
   return std::make_pair(PKCS11_ECDSA_PublicKey(session, pub_key_handle),
6✔
207
                         PKCS11_ECDSA_PrivateKey(session, priv_key_handle));
18✔
208
}
209

210
}  // namespace Botan::PKCS11
211

212
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc