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