Botan 3.10.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/internal/parsing.h>
11#include <botan/internal/scan_name.h>
12#include <sstream>
13
14#if defined(BOTAN_HAS_BLOCK_CIPHER)
15 #include <botan/block_cipher.h>
16#endif
17
18#if defined(BOTAN_HAS_AEAD_CCM)
19 #include <botan/internal/ccm.h>
20#endif
21
22#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
23 #include <botan/internal/chacha20poly1305.h>
24#endif
25
26#if defined(BOTAN_HAS_AEAD_EAX)
27 #include <botan/internal/eax.h>
28#endif
29
30#if defined(BOTAN_HAS_AEAD_GCM)
31 #include <botan/internal/gcm.h>
32#endif
33
34#if defined(BOTAN_HAS_AEAD_OCB)
35 #include <botan/internal/ocb.h>
36#endif
37
38#if defined(BOTAN_HAS_AEAD_SIV)
39 #include <botan/internal/siv.h>
40#endif
41
42#if defined(BOTAN_HAS_ASCON_AEAD128)
43 #include <botan/internal/ascon_aead128.h>
44#endif
45
46namespace Botan {
47
48std::unique_ptr<AEAD_Mode> AEAD_Mode::create_or_throw(std::string_view algo,
49 Cipher_Dir dir,
50 std::string_view provider) {
51 if(auto aead = AEAD_Mode::create(algo, dir, provider)) {
52 return aead;
53 }
54
55 throw Lookup_Error("AEAD", algo, provider);
56}
57
58std::unique_ptr<AEAD_Mode> AEAD_Mode::create(std::string_view algo, Cipher_Dir dir, std::string_view provider) {
60#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
61 if(algo == "ChaCha20Poly1305") {
62 if(dir == Cipher_Dir::Encryption) {
63 return std::make_unique<ChaCha20Poly1305_Encryption>();
64 } else {
65 return std::make_unique<ChaCha20Poly1305_Decryption>();
66 }
67 }
68#endif
69
70#if defined(BOTAN_HAS_ASCON_AEAD128)
71 if(algo == "Ascon-AEAD128") {
72 if(dir == Cipher_Dir::Encryption) {
73 return std::make_unique<Ascon_AEAD128_Encryption>();
74 } else {
75 return std::make_unique<Ascon_AEAD128_Decryption>();
76 }
77 }
78#endif
79
80 if(algo.find('/') != std::string::npos) {
81 const std::vector<std::string> algo_parts = split_on(algo, '/');
82 std::string_view cipher_name = algo_parts[0];
83 const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
84
85 if(mode_info.empty()) {
86 return std::unique_ptr<AEAD_Mode>();
87 }
88
89 std::ostringstream mode_name;
90
91 mode_name << mode_info[0] << '(' << cipher_name;
92 for(size_t i = 1; i < mode_info.size(); ++i) {
93 mode_name << ',' << mode_info[i];
94 }
95 for(size_t i = 2; i < algo_parts.size(); ++i) {
96 mode_name << ',' << algo_parts[i];
97 }
98 mode_name << ')';
99
100 return AEAD_Mode::create(mode_name.str(), dir);
101 }
102
103#if defined(BOTAN_HAS_BLOCK_CIPHER)
104
105 SCAN_Name req(algo);
106
107 if(req.arg_count() == 0) {
108 return std::unique_ptr<AEAD_Mode>();
109 }
110
111 auto bc = BlockCipher::create(req.arg(0), provider);
112
113 if(!bc) {
114 return std::unique_ptr<AEAD_Mode>();
115 }
116
117 #if defined(BOTAN_HAS_AEAD_CCM)
118 if(req.algo_name() == "CCM") {
119 size_t tag_len = req.arg_as_integer(1, 16);
120 size_t L_len = req.arg_as_integer(2, 3);
121 if(dir == Cipher_Dir::Encryption) {
122 return std::make_unique<CCM_Encryption>(std::move(bc), tag_len, L_len);
123 } else {
124 return std::make_unique<CCM_Decryption>(std::move(bc), tag_len, L_len);
125 }
126 }
127 #endif
128
129 #if defined(BOTAN_HAS_AEAD_GCM)
130 if(req.algo_name() == "GCM") {
131 size_t tag_len = req.arg_as_integer(1, 16);
132 if(dir == Cipher_Dir::Encryption) {
133 return std::make_unique<GCM_Encryption>(std::move(bc), tag_len);
134 } else {
135 return std::make_unique<GCM_Decryption>(std::move(bc), tag_len);
136 }
137 }
138 #endif
139
140 #if defined(BOTAN_HAS_AEAD_OCB)
141 if(req.algo_name() == "OCB") {
142 size_t tag_len = req.arg_as_integer(1, 16);
143 if(dir == Cipher_Dir::Encryption) {
144 return std::make_unique<OCB_Encryption>(std::move(bc), tag_len);
145 } else {
146 return std::make_unique<OCB_Decryption>(std::move(bc), tag_len);
147 }
148 }
149 #endif
150
151 #if defined(BOTAN_HAS_AEAD_EAX)
152 if(req.algo_name() == "EAX") {
153 size_t tag_len = req.arg_as_integer(1, bc->block_size());
154 if(dir == Cipher_Dir::Encryption) {
155 return std::make_unique<EAX_Encryption>(std::move(bc), tag_len);
156 } else {
157 return std::make_unique<EAX_Decryption>(std::move(bc), tag_len);
158 }
159 }
160 #endif
161
162 #if defined(BOTAN_HAS_AEAD_SIV)
163 if(req.algo_name() == "SIV") {
164 if(dir == Cipher_Dir::Encryption) {
165 return std::make_unique<SIV_Encryption>(std::move(bc));
166 } else {
167 return std::make_unique<SIV_Decryption>(std::move(bc));
168 }
169 }
170 #endif
171
172#endif
173
174 return std::unique_ptr<AEAD_Mode>();
175}
176
177} // 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:48
static std::unique_ptr< AEAD_Mode > create(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition aead.cpp:58
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:49
const std::string & algo_name() const
Definition scan_name.h:44
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:111
std::vector< std::string > parse_algorithm_name(std::string_view namex)
Definition parsing.cpp:57