Coverage Report

Created: 2021-02-21 07:20

/src/botan/src/lib/pubkey/ed25519/ed25519_key.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Ed25519
3
* (C) 2017 Ribose Inc
4
*
5
* Based on the public domain code from SUPERCOP ref10 by
6
* Peter Schwabe, Daniel J. Bernstein, Niels Duif, Tanja Lange, Bo-Yin Yang
7
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*/
10
11
#include <botan/ed25519.h>
12
#include <botan/internal/pk_ops_impl.h>
13
#include <botan/hash.h>
14
#include <botan/ber_dec.h>
15
#include <botan/der_enc.h>
16
#include <botan/rng.h>
17
18
namespace Botan {
19
20
AlgorithmIdentifier Ed25519_PublicKey::algorithm_identifier() const
21
0
   {
22
0
   return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);
23
0
   }
24
25
bool Ed25519_PublicKey::check_key(RandomNumberGenerator&, bool) const
26
0
   {
27
0
   return true; // no tests possible?
28
   // TODO could check cofactor
29
0
   }
30
31
Ed25519_PublicKey::Ed25519_PublicKey(const uint8_t pub_key[], size_t pub_len)
32
0
   {
33
0
   if(pub_len != 32)
34
0
      throw Decoding_Error("Invalid length for Ed25519 key");
35
0
   m_public.assign(pub_key, pub_key + pub_len);
36
0
   }
Unexecuted instantiation: Botan::Ed25519_PublicKey::Ed25519_PublicKey(unsigned char const*, unsigned long)
Unexecuted instantiation: Botan::Ed25519_PublicKey::Ed25519_PublicKey(unsigned char const*, unsigned long)
37
38
Ed25519_PublicKey::Ed25519_PublicKey(const AlgorithmIdentifier&,
39
                                     const std::vector<uint8_t>& key_bits)
40
206
   {
41
206
   m_public = key_bits;
42
43
206
   if(m_public.size() != 32)
44
4
      throw Decoding_Error("Invalid size for Ed25519 public key");
45
206
   }
Unexecuted instantiation: Botan::Ed25519_PublicKey::Ed25519_PublicKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Botan::Ed25519_PublicKey::Ed25519_PublicKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Line
Count
Source
40
206
   {
41
206
   m_public = key_bits;
42
43
206
   if(m_public.size() != 32)
44
4
      throw Decoding_Error("Invalid size for Ed25519 public key");
45
206
   }
46
47
std::vector<uint8_t> Ed25519_PublicKey::public_key_bits() const
48
0
   {
49
0
   return m_public;
50
0
   }
51
52
Ed25519_PrivateKey::Ed25519_PrivateKey(const secure_vector<uint8_t>& secret_key)
53
0
   {
54
0
   if(secret_key.size() == 64)
55
0
      {
56
0
      m_private = secret_key;
57
0
      m_public.assign(m_private.begin() + 32, m_private.end());
58
0
      }
59
0
   else if(secret_key.size() == 32)
60
0
      {
61
0
      m_public.resize(32);
62
0
      m_private.resize(64);
63
0
      ed25519_gen_keypair(m_public.data(), m_private.data(), secret_key.data());
64
0
      }
65
0
   else
66
0
      throw Decoding_Error("Invalid size for Ed25519 private key");
67
0
   }
Unexecuted instantiation: Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Unexecuted instantiation: Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
68
69
Ed25519_PrivateKey::Ed25519_PrivateKey(RandomNumberGenerator& rng)
70
0
   {
71
0
   const secure_vector<uint8_t> seed = rng.random_vec(32);
72
0
   m_public.resize(32);
73
0
   m_private.resize(64);
74
0
   ed25519_gen_keypair(m_public.data(), m_private.data(), seed.data());
75
0
   }
Unexecuted instantiation: Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(Botan::RandomNumberGenerator&)
Unexecuted instantiation: Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(Botan::RandomNumberGenerator&)
76
77
Ed25519_PrivateKey::Ed25519_PrivateKey(const AlgorithmIdentifier&,
78
                                       const secure_vector<uint8_t>& key_bits)
