Botan  2.9.0
Crypto and TLS for C++11
eme_pkcs.cpp
Go to the documentation of this file.
1 /*
2 * PKCS #1 v1.5 Type 2 (encryption) padding
3 * (C) 1999-2007,2015,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/eme_pkcs.h>
9 #include <botan/exceptn.h>
10 #include <botan/rng.h>
11 #include <botan/internal/ct_utils.h>
12 
13 namespace Botan {
14 
15 /*
16 * PKCS1 Pad Operation
17 */
18 secure_vector<uint8_t> EME_PKCS1v15::pad(const uint8_t in[], size_t inlen,
19  size_t key_length,
20  RandomNumberGenerator& rng) const
21  {
22  key_length /= 8;
23 
24  if(inlen > maximum_input_size(key_length * 8))
25  {
26  throw Invalid_Argument("PKCS1: Input is too large");
27  }
28 
29  secure_vector<uint8_t> out(key_length);
30 
31  out[0] = 0x02;
32  rng.randomize(out.data() + 1, (key_length - inlen - 2));
33 
34  for(size_t j = 1; j != key_length - inlen - 1; ++j)
35  {
36  if(out[j] == 0)
37  {
38  out[j] = rng.next_nonzero_byte();
39  }
40  }
41 
42  buffer_insert(out, key_length - inlen, in, inlen);
43 
44  return out;
45  }
46 
47 /*
48 * PKCS1 Unpad Operation
49 */
51  const uint8_t in[], size_t inlen) const
52  {
53  /*
54  * RSA decryption pads the ciphertext up to the modulus size, so this only
55  * occurs with very (!) small keys, or when fuzzing.
56  *
57  * 11 bytes == 00,02 + 8 bytes mandatory padding + 00
58  */
59  if(inlen < 11)
60  {
61  valid_mask = false;
62  return secure_vector<uint8_t>();
63  }
64 
65  CT::poison(in, inlen);
66 
69  size_t delim_idx = 2; // initial 0002
70 
71  bad_input_m |= ~CT::Mask<uint8_t>::is_equal(in[0], 0);
72  bad_input_m |= ~CT::Mask<uint8_t>::is_equal(in[1], 2);
73 
74  for(size_t i = 2; i < inlen; ++i)
75  {
76  const auto is_zero_m = CT::Mask<uint8_t>::is_zero(in[i]);
77  delim_idx += seen_zero_m.if_not_set_return(1);
78  seen_zero_m |= is_zero_m;
79  }
80 
81  // no zero delim -> bad padding
82  bad_input_m |= ~seen_zero_m;
83  /*
84  delim indicates < 8 bytes padding -> bad padding
85 
86  We require 11 here because we are counting also the 00 delim byte
87  */
88  bad_input_m |= CT::Mask<uint8_t>(CT::Mask<size_t>::is_lt(delim_idx, 11));
89 
90  valid_mask = (~bad_input_m).unpoisoned_value();
91  const secure_vector<uint8_t> output = CT::copy_output(bad_input_m, in, inlen, delim_idx);
92 
93  CT::unpoison(in, inlen);
94 
95  return output;
96  }
97 
98 /*
99 * Return the max input size for a given key size
100 */
101 size_t EME_PKCS1v15::maximum_input_size(size_t keybits) const
102  {
103  if(keybits / 8 > 10)
104  return ((keybits / 8) - 10);
105  else
106  return 0;
107  }
108 
109 }
static Mask< T > cleared()
Definition: ct_utils.h:115
size_t maximum_input_size(size_t) const override
Definition: eme_pkcs.cpp:101
virtual void randomize(uint8_t output[], size_t length)=0
void poison(const T *p, size_t n)
Definition: ct_utils.h:48
uint8_t next_nonzero_byte()
Definition: rng.h:162
secure_vector< uint8_t > pad(const uint8_t[], size_t, size_t, RandomNumberGenerator &) const override
Definition: eme_pkcs.cpp:18
secure_vector< uint8_t > copy_output(CT::Mask< uint8_t > bad_input, const uint8_t input[], size_t input_length, size_t offset)
Definition: ct_utils.cpp:13
Definition: alg_id.cpp:13
secure_vector< uint8_t > unpad(uint8_t &valid_mask, const uint8_t in[], size_t in_len) const override
Definition: eme_pkcs.cpp:50
T if_not_set_return(T x) const
Definition: ct_utils.h:256
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:80
void unpoison(const T *p, size_t n)
Definition: ct_utils.h:59
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
static Mask< T > is_zero(T x)
Definition: ct_utils.h:141
static Mask< T > is_lt(T x, T y)
Definition: ct_utils.h:157