Coverage Report

Created: 2024-06-28 06:39

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