Botan  1.10.9
eme1.cpp
Go to the documentation of this file.
1 /*
2 * EME1 (aka OAEP)
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/eme1.h>
9 #include <botan/mgf1.h>
10 #include <botan/mem_ops.h>
11 #include <memory>
12 
13 namespace Botan {
14 
15 /*
16 * EME1 Pad Operation
17 */
18 SecureVector<byte> EME1::pad(const byte in[], size_t in_length,
19  size_t key_length,
20  RandomNumberGenerator& rng) const
21  {
22  key_length /= 8;
23 
24  if(key_length < in_length + 2*Phash.size() + 1)
25  throw Invalid_Argument("EME1: Input is too large");
26 
27  SecureVector<byte> out(key_length);
28 
29  rng.randomize(&out[0], Phash.size());
30 
31  out.copy(Phash.size(), &Phash[0], Phash.size());
32  out[out.size() - in_length - 1] = 0x01;
33  out.copy(out.size() - in_length, in, in_length);
34 
35  mgf->mask(&out[0], Phash.size(),
36  &out[Phash.size()], out.size() - Phash.size());
37 
38  mgf->mask(&out[Phash.size()], out.size() - Phash.size(),
39  &out[0], Phash.size());
40 
41  return out;
42  }
43 
44 /*
45 * EME1 Unpad Operation
46 */
47 SecureVector<byte> EME1::unpad(const byte in[], size_t in_length,
48  size_t key_length) const
49  {
50  /*
51  Must be careful about error messages here; if an attacker can
52  distinguish them, it is easy to use the differences as an oracle to
53  find the secret key, as described in "A Chosen Ciphertext Attack on
54  RSA Optimal Asymmetric Encryption Padding (OAEP) as Standardized in
55  PKCS #1 v2.0", James Manger, Crypto 2001
56 
57  Also have to be careful about timing attacks! Pointed out by Falko
58  Strenzke.
59  */
60 
61  key_length /= 8;
62 
63  // Invalid input: truncate to zero length input, causing later
64  // checks to fail
65  if(in_length > key_length)
66  in_length = 0;
67 
68  SecureVector<byte> input(key_length);
69  input.copy(key_length - in_length, in, in_length);
70 
71  mgf->mask(&input[Phash.size()], input.size() - Phash.size(),
72  &input[0], Phash.size());
73  mgf->mask(&input[0], Phash.size(),
74  &input[Phash.size()], input.size() - Phash.size());
75 
76  bool waiting_for_delim = true;
77  bool bad_input = false;
78  size_t delim_idx = 2 * Phash.size();
79 
80  /*
81  * GCC 4.5 on x86-64 compiles this in a way that is still vunerable
82  * to timing analysis. Other compilers, or GCC on other platforms,
83  * may or may not.
84  */
85  for(size_t i = delim_idx; i < input.size(); ++i)
86  {
87  const bool zero_p = !input[i];
88  const bool one_p = input[i] == 0x01;
89 
90  const bool add_1 = waiting_for_delim && zero_p;
91 
92  bad_input |= waiting_for_delim && !(zero_p || one_p);
93 
94  delim_idx += add_1;
95 
96  waiting_for_delim &= zero_p;
97  }
98 
99  // If we never saw any non-zero byte, then it's not valid input
100  bad_input |= waiting_for_delim;
101 
102  bad_input |= !same_mem(&input[Phash.size()], &Phash[0], Phash.size());
103 
104  if(bad_input)
105  throw Decoding_Error("Invalid EME1 encoding");
106 
107  return SecureVector<byte>(input + delim_idx + 1,
108  input.size() - delim_idx - 1);
109  }
110 
111 /*
112 * Return the max input size for a given key size
113 */
114 size_t EME1::maximum_input_size(size_t keybits) const
115  {
116  if(keybits / 8 > 2*Phash.size() + 1)
117  return ((keybits / 8) - 2*Phash.size() - 1);
118  else
119  return 0;
120  }
121 
122 /*
123 * EME1 Constructor
124 */
125 EME1::EME1(HashFunction* hash, const std::string& P)
126  {
127  Phash = hash->process(P);
128  mgf = new MGF1(hash);
129  }
130 
131 }
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:57
size_t maximum_input_size(size_t) const
Definition: eme1.cpp:114
EME1(HashFunction *hash, const std::string &P="")
Definition: eme1.cpp:125
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
unsigned char byte
Definition: types.h:22
virtual void mask(const byte in[], size_t in_len, byte out[], size_t out_len) const =0
RandomNumberGenerator * rng
Definition: global_rng.cpp:165
SecureVector< byte > process(const byte in[], size_t length)
Definition: buf_comp.h:101
size_t size() const
Definition: secmem.h:29