79
17
   {
80
17
   secure_vector<uint8_t> bits;
81
17
   BER_Decoder(key_bits).decode(bits, ASN1_Type::OctetString).discard_remaining();
82
83
17
   if(bits.size() != 32)
84
13
      throw Decoding_Error("Invalid size for Ed25519 private key");
85
4
   m_public.resize(32);
86
4
   m_private.resize(64);
87
4
   ed25519_gen_keypair(m_public.data(), m_private.data(), bits.data());
88
4
   }
Unexecuted instantiation: Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Botan::Ed25519_PrivateKey::Ed25519_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Line
Count
Source
79
17
   {
80
17
   secure_vector<uint8_t> bits;
81
17
   BER_Decoder(key_bits).decode(bits, ASN1_Type::OctetString).discard_remaining();
82
83
17
   if(bits.size() != 32)
84
13
      throw Decoding_Error("Invalid size for Ed25519 private key");
85
4
   m_public.resize(32);
86
4
   m_private.resize(64);
87
4
   ed25519_gen_keypair(m_public.data(), m_private.data(), bits.data());
88
4
   }
89
90
std::unique_ptr<Public_Key> Ed25519_PrivateKey::public_key() const
91
0
   {
92
0
   return std::unique_ptr<Public_Key>(new Ed25519_PublicKey(get_public_key()));
93
0
   }
94
95
secure_vector<uint8_t> Ed25519_PrivateKey::private_key_bits() const
96
0
   {
97
0
   secure_vector<uint8_t> bits(&m_private[0], &m_private[32]);
98
0
   return DER_Encoder().encode(bits, ASN1_Type::OctetString).get_contents();
99
0
   }
100
101
bool Ed25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
102
0
   {
103
0
   return true; // ???
104
0
   }
105
106
namespace {
107
108
/**
109
* Ed25519 verifying operation
110
*/
111
class Ed25519_Pure_Verify_Operation final : public PK_Ops::Verification
112
   {
113
   public:
114
      Ed25519_Pure_Verify_Operation(const Ed25519_PublicKey& key) : m_key(key)
115
95
         {
116
95
         }
117
118
      void update(const uint8_t msg[], size_t msg_len) override
119
95
         {
120
95
         m_msg.insert(m_msg.end(), msg, msg + msg_len);
121
95
         }
122
123
      bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
124
95
         {
125
95
         if(sig_len != 64)
126
1
            return false;
127
128
94
         const std::vector<uint8_t>& pub_key = m_key.get_public_key();
129
94
         BOTAN_ASSERT_EQUAL(pub_key.size(), 32, "Expected size");
130
94
         const bool ok = ed25519_verify(m_msg.data(), m_msg.size(), sig, pub_key.data(), nullptr, 0);
131
94
         m_msg.clear();
132
94
         return ok;
133
94
         }
134
135
   private:
136
      std::vector<uint8_t> m_msg;
137
      const Ed25519_PublicKey& m_key;
138
   };
139
140
/**
141
* Ed25519 verifying operation with pre-hash
142
*/
143
class Ed25519_Hashed_Verify_Operation final : public PK_Ops::Verification
144
   {
145
   public:
146
      Ed25519_Hashed_Verify_Operation(const Ed25519_PublicKey& key, const std::string& hash, bool rfc8032) :
147
         m_key(key)
148
0
         {
149
0
         m_hash = HashFunction::create_or_throw(hash);
150
151
0
         if(rfc8032)
152
0
            {
153
0
            m_domain_sep = {
154
0
               0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
155
0
               0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
156
0
               0x01, 0x00 };
157
0
            }
158
0
         }
159
160
      void update(const uint8_t msg[], size_t msg_len) override
161
0
         {
162
0
         m_hash->update(msg, msg_len);
163
0
         }
164
165
      bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
166
0
         {
167
0
         if(sig_len != 64)
168
0
            return false;
169
0
         std::vector<uint8_t> msg_hash(m_hash->output_length());
170
0
         m_hash->final(msg_hash.data());
171
172
0
         const std::vector<uint8_t>& pub_key = m_key.get_public_key();
173
0
         BOTAN_ASSERT_EQUAL(pub_key.size(), 32, "Expected size");
174
0
         return ed25519_verify(msg_hash.data(), msg_hash.size(), sig, pub_key.data(), m_domain_sep.data(), m_domain_sep.size());
175
0
         }
176
177
   private:
178
      std::unique_ptr<HashFunction> m_hash;
179
      const Ed25519_PublicKey& m_key;
180
      std::vector<uint8_t> m_domain_sep;
181
   };
182
183
/**
184
* Ed25519 signing operation ('pure' - signs message directly)
185
*/
186
class Ed25519_Pure_Sign_Operation final : public PK_Ops::Signature
187
   {
188
   public:
189
      Ed25519_Pure_Sign_Operation(const Ed25519_PrivateKey& key) : m_key(key)
190
0
         {
191
0
         }
192
193
      void update(const uint8_t msg[], size_t msg_len) override
194
0
         {
195
0
         m_msg.insert(m_msg.end(), msg, msg + msg_len);
196
0
         }
197
198
      secure_vector<uint8_t> sign(RandomNumberGenerator&) override
199
0
         {
200
0
         secure_vector<uint8_t> sig(64);
201
0
         ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.get_private_key().data(), nullptr, 0);
202
0
         m_msg.clear();
203
0
         return sig;
204
0
         }
205
206
0
      size_t signature_length() const override { return 64; }
207
208
   private:
209
      std::vector<uint8_t> m_msg;
210
      const Ed25519_PrivateKey& m_key;
211
   };
