monotone

monotone Mtn Source Tree

Root/botan/emsa4.cpp

1/*************************************************
2* EMSA4 Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/emsa.h>
7#include <botan/lookup.h>
8#include <botan/look_pk.h>
9#include <botan/bit_ops.h>
10#include <botan/rng.h>
11
12namespace Botan {
13
14/*************************************************
15* EMSA4 Update Operation *
16*************************************************/
17void EMSA4::update(const byte input[], u32bit length)
18 {
19 hash->update(input, length);
20 }
21
22/*************************************************
23* Return the raw (unencoded) data *
24*************************************************/
25SecureVector<byte> EMSA4::raw_data()
26 {
27 return hash->final();
28 }
29
30/*************************************************
31* EMSA4 Encode Operation *
32*************************************************/
33SecureVector<byte> EMSA4::encoding_of(const MemoryRegion<byte>& msg,
34 u32bit output_bits)
35 {
36 const u32bit HASH_SIZE = hash->OUTPUT_LENGTH;
37
38 if(msg.size() != HASH_SIZE)
39 throw Encoding_Error("EMSA4::encoding_of: Bad input length");
40 if(output_bits < 8*HASH_SIZE + 8*SALT_SIZE + 9)
41 throw Encoding_Error("EMSA4::encoding_of: Output length is too small");
42
43 const u32bit output_length = (output_bits + 7) / 8;
44
45 SecureVector<byte> salt(SALT_SIZE);
46 Global_RNG::randomize(salt, SALT_SIZE);
47
48 for(u32bit j = 0; j != 8; ++j)
49 hash->update(0);
50 hash->update(msg);
51 hash->update(salt, SALT_SIZE);
52 SecureVector<byte> H = hash->final();
53
54 SecureVector<byte> EM(output_length);
55
56 EM[output_length - HASH_SIZE - SALT_SIZE - 2] = 0x01;
57 EM.copy(output_length - 1 - HASH_SIZE - SALT_SIZE, salt, SALT_SIZE);
58 mgf->mask(H, HASH_SIZE, EM, output_length - HASH_SIZE - 1);
59 EM[0] &= 0xFF >> (8 * ((output_bits + 7) / 8) - output_bits);
60 EM.copy(output_length - 1 - HASH_SIZE, H, HASH_SIZE);
61 EM[output_length-1] = 0xBC;
62
63 return EM;
64 }
65
66/*************************************************
67* EMSA4 Decode/Verify Operation *
68*************************************************/
69bool EMSA4::verify(const MemoryRegion<byte>& const_coded,
70 const MemoryRegion<byte>& raw, u32bit key_bits) throw()
71 {
72 const u32bit HASH_SIZE = hash->OUTPUT_LENGTH;
73 const u32bit KEY_BYTES = (key_bits + 7) / 8;
74
75 if(key_bits < 8*HASH_SIZE + 9)
76 return false;
77 if(raw.size() != HASH_SIZE)
78 return false;
79 if(const_coded.size() > KEY_BYTES)
80 return false;
81 if(const_coded[const_coded.size()-1] != 0xBC)
82 return false;
83
84 SecureVector<byte> coded = const_coded;
85 if(coded.size() < KEY_BYTES)
86 {
87 SecureVector<byte> temp(KEY_BYTES);
88 temp.copy(KEY_BYTES - coded.size(), coded, coded.size());
89 coded = temp;
90 }
91
92 const u32bit TOP_BITS = 8 * ((key_bits + 7) / 8) - key_bits;
93 if(TOP_BITS > 8 - high_bit(coded[0]))
94 return false;
95
96 SecureVector<byte> DB(coded.begin(), coded.size() - HASH_SIZE - 1);
97 SecureVector<byte> H(coded + coded.size() - HASH_SIZE - 1, HASH_SIZE);
98
99 mgf->mask(H, H.size(), DB, coded.size() - H.size() - 1);
100 DB[0] &= 0xFF >> TOP_BITS;
101
102 u32bit salt_offset = 0;
103 for(u32bit j = 0; j != DB.size(); ++j)
104 {
105 if(DB[j] == 0x01)
106 { salt_offset = j + 1; break; }
107 if(DB[j])
108 return false;
109 }
110 if(salt_offset == 0)
111 return false;
112
113 SecureVector<byte> salt(DB + salt_offset, DB.size() - salt_offset);
114
115 for(u32bit j = 0; j != 8; ++j)
116 hash->update(0);
117 hash->update(raw);
118 hash->update(salt);
119 SecureVector<byte> H2 = hash->final();
120
121 return (H == H2);
122 }
123
124/*************************************************
125* EMSA4 Constructor *
126*************************************************/
127EMSA4::EMSA4(const std::string& hash_name, const std::string& mgf_name) :
128 SALT_SIZE(output_length_of(hash_name))
129 {
130 hash = get_hash(hash_name);
131 mgf = get_mgf(mgf_name + "(" + hash_name + ")");
132 }
133
134/*************************************************
135* EMSA4 Constructor *
136*************************************************/
137EMSA4::EMSA4(const std::string& hash_name, const std::string& mgf_name,
138 u32bit salt_size) : SALT_SIZE(salt_size)
139 {
140 hash = get_hash(hash_name);
141 mgf = get_mgf(mgf_name + "(" + hash_name + ")");
142 }
143
144}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status