Botan  2.7.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,
69  RandomNumberGenerator&)
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  if(raw.size() != m_hash->output_length())
81  return false;
82 
83  // Call emsa1_encoding to handle any required bit shifting
84  const secure_vector<uint8_t> our_coding = emsa1_encoding(raw, key_bits);
85 
86  if(our_coding.size() < input.size())
87  return false;
88 
89  const size_t offset = our_coding.size() - input.size(); // must be >= 0 per check above
90 
91  // If our encoding is longer, all the bytes in it must be zero
92  for(size_t i = 0; i != offset; ++i)
93  if(our_coding[i] != 0)
94  return false;
95 
96  return constant_time_compare(input.data(), &our_coding[offset], input.size());
97  }
98 
100  const std::string& cert_hash_name) const
101  {
102  if(cert_hash_name != m_hash->name())
103  throw Invalid_Argument("Hash function from opts and hash_fn argument"
104  " need to be identical");
105  // check that the signature algorithm and the padding scheme fit
106  if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA1"))
107  {
108  throw Invalid_Argument("Encoding scheme with canonical name EMSA1"
109  " not supported for signature algorithm " + key.algo_name());
110  }
111 
112  AlgorithmIdentifier sig_algo;
113  sig_algo.oid = OIDS::lookup( key.algo_name() + "/" + name() );
114 
115  std::string algo_name = key.algo_name();
116  if(algo_name == "DSA" ||
117  algo_name == "ECDSA" ||
118  algo_name == "ECGDSA" ||
119  algo_name == "ECKCDSA" ||
120  algo_name == "GOST-34.10")
121  {
122  // for DSA, ECDSA, GOST parameters "SHALL" be empty
123  sig_algo.parameters = {};
124  }
125  else
126  {
127  sig_algo.parameters = key.algorithm_identifier().parameters;
128  }
129 
130  return sig_algo;
131  }
132 
133 }
AlgorithmIdentifier config_for_x509(const Private_Key &key, const std::string &cert_hash_name) const override
Definition: emsa1.cpp:99
EMSA1(HashFunction *hash)
Definition: emsa1.h:26
void carry(int64_t &h0, int64_t &h1)
std::vector< uint8_t > parameters
Definition: alg_id.h:46
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:51
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::string name() const override
Definition: emsa1.cpp:47
std::string lookup(const OID &oid)
Definition: oids.cpp:113
EMSA * clone() override
Definition: emsa1.cpp:52