Botan  2.10.0
Crypto and TLS for C++11
pubkey.cpp
Go to the documentation of this file.
1 /*
2 * (C) 1999-2010,2015,2018 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/pubkey.h>
8 #include <botan/der_enc.h>
9 #include <botan/ber_dec.h>
10 #include <botan/bigint.h>
11 #include <botan/pk_ops.h>
12 #include <botan/internal/ct_utils.h>
13 #include <botan/rng.h>
14 
15 namespace Botan {
16 
17 secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const
18  {
19  uint8_t valid_mask = 0;
20 
21  secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
22 
23  if(valid_mask == 0)
24  throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
25 
26  return decoded;
27  }
28 
29 secure_vector<uint8_t>
30 PK_Decryptor::decrypt_or_random(const uint8_t in[],
31  size_t length,
32  size_t expected_pt_len,
33  RandomNumberGenerator& rng,
34  const uint8_t required_content_bytes[],
35  const uint8_t required_content_offsets[],
36  size_t required_contents_length) const
37  {
38  const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len);
39 
40  uint8_t decrypt_valid = 0;
41  secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
42 
43  auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
44  valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len));
45 
46  decoded.resize(expected_pt_len);
47 
48  for(size_t i = 0; i != required_contents_length; ++i)
49  {
50  /*
51  These values are chosen by the application and for TLS are constants,
52  so this early failure via assert is fine since we know 0,1 < 48
53 
54  If there is a protocol that has content checks on the key where
55  the expected offsets are controllable by the attacker this could
56  still leak.
57 
58  Alternately could always reduce the offset modulo the length?
59  */
60 
61  const uint8_t exp = required_content_bytes[i];
62  const uint8_t off = required_content_offsets[i];
63 
64  BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
65 
66  auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
67 
68  valid_mask &= eq;
69  }
70 
71  // If valid_mask is false, assign fake pre master instead
72  valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
73 
74  return decoded;
75  }
76 
77 secure_vector<uint8_t>
78 PK_Decryptor::decrypt_or_random(const uint8_t in[],
79  size_t length,
80  size_t expected_pt_len,
81  RandomNumberGenerator& rng) const
82  {
83  return decrypt_or_random(in, length, expected_pt_len, rng,
84  nullptr, nullptr, 0);
85  }
86 
87 PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
88  RandomNumberGenerator& rng,
89  const std::string& padding,
90  const std::string& provider)
91  {
92  m_op = key.create_encryption_op(rng, padding, provider);
93  if(!m_op)
94  throw Invalid_Argument("Key type " + key.algo_name() + " does not support encryption");
95  }
96 
97 PK_Encryptor_EME::~PK_Encryptor_EME() { /* for unique_ptr */ }
98 
99 size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const
100  {
101  return m_op->ciphertext_length(ptext_len);
102  }
103 
104 std::vector<uint8_t>
105 PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const
106  {
107  return unlock(m_op->encrypt(in, length, rng));
108  }
109 
110 size_t PK_Encryptor_EME::maximum_input_size() const
111  {
112  return m_op->max_input_bits() / 8;
113  }
114 
115 PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
116  RandomNumberGenerator& rng,
117  const std::string& padding,
118  const std::string& provider)
119  {
120  m_op = key.create_decryption_op(rng, padding, provider);
121  if(!m_op)
122  throw Invalid_Argument("Key type " + key.algo_name() + " does not support decryption");
123  }
124 
125 PK_Decryptor_EME::~PK_Decryptor_EME() { /* for unique_ptr */ }
126 
127 size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const
128  {
129  return m_op->plaintext_length(ctext_len);
130  }
131 
132 secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask,
133  const uint8_t in[], size_t in_len) const
134  {
135  return m_op->decrypt(valid_mask, in, in_len);
136  }
137 
138 PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key,
139  RandomNumberGenerator& rng,
140  const std::string& param,
141  const std::string& provider)
142  {
143  m_op = key.create_kem_encryption_op(rng, param, provider);
144  if(!m_op)
145  throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM encryption");
146  }
147 
148 PK_KEM_Encryptor::~PK_KEM_Encryptor() { /* for unique_ptr */ }
149 
150 void PK_KEM_Encryptor::encrypt(secure_vector<uint8_t>& out_encapsulated_key,
151  secure_vector<uint8_t>& out_shared_key,
152  size_t desired_shared_key_len,
153  Botan::RandomNumberGenerator& rng,
154  const uint8_t salt[],
155  size_t salt_len)
156  {
157  m_op->kem_encrypt(out_encapsulated_key,
158  out_shared_key,
159  desired_shared_key_len,
160  rng,
161  salt,
162  salt_len);
163  }
164 
165 PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
166  RandomNumberGenerator& rng,
167  const std::string& param,
168  const std::string& provider)
169  {
170  m_op = key.create_kem_decryption_op(rng, param, provider);
171  if(!m_op)
172  throw Invalid_Argument("Key type " + key.algo_name() + " does not support KEM decryption");
173  }
174 
175 PK_KEM_Decryptor::~PK_KEM_Decryptor() { /* for unique_ptr */ }
176 
177 secure_vector<uint8_t> PK_KEM_Decryptor::decrypt(const uint8_t encap_key[],
178  size_t encap_key_len,
179  size_t desired_shared_key_len,
180  const uint8_t salt[],
181  size_t salt_len)
182  {
183  return m_op->kem_decrypt(encap_key, encap_key_len,
184  desired_shared_key_len,
185  salt, salt_len);
186  }
187 
188 PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
189  RandomNumberGenerator& rng,
190  const std::string& kdf,
191  const std::string& provider)
192  {
193  m_op = key.create_key_agreement_op(rng, kdf, provider);
194  if(!m_op)
195  throw Invalid_Argument("Key type " + key.algo_name() + " does not support key agreement");
196  }
197 
198 PK_Key_Agreement::~PK_Key_Agreement() { /* for unique_ptr */ }
199 
200 PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&& other)
201  {
202  if(this != &other)
203  {
204  m_op = std::move(other.m_op);
205  }
206  return (*this);
207  }
208 
209 PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) :
210  m_op(std::move(other.m_op))
211  {}
212 
213 size_t PK_Key_Agreement::agreed_value_size() const
214  {
215  return m_op->agreed_value_size();
216  }
217 
218 SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
219  const uint8_t in[], size_t in_len,
220  const uint8_t salt[],
221  size_t salt_len) const
222  {
223  return m_op->agree(key_len, in, in_len, salt, salt_len);
224  }
225 
226 PK_Signer::PK_Signer(const Private_Key& key,
227  RandomNumberGenerator& rng,
228  const std::string& emsa,
229  Signature_Format format,
230  const std::string& provider)
231  {
232  m_op = key.create_signature_op(rng, emsa, provider);
233  if(!m_op)
234  throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature generation");
235  m_sig_format = format;
236  m_parts = key.message_parts();
237  m_part_size = key.message_part_size();
238  }
239 
240 PK_Signer::~PK_Signer() { /* for unique_ptr */ }
241 
242 void PK_Signer::update(const uint8_t in[], size_t length)
243  {
244  m_op->update(in, length);
245  }
246 
247 namespace {
248 
249 std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig,
250  size_t parts,
251  size_t part_size)
252  {
253  if(sig.size() % parts != 0 || sig.size() != parts * part_size)
254  throw Encoding_Error("Unexpected size for DER signature");
255 
256  std::vector<BigInt> sig_parts(parts);
257  for(size_t i = 0; i != sig_parts.size(); ++i)
258  sig_parts[i].binary_decode(&sig[part_size*i], part_size);
259 
260  std::vector<uint8_t> output;
261  DER_Encoder(output)
262  .start_cons(SEQUENCE)
263  .encode_list(sig_parts)
264  .end_cons();
265  return output;
266  }
267 
268 }
269 
270 size_t PK_Signer::signature_length() const
271  {
272  if(m_sig_format == IEEE_1363)
273  {
274  return m_op->signature_length();
275  }
276  else if(m_sig_format == DER_SEQUENCE)
277  {
278  // This is a large over-estimate but its easier than computing
279  // the exact value
280  return m_op->signature_length() + (8 + 4*m_parts);
281  }
282  else
283  throw Internal_Error("PK_Signer: Invalid signature format enum");
284  }
285 
286 std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng)
287  {
288  const std::vector<uint8_t> sig = unlock(m_op->sign(rng));
289 
290  if(m_sig_format == IEEE_1363)
291  {
292  return sig;
293  }
294  else if(m_sig_format == DER_SEQUENCE)
295  {
296  return der_encode_signature(sig, m_parts, m_part_size);
297  }
298  else
299  throw Internal_Error("PK_Signer: Invalid signature format enum");
300  }
301 
302 PK_Verifier::PK_Verifier(const Public_Key& key,
303  const std::string& emsa,
304  Signature_Format format,
305  const std::string& provider)
306  {
307  m_op = key.create_verification_op(emsa, provider);
308  if(!m_op)
309  throw Invalid_Argument("Key type " + key.algo_name() + " does not support signature verification");
310  m_sig_format = format;
311  m_parts = key.message_parts();
312  m_part_size = key.message_part_size();
313  }
314 
315 PK_Verifier::~PK_Verifier() { /* for unique_ptr */ }
316 
317 void PK_Verifier::set_input_format(Signature_Format format)
318  {
319  if(format != IEEE_1363 && m_parts == 1)
320  throw Invalid_Argument("PK_Verifier: This algorithm does not support DER encoding");
321  m_sig_format = format;
322  }
323 
324 bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length,
325  const uint8_t sig[], size_t sig_length)
326  {
327  update(msg, msg_length);
328  return check_signature(sig, sig_length);
329  }
330 
331 void PK_Verifier::update(const uint8_t in[], size_t length)
332  {
333  m_op->update(in, length);
334  }
335 
336 bool PK_Verifier::check_signature(const uint8_t sig[], size_t length)
337  {
338  try {
339  if(m_sig_format == IEEE_1363)
340  {
341  return m_op->is_valid_signature(sig, length);
342  }
343  else if(m_sig_format == DER_SEQUENCE)
344  {
345  std::vector<uint8_t> real_sig;
346  BER_Decoder decoder(sig, length);
347  BER_Decoder ber_sig = decoder.start_cons(SEQUENCE);
348 
349  BOTAN_ASSERT_NOMSG(m_parts != 0 && m_part_size != 0);
350 
351  size_t count = 0;
352 
353  while(ber_sig.more_items())
354  {
355  BigInt sig_part;
356  ber_sig.decode(sig_part);
357  real_sig += BigInt::encode_1363(sig_part, m_part_size);
358  ++count;
359  }
360 
361  if(count != m_parts)
362  throw Decoding_Error("PK_Verifier: signature size invalid");
363 
364  const std::vector<uint8_t> reencoded =
365  der_encode_signature(real_sig, m_parts, m_part_size);
366 
367  if(reencoded.size() != length ||
368  same_mem(reencoded.data(), sig, reencoded.size()) == false)
369  {
370  throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
371  }
372 
373  return m_op->is_valid_signature(real_sig.data(), real_sig.size());
374  }
375  else
376  throw Internal_Error("PK_Verifier: Invalid signature format enum");
377  }
378  catch(Invalid_Argument&) { return false; }
379  }
380 
381 }
bool RandomNumberGenerator & rng
Definition: numthry.h:176
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:186
botan_pubkey_t const char * padding
Definition: ffi.h:1311
Signature_Format
Definition: pubkey.h:28
Definition: bigint.h:1136
void const uint8_t in[]
Definition: mgf1.h:26
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68
const uint8_t sig[]
Definition: ffi.h:1382
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
Definition: cryptobox.cpp:162
Definition: alg_id.cpp:13
OctetString SymmetricKey
Definition: symkey.h:141
const uint8_t * key
Definition: ffi.h:359
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:72
int(* update)(CTX *, const void *, CC_LONG len)
uint8_t size_t const std::string const uint8_t salt[]
Definition: pbkdf2.h:19
void BlockCipher const uint8_t size_t uint8_t output[]
Definition: package.h:29
void const uint8_t size_t in_len
Definition: mgf1.h:26
botan_rng_t const char * param
Definition: ffi.h:944
static Mask< T > is_zero(T x)
Definition: ct_utils.h:141
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:149
size_t size_t * ctext_len
Definition: ffi.h:1318
size_t ptext_len
Definition: ffi.h:1318
std::string encrypt(const uint8_t input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)
Definition: cryptobox.cpp:43
const uint8_t size_t key_len
Definition: ffi.h:359
uint8_t size_t const std::string const uint8_t size_t salt_len
Definition: pbkdf2.h:19