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