Botan 2.19.5 Crypto and TLS for C&

emsa_pkcs1.cpp
Go to the documentation of this file.
1/*
2* PKCS #1 v1.5 signature padding
3* (C) 1999-2008 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/emsa_pkcs1.h>
9#include <botan/hash_id.h>
10#include <botan/exceptn.h>
11#include <botan/pk_keys.h>
12#include <botan/internal/padding.h>
13
14 namespace Botan {
15
16 namespace {
17
18secure_vector<uint8_t> emsa3_encoding(const secure_vector<uint8_t>& msg,
19 size_t output_bits,
20 const uint8_t hash_id[],
21 size_t hash_id_length)
22 {
23 size_t output_length = output_bits / 8;
24 if(output_length < hash_id_length + msg.size() + 10)
25 throw Encoding_Error("emsa3_encoding: Output length is too small");
26
27 secure_vector<uint8_t> T(output_length);
28 const size_t P_LENGTH = output_length - msg.size() - hash_id_length - 2;
29
30 T[0] = 0x01;
31 set_mem(&T[1], P_LENGTH, 0xFF);
32 T[P_LENGTH+1] = 0x00;
33
34 if(hash_id_length > 0)
35 {
36 BOTAN_ASSERT_NONNULL(hash_id);
37 buffer_insert(T, P_LENGTH+2, hash_id, hash_id_length);
38 }
39
40 buffer_insert(T, output_length-msg.size(), msg.data(), msg.size());
41 return T;
42 }
43
44}
45
46 void EMSA_PKCS1v15::update(const uint8_t input[], size_t length)
47 {
48 m_hash->update(input, length);
49 }
50
51 secure_vector<uint8_t> EMSA_PKCS1v15::raw_data()
52 {
53 return m_hash->final();
54 }
55
56 secure_vector<uint8_t>
57 EMSA_PKCS1v15::encoding_of(const secure_vector<uint8_t>& msg,
58 size_t output_bits,
59 RandomNumberGenerator&)
60 {
61 if(msg.size() != m_hash->output_length())
62 throw Encoding_Error("EMSA_PKCS1v15::encoding_of: Bad input length");
63
64 return emsa3_encoding(msg, output_bits,
65 m_hash_id.data(), m_hash_id.size());
66 }
67
68 bool EMSA_PKCS1v15::verify(const secure_vector<uint8_t>& coded,
69 const secure_vector<uint8_t>& raw,
70 size_t key_bits)
71 {
72 if(raw.size() != m_hash->output_length())
73 return false;
74
75 try
76 {
77 return (coded == emsa3_encoding(raw, key_bits,
78 m_hash_id.data(), m_hash_id.size()));
79 }
80 catch(...)
81 {
82 return false;
83 }
84 }
85
86 AlgorithmIdentifier EMSA_PKCS1v15::config_for_x509(const Private_Key& key,
87 const std::string& cert_hash_name) const
88 {
89 if(cert_hash_name != m_hash->name())
90 throw Invalid_Argument("Hash function from opts and hash_fn argument"
91 " need to be identical");
92 // check that the signature algorithm and the padding scheme fit
93 if(!sig_algo_and_pad_ok(key.algo_name(), "EMSA3"))
94 {
95 throw Invalid_Argument("Encoding scheme with canonical name EMSA3"
96 " not supported for signature algorithm " + key.algo_name());
97 }
98
99 // for RSA PKCSv1.5 parameters "SHALL" be NULL
100
101 const OID oid = OID::from_string(key.algo_name() + "/" + name());
102 return AlgorithmIdentifier(oid, AlgorithmIdentifier::USE_NULL_PARAM);
103 }
104
105 EMSA_PKCS1v15::EMSA_PKCS1v15(HashFunction* hash) : m_hash(hash)
106 {
107 m_hash_id = pkcs_hash_id(m_hash->name());
108 }
109
110 EMSA_PKCS1v15_Raw::EMSA_PKCS1v15_Raw(const std::string& hash_algo)
111 {
112 if(!hash_algo.empty())
113 {
114 m_hash_id = pkcs_hash_id(hash_algo);
115 std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_algo));
116 m_hash_name = hash->name();
117 m_hash_output_len = hash->output_length();
118 }
119 else
120 {
121 m_hash_output_len = 0;
122 }
123 }
124
125 void EMSA_PKCS1v15_Raw::update(const uint8_t input[], size_t length)
126 {
127 m_message += std::make_pair(input, length);
128 }
129
130 secure_vector<uint8_t> EMSA_PKCS1v15_Raw::raw_data()
131 {
132 secure_vector<uint8_t> ret;
133 std::swap(ret, m_message);
134
135 if(m_hash_output_len > 0 && ret.size() != m_hash_output_len)
136 throw Encoding_Error("EMSA_PKCS1v15_Raw::encoding_of: Bad input length");
137
138 return ret;
139 }
140
141 secure_vector<uint8_t>
142 EMSA_PKCS1v15_Raw::encoding_of(const secure_vector<uint8_t>& msg,
143 size_t output_bits,
144 RandomNumberGenerator&)
145 {
146 return emsa3_encoding(msg, output_bits, m_hash_id.data(), m_hash_id.size());
147 }
148
149 bool EMSA_PKCS1v15_Raw::verify(const secure_vector<uint8_t>& coded,
150 const secure_vector<uint8_t>& raw,
151 size_t key_bits)
152 {
153 if(m_hash_output_len > 0 && raw.size() != m_hash_output_len)
154 return false;
155
156 try
157 {
158 return (coded == emsa3_encoding(raw, key_bits, m_hash_id.data(), m_hash_id.size()));
159 }
160 catch(...)
161 {
162 return false;
163 }
164 }
165
166}
BOTAN_ASSERT_NONNULL
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:107
Botan::AlgorithmIdentifier
Definition: asn1_obj.h:430
Botan::AlgorithmIdentifier::USE_NULL_PARAM
@ USE_NULL_PARAM
Definition: asn1_obj.h:432
Botan::EMSA_PKCS1v15_Raw::EMSA_PKCS1v15_Raw
EMSA_PKCS1v15_Raw(const std::string &hash_algo="")
Definition: emsa_pkcs1.cpp:110
Botan::EMSA_PKCS1v15_Raw::update
void update(const uint8_t[], size_t) override
Definition: emsa_pkcs1.cpp:125
Botan::EMSA_PKCS1v15_Raw::verify
bool verify(const secure_vector< uint8_t > &, const secure_vector< uint8_t > &, size_t) override
Definition: emsa_pkcs1.cpp:149
Botan::EMSA_PKCS1v15_Raw::raw_data
secure_vector< uint8_t > raw_data() override
Definition: emsa_pkcs1.cpp:130
Botan::EMSA_PKCS1v15_Raw::encoding_of
secure_vector< uint8_t > encoding_of(const secure_vector< uint8_t > &, size_t, RandomNumberGenerator &rng) override
Definition: emsa_pkcs1.cpp:142
Botan::EMSA_PKCS1v15::name
std::string name() const override
Definition: emsa_pkcs1.h:43
Botan::EMSA_PKCS1v15::config_for_x509
AlgorithmIdentifier config_for_x509(const Private_Key &key, const std::string &cert_hash_name) const override
Definition: emsa_pkcs1.cpp:86
Botan::EMSA_PKCS1v15::EMSA_PKCS1v15
EMSA_PKCS1v15(HashFunction *hash)
Definition: emsa_pkcs1.cpp:105
Botan::EMSA_PKCS1v15::raw_data
secure_vector< uint8_t > raw_data() override
Definition: emsa_pkcs1.cpp:51
Botan::EMSA_PKCS1v15::encoding_of
secure_vector< uint8_t > encoding_of(const secure_vector< uint8_t > &, size_t, RandomNumberGenerator &rng) override
Definition: emsa_pkcs1.cpp:57
Botan::EMSA_PKCS1v15::verify
bool verify(const secure_vector< uint8_t > &, const secure_vector< uint8_t > &, size_t) override
Definition: emsa_pkcs1.cpp:68
Botan::EMSA_PKCS1v15::update
void update(const uint8_t[], size_t) override
Definition: emsa_pkcs1.cpp:46
Botan::Encoding_Error
Definition: exceptn.h:185
Botan::HashFunction
Definition: hash.h:21
Botan::HashFunction::create_or_throw
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:329
Botan::Invalid_Argument
Definition: exceptn.h:137
Botan::OID
Definition: asn1_obj.h:194
Botan::OID::from_string
static OID from_string(const std::string &str)
Definition: asn1_oid.cpp:62
Botan::Private_Key
Definition: pk_keys.h:181
Botan::Public_Key::algo_name
virtual std::string algo_name() const =0
Botan::RandomNumberGenerator
Definition: rng.h:26
T
fe T
Definition: ge.cpp:37
Botan
Definition: alg_id.cpp:13
Botan::set_mem
void set_mem(uint8_t *ptr, size_t n, uint8_t val)
Definition: mem_ops.h:182
Botan::buffer_insert
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: mem_ops.h:228
Botan::pkcs_hash_id
std::vector< uint8_t > pkcs_hash_id(const std::string &name)
Definition: hash_id.cpp:77
Botan::sig_algo_and_pad_ok
bool sig_algo_and_pad_ok(const std::string algo, const std::string padding)
Definition: padding.cpp:39
Botan::secure_vector
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
hash
MechanismType hash
Definition: p11_mechanism.cpp:64
hash_algo
AlgorithmIdentifier hash_algo
Definition: x509_obj.cpp:22