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