Botan: src/pk_pad/eme1/eme1.cpp Source File

Botan 1.10.17

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 }
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:57
Botan::EME1::EME1
EME1(HashFunction *hash, const std::string &P="")
Definition: eme1.cpp:125
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::MGF::mask
virtual void mask(const byte in[], size_t in_len, byte out[], size_t out_len) const =0
Botan::Buffered_Computation::process
SecureVector< byte > process(const byte in[], size_t length)
Definition: buf_comp.h:101
Botan
Definition: algo_base.h:14
Botan::HashFunction
Definition: hash.h:20
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::EME1::maximum_input_size
size_t maximum_input_size(size_t) const
Definition: eme1.cpp:114
Botan::MGF1
Definition: mgf1.h:19