Botan  1.10.9
emsa1.cpp
Go to the documentation of this file.
1 /*
2 * EMSA1
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/emsa1.h>
9 
10 namespace Botan {
11 
12 namespace {
13 
14 SecureVector<byte> emsa1_encoding(const MemoryRegion<byte>& msg,
15  size_t output_bits)
16  {
17  if(8*msg.size() <= output_bits)
18  return msg;
19 
20  size_t shift = 8*msg.size() - output_bits;
21 
22  size_t byte_shift = shift / 8, bit_shift = shift % 8;
23  SecureVector<byte> digest(msg.size() - byte_shift);
24 
25  for(size_t j = 0; j != msg.size() - byte_shift; ++j)
26  digest[j] = msg[j];
27 
28  if(bit_shift)
29  {
30  byte carry = 0;
31  for(size_t j = 0; j != digest.size(); ++j)
32  {
33  byte temp = digest[j];
34  digest[j] = (temp >> bit_shift) | carry;
35  carry = (temp << (8 - bit_shift));
36  }
37  }
38  return digest;
39  }
40 
41 }
42 
43 /*
44 * EMSA1 Update Operation
45 */
46 void EMSA1::update(const byte input[], size_t length)
47  {
48  hash->update(input, length);
49  }
50 
51 /*
52 * Return the raw (unencoded) data
53 */
54 SecureVector<byte> EMSA1::raw_data()
55  {
56  return hash->final();
57  }
58 
59 /*
60 * EMSA1 Encode Operation
61 */
62 SecureVector<byte> EMSA1::encoding_of(const MemoryRegion<byte>& msg,
63  size_t output_bits,
64  RandomNumberGenerator&)
65  {
66  if(msg.size() != hash->output_length())
67  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
68  return emsa1_encoding(msg, output_bits);
69  }
70 
71 /*
72 * EMSA1 Decode/Verify Operation
73 */
74 bool EMSA1::verify(const MemoryRegion<byte>& coded,
75  const MemoryRegion<byte>& raw, size_t key_bits)
76  {
77  try {
78  if(raw.size() != hash->output_length())
79  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
80 
81  SecureVector<byte> our_coding = emsa1_encoding(raw, key_bits);
82 
83  if(our_coding == coded) return true;
84  if(our_coding[0] != 0) return false;
85  if(our_coding.size() <= coded.size()) return false;
86 
87  size_t offset = 0;
88  while(our_coding[offset] == 0 && offset < our_coding.size())
89  ++offset;
90  if(our_coding.size() - offset != coded.size())
91  return false;
92 
93  for(size_t j = 0; j != coded.size(); ++j)
94  if(coded[j] != our_coding[j+offset])
95  return false;
96 
97  return true;
98  }
99  catch(Invalid_Argument)
100  {
101  return false;
102  }
103  }
104 
105 }
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
unsigned char byte
Definition: types.h:22
void update(const byte in[], size_t length)
Definition: buf_comp.h:33
void final(byte out[])
Definition: buf_comp.h:80
virtual size_t output_length() const =0