Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

chacha20poly1305.cpp
Go to the documentation of this file.
1 /*
2 * ChaCha20Poly1305 AEAD
3 * (C) 2014,2016 Jack Lloyd
4 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/chacha20poly1305.h>
10
11 namespace Botan {
12
13 ChaCha20Poly1305_Mode::ChaCha20Poly1305_Mode() :
14 m_chacha(StreamCipher::create("ChaCha")),
15 m_poly1305(MessageAuthenticationCode::create("Poly1305"))
16 {
17 if(!m_chacha || !m_poly1305)
18 throw Algorithm_Not_Found("ChaCha20Poly1305");
19 }
20
21 bool ChaCha20Poly1305_Mode::valid_nonce_length(size_t n) const
22 {
23 return (n == 8 || n == 12);
24 }
25
26 void ChaCha20Poly1305_Mode::clear()
27 {
28 m_chacha->clear();
29 m_poly1305->clear();
30 reset();
31 }
32
33 void ChaCha20Poly1305_Mode::reset()
34 {
35 m_ad.clear();
36 m_ctext_len = 0;
37 m_nonce_len = 0;
38 }
39
40 void ChaCha20Poly1305_Mode::key_schedule(const uint8_t key[], size_t length)
41 {
42 m_chacha->set_key(key, length);
43 }
44
45 void ChaCha20Poly1305_Mode::set_associated_data(const uint8_t ad[], size_t length)
46 {
47 if(m_ctext_len)
48 throw Exception("Too late to set AD for ChaCha20Poly1305");
49 m_ad.assign(ad, ad + length);
50 }
51
52 void ChaCha20Poly1305_Mode::update_len(size_t len)
53 {
54 uint8_t len8[8] = { 0 };
55 store_le(static_cast<uint64_t>(len), len8);
56 m_poly1305->update(len8, 8);
57 }
58
59 void ChaCha20Poly1305_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
60 {
61 if(!valid_nonce_length(nonce_len))
62 throw Invalid_IV_Length(name(), nonce_len);
63
64 m_ctext_len = 0;
65 m_nonce_len = nonce_len;
66
67 m_chacha->set_iv(nonce, nonce_len);
68
69 secure_vector<uint8_t> init(64); // zeros
70 m_chacha->encrypt(init);
71
72 m_poly1305->set_key(init.data(), 32);
73 // Remainder of output is discard
74
75 m_poly1305->update(m_ad);
76
77 if(cfrg_version())
78 {
79 if(m_ad.size() % 16)
80 {
81 const uint8_t zeros[16] = { 0 };
82 m_poly1305->update(zeros, 16 - m_ad.size() % 16);
83 }
84 }
85 else
86 {
87 update_len(m_ad.size());
88 }
89 }
90
91 size_t ChaCha20Poly1305_Encryption::process(uint8_t buf[], size_t sz)
92 {
93 m_chacha->cipher1(buf, sz);
94 m_poly1305->update(buf, sz); // poly1305 of ciphertext
95 m_ctext_len += sz;
96 return sz;
97 }
98
99 void ChaCha20Poly1305_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
100 {
101 update(buffer, offset);
102 if(cfrg_version())
103 {
104 if(m_ctext_len % 16)
105 {
106 const uint8_t zeros[16] = { 0 };
107 m_poly1305->update(zeros, 16 - m_ctext_len % 16);
108 }
109 update_len(m_ad.size());
110 }
111 update_len(m_ctext_len);
112
113 const secure_vector<uint8_t> mac = m_poly1305->final();
114 buffer += std::make_pair(mac.data(), tag_size());
115 m_ctext_len = 0;
116 }
117
118 size_t ChaCha20Poly1305_Decryption::process(uint8_t buf[], size_t sz)
119 {
120 m_poly1305->update(buf, sz); // poly1305 of ciphertext
121 m_chacha->cipher1(buf, sz);
122 m_ctext_len += sz;
123 return sz;
124 }
125
126 void ChaCha20Poly1305_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
127 {
128 BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
129 const size_t sz = buffer.size() - offset;
130 uint8_t* buf = buffer.data() + offset;
131
132 BOTAN_ASSERT(sz >= tag_size(), "Have the tag as part of final input");
133
134 const size_t remaining = sz - tag_size();
135
136 if(remaining)
137 {
138 m_poly1305->update(buf, remaining); // poly1305 of ciphertext
139 m_chacha->cipher1(buf, remaining);
140 m_ctext_len += remaining;
141 }
142
143 if(cfrg_version())
144 {
145 if(m_ctext_len % 16)
146 {
147 const uint8_t zeros[16] = { 0 };
148 m_poly1305->update(zeros, 16 - m_ctext_len % 16);
149 }
150 update_len(m_ad.size());
151 }
152
153 update_len(m_ctext_len);
154 const secure_vector<uint8_t> mac = m_poly1305->final();
155
156 const uint8_t* included_tag = &buf[remaining];
157
158 m_ctext_len = 0;
159
160 if(!same_mem(mac.data(), included_tag, tag_size()))
161 throw Integrity_Failure("ChaCha20Poly1305 tag check failed");
162 buffer.resize(offset + remaining);
163 }
164
165 }
Botan::ChaCha20Poly1305_Encryption::process
size_t process(uint8_t buf[], size_t size) override
Definition: chacha20poly1305.cpp:91
Botan::Exception
Definition: exceptn.h:21
Botan::ChaCha20Poly1305_Encryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: chacha20poly1305.cpp:99
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:98
Botan::ChaCha20Poly1305_Decryption::process
size_t process(uint8_t buf[], size_t size) override
Definition: chacha20poly1305.cpp:118
Botan::ChaCha20Poly1305_Mode::m_poly1305
std::unique_ptr< MessageAuthenticationCode > m_poly1305
Definition: chacha20poly1305.h:46
Botan::ChaCha20Poly1305_Decryption::finish
void finish(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition: chacha20poly1305.cpp:126
Botan::Integrity_Failure
Definition: exceptn.h:198
Botan::Cipher_Mode::update
void update(secure_vector< uint8_t > &buffer, size_t offset=0)
Definition: cipher_mode.h:81
Botan::ChaCha20Poly1305_Mode::m_chacha
std::unique_ptr< StreamCipher > m_chacha
Definition: chacha20poly1305.h:45
Botan::MessageAuthenticationCode
Definition: mac.h:20
Botan::Invalid_IV_Length
Definition: exceptn.h:109
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:27
Botan::ChaCha20Poly1305_Mode::clear
void clear() override
Definition: chacha20poly1305.cpp:26
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::StreamCipher
Definition: stream_cipher.h:19
Botan::ChaCha20Poly1305_Mode::reset
void reset() override
Definition: chacha20poly1305.cpp:33
Botan::ChaCha20Poly1305_Mode::tag_size
size_t tag_size() const override
Definition: chacha20poly1305.h:38
Botan::ChaCha20Poly1305_Mode::m_ad
secure_vector< uint8_t > m_ad
Definition: chacha20poly1305.h:50
Botan
Definition: alg_id.cpp:13
Botan::ChaCha20Poly1305_Mode::cfrg_version
bool cfrg_version() const
Definition: chacha20poly1305.h:54
Botan::ChaCha20Poly1305_Mode::set_associated_data
void set_associated_data(const uint8_t ad[], size_t ad_len) override
Definition: chacha20poly1305.cpp:45
Botan::ChaCha20Poly1305_Mode::m_nonce_len
size_t m_nonce_len
Definition: chacha20poly1305.h:51
Botan::ChaCha20Poly1305_Mode::update_len
void update_len(size_t len)
Definition: chacha20poly1305.cpp:52
Botan::ChaCha20Poly1305_Mode::valid_nonce_length
bool valid_nonce_length(size_t n) const override
Definition: chacha20poly1305.cpp:21
Botan::ChaCha20Poly1305_Mode::m_ctext_len
size_t m_ctext_len
Definition: chacha20poly1305.h:52
Botan::ChaCha20Poly1305_Mode::name
std::string name() const override
Definition: chacha20poly1305.h:29
Botan::Algorithm_Not_Found
Definition: exceptn.h:140
Botan::store_le
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:457
Botan::ChaCha20Poly1305_Mode::ChaCha20Poly1305_Mode
ChaCha20Poly1305_Mode()
Definition: chacha20poly1305.cpp:13