Coverage Report

Created: 2025-04-11 06:34

/src/botan/src/lib/pk_pad/emsa.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2015 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#include <botan/internal/emsa.h>
8
9
#include <botan/exceptn.h>
10
#include <botan/hash.h>
11
#include <botan/internal/scan_name.h>
12
13
#if defined(BOTAN_HAS_EMSA_X931)
14
   #include <botan/internal/emsa_x931.h>
15
#endif
16
17
#if defined(BOTAN_HAS_EMSA_PKCS1)
18
   #include <botan/internal/emsa_pkcs1.h>
19
#endif
20
21
#if defined(BOTAN_HAS_EMSA_PSSR)
22
   #include <botan/internal/pssr.h>
23
#endif
24
25
#if defined(BOTAN_HAS_EMSA_RAW)
26
   #include <botan/internal/emsa_raw.h>
27
#endif
28
29
#if defined(BOTAN_HAS_ISO_9796)
30
   #include <botan/internal/iso9796.h>
31
#endif
32
33
namespace Botan {
34
35
3.28k
std::unique_ptr<EMSA> EMSA::create(std::string_view algo_spec) {
36
3.28k
   SCAN_Name req(algo_spec);
37
38
3.28k
#if defined(BOTAN_HAS_EMSA_PKCS1)
39
   // TODO(Botan4) Remove all but "PKCS1v15"
40
3.28k
   if(req.algo_name() == "EMSA_PKCS1" || req.algo_name() == "PKCS1v15" || req.algo_name() == "EMSA-PKCS1-v1_5" ||
41
3.28k
      req.algo_name() == "EMSA3") {
42
3.06k
      if(req.arg_count() == 2 && req.arg(0) == "Raw") {
43
0
         return std::make_unique<EMSA_PKCS1v15_Raw>(req.arg(1));
44
3.06k
      } else if(req.arg_count() == 1) {
45
3.06k
         if(req.arg(0) == "Raw") {
46
0
            return std::make_unique<EMSA_PKCS1v15_Raw>();
47
3.06k
         } else {
48
3.06k
            if(auto hash = HashFunction::create(req.arg(0))) {
49
3.05k
               return std::make_unique<EMSA_PKCS1v15>(std::move(hash));
50
3.05k
            }
51
3.06k
         }
52
3.06k
      }
53
3.06k
   }
54
225
#endif
55
56
225
#if defined(BOTAN_HAS_EMSA_PSSR)
57
   // TODO(Botan4) Remove all but "PSS_Raw"
58
225
   if(req.algo_name() == "PSS_Raw" || req.algo_name() == "PSSR_Raw") {
59
0
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") {
60
0
         if(auto hash = HashFunction::create(req.arg(0))) {
61
0
            if(req.arg_count() == 3) {
62
0
               const size_t salt_size = req.arg_as_integer(2, 0);
63
0
               return std::make_unique<PSSR_Raw>(std::move(hash), salt_size);
64
0
            } else {
65
0
               return std::make_unique<PSSR_Raw>(std::move(hash));
66
0
            }
67
0
         }
68
0
      }
69
0
   }
70
71
   // TODO(Botan4) Remove all but "PSS"
72
225
   if(req.algo_name() == "PSS" || req.algo_name() == "PSSR" || req.algo_name() == "EMSA-PSS" ||
73
225
      req.algo_name() == "PSS-MGF1" || req.algo_name() == "EMSA4") {
74
98
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") {
75
98
         if(auto hash = HashFunction::create(req.arg(0))) {
76
98
            if(req.arg_count() == 3) {
77
98
               const size_t salt_size = req.arg_as_integer(2, 0);
78
98
               return std::make_unique<PSSR>(std::move(hash), salt_size);
79
98
            } else {
80
0
               return std::make_unique<PSSR>(std::move(hash));
81
0
            }
82
98
         }
83
98
      }
84
98
   }
85
127
#endif
86
87
127
#if defined(BOTAN_HAS_ISO_9796)
88
127
   if(req.algo_name() == "ISO_9796_DS2") {
89
0
      if(req.arg_count_between(1, 3)) {
90
0
         if(auto hash = HashFunction::create(req.arg(0))) {
91
0
            const size_t salt_size = req.arg_as_integer(2, hash->output_length());
92
0
            const bool implicit = req.arg(1, "exp") == "imp";
93
0
            return std::make_unique<ISO_9796_DS2>(std::move(hash), implicit, salt_size);
94
0
         }
95
0
      }
96
0
   }
97
   //ISO-9796-2 DS 3 is deterministic and DS2 without a salt
98
127
   if(req.algo_name() == "ISO_9796_DS3") {
99
0
      if(req.arg_count_between(1, 2)) {
100
0
         if(auto hash = HashFunction::create(req.arg(0))) {
101
0
            const bool implicit = req.arg(1, "exp") == "imp";
102
0
            return std::make_unique<ISO_9796_DS3>(std::move(hash), implicit);
103
0
         }
104
0
      }
105
0
   }
106
127
#endif
107
108
127
#if defined(BOTAN_HAS_EMSA_X931)
109
   // TODO(Botan4) Remove all but "X9.31"
110
127
   if(req.algo_name() == "EMSA_X931" || req.algo_name() == "EMSA2" || req.algo_name() == "X9.31") {
111
0
      if(req.arg_count() == 1) {
112
0
         if(auto hash = HashFunction::create(req.arg(0))) {
113
0
            return std::make_unique<EMSA_X931>(std::move(hash));
114
0
         }
115
0
      }
116
0
   }
117
127
#endif
118
119
127
#if defined(BOTAN_HAS_EMSA_RAW)
120
127
   if(req.algo_name() == "Raw") {
121
0
      if(req.arg_count() == 0) {
122
0
         return std::make_unique<EMSA_Raw>();
123
0
      } else {
124
0
         auto hash = HashFunction::create(req.arg(0));
125
0
         if(hash) {
126
0
            return std::make_unique<EMSA_Raw>(hash->output_length());
127
0
         }
128
0
      }
129
0
   }
130
127
#endif
131
132
127
   return nullptr;
133
127
}
134
135
3.28k
std::unique_ptr<EMSA> EMSA::create_or_throw(std::string_view algo_spec) {
136
3.28k
   auto emsa = EMSA::create(algo_spec);
137
3.28k
   if(emsa) {
138
3.15k
      return emsa;
139
3.15k
   }
140
127
   throw Algorithm_Not_Found(algo_spec);
141
3.28k
}
142
143
}  // namespace Botan