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
13namespace Botan {
14
15/*
16* EME1 Pad Operation
17*/
18SecureVector<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*/
47SecureVector<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*/
114size_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*/
125EME1::EME1(HashFunction* hash, const std::string& P)
126 {
127 Phash = hash->process(P);
128 mgf = new MGF1(hash);
129 }
130
131}
SecureVector< byte > process(const byte in[], size_t length)
Definition buf_comp.h:101
size_t maximum_input_size(size_t) const
Definition eme1.cpp:114
EME1(HashFunction *hash, const std::string &P="")
Definition eme1.cpp:125
MGF1(HashFunction *hash)
Definition mgf1.cpp:42
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
bool same_mem(const T *p1, const T *p2, size_t n)
Definition mem_ops.h:57
Decoding_Error(const std::string &name)
Definition exceptn.h:140