Botan 3.13.0
Crypto and TLS for C&
aead.cpp
Go to the documentation of this file.
1/*
2* (C) 2013,2015 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/aead.h>
8
9#include <botan/assert.h>
10#include <botan/exceptn.h>
11#include <botan/internal/parsing.h>
12#include <botan/internal/scan_name.h>
13#include <sstream>
14
15#if defined(BOTAN_HAS_BLOCK_CIPHER)
16 #include <botan/block_cipher.h>
17#endif
18
19#if defined(BOTAN_HAS_AEAD_CCM)
20 #include <botan/internal/ccm.h>
21#endif
22
23#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
24 #include <botan/internal/chacha20poly1305.h>
25#endif
26
27#if defined(BOTAN_HAS_AEAD_EAX)
28 #include <botan/internal/eax.h>
29#endif
30
31#if defined(BOTAN_HAS_AEAD_GCM)
32 #include <botan/internal/gcm.h>
33#endif
34
35#if defined(BOTAN_HAS_AEAD_GCM_SIV)
36 #include <botan/internal/gcm_siv.h>
37#endif
38
39#if defined(BOTAN_HAS_AEAD_OCB)
40 #include <botan/internal/ocb.h>
41#endif
42
43#if defined(BOTAN_HAS_AEAD_SIV)
44 #include <botan/internal/siv.h>
45#endif
46
47#if defined(BOTAN_HAS_ASCON_AEAD128)
48 #include <botan/internal/ascon_aead128.h>
49#endif
50
51namespace Botan {
52
53std::unique_ptr<AEAD_Mode> AEAD_Mode::create_or_throw(std::string_view algo,
54 Cipher_Dir dir,
55 std::string_view provider) {
56 if(auto aead = AEAD_Mode::create(algo, dir, provider)) {
57 return aead;
58 }
59
60 throw Lookup_Error("AEAD", algo, provider);
61}
62
63std::unique_ptr<AEAD_Mode> AEAD_Mode::create(std::string_view algo, Cipher_Dir dir, std::string_view provider) {
65#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
66 if(algo == "ChaCha20Poly1305") {
67 if(dir == Cipher_Dir::Encryption) {
68 return std::make_unique<ChaCha20Poly1305_Encryption>();
69 } else {
70 return std::make_unique<ChaCha20Poly1305_Decryption>();
71 }
72 }
73#endif
74
75#if defined(BOTAN_HAS_ASCON_AEAD128)
76 if(algo == "Ascon-AEAD128") {
77 if(dir == Cipher_Dir::Encryption) {
78 return std::make_unique<Ascon_AEAD128_Encryption>();
79 } else {
80 return std::make_unique<Ascon_AEAD128_Decryption>();
81 }
82 }
83#endif
84
85 if(algo.find('/') != std::string::npos) {
86 const std::vector<std::string> algo_parts = split_on(algo, '/');
87 if(algo_parts.size() < 2) {
88 return std::unique_ptr<AEAD_Mode>();
89 }
90 const std::string_view cipher_name = algo_parts[0];
91 const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
92
93 if(mode_info.empty()) {
94 return std::unique_ptr<AEAD_Mode>();
95 }
96
97 std::ostringstream mode_name;
98
99 mode_name << mode_info[0] << '(' << cipher_name;
100 for(size_t i = 1; i < mode_info.size(); ++i) {
101 mode_name << ',' << mode_info[i];
102 }
103 for(size_t i = 2; i < algo_parts.size(); ++i) {
104 mode_name << ',' << algo_parts[i];
105 }
106 mode_name << ')';
107
108 return AEAD_Mode::create(mode_name.str(), dir);
109 }
110
111#if defined(BOTAN_HAS_BLOCK_CIPHER)
112
113 const SCAN_Name req(algo);
114
115 if(req.arg_count() == 0) {
116 return std::unique_ptr<AEAD_Mode>();
117 }
118
119 auto bc = BlockCipher::create(req.arg(0), provider);
120
121 if(!bc) {
122 return std::unique_ptr<AEAD_Mode>();
123 }
124
125 #if defined(BOTAN_HAS_AEAD_CCM)
126 if(req.algo_name() == "CCM") {
127 const size_t tag_len = req.arg_as_integer(1, 16);
128 const size_t L_len = req.arg_as_integer(2, 3);
129 if(dir == Cipher_Dir::Encryption) {
130 return std::make_unique<CCM_Encryption>(std::move(bc), tag_len, L_len);
131 } else {
132 return std::make_unique<CCM_Decryption>(std::move(bc), tag_len, L_len);
133 }
134 }
135 #endif
136
137 #if defined(BOTAN_HAS_AEAD_GCM)
138 if(req.algo_name() == "GCM") {
139 const size_t tag_len = req.arg_as_integer(1, 16);
140 if(dir == Cipher_Dir::Encryption) {
141 return std::make_unique<GCM_Encryption>(std::move(bc), tag_len);
142 } else {
143 return std::make_unique<GCM_Decryption>(std::move(bc), tag_len);
144 }
145 }
146 #endif
147
148 #if defined(BOTAN_HAS_AEAD_GCM_SIV)
149 if(req.algo_name() == "GCM-SIV") {
150 // Unlike GCM the tag length is fixed, so reject eg "AES-128/GCM-SIV(12)"
151 if(req.arg_count() != 1) {
152 return std::unique_ptr<AEAD_Mode>();
153 }
154 if(dir == Cipher_Dir::Encryption) {
155 return std::make_unique<GCM_SIV_Encryption>(std::move(bc));
156 } else {
157 return std::make_unique<GCM_SIV_Decryption>(std::move(bc));
158 }
159 }
160 #endif
161
162 #if defined(BOTAN_HAS_AEAD_OCB)
163 if(req.algo_name() == "OCB") {
164 const size_t tag_len = req.arg_as_integer(1, 16);
165 if(dir == Cipher_Dir::Encryption) {
166 return std::make_unique<OCB_Encryption>(std::move(bc), tag_len);
167 } else {
168 return std::make_unique<OCB_Decryption>(std::move(bc), tag_len);
169 }
170 }
171 #endif
172
173 #if defined(BOTAN_HAS_AEAD_EAX)
174 if(req.algo_name() == "EAX") {
175 const size_t tag_len = req.arg_as_integer(1, bc->block_size());
176 if(dir == Cipher_Dir::Encryption) {
177 return std::make_unique<EAX_Encryption>(std::move(bc), tag_len);
178 } else {
179 return std::make_unique<EAX_Decryption>(std::move(bc), tag_len);
180 }
181 }
182 #endif
183
184 #if defined(BOTAN_HAS_AEAD_SIV)
185 if(req.algo_name() == "SIV") {
186 if(dir == Cipher_Dir::Encryption) {
187 return std::make_unique<SIV_Encryption>(std::move(bc));
188 } else {
189 return std::make_unique<SIV_Decryption>(std::move(bc));
190 }
191 }
192 #endif
193
194#endif
195
196 return std::unique_ptr<AEAD_Mode>();
197}
198
199} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:144
static std::unique_ptr< AEAD_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition aead.cpp:53
static std::unique_ptr< AEAD_Mode > create(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition aead.cpp:63
static std::unique_ptr< BlockCipher > create(std::string_view algo_spec, std::string_view provider="")
virtual std::string provider() const
std::string arg(size_t i) const
size_t arg_count() const
Definition scan_name.h:43
const std::string & algo_name() const
Definition scan_name.h:38
size_t arg_as_integer(size_t i, size_t def_value) const
std::vector< std::string > split_on(std::string_view str, char delim)
Definition parsing.cpp:141
std::vector< std::string > parse_algorithm_name(std::string_view scan_name)
Definition parsing.cpp:87