Botan 3.0.0
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/internal/emsa_pkcs1.h>
9#include <botan/internal/hash_id.h>
10#include <botan/exceptn.h>
11
12namespace Botan {
13
14namespace {
15
16std::vector<uint8_t> emsa3_encoding(const std::vector<uint8_t>& msg,
17 size_t output_bits,
18 const uint8_t hash_id[],
19 size_t hash_id_length)
20 {
21 size_t output_length = output_bits / 8;
22 if(output_length < hash_id_length + msg.size() + 10)
23 throw Encoding_Error("emsa3_encoding: Output length is too small");
24
25 std::vector<uint8_t> T(output_length);
26 const size_t P_LENGTH = output_length - msg.size() - hash_id_length - 2;
27
28 T[0] = 0x01;
29 set_mem(&T[1], P_LENGTH, 0xFF);
30 T[P_LENGTH+1] = 0x00;
31
32 if(hash_id_length > 0)
33 {
34 BOTAN_ASSERT_NONNULL(hash_id);
35 buffer_insert(T, P_LENGTH+2, hash_id, hash_id_length);
36 }
37
38 buffer_insert(T, output_length-msg.size(), msg.data(), msg.size());
39 return T;
40 }
41
42}
43
44void EMSA_PKCS1v15::update(const uint8_t input[], size_t length)
45 {
46 m_hash->update(input, length);
47 }
48
49std::vector<uint8_t> EMSA_PKCS1v15::raw_data()
50 {
51 return m_hash->final_stdvec();
52 }
53
54std::vector<uint8_t>
55EMSA_PKCS1v15::encoding_of(const std::vector<uint8_t>& msg,
56 size_t output_bits,
57 RandomNumberGenerator& /*rng*/)
58 {
59 if(msg.size() != m_hash->output_length())
60 throw Encoding_Error("EMSA_PKCS1v15::encoding_of: Bad input length");
61
62 return emsa3_encoding(msg, output_bits,
63 m_hash_id.data(), m_hash_id.size());
64 }
65
66bool EMSA_PKCS1v15::verify(const std::vector<uint8_t>& coded,
67 const std::vector<uint8_t>& raw,
68 size_t key_bits)
69 {
70 if(raw.size() != m_hash->output_length())
71 return false;
72
73 try
74 {
75 return (coded == emsa3_encoding(raw, key_bits,
76 m_hash_id.data(), m_hash_id.size()));
77 }
78 catch(...)
79 {
80 return false;
81 }
82 }
83
84EMSA_PKCS1v15::EMSA_PKCS1v15(std::unique_ptr<HashFunction> hash) :
85 m_hash(std::move(hash))
86 {
87 m_hash_id = pkcs_hash_id(m_hash->name());
88 }
89
91 {
92 m_hash_output_len = 0;
93 // m_hash_id, m_hash_name left empty
94 }
95
96EMSA_PKCS1v15_Raw::EMSA_PKCS1v15_Raw(std::string_view hash_algo)
97 {
98 std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_algo));
99 m_hash_id = pkcs_hash_id(hash_algo);
100 m_hash_name = hash->name();
101 m_hash_output_len = hash->output_length();
102 }
103
104void EMSA_PKCS1v15_Raw::update(const uint8_t input[], size_t length)
105 {
106 m_message += std::make_pair(input, length);
107 }
108
109std::vector<uint8_t> EMSA_PKCS1v15_Raw::raw_data()
110 {
111 std::vector<uint8_t> ret;
112 std::swap(ret, m_message);
113
114 if(m_hash_output_len > 0 && ret.size() != m_hash_output_len)
115 throw Encoding_Error("EMSA_PKCS1v15_Raw::encoding_of: Bad input length");
116
117 return ret;
118 }
119
120std::vector<uint8_t>
121EMSA_PKCS1v15_Raw::encoding_of(const std::vector<uint8_t>& msg,
122 size_t output_bits,
123 RandomNumberGenerator& /*rng*/)
124 {
125 return emsa3_encoding(msg, output_bits, m_hash_id.data(), m_hash_id.size());
126 }
127
128bool EMSA_PKCS1v15_Raw::verify(const std::vector<uint8_t>& coded,
129 const std::vector<uint8_t>& raw,
130 size_t key_bits)
131 {
132 if(m_hash_output_len > 0 && raw.size() != m_hash_output_len)
133 return false;
134
135 try
136 {
137 return (coded == emsa3_encoding(raw, key_bits, m_hash_id.data(), m_hash_id.size()));
138 }
139 catch(...)
140 {
141 return false;
142 }
143 }
144
145}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:106
std::vector< uint8_t > encoding_of(const std::vector< uint8_t > &, size_t, RandomNumberGenerator &rng) override
Definition: emsa_pkcs1.cpp:121
void update(const uint8_t[], size_t) override
Definition: emsa_pkcs1.cpp:104
std::vector< uint8_t > raw_data() override
Definition: emsa_pkcs1.cpp:109
bool verify(const std::vector< uint8_t > &, const std::vector< uint8_t > &, size_t) override
Definition: emsa_pkcs1.cpp:128
std::vector< uint8_t > raw_data() override
Definition: emsa_pkcs1.cpp:49
EMSA_PKCS1v15(std::unique_ptr< HashFunction > hash)
Definition: emsa_pkcs1.cpp:84
bool verify(const std::vector< uint8_t > &, const std::vector< uint8_t > &, size_t) override
Definition: emsa_pkcs1.cpp:66
void update(const uint8_t[], size_t) override
Definition: emsa_pkcs1.cpp:44
std::vector< uint8_t > encoding_of(const std::vector< uint8_t > &, size_t, RandomNumberGenerator &rng) override
Definition: emsa_pkcs1.cpp:55
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition: hash.cpp:320
FE_25519 T
Definition: ge.cpp:36
Definition: alg_id.cpp:12
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: mem_ops.h:221
std::vector< uint8_t > pkcs_hash_id(std::string_view name)
Definition: hash_id.cpp:73
Definition: bigint.h:1092