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