8 #include <botan/iso9796.h>
9 #include <botan/mgf1.h>
10 #include <botan/internal/bit_ops.h>
11 #include <botan/hash_id.h>
12 #include <botan/internal/ct_utils.h>
18 secure_vector<uint8_t> iso9796_encoding(
const secure_vector<uint8_t>& msg,
19 size_t output_bits, std::unique_ptr<HashFunction>&
hash,
size_t SALT_SIZE,
bool implicit, RandomNumberGenerator& rng)
21 const size_t output_length = (output_bits + 7) / 8;
29 const size_t HASH_SIZE = hash->output_length();
31 if(output_length <= HASH_SIZE + SALT_SIZE + tLength)
33 throw Encoding_Error(
"ISO9796-2::encoding_of: Output length is too small");
37 const size_t capacity = output_length
38 - HASH_SIZE - SALT_SIZE - tLength - 1;
41 secure_vector<uint8_t> msg1;
42 secure_vector<uint8_t> msg2;
43 if(msg.size() > capacity)
45 msg1 = secure_vector<uint8_t> (msg.begin(), msg.begin() + capacity);
46 msg2 = secure_vector<uint8_t> (msg.begin() + capacity, msg.end());
56 uint64_t msgLength = msg1.size();
57 secure_vector<uint8_t> salt = rng.random_vec(SALT_SIZE);
58 hash->update_be(msgLength * 8);
62 secure_vector<uint8_t> H = hash->final();
64 secure_vector<uint8_t> EM(output_length);
67 size_t offset = output_length - HASH_SIZE - SALT_SIZE - tLength
76 mgf1_mask(*hash, H.data(), HASH_SIZE, EM.data(),
77 output_length - HASH_SIZE - tLength);
85 throw Encoding_Error(
"ISO9796-2::encoding_of: no hash identifier for " + hash->name());
87 EM[output_length - 1] = 0xCC;
88 EM[output_length - 2] = hash_id;
93 EM[output_length - 1] = 0xBC;
101 bool iso9796_verification(
const secure_vector<uint8_t>& const_coded,
102 const secure_vector<uint8_t>& raw,
size_t key_bits, std::unique_ptr<HashFunction>& hash,
size_t SALT_SIZE)
104 const size_t HASH_SIZE = hash->output_length();
105 const size_t KEY_BYTES = (key_bits + 7) / 8;
107 if(const_coded.size() != KEY_BYTES)
113 if(const_coded[const_coded.size() - 1] == 0xBC)
120 if((!const_coded[const_coded.size() - 2]) || (const_coded[const_coded.size() - 2] != hash_id) ||
121 (const_coded[const_coded.size() - 1] != 0xCC))
128 secure_vector<uint8_t> coded = const_coded;
132 uint8_t* DB = coded.data();
133 const size_t DB_size = coded.size() - HASH_SIZE - tLength;
135 const uint8_t* H = &coded[DB_size];
137 mgf1_mask(*hash, H, HASH_SIZE, DB, DB_size);
142 size_t msg1_offset = 1;
143 uint8_t waiting_for_delim = 0xFF;
144 uint8_t bad_input = 0;
145 for(
size_t j = 0; j < DB_size; ++j)
147 const uint8_t one_m = CT::is_equal<uint8_t>(DB[j], 0x01);
149 const uint8_t add_m = waiting_for_delim & zero_m;
151 bad_input |= waiting_for_delim & ~(zero_m | one_m);
152 msg1_offset += CT::select<uint8_t>(add_m, 1, 0);
154 waiting_for_delim &= zero_m;
158 bad_input |= waiting_for_delim;
159 bad_input |=
CT::is_less(coded.size(), tLength + HASH_SIZE + msg1_offset + SALT_SIZE);
161 msg1_offset = CT::select<size_t>(bad_input, 0, msg1_offset);
162 secure_vector<uint8_t> msg1(coded.begin() + msg1_offset,
163 coded.end() - tLength - HASH_SIZE - SALT_SIZE);
164 secure_vector<uint8_t> salt(coded.begin() + msg1_offset + msg1.size(),
165 coded.end() - tLength - HASH_SIZE);
168 const size_t capacity = (key_bits - 2 + 7) / 8 - HASH_SIZE
169 - SALT_SIZE - tLength - 1;
170 secure_vector<uint8_t> msg1raw;
171 secure_vector<uint8_t> msg2;
172 if(raw.size() > capacity)
174 msg1raw = secure_vector<uint8_t> (raw.begin(), raw.begin() + capacity);
175 msg2 = secure_vector<uint8_t> (raw.begin() + capacity, raw.end());
182 msg2 = hash->final();
184 uint64_t msg1rawLength = msg1raw.size();
185 hash->update_be(msg1rawLength * 8);
186 hash->update(msg1raw);
189 secure_vector<uint8_t> H3 = hash->final();
192 uint64_t msgLength = msg1.size();
193 hash->update_be(msgLength * 8);
197 secure_vector<uint8_t> H2 = hash->final();
200 bad_input |= CT::is_equal<uint8_t>(
same_mem(H3.data(), H2.data(), HASH_SIZE),
false);
203 return (bad_input == 0);
211 void ISO_9796_DS2::update(
const uint8_t input[],
size_t length)
214 m_msg_buffer.insert(m_msg_buffer.end(), input, input+length);
220 secure_vector<uint8_t> ISO_9796_DS2::raw_data()
222 secure_vector<uint8_t> retbuffer = m_msg_buffer;
223 m_msg_buffer.clear();
230 secure_vector<uint8_t> ISO_9796_DS2::encoding_of(
const secure_vector<uint8_t>& msg,
231 size_t output_bits, RandomNumberGenerator& rng)
233 return iso9796_encoding(msg, output_bits, m_hash, m_SALT_SIZE, m_implicit, rng);
239 bool ISO_9796_DS2::verify(
const secure_vector<uint8_t>& const_coded,
240 const secure_vector<uint8_t>& raw,
size_t key_bits)
242 return iso9796_verification(const_coded,raw,key_bits,m_hash,m_SALT_SIZE);
249 void ISO_9796_DS3::update(
const uint8_t input[],
size_t length)
252 m_msg_buffer.insert(m_msg_buffer.end(), input, input+length);
258 secure_vector<uint8_t> ISO_9796_DS3::raw_data()
260 secure_vector<uint8_t> retbuffer = m_msg_buffer;
261 m_msg_buffer.clear();
268 secure_vector<uint8_t> ISO_9796_DS3::encoding_of(
const secure_vector<uint8_t>& msg,
269 size_t output_bits, RandomNumberGenerator& rng)
271 return iso9796_encoding(msg, output_bits, m_hash, 0, m_implicit, rng);
277 bool ISO_9796_DS3::verify(
const secure_vector<uint8_t>& const_coded,
278 const secure_vector<uint8_t>& raw,
size_t key_bits)
280 return iso9796_verification(const_coded, raw, key_bits, m_hash, 0);
bool same_mem(const T *p1, const T *p2, size_t n)
void poison(const T *p, size_t n)
uint8_t ieee1363_hash_id(const std::string &name)
void mgf1_mask(HashFunction &hash, const uint8_t in[], size_t in_len, uint8_t out[], size_t out_len)
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
void unpoison(const T *p, size_t n)