212
213
/**
214
* Ed25519 signing operation with pre-hash
215
*/
216
class Ed25519_Hashed_Sign_Operation final : public PK_Ops::Signature
217
   {
218
   public:
219
      Ed25519_Hashed_Sign_Operation(const Ed25519_PrivateKey& key, const std::string& hash, bool rfc8032) :
220
         m_key(key)
221
0
         {
222
0
         m_hash = HashFunction::create_or_throw(hash);
223
224
0
         if(rfc8032)
225
0
            {
226
0
            m_domain_sep = std::vector<uint8_t>{
227
0
               0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
228
0
               0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
229
0
               0x01, 0x00 };
230
0
            }
231
0
         }
232
233
0
      size_t signature_length() const override { return 64; }
234
235
      void update(const uint8_t msg[], size_t msg_len) override
236
0
         {
237
0
         m_hash->update(msg, msg_len);
238
0
         }
239
240
      secure_vector<uint8_t> sign(RandomNumberGenerator&) override
241
0
         {
242
0
         secure_vector<uint8_t> sig(64);
243
0
         std::vector<uint8_t> msg_hash(m_hash->output_length());
244
0
         m_hash->final(msg_hash.data());
245
0
         ed25519_sign(sig.data(),
246
0
                      msg_hash.data(), msg_hash.size(),
247
0
                      m_key.get_private_key().data(),
248
0
                      m_domain_sep.data(), m_domain_sep.size());
249
0
         return sig;
250
0
         }
251
252
   private:
253
      std::unique_ptr<HashFunction> m_hash;
254
      const Ed25519_PrivateKey& m_key;
255
      std::vector<uint8_t> m_domain_sep;
256
   };
257
258
}
259
260
std::unique_ptr<PK_Ops::Verification>
261
Ed25519_PublicKey::create_verification_op(const std::string& params,
262
                                          const std::string& provider) const
263
95
   {
264
95
   if(provider == "base" || provider.empty())
265
95
      {
266
95
      if(params == "" || params == "Identity" || params == "Pure")
267
95
         return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Pure_Verify_Operation(*this));
268
0
      else if(params == "Ed25519ph")
269
0
         return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, "SHA-512", true));
270
0
      else
271
0
         return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, params, false));
272
0
      }
273
0
   throw Provider_Not_Found(algo_name(), provider);
274
0
   }
275
276
std::unique_ptr<PK_Ops::Signature>
277
Ed25519_PrivateKey::create_signature_op(RandomNumberGenerator&,
278
                                        const std::string& params,
279
                                        const std::string& provider) const
280
0
   {
281
0
   if(provider == "base" || provider.empty())
282
0
      {
283
0
      if(params == "" || params == "Identity" || params == "Pure")
284
0
         return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Pure_Sign_Operation(*this));
285
0
      else if(params == "Ed25519ph")
286
0
         return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, "SHA-512", true));
287
0
      else
288
0
         return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, params, false));
289
0
      }
290
0
   throw Provider_Not_Found(algo_name(), provider);
291
0
   }
292
293
}