Coverage Report

Created: 2020-06-30 13:58

/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.92k
   {
46
1.92k
   if(auto aead = AEAD_Mode::create(algo, dir, provider))
47
1.92k
      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.71k
   {
56
3.71k
   BOTAN_UNUSED(provider);
57
3.71k
#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
58
3.71k
   if(algo == "ChaCha20Poly1305")
59
140
      {
60
140
      if(dir == ENCRYPTION)
61
72
         return std::unique_ptr<AEAD_Mode>(new ChaCha20Poly1305_Encryption);
62
68
      else
63
68
         return std::unique_ptr<AEAD_Mode>(new ChaCha20Poly1305_Decryption);
64
3.57k
65
3.57k
      }
66
3.57k
#endif
67
3.57k
68
3.57k
   if(algo.find('/') != std::string::npos)
69
1.78k
      {
70
1.78k
      const std::vector<std::string> algo_parts = split_on(algo, '/');
71
1.78k
      const std::string cipher_name = algo_parts[0];
72
1.78k
      const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
73
1.78k
74
1.78k
      if(mode_info.empty())
75
0
         return std::unique_ptr<AEAD_Mode>();
76
1.78k
77
1.78k
      std::ostringstream alg_args;
78
1.78k
79
1.78k
      alg_args << '(' << cipher_name;
80
2.53k
      for(size_t i = 1; i < mode_info.size(); ++i)
81
751
         alg_args << ',' << mode_info[i];
82
1.78k
      for(size_t i = 2; i < algo_parts.size(); ++i)
83
0
         alg_args << ',' << algo_parts[i];
84
1.78k
      alg_args << ')';
85
1.78k
86
1.78k
      const std::string mode_name = mode_info[0] + alg_args.str();
87
1.78k
      return AEAD_Mode::create(mode_name, dir);
88
1.78k
      }
89
1.78k
90
1.78k
#if defined(BOTAN_HAS_BLOCK_CIPHER)
91
1.78k
92
1.78k
   SCAN_Name req(algo);
93
1.78k
94
1.78k
   if(req.arg_count() == 0)
95
0
      {
96
0
      return std::unique_ptr<AEAD_Mode>();
97
0
      }
98
1.78k
99
1.78k
   std::unique_ptr<BlockCipher> bc(BlockCipher::create(req.arg(0), provider));
100
1.78k
101
1.78k
   if(!bc)
102
0
      {
103
0
      return std::unique_ptr<AEAD_Mode>();
104
0
      }
105
1.78k
106
1.78k
#if defined(BOTAN_HAS_AEAD_CCM)
107
1.78k
   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
153
         return std::unique_ptr<AEAD_Mode>(new CCM_Encryption(bc.release(), tag_len, L_len));
113
156
      else
114
156
         return std::unique_ptr<AEAD_Mode>(new CCM_Decryption(bc.release(), tag_len, L_len));
115
1.47k
      }
116
1.47k
#endif
117
1.47k
118
1.47k
#if defined(BOTAN_HAS_AEAD_GCM)
119
1.47k
   if(req.algo_name() == "GCM")
120
943
      {
121
943
      size_t tag_len = req.arg_as_integer(1, 16);
122
943
      if(dir == ENCRYPTION)
123
628
         return std::unique_ptr<AEAD_Mode>(new GCM_Encryption(bc.release(), tag_len));
124
315
      else
125
315
         return std::unique_ptr<AEAD_Mode>(new GCM_Decryption(bc.release(), tag_len));
126
536
      }
127
536
#endif
128
536
129
536
#if defined(BOTAN_HAS_AEAD_OCB)
130
536
   if(req.algo_name() == "OCB")
131
536
      {
132
536
      size_t tag_len = req.arg_as_integer(1, 16);
133
536
      if(dir == ENCRYPTION)
134
255
         return std::unique_ptr<AEAD_Mode>(new OCB_Encryption(bc.release(), tag_len));
135
281
      else
136
281
         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
}