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