Coverage Report

Created: 2025-11-16 06:56

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