Botan  1.11.34
Crypto and TLS for C++11
emsa1.cpp
Go to the documentation of this file.
1 /*
2 * EMSA1
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/emsa1.h>
9 
10 namespace Botan {
11 
12 namespace {
13 
14 secure_vector<byte> emsa1_encoding(const secure_vector<byte>& msg,
15  size_t output_bits)
16  {
17  if(8*msg.size() <= output_bits)
18  return msg;
19 
20  size_t shift = 8*msg.size() - output_bits;
21 
22  size_t byte_shift = shift / 8, bit_shift = shift % 8;
23  secure_vector<byte> digest(msg.size() - byte_shift);
24 
25  for(size_t j = 0; j != msg.size() - byte_shift; ++j)
26  digest[j] = msg[j];
27 
28  if(bit_shift)
29  {
30  byte carry = 0;
31  for(size_t j = 0; j != digest.size(); ++j)
32  {
33  byte temp = digest[j];
34  digest[j] = (temp >> bit_shift) | carry;
35  carry = (temp << (8 - bit_shift));
36  }
37  }
38  return digest;
39  }
40 
41 }
42 
44  {
45  return new EMSA1(m_hash->clone());
46  }
47 
48 void EMSA1::update(const byte input[], size_t length)
49  {
50  m_hash->update(input, length);
51  }
52 
53 secure_vector<byte> EMSA1::raw_data()
54  {
55  return m_hash->final();
56  }
57 
58 secure_vector<byte> EMSA1::encoding_of(const secure_vector<byte>& msg,
59  size_t output_bits,
61  {
62  if(msg.size() != hash_output_length())
63  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
64  return emsa1_encoding(msg, output_bits);
65  }
66 
67 bool EMSA1::verify(const secure_vector<byte>& input,
68  const secure_vector<byte>& raw,
69  size_t key_bits)
70  {
71  try {
72  if(raw.size() != m_hash->output_length())
73  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
74 
75  // Call emsa1_encoding to handle any required bit shifting
76  const secure_vector<byte> our_coding = emsa1_encoding(raw, key_bits);
77 
78  if(our_coding.size() < input.size())
79  return false;
80 
81  const size_t offset = our_coding.size() - input.size(); // must be >= 0 per check above
82 
83  // If our encoding is longer, all the bytes in it must be zero
84  for(size_t i = 0; i != offset; ++i)
85  if(our_coding[i] != 0)
86  return false;
87 
88  return same_mem(input.data(), &our_coding[offset], input.size());
89  }
90  catch(Invalid_Argument)
91  {
92  return false;
93  }
94  }
95 
96 }
EMSA1(HashFunction *hash)
Definition: emsa1.h:26
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:98
size_t hash_output_length() const
Definition: emsa1.h:31
std::unique_ptr< HashFunction > m_hash
Definition: emsa1.h:33
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:113
Definition: alg_id.cpp:13
EMSA * clone() override
Definition: emsa1.cpp:43
std::uint8_t byte
Definition: types.h:31