/src/wolfssl/wolfcrypt/src/signature.c
Line | Count | Source |
1 | | /* signature.c |
2 | | * |
3 | | * Copyright (C) 2006-2026 wolfSSL Inc. |
4 | | * |
5 | | * This file is part of wolfSSL. |
6 | | * |
7 | | * wolfSSL is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * wolfSSL is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
20 | | */ |
21 | | |
22 | | #include <wolfssl/wolfcrypt/libwolfssl_sources.h> |
23 | | |
24 | | #include <wolfssl/wolfcrypt/signature.h> |
25 | | #ifndef NO_ASN |
26 | | #include <wolfssl/wolfcrypt/asn.h> |
27 | | #endif |
28 | | #ifdef HAVE_ECC |
29 | | #include <wolfssl/wolfcrypt/ecc.h> |
30 | | #endif |
31 | | #ifndef NO_RSA |
32 | | #include <wolfssl/wolfcrypt/rsa.h> |
33 | | #endif |
34 | | |
35 | | /* If ECC and RSA are disabled then disable signature wrapper */ |
36 | | #if (!defined(HAVE_ECC) || (defined(HAVE_ECC) && !defined(HAVE_ECC_SIGN) \ |
37 | | && !defined(HAVE_ECC_VERIFY))) && defined(NO_RSA) |
38 | | #undef NO_SIG_WRAPPER |
39 | | #define NO_SIG_WRAPPER |
40 | | #endif |
41 | | |
42 | | /* Signature wrapper disabled check */ |
43 | | #ifndef NO_SIG_WRAPPER |
44 | | |
45 | | #if !defined(NO_RSA) && defined(NO_ASN) |
46 | | #ifndef MAX_DER_DIGEST_ASN_SZ |
47 | | #define MAX_DER_DIGEST_ASN_SZ 36 |
48 | | #endif |
49 | | /* Fallback when asn.h (which defines MAX_ENCODED_CLASSIC_SIG_SZ) is not |
50 | | * available. Sized to hold an RSA-modulus signature. */ |
51 | | #ifndef MAX_ENCODED_CLASSIC_SIG_SZ |
52 | | #define MAX_ENCODED_CLASSIC_SIG_SZ 1024 /* Supports 8192 bit keys */ |
53 | | #endif |
54 | | #endif |
55 | | |
56 | | static int wc_SignatureCheckHashStrength(enum wc_HashType hash_type) |
57 | 0 | { |
58 | 0 | int min_sz, this_sz; |
59 | |
|
60 | 0 | min_sz = wc_HashGetDigestSize(WC_SIG_MIN_HASH_TYPE); |
61 | 0 | if (min_sz < 0) { |
62 | | /* configured floor not compiled in - skip enforcement */ |
63 | 0 | return 0; |
64 | 0 | } |
65 | 0 | this_sz = wc_HashGetDigestSize(hash_type); |
66 | 0 | if (this_sz < 0) { |
67 | 0 | return this_sz; |
68 | 0 | } |
69 | 0 | if (this_sz < min_sz) { |
70 | 0 | WOLFSSL_MSG("wc_Signature*: hash weaker than WC_SIG_MIN_HASH_TYPE"); |
71 | 0 | return BAD_FUNC_ARG; |
72 | 0 | } |
73 | 0 | return 0; |
74 | 0 | } |
75 | | |
76 | | |
77 | | #if !defined(NO_RSA) && defined(WOLFSSL_CRYPTOCELL) |
78 | | extern int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig, |
79 | | RsaKey* key, CRYS_RSA_HASH_OpMode_t mode); |
80 | | extern int cc310_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, |
81 | | word32 outLen, RsaKey* key, CRYS_RSA_HASH_OpMode_t mode); |
82 | | #endif |
83 | | |
84 | | #if !defined(NO_RSA) && !defined(NO_ASN) |
85 | | static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte* hash_data, |
86 | | word32 hash_len, word32* hash_enc_len) |
87 | 0 | { |
88 | 0 | int ret, oid; |
89 | |
|
90 | 0 | ret = wc_HashGetOID(hash_type); |
91 | 0 | if (ret < 0) { |
92 | 0 | return ret; |
93 | 0 | } |
94 | 0 | oid = ret; |
95 | |
|
96 | 0 | ret = (int)wc_EncodeSignature(hash_data, hash_data, hash_len, oid); |
97 | 0 | if (ret > 0) { |
98 | 0 | *hash_enc_len = (word32)ret; |
99 | 0 | ret = 0; |
100 | 0 | } |
101 | |
|
102 | 0 | return ret; |
103 | 0 | } |
104 | | #endif /* !NO_RSA && !NO_ASN */ |
105 | | |
106 | | int wc_SignatureGetSize(enum wc_SignatureType sig_type, |
107 | | const void* key, word32 key_len) |
108 | 0 | { |
109 | 0 | int sig_len = WC_NO_ERR_TRACE(BAD_FUNC_ARG); |
110 | | |
111 | | /* Suppress possible unused args if all signature types are disabled */ |
112 | 0 | (void)key; |
113 | 0 | (void)key_len; |
114 | |
|
115 | 0 | switch(sig_type) { |
116 | 0 | case WC_SIGNATURE_TYPE_ECC: |
117 | 0 | #ifdef HAVE_ECC |
118 | | /* Verify that key_len matches exactly sizeof(ecc_key). |
119 | | * This is a necessary but not sufficient type check: |
120 | | * the const void* API cannot verify the actual runtime |
121 | | * type of the pointed-to object. |
122 | | * Callers must pass a valid ecc_key* cast to const void*. */ |
123 | 0 | if ((size_t)key_len == sizeof(ecc_key)) { |
124 | | #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) |
125 | | sig_len = wc_ecc_sig_size((ecc_key*)(wc_ptr_t)key); |
126 | | #else |
127 | 0 | sig_len = wc_ecc_sig_size((const ecc_key*)key); |
128 | 0 | #endif |
129 | 0 | } |
130 | 0 | else { |
131 | 0 | WOLFSSL_MSG("wc_SignatureGetSize: Invalid ECC key size"); |
132 | 0 | } |
133 | | #else |
134 | | sig_len = SIG_TYPE_E; |
135 | | #endif |
136 | 0 | break; |
137 | | |
138 | 0 | case WC_SIGNATURE_TYPE_RSA_W_ENC: |
139 | 0 | case WC_SIGNATURE_TYPE_RSA: |
140 | 0 | #ifndef NO_RSA |
141 | | /* Verify that key_len matches exactly sizeof(RsaKey). |
142 | | * Same caveat as the ECC case above: size equality is necessary |
143 | | * but not sufficient; the caller must pass a valid RsaKey*. */ |
144 | 0 | if ((size_t)key_len == sizeof(RsaKey)) { |
145 | | #if defined(HAVE_SELFTEST) || (defined(HAVE_FIPS) && FIPS_VERSION3_LT(5,0,0)) |
146 | | sig_len = wc_RsaEncryptSize((RsaKey*)(wc_ptr_t)key); |
147 | | #else |
148 | 0 | sig_len = wc_RsaEncryptSize((const RsaKey*)key); |
149 | 0 | #endif |
150 | | #if defined(WOLFSSL_MICROCHIP_TA100) |
151 | | if (sig_len <= 0) { |
152 | | const RsaKey* r = (const RsaKey*)key; |
153 | | /* TA100 stores hardware-backed RSA public keys outside |
154 | | * the software mp_int fields, so use the backend's fixed |
155 | | * public-key buffer size when handles are present. */ |
156 | | if (r->rKeyH != 0 || r->uKeyH != 0) { |
157 | | sig_len = WOLFSSL_TA_KEY_TYPE_RSA_SIZE; |
158 | | } |
159 | | } |
160 | | #endif |
161 | 0 | } |
162 | 0 | else { |
163 | 0 | WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size"); |
164 | 0 | } |
165 | | #else |
166 | | sig_len = SIG_TYPE_E; |
167 | | #endif |
168 | 0 | break; |
169 | | |
170 | 0 | case WC_SIGNATURE_TYPE_NONE: |
171 | 0 | default: |
172 | 0 | sig_len = BAD_FUNC_ARG; |
173 | 0 | break; |
174 | 0 | } |
175 | 0 | return sig_len; |
176 | 0 | } |
177 | | |
178 | | int wc_SignatureVerifyHash( |
179 | | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
180 | | const byte* hash_data, word32 hash_len, |
181 | | const byte* sig, word32 sig_len, |
182 | | void* key, word32 key_len) |
183 | 0 | { |
184 | 0 | int ret; |
185 | | |
186 | | /* Check arguments */ |
187 | 0 | if (hash_data == NULL || hash_len == 0 || |
188 | 0 | sig == NULL || sig_len == 0 || |
189 | 0 | key == NULL || key_len == 0) { |
190 | 0 | return BAD_FUNC_ARG; |
191 | 0 | } |
192 | | |
193 | | /* Validate signature len (1 to max is okay) */ |
194 | 0 | if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { |
195 | 0 | WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); |
196 | 0 | return BAD_FUNC_ARG; |
197 | 0 | } |
198 | | |
199 | | /* Validate hash size */ |
200 | 0 | ret = wc_HashGetDigestSize(hash_type); |
201 | 0 | if (ret < 0) { |
202 | 0 | WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); |
203 | 0 | return ret; |
204 | 0 | } |
205 | | |
206 | 0 | #if !defined(NO_RSA) && !defined(NO_ASN) |
207 | | /* For WC_SIGNATURE_TYPE_RSA_W_ENC, we need to extract the actual size of |
208 | | * the ASN.1-encoded hash. |
209 | | */ |
210 | 0 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
211 | 0 | int hash_dec_len; |
212 | 0 | word32 idx = 0; |
213 | 0 | if (GetSequence(hash_data, &idx, &hash_dec_len, hash_len) < 0) |
214 | 0 | return ASN_PARSE_E; |
215 | | /* skip the AlgorithmIdentifier */ |
216 | 0 | if (GetSequence(hash_data, &idx, &hash_dec_len, hash_len) < 0) |
217 | 0 | return ASN_PARSE_E; |
218 | 0 | idx += (word32)hash_dec_len; |
219 | | /* now sitting at the OCTET STRING containing the digest */ |
220 | 0 | if (GetOctetString(hash_data, &idx, &hash_dec_len, hash_len) < 0) |
221 | 0 | return ASN_PARSE_E; |
222 | 0 | if (hash_dec_len != ret) |
223 | 0 | return BAD_LENGTH_E; |
224 | 0 | } |
225 | 0 | else |
226 | 0 | #endif |
227 | 0 | { |
228 | 0 | if (hash_len != (word32)ret) { |
229 | 0 | WOLFSSL_MSG("wc_SignatureVerify: Invalid hash size"); |
230 | 0 | return BAD_LENGTH_E; |
231 | 0 | } |
232 | 0 | } |
233 | | |
234 | 0 | ret = 0; |
235 | | |
236 | | /* Verify signature using hash */ |
237 | 0 | switch (sig_type) { |
238 | 0 | case WC_SIGNATURE_TYPE_ECC: |
239 | 0 | { |
240 | 0 | #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY) |
241 | 0 | int is_valid_sig = 0; |
242 | | |
243 | | /* Perform verification of signature using provided ECC key */ |
244 | 0 | do { |
245 | | #ifdef WOLFSSL_ASYNC_CRYPT |
246 | | ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, |
247 | | WC_ASYNC_FLAG_CALL_AGAIN); |
248 | | #endif |
249 | 0 | if (ret >= 0) |
250 | 0 | ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, |
251 | 0 | &is_valid_sig, (ecc_key*)key); |
252 | 0 | } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); |
253 | 0 | if (ret != 0 || is_valid_sig != 1) { |
254 | 0 | ret = SIG_VERIFY_E; |
255 | 0 | } |
256 | | #else |
257 | | ret = SIG_TYPE_E; |
258 | | #endif |
259 | 0 | break; |
260 | 0 | } |
261 | | |
262 | 0 | case WC_SIGNATURE_TYPE_RSA_W_ENC: |
263 | 0 | case WC_SIGNATURE_TYPE_RSA: |
264 | 0 | { |
265 | 0 | #ifndef NO_RSA |
266 | | #ifdef WOLFSSL_CRYPTOCELL |
267 | | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
268 | | ret = cc310_RsaSSL_Verify(hash_data, hash_len, (byte*)sig, |
269 | | (RsaKey*)key, cc310_hashModeRSA(hash_type, 0)); |
270 | | } |
271 | | else { |
272 | | ret = cc310_RsaSSL_Verify(hash_data, hash_len, (byte*)sig, |
273 | | (RsaKey*)key, cc310_hashModeRSA(hash_type, 1)); |
274 | | } |
275 | | if (ret != 0) { |
276 | | ret = SIG_VERIFY_E; |
277 | | } |
278 | | #else |
279 | |
|
280 | 0 | word32 plain_len = hash_len; |
281 | | #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) |
282 | | byte *plain_data; |
283 | | #else |
284 | 0 | ALIGN64 byte plain_data[MAX_ENCODED_CLASSIC_SIG_SZ]; |
285 | 0 | #endif |
286 | | |
287 | | /* Make sure the plain text output is at least key size */ |
288 | 0 | if (plain_len < sig_len) { |
289 | 0 | plain_len = sig_len; |
290 | 0 | } |
291 | | #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) |
292 | | plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
293 | | if (plain_data) |
294 | | #else |
295 | 0 | if (plain_len <= sizeof(plain_data)) |
296 | 0 | #endif |
297 | 0 | { |
298 | 0 | byte* plain_ptr = NULL; |
299 | 0 | XMEMSET(plain_data, 0, plain_len); |
300 | 0 | XMEMCPY(plain_data, sig, sig_len); |
301 | | /* Perform verification of signature using provided RSA key */ |
302 | 0 | do { |
303 | | #ifdef WOLFSSL_ASYNC_CRYPT |
304 | | ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, |
305 | | WC_ASYNC_FLAG_CALL_AGAIN); |
306 | | #endif |
307 | 0 | if (ret >= 0) |
308 | 0 | ret = wc_RsaSSL_VerifyInline(plain_data, sig_len, |
309 | 0 | &plain_ptr, (RsaKey*)key); |
310 | 0 | } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); |
311 | 0 | if (ret >= 0 && plain_ptr) { |
312 | 0 | if ((word32)ret == hash_len && |
313 | 0 | XMEMCMP(plain_ptr, hash_data, hash_len) == 0) { |
314 | 0 | ret = 0; /* Success */ |
315 | 0 | } |
316 | 0 | else { |
317 | 0 | ret = SIG_VERIFY_E; |
318 | 0 | } |
319 | 0 | } |
320 | | #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) |
321 | | XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
322 | | #endif |
323 | 0 | } |
324 | 0 | else { |
325 | 0 | ret = MEMORY_E; |
326 | 0 | } |
327 | 0 | #endif /* WOLFSSL_CRYPTOCELL */ |
328 | 0 | if (ret != 0) { |
329 | 0 | WOLFSSL_MSG("RSA Signature Verify failed!"); |
330 | 0 | } |
331 | | #else |
332 | | ret = SIG_TYPE_E; |
333 | | #endif |
334 | 0 | break; |
335 | 0 | } |
336 | | |
337 | 0 | case WC_SIGNATURE_TYPE_NONE: |
338 | 0 | default: |
339 | 0 | ret = BAD_FUNC_ARG; |
340 | 0 | break; |
341 | 0 | } |
342 | | |
343 | 0 | return ret; |
344 | 0 | } |
345 | | |
346 | | int wc_SignatureVerify( |
347 | | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
348 | | const byte* data, word32 data_len, |
349 | | const byte* sig, word32 sig_len, |
350 | | void* key, word32 key_len) |
351 | 0 | { |
352 | 0 | int ret; |
353 | 0 | word32 hash_len, hash_enc_len; |
354 | | #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN) |
355 | | byte *hash_data; |
356 | | #else |
357 | 0 | byte hash_data[MAX_DER_DIGEST_SZ]; |
358 | 0 | #endif |
359 | | |
360 | | /* Check arguments */ |
361 | 0 | if (data == NULL || data_len == 0 || |
362 | 0 | sig == NULL || sig_len == 0 || |
363 | 0 | key == NULL || key_len == 0) { |
364 | 0 | return BAD_FUNC_ARG; |
365 | 0 | } |
366 | | |
367 | | /* Validate signature len (1 to max is okay) */ |
368 | 0 | if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { |
369 | 0 | WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); |
370 | 0 | return BAD_FUNC_ARG; |
371 | 0 | } |
372 | | |
373 | | /* Validate hash size */ |
374 | 0 | ret = wc_HashGetDigestSize(hash_type); |
375 | 0 | if (ret < 0) { |
376 | 0 | WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); |
377 | 0 | return ret; |
378 | 0 | } |
379 | 0 | hash_enc_len = hash_len = (word32)ret; |
380 | | |
381 | | /* Reject hashes weaker than WC_SIG_MIN_HASH_TYPE (default SHA-256) */ |
382 | 0 | ret = wc_SignatureCheckHashStrength(hash_type); |
383 | 0 | if (ret != 0) { |
384 | 0 | return ret; |
385 | 0 | } |
386 | | |
387 | 0 | #ifndef NO_RSA |
388 | 0 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
389 | | /* For RSA with ASN.1 encoding include room */ |
390 | 0 | hash_enc_len += MAX_DER_DIGEST_ASN_SZ; |
391 | 0 | } |
392 | 0 | #endif |
393 | |
|
394 | | #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN) |
395 | | /* Allocate temporary buffer for hash data */ |
396 | | hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
397 | | if (hash_data == NULL) { |
398 | | return MEMORY_E; |
399 | | } |
400 | | #endif |
401 | | |
402 | | /* Perform hash of data */ |
403 | 0 | ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); |
404 | 0 | if (ret == 0) { |
405 | | /* Handle RSA with DER encoding */ |
406 | 0 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
407 | | #if defined(NO_RSA) || defined(NO_ASN) |
408 | | ret = SIG_TYPE_E; |
409 | | #else |
410 | 0 | ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len, |
411 | 0 | &hash_enc_len); |
412 | 0 | #endif |
413 | 0 | } |
414 | |
|
415 | 0 | if (ret == 0) { |
416 | | /* Verify signature using hash */ |
417 | 0 | ret = wc_SignatureVerifyHash(hash_type, sig_type, |
418 | 0 | hash_data, hash_enc_len, sig, sig_len, key, key_len); |
419 | 0 | } |
420 | 0 | } |
421 | |
|
422 | | #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN) |
423 | | XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
424 | | #endif |
425 | |
|
426 | 0 | return ret; |
427 | 0 | } |
428 | | |
429 | | |
430 | | int wc_SignatureGenerateHash( |
431 | | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
432 | | const byte* hash_data, word32 hash_len, |
433 | | byte* sig, word32 *sig_len, |
434 | | void* key, word32 key_len, WC_RNG* rng) |
435 | 0 | { |
436 | 0 | return wc_SignatureGenerateHash_ex(hash_type, sig_type, hash_data, hash_len, |
437 | 0 | sig, sig_len, key, key_len, rng, 1); |
438 | 0 | } |
439 | | |
440 | | int wc_SignatureGenerateHash_ex( |
441 | | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
442 | | const byte* hash_data, word32 hash_len, |
443 | | byte* sig, word32 *sig_len, |
444 | | void* key, word32 key_len, WC_RNG* rng, int verify) |
445 | 0 | { |
446 | 0 | int ret; |
447 | | |
448 | | /* Suppress possible unused arg if all signature types are disabled */ |
449 | 0 | (void)rng; |
450 | | |
451 | | /* Check arguments */ |
452 | 0 | if (hash_data == NULL || hash_len == 0 || |
453 | 0 | sig == NULL || sig_len == NULL || *sig_len == 0 || |
454 | 0 | key == NULL || key_len == 0) { |
455 | 0 | return BAD_FUNC_ARG; |
456 | 0 | } |
457 | | |
458 | | /* Validate signature len (needs to be at least max) */ |
459 | 0 | if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { |
460 | 0 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); |
461 | 0 | return BAD_FUNC_ARG; |
462 | 0 | } |
463 | | |
464 | | /* Validate hash size */ |
465 | 0 | ret = wc_HashGetDigestSize(hash_type); |
466 | 0 | if (ret < 0) { |
467 | 0 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); |
468 | 0 | return ret; |
469 | 0 | } |
470 | 0 | ret = 0; |
471 | | |
472 | | /* Create signature using hash as data */ |
473 | 0 | switch (sig_type) { |
474 | 0 | case WC_SIGNATURE_TYPE_ECC: |
475 | 0 | #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) |
476 | | /* Create signature using provided ECC key */ |
477 | 0 | do { |
478 | | #ifdef WOLFSSL_ASYNC_CRYPT |
479 | | ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev, |
480 | | WC_ASYNC_FLAG_CALL_AGAIN); |
481 | | #endif |
482 | 0 | if (ret >= 0) |
483 | 0 | ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, |
484 | 0 | rng, (ecc_key*)key); |
485 | 0 | } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); |
486 | | #else |
487 | | ret = SIG_TYPE_E; |
488 | | #endif |
489 | 0 | break; |
490 | | |
491 | 0 | case WC_SIGNATURE_TYPE_RSA_W_ENC: |
492 | 0 | case WC_SIGNATURE_TYPE_RSA: |
493 | 0 | #if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \ |
494 | 0 | !defined(WOLFSSL_RSA_VERIFY_ONLY) |
495 | | #ifdef WOLFSSL_CRYPTOCELL |
496 | | /* use expected signature size (incoming sig_len could be larger buffer */ |
497 | | *sig_len = wc_SignatureGetSize(sig_type, key, key_len); |
498 | | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
499 | | ret = cc310_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, |
500 | | (RsaKey*)key, cc310_hashModeRSA(hash_type, 0)); |
501 | | } |
502 | | else { |
503 | | ret = cc310_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, |
504 | | (RsaKey*)key, cc310_hashModeRSA(hash_type, 1)); |
505 | | } |
506 | | #else |
507 | | /* Create signature using provided RSA key */ |
508 | 0 | do { |
509 | | #ifdef WOLFSSL_ASYNC_CRYPT |
510 | | ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev, |
511 | | WC_ASYNC_FLAG_CALL_AGAIN); |
512 | | #endif |
513 | 0 | if (ret >= 0) |
514 | 0 | ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, |
515 | 0 | (RsaKey*)key, rng); |
516 | 0 | } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E)); |
517 | 0 | #endif /* WOLFSSL_CRYPTOCELL */ |
518 | 0 | if (ret >= 0) { |
519 | 0 | *sig_len = (word32)ret; |
520 | 0 | ret = 0; /* Success */ |
521 | 0 | } |
522 | | #else |
523 | | ret = SIG_TYPE_E; |
524 | | #endif |
525 | 0 | break; |
526 | | |
527 | 0 | case WC_SIGNATURE_TYPE_NONE: |
528 | 0 | default: |
529 | 0 | ret = BAD_FUNC_ARG; |
530 | 0 | break; |
531 | 0 | } |
532 | | |
533 | 0 | if (ret == 0 && verify) { |
534 | 0 | ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data, hash_len, |
535 | 0 | sig, *sig_len, key, key_len); |
536 | 0 | } |
537 | |
|
538 | 0 | return ret; |
539 | 0 | } |
540 | | |
541 | | int wc_SignatureGenerate( |
542 | | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
543 | | const byte* data, word32 data_len, |
544 | | byte* sig, word32 *sig_len, |
545 | | void* key, word32 key_len, WC_RNG* rng) |
546 | 0 | { |
547 | 0 | return wc_SignatureGenerate_ex(hash_type, sig_type, data, data_len, sig, |
548 | 0 | sig_len, key, key_len, rng, 1); |
549 | 0 | } |
550 | | |
551 | | int wc_SignatureGenerate_ex( |
552 | | enum wc_HashType hash_type, enum wc_SignatureType sig_type, |
553 | | const byte* data, word32 data_len, |
554 | | byte* sig, word32 *sig_len, |
555 | | void* key, word32 key_len, WC_RNG* rng, int verify) |
556 | 0 | { |
557 | 0 | int ret; |
558 | 0 | word32 hash_len, hash_enc_len; |
559 | | #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN) |
560 | | byte *hash_data; |
561 | | #else |
562 | 0 | byte hash_data[MAX_DER_DIGEST_SZ]; |
563 | 0 | #endif |
564 | | |
565 | | /* Check arguments */ |
566 | 0 | if (data == NULL || data_len == 0 || |
567 | 0 | sig == NULL || sig_len == NULL || *sig_len == 0 || |
568 | 0 | key == NULL || key_len == 0) { |
569 | 0 | return BAD_FUNC_ARG; |
570 | 0 | } |
571 | | |
572 | | /* Validate signature len (needs to be at least max) */ |
573 | 0 | if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { |
574 | 0 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); |
575 | 0 | return BAD_FUNC_ARG; |
576 | 0 | } |
577 | | |
578 | | /* Validate hash size */ |
579 | 0 | ret = wc_HashGetDigestSize(hash_type); |
580 | 0 | if (ret < 0) { |
581 | 0 | WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); |
582 | 0 | return ret; |
583 | 0 | } |
584 | 0 | hash_enc_len = hash_len = (word32)ret; |
585 | | |
586 | | /* Reject hashes weaker than WC_SIG_MIN_HASH_TYPE (default SHA-256) */ |
587 | 0 | ret = wc_SignatureCheckHashStrength(hash_type); |
588 | 0 | if (ret != 0) { |
589 | 0 | return ret; |
590 | 0 | } |
591 | | |
592 | 0 | #if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) |
593 | 0 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
594 | | /* For RSA with ASN.1 encoding include room */ |
595 | 0 | hash_enc_len += MAX_DER_DIGEST_ASN_SZ; |
596 | 0 | } |
597 | 0 | #endif |
598 | |
|
599 | | #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN) |
600 | | /* Allocate temporary buffer for hash data */ |
601 | | hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
602 | | if (hash_data == NULL) { |
603 | | return MEMORY_E; |
604 | | } |
605 | | #endif |
606 | | |
607 | | /* Perform hash of data */ |
608 | 0 | ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); |
609 | 0 | if (ret == 0) { |
610 | | /* Handle RSA with DER encoding */ |
611 | 0 | if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) { |
612 | | #if defined(NO_RSA) || defined(NO_ASN) || \ |
613 | | defined(WOLFSSL_RSA_PUBLIC_ONLY) |
614 | | ret = SIG_TYPE_E; |
615 | | #else |
616 | 0 | ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len, |
617 | 0 | &hash_enc_len); |
618 | 0 | #endif |
619 | 0 | } |
620 | 0 | if (ret == 0) { |
621 | | /* Generate signature using hash (also handles verify) */ |
622 | 0 | ret = wc_SignatureGenerateHash_ex(hash_type, sig_type, hash_data, |
623 | 0 | hash_enc_len, sig, sig_len, key, key_len, rng, verify); |
624 | 0 | } |
625 | 0 | } |
626 | |
|
627 | | #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN) |
628 | | XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); |
629 | | #endif |
630 | |
|
631 | 0 | return ret; |
632 | 0 | } |
633 | | |
634 | | #endif /* NO_SIG_WRAPPER */ |