Botan 3.8.1
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
10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/hash_id.h>
13#include <botan/internal/stl_util.h>
14
15namespace Botan {
16
17namespace {
18
19std::vector<uint8_t> pkcs1v15_sig_encoding(std::span<const uint8_t> msg,
20 size_t output_bits,
21 std::span<const uint8_t> hash_id) {
22 const size_t output_length = output_bits / 8;
23
24 if(output_length < hash_id.size() + msg.size() + 2 + 8) {
25 throw Encoding_Error("pkcs1v15_sig_encoding: Output length is too small");
26 }
27
28 std::vector<uint8_t> padded(output_length);
29 BufferStuffer stuffer(padded);
30
31 stuffer.append(0x01);
32 stuffer.append(0xFF, stuffer.remaining_capacity() - (1 + hash_id.size() + msg.size()));
33 stuffer.append(0x00);
34 stuffer.append(hash_id);
35 stuffer.append(msg);
36 BOTAN_ASSERT_NOMSG(stuffer.full());
37
38 return padded;
39}
40
41} // namespace
42
43void EMSA_PKCS1v15::update(const uint8_t input[], size_t length) {
44 m_hash->update(input, length);
45}
46
47std::vector<uint8_t> EMSA_PKCS1v15::raw_data() {
48 return m_hash->final_stdvec();
49}
50
51std::vector<uint8_t> EMSA_PKCS1v15::encoding_of(std::span<const uint8_t> msg,
52 size_t output_bits,
53 RandomNumberGenerator& /*rng*/) {
54 if(msg.size() != m_hash->output_length()) {
55 throw Encoding_Error("EMSA_PKCS1v15::encoding_of: Bad input length");
56 }
57
58 return pkcs1v15_sig_encoding(msg, output_bits, m_hash_id);
59}
60
61bool EMSA_PKCS1v15::verify(std::span<const uint8_t> coded, std::span<const uint8_t> raw, size_t key_bits) {
62 if(raw.size() != m_hash->output_length()) {
63 return false;
64 }
65
66 try {
67 const auto pkcs1 = pkcs1v15_sig_encoding(raw, key_bits, m_hash_id);
68 return constant_time_compare(coded, pkcs1);
69 } catch(...) {
70 return false;
71 }
72}
73
74EMSA_PKCS1v15::EMSA_PKCS1v15(std::unique_ptr<HashFunction> hash) : m_hash(std::move(hash)) {
75 m_hash_id = pkcs_hash_id(m_hash->name());
76}
77
78std::string EMSA_PKCS1v15::name() const {
79 return "PKCS1v15(" + m_hash->name() + ")";
80}
81
82std::string EMSA_PKCS1v15_Raw::name() const {
83 if(m_hash_name.empty()) {
84 return "PKCS1v15(Raw)";
85 } else {
86 return "PKCS1v15(Raw," + m_hash_name + ")";
87 }
88}
89
91 m_hash_output_len = 0;
92 // m_hash_id, m_hash_name left empty
93}
94
95EMSA_PKCS1v15_Raw::EMSA_PKCS1v15_Raw(std::string_view hash_algo) {
96 std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_algo));
97 m_hash_id = pkcs_hash_id(hash_algo);
98 m_hash_name = hash->name();
99 m_hash_output_len = hash->output_length();
100}
101
102void EMSA_PKCS1v15_Raw::update(const uint8_t input[], size_t length) {
103 m_message += std::make_pair(input, length);
104}
105
106std::vector<uint8_t> EMSA_PKCS1v15_Raw::raw_data() {
107 std::vector<uint8_t> ret;
108 std::swap(ret, m_message);
109
110 if(m_hash_output_len > 0 && ret.size() != m_hash_output_len) {
111 throw Encoding_Error("EMSA_PKCS1v15_Raw::encoding_of: Bad input length");
112 }
113
114 return ret;
115}
116
117std::vector<uint8_t> EMSA_PKCS1v15_Raw::encoding_of(std::span<const uint8_t> msg,
118 size_t output_bits,
119 RandomNumberGenerator& /*rng*/) {
120 return pkcs1v15_sig_encoding(msg, output_bits, m_hash_id);
121}
122
123bool EMSA_PKCS1v15_Raw::verify(std::span<const uint8_t> coded, std::span<const uint8_t> raw, size_t key_bits) {
124 if(m_hash_output_len > 0 && raw.size() != m_hash_output_len) {
125 return false;
126 }
127
128 try {
129 const auto pkcs1 = pkcs1v15_sig_encoding(raw, key_bits, m_hash_id);
130 return constant_time_compare(coded, pkcs1);
131 } catch(...) {
132 return false;
133 }
134}
135
136} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:61
Helper class to ease in-place marshalling of concatenated fixed-length values.
Definition stl_util.h:143
void update(const uint8_t[], size_t) override
std::string name() const override
std::vector< uint8_t > raw_data() override
std::vector< uint8_t > encoding_of(std::span< const uint8_t >, size_t, RandomNumberGenerator &rng) override
bool verify(std::span< const uint8_t >, std::span< const uint8_t >, size_t) override
std::string name() const override
std::vector< uint8_t > raw_data() override
EMSA_PKCS1v15(std::unique_ptr< HashFunction > hash)
bool verify(std::span< const uint8_t >, std::span< const uint8_t >, size_t) override
void update(const uint8_t[], size_t) override
std::vector< uint8_t > encoding_of(std::span< const uint8_t >, size_t, RandomNumberGenerator &rng) override
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:298
std::vector< uint8_t > pkcs_hash_id(std::string_view name)
Definition hash_id.cpp:78
bool constant_time_compare(std::span< const uint8_t > x, std::span< const uint8_t > y)
Definition mem_ops.cpp:17