/src/cryptofuzz-openssl-api/modules/wolfcrypt-openssl/module.cpp
Line | Count | Source |
1 | | #include "module.h" |
2 | | #include <cryptofuzz/util.h> |
3 | | #include <cryptofuzz/repository.h> |
4 | | #include <fuzzing/datasource/id.hpp> |
5 | | #include "bn_ops.h" |
6 | | extern "C" { |
7 | | #include <wolfssl/openssl/hmac.h> |
8 | | } |
9 | | #if defined(HMAC) |
10 | | #undef HMAC |
11 | | #endif |
12 | | #include "module_internal.h" |
13 | | |
14 | | namespace cryptofuzz { |
15 | | namespace module { |
16 | | |
17 | | wolfCrypt_OpenSSL::wolfCrypt_OpenSSL(void) : |
18 | 2 | Module("wolfCrypt-OpenSSL") { |
19 | 2 | } |
20 | | |
21 | | namespace wolfCrypt_OpenSSL_detail { |
22 | 3.06k | const EVP_MD* toEVPMD(const component::DigestType& digestType) { |
23 | 3.06k | using fuzzing::datasource::ID; |
24 | | |
25 | 3.06k | static const std::map<uint64_t, const EVP_MD*> LUT = { |
26 | | #if defined(CRYPTOFUZZ_BORINGSSL) |
27 | | { CF_DIGEST("SHA1"), EVP_sha1() }, |
28 | | { CF_DIGEST("SHA224"), EVP_sha224() }, |
29 | | { CF_DIGEST("SHA256"), EVP_sha256() }, |
30 | | { CF_DIGEST("SHA384"), EVP_sha384() }, |
31 | | { CF_DIGEST("SHA512"), EVP_sha512() }, |
32 | | { CF_DIGEST("MD4"), EVP_md4() }, |
33 | | { CF_DIGEST("MD5"), EVP_md5() }, |
34 | | { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() }, |
35 | | { CF_DIGEST("SHA512-256"), EVP_sha512_256() }, |
36 | | #elif defined(CRYPTOFUZZ_LIBRESSL) |
37 | | { CF_DIGEST("SHA1"), EVP_sha1() }, |
38 | | { CF_DIGEST("SHA224"), EVP_sha224() }, |
39 | | { CF_DIGEST("SHA256"), EVP_sha256() }, |
40 | | { CF_DIGEST("SHA384"), EVP_sha384() }, |
41 | | { CF_DIGEST("SHA512"), EVP_sha512() }, |
42 | | { CF_DIGEST("MD4"), EVP_md4() }, |
43 | | { CF_DIGEST("MD5"), EVP_md5() }, |
44 | | { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() }, |
45 | | { CF_DIGEST("RIPEMD160"), EVP_ripemd160() }, |
46 | | { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() }, |
47 | | { CF_DIGEST("SM3"), EVP_sm3() }, |
48 | | { CF_DIGEST("GOST-R-34.11-94"), EVP_gostr341194() }, |
49 | | { CF_DIGEST("GOST-28147-89"), EVP_gost2814789imit() }, |
50 | | { CF_DIGEST("STREEBOG-256"), EVP_streebog256() }, |
51 | | { CF_DIGEST("STREEBOG-512"), EVP_streebog512() }, |
52 | | #elif defined(CRYPTOFUZZ_OPENSSL_102) |
53 | | { CF_DIGEST("SHA1"), EVP_sha1() }, |
54 | | { CF_DIGEST("SHA224"), EVP_sha224() }, |
55 | | { CF_DIGEST("SHA256"), EVP_sha256() }, |
56 | | { CF_DIGEST("SHA384"), EVP_sha384() }, |
57 | | { CF_DIGEST("SHA512"), EVP_sha512() }, |
58 | | { CF_DIGEST("MD2"), EVP_md2() }, |
59 | | { CF_DIGEST("MD4"), EVP_md4() }, |
60 | | { CF_DIGEST("MD5"), EVP_md5() }, |
61 | | { CF_DIGEST("MDC2"), EVP_mdc2() }, |
62 | | { CF_DIGEST("RIPEMD160"), EVP_ripemd160() }, |
63 | | { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() }, |
64 | | #elif defined(CRYPTOFUZZ_OPENSSL_110) |
65 | | { CF_DIGEST("SHA1"), EVP_sha1() }, |
66 | | { CF_DIGEST("SHA224"), EVP_sha224() }, |
67 | | { CF_DIGEST("SHA256"), EVP_sha256() }, |
68 | | { CF_DIGEST("SHA384"), EVP_sha384() }, |
69 | | { CF_DIGEST("SHA512"), EVP_sha512() }, |
70 | | { CF_DIGEST("MD2"), EVP_md2() }, |
71 | | { CF_DIGEST("MD4"), EVP_md4() }, |
72 | | { CF_DIGEST("MD5"), EVP_md5() }, |
73 | | { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() }, |
74 | | { CF_DIGEST("MDC2"), EVP_mdc2() }, |
75 | | { CF_DIGEST("RIPEMD160"), EVP_ripemd160() }, |
76 | | { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() }, |
77 | | { CF_DIGEST("BLAKE2B512"), EVP_blake2b512() }, |
78 | | { CF_DIGEST("BLAKE2S256"), EVP_blake2s256() }, |
79 | | #elif defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
80 | 3.06k | { CF_DIGEST("SHA1"), EVP_sha1() }, |
81 | 3.06k | { CF_DIGEST("MDC2"), EVP_mdc2() }, |
82 | 3.06k | { CF_DIGEST("MD4"), EVP_md4() }, |
83 | 3.06k | { CF_DIGEST("MD5"), EVP_md5() }, |
84 | 3.06k | { CF_DIGEST("SHA224"), EVP_sha224() }, |
85 | 3.06k | { CF_DIGEST("SHA256"), EVP_sha256() }, |
86 | 3.06k | { CF_DIGEST("SHA384"), EVP_sha384() }, |
87 | 3.06k | { CF_DIGEST("SHA512"), EVP_sha512() }, |
88 | 3.06k | { CF_DIGEST("RIPEMD160"), EVP_ripemd160() }, |
89 | | #if 0 |
90 | | { CF_DIGEST("MDC2"), EVP_mdc2() }, |
91 | | { CF_DIGEST("MD4"), EVP_md4() }, |
92 | | { CF_DIGEST("MD5"), EVP_md5() }, |
93 | | { CF_DIGEST("SHA1"), EVP_sha1() }, |
94 | | { CF_DIGEST("SHA224"), EVP_sha224() }, |
95 | | { CF_DIGEST("SHA256"), EVP_sha256() }, |
96 | | { CF_DIGEST("SHA384"), EVP_sha384() }, |
97 | | { CF_DIGEST("SHA512"), EVP_sha512() }, |
98 | | { CF_DIGEST("RIPEMD160"), EVP_ripemd160() }, |
99 | | { CF_DIGEST("SHA3-224"), EVP_sha3_224() }, |
100 | | { CF_DIGEST("SHA3-256"), EVP_sha3_256() }, |
101 | | { CF_DIGEST("SHA3-384"), EVP_sha3_384() }, |
102 | | { CF_DIGEST("SHA3-512"), EVP_sha3_512() }, |
103 | | #endif |
104 | | #else |
105 | | { CF_DIGEST("SHA1"), EVP_sha1() }, |
106 | | { CF_DIGEST("SHA224"), EVP_sha224() }, |
107 | | { CF_DIGEST("SHA256"), EVP_sha256() }, |
108 | | { CF_DIGEST("SHA384"), EVP_sha384() }, |
109 | | { CF_DIGEST("SHA512"), EVP_sha512() }, |
110 | | { CF_DIGEST("MD2"), EVP_md2() }, |
111 | | { CF_DIGEST("MD4"), EVP_md4() }, |
112 | | { CF_DIGEST("MD5"), EVP_md5() }, |
113 | | { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() }, |
114 | | { CF_DIGEST("MDC2"), EVP_mdc2() }, |
115 | | { CF_DIGEST("RIPEMD160"), EVP_ripemd160() }, |
116 | | { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() }, |
117 | | { CF_DIGEST("SM3"), EVP_sm3() }, |
118 | | { CF_DIGEST("BLAKE2B512"), EVP_blake2b512() }, |
119 | | { CF_DIGEST("BLAKE2S256"), EVP_blake2s256() }, |
120 | | { CF_DIGEST("SHAKE128"), EVP_shake128() }, |
121 | | { CF_DIGEST("SHAKE256"), EVP_shake256() }, |
122 | | { CF_DIGEST("SHA3-224"), EVP_sha3_224() }, |
123 | | { CF_DIGEST("SHA3-256"), EVP_sha3_256() }, |
124 | | { CF_DIGEST("SHA3-384"), EVP_sha3_384() }, |
125 | | { CF_DIGEST("SHA3-512"), EVP_sha3_512() }, |
126 | | { CF_DIGEST("SHA512-224"), EVP_sha512_224() }, |
127 | | { CF_DIGEST("SHA512-256"), EVP_sha512_256() }, |
128 | | #endif |
129 | 3.06k | }; |
130 | | |
131 | 3.06k | if ( LUT.find(digestType.Get()) == LUT.end() ) { |
132 | 643 | return nullptr; |
133 | 643 | } |
134 | | |
135 | 2.42k | return LUT.at(digestType.Get()); |
136 | 3.06k | } |
137 | | } |
138 | | |
139 | 879 | std::optional<component::Digest> wolfCrypt_OpenSSL::OpDigest(operation::Digest& op) { |
140 | 879 | std::optional<component::Digest> ret = std::nullopt; |
141 | 879 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
142 | | |
143 | 879 | util::Multipart parts; |
144 | | |
145 | 879 | CF_EVP_MD_CTX ctx(ds); |
146 | 879 | const EVP_MD* md = nullptr; |
147 | | |
148 | | /* Initialize */ |
149 | 879 | { |
150 | 879 | parts = util::ToParts(ds, op.cleartext); |
151 | 879 | CF_CHECK_NE(md = wolfCrypt_OpenSSL_detail::toEVPMD(op.digestType), nullptr); |
152 | 598 | CF_CHECK_EQ(EVP_DigestInit_ex(ctx.GetPtr(), md, nullptr), 1); |
153 | 598 | } |
154 | | |
155 | | /* Process */ |
156 | 19.8k | for (const auto& part : parts) { |
157 | 19.8k | CF_CHECK_EQ(EVP_DigestUpdate(ctx.GetPtr(), part.first, part.second), 1); |
158 | 19.8k | } |
159 | | |
160 | | /* Finalize */ |
161 | 598 | { |
162 | 598 | unsigned int len = -1; |
163 | 598 | unsigned char md[EVP_MAX_MD_SIZE]; |
164 | 598 | CF_CHECK_EQ(EVP_DigestFinal_ex(ctx.GetPtr(), md, &len), 1); |
165 | | |
166 | 598 | ret = component::Digest(md, len); |
167 | 598 | } |
168 | | |
169 | 879 | end: |
170 | 879 | return ret; |
171 | 598 | } |
172 | | |
173 | | namespace wolfCrypt_OpenSSL_detail { |
174 | 673 | std::optional<component::MAC> OpHMAC_EVP(operation::HMAC& op, Datasource& ds) { |
175 | 673 | std::optional<component::MAC> ret = std::nullopt; |
176 | | |
177 | 673 | util::Multipart parts; |
178 | | |
179 | 673 | CF_EVP_MD_CTX ctx(ds); |
180 | 673 | const EVP_MD* md = nullptr; |
181 | 673 | EVP_PKEY *pkey = nullptr; |
182 | | |
183 | | /* Initialize */ |
184 | 673 | { |
185 | 673 | parts = util::ToParts(ds, op.cleartext); |
186 | | |
187 | 673 | CF_CHECK_NE(md = wolfCrypt_OpenSSL_detail::toEVPMD(op.digestType), nullptr); |
188 | 490 | CF_CHECK_NE(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, op.cipher.key.GetPtr(), op.cipher.key.GetSize()), nullptr); |
189 | 490 | CF_CHECK_EQ(EVP_DigestSignInit(ctx.GetPtr(), nullptr, md, nullptr, pkey), 1); |
190 | 430 | } |
191 | | |
192 | | /* Process */ |
193 | 7.11k | for (const auto& part : parts) { |
194 | 7.11k | CF_CHECK_EQ(EVP_DigestSignUpdate(ctx.GetPtr(), part.first, part.second), 1); |
195 | 6.96k | } |
196 | | |
197 | | /* Finalize */ |
198 | 274 | { |
199 | 274 | size_t len = -1; |
200 | 274 | uint8_t out[EVP_MAX_MD_SIZE]; |
201 | 274 | CF_CHECK_EQ(EVP_DigestSignFinal(ctx.GetPtr(), out, &len), 1); |
202 | | |
203 | 274 | ret = component::MAC(out, len); |
204 | 274 | } |
205 | | |
206 | 673 | end: |
207 | 673 | EVP_PKEY_free(pkey); |
208 | | |
209 | 673 | return ret; |
210 | 274 | } |
211 | | |
212 | 141 | std::optional<component::MAC> OpHMAC_HMAC(operation::HMAC& op, Datasource& ds) { |
213 | 141 | std::optional<component::MAC> ret = std::nullopt; |
214 | | |
215 | 141 | util::Multipart parts; |
216 | | |
217 | 141 | CF_HMAC_CTX ctx(ds); |
218 | 141 | const EVP_MD* md = nullptr; |
219 | | |
220 | | /* Initialize */ |
221 | 141 | { |
222 | 141 | parts = util::ToParts(ds, op.cleartext); |
223 | | /* TODO remove ? */ |
224 | 141 | HMAC_CTX_reset(ctx.GetPtr()); |
225 | 141 | CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr); |
226 | 120 | CF_CHECK_EQ(HMAC_Init_ex(ctx.GetPtr(), op.cipher.key.GetPtr(), op.cipher.key.GetSize(), md, nullptr), 1); |
227 | 93 | } |
228 | | |
229 | | /* Process */ |
230 | 4.53k | for (const auto& part : parts) { |
231 | 4.53k | CF_CHECK_EQ(HMAC_Update(ctx.GetPtr(), part.first, part.second), 1); |
232 | 4.53k | } |
233 | | |
234 | | /* Finalize */ |
235 | 93 | { |
236 | 93 | unsigned int len = -1; |
237 | 93 | uint8_t out[EVP_MAX_MD_SIZE]; |
238 | 93 | CF_CHECK_EQ(HMAC_Final(ctx.GetPtr(), out, &len), 1); |
239 | | |
240 | 93 | ret = component::MAC(out, len); |
241 | 93 | } |
242 | | |
243 | 141 | end: |
244 | 141 | return ret; |
245 | 93 | } |
246 | | } |
247 | | |
248 | 814 | std::optional<component::MAC> wolfCrypt_OpenSSL::OpHMAC(operation::HMAC& op) { |
249 | 814 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
250 | | |
251 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
252 | | if ( op.digestType.Get() == CF_DIGEST("SIPHASH64") || |
253 | | op.digestType.Get() == CF_DIGEST("SIPHASH128") ) { |
254 | | /* Not HMAC but invoking SipHash here anyway due to convenience. */ |
255 | | return OpenSSL_detail::SipHash(op); |
256 | | } |
257 | | #endif |
258 | | |
259 | 814 | bool useEVP = true; |
260 | 814 | try { |
261 | 814 | useEVP = ds.Get<bool>(); |
262 | 814 | } catch ( fuzzing::datasource::Datasource::OutOfData ) { |
263 | 182 | } |
264 | | |
265 | 814 | if ( useEVP == true ) { |
266 | 673 | #if !defined(CRYPTOFUZZ_BORINGSSL) |
267 | 673 | return wolfCrypt_OpenSSL_detail::OpHMAC_EVP(op, ds); |
268 | | #else |
269 | | return wolfCrypt_OpenSSL_detail::OpHMAC_HMAC(op, ds); |
270 | | #endif |
271 | 673 | } else { |
272 | 141 | #if !defined(CRYPTOFUZZ_OPENSSL_102) |
273 | 141 | return wolfCrypt_OpenSSL_detail::OpHMAC_HMAC(op, ds); |
274 | | #else |
275 | | return wolfCrypt_OpenSSL_detail::OpHMAC_EVP(op, ds); |
276 | | #endif |
277 | 141 | } |
278 | | |
279 | 0 | return {}; |
280 | 814 | } |
281 | | |
282 | | namespace wolfCrypt_OpenSSL_detail { |
283 | | |
284 | 5.88k | const EVP_CIPHER* toEVPCIPHER(const component::SymmetricCipherType cipherType) { |
285 | 5.88k | using fuzzing::datasource::ID; |
286 | | |
287 | 5.88k | switch ( cipherType.Get() ) { |
288 | 410 | case CF_CIPHER("AES_128_CBC"): |
289 | 410 | return EVP_aes_128_cbc(); |
290 | 199 | case CF_CIPHER("AES_128_CFB1"): |
291 | 199 | return EVP_aes_128_cfb1(); |
292 | 95 | case CF_CIPHER("AES_128_CFB8"): |
293 | 95 | return EVP_aes_128_cfb8(); |
294 | 104 | case CF_CIPHER("AES_128_CTR"): |
295 | 104 | return EVP_aes_128_ctr(); |
296 | 81 | case CF_CIPHER("AES_128_ECB"): |
297 | 81 | return EVP_aes_128_ecb(); |
298 | 452 | case CF_CIPHER("AES_128_GCM"): |
299 | 452 | return EVP_aes_128_gcm(); |
300 | 224 | case CF_CIPHER("AES_128_OFB"): |
301 | 224 | return EVP_aes_128_ofb(); |
302 | 228 | case CF_CIPHER("AES_128_XTS"): |
303 | 228 | return EVP_aes_128_xts(); |
304 | 146 | case CF_CIPHER("AES_192_CBC"): |
305 | 146 | return EVP_aes_192_cbc(); |
306 | 46 | case CF_CIPHER("AES_192_CFB1"): |
307 | 46 | return EVP_aes_192_cfb1(); |
308 | 153 | case CF_CIPHER("AES_192_CFB8"): |
309 | 153 | return EVP_aes_192_cfb8(); |
310 | 246 | case CF_CIPHER("AES_192_CTR"): |
311 | 246 | return EVP_aes_192_ctr(); |
312 | 99 | case CF_CIPHER("AES_192_ECB"): |
313 | 99 | return EVP_aes_192_ecb(); |
314 | 232 | case CF_CIPHER("AES_192_GCM"): |
315 | 232 | return EVP_aes_192_gcm(); |
316 | 137 | case CF_CIPHER("AES_192_OFB"): |
317 | 137 | return EVP_aes_192_ofb(); |
318 | 151 | case CF_CIPHER("AES_256_CBC"): |
319 | 151 | return EVP_aes_256_cbc(); |
320 | 144 | case CF_CIPHER("AES_256_CFB1"): |
321 | 144 | return EVP_aes_256_cfb1(); |
322 | 109 | case CF_CIPHER("AES_256_CFB8"): |
323 | 109 | return EVP_aes_256_cfb8(); |
324 | 92 | case CF_CIPHER("AES_256_CTR"): |
325 | 92 | return EVP_aes_256_ctr(); |
326 | 43 | case CF_CIPHER("AES_256_ECB"): |
327 | 43 | return EVP_aes_256_ecb(); |
328 | 585 | case CF_CIPHER("AES_256_GCM"): |
329 | 585 | return EVP_aes_256_gcm(); |
330 | 186 | case CF_CIPHER("AES_256_OFB"): |
331 | 186 | return EVP_aes_256_ofb(); |
332 | 142 | case CF_CIPHER("AES_256_XTS"): |
333 | 142 | return EVP_aes_256_xts(); |
334 | 267 | case CF_CIPHER("DES_CBC"): |
335 | 267 | return EVP_des_cbc(); |
336 | 431 | case CF_CIPHER("DES_ECB"): |
337 | 431 | return EVP_des_ecb(); |
338 | 113 | case CF_CIPHER("DES_EDE3_CBC"): |
339 | 113 | return EVP_des_ede3_cbc(); |
340 | 62 | case CF_CIPHER("RC4"): |
341 | 62 | return EVP_rc4(); |
342 | 704 | default: |
343 | 704 | return nullptr; |
344 | 5.88k | } |
345 | 5.88k | } |
346 | | |
347 | 1.30k | inline bool isAEAD(const EVP_CIPHER* ctx) { |
348 | 1.30k | return (EVP_CIPHER_flags(ctx) & EVP_CIPH_GCM_MODE) == EVP_CIPH_GCM_MODE; |
349 | 1.30k | } |
350 | | |
351 | 4.55k | bool checkSetIVLength(const uint64_t cipherType, const EVP_CIPHER* cipher, EVP_CIPHER_CTX* ctx, const size_t inputIvLength) { |
352 | 4.55k | bool ret = false; |
353 | | |
354 | 4.55k | const size_t ivLength = EVP_CIPHER_iv_length(cipher); |
355 | 4.55k | const bool ivLengthMismatch = ivLength != inputIvLength; |
356 | | |
357 | 4.55k | return !ivLengthMismatch; |
358 | 0 | if ( isAEAD(cipher) == false ) { |
359 | | /* Return true (success) if input IV length is expected IV length */ |
360 | 0 | return !ivLengthMismatch; |
361 | 0 | } |
362 | | |
363 | 0 | const bool isCCM = repository::IsCCM( cipherType ); |
364 | | |
365 | | /* Only AEAD ciphers past this point */ |
366 | | |
367 | | /* EVP_CIPHER_iv_length may return the wrong default IV length for CCM ciphers. |
368 | | * Eg. EVP_CIPHER_iv_length returns 12 for EVP_aes_128_ccm() even though the |
369 | | * IV length is actually. |
370 | | * |
371 | | * Hence, with CCM ciphers set the desired IV length always. |
372 | | */ |
373 | |
|
374 | 0 | if ( isCCM || ivLengthMismatch ) { |
375 | 0 | CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, inputIvLength, nullptr), 1); |
376 | 0 | } |
377 | | |
378 | 0 | ret = true; |
379 | 0 | end: |
380 | |
|
381 | 0 | return ret; |
382 | 0 | } |
383 | | |
384 | 4.05k | bool checkSetKeyLength(const EVP_CIPHER* cipher, EVP_CIPHER_CTX* ctx, const size_t inputKeyLength) { |
385 | 4.05k | (void)ctx; |
386 | | |
387 | 4.05k | bool ret = false; |
388 | | |
389 | 4.05k | const size_t keyLength = EVP_CIPHER_key_length(cipher); |
390 | 4.05k | if ( keyLength != inputKeyLength ) { |
391 | 190 | return false; |
392 | 0 | CF_CHECK_EQ(EVP_CIPHER_CTX_set_key_length(ctx, inputKeyLength), 1); |
393 | 0 | } |
394 | | |
395 | 3.86k | ret = true; |
396 | | |
397 | 3.86k | end: |
398 | 3.86k | return ret; |
399 | 3.86k | } |
400 | | |
401 | 2.68k | std::optional<component::Ciphertext> OpSymmetricEncrypt_EVP(operation::SymmetricEncrypt& op, Datasource& ds) { |
402 | 2.68k | std::optional<component::Ciphertext> ret = std::nullopt; |
403 | | |
404 | 2.68k | util::Multipart partsCleartext, partsAAD; |
405 | | |
406 | 2.68k | const EVP_CIPHER* cipher = nullptr; |
407 | 2.68k | CF_EVP_CIPHER_CTX ctx(ds); |
408 | | |
409 | 2.68k | size_t out_size = op.ciphertextSize; |
410 | 2.68k | size_t outIdx = 0; |
411 | 2.68k | uint8_t* out = util::malloc(out_size); |
412 | 2.68k | uint8_t* outTag = op.tagSize != std::nullopt ? util::malloc(*op.tagSize) : nullptr; |
413 | | |
414 | | /* Initialize */ |
415 | 2.68k | { |
416 | 2.68k | CF_CHECK_NE(cipher = wolfCrypt_OpenSSL_detail::toEVPCIPHER(op.cipher.cipherType), nullptr); |
417 | 2.35k | if ( op.tagSize != std::nullopt || op.aad != std::nullopt ) { |
418 | | /* Trying to treat non-AEAD with AEAD-specific features (tag, aad) |
419 | | * leads to all kinds of gnarly memory bugs in OpenSSL. |
420 | | * It is quite arguably misuse of the OpenSSL API, so don't do this. |
421 | | */ |
422 | 743 | CF_CHECK_EQ(isAEAD(cipher), true); |
423 | 665 | } |
424 | | |
425 | 2.27k | CF_CHECK_EQ(EVP_EncryptInit_ex(ctx.GetPtr(), cipher, nullptr, nullptr, nullptr), 1); |
426 | | |
427 | | /* Must be a multiple of the block size of this cipher */ |
428 | | //CF_CHECK_EQ(op.cleartext.GetSize() % EVP_CIPHER_block_size(cipher), 0); |
429 | | |
430 | | /* Convert cleartext to parts */ |
431 | 2.27k | partsCleartext = util::CipherInputTransform(ds, op.cipher.cipherType, out, out_size, op.cleartext.GetPtr(), op.cleartext.GetSize()); |
432 | | |
433 | 2.27k | if ( op.aad != std::nullopt ) { |
434 | 325 | if ( repository::IsCCM( op.cipher.cipherType.Get() ) ) { |
435 | | /* CCM does not support chunked AAD updating. |
436 | | * See: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_CCM_mode |
437 | | */ |
438 | 0 | partsAAD = { {op.aad->GetPtr(), op.aad->GetSize()} }; |
439 | 325 | } else { |
440 | 325 | partsAAD = util::ToParts(ds, *(op.aad)); |
441 | 325 | } |
442 | 325 | } |
443 | | |
444 | 2.27k | if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) { |
445 | 2.27k | CF_CHECK_EQ(checkSetIVLength(op.cipher.cipherType.Get(), cipher, ctx.GetPtr(), op.cipher.iv.GetSize()), true); |
446 | 2.02k | } else { |
447 | 0 | CF_CHECK_EQ(op.cipher.iv.GetSize(), 12); |
448 | 0 | } |
449 | 2.02k | CF_CHECK_EQ(checkSetKeyLength(cipher, ctx.GetPtr(), op.cipher.key.GetSize()), true); |
450 | | |
451 | 1.92k | if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) { |
452 | 1.92k | CF_CHECK_EQ(EVP_EncryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), op.cipher.iv.GetPtr()), 1); |
453 | 1.92k | } else { |
454 | | /* Prepend the 32 bit counter (which is 0) to the iv */ |
455 | 0 | uint8_t cc20IV[16]; |
456 | 0 | memset(cc20IV, 0, 4); |
457 | 0 | memcpy(cc20IV + 4, op.cipher.iv.GetPtr(), op.cipher.iv.GetSize()); |
458 | 0 | CF_CHECK_EQ(EVP_EncryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), cc20IV), 1); |
459 | 0 | } |
460 | | |
461 | | /* Disable ECB padding for consistency with mbed TLS */ |
462 | 1.92k | if ( repository::IsECB(op.cipher.cipherType.Get()) ) { |
463 | 299 | CF_CHECK_EQ(EVP_CIPHER_CTX_set_padding(ctx.GetPtr(), 0), 1); |
464 | 299 | } |
465 | 1.92k | } |
466 | | |
467 | | /* Process */ |
468 | 1.92k | { |
469 | | /* If the cipher is CCM, the total cleartext size needs to be indicated explicitly |
470 | | * https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption |
471 | | */ |
472 | 1.92k | if ( repository::IsCCM(op.cipher.cipherType.Get()) == true ) { |
473 | 0 | int len; |
474 | 0 | CF_CHECK_EQ(EVP_EncryptUpdate(ctx.GetPtr(), nullptr, &len, nullptr, op.cleartext.GetSize()), 1); |
475 | 0 | } |
476 | | |
477 | | /* Set AAD */ |
478 | 1.92k | if ( op.aad != std::nullopt ) { |
479 | 232 | for (const auto& part : partsAAD) { |
480 | 232 | int len; |
481 | 232 | CF_CHECK_EQ(EVP_EncryptUpdate(ctx.GetPtr(), nullptr, &len, part.first, part.second), 1); |
482 | 232 | } |
483 | 230 | } |
484 | | |
485 | 39.3k | for (const auto& part : partsCleartext) { |
486 | | /* "the amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1)" */ |
487 | 39.3k | CF_CHECK_GTE(out_size, part.second + EVP_CIPHER_block_size(cipher) - 1); |
488 | | |
489 | 39.2k | int len = -1; |
490 | 39.2k | CF_CHECK_EQ(EVP_EncryptUpdate(ctx.GetPtr(), out + outIdx, &len, part.first, part.second), 1); |
491 | 39.2k | outIdx += len; |
492 | 39.2k | out_size -= len; |
493 | 39.2k | } |
494 | 1.92k | } |
495 | | |
496 | | /* Finalize */ |
497 | 1.76k | { |
498 | 1.76k | CF_CHECK_GTE(out_size, static_cast<size_t>(EVP_CIPHER_block_size(cipher))); |
499 | | |
500 | 1.74k | int len = -1; |
501 | 1.74k | CF_CHECK_EQ(EVP_EncryptFinal_ex(ctx.GetPtr(), out + outIdx, &len), 1); |
502 | 1.68k | outIdx += len; |
503 | | |
504 | 1.68k | if ( op.tagSize != std::nullopt ) { |
505 | | /* Get tag. |
506 | | * |
507 | | * See comments around EVP_CTRL_AEAD_SET_TAG in OpSymmetricDecrypt_EVP for reasons |
508 | | * as to why this is disabled for LibreSSL. |
509 | | */ |
510 | 552 | CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx.GetPtr(), EVP_CTRL_AEAD_GET_TAG, *op.tagSize, outTag), 1); |
511 | 227 | ret = component::Ciphertext(Buffer(out, outIdx), Buffer(outTag, *op.tagSize)); |
512 | 1.13k | } else { |
513 | 1.13k | ret = component::Ciphertext(Buffer(out, outIdx)); |
514 | 1.13k | } |
515 | 1.68k | } |
516 | | |
517 | 2.68k | end: |
518 | | |
519 | 2.68k | util::free(out); |
520 | 2.68k | util::free(outTag); |
521 | | |
522 | 2.68k | return ret; |
523 | 1.68k | } |
524 | | |
525 | | } |
526 | | |
527 | 2.68k | std::optional<component::Ciphertext> wolfCrypt_OpenSSL::OpSymmetricEncrypt(operation::SymmetricEncrypt& op) { |
528 | 2.68k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
529 | 2.68k | return wolfCrypt_OpenSSL_detail::OpSymmetricEncrypt_EVP(op, ds); |
530 | 2.68k | } |
531 | | |
532 | | namespace wolfCrypt_OpenSSL_detail { |
533 | | |
534 | 2.47k | std::optional<component::Cleartext> OpSymmetricDecrypt_EVP(operation::SymmetricDecrypt& op, Datasource& ds) { |
535 | 2.47k | std::optional<component::Cleartext> ret = std::nullopt; |
536 | | |
537 | 2.47k | util::Multipart partsCiphertext, partsAAD; |
538 | | |
539 | 2.47k | const EVP_CIPHER* cipher = nullptr; |
540 | 2.47k | CF_EVP_CIPHER_CTX ctx(ds); |
541 | | |
542 | 2.47k | size_t out_size = op.cleartextSize; |
543 | 2.47k | size_t outIdx = 0; |
544 | 2.47k | uint8_t* out = util::malloc(out_size); |
545 | | |
546 | | /* Initialize */ |
547 | 2.47k | { |
548 | 2.47k | CF_CHECK_NE(cipher = toEVPCIPHER(op.cipher.cipherType), nullptr); |
549 | 2.34k | if ( op.tag != std::nullopt || op.aad != std::nullopt ) { |
550 | | /* Trying to treat non-AEAD with AEAD-specific features (tag, aad) |
551 | | * leads to all kinds of gnarly memory bugs in OpenSSL. |
552 | | * It is quite arguably misuse of the OpenSSL API, so don't do this. |
553 | | */ |
554 | 561 | CF_CHECK_EQ(isAEAD(cipher), true); |
555 | 504 | } |
556 | 2.28k | CF_CHECK_EQ(EVP_DecryptInit_ex(ctx.GetPtr(), cipher, nullptr, nullptr, nullptr), 1); |
557 | | |
558 | | /* Must be a multiple of the block size of this cipher */ |
559 | | //CF_CHECK_EQ(op.ciphertext.GetSize() % EVP_CIPHER_block_size(cipher), 0); |
560 | | |
561 | | /* Convert ciphertext to parts */ |
562 | | //partsCiphertext = util::CipherInputTransform(ds, op.cipher.cipherType, out, out_size, op.ciphertext.GetPtr(), op.ciphertext.GetSize()); |
563 | 2.28k | partsCiphertext = { {op.ciphertext.GetPtr(), op.ciphertext.GetSize()} }; |
564 | | |
565 | 2.28k | if ( op.aad != std::nullopt ) { |
566 | 285 | if ( repository::IsCCM( op.cipher.cipherType.Get() ) ) { |
567 | | /* CCM does not support chunked AAD updating. |
568 | | * See: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_CCM_mode |
569 | | */ |
570 | 0 | partsAAD = { {op.aad->GetPtr(), op.aad->GetSize()} }; |
571 | 285 | } else { |
572 | 285 | partsAAD = util::ToParts(ds, *(op.aad)); |
573 | 285 | } |
574 | 285 | } |
575 | | |
576 | 2.28k | if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) { |
577 | 2.28k | CF_CHECK_EQ(checkSetIVLength(op.cipher.cipherType.Get(), cipher, ctx.GetPtr(), op.cipher.iv.GetSize()), true); |
578 | 2.03k | } else { |
579 | 0 | CF_CHECK_EQ(op.cipher.iv.GetSize(), 12); |
580 | 0 | } |
581 | 2.03k | CF_CHECK_EQ(checkSetKeyLength(cipher, ctx.GetPtr(), op.cipher.key.GetSize()), true); |
582 | | |
583 | 1.93k | if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) { |
584 | 1.93k | CF_CHECK_EQ(EVP_DecryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), op.cipher.iv.GetPtr()), 1); |
585 | 1.93k | } else { |
586 | | /* Prepend the 32 bit counter (which is 0) to the iv */ |
587 | 0 | uint8_t cc20IV[16]; |
588 | 0 | memset(cc20IV, 0, 4); |
589 | 0 | memcpy(cc20IV + 4, op.cipher.iv.GetPtr(), op.cipher.iv.GetSize()); |
590 | 0 | CF_CHECK_EQ(EVP_DecryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), cc20IV), 1); |
591 | 0 | } |
592 | | |
593 | | /* Disable ECB padding for consistency with mbed TLS */ |
594 | 1.93k | if ( repository::IsECB(op.cipher.cipherType.Get()) ) { |
595 | 233 | CF_CHECK_EQ(EVP_CIPHER_CTX_set_padding(ctx.GetPtr(), 0), 1); |
596 | 233 | } |
597 | 1.93k | } |
598 | | |
599 | | /* Process */ |
600 | 1.93k | { |
601 | | /* If the cipher is CCM, the total cleartext size needs to be indicated explicitly |
602 | | * https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption |
603 | | */ |
604 | 1.93k | if ( repository::IsCCM(op.cipher.cipherType.Get()) == true ) { |
605 | 0 | int len; |
606 | 0 | CF_CHECK_EQ(EVP_DecryptUpdate(ctx.GetPtr(), nullptr, &len, nullptr, op.ciphertext.GetSize()), 1); |
607 | 0 | } |
608 | | |
609 | | /* Set AAD */ |
610 | 1.93k | if ( op.aad != std::nullopt ) { |
611 | 2.96k | for (const auto& part : partsAAD) { |
612 | 2.96k | int len; |
613 | 2.96k | CF_CHECK_EQ(EVP_DecryptUpdate(ctx.GetPtr(), nullptr, &len, part.first, part.second), 1); |
614 | 2.96k | } |
615 | 184 | } |
616 | | |
617 | | /* Set ciphertext */ |
618 | 1.93k | for (const auto& part : partsCiphertext) { |
619 | 1.93k | CF_CHECK_GTE(out_size, part.second + EVP_CIPHER_block_size(cipher)); |
620 | | |
621 | 1.87k | int len = -1; |
622 | 1.87k | CF_CHECK_EQ(EVP_DecryptUpdate(ctx.GetPtr(), out + outIdx, &len, part.first, part.second), 1); |
623 | | |
624 | 1.87k | outIdx += len; |
625 | 1.87k | out_size -= len; |
626 | 1.87k | } |
627 | | |
628 | 1.87k | if ( op.tag != std::nullopt ) { |
629 | 267 | CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx.GetPtr(), EVP_CTRL_AEAD_SET_TAG, op.tag->GetSize(), (void*)op.tag->GetPtr()), 1); |
630 | 238 | } |
631 | 1.87k | } |
632 | | |
633 | | /* Finalize */ |
634 | 1.84k | { |
635 | 1.84k | CF_CHECK_GTE(out_size, static_cast<size_t>(EVP_CIPHER_block_size(cipher))); |
636 | | |
637 | 1.84k | int len = -1; |
638 | 1.84k | CF_CHECK_EQ(EVP_DecryptFinal_ex(ctx.GetPtr(), out + outIdx, &len), 1); |
639 | 1.51k | outIdx += len; |
640 | | |
641 | 1.51k | ret = component::Cleartext(out, outIdx); |
642 | 1.51k | } |
643 | | |
644 | 2.47k | end: |
645 | | |
646 | 2.47k | util::free(out); |
647 | | |
648 | 2.47k | return ret; |
649 | 1.51k | } |
650 | | |
651 | | } |
652 | | |
653 | 2.47k | std::optional<component::Cleartext> wolfCrypt_OpenSSL::OpSymmetricDecrypt(operation::SymmetricDecrypt& op) { |
654 | 2.47k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
655 | 2.47k | return wolfCrypt_OpenSSL_detail::OpSymmetricDecrypt_EVP(op, ds); |
656 | 2.47k | } |
657 | | |
658 | 715 | std::optional<component::MAC> wolfCrypt_OpenSSL::OpCMAC(operation::CMAC& op) { |
659 | 715 | std::optional<component::MAC> ret = std::nullopt; |
660 | 715 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
661 | | |
662 | 715 | util::Multipart parts; |
663 | | |
664 | 715 | CF_CMAC_CTX ctx(ds); |
665 | 715 | const EVP_CIPHER* cipher = nullptr; |
666 | | |
667 | | /* Initialize */ |
668 | 715 | { |
669 | 715 | parts = util::ToParts(ds, op.cleartext); |
670 | | |
671 | 715 | CF_CHECK_NE(cipher = wolfCrypt_OpenSSL_detail::toEVPCIPHER(op.cipher.cipherType), nullptr); |
672 | 484 | CF_CHECK_EQ(CMAC_Init(ctx.GetPtr(), op.cipher.key.GetPtr(), op.cipher.key.GetSize(), cipher, nullptr), 1); |
673 | 264 | } |
674 | | |
675 | | /* Process */ |
676 | 3.62k | for (const auto& part : parts) { |
677 | 3.62k | CF_CHECK_EQ(CMAC_Update(ctx.GetPtr(), part.first, part.second), 1); |
678 | 3.62k | } |
679 | | |
680 | | /* Finalize */ |
681 | 264 | { |
682 | 264 | size_t len = 0; |
683 | 264 | uint8_t out[EVP_MAX_MD_SIZE]; |
684 | 264 | CF_CHECK_EQ(CMAC_Final(ctx.GetPtr(), out, &len), 1); |
685 | 264 | ret = component::MAC(out, len); |
686 | 264 | } |
687 | | |
688 | 715 | end: |
689 | 715 | return ret; |
690 | 264 | } |
691 | | |
692 | 818 | std::optional<component::Key> wolfCrypt_OpenSSL::OpKDF_HKDF(operation::KDF_HKDF& op) { |
693 | 818 | std::optional<component::Key> ret = std::nullopt; |
694 | 818 | EVP_PKEY_CTX* pctx = nullptr; |
695 | 818 | const EVP_MD* md = nullptr; |
696 | | |
697 | 818 | size_t out_size = op.keySize; |
698 | 818 | uint8_t* out = util::malloc(out_size); |
699 | | |
700 | | /* Initialize */ |
701 | 818 | { |
702 | 818 | CF_CHECK_NE(md = wolfCrypt_OpenSSL_detail::toEVPMD(op.digestType), nullptr); |
703 | 737 | CF_CHECK_NE(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr), nullptr); |
704 | 737 | CF_CHECK_EQ(EVP_PKEY_derive_init(pctx), 1); |
705 | 737 | CF_CHECK_EQ(EVP_PKEY_CTX_set_hkdf_md(pctx, md), 1); |
706 | 737 | CF_CHECK_EQ(EVP_PKEY_CTX_set1_hkdf_key(pctx, op.password.GetPtr(), op.password.GetSize()), 1); |
707 | 559 | CF_CHECK_EQ(EVP_PKEY_CTX_set1_hkdf_salt(pctx, op.salt.GetPtr(), op.salt.GetSize()), 1); |
708 | 559 | CF_CHECK_EQ(EVP_PKEY_CTX_add1_hkdf_info(pctx, op.info.GetPtr(), op.info.GetSize()), 1); |
709 | 559 | } |
710 | | |
711 | | /* Process/finalize */ |
712 | 0 | { |
713 | 559 | CF_CHECK_EQ(EVP_PKEY_derive(pctx, out, &out_size) , 1); |
714 | | |
715 | 344 | CF_CHECK_NE(out, nullptr); |
716 | | |
717 | 344 | ret = component::Key(out, out_size); |
718 | 344 | } |
719 | | |
720 | 818 | end: |
721 | 818 | EVP_PKEY_CTX_free(pctx); |
722 | | |
723 | 818 | util::free(out); |
724 | | |
725 | 818 | return ret; |
726 | 344 | } |
727 | | |
728 | 552 | std::optional<component::Key> wolfCrypt_OpenSSL::OpKDF_PBKDF2(operation::KDF_PBKDF2& op) { |
729 | 552 | std::optional<component::Key> ret = std::nullopt; |
730 | 552 | const EVP_MD* md = nullptr; |
731 | | |
732 | 552 | const size_t outSize = op.keySize; |
733 | 552 | uint8_t* out = util::malloc(outSize); |
734 | | |
735 | 552 | CF_CHECK_NE(md = wolfCrypt_OpenSSL_detail::toEVPMD(op.digestType), nullptr); |
736 | 438 | CF_CHECK_EQ(PKCS5_PBKDF2_HMAC( |
737 | 438 | (const char*)(op.password.GetPtr()), |
738 | 438 | op.password.GetSize(), |
739 | 438 | op.salt.GetPtr(), |
740 | 438 | op.salt.GetSize(), |
741 | 438 | op.iterations, |
742 | 438 | md, |
743 | 438 | outSize, |
744 | 438 | out), 1); |
745 | | |
746 | 361 | ret = component::Key(out, outSize); |
747 | 552 | end: |
748 | 552 | util::free(out); |
749 | | |
750 | 552 | return ret; |
751 | 361 | } |
752 | | |
753 | 3.20k | static std::optional<int> toCurveNID(const component::CurveType& curveType) { |
754 | 3.20k | static const std::map<uint64_t, int> LUT = { |
755 | 3.20k | { CF_ECC_CURVE("secp192r1"), NID_X9_62_prime192v1 }, |
756 | 3.20k | { CF_ECC_CURVE("x962_p192v2"), NID_X9_62_prime192v2 }, |
757 | 3.20k | { CF_ECC_CURVE("x962_p192v3"), NID_X9_62_prime192v3 }, |
758 | 3.20k | { CF_ECC_CURVE("x962_p239v1"), NID_X9_62_prime239v1 }, |
759 | 3.20k | { CF_ECC_CURVE("x962_p239v2"), NID_X9_62_prime239v2 }, |
760 | 3.20k | { CF_ECC_CURVE("x962_p239v3"), NID_X9_62_prime239v3 }, |
761 | 3.20k | { CF_ECC_CURVE("secp256r1"), NID_X9_62_prime256v1 }, |
762 | 3.20k | { CF_ECC_CURVE("brainpool160r1"), NID_brainpoolP160r1 }, |
763 | 3.20k | { CF_ECC_CURVE("brainpool192r1"), NID_brainpoolP192r1 }, |
764 | 3.20k | { CF_ECC_CURVE("brainpool224r1"), NID_brainpoolP224r1 }, |
765 | 3.20k | { CF_ECC_CURVE("brainpool256r1"), NID_brainpoolP256r1 }, |
766 | 3.20k | { CF_ECC_CURVE("brainpool320r1"), NID_brainpoolP320r1 }, |
767 | 3.20k | { CF_ECC_CURVE("brainpool384r1"), NID_brainpoolP384r1 }, |
768 | 3.20k | { CF_ECC_CURVE("brainpool512r1"), NID_brainpoolP512r1 }, |
769 | 3.20k | { CF_ECC_CURVE("secp112r1"), NID_secp112r1 }, |
770 | 3.20k | { CF_ECC_CURVE("secp112r2"), NID_secp112r2 }, |
771 | 3.20k | { CF_ECC_CURVE("secp128r1"), NID_secp128r1 }, |
772 | 3.20k | { CF_ECC_CURVE("secp128r2"), NID_secp128r2 }, |
773 | 3.20k | { CF_ECC_CURVE("secp160k1"), NID_secp160k1 }, |
774 | 3.20k | { CF_ECC_CURVE("secp160r1"), NID_secp160r1 }, |
775 | 3.20k | { CF_ECC_CURVE("secp160r2"), NID_secp160r2 }, |
776 | 3.20k | { CF_ECC_CURVE("secp192k1"), NID_secp192k1 }, |
777 | 3.20k | { CF_ECC_CURVE("secp224k1"), NID_secp224k1 }, |
778 | 3.20k | { CF_ECC_CURVE("secp224r1"), NID_secp224r1 }, |
779 | 3.20k | { CF_ECC_CURVE("secp256k1"), NID_secp256k1 }, |
780 | 3.20k | { CF_ECC_CURVE("secp384r1"), NID_secp384r1 }, |
781 | 3.20k | { CF_ECC_CURVE("secp521r1"), NID_secp521r1 }, |
782 | 3.20k | }; |
783 | | |
784 | 3.20k | if ( LUT.find(curveType.Get()) == LUT.end() ) { |
785 | 353 | return std::nullopt; |
786 | 353 | } |
787 | | |
788 | 2.85k | return LUT.at(curveType.Get()); |
789 | 3.20k | } |
790 | | |
791 | 261 | std::optional<bool> wolfCrypt_OpenSSL::OpECC_ValidatePubkey(operation::ECC_ValidatePubkey& op) { |
792 | 261 | std::optional<bool> ret = std::nullopt; |
793 | 261 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
794 | | |
795 | 261 | CF_EC_KEY key(ds); |
796 | 261 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
797 | | |
798 | 261 | std::unique_ptr<CF_EC_POINT> pub = nullptr; |
799 | | |
800 | 261 | { |
801 | 261 | std::optional<int> curveNID; |
802 | 261 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
803 | 204 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
804 | 204 | group->Lock(); |
805 | 204 | CF_CHECK_NE(group->GetPtr(), nullptr); |
806 | 204 | } |
807 | | |
808 | 204 | CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1); |
809 | | |
810 | | /* Construct key */ |
811 | 204 | CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
812 | 204 | CF_CHECK_TRUE(pub->Set(op.pub.first, op.pub.second)); |
813 | | |
814 | | /* Reject oversized pubkeys until it is fixed in OpenSSL |
815 | | * https://github.com/openssl/openssl/issues/17590 |
816 | | */ |
817 | | #if 0 |
818 | | { |
819 | | const auto order = cryptofuzz::repository::ECC_CurveToOrder(op.curveType.Get()); |
820 | | CF_CHECK_NE(order, std::nullopt); |
821 | | CF_CHECK_TRUE(op.pub.first.IsLessThan(*order)); |
822 | | CF_CHECK_TRUE(op.pub.second.IsLessThan(*order)); |
823 | | } |
824 | | #endif |
825 | | |
826 | 23 | ret = EC_KEY_set_public_key(key.GetPtr(), pub->GetPtr()) == 1; |
827 | 261 | end: |
828 | 261 | return ret; |
829 | 23 | } |
830 | | |
831 | 829 | std::optional<component::ECC_PublicKey> wolfCrypt_OpenSSL::OpECC_PrivateToPublic(operation::ECC_PrivateToPublic& op) { |
832 | 829 | std::optional<component::ECC_PublicKey> ret = std::nullopt; |
833 | 829 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
834 | | |
835 | 829 | char* pub_x_str = nullptr; |
836 | 829 | char* pub_y_str = nullptr; |
837 | | |
838 | 829 | try { |
839 | 829 | CF_EC_KEY key(ds); |
840 | 829 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
841 | 829 | OpenSSL_bignum::Bignum prv(ds); |
842 | 829 | std::unique_ptr<CF_EC_POINT> pub = nullptr; |
843 | 829 | OpenSSL_bignum::Bignum pub_x(ds); |
844 | 829 | OpenSSL_bignum::Bignum pub_y(ds); |
845 | | |
846 | 829 | { |
847 | 829 | std::optional<int> curveNID; |
848 | 829 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
849 | 721 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
850 | 721 | group->Lock(); |
851 | 721 | CF_CHECK_NE(group->GetPtr(), nullptr); |
852 | 721 | } |
853 | | |
854 | 721 | CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1); |
855 | | |
856 | | /* Load private key */ |
857 | 721 | CF_CHECK_EQ(prv.Set(op.priv.ToString(ds)), true); |
858 | | |
859 | | /* Set private key */ |
860 | 696 | CF_CHECK_EQ(EC_KEY_set_private_key(key.GetPtr(), prv.GetPtr()), 1); |
861 | | |
862 | | /* Compute public key */ |
863 | 630 | CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
864 | 630 | CF_CHECK_EQ(EC_POINT_mul(group->GetPtr(), pub->GetPtr(), prv.GetPtr(), nullptr, nullptr, nullptr), 1); |
865 | | |
866 | 582 | CF_CHECK_EQ(pub_x.New(), true); |
867 | 582 | CF_CHECK_EQ(pub_y.New(), true); |
868 | | |
869 | 582 | CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), pub->GetPtr(), pub_x.GetDestPtr(), pub_y.GetDestPtr(), nullptr), 0); |
870 | | |
871 | | /* Convert bignum x/y to strings */ |
872 | 559 | CF_CHECK_NE(pub_x_str = BN_bn2dec(pub_x.GetPtr()), nullptr); |
873 | 559 | CF_CHECK_NE(pub_y_str = BN_bn2dec(pub_y.GetPtr()), nullptr); |
874 | | |
875 | | /* Save bignum x/y */ |
876 | 559 | ret = { std::string(pub_x_str), std::string(pub_y_str) }; |
877 | 559 | } catch ( ... ) { } |
878 | | |
879 | 829 | end: |
880 | 829 | OPENSSL_free(pub_x_str); |
881 | 829 | OPENSSL_free(pub_y_str); |
882 | | |
883 | 829 | return ret; |
884 | 829 | } |
885 | | |
886 | 153 | std::optional<component::ECC_Point> wolfCrypt_OpenSSL::OpECC_Point_Add(operation::ECC_Point_Add& op) { |
887 | 153 | std::optional<component::ECC_Point> ret = std::nullopt; |
888 | 153 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
889 | | |
890 | 153 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
891 | 153 | std::unique_ptr<CF_EC_POINT> a = nullptr, b = nullptr, res = nullptr; |
892 | 153 | char* x_str = nullptr; |
893 | 153 | char* y_str = nullptr; |
894 | | |
895 | 153 | { |
896 | 153 | std::optional<int> curveNID; |
897 | 153 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
898 | 123 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
899 | 123 | group->Lock(); |
900 | 123 | CF_CHECK_NE(group->GetPtr(), nullptr); |
901 | 123 | } |
902 | | |
903 | 123 | CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
904 | 123 | CF_CHECK_TRUE(a->Set(op.a.first, op.a.second)); |
905 | | |
906 | 92 | CF_CHECK_NE(b = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
907 | 92 | CF_CHECK_TRUE(b->Set(op.b.first, op.b.second)); |
908 | | |
909 | 71 | CF_CHECK_NE(res = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
910 | | |
911 | 71 | CF_CHECK_NE(EC_POINT_add(group->GetPtr(), res->GetPtr(), a->GetPtr(), b->GetPtr(), nullptr), 0); |
912 | | |
913 | 71 | { |
914 | 71 | OpenSSL_bignum::Bignum x(ds); |
915 | 71 | OpenSSL_bignum::Bignum y(ds); |
916 | | |
917 | 71 | CF_CHECK_EQ(x.New(), true); |
918 | 71 | CF_CHECK_EQ(y.New(), true); |
919 | | |
920 | 71 | CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), res->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0); |
921 | | |
922 | | /* Convert bignum x/y to strings */ |
923 | 64 | CF_CHECK_NE(x_str = BN_bn2dec(x.GetPtr()), nullptr); |
924 | 64 | CF_CHECK_NE(y_str = BN_bn2dec(y.GetPtr()), nullptr); |
925 | | |
926 | 64 | ret = { std::string(x_str), std::string(y_str) }; |
927 | 64 | } |
928 | | |
929 | 153 | end: |
930 | 153 | OPENSSL_free(x_str); |
931 | 153 | OPENSSL_free(y_str); |
932 | | |
933 | 153 | return ret; |
934 | 64 | } |
935 | | |
936 | 251 | std::optional<component::ECC_Point> wolfCrypt_OpenSSL::OpECC_Point_Mul(operation::ECC_Point_Mul& op) { |
937 | 251 | std::optional<component::ECC_Point> ret = std::nullopt; |
938 | 251 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
939 | | |
940 | 251 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
941 | 251 | std::unique_ptr<CF_EC_POINT> a = nullptr, res = nullptr; |
942 | 251 | OpenSSL_bignum::Bignum b(ds); |
943 | 251 | char* x_str = nullptr; |
944 | 251 | char* y_str = nullptr; |
945 | | |
946 | 251 | { |
947 | 251 | std::optional<int> curveNID; |
948 | 251 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
949 | 203 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
950 | 203 | group->Lock(); |
951 | 203 | CF_CHECK_NE(group->GetPtr(), nullptr); |
952 | 203 | } |
953 | | |
954 | 203 | CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
955 | 203 | CF_CHECK_TRUE(a->Set(op.a.first, op.a.second)); |
956 | | |
957 | 146 | CF_CHECK_NE(res = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
958 | | |
959 | 146 | CF_CHECK_EQ(b.Set(op.b.ToString(ds)), true); |
960 | | |
961 | 139 | CF_CHECK_NE(EC_POINT_mul(group->GetPtr(), res->GetPtr(), nullptr, a->GetPtr(), b.GetPtr(), nullptr), 0); |
962 | | |
963 | 128 | if ( op.b.ToTrimmedString() == "0" ) { |
964 | 10 | CF_ASSERT( |
965 | 10 | EC_POINT_is_at_infinity(group->GetPtr(), res->GetPtr()) == 1, |
966 | 10 | "Point multiplication by 0 does not yield point at infinity"); |
967 | 10 | } |
968 | | |
969 | 128 | { |
970 | 128 | OpenSSL_bignum::BN_CTX ctx(ds); |
971 | | |
972 | 128 | if ( !EC_POINT_is_on_curve(group->GetPtr(), a->GetPtr(), ctx.GetPtr()) ) { |
973 | 0 | CF_ASSERT( |
974 | 0 | EC_POINT_is_on_curve(group->GetPtr(), res->GetPtr(), ctx.GetPtr()) == 0, |
975 | 0 | "Point multiplication of invalid point yields valid point"); |
976 | 0 | } |
977 | 128 | } |
978 | | |
979 | 128 | ret = res->Get(); |
980 | | |
981 | 251 | end: |
982 | 251 | OPENSSL_free(x_str); |
983 | 251 | OPENSSL_free(y_str); |
984 | | |
985 | 251 | return ret; |
986 | 128 | } |
987 | | |
988 | 244 | std::optional<component::ECC_Point> wolfCrypt_OpenSSL::OpECC_Point_Neg(operation::ECC_Point_Neg& op) { |
989 | 244 | std::optional<component::ECC_Point> ret = std::nullopt; |
990 | 244 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
991 | | |
992 | 244 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
993 | 244 | std::unique_ptr<CF_EC_POINT> a = nullptr, res = nullptr; |
994 | 244 | char* x_str = nullptr; |
995 | 244 | char* y_str = nullptr; |
996 | | |
997 | 244 | { |
998 | 244 | std::optional<int> curveNID; |
999 | 244 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
1000 | 202 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
1001 | 202 | group->Lock(); |
1002 | 202 | CF_CHECK_NE(group->GetPtr(), nullptr); |
1003 | 202 | } |
1004 | | |
1005 | 202 | CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
1006 | 202 | CF_CHECK_TRUE(a->Set(op.a.first, op.a.second)); |
1007 | | |
1008 | 39 | CF_CHECK_NE(EC_POINT_invert(group->GetPtr(), a->GetPtr(), nullptr), 0); |
1009 | | |
1010 | 39 | { |
1011 | 39 | OpenSSL_bignum::Bignum x(ds); |
1012 | 39 | OpenSSL_bignum::Bignum y(ds); |
1013 | | |
1014 | 39 | CF_CHECK_EQ(x.New(), true); |
1015 | 39 | CF_CHECK_EQ(y.New(), true); |
1016 | | |
1017 | 39 | CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), a->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0); |
1018 | | |
1019 | | /* Convert bignum x/y to strings */ |
1020 | 39 | CF_CHECK_NE(x_str = BN_bn2dec(x.GetPtr()), nullptr); |
1021 | 39 | CF_CHECK_NE(y_str = BN_bn2dec(y.GetPtr()), nullptr); |
1022 | | |
1023 | 39 | ret = { std::string(x_str), std::string(y_str) }; |
1024 | 39 | } |
1025 | | |
1026 | 244 | end: |
1027 | 244 | OPENSSL_free(x_str); |
1028 | 244 | OPENSSL_free(y_str); |
1029 | | |
1030 | 244 | return ret; |
1031 | 39 | } |
1032 | | |
1033 | 98 | std::optional<bool> wolfCrypt_OpenSSL::OpECC_Point_Cmp(operation::ECC_Point_Cmp& op) { |
1034 | 98 | std::optional<bool> ret = std::nullopt; |
1035 | 98 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1036 | | |
1037 | 98 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
1038 | 98 | std::unique_ptr<CF_EC_POINT> a = nullptr, b = nullptr; |
1039 | | |
1040 | 98 | { |
1041 | 98 | std::optional<int> curveNID; |
1042 | 98 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
1043 | 69 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
1044 | 69 | group->Lock(); |
1045 | 69 | CF_CHECK_NE(group->GetPtr(), nullptr); |
1046 | 69 | } |
1047 | | |
1048 | 69 | CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
1049 | 69 | CF_CHECK_TRUE(a->Set(op.a.first, op.a.second)); |
1050 | | |
1051 | 52 | CF_CHECK_NE(b = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
1052 | 52 | CF_CHECK_TRUE(b->Set(op.b.first, op.b.second)); |
1053 | | |
1054 | 36 | ret = EC_POINT_cmp(group->GetPtr(), a->GetPtr(), b->GetPtr(), nullptr) == 0; |
1055 | | |
1056 | 98 | end: |
1057 | | |
1058 | 98 | return ret; |
1059 | 36 | } |
1060 | | |
1061 | 717 | std::optional<bool> wolfCrypt_OpenSSL::OpECDSA_Verify(operation::ECDSA_Verify& op) { |
1062 | 717 | std::optional<bool> ret = std::nullopt; |
1063 | 717 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1064 | | |
1065 | 717 | ECDSA_SIG* signature = nullptr; |
1066 | | |
1067 | 717 | try { |
1068 | 717 | CF_EC_KEY key(ds); |
1069 | 717 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
1070 | | |
1071 | 717 | std::unique_ptr<CF_EC_POINT> pub = nullptr; |
1072 | | |
1073 | 717 | OpenSSL_bignum::Bignum sig_s(ds); |
1074 | 717 | OpenSSL_bignum::Bignum sig_r(ds); |
1075 | | |
1076 | | /* Initialize */ |
1077 | 717 | { |
1078 | 717 | { |
1079 | 717 | std::optional<int> curveNID; |
1080 | 717 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
1081 | 689 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
1082 | 689 | group->Lock(); |
1083 | 689 | CF_CHECK_NE(group->GetPtr(), nullptr); |
1084 | 689 | } |
1085 | 689 | CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1); |
1086 | | |
1087 | | /* Construct signature */ |
1088 | 689 | CF_CHECK_EQ(sig_r.Set(op.signature.signature.first.ToString(ds)), true); |
1089 | 679 | CF_CHECK_EQ(sig_s.Set(op.signature.signature.second.ToString(ds)), true); |
1090 | 669 | CF_CHECK_NE(signature = ECDSA_SIG_new(), nullptr); |
1091 | 669 | CF_CHECK_EQ(ECDSA_SIG_set0(signature, sig_r.GetDestPtr(false), sig_s.GetDestPtr(false)), 1); |
1092 | | /* 'signature' now has ownership, and the BIGNUMs will be freed by ECDSA_SIG_free */ |
1093 | 669 | sig_r.ReleaseOwnership(); |
1094 | 669 | sig_s.ReleaseOwnership(); |
1095 | | |
1096 | | /* Construct key */ |
1097 | 669 | CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
1098 | 669 | CF_CHECK_TRUE(pub->Set(op.signature.pub.first, op.signature.pub.second)); |
1099 | 656 | CF_CHECK_EQ(EC_KEY_set_public_key(key.GetPtr(), pub->GetPtr()), 1); |
1100 | 656 | } |
1101 | | |
1102 | | /* Process */ |
1103 | 0 | { |
1104 | 656 | int res; |
1105 | 656 | if ( op.digestType.Get() == CF_DIGEST("NULL") ) { |
1106 | | //const auto CT = op.cleartext.ECDSA_RandomPad(ds, op.curveType); |
1107 | 596 | const auto CT = op.cleartext; |
1108 | 596 | res = ECDSA_do_verify(CT.GetPtr(), CT.GetSize(), signature, key.GetPtr()); |
1109 | 596 | } else if ( op.digestType.Get() == CF_DIGEST("SHA256") ) { |
1110 | 36 | uint8_t CT[32]; |
1111 | 36 | SHA256(op.cleartext.GetPtr(), op.cleartext.GetSize(), CT); |
1112 | 36 | res = ECDSA_do_verify(CT, sizeof(CT), signature, key.GetPtr()); |
1113 | 36 | } else { |
1114 | | /* TODO other digests */ |
1115 | 24 | goto end; |
1116 | 24 | } |
1117 | | |
1118 | 632 | if ( res == 0 ) { |
1119 | 68 | ret = false; |
1120 | 564 | } else if ( res == 1 ) { |
1121 | 513 | ret = true; |
1122 | 513 | } else { |
1123 | | /* ECDSA_do_verify failed -- don't set ret */ |
1124 | 51 | } |
1125 | | |
1126 | 632 | } |
1127 | 632 | } catch ( ... ) { } |
1128 | | |
1129 | 717 | end: |
1130 | 717 | if ( signature != nullptr ) { |
1131 | 669 | ECDSA_SIG_free(signature); |
1132 | 669 | } |
1133 | | |
1134 | 717 | return ret; |
1135 | 717 | } |
1136 | | |
1137 | 774 | std::optional<component::ECDSA_Signature> wolfCrypt_OpenSSL::OpECDSA_Sign(operation::ECDSA_Sign& op) { |
1138 | 774 | std::optional<component::ECDSA_Signature> ret = std::nullopt; |
1139 | 774 | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1140 | | |
1141 | 774 | ECDSA_SIG* signature = nullptr; |
1142 | 774 | char* pub_x_str = nullptr; |
1143 | 774 | char* pub_y_str = nullptr; |
1144 | 774 | char* sig_r_str = nullptr; |
1145 | 774 | char* sig_s_str = nullptr; |
1146 | | |
1147 | 774 | try { |
1148 | 774 | CF_EC_KEY key(ds); |
1149 | 774 | std::shared_ptr<CF_EC_GROUP> group = nullptr; |
1150 | 774 | OpenSSL_bignum::Bignum prv(ds); |
1151 | 774 | std::unique_ptr<CF_EC_POINT> pub = nullptr; |
1152 | 774 | OpenSSL_bignum::Bignum pub_x(ds); |
1153 | 774 | OpenSSL_bignum::Bignum pub_y(ds); |
1154 | 774 | const BIGNUM *R = nullptr, *S = nullptr; |
1155 | | |
1156 | 774 | CF_CHECK_TRUE(op.UseRandomNonce()); |
1157 | 739 | CF_CHECK_TRUE(op.digestType.Is(CF_DIGEST("NULL"))); |
1158 | | |
1159 | 653 | { |
1160 | 653 | std::optional<int> curveNID; |
1161 | 653 | CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt); |
1162 | 642 | CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr); |
1163 | 642 | group->Lock(); |
1164 | 642 | CF_CHECK_NE(group->GetPtr(), nullptr); |
1165 | 642 | } |
1166 | | |
1167 | 642 | CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1); |
1168 | | |
1169 | | /* Load private key */ |
1170 | 642 | CF_CHECK_EQ(prv.Set(op.priv.ToString(ds)), true); |
1171 | | |
1172 | | /* Set private key */ |
1173 | 632 | CF_CHECK_EQ(EC_KEY_set_private_key(key.GetPtr(), prv.GetPtr()), 1); |
1174 | | |
1175 | | /* Compute public key */ |
1176 | 621 | CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group), nullptr); |
1177 | 621 | CF_CHECK_EQ(EC_POINT_mul(group->GetPtr(), pub->GetPtr(), prv.GetPtr(), nullptr, nullptr, nullptr), 1); |
1178 | | |
1179 | 611 | CF_CHECK_EQ(pub_x.New(), true); |
1180 | 611 | CF_CHECK_EQ(pub_y.New(), true); |
1181 | | |
1182 | 611 | CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), pub->GetPtr(), pub_x.GetDestPtr(), pub_y.GetDestPtr(), nullptr), 0); |
1183 | | |
1184 | 600 | CF_CHECK_NE(pub_x_str = BN_bn2dec(pub_x.GetPtr()), nullptr); |
1185 | 600 | CF_CHECK_NE(pub_y_str = BN_bn2dec(pub_y.GetPtr()), nullptr); |
1186 | | |
1187 | 600 | const auto CT = op.cleartext.ECDSA_RandomPad(ds, op.curveType); |
1188 | | |
1189 | 600 | CF_CHECK_NE(signature = ECDSA_do_sign(CT.GetPtr(), CT.GetSize(), key.GetPtr()), nullptr); |
1190 | | |
1191 | 486 | /* noret */ ECDSA_SIG_get0(signature, &R, &S); |
1192 | 486 | CF_CHECK_NE(R, nullptr); |
1193 | 486 | CF_CHECK_NE(S, nullptr); |
1194 | | |
1195 | | /* Convert bignum x/y to strings */ |
1196 | 486 | CF_CHECK_NE(sig_r_str = BN_bn2dec(R), nullptr); |
1197 | 486 | CF_CHECK_NE(sig_s_str = BN_bn2dec(S), nullptr); |
1198 | | |
1199 | | |
1200 | 486 | component::Bignum S_corrected{std::string(sig_s_str)}; |
1201 | 486 | CF_NORET(util::AdjustECDSASignature(op.curveType.Get(), S_corrected)); |
1202 | | |
1203 | 486 | ret = { {sig_r_str, S_corrected.ToTrimmedString()}, {pub_x_str, pub_y_str} }; |
1204 | 486 | } catch ( ... ) { } |
1205 | | |
1206 | 774 | end: |
1207 | 774 | if ( signature != nullptr ) { |
1208 | 486 | ECDSA_SIG_free(signature); |
1209 | 486 | } |
1210 | 774 | OPENSSL_free(pub_x_str); |
1211 | 774 | OPENSSL_free(pub_y_str); |
1212 | 774 | OPENSSL_free(sig_r_str); |
1213 | 774 | OPENSSL_free(sig_s_str); |
1214 | | |
1215 | 774 | return ret; |
1216 | 774 | } |
1217 | | |
1218 | 3.48k | std::optional<component::Bignum> wolfCrypt_OpenSSL::OpBignumCalc(operation::BignumCalc& op) { |
1219 | 3.48k | std::optional<component::Bignum> ret = std::nullopt; |
1220 | 3.48k | Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize()); |
1221 | | |
1222 | 3.48k | OpenSSL_bignum::BN_CTX ctx(ds); |
1223 | 3.48k | OpenSSL_bignum::BignumCluster bn(ds, |
1224 | 3.48k | OpenSSL_bignum::Bignum(ds), |
1225 | 3.48k | OpenSSL_bignum::Bignum(ds), |
1226 | 3.48k | OpenSSL_bignum::Bignum(ds), |
1227 | 3.48k | OpenSSL_bignum::Bignum(ds)); |
1228 | 3.48k | OpenSSL_bignum::Bignum res(ds); |
1229 | 3.48k | std::unique_ptr<OpenSSL_bignum::Operation> opRunner = nullptr; |
1230 | | |
1231 | 3.48k | CF_CHECK_EQ(res.New(), true); |
1232 | 3.48k | CF_CHECK_EQ(bn.New(0), true); |
1233 | 3.48k | CF_CHECK_EQ(bn.New(1), true); |
1234 | 3.48k | CF_CHECK_EQ(bn.New(2), true); |
1235 | 3.48k | CF_CHECK_EQ(bn.New(3), true); |
1236 | | |
1237 | 3.48k | CF_CHECK_EQ(res.Set("0"), true); |
1238 | 3.48k | CF_CHECK_EQ(bn.Set(0, op.bn0.ToString(ds)), true); |
1239 | 3.46k | CF_CHECK_EQ(bn.Set(1, op.bn1.ToString(ds)), true); |
1240 | 3.45k | CF_CHECK_EQ(bn.Set(2, op.bn2.ToString(ds)), true); |
1241 | 3.44k | CF_CHECK_EQ(bn.Set(3, op.bn3.ToString(ds)), true); |
1242 | | |
1243 | 3.44k | switch ( op.calcOp.Get() ) { |
1244 | 20 | case CF_CALCOP("Add(A,B)"): |
1245 | 20 | opRunner = std::make_unique<OpenSSL_bignum::Add>(); |
1246 | 20 | break; |
1247 | 29 | case CF_CALCOP("Sub(A,B)"): |
1248 | 29 | opRunner = std::make_unique<OpenSSL_bignum::Sub>(); |
1249 | 29 | break; |
1250 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1251 | | case CF_CALCOP("Mul(A,B)"): |
1252 | | opRunner = std::make_unique<OpenSSL_bignum::Mul>(); |
1253 | | break; |
1254 | | #endif |
1255 | 48 | case CF_CALCOP("Mod(A,B)"): |
1256 | 48 | opRunner = std::make_unique<OpenSSL_bignum::Mod>(); |
1257 | 48 | break; |
1258 | 321 | case CF_CALCOP("ExpMod(A,B,C)"): |
1259 | 321 | opRunner = std::make_unique<OpenSSL_bignum::ExpMod>(); |
1260 | 321 | break; |
1261 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1262 | | case CF_CALCOP("Sqr(A)"): |
1263 | | opRunner = std::make_unique<OpenSSL_bignum::Sqr>(); |
1264 | | break; |
1265 | | #endif |
1266 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1267 | | case CF_CALCOP("GCD(A,B)"): |
1268 | | opRunner = std::make_unique<OpenSSL_bignum::GCD>(); |
1269 | | break; |
1270 | | #endif |
1271 | 51 | case CF_CALCOP("AddMod(A,B,C)"): |
1272 | 51 | opRunner = std::make_unique<OpenSSL_bignum::AddMod>(); |
1273 | 51 | break; |
1274 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1275 | | case CF_CALCOP("SubMod(A,B,C)"): |
1276 | | opRunner = std::make_unique<OpenSSL_bignum::SubMod>(); |
1277 | | break; |
1278 | | #endif |
1279 | 45 | case CF_CALCOP("MulMod(A,B,C)"): |
1280 | 45 | opRunner = std::make_unique<OpenSSL_bignum::MulMod>(); |
1281 | 45 | break; |
1282 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1283 | | case CF_CALCOP("SqrMod(A,B)"): |
1284 | | opRunner = std::make_unique<OpenSSL_bignum::SqrMod>(); |
1285 | | break; |
1286 | | #endif |
1287 | 244 | case CF_CALCOP("InvMod(A,B)"): |
1288 | 244 | opRunner = std::make_unique<OpenSSL_bignum::InvMod>(); |
1289 | 244 | break; |
1290 | 37 | case CF_CALCOP("Cmp(A,B)"): |
1291 | 37 | opRunner = std::make_unique<OpenSSL_bignum::Cmp>(); |
1292 | 37 | break; |
1293 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1294 | | case CF_CALCOP("Div(A,B)"): |
1295 | | opRunner = std::make_unique<OpenSSL_bignum::Div>(); |
1296 | | break; |
1297 | | #endif |
1298 | 10 | case CF_CALCOP("IsPrime(A)"): |
1299 | 10 | opRunner = std::make_unique<OpenSSL_bignum::IsPrime>(); |
1300 | 10 | break; |
1301 | 10 | case CF_CALCOP("Sqrt(A)"): |
1302 | 10 | opRunner = std::make_unique<OpenSSL_bignum::Sqrt>(); |
1303 | 10 | break; |
1304 | 15 | case CF_CALCOP("IsNeg(A)"): |
1305 | 15 | opRunner = std::make_unique<OpenSSL_bignum::IsNeg>(); |
1306 | 15 | break; |
1307 | 8 | case CF_CALCOP("IsEq(A,B)"): |
1308 | 8 | opRunner = std::make_unique<OpenSSL_bignum::IsEq>(); |
1309 | 8 | break; |
1310 | 20 | case CF_CALCOP("IsEven(A)"): |
1311 | 20 | opRunner = std::make_unique<OpenSSL_bignum::IsEven>(); |
1312 | 20 | break; |
1313 | 20 | case CF_CALCOP("IsOdd(A)"): |
1314 | 20 | opRunner = std::make_unique<OpenSSL_bignum::IsOdd>(); |
1315 | 20 | break; |
1316 | 31 | case CF_CALCOP("IsZero(A)"): |
1317 | 31 | opRunner = std::make_unique<OpenSSL_bignum::IsZero>(); |
1318 | 31 | break; |
1319 | 31 | case CF_CALCOP("IsOne(A)"): |
1320 | 31 | opRunner = std::make_unique<OpenSSL_bignum::IsOne>(); |
1321 | 31 | break; |
1322 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1323 | | case CF_CALCOP("Jacobi(A,B)"): |
1324 | | opRunner = std::make_unique<OpenSSL_bignum::Jacobi>(); |
1325 | | break; |
1326 | | #endif |
1327 | | #if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1328 | | case CF_CALCOP("Mod_NIST_192(A)"): |
1329 | | opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_192>(); |
1330 | | break; |
1331 | | case CF_CALCOP("Mod_NIST_224(A)"): |
1332 | | opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_224>(); |
1333 | | break; |
1334 | | case CF_CALCOP("Mod_NIST_256(A)"): |
1335 | | opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_256>(); |
1336 | | break; |
1337 | | case CF_CALCOP("Mod_NIST_384(A)"): |
1338 | | opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_384>(); |
1339 | | break; |
1340 | | case CF_CALCOP("Mod_NIST_521(A)"): |
1341 | | opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_521>(); |
1342 | | break; |
1343 | | #endif |
1344 | 6 | case CF_CALCOP("SqrtMod(A,B)"): |
1345 | 6 | opRunner = std::make_unique<OpenSSL_bignum::SqrtMod>(); |
1346 | 6 | break; |
1347 | | #if defined(CRYPTOFUZZ_BORINGSSL) |
1348 | | case CF_CALCOP("LCM(A,B)"): |
1349 | | opRunner = std::make_unique<OpenSSL_bignum::LCM>(); |
1350 | | break; |
1351 | | #endif |
1352 | 6 | case CF_CALCOP("Exp(A,B)"): |
1353 | 6 | opRunner = std::make_unique<OpenSSL_bignum::Exp>(); |
1354 | 6 | break; |
1355 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1356 | | case CF_CALCOP("Abs(A)"): |
1357 | | opRunner = std::make_unique<OpenSSL_bignum::Abs>(); |
1358 | | break; |
1359 | | #endif |
1360 | 26 | case CF_CALCOP("RShift(A,B)"): |
1361 | 26 | opRunner = std::make_unique<OpenSSL_bignum::RShift>(); |
1362 | 26 | break; |
1363 | 10 | case CF_CALCOP("LShift1(A)"): |
1364 | 10 | opRunner = std::make_unique<OpenSSL_bignum::LShift1>(); |
1365 | 10 | break; |
1366 | 17 | case CF_CALCOP("SetBit(A,B)"): |
1367 | 17 | opRunner = std::make_unique<OpenSSL_bignum::SetBit>(); |
1368 | 17 | break; |
1369 | 23 | case CF_CALCOP("ClearBit(A,B)"): |
1370 | 23 | opRunner = std::make_unique<OpenSSL_bignum::ClearBit>(); |
1371 | 23 | break; |
1372 | 21 | case CF_CALCOP("Bit(A,B)"): |
1373 | 21 | opRunner = std::make_unique<OpenSSL_bignum::Bit>(); |
1374 | 21 | break; |
1375 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1376 | | case CF_CALCOP("CmpAbs(A,B)"): |
1377 | | opRunner = std::make_unique<OpenSSL_bignum::CmpAbs>(); |
1378 | | break; |
1379 | | #endif |
1380 | | #if !defined(CRYPTOFUZZ_WOLFCRYPT_OPENSSL) |
1381 | | case CF_CALCOP("ModLShift(A,B,C)"): |
1382 | | opRunner = std::make_unique<OpenSSL_bignum::ModLShift>(); |
1383 | | break; |
1384 | | #endif |
1385 | 10 | case CF_CALCOP("IsPow2(A)"): |
1386 | 10 | opRunner = std::make_unique<OpenSSL_bignum::IsPow2>(); |
1387 | 10 | break; |
1388 | 19 | case CF_CALCOP("Mask(A,B)"): |
1389 | 19 | opRunner = std::make_unique<OpenSSL_bignum::Mask>(); |
1390 | 19 | break; |
1391 | 3.44k | } |
1392 | | |
1393 | 3.44k | CF_CHECK_NE(opRunner, nullptr); |
1394 | 1.07k | CF_CHECK_EQ(opRunner->Run(ds, res, bn, ctx), true); |
1395 | | |
1396 | 638 | ret = res.ToComponentBignum(); |
1397 | | |
1398 | 3.46k | end: |
1399 | 3.46k | return ret; |
1400 | 638 | } |
1401 | | |
1402 | | } /* namespace module */ |
1403 | | } /* namespace cryptofuzz */ |