Botan 2.19.2
Crypto and TLS for C&
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
13namespace Botan {
14
15namespace {
16
17secure_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
46std::string EMSA1::name() const
47 {
48 return "EMSA1(" + m_hash->name() + ")";
49 }
50
52 {
53 return new EMSA1(m_hash->clone());
54 }
55
56void EMSA1::update(const uint8_t input[], size_t length)
57 {
58 m_hash->update(input, length);
59 }
60
61secure_vector<uint8_t> EMSA1::raw_data()
62 {
63 return m_hash->final();
64 }
65
66secure_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
75bool 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}
const std::vector< uint8_t > & get_parameters() const
Definition: asn1_obj.h:446
EMSA * clone() override
Definition: emsa1.cpp:51
std::string name() const override
Definition: emsa1.cpp:46
EMSA1(HashFunction *hash)
Definition: emsa1.h:28
AlgorithmIdentifier config_for_x509(const Private_Key &key, const std::string &cert_hash_name) const override
Definition: emsa1.cpp:98
static OID from_string(const std::string &str)
Definition: asn1_oid.cpp:62
virtual AlgorithmIdentifier algorithm_identifier() const =0
virtual std::string algo_name() const =0
Definition: alg_id.cpp:13
void carry(int64_t &h0, int64_t &h1)
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:82
bool sig_algo_and_pad_ok(const std::string algo, const std::string padding)
Definition: padding.cpp:39