1 /* signature.c
2 *
3 * Copyright (C) 2006-2021 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 2 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
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <wolfssl/wolfcrypt/settings.h>
28 #include <wolfssl/wolfcrypt/signature.h>
29 #include <wolfssl/wolfcrypt/error-crypt.h>
30 #include <wolfssl/wolfcrypt/logging.h>
31 #ifndef NO_ASN
32 #include <wolfssl/wolfcrypt/asn.h>
33 #endif
34 #ifdef HAVE_ECC
35 #include <wolfssl/wolfcrypt/ecc.h>
36 #endif
37 #ifndef NO_RSA
38 #include <wolfssl/wolfcrypt/rsa.h>
39 #endif
40
41 /* If ECC and RSA are disabled then disable signature wrapper */
42 #if (!defined(HAVE_ECC) || (defined(HAVE_ECC) && !defined(HAVE_ECC_SIGN) \
43 && !defined(HAVE_ECC_VERIFY))) && defined(NO_RSA)
44 #undef NO_SIG_WRAPPER
45 #define NO_SIG_WRAPPER
46 #endif
47
48 /* Signature wrapper disabled check */
49 #ifndef NO_SIG_WRAPPER
50
51 #if !defined(NO_RSA) && defined(WOLFSSL_CRYPTOCELL)
52 extern int cc310_RsaSSL_Verify(const byte* in, word32 inLen, byte* sig,
53 RsaKey* key, CRYS_RSA_HASH_OpMode_t mode);
54 extern int cc310_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
55 word32 outLen, RsaKey* key, CRYS_RSA_HASH_OpMode_t mode);
56 #endif
57
58 #if !defined(NO_RSA) && !defined(NO_ASN)
wc_SignatureDerEncode(enum wc_HashType hash_type,byte * hash_data,word32 hash_len,word32 * hash_enc_len)59 static int wc_SignatureDerEncode(enum wc_HashType hash_type, byte* hash_data,
60 word32 hash_len, word32* hash_enc_len)
61 {
62 int ret, oid;
63
64 ret = wc_HashGetOID(hash_type);
65 if (ret < 0) {
66 return ret;
67 }
68 oid = ret;
69
70 ret = wc_EncodeSignature(hash_data, hash_data, hash_len, oid);
71 if (ret > 0) {
72 *hash_enc_len = ret;
73 ret = 0;
74 }
75
76 return ret;
77 }
78 #endif /* !NO_RSA && !NO_ASN */
79
wc_SignatureGetSize(enum wc_SignatureType sig_type,const void * key,word32 key_len)80 int wc_SignatureGetSize(enum wc_SignatureType sig_type,
81 const void* key, word32 key_len)
82 {
83 int sig_len = BAD_FUNC_ARG;
84
85 /* Suppress possible unused args if all signature types are disabled */
86 (void)key;
87 (void)key_len;
88
89 switch(sig_type) {
90 case WC_SIGNATURE_TYPE_ECC:
91 #ifdef HAVE_ECC
92 /* Sanity check that void* key is at least ecc_key in size */
93 if (key_len >= sizeof(ecc_key)) {
94 sig_len = wc_ecc_sig_size((ecc_key*)key);
95 }
96 else {
97 WOLFSSL_MSG("wc_SignatureGetSize: Invalid ECC key size");
98 }
99 #else
100 sig_len = SIG_TYPE_E;
101 #endif
102 break;
103
104 case WC_SIGNATURE_TYPE_RSA_W_ENC:
105 case WC_SIGNATURE_TYPE_RSA:
106 #ifndef NO_RSA
107 /* Sanity check that void* key is at least RsaKey in size */
108 if (key_len >= sizeof(RsaKey)) {
109 sig_len = wc_RsaEncryptSize((RsaKey*)key);
110 }
111 else {
112 WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size");
113 }
114 #else
115 sig_len = SIG_TYPE_E;
116 #endif
117 break;
118
119 case WC_SIGNATURE_TYPE_NONE:
120 default:
121 sig_len = BAD_FUNC_ARG;
122 break;
123 }
124 return sig_len;
125 }
126
wc_SignatureVerifyHash(enum wc_HashType hash_type,enum wc_SignatureType sig_type,const byte * hash_data,word32 hash_len,const byte * sig,word32 sig_len,const void * key,word32 key_len)127 int wc_SignatureVerifyHash(
128 enum wc_HashType hash_type, enum wc_SignatureType sig_type,
129 const byte* hash_data, word32 hash_len,
130 const byte* sig, word32 sig_len,
131 const void* key, word32 key_len)
132 {
133 int ret;
134
135 /* Check arguments */
136 if (hash_data == NULL || hash_len == 0 ||
137 sig == NULL || sig_len == 0 ||
138 key == NULL || key_len == 0) {
139 return BAD_FUNC_ARG;
140 }
141
142 /* Validate signature len (1 to max is okay) */
143 if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) {
144 WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len");
145 return BAD_FUNC_ARG;
146 }
147
148 /* Validate hash size */
149 ret = wc_HashGetDigestSize(hash_type);
150 if (ret < 0) {
151 WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len");
152 return ret;
153 }
154 ret = 0;
155
156 /* Verify signature using hash */
157 switch (sig_type) {
158 case WC_SIGNATURE_TYPE_ECC:
159 {
160 #if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY)
161 int is_valid_sig = 0;
162
163 /* Perform verification of signature using provided ECC key */
164 do {
165 #ifdef WOLFSSL_ASYNC_CRYPT
166 ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev,
167 WC_ASYNC_FLAG_CALL_AGAIN);
168 #endif
169 if (ret >= 0)
170 ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len,
171 &is_valid_sig, (ecc_key*)key);
172 } while (ret == WC_PENDING_E);
173 if (ret != 0 || is_valid_sig != 1) {
174 ret = SIG_VERIFY_E;
175 }
176 #else
177 ret = SIG_TYPE_E;
178 #endif
179 break;
180 }
181
182 case WC_SIGNATURE_TYPE_RSA_W_ENC:
183 case WC_SIGNATURE_TYPE_RSA:
184 {
185 #ifndef NO_RSA
186 #ifdef WOLFSSL_CRYPTOCELL
187 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
188 ret = cc310_RsaSSL_Verify(hash_data, hash_len, (byte*)sig,
189 (RsaKey*)key, cc310_hashModeRSA(hash_type, 0));
190 }
191 else {
192 ret = cc310_RsaSSL_Verify(hash_data, hash_len, (byte*)sig,
193 (RsaKey*)key, cc310_hashModeRSA(hash_type, 1));
194 }
195 #else
196
197 word32 plain_len = hash_len;
198 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
199 byte *plain_data;
200 #else
201 byte plain_data[MAX_ENCODED_SIG_SZ];
202 #endif
203
204 /* Make sure the plain text output is at least key size */
205 if (plain_len < sig_len) {
206 plain_len = sig_len;
207 }
208 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
209 plain_data = (byte*)XMALLOC(plain_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
210 if (plain_data)
211 #else
212 if (plain_len <= sizeof(plain_data))
213 #endif
214 {
215 byte* plain_ptr = NULL;
216 XMEMSET(plain_data, 0, plain_len);
217 XMEMCPY(plain_data, sig, sig_len);
218 /* Perform verification of signature using provided RSA key */
219 do {
220 #ifdef WOLFSSL_ASYNC_CRYPT
221 ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev,
222 WC_ASYNC_FLAG_CALL_AGAIN);
223 #endif
224 if (ret >= 0)
225 ret = wc_RsaSSL_VerifyInline(plain_data, sig_len, &plain_ptr, (RsaKey*)key);
226 } while (ret == WC_PENDING_E);
227 if (ret >= 0 && plain_ptr) {
228 if ((word32)ret == hash_len &&
229 XMEMCMP(plain_ptr, hash_data, hash_len) == 0) {
230 ret = 0; /* Success */
231 }
232 else {
233 ret = SIG_VERIFY_E;
234 }
235 }
236 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
237 XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
238 #endif
239 }
240 else {
241 ret = MEMORY_E;
242 }
243 #endif /* WOLFSSL_CRYPTOCELL */
244 if (ret != 0) {
245 WOLFSSL_MSG("RSA Signature Verify difference!");
246 ret = SIG_VERIFY_E;
247 }
248 #else
249 ret = SIG_TYPE_E;
250 #endif
251 break;
252 }
253
254 case WC_SIGNATURE_TYPE_NONE:
255 default:
256 ret = BAD_FUNC_ARG;
257 break;
258 }
259
260 return ret;
261 }
262
wc_SignatureVerify(enum wc_HashType hash_type,enum wc_SignatureType sig_type,const byte * data,word32 data_len,const byte * sig,word32 sig_len,const void * key,word32 key_len)263 int wc_SignatureVerify(
264 enum wc_HashType hash_type, enum wc_SignatureType sig_type,
265 const byte* data, word32 data_len,
266 const byte* sig, word32 sig_len,
267 const void* key, word32 key_len)
268 {
269 int ret;
270 word32 hash_len, hash_enc_len;
271 #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN)
272 byte *hash_data;
273 #else
274 byte hash_data[MAX_DER_DIGEST_SZ];
275 #endif
276
277 /* Check arguments */
278 if (data == NULL || data_len == 0 ||
279 sig == NULL || sig_len == 0 ||
280 key == NULL || key_len == 0) {
281 return BAD_FUNC_ARG;
282 }
283
284 /* Validate signature len (1 to max is okay) */
285 if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) {
286 WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len");
287 return BAD_FUNC_ARG;
288 }
289
290 /* Validate hash size */
291 ret = wc_HashGetDigestSize(hash_type);
292 if (ret < 0) {
293 WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len");
294 return ret;
295 }
296 hash_enc_len = hash_len = ret;
297
298 #ifndef NO_RSA
299 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
300 /* For RSA with ASN.1 encoding include room */
301 hash_enc_len += MAX_DER_DIGEST_ASN_SZ;
302 }
303 #endif
304
305 #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN)
306 /* Allocate temporary buffer for hash data */
307 hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
308 if (hash_data == NULL) {
309 return MEMORY_E;
310 }
311 #endif
312
313 /* Perform hash of data */
314 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);
315 if (ret == 0) {
316 /* Handle RSA with DER encoding */
317 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
318 #if defined(NO_RSA) || defined(NO_ASN)
319 ret = SIG_TYPE_E;
320 #else
321 ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,
322 &hash_enc_len);
323 #endif
324 }
325
326 if (ret == 0) {
327 /* Verify signature using hash */
328 ret = wc_SignatureVerifyHash(hash_type, sig_type,
329 hash_data, hash_enc_len, sig, sig_len, key, key_len);
330 }
331 }
332
333 #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN)
334 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
335 #endif
336
337 return ret;
338 }
339
340
wc_SignatureGenerateHash(enum wc_HashType hash_type,enum wc_SignatureType sig_type,const byte * hash_data,word32 hash_len,byte * sig,word32 * sig_len,const void * key,word32 key_len,WC_RNG * rng)341 int wc_SignatureGenerateHash(
342 enum wc_HashType hash_type, enum wc_SignatureType sig_type,
343 const byte* hash_data, word32 hash_len,
344 byte* sig, word32 *sig_len,
345 const void* key, word32 key_len, WC_RNG* rng)
346 {
347 return wc_SignatureGenerateHash_ex(hash_type, sig_type, hash_data, hash_len,
348 sig, sig_len, key, key_len, rng, 1);
349 }
350
wc_SignatureGenerateHash_ex(enum wc_HashType hash_type,enum wc_SignatureType sig_type,const byte * hash_data,word32 hash_len,byte * sig,word32 * sig_len,const void * key,word32 key_len,WC_RNG * rng,int verify)351 int wc_SignatureGenerateHash_ex(
352 enum wc_HashType hash_type, enum wc_SignatureType sig_type,
353 const byte* hash_data, word32 hash_len,
354 byte* sig, word32 *sig_len,
355 const void* key, word32 key_len, WC_RNG* rng, int verify)
356 {
357 int ret;
358
359 /* Suppress possible unused arg if all signature types are disabled */
360 (void)rng;
361
362 /* Check arguments */
363 if (hash_data == NULL || hash_len == 0 ||
364 sig == NULL || sig_len == NULL || *sig_len == 0 ||
365 key == NULL || key_len == 0) {
366 return BAD_FUNC_ARG;
367 }
368
369 /* Validate signature len (needs to be at least max) */
370 if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) {
371 WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len");
372 return BAD_FUNC_ARG;
373 }
374
375 /* Validate hash size */
376 ret = wc_HashGetDigestSize(hash_type);
377 if (ret < 0) {
378 WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len");
379 return ret;
380 }
381 ret = 0;
382
383 /* Create signature using hash as data */
384 switch (sig_type) {
385 case WC_SIGNATURE_TYPE_ECC:
386 #if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)
387 /* Create signature using provided ECC key */
388 do {
389 #ifdef WOLFSSL_ASYNC_CRYPT
390 ret = wc_AsyncWait(ret, &((ecc_key*)key)->asyncDev,
391 WC_ASYNC_FLAG_CALL_AGAIN);
392 #endif
393 if (ret >= 0)
394 ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len,
395 rng, (ecc_key*)key);
396 } while (ret == WC_PENDING_E);
397 #else
398 ret = SIG_TYPE_E;
399 #endif
400 break;
401
402 case WC_SIGNATURE_TYPE_RSA_W_ENC:
403 case WC_SIGNATURE_TYPE_RSA:
404 #if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
405 !defined(WOLFSSL_RSA_VERIFY_ONLY)
406 #ifdef WOLFSSL_CRYPTOCELL
407 /* use expected signature size (incoming sig_len could be larger buffer */
408 *sig_len = wc_SignatureGetSize(sig_type, key, key_len);
409 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
410 ret = cc310_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len,
411 (RsaKey*)key, cc310_hashModeRSA(hash_type, 0));
412 }
413 else {
414 ret = cc310_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len,
415 (RsaKey*)key, cc310_hashModeRSA(hash_type, 1));
416 }
417 #else
418 /* Create signature using provided RSA key */
419 do {
420 #ifdef WOLFSSL_ASYNC_CRYPT
421 ret = wc_AsyncWait(ret, &((RsaKey*)key)->asyncDev,
422 WC_ASYNC_FLAG_CALL_AGAIN);
423 #endif
424 if (ret >= 0)
425 ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len,
426 (RsaKey*)key, rng);
427 } while (ret == WC_PENDING_E);
428 #endif /* WOLFSSL_CRYPTOCELL */
429 if (ret >= 0) {
430 *sig_len = ret;
431 ret = 0; /* Success */
432 }
433 #else
434 ret = SIG_TYPE_E;
435 #endif
436 break;
437
438 case WC_SIGNATURE_TYPE_NONE:
439 default:
440 ret = BAD_FUNC_ARG;
441 break;
442 }
443
444 if (ret == 0 && verify) {
445 ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data, hash_len,
446 sig, *sig_len, key, key_len);
447 }
448
449 return ret;
450 }
451
wc_SignatureGenerate(enum wc_HashType hash_type,enum wc_SignatureType sig_type,const byte * data,word32 data_len,byte * sig,word32 * sig_len,const void * key,word32 key_len,WC_RNG * rng)452 int wc_SignatureGenerate(
453 enum wc_HashType hash_type, enum wc_SignatureType sig_type,
454 const byte* data, word32 data_len,
455 byte* sig, word32 *sig_len,
456 const void* key, word32 key_len, WC_RNG* rng)
457 {
458 return wc_SignatureGenerate_ex(hash_type, sig_type, data, data_len, sig,
459 sig_len, key, key_len, rng, 1);
460 }
461
wc_SignatureGenerate_ex(enum wc_HashType hash_type,enum wc_SignatureType sig_type,const byte * data,word32 data_len,byte * sig,word32 * sig_len,const void * key,word32 key_len,WC_RNG * rng,int verify)462 int wc_SignatureGenerate_ex(
463 enum wc_HashType hash_type, enum wc_SignatureType sig_type,
464 const byte* data, word32 data_len,
465 byte* sig, word32 *sig_len,
466 const void* key, word32 key_len, WC_RNG* rng, int verify)
467 {
468 int ret;
469 word32 hash_len, hash_enc_len;
470 #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN)
471 byte *hash_data;
472 #else
473 byte hash_data[MAX_DER_DIGEST_SZ];
474 #endif
475
476 /* Check arguments */
477 if (data == NULL || data_len == 0 ||
478 sig == NULL || sig_len == NULL || *sig_len == 0 ||
479 key == NULL || key_len == 0) {
480 return BAD_FUNC_ARG;
481 }
482
483 /* Validate signature len (needs to be at least max) */
484 if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) {
485 WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len");
486 return BAD_FUNC_ARG;
487 }
488
489 /* Validate hash size */
490 ret = wc_HashGetDigestSize(hash_type);
491 if (ret < 0) {
492 WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len");
493 return ret;
494 }
495 hash_enc_len = hash_len = ret;
496
497 #if !defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
498 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
499 /* For RSA with ASN.1 encoding include room */
500 hash_enc_len += MAX_DER_DIGEST_ASN_SZ;
501 }
502 #endif
503
504 #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN)
505 /* Allocate temporary buffer for hash data */
506 hash_data = (byte*)XMALLOC(hash_enc_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
507 if (hash_data == NULL) {
508 return MEMORY_E;
509 }
510 #endif
511
512 /* Perform hash of data */
513 ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len);
514 if (ret == 0) {
515 /* Handle RSA with DER encoding */
516 if (sig_type == WC_SIGNATURE_TYPE_RSA_W_ENC) {
517 #if defined(NO_RSA) || defined(NO_ASN) || \
518 defined(WOLFSSL_RSA_PUBLIC_ONLY)
519 ret = SIG_TYPE_E;
520 #else
521 ret = wc_SignatureDerEncode(hash_type, hash_data, hash_len,
522 &hash_enc_len);
523 #endif
524 }
525 if (ret == 0) {
526 /* Generate signature using hash */
527 ret = wc_SignatureGenerateHash(hash_type, sig_type,
528 hash_data, hash_enc_len, sig, sig_len, key, key_len, rng);
529 }
530 }
531
532 if (ret == 0 && verify) {
533 ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data,
534 hash_enc_len, sig, *sig_len, key, key_len);
535 }
536
537 #if defined(WOLFSSL_SMALL_STACK) || defined(NO_ASN)
538 XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
539 #endif
540
541 return ret;
542 }
543
544 #endif /* NO_SIG_WRAPPER */
545