Coverage Report

Created: 2020-03-26 13:53

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