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