Botan 1.10.17
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
13namespace 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*/
44void 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*/
77void 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*/
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 update(const byte in[], size_t length)
Definition buf_comp.h:33
void final(byte out[])
Definition buf_comp.h:80
const size_t TAG_SIZE
Definition eax.h:64
SecureVector< byte > ctr_buf
Definition eax.h:94
SecureVector< byte > header_mac
Definition eax.h:89
MessageAuthenticationCode * cmac
Definition eax.h:79
EAX_Base(BlockCipher *cipher, size_t tag_size)
Definition eax.cpp:38
SecureVector< byte > nonce_mac
Definition eax.h:84
void set_iv(const InitializationVector &iv)
Definition eax.cpp:89
StreamCipher * ctr
Definition eax.h:74
void set_key(const SymmetricKey &key)
Definition eax.cpp:64
EAX_Decryption(BlockCipher *ciph, size_t tag_size=0)
Definition eax_dec.cpp:18
void send(const byte in[], size_t length)
Definition filter.cpp:28
virtual void end_msg()
Definition filter.h:44
virtual std::string name() const =0
size_t size() const
Definition secmem.h:29
void copy(const T in[], size_t n)
Definition secmem.h:126
virtual void cipher(const byte in[], byte out[], size_t len)=0
OctetString SymmetricKey
Definition symkey.h:147
void xor_buf(byte out[], const byte in[], size_t length)
Definition xor_buf.h:21
OctetString InitializationVector
Definition symkey.h:152
bool same_mem(const T *p1, const T *p2, size_t n)
Definition mem_ops.h:57
Decoding_Error(const std::string &name)
Definition exceptn.h:140