/src/botan/src/lib/pk_pad/emsa_x931/emsa_x931.cpp
Line | Count | Source (jump to first uncovered line) |
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/internal/hash_id.h> |
12 | | #include <botan/internal/stl_util.h> |
13 | | |
14 | | namespace Botan { |
15 | | |
16 | | namespace { |
17 | | |
18 | | std::vector<uint8_t> emsa2_encoding(const std::vector<uint8_t>& msg, |
19 | | size_t output_bits, |
20 | | const std::vector<uint8_t>& empty_hash, |
21 | 0 | uint8_t hash_id) { |
22 | 0 | const size_t HASH_SIZE = empty_hash.size(); |
23 | |
|
24 | 0 | const size_t output_length = (output_bits + 1) / 8; |
25 | |
|
26 | 0 | if(msg.size() != HASH_SIZE) { |
27 | 0 | throw Encoding_Error("EMSA_X931::encoding_of: Bad input length"); |
28 | 0 | } |
29 | 0 | if(output_length < HASH_SIZE + 4) { |
30 | 0 | throw Encoding_Error("EMSA_X931::encoding_of: Output length is too small"); |
31 | 0 | } |
32 | | |
33 | 0 | const bool empty_input = (msg == empty_hash); |
34 | |
|
35 | 0 | std::vector<uint8_t> output(output_length); |
36 | 0 | BufferStuffer stuffer(output); |
37 | |
|
38 | 0 | stuffer.append(empty_input ? 0x4B : 0x6B); |
39 | 0 | stuffer.append(0xBB, stuffer.remaining_capacity() - (1 + msg.size() + 2)); |
40 | 0 | stuffer.append(0xBA); |
41 | 0 | stuffer.append(msg); |
42 | 0 | stuffer.append(hash_id); |
43 | 0 | stuffer.append(0xCC); |
44 | 0 | BOTAN_ASSERT_NOMSG(stuffer.full()); |
45 | |
|
46 | 0 | return output; |
47 | 0 | } |
48 | | |
49 | | } // namespace |
50 | | |
51 | 0 | std::string EMSA_X931::name() const { |
52 | 0 | return "EMSA2(" + m_hash->name() + ")"; |
53 | 0 | } |
54 | | |
55 | 0 | void EMSA_X931::update(const uint8_t input[], size_t length) { |
56 | 0 | m_hash->update(input, length); |
57 | 0 | } |
58 | | |
59 | 0 | std::vector<uint8_t> EMSA_X931::raw_data() { |
60 | 0 | return m_hash->final_stdvec(); |
61 | 0 | } |
62 | | |
63 | | /* |
64 | | * EMSA_X931 Encode Operation |
65 | | */ |
66 | | std::vector<uint8_t> EMSA_X931::encoding_of(const std::vector<uint8_t>& msg, |
67 | | size_t output_bits, |
68 | 0 | RandomNumberGenerator& /*rng*/) { |
69 | 0 | return emsa2_encoding(msg, output_bits, m_empty_hash, m_hash_id); |
70 | 0 | } |
71 | | |
72 | | /* |
73 | | * EMSA_X931 Verify Operation |
74 | | */ |
75 | 0 | bool EMSA_X931::verify(const std::vector<uint8_t>& coded, const std::vector<uint8_t>& raw, size_t key_bits) { |
76 | 0 | try { |
77 | 0 | return (coded == emsa2_encoding(raw, key_bits, m_empty_hash, m_hash_id)); |
78 | 0 | } catch(...) { |
79 | 0 | return false; |
80 | 0 | } |
81 | 0 | } |
82 | | |
83 | | /* |
84 | | * EMSA_X931 Constructor |
85 | | */ |
86 | 0 | EMSA_X931::EMSA_X931(std::unique_ptr<HashFunction> hash) : m_hash(std::move(hash)) { |
87 | 0 | m_empty_hash = m_hash->final_stdvec(); |
88 | |
|
89 | 0 | m_hash_id = ieee1363_hash_id(m_hash->name()); |
90 | |
|
91 | 0 | if(!m_hash_id) { |
92 | 0 | throw Encoding_Error("EMSA_X931 no hash identifier for " + m_hash->name()); |
93 | 0 | } |
94 | 0 | } |
95 | | |
96 | | } // namespace Botan |