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