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