Coverage Report

Created: 2026-09-28 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 */