Botan  2.4.0
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 #include <botan/exceptn.h>
10 #include <botan/oids.h>
11 #include <botan/pk_keys.h>
12 #include <botan/internal/padding.h>
13 
14 namespace Botan {
15 
16 namespace {
17 
18 secure_vector<uint8_t> emsa1_encoding(const secure_vector<uint8_t>& msg,
19  size_t output_bits)
20  {
21  if(8*msg.size() <= output_bits)
22  return msg;
23 
24  size_t shift = 8*msg.size() - output_bits;
25 
26  size_t byte_shift = shift / 8, bit_shift = shift % 8;
27  secure_vector<uint8_t> digest(msg.size() - byte_shift);
28 
29  for(size_t j = 0; j != msg.size() - byte_shift; ++j)
30  digest[j] = msg[j];
31 
32  if(bit_shift)
33  {
34  uint8_t carry = 0;
35  for(size_t j = 0; j != digest.size(); ++j)
36  {
37  uint8_t temp = digest[j];
38  digest[j] = (temp >> bit_shift) | carry;
39  carry = (temp << (8 - bit_shift));
40  }
41  }
42  return digest;
43  }
44 
45 }
46 
47 std::string EMSA1::name() const
48  {
49  return "EMSA1(" + m_hash->name() + ")";
50  }
51 
53  {
54  return new EMSA1(m_hash->clone());
55  }
56 
57 void EMSA1::update(const uint8_t input[], size_t length)
58  {
59  m_hash->update(input, length);
60  }
61 
62 secure_vector<uint8_t> EMSA1::raw_data()
63  {
64  return m_hash->final();
65  }
66 
67 secure_vector<uint8_t> EMSA1::encoding_of(const secure_vector<uint8_t>& msg,
68  size_t output_bits,
70  {
71  if(msg.size() != hash_output_length())
72  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
73  return emsa1_encoding(msg, output_bits);
74  }
75 
76 bool EMSA1::verify(const secure_vector<uint8_t>& input,
77  const secure_vector<uint8_t>& raw,
78  size_t key_bits)
79  {
80  try {
81  if(raw.size() != m_hash->output_length())
82  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
83 
84  // Call emsa1_encoding to handle any required bit shifting
85  const secure_vector<uint8_t> our_coding = emsa1_encoding(raw, key_bits);
86 
87  if(our_coding.size() < input.size())
88  return false;
89 
90  const size_t offset = our_coding.size() - input.size(); // must be >= 0 per check above
91 
92  // If our encoding is longer, all the bytes in it must be zero
93  for(size_t i = 0; i != offset; ++i)
94  if(our_coding[i] != 0)
95  return false;
96 
97  return constant_time_compare(input.data(), &our_coding[offset], input.size());
98  }
99  catch(Invalid_Argument)
100  {
101  return false;
102  }
103  }
104 
106  const std::string& cert_hash_name) const
107  {
108  if(cert_hash_name != m_hash->name())
109  throw Invalid_Argument("Hash function from opts and hash_fn argument"
110  " need to be identical");
111  // check that the signature algorithm and the padding scheme fit
112  if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA1"))
113  {
114  throw Invalid_Argument("Encoding scheme with canonical name EMSA1"
115  " not supported for signature algorithm " + key.algo_name());
116  }
117 
118  AlgorithmIdentifier sig_algo;
119  sig_algo.oid = OIDS::lookup( key.algo_name() + "/" + name() );
120 
121  std::string algo_name = key.algo_name();
122  if(algo_name == "DSA" ||
123  algo_name == "ECDSA" ||
124  algo_name == "ECGDSA" ||
125  algo_name == "ECKCDSA" ||
126  algo_name == "GOST-34.10")
127  {
128  // for DSA, ECDSA, GOST parameters "SHALL" be empty
129  sig_algo.parameters = {};
130  }
131  else
132  {
133  sig_algo.parameters = key.algorithm_identifier().parameters;
134  }
135 
136  return sig_algo;
137  }
138 
139 }
AlgorithmIdentifier config_for_x509(const Private_Key &key, const std::string &cert_hash_name) const override
Definition: emsa1.cpp:105
EMSA1(HashFunction *hash)
Definition: emsa1.h:26
std::vector< uint8_t > parameters
Definition: alg_id.h:45
virtual AlgorithmIdentifier algorithm_identifier() const =0
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.cpp:44
virtual std::string algo_name() const =0
bool sig_algo_and_pad_ok(const std::string algo, const std::string padding)
Definition: padding.cpp:37
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
std::string name() const override
Definition: emsa1.cpp:47
std::string lookup(const OID &oid)
Definition: oids.cpp:18
EMSA * clone() override
Definition: emsa1.cpp:52