Botan  1.10.9
eax_dec.cpp
Go to the documentation of this file.
1 /*
2 * EAX Mode Encryption
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/eax.h>
9 #include <botan/internal/xor_buf.h>
10 #include <botan/parsing.h>
11 #include <algorithm>
12 
13 namespace Botan {
14 
15 /*
16 * EAX_Decryption Constructor
17 */
19  size_t tag_size) :
20  EAX_Base(ciph, tag_size)
21  {
22  queue.resize(2*TAG_SIZE + DEFAULT_BUFFERSIZE);
23  queue_start = queue_end = 0;
24  }
25 
26 /*
27 * EAX_Decryption Constructor
28 */
30  const SymmetricKey& key,
31  const InitializationVector& iv,
32  size_t tag_size) :
33  EAX_Base(ciph, tag_size)
34  {
35  set_key(key);
36  set_iv(iv);
37  queue.resize(2*TAG_SIZE + DEFAULT_BUFFERSIZE);
38  queue_start = queue_end = 0;
39  }
40 
41 /*
42 * Decrypt in EAX mode
43 */
44 void EAX_Decryption::write(const byte input[], size_t length)
45  {
46  while(length)
47  {
48  const size_t copied = std::min<size_t>(length, queue.size() - queue_end);
49 
50  queue.copy(queue_end, input, copied);
51  input += copied;
52  length -= copied;
53  queue_end += copied;
54 
55  while((queue_end - queue_start) > TAG_SIZE)
56  {
57  size_t removed = (queue_end - queue_start) - TAG_SIZE;
58  do_write(&queue[queue_start], removed);
59  queue_start += removed;
60  }
61 
62  if(queue_start + TAG_SIZE == queue_end &&
63  queue_start >= queue.size() / 2)
64  {
65  SecureVector<byte> queue_data(TAG_SIZE);
66  queue_data.copy(&queue[queue_start], TAG_SIZE);
67  queue.copy(&queue_data[0], TAG_SIZE);
68  queue_start = 0;
69  queue_end = TAG_SIZE;
70  }
71  }
72  }
73 
74 /*
75 * Decrypt in EAX mode
76 */
77 void EAX_Decryption::do_write(const byte input[], size_t length)
78  {
79  while(length)
80  {
81  size_t copied = std::min<size_t>(length, ctr_buf.size());
82 
83  /*
84  Process same block with cmac and ctr at the same time to
85  help cache locality.
86  */
87  cmac->update(input, copied);
88  ctr->cipher(input, &ctr_buf[0], copied);
89  send(ctr_buf, copied);
90  input += copied;
91  length -= copied;
92  }
93  }
94 
95 /*
96 * Finish decrypting in EAX mode
97 */
98 void EAX_Decryption::end_msg()
99  {
100  if((queue_end - queue_start) != TAG_SIZE)
101  throw Decoding_Error(name() + ": Message authentication failure");
102 
103  const byte* included_mac = &queue[queue_start];
104 
105  SecureVector<byte> computed_mac = cmac->final();
106 
107  xor_buf(&computed_mac[0], &nonce_mac[0], TAG_SIZE);
108  xor_buf(&computed_mac[0], &header_mac[0], TAG_SIZE);
109 
110  if(!same_mem(included_mac, &computed_mac[0], TAG_SIZE))
111  throw Decoding_Error(name() + ": Message authentication failure");
112 
113  queue_start = queue_end = 0;
114  }
115 
116 }
void set_iv(const InitializationVector &iv)
Definition: eax.cpp:89
std::string name() const
Definition: eax.cpp:106
void resize(size_t n)
Definition: secmem.h:211
StreamCipher * ctr
Definition: eax.h:74
EAX_Decryption(BlockCipher *ciph, size_t tag_size=0)
Definition: eax_dec.cpp:18
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:57
SecureVector< byte > ctr_buf
Definition: eax.h:94
SecureVector< byte > header_mac
Definition: eax.h:89
const size_t TAG_SIZE
Definition: eax.h:64
MessageAuthenticationCode * cmac
Definition: eax.h:79
void copy(const T in[], size_t n)
Definition: secmem.h:120
unsigned char byte
Definition: types.h:22
void send(const byte in[], size_t length)
Definition: filter.cpp:28
void update(const byte in[], size_t length)
Definition: buf_comp.h:33
virtual void cipher(const byte in[], byte out[], size_t len)=0
size_t size() const
Definition: secmem.h:29
void final(byte out[])
Definition: buf_comp.h:80
void set_key(const SymmetricKey &key)
Definition: eax.cpp:64
void xor_buf(byte out[], const byte in[], size_t length)
Definition: xor_buf.h:21
SecureVector< byte > nonce_mac
Definition: eax.h:84