Coverage Report

Created: 2025-08-28 06:21

/src/Botan-3.4.0/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
52.9k
std::unique_ptr<EMSA> EMSA::create(std::string_view algo_spec) {
36
52.9k
   SCAN_Name req(algo_spec);
37
38
52.9k
#if defined(BOTAN_HAS_EMSA_PKCS1)
39
52.9k
   if(req.algo_name() == "EMSA_PKCS1" || req.algo_name() == "PKCS1v15" || req.algo_name() == "EMSA-PKCS1-v1_5" ||
40
52.9k
      req.algo_name() == "EMSA3") {
41
52.9k
      if(req.arg_count() == 2 && req.arg(0) == "Raw") {
42
52.9k
         return std::make_unique<EMSA_PKCS1v15_Raw>(req.arg(1));
43
52.9k
      } else if(req.arg_count() == 1) {
44
0
         if(req.arg(0) == "Raw") {
45
0
            return std::make_unique<EMSA_PKCS1v15_Raw>();
46
0
         } else {
47
0
            if(auto hash = HashFunction::create(req.arg(0))) {
48
0
               return std::make_unique<EMSA_PKCS1v15>(std::move(hash));
49
0
            }
50
0
         }
51
0
      }
52
52.9k
   }
53
0
#endif
54
55
0
#if defined(BOTAN_HAS_EMSA_PSSR)
56
0
   if(req.algo_name() == "PSS_Raw" || req.algo_name() == "PSSR_Raw") {
57
0
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") {
58
0
         if(auto hash = HashFunction::create(req.arg(0))) {
59
0
            if(req.arg_count() == 3) {
60
0
               const size_t salt_size = req.arg_as_integer(2, 0);
61
0
               return std::make_unique<PSSR_Raw>(std::move(hash), salt_size);
62
0
            } else {
63
0
               return std::make_unique<PSSR_Raw>(std::move(hash));
64
0
            }
65
0
         }
66
0
      }
67
0
   }
68
69
0
   if(req.algo_name() == "PSS" || req.algo_name() == "PSSR" || req.algo_name() == "EMSA-PSS" ||
70
0
      req.algo_name() == "PSS-MGF1" || req.algo_name() == "EMSA4") {
71
0
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1") {
72
0
         if(auto hash = HashFunction::create(req.arg(0))) {
73
0
            if(req.arg_count() == 3) {
74
0
               const size_t salt_size = req.arg_as_integer(2, 0);
75
0
               return std::make_unique<PSSR>(std::move(hash), salt_size);
76
0
            } else {
77
0
               return std::make_unique<PSSR>(std::move(hash));
78
0
            }
79
0
         }
80
0
      }
81
0
   }
82
0
#endif
83
84
#if defined(BOTAN_HAS_ISO_9796)
85
   if(req.algo_name() == "ISO_9796_DS2") {
86
      if(req.arg_count_between(1, 3)) {
87
         if(auto hash = HashFunction::create(req.arg(0))) {
88
            const size_t salt_size = req.arg_as_integer(2, hash->output_length());
89
            const bool implicit = req.arg(1, "exp") == "imp";
90
            return std::make_unique<ISO_9796_DS2>(std::move(hash), implicit, salt_size);
91
         }
92
      }
93
   }
94
   //ISO-9796-2 DS 3 is deterministic and DS2 without a salt
95
   if(req.algo_name() == "ISO_9796_DS3") {
96
      if(req.arg_count_between(1, 2)) {
97
         if(auto hash = HashFunction::create(req.arg(0))) {
98
            const bool implicit = req.arg(1, "exp") == "imp";
99
            return std::make_unique<ISO_9796_DS3>(std::move(hash), implicit);
100
         }
101
      }
102
   }
103
#endif
104
105
#if defined(BOTAN_HAS_EMSA_X931)
106
   if(req.algo_name() == "EMSA_X931" || req.algo_name() == "EMSA2" || req.algo_name() == "X9.31") {
107
      if(req.arg_count() == 1) {
108
         if(auto hash = HashFunction::create(req.arg(0))) {
109
            return std::make_unique<EMSA_X931>(std::move(hash));
110
         }
111
      }
112
   }
113
#endif
114
115
0
#if defined(BOTAN_HAS_EMSA_RAW)
116
0
   if(req.algo_name() == "Raw") {
117
0
      if(req.arg_count() == 0) {
118
0
         return std::make_unique<EMSA_Raw>();
119
0
      } else {
120
0
         auto hash = HashFunction::create(req.arg(0));
121
0
         if(hash) {
122
0
            return std::make_unique<EMSA_Raw>(hash->output_length());
123
0
         }
124
0
      }
125
0
   }
126
0
#endif
127
128
0
   return nullptr;
129
0
}
130
131
52.9k
std::unique_ptr<EMSA> EMSA::create_or_throw(std::string_view algo_spec) {
132
52.9k
   auto emsa = EMSA::create(algo_spec);
133
52.9k
   if(emsa) {
134
52.9k
      return emsa;
135
52.9k
   }
136
0
   throw Algorithm_Not_Found(algo_spec);
137
52.9k
}
138
139
}  // namespace Botan