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