Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

p11_mechanism.cpp
Go to the documentation of this file.
1 /*
2 * PKCS#11 Mechanism
3 * (C) 2016 Daniel Neus, Sirrix AG
4 * (C) 2016 Philipp Weber, Sirrix AG
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/internal/p11_mechanism.h>
10 #include <botan/scan_name.h>
11 #include <botan/emsa.h>
12
13 #include <tuple>
14
15 namespace Botan {
16 namespace PKCS11 {
17
18 namespace {
19 using PSS_Params = std::tuple<size_t, MechanismType, MGF>;
20
21 // maps a PSS mechanism type to the number of bytes used for the salt, the mechanism type of the underlying hash algorithm and the MGF
22 static const std::map<MechanismType, PSS_Params> PssOptions =
23 {
24 { MechanismType::RsaPkcsPss, PSS_Params(0, MechanismType::Sha1, MGF::Mgf1Sha1) },
25 { MechanismType::Sha1RsaPkcsPss, PSS_Params(20, MechanismType::Sha1, MGF::Mgf1Sha1) },
26 { MechanismType::Sha224RsaPkcsPss, PSS_Params(28, MechanismType::Sha224, MGF::Mgf1Sha224) },
27 { MechanismType::Sha256RsaPkcsPss, PSS_Params(32, MechanismType::Sha256, MGF::Mgf1Sha256) },
28 { MechanismType::Sha384RsaPkcsPss, PSS_Params(48, MechanismType::Sha384, MGF::Mgf1Sha384) },
29 { MechanismType::Sha512RsaPkcsPss, PSS_Params(64, MechanismType::Sha512, MGF::Mgf1Sha512) }
30 };
31
32 struct MechanismData
33 {
34 explicit MechanismData(MechanismType _type)
35 : type(_type)
36 {}
37
38 MechanismData(MechanismData const&) = default;
39 MechanismData& operator=(MechanismData const&) = default;
40 virtual ~MechanismData() = default;
41
42 // the mechanism to perform
43 MechanismType type;
44 };
45
46 struct RSA_SignMechanism : public MechanismData
47 {
48 explicit RSA_SignMechanism(MechanismType _type)
49 : MechanismData(_type), hash(static_cast<MechanismType>(0)), mgf(static_cast<MGF>(0)), salt_size(0)
50 {
51 auto pss_option = PssOptions.find(type);
52 if(pss_option != PssOptions.end())
53 {
54 hash = std::get<1>(pss_option->second);
55 mgf = std::get<2>(pss_option->second);
56 salt_size = std::get<0>(pss_option->second);
57 }
58 }
59
60 // hash algorithm used in the PSS encoding; if the signature mechanism does not include message hashing,
61 // then this value must be the mechanism used by the application to generate the message hash;
62 // if the signature mechanism includes hashing, then this value must match the hash algorithm indicated by the signature mechanism
63 MechanismType hash;
64
65 // mask generation function to use on the encoded block
66 MGF mgf;
67
68 // length, in bytes, of the salt value used in the PSS encoding; typical values are the length of the message hash and zero
69 size_t salt_size;
70 };
71
72 // note: when updating this map, update the documentation for `MechanismWrapper::create_rsa_sign_mechanism`
73 static std::map<std::string, RSA_SignMechanism> SignMechanisms =
74 {
75 { "Raw", RSA_SignMechanism(MechanismType::RsaX509) },
76
77 { "EMSA2(Raw)", RSA_SignMechanism(MechanismType::RsaX931) },
78 { "EMSA2(SHA-1)", RSA_SignMechanism(MechanismType::Sha1RsaX931) },
79
80 // RSASSA PKCS#1 v1.5
81 { "EMSA3(Raw)", RSA_SignMechanism(MechanismType::RsaPkcs) },
82 { "EMSA3(SHA-1)", RSA_SignMechanism(MechanismType::Sha1RsaPkcs) },
83 { "EMSA3(SHA-224)", RSA_SignMechanism(MechanismType::Sha224RsaPkcs) },
84 { "EMSA3(SHA-256)", RSA_SignMechanism(MechanismType::Sha256RsaPkcs) },
85 { "EMSA3(SHA-384)", RSA_SignMechanism(MechanismType::Sha384RsaPkcs) },
86 { "EMSA3(SHA-512)", RSA_SignMechanism(MechanismType::Sha512RsaPkcs) },
87
88 // RSASSA PKCS#1 PSS
89 { "EMSA4(Raw)", RSA_SignMechanism(MechanismType::RsaPkcsPss) },
90 { "EMSA4(SHA-1)", RSA_SignMechanism(MechanismType::Sha1RsaPkcsPss) },
91 { "EMSA4(SHA-224)", RSA_SignMechanism(MechanismType::Sha224RsaPkcsPss) },
92 { "EMSA4(SHA-256)", RSA_SignMechanism(MechanismType::Sha256RsaPkcsPss) },
93 { "EMSA4(SHA-384)", RSA_SignMechanism(MechanismType::Sha384RsaPkcsPss) },
94 { "EMSA4(SHA-512)", RSA_SignMechanism(MechanismType::Sha512RsaPkcsPss) },
95
96 { "ISO9796", RSA_SignMechanism(MechanismType::Rsa9796) }
97 };
98
99 struct RSA_CryptMechanism : public MechanismData
100 {
101 RSA_CryptMechanism(MechanismType _type, size_t _padding_size, MechanismType _hash, MGF _mgf)
102 : MechanismData(_type), hash(_hash), mgf(_mgf), padding_size(_padding_size)
103 {}
104
105 RSA_CryptMechanism(MechanismType _type, size_t _padding_size)
106 : RSA_CryptMechanism(_type, _padding_size, static_cast<MechanismType>(0), static_cast<MGF>(0))
107 {}
108
109 // mechanism ID of the message digest algorithm used to calculate the digest of the encoding parameter
110 MechanismType hash;
111
112 // mask generation function to use on the encoded block
113 MGF mgf;
114
115 // number of bytes required for the padding
116 size_t padding_size;
117 };
118
119 // note: when updating this map, update the documentation for `MechanismWrapper::create_rsa_crypt_mechanism`
120 static const std::map<std::string, RSA_CryptMechanism> CryptMechanisms =
121 {
122 { "Raw", RSA_CryptMechanism(MechanismType::RsaX509, 0) },
123 { "EME-PKCS1-v1_5", RSA_CryptMechanism(MechanismType::RsaPkcs, 11) },
124 { "OAEP(SHA-1)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 20, MechanismType::Sha1, MGF::Mgf1Sha1) },
125 { "OAEP(SHA-224)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 28, MechanismType::Sha224, MGF::Mgf1Sha224) },
126 { "OAEP(SHA-256)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 32, MechanismType::Sha256, MGF::Mgf1Sha256) },
127 { "OAEP(SHA-384)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 48, MechanismType::Sha384, MGF::Mgf1Sha384) },
128 { "OAEP(SHA-512)", RSA_CryptMechanism(MechanismType::RsaPkcsOaep, 2 + 2 * 64, MechanismType::Sha512, MGF::Mgf1Sha512) }
129 };
130
131 // note: when updating this map, update the documentation for `MechanismWrapper::create_ecdsa_mechanism`
132 static std::map<std::string, MechanismType> EcdsaHash =
133 {
134 { "Raw", MechanismType::Ecdsa },
135 { "SHA-160", MechanismType::EcdsaSha1 },
136 { "SHA-224", MechanismType::EcdsaSha224 },
137 { "SHA-256", MechanismType::EcdsaSha256 },
138 { "SHA-384", MechanismType::EcdsaSha384 },
139 { "SHA-512", MechanismType::EcdsaSha512 }
140 };
141
142 // note: when updating this map, update the documentation for `MechanismWrapper::create_ecdh_mechanism`
143 static std::map<std::string, KeyDerivation> EcdhHash =
144 {
145 { "Raw", KeyDerivation::Null },
146 { "SHA-160", KeyDerivation::Sha1Kdf },
147 { "SHA-224", KeyDerivation::Sha224Kdf },
148 { "SHA-256", KeyDerivation::Sha256Kdf },
149 { "SHA-384", KeyDerivation::Sha384Kdf },
150 { "SHA-512", KeyDerivation::Sha512Kdf }
151 };
152 }
153
154 MechanismWrapper::MechanismWrapper(MechanismType mechanism_type)
155 : m_mechanism( { static_cast<CK_MECHANISM_TYPE>(mechanism_type), nullptr, 0 }), m_parameters(nullptr)
156 {}
157
158 MechanismWrapper MechanismWrapper::create_rsa_crypt_mechanism(const std::string& padding)
159 {
160 auto mechanism_info_it = CryptMechanisms.find(padding);
161 if(mechanism_info_it == CryptMechanisms.end())
162 {
163 // at this point it would be possible to support additional configurations that are not predefined above by parsing `padding`
164 throw Lookup_Error("PKCS#11 RSA encrypt/decrypt does not support EME " + padding);
165 }
166 RSA_CryptMechanism mechanism_info = mechanism_info_it->second;
167
168 MechanismWrapper mech(mechanism_info.type);
169 if(mechanism_info.type == MechanismType::RsaPkcsOaep)
170 {
171 mech.m_parameters = std::make_shared<MechanismParameters>();
172 mech.m_parameters->oaep_params.hashAlg = static_cast<CK_MECHANISM_TYPE>(mechanism_info.hash);
173 mech.m_parameters->oaep_params.mgf = static_cast<CK_RSA_PKCS_MGF_TYPE>(mechanism_info.mgf);
174 mech.m_parameters->oaep_params.source = CKZ_DATA_SPECIFIED;
175 mech.m_parameters->oaep_params.pSourceData = nullptr;
176 mech.m_parameters->oaep_params.ulSourceDataLen = 0;
177 mech.m_mechanism.pParameter = mech.m_parameters.get();
178 mech.m_mechanism.ulParameterLen = sizeof(RsaPkcsOaepParams);
179 }
180 mech.m_padding_size = mechanism_info.padding_size;
181 return mech;
182 }
183
184 MechanismWrapper MechanismWrapper::create_rsa_sign_mechanism(const std::string& padding)
185 {
186 auto mechanism_info_it = SignMechanisms.find(padding);
187 if(mechanism_info_it == SignMechanisms.end())
188 {
189 // at this point it would be possible to support additional configurations that are not predefined above by parsing `padding`
190 throw Lookup_Error("PKCS#11 RSA sign/verify does not support EMSA " + padding);
191 }
192 RSA_SignMechanism mechanism_info = mechanism_info_it->second;
193
194 MechanismWrapper mech(mechanism_info.type);
195 if(PssOptions.find(mechanism_info.type) != PssOptions.end())
196 {
197 mech.m_parameters = std::make_shared<MechanismParameters>();
198 mech.m_parameters->pss_params.hashAlg = static_cast<CK_MECHANISM_TYPE>(mechanism_info.hash);
199 mech.m_parameters->pss_params.mgf = static_cast<CK_RSA_PKCS_MGF_TYPE>(mechanism_info.mgf);
200 mech.m_parameters->pss_params.sLen = mechanism_info.salt_size;
201 mech.m_mechanism.pParameter = mech.m_parameters.get();
202 mech.m_mechanism.ulParameterLen = sizeof(RsaPkcsPssParams);
203 }
204 return mech;
205 }
206
207 MechanismWrapper MechanismWrapper::create_ecdsa_mechanism(const std::string& hash)
208 {
209 std::string hash_name = hash;
210
211 if(hash_name != "Raw")
212 {
213 hash_name = hash_for_emsa(hash);
214 }
215
216 auto mechanism_type = EcdsaHash.find(hash_name);
217 if(mechanism_type == EcdsaHash.end())
218 {
219 throw Lookup_Error("PKCS#11 ECDSA sign/verify does not support " + hash);
220 }
221 return MechanismWrapper(mechanism_type->second);
222 }
223
224 MechanismWrapper MechanismWrapper::create_ecdh_mechanism(const std::string& params)
225 {
226 std::vector<std::string> param_parts = split_on(params, ',');
227
228 if(param_parts.empty() || param_parts.size() > 2)
229 throw Invalid_Argument("PKCS #11 ECDH key derivation bad params " + params);
230
231 const bool use_cofactor =
232 (param_parts[0] == "Cofactor") ||
233 (param_parts.size() == 2 && param_parts[1] == "Cofactor");
234
235 std::string kdf_name = (param_parts[0] == "Cofactor" ? param_parts[1] : param_parts[0]);
236 std::string hash = kdf_name;
237
238 if(kdf_name != "Raw")
239 {
240 SCAN_Name kdf_hash(kdf_name);
241
242 if(kdf_hash.arg_count() > 0)
243 {
244 hash = kdf_hash.arg(0);
245 }
246 }
247
248 auto kdf = EcdhHash.find(hash);
249 if(kdf == EcdhHash.end())
250 {
251 throw Lookup_Error("PKCS#11 ECDH key derivation does not support KDF " + kdf_name);
252 }
253 MechanismWrapper mech(use_cofactor ? MechanismType::Ecdh1CofactorDerive : MechanismType::Ecdh1Derive);
254 mech.m_parameters = std::make_shared<MechanismParameters>();
255 mech.m_parameters->ecdh_params.kdf = static_cast<CK_EC_KDF_TYPE>(kdf->second);
256 mech.m_mechanism.pParameter = mech.m_parameters.get();
257 mech.m_mechanism.ulParameterLen = sizeof(Ecdh1DeriveParams);
258 return mech;
259 }
260
261 }
262 }
Botan::SCAN_Name::arg
std::string arg(size_t i) const
Definition: scan_name.cpp:122
Botan::PKCS11::MechanismType::EcdsaSha224
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::hash_for_emsa
std::string hash_for_emsa(const std::string &algo_spec)
Definition: emsa.cpp:142
Botan::PKCS11::MechanismType::EcdsaSha1
Botan::PKCS11::MechanismType::Sha512
CK_MECHANISM_TYPE
CK_ULONG CK_MECHANISM_TYPE
Definition: pkcs11t.h:583
Botan::PKCS11::KeyDerivation::Null
Botan::PKCS11::KeyDerivation::Sha1Kdf
Botan::PKCS11::MechanismType::Rsa9796
Botan::PKCS11::MechanismType::EcdsaSha256
Botan::PKCS11::MechanismType::RsaX509
Botan::split_on
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:138
Botan::PKCS11::MGF::Mgf1Sha224
Botan::PKCS11::MechanismType::Sha256RsaPkcsPss
Botan::SCAN_Name::arg_count
size_t arg_count() const
Definition: scan_name.h:50
salt_size
size_t salt_size
Definition: p11_mechanism.cpp:69
type
MechanismType type
Definition: p11_mechanism.cpp:43
Botan::PKCS11::MechanismWrapper::create_ecdh_mechanism
static MechanismWrapper create_ecdh_mechanism(const std::string &params)
Definition: p11_mechanism.cpp:224
Botan::PKCS11::MechanismWrapper
Definition: p11_mechanism.h:26
Botan::PKCS11::MechanismType::Sha384RsaPkcs
CK_MECHANISM::ulParameterLen
CK_ULONG ulParameterLen
Definition: pkcs11t.h:986
Botan::PKCS11::AttributeType::MechanismType
Botan::PKCS11::MechanismType::Sha512RsaPkcsPss
Botan::PKCS11::MechanismType::Sha224RsaPkcsPss
Botan::PKCS11::MechanismType::Sha384RsaPkcsPss
Botan::PKCS11::KeyDerivation::Sha224Kdf
Botan::PKCS11::KeyDerivation::Sha384Kdf
Botan::PKCS11::MechanismWrapper::MechanismWrapper
MechanismWrapper(MechanismType mechanism_type)
Definition: p11_mechanism.cpp:154
Botan::PKCS11::MechanismType::RsaPkcsPss
Botan::PKCS11::MechanismType::Sha224RsaPkcs
Botan::PKCS11::MechanismType::Sha1
Botan::PKCS11::MechanismType::Sha512RsaPkcs
Botan::PKCS11::MechanismType::RsaPkcs
Botan::PKCS11::MechanismType::RsaX931
Botan::PKCS11::MechanismType::Sha1RsaX931
Botan::PKCS11::MechanismType::Ecdh1CofactorDerive
Botan::PKCS11::RsaPkcsPssParams
CK_RSA_PKCS_PSS_PARAMS RsaPkcsPssParams
Definition: p11.h:849
Botan::PKCS11::MGF::Mgf1Sha512
Botan::PKCS11::KeyDerivation::Sha512Kdf
Botan::Lookup_Error
Definition: exceptn.h:71
Botan::PKCS11::MGF::Mgf1Sha384
Botan::PKCS11::MGF
MGF
Definition: p11.h:270
padding_size
size_t padding_size
Definition: p11_mechanism.cpp:116
mgf
MGF mgf
Definition: p11_mechanism.cpp:66
Botan
Definition: alg_id.cpp:13
Botan::PKCS11::MechanismType::Sha384
Botan::SCAN_Name
Definition: scan_name.h:22
CKZ_DATA_SPECIFIED
#define CKZ_DATA_SPECIFIED
Definition: pkcs11t.h:1261
Botan::PKCS11::MechanismType::Sha1RsaPkcsPss
Botan::PKCS11::MechanismType::RsaPkcsOaep
Botan::PKCS11::MechanismType::Ecdh1Derive
Botan::PKCS11::MechanismType
MechanismType
Definition: p11.h:335
Botan::PKCS11::MGF::Mgf1Sha256
Botan::PKCS11::MechanismType::EcdsaSha384
Botan::PKCS11::KeyType::Ecdsa
Botan::PKCS11::RsaPkcsOaepParams
CK_RSA_PKCS_OAEP_PARAMS RsaPkcsOaepParams
Definition: p11.h:848
Botan::PKCS11::KeyDerivation::Sha256Kdf
Botan::PKCS11::MechanismWrapper::create_rsa_crypt_mechanism
static MechanismWrapper create_rsa_crypt_mechanism(const std::string &padding)
Definition: p11_mechanism.cpp:158
Botan::PKCS11::MechanismType::Sha256
CK_RSA_PKCS_MGF_TYPE
CK_ULONG CK_RSA_PKCS_MGF_TYPE
Definition: pkcs11t.h:1241
Botan::PKCS11::MechanismType::Sha1RsaPkcs
Botan::PKCS11::MGF::Mgf1Sha1
Botan::PKCS11::MechanismWrapper::create_ecdsa_mechanism
static MechanismWrapper create_ecdsa_mechanism(const std::string &hash)
Definition: p11_mechanism.cpp:207
Botan::PKCS11::MechanismType::Sha256RsaPkcs
Botan::PKCS11::Ecdh1DeriveParams
CK_ECDH1_DERIVE_PARAMS Ecdh1DeriveParams
Definition: p11.h:850
CK_MECHANISM::pParameter
CK_VOID_PTR pParameter
Definition: pkcs11t.h:985
Botan::PKCS11::MechanismType::Sha224
Botan::PKCS11::MechanismWrapper::create_rsa_sign_mechanism
static MechanismWrapper create_rsa_sign_mechanism(const std::string &padding)
Definition: p11_mechanism.cpp:184
hash
MechanismType hash
Definition: p11_mechanism.cpp:63
CK_EC_KDF_TYPE
CK_ULONG CK_EC_KDF_TYPE
Definition: pkcs11t.h:1287
Botan::PKCS11::MechanismType::EcdsaSha512