Coverage Report

Created: 2019-12-03 15:21

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