Botan 3.8.1
Crypto and TLS for C&
emsa_x931.cpp
Go to the documentation of this file.
1/*
2* EMSA_X931
3* (C) 1999-2007 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/emsa_x931.h>
9
10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/fmt.h>
13#include <botan/internal/hash_id.h>
14#include <botan/internal/stl_util.h>
15
16namespace Botan {
17
18namespace {
19
20std::vector<uint8_t> emsa2_encoding(std::span<const uint8_t> msg,
21 size_t output_bits,
22 std::span<const uint8_t> empty_hash,
23 uint8_t hash_id) {
24 const size_t HASH_SIZE = empty_hash.size();
25
26 const size_t output_length = (output_bits + 1) / 8;
27
28 if(msg.size() != HASH_SIZE) {
29 throw Encoding_Error("EMSA_X931::encoding_of: Bad input length");
30 }
31 if(output_length < HASH_SIZE + 4) {
32 throw Encoding_Error("EMSA_X931::encoding_of: Output length is too small");
33 }
34
35 const bool empty_input = constant_time_compare(msg, empty_hash);
36
37 std::vector<uint8_t> output(output_length);
38 BufferStuffer stuffer(output);
39
40 stuffer.append(empty_input ? 0x4B : 0x6B);
41 stuffer.append(0xBB, stuffer.remaining_capacity() - (1 + msg.size() + 2));
42 stuffer.append(0xBA);
43 stuffer.append(msg);
44 stuffer.append(hash_id);
45 stuffer.append(0xCC);
46 BOTAN_ASSERT_NOMSG(stuffer.full());
47
48 return output;
49}
50
51} // namespace
52
53std::string EMSA_X931::name() const {
54 return fmt("X9.31({})", m_hash->name());
55}
56
57void EMSA_X931::update(const uint8_t input[], size_t length) {
58 m_hash->update(input, length);
59}
60
61std::vector<uint8_t> EMSA_X931::raw_data() {
62 return m_hash->final_stdvec();
63}
64
65/*
66* EMSA_X931 Encode Operation
67*/
68std::vector<uint8_t> EMSA_X931::encoding_of(std::span<const uint8_t> msg,
69 size_t output_bits,
70 RandomNumberGenerator& /*rng*/) {
71 return emsa2_encoding(msg, output_bits, m_empty_hash, m_hash_id);
72}
73
74/*
75* EMSA_X931 Verify Operation
76*/
77bool EMSA_X931::verify(std::span<const uint8_t> coded, std::span<const uint8_t> raw, size_t key_bits) {
78 try {
79 const auto emsa2 = emsa2_encoding(raw, key_bits, m_empty_hash, m_hash_id);
80 return constant_time_compare(coded, emsa2);
81 } catch(...) {
82 return false;
83 }
84}
85
86/*
87* EMSA_X931 Constructor
88*/
89EMSA_X931::EMSA_X931(std::unique_ptr<HashFunction> hash) : m_hash(std::move(hash)) {
90 m_empty_hash = m_hash->final_stdvec();
91
92 m_hash_id = ieee1363_hash_id(m_hash->name());
93
94 if(!m_hash_id) {
95 throw Encoding_Error("EMSA_X931 no hash identifier for " + m_hash->name());
96 }
97}
98
99} // 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
EMSA_X931(std::unique_ptr< HashFunction > hash)
Definition emsa_x931.cpp:89
std::string name() const override
Definition emsa_x931.cpp:53
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
uint8_t ieee1363_hash_id(std::string_view name)
Definition hash_id.cpp:144
bool constant_time_compare(std::span< const uint8_t > x, std::span< const uint8_t > y)
Definition mem_ops.cpp:17