Coverage Report

Created: 2025-07-31 06:22

/src/wolfssl/src/pk.c
Line
Count
Source (jump to first uncovered line)
1
/* pk.c
2
 *
3
 * Copyright (C) 2006-2025 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/internal.h>
25
#ifndef WC_NO_RNG
26
    #include <wolfssl/wolfcrypt/random.h>
27
#endif
28
29
#ifdef HAVE_ECC
30
    #include <wolfssl/wolfcrypt/ecc.h>
31
    #ifdef HAVE_SELFTEST
32
        /* point compression types. */
33
        #define ECC_POINT_COMP_EVEN 0x02
34
        #define ECC_POINT_COMP_ODD  0x03
35
        #define ECC_POINT_UNCOMP    0x04
36
    #endif
37
#endif
38
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
39
    /* FIPS build has replaced ecc.h. */
40
    #define wc_ecc_key_get_priv(key) (&((key)->k))
41
    #define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
42
#endif
43
44
#if !defined(WOLFSSL_PK_INCLUDED)
45
    #ifndef WOLFSSL_IGNORE_FILE_WARN
46
        #warning pk.c does not need to be compiled separately from ssl.c
47
    #endif
48
#else
49
50
#ifndef NO_RSA
51
    #include <wolfssl/wolfcrypt/rsa.h>
52
#endif
53
54
/*******************************************************************************
55
 * COMMON FUNCTIONS
56
 ******************************************************************************/
57
58
/* Calculate the number of bytes require to represent a length value in ASN.
59
 *
60
 * @param [in] l  Length value to use.
61
 * @return  Number of bytes required to represent length value.
62
 */
63
#define ASN_LEN_SIZE(l)             \
64
    (((l) < 128) ? 1 : (((l) < 256) ? 2 : 3))
65
66
#if defined(OPENSSL_EXTRA)
67
68
#ifndef NO_ASN
69
70
#if (!defined(NO_FILESYSTEM) && (defined(OPENSSL_EXTRA) || \
71
     defined(OPENSSL_ALL))) || (!defined(NO_BIO) && defined(OPENSSL_EXTRA))
72
/* Convert the PEM encoding in the buffer to DER.
73
 *
74
 * @param [in]  pem        Buffer containing PEM encoded data.
75
 * @param [in]  pemSz      Size of data in buffer in bytes.
76
 * @param [in]  cb         Password callback when PEM encrypted.
77
 * @param [in]  pass       NUL terminated string for passphrase when PEM
78
 *                         encrypted.
79
 * @param [in]  keyType    Type of key to match against PEM header/footer.
80
 * @param [out] keyFormat  Format of key.
81
 * @param [out] der        Buffer holding DER encoding.
82
 * @return  Negative on failure.
83
 * @return  Number of bytes consumed on success.
84
 */
85
static int pem_mem_to_der(const char* pem, int pemSz, wc_pem_password_cb* cb,
86
    void* pass, int keyType, int* keyFormat, DerBuffer** der)
87
{
88
#ifdef WOLFSSL_SMALL_STACK
89
    EncryptedInfo* info = NULL;
90
#else
91
    EncryptedInfo info[1];
92
#endif /* WOLFSSL_SMALL_STACK */
93
    wc_pem_password_cb* localCb = NULL;
94
    int ret = 0;
95
96
    if (cb != NULL) {
97
        localCb = cb;
98
    }
99
    else if (pass != NULL) {
100
        localCb = wolfSSL_PEM_def_callback;
101
    }
102
103
#ifdef WOLFSSL_SMALL_STACK
104
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
105
        DYNAMIC_TYPE_ENCRYPTEDINFO);
106
    if (info == NULL) {
107
        WOLFSSL_ERROR_MSG("Error getting memory for EncryptedInfo structure");
108
        ret = MEMORY_E;
109
    }
110
#endif /* WOLFSSL_SMALL_STACK */
111
112
    if (ret == 0) {
113
        XMEMSET(info, 0, sizeof(EncryptedInfo));
114
        info->passwd_cb       = localCb;
115
        info->passwd_userdata = pass;
116
117
        /* Do not strip PKCS8 header */
118
        ret = PemToDer((const unsigned char *)pem, pemSz, keyType, der, NULL,
119
            info, keyFormat);
120
        if (ret < 0) {
121
            WOLFSSL_ERROR_MSG("Bad PEM To DER");
122
        }
123
    }
124
    if (ret >= 0) {
125
        ret = (int)info->consumed;
126
    }
127
128
#ifdef WOLFSSL_SMALL_STACK
129
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
130
#endif
131
132
    return ret;
133
}
134
#endif
135
136
#if !defined(NO_RSA) || !defined(WOLFCRYPT_ONLY)
137
#ifndef NO_BIO
138
/* Read PEM data from a BIO and decode to DER in a new buffer.
139
 *
140
 * @param [in, out] bio        BIO object to read with.
141
 * @param [in]      cb         Password callback when PEM encrypted.
142
 * @param [in]      pass       NUL terminated string for passphrase when PEM
143
 *                             encrypted.
144
 * @param [in]      keyType    Type of key to match against PEM header/footer.
145
 * @param [out]     keyFormat  Format of key.
146
 * @param [out]     der        Buffer holding DER encoding.
147
 * @return  Negative on failure.
148
 * @return  Number of bytes consumed on success.
149
 */
150
static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
151
    void* pass, int keyType, int* keyFormat, DerBuffer** der)
152
{
153
    int ret;
154
    char* mem = NULL;
155
    int memSz;
156
    int alloced = 0;
157
158
    ret = wolfssl_read_bio(bio, &mem, &memSz, &alloced);
159
    if (ret == 0) {
160
        ret = pem_mem_to_der(mem, memSz, cb, pass, keyType, keyFormat, der);
161
        /* Write left over data back to BIO if not a file BIO */
162
        if ((ret > 0) && ((memSz - ret) > 0) &&
163
                 (bio->type != WOLFSSL_BIO_FILE)) {
164
            int res;
165
            if (!alloced) {
166
                /* If wolfssl_read_bio() points mem at the buffer internal to
167
                 * bio, we need to dup it before calling wolfSSL_BIO_write(),
168
                 * because the latter may reallocate the bio, invalidating the
169
                 * mem pointer before reading from it.
170
                 */
171
                char *mem_dup = (char *)XMALLOC((size_t)(memSz - ret),
172
                                                NULL, DYNAMIC_TYPE_TMP_BUFFER);
173
                if (mem_dup != NULL) {
174
                    XMEMCPY(mem_dup, mem + ret, (size_t)(memSz - ret));
175
                    res = wolfSSL_BIO_write(bio, mem_dup, memSz - ret);
176
                    mem = mem_dup;
177
                    alloced = 1;
178
                }
179
                else
180
                    res = MEMORY_E;
181
            }
182
            else
183
                res = wolfSSL_BIO_write(bio, mem + ret, memSz - ret);
184
            if (res != memSz - ret) {
185
                WOLFSSL_ERROR_MSG("Unable to write back excess data");
186
                if (res < 0) {
187
                    ret = res;
188
                }
189
                else {
190
                    ret = MEMORY_E;
191
                }
192
            }
193
        }
194
        if (alloced) {
195
            XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
196
        }
197
    }
198
199
    return ret;
200
}
201
#endif /* !NO_BIO */
202
203
#if !defined(NO_FILESYSTEM)
204
/* Read PEM data from a file and decode to DER in a new buffer.
205
 *
206
 * @param [in]  fp         File pointer to read with.
207
 * @param [in]  cb         Password callback when PEM encrypted.
208
 * @param [in]  pass       NUL terminated string for passphrase when PEM
209
 *                         encrypted.
210
 * @param [in]  keyType    Type of key to match against PEM header/footer.
211
 * @param [out] keyFormat  Format of key.
212
 * @param [out] der        Buffer holding DER encoding.
213
 * @return  Negative on failure.
214
 * @return  Number of bytes consumed on success.
215
 */
216
static int pem_read_file_key(XFILE fp, wc_pem_password_cb* cb, void* pass,
217
    int keyType, int* keyFormat, DerBuffer** der)
218
{
219
    int ret;
220
    char* mem = NULL;
221
    int memSz;
222
223
    ret = wolfssl_read_file(fp, &mem, &memSz);
224
    if (ret == 0) {
225
        ret = pem_mem_to_der(mem, memSz, cb, pass, keyType, keyFormat, der);
226
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
227
    }
228
229
    return ret;
230
}
231
#endif /* !NO_FILESYSTEM */
232
#endif
233
234
#if defined(OPENSSL_EXTRA) && ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) \
235
    || !defined(WOLFCRYPT_ONLY))
236
/* Convert DER data to PEM in an allocated buffer.
237
 *
238
 * @param [in]  der    Buffer containing DER data.
239
 * @param [in]  derSz  Size of DER data in bytes.
240
 * @param [in]  type   Type of key being encoded.
241
 * @param [in]  heap   Heap hint for dynamic memory allocation.
242
 * @param [out] out    Allocated buffer containing PEM.
243
 * @param [out] outSz  Size of PEM encoding.
244
 * @return  1 on success.
245
 * @return  0 on error.
246
 */
247
static int der_to_pem_alloc(const unsigned char* der, int derSz, int type,
248
    void* heap, byte** out, int* outSz)
249
{
250
    int ret = 1;
251
    int pemSz;
252
    byte* pem = NULL;
253
254
    (void)heap;
255
256
    /* Convert DER to PEM - to get size. */
257
    pemSz = wc_DerToPem(der, (word32)derSz, NULL, 0, type);
258
    if (pemSz < 0) {
259
        ret = 0;
260
    }
261
262
    if (ret == 1) {
263
        /* Allocate memory for PEM to be encoded into. */
264
        pem = (byte*)XMALLOC((size_t)pemSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
265
        if (pem == NULL) {
266
            ret = 0;
267
        }
268
    }
269
270
    /* Convert DER to PEM. */
271
    if ((ret == 1) && (wc_DerToPem(der, (word32)derSz, pem, (word32)pemSz,
272
            type) < 0)) {
273
        ret = 0;
274
        XFREE(pem, heap, DYNAMIC_TYPE_TMP_BUFFER);
275
        pem = NULL;
276
    }
277
278
    *out = pem;
279
    *outSz = pemSz;
280
    return ret;
281
}
282
283
#ifndef NO_BIO
284
/* Write the DER data as PEM into BIO.
285
 *
286
 * @param [in]      der    Buffer containing DER data.
287
 * @param [in]      derSz  Size of DER data in bytes.
288
 * @param [in, out] bio    BIO object to write with.
289
 * @param [in]      type   Type of key being encoded.
290
 * @return  1 on success.
291
 * @return  0 on error.
292
 */
293
static int der_write_to_bio_as_pem(const unsigned char* der, int derSz,
294
    WOLFSSL_BIO* bio, int type)
295
{
296
    int ret;
297
    int pemSz;
298
    byte* pem = NULL;
299
300
    ret = der_to_pem_alloc(der, derSz, type, bio->heap, &pem, &pemSz);
301
    if (ret == 1) {
302
        int len = wolfSSL_BIO_write(bio, pem, pemSz);
303
        if (len != pemSz) {
304
            WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
305
            ret = 0;
306
        }
307
    }
308
309
    XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
310
    return ret;
311
}
312
#endif
313
#endif
314
315
#if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || \
316
     (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
317
     (defined(HAVE_ECC) && defined(WOLFSSL_KEY_GEN))
318
#if !defined(NO_FILESYSTEM)
319
/* Write the DER data as PEM into file pointer.
320
 *
321
 * @param [in] der    Buffer containing DER data.
322
 * @param [in] derSz  Size of DER data in bytes.
323
 * @param [in] fp     File pointer to write with.
324
 * @param [in] type   Type of key being encoded.
325
 * @param [in] heap   Heap hint for dynamic memory allocation.
326
 * @return  1 on success.
327
 * @return  0 on error.
328
 */
329
static int der_write_to_file_as_pem(const unsigned char* der, int derSz,
330
    XFILE fp, int type, void* heap)
331
{
332
    int ret;
333
    int pemSz;
334
    byte* pem = NULL;
335
336
    ret = der_to_pem_alloc(der, derSz, type, heap, &pem, &pemSz);
337
    if (ret == 1) {
338
        int len = (int)XFWRITE(pem, 1, (size_t)pemSz, fp);
339
        if (len != pemSz) {
340
            WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
341
            ret = 0;
342
        }
343
    }
344
345
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
346
    return ret;
347
}
348
#endif
349
#endif
350
351
#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
352
/* Encrypt private key into PEM format.
353
 *
354
 * DER is encrypted in place.
355
 *
356
 * @param [in]  der         DER encoding of private key.
357
 * @param [in]  derSz       Size of DER in bytes.
358
 * @param [in]  cipher      EVP cipher.
359
 * @param [in]  passwd      Password to use with encryption.
360
 * @param [in]  passedSz    Size of password in bytes.
361
 * @param [out] cipherInfo  PEM cipher information lines.
362
 * @param [in]  maxDerSz    Maximum size of DER buffer.
363
 * @param [in]  hashType    Hash algorithm
364
 * @return  1 on success.
365
 * @return  0 on error.
366
 */
367
int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher,
368
    unsigned char* passwd, int passwdSz, byte **cipherInfo, int maxDerSz,
369
    int hashType)
370
{
371
    int ret = 0;
372
    int paddingSz = 0;
373
    word32 idx;
374
    word32 cipherInfoSz = 0;
375
#ifdef WOLFSSL_SMALL_STACK
376
    EncryptedInfo* info = NULL;
377
#else
378
    EncryptedInfo  info[1];
379
#endif
380
381
    WOLFSSL_ENTER("EncryptDerKey");
382
383
    /* Validate parameters. */
384
    if ((der == NULL) || (derSz == NULL) || (cipher == NULL) ||
385
            (passwd == NULL) || (cipherInfo == NULL)) {
386
        ret = BAD_FUNC_ARG;
387
    }
388
389
    #ifdef WOLFSSL_SMALL_STACK
390
    if (ret == 0) {
391
        /* Allocate encrypted info. */
392
        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
393
            DYNAMIC_TYPE_ENCRYPTEDINFO);
394
        if (info == NULL) {
395
            WOLFSSL_MSG("malloc failed");
396
            ret = MEMORY_E;
397
        }
398
    }
399
    #endif
400
    if (ret == 0) {
401
        /* Clear the encrypted info and set name. */
402
        XMEMSET(info, 0, sizeof(EncryptedInfo));
403
        XSTRNCPY(info->name, cipher, NAME_SZ - 1);
404
        info->name[NAME_SZ - 1] = '\0'; /* null term */
405
406
        /* Get encrypted info from name. */
407
        ret = wc_EncryptedInfoGet(info, info->name);
408
        if (ret != 0) {
409
            WOLFSSL_MSG("unsupported cipher");
410
        }
411
    }
412
413
    if (ret == 0) {
414
        /* Generate a random salt. */
415
        if (wolfSSL_RAND_bytes(info->iv, (int)info->ivSz) != 1) {
416
            WOLFSSL_MSG("generate iv failed");
417
            ret = WOLFSSL_FATAL_ERROR;
418
        }
419
    }
420
421
    if (ret == 0) {
422
        /* Calculate padding size - always a padding block. */
423
        paddingSz = (int)info->ivSz - ((*derSz) % (int)info->ivSz);
424
        /* Check der is big enough. */
425
        if (maxDerSz < (*derSz) + paddingSz) {
426
            WOLFSSL_MSG("not enough DER buffer allocated");
427
            ret = BAD_FUNC_ARG;
428
        }
429
    }
430
    if (ret == 0) {
431
        /* Set padding bytes to padding length. */
432
        XMEMSET(der + (*derSz), (byte)paddingSz, (size_t)paddingSz);
433
        /* Add padding to DER size. */
434
        (*derSz) += (int)paddingSz;
435
436
        /* Encrypt DER buffer. */
437
        ret = wc_BufferKeyEncrypt(info, der, (word32)*derSz, passwd, passwdSz,
438
            hashType);
439
        if (ret != 0) {
440
            WOLFSSL_MSG("encrypt key failed");
441
        }
442
    }
443
444
    if (ret == 0) {
445
        /* Create cipher info : 'cipher_name,Salt(hex)' */
446
        cipherInfoSz = (word32)(2 * info->ivSz + XSTRLEN(info->name) + 2);
447
        /* Allocate memory for PEM encryption lines. */
448
        *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL, DYNAMIC_TYPE_STRING);
449
        if (*cipherInfo == NULL) {
450
            WOLFSSL_MSG("malloc failed");
451
            ret = MEMORY_E;
452
        }
453
    }
454
    if (ret == 0) {
455
        /* Copy in name and add on comma. */
456
        XSTRLCPY((char*)*cipherInfo, info->name, cipherInfoSz);
457
        XSTRLCAT((char*)*cipherInfo, ",", cipherInfoSz);
458
459
        /* Find end of string. */
460
        idx = (word32)XSTRLEN((char*)*cipherInfo);
461
        /* Calculate remaining bytes. */
462
        cipherInfoSz -= idx;
463
464
        /* Encode IV into PEM encryption lines. */
465
        ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo + idx,
466
            &cipherInfoSz);
467
        if (ret != 0) {
468
            WOLFSSL_MSG("Base16_Encode failed");
469
            XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
470
            *cipherInfo = NULL;
471
        }
472
    }
473
474
#ifdef WOLFSSL_SMALL_STACK
475
    /* Free dynamically allocated info. */
476
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
477
#endif
478
    return ret == 0;
479
}
480
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
481
482
483
#if defined(WOLFSSL_KEY_GEN) && \
484
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
485
    (!defined(NO_RSA) || defined(HAVE_ECC))
486
/* Encrypt the DER in PEM format.
487
 *
488
 * @param [in]  der       DER encoded private key.
489
 * @param [in]  derSz     Size of DER in bytes.
490
 * @param [in]  cipher    EVP cipher.
491
 * @param [in]  passwd    Password to use in encryption.
492
 * @param [in]  passwdSz  Size of password in bytes.
493
 * @param [in]  type      PEM type of write out.
494
 * @param [in]  heap      Dynamic memory hint.
495
 * @param [out] out       Allocated buffer containing PEM encoding.
496
 *                        heap was NULL and dynamic type is DYNAMIC_TYPE_KEY.
497
 * @param [out] outSz     Size of PEM encoding in bytes.
498
 * @return  1 on success.
499
 * @return  0 on failure.
500
 */
501
static int der_to_enc_pem_alloc(unsigned char* der, int derSz,
502
    const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
503
    int type, void* heap, byte** out, int* outSz)
504
{
505
    int ret = 1;
506
    byte* tmp = NULL;
507
    byte* cipherInfo = NULL;
508
    int pemSz = 0;
509
    int hashType = WC_HASH_TYPE_NONE;
510
#if !defined(NO_MD5)
511
    hashType = WC_MD5;
512
#elif !defined(NO_SHA)
513
    hashType = WC_SHA;
514
#endif
515
516
    /* Macro doesn't always use it. */
517
    (void)heap;
518
519
    /* Encrypt DER buffer if required. */
520
    if ((ret == 1) && (passwd != NULL) && (passwdSz > 0) && (cipher != NULL)) {
521
        int blockSz = wolfSSL_EVP_CIPHER_block_size(cipher);
522
        byte *tmpBuf;
523
524
        /* Add space for padding. */
525
    #ifdef WOLFSSL_NO_REALLOC
526
        tmpBuf = (byte*)XMALLOC((size_t)(derSz + blockSz), heap,
527
            DYNAMIC_TYPE_TMP_BUFFER);
528
        if (tmpBuf != NULL && der != NULL)
529
        {
530
                XMEMCPY(tmpBuf, der, (size_t)(derSz));
531
                XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
532
                der = NULL;
533
        }
534
    #else
535
        tmpBuf = (byte*)XREALLOC(der, (size_t)(derSz + blockSz), heap,
536
            DYNAMIC_TYPE_TMP_BUFFER);
537
    #endif
538
        if (tmpBuf == NULL) {
539
            WOLFSSL_ERROR_MSG("Extending DER buffer failed");
540
            ret = 0; /* der buffer is free'd at the end of the function */
541
        }
542
        else {
543
            der = tmpBuf;
544
545
            /* Encrypt DER inline. */
546
            ret = EncryptDerKey(der, &derSz, cipher, passwd, passwdSz,
547
                &cipherInfo, derSz + blockSz, hashType);
548
            if (ret != 1) {
549
                WOLFSSL_ERROR_MSG("EncryptDerKey failed");
550
            }
551
        }
552
    }
553
554
    if (ret == 1) {
555
        /* Calculate PEM encoding size. */
556
        pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, cipherInfo, type);
557
        if (pemSz <= 0) {
558
            WOLFSSL_ERROR_MSG("wc_DerToPemEx failed");
559
            ret = 0;
560
        }
561
    }
562
    if (ret == 1) {
563
        /* Allocate space for PEM encoding plus a NUL terminator. */
564
        tmp = (byte*)XMALLOC((size_t)(pemSz + 1), NULL, DYNAMIC_TYPE_KEY);
565
        if (tmp == NULL) {
566
            WOLFSSL_ERROR_MSG("malloc failed");
567
            ret = 0;
568
        }
569
    }
570
    if (ret == 1) {
571
        /* DER to PEM */
572
        pemSz = wc_DerToPemEx(der, (word32)derSz, tmp, (word32)pemSz,
573
            cipherInfo, type);
574
        if (pemSz <= 0) {
575
            WOLFSSL_ERROR_MSG("wc_DerToPemEx failed");
576
            ret = 0;
577
        }
578
    }
579
    if (ret == 1) {
580
        /* NUL terminate string - PEM.  */
581
        tmp[pemSz] = 0x00;
582
        /* Return allocated buffer and size. */
583
        *out = tmp;
584
        *outSz = pemSz;
585
        /* Don't free returning buffer. */
586
        tmp = NULL;
587
    }
588
589
    XFREE(tmp, NULL, DYNAMIC_TYPE_KEY);
590
    XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
591
    XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
592
593
    return ret;
594
}
595
#endif
596
597
#endif /* !NO_ASN */
598
599
#if !defined(NO_CERTS) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
600
    !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA) || \
601
    defined(HAVE_ECC)) && defined(OPENSSL_EXTRA)
602
/* Print the number bn in hex with name field and indentation indent to file fp.
603
 *
604
 * Used by wolfSSL_DSA_print_fp, wolfSSL_RSA_print_fp and
605
 * wolfSSL_EC_KEY_print_fp to print DSA, RSA and ECC keys and parameters.
606
 *
607
 * @param [in] fp      File pointer to write to.
608
 * @param [in] indent  Number of spaces to prepend to each line.
609
 * @param [in] field   Name of field.
610
 * @param [in] bn      Big number to print.
611
 * @return  1 on success.
612
 * @return  0 on failure.
613
 * @return  BAD_FUNC_ARG when fp is invalid, indent is less than 0, or field or
614
 *          bn or NULL.
615
 */
616
static int pk_bn_field_print_fp(XFILE fp, int indent, const char* field,
617
    const WOLFSSL_BIGNUM* bn)
618
{
619
    static const int HEX_INDENT = 4;
620
    static const int MAX_DIGITS_PER_LINE = 30;
621
622
    int ret = 1;
623
    int i = 0;
624
    char* buf = NULL;
625
626
    /* Internal function - assume parameters are valid. */
627
628
    /* Convert BN to hexadecimal character array (allocates buffer). */
629
    buf = wolfSSL_BN_bn2hex(bn);
630
    if (buf == NULL) {
631
        ret = 0;
632
    }
633
    if (ret == 1) {
634
        /* Print leading spaces, name and spaces before data. */
635
        if (indent > 0) {
636
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
637
                ret = 0;
638
        }
639
    }
640
    if (ret == 1) {
641
        if (XFPRINTF(fp, "%s:\n", field) < 0)
642
            ret = 0;
643
    }
644
    if (ret == 1) {
645
        if (indent > 0) {
646
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
647
                ret = 0;
648
        }
649
    }
650
    if (ret == 1) {
651
        if (XFPRINTF(fp, "%*s", HEX_INDENT, "") < 0)
652
            ret = 0;
653
    }
654
    if (ret == 1) {
655
        /* Print first byte - should always exist. */
656
        if ((buf[i] != '\0') && (buf[i+1] != '\0')) {
657
            if (XFPRINTF(fp, "%c", buf[i++]) < 0)
658
                ret = 0;
659
            else if (XFPRINTF(fp, "%c", buf[i++]) < 0)
660
                    ret = 0;
661
        }
662
    }
663
    if (ret == 1) {
664
        /* Print each hexadecimal character with byte separator. */
665
        while ((buf[i] != '\0') && (buf[i+1] != '\0')) {
666
            /* Byte separator every two nibbles - one byte. */
667
            if (XFPRINTF(fp, ":") < 0) {
668
                ret = 0;
669
                break;
670
            }
671
            /* New line after every 15 bytes - 30 nibbles. */
672
            if (i % MAX_DIGITS_PER_LINE == 0) {
673
                if (XFPRINTF(fp, "\n") < 0) {
674
                    ret = 0;
675
                    break;
676
                }
677
                if (indent > 0) {
678
                    if (XFPRINTF(fp, "%*s", indent, "") < 0) {
679
                        ret = 0;
680
                        break;
681
                    }
682
                }
683
                if (XFPRINTF(fp, "%*s", HEX_INDENT, "") < 0) {
684
                    ret = 0;
685
                    break;
686
                }
687
            }
688
            /* Print two nibbles - one byte. */
689
            if (XFPRINTF(fp, "%c", buf[i++]) < 0) {
690
                ret = 0;
691
                break;
692
            }
693
            if (XFPRINTF(fp, "%c", buf[i++]) < 0) {
694
                ret = 0;
695
                break;
696
            }
697
        }
698
        /* Ensure on new line after data. */
699
        if (XFPRINTF(fp, "\n") < 0) {
700
            ret = 0;
701
        }
702
    }
703
704
    /* Dispose of any allocated character array. */
705
    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
706
707
    return ret;
708
}
709
#endif /* !NO_CERTS && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM &&
710
        * (!NO_DSA || !NO_RSA || HAVE_ECC) */
711
712
#if defined(XSNPRINTF) && !defined(NO_BIO) && !defined(NO_RSA)
713
/* snprintf() must be available */
714
715
/* Maximum number of extra indent spaces on each line. */
716
#define PRINT_NUM_MAX_INDENT        48
717
/* Maximum size of a line containing a value. */
718
#define PRINT_NUM_MAX_VALUE_LINE    PRINT_NUM_MAX_INDENT
719
/* Number of leading spaces on each line. */
720
#define PRINT_NUM_INDENT_CNT        4
721
/* Indent spaces for number lines. */
722
#define PRINT_NUM_INDENT            "    "
723
/* 4 leading spaces and 15 bytes with colons is a complete line. */
724
#define PRINT_NUM_MAX_DIGIT_LINE   (PRINT_NUM_INDENT_CNT + 3 * 15)
725
726
/* Print indent to BIO.
727
 *
728
 * @param [in] bio      BIO object to write to.
729
 * @param [in] line     Buffer to put characters to before writing to BIO.
730
 * @param [in] lineLen  Length of buffer.
731
 * @return  1 on success.
732
 * @return  0 on failure.
733
 */
734
static int wolfssl_print_indent(WOLFSSL_BIO* bio, char* line, int lineLen,
735
    int indent)
736
{
737
    int ret = 1;
738
739
    if (indent > 0) {
740
        /* Print indent spaces. */
741
        int len_wanted = XSNPRINTF(line, (size_t)lineLen, "%*s", indent, " ");
742
        if ((len_wanted < 0) || (len_wanted >= lineLen)) {
743
            WOLFSSL_ERROR_MSG("Buffer overflow formatting indentation");
744
            ret = 0;
745
        }
746
        else {
747
            /* Write indents string to BIO */
748
            if (wolfSSL_BIO_write(bio, line, len_wanted) <= 0) {
749
                ret = 0;
750
            }
751
        }
752
    }
753
754
    return ret;
755
}
756
757
/* Print out name, and value in decimal and hex to BIO.
758
 *
759
 * @param [in] bio     BIO object to write to.
760
 * @param [in] value   MP integer to write.
761
 * @param [in] name    Name of value.
762
 * @param [in] indent  Number of leading spaces before line.
763
 * @return  1 on success.
764
 * @return  0 on failure.
765
 */
766
static int wolfssl_print_value(WOLFSSL_BIO* bio, mp_int* value,
767
    const char* name, int indent)
768
{
769
    int ret = 1;
770
    int len;
771
    char line[PRINT_NUM_MAX_VALUE_LINE + 1];
772
773
    /* Get the length of hex encoded value. */
774
    len = mp_unsigned_bin_size(value);
775
    /* Value must no more than 32-bits - 4 bytes. */
776
    if ((len < 0) || (len > 4)) {
777
        WOLFSSL_ERROR_MSG("Error getting exponent size");
778
        ret = 0;
779
    }
780
    if (ret == 1) {
781
        /* Print any indent spaces. */
782
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
783
    }
784
    if (ret == 1) {
785
        /* Get 32-bits of value. */
786
        word32 v = (word32)value->dp[0];
787
        /* Print the line to the string. */
788
        len = (int)XSNPRINTF(line, sizeof(line), "%s %u (0x%x)\n", name, v,
789
            v);
790
        if (len >= (int)sizeof(line)) {
791
            WOLFSSL_ERROR_MSG("Buffer overflow while formatting value");
792
            ret = 0;
793
        } else {
794
            /* Write string to BIO */
795
            if (wolfSSL_BIO_write(bio, line, len) <= 0) {
796
                ret = 0;
797
            }
798
        }
799
    }
800
801
    return ret;
802
}
803
804
/* Print out name and multi-precision number to BIO.
805
 *
806
 * @param [in] bio     BIO object to write to.
807
 * @param [in] num     MP integer to write.
808
 * @param [in] name    Name of value.
809
 * @param [in] indent  Number of leading spaces before each line.
810
 * @return  1 on success.
811
 * @return  0 on failure.
812
 */
813
static int wolfssl_print_number(WOLFSSL_BIO* bio, mp_int* num, const char* name,
814
    int indent)
815
{
816
    int ret = 1;
817
    int rawLen = 0;
818
    byte* rawKey = NULL;
819
    char line[PRINT_NUM_MAX_DIGIT_LINE + 1];
820
    int li = 0; /* Line index. */
821
    int i;
822
823
    /* Allocate a buffer to hold binary encoded data. */
824
    rawLen = mp_unsigned_bin_size(num);
825
    if (rawLen == 0) {
826
        WOLFSSL_ERROR_MSG("Invalid number");
827
        ret = 0;
828
    }
829
    if (ret == 1) {
830
        rawKey = (byte*)XMALLOC((size_t)rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
831
        if (rawKey == NULL) {
832
            WOLFSSL_ERROR_MSG("Memory allocation error");
833
            ret = 0;
834
        }
835
    }
836
    /* Encode number as big-endian byte array. */
837
    if ((ret == 1) && (mp_to_unsigned_bin(num, rawKey) < 0)) {
838
        ret = 0;
839
    }
840
841
    if (ret == 1) {
842
        /* Print any indent spaces. */
843
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
844
    }
845
    if (ret == 1) {
846
        /* Print header string line to string. */
847
        li = XSNPRINTF(line, sizeof(line), "%s\n", name);
848
        if (li >= (int)sizeof(line)) {
849
            WOLFSSL_ERROR_MSG("Buffer overflow formatting name");
850
            ret = 0;
851
        }
852
        else {
853
            if (wolfSSL_BIO_write(bio, line, li) <= 0) {
854
                ret = 0;
855
            }
856
        }
857
    }
858
    if (ret == 1) {
859
        /* Print any indent spaces. */
860
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
861
    }
862
    if (ret == 1) {
863
        /* Start first digit line with spaces.
864
         * Writing out zeros ensures number is a positive value. */
865
        li = XSNPRINTF(line, sizeof(line), PRINT_NUM_INDENT "%s",
866
            mp_leading_bit(num) ?  "00:" : "");
867
        if (li >= (int)sizeof(line)) {
868
            WOLFSSL_ERROR_MSG("Buffer overflow formatting spaces");
869
            ret = 0;
870
        }
871
    }
872
873
    /* Put out each line of numbers. */
874
    for (i = 0; (ret == 1) && (i < rawLen); i++) {
875
        /* Encode another byte as 2 hex digits and append colon. */
876
        int len_wanted = XSNPRINTF(line + li, sizeof(line) - (size_t)li,
877
                                   "%02x:", rawKey[i]);
878
        /* Check if there was room -- if not, print the current line, not
879
         * including the newest octet.
880
         */
881
        if (len_wanted >= (int)sizeof(line) - li) {
882
            /* bump current octet to the next line. */
883
            --i;
884
            /* More bytes coming so add a line break. */
885
            line[li++] = '\n';
886
            /* Write out the line. */
887
            if (wolfSSL_BIO_write(bio, line, li) <= 0) {
888
                ret = 0;
889
            }
890
            if (ret == 1) {
891
                /* Print any indent spaces. */
892
                ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
893
            }
894
            /* Put the leading spaces on new line. */
895
            XSTRNCPY(line, PRINT_NUM_INDENT, PRINT_NUM_INDENT_CNT + 1);
896
            li = PRINT_NUM_INDENT_CNT;
897
        }
898
        else {
899
            li += len_wanted;
900
        }
901
    }
902
903
    if (ret == 1) {
904
        /* Put out last line - replace last colon with carriage return. */
905
        line[li-1] = '\n';
906
        if (wolfSSL_BIO_write(bio, line, li) <= 0) {
907
            ret = 0;
908
        }
909
    }
910
911
    /* Dispose of any allocated data. */
912
    XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
913
    return ret;
914
}
915
916
#endif /* XSNPRINTF && !NO_BIO && !NO_RSA */
917
918
#endif /* OPENSSL_EXTRA */
919
920
#if !defined(NO_CERTS) || (defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || \
921
    (!defined(NO_DH) && defined(HAVE_FIPS) && !FIPS_VERSION_GT(2,0)) || \
922
    defined(HAVE_ECC)))
923
924
/* Uses the DER SEQUENCE to determine size of DER data.
925
 *
926
 * Outer SEQUENCE encapsulates all the DER encoding.
927
 * Add the length of the SEQUENCE data to the length of the SEQUENCE header.
928
 *
929
 * @param [in] seq  Buffer holding DER encoded sequence.
930
 * @param [in] len  Length of data in buffer (may be larger than SEQ).
931
 * @return  Size of complete DER encoding on success.
932
 * @return  0 on failure.
933
 */
934
static int wolfssl_der_length(const unsigned char* seq, int len)
935
0
{
936
0
    int ret = 0;
937
0
    word32 i = 0;
938
939
    /* Check it is a SEQUENCE and get the length of the underlying data.
940
     * i is updated to be after SEQUENCE header bytes.
941
     */
942
0
    if (GetSequence_ex(seq, &i, &ret, (word32)len, 0) >= 0) {
943
        /* Add SEQUENCE header length to underlying data length. */
944
0
        ret += (int)i;
945
0
    }
946
947
0
    return ret;
948
0
}
949
950
#endif
951
952
/*******************************************************************************
953
 * START OF RSA API
954
 ******************************************************************************/
955
956
#ifndef NO_RSA
957
958
/*
959
 * RSA METHOD
960
 * Could be used to hold function pointers to implementations of RSA operations.
961
 */
962
963
#if defined(OPENSSL_EXTRA)
964
/* Return a blank RSA method and set the name and flags.
965
 *
966
 * Only one implementation of RSA operations.
967
 * name is duplicated.
968
 *
969
 * @param [in] name   Name to use in method.
970
 * @param [in] flags  Flags to set into method.
971
 * @return  Newly allocated RSA method on success.
972
 * @return  NULL on failure.
973
 */
974
WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags)
975
{
976
    WOLFSSL_RSA_METHOD* meth = NULL;
977
    int name_len = 0;
978
    int err;
979
980
    /* Validate name is not NULL. */
981
    err = (name == NULL);
982
    if (!err) {
983
        /* Allocate an RSA METHOD to return. */
984
        meth = (WOLFSSL_RSA_METHOD*)XMALLOC(sizeof(WOLFSSL_RSA_METHOD), NULL,
985
            DYNAMIC_TYPE_OPENSSL);
986
        err = (meth == NULL);
987
    }
988
    if (!err) {
989
        XMEMSET(meth, 0, sizeof(*meth));
990
        meth->flags = flags;
991
        meth->dynamic = 1;
992
993
        name_len = (int)XSTRLEN(name);
994
        meth->name = (char*)XMALLOC((size_t)(name_len + 1), NULL,
995
            DYNAMIC_TYPE_OPENSSL);
996
        err = (meth->name == NULL);
997
    }
998
    if (!err) {
999
        XMEMCPY(meth->name, name, (size_t)(name_len + 1));
1000
    }
1001
1002
    if (err) {
1003
        /* meth->name won't be allocated on error. */
1004
        XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL);
1005
        meth = NULL;
1006
    }
1007
    return meth;
1008
}
1009
1010
/* Default RSA method is one with wolfSSL name and no flags.
1011
 *
1012
 * @return  Newly allocated wolfSSL RSA method on success.
1013
 * @return  NULL on failure.
1014
 */
1015
const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void)
1016
{
1017
    static const WOLFSSL_RSA_METHOD wolfssl_rsa_meth = {
1018
        0, /* No flags. */
1019
        (char*)"wolfSSL RSA",
1020
        0  /* Static definition. */
1021
    };
1022
    return &wolfssl_rsa_meth;
1023
}
1024
1025
/* Dispose of RSA method and allocated data.
1026
 *
1027
 * @param [in] meth  RSA method to free.
1028
 */
1029
void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth)
1030
{
1031
    /* Free method if available and dynamically allocated. */
1032
    if ((meth != NULL) && meth->dynamic) {
1033
        /* Name was duplicated and must be freed. */
1034
        XFREE(meth->name, NULL, DYNAMIC_TYPE_OPENSSL);
1035
        /* Dispose of RSA method. */
1036
        XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL);
1037
    }
1038
}
1039
1040
#ifndef NO_WOLFSSL_STUB
1041
/* Stub function for any RSA method setting function.
1042
 *
1043
 * Nothing is stored - not even flags or name.
1044
 *
1045
 * @param [in] meth  RSA method.
1046
 * @param [in] p     A pointer.
1047
 * @return  1 to indicate success.
1048
 */
1049
int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *meth, void* p)
1050
{
1051
    WOLFSSL_STUB("RSA_METHOD is not implemented.");
1052
1053
    (void)meth;
1054
    (void)p;
1055
1056
    return 1;
1057
}
1058
#endif /* !NO_WOLFSSL_STUB */
1059
#endif /* OPENSSL_EXTRA */
1060
1061
/*
1062
 * RSA constructor/deconstructor APIs
1063
 */
1064
1065
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1066
/* Dispose of RSA key and allocated data.
1067
 *
1068
 * Cannot use rsa after this call.
1069
 *
1070
 * @param [in] rsa  RSA key to free.
1071
 */
1072
void wolfSSL_RSA_free(WOLFSSL_RSA* rsa)
1073
{
1074
    int doFree = 1;
1075
1076
    WOLFSSL_ENTER("wolfSSL_RSA_free");
1077
1078
    /* Validate parameter. */
1079
    if (rsa == NULL) {
1080
        doFree = 0;
1081
    }
1082
    if (doFree) {
1083
        int err;
1084
1085
        /* Decrement reference count. */
1086
        wolfSSL_RefDec(&rsa->ref, &doFree, &err);
1087
    #ifndef WOLFSSL_REFCNT_ERROR_RETURN
1088
        (void)err;
1089
    #endif
1090
    }
1091
    if (doFree) {
1092
        void* heap = rsa->heap;
1093
1094
        /* Dispose of allocated reference counting data. */
1095
        wolfSSL_RefFree(&rsa->ref);
1096
1097
    #ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1098
        wolfSSL_CRYPTO_cleanup_ex_data(&rsa->ex_data);
1099
    #endif
1100
1101
        if (rsa->internal != NULL) {
1102
        #if !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING)
1103
            /* Check if RNG is owned before freeing it. */
1104
            if (rsa->ownRng) {
1105
                WC_RNG* rng = ((RsaKey*)(rsa->internal))->rng;
1106
                if ((rng != NULL) && (rng != wolfssl_get_global_rng())) {
1107
                    wc_FreeRng(rng);
1108
                    XFREE(rng, heap, DYNAMIC_TYPE_RNG);
1109
                }
1110
                /* RNG isn't freed by wolfCrypt RSA free. */
1111
            }
1112
        #endif
1113
            /* Dispose of allocated data in wolfCrypt RSA key. */
1114
            wc_FreeRsaKey((RsaKey*)rsa->internal);
1115
            /* Dispose of memory for wolfCrypt RSA key. */
1116
            XFREE(rsa->internal, heap, DYNAMIC_TYPE_RSA);
1117
        }
1118
1119
        /* Dispose of external representation of RSA values. */
1120
        wolfSSL_BN_clear_free(rsa->iqmp);
1121
        wolfSSL_BN_clear_free(rsa->dmq1);
1122
        wolfSSL_BN_clear_free(rsa->dmp1);
1123
        wolfSSL_BN_clear_free(rsa->q);
1124
        wolfSSL_BN_clear_free(rsa->p);
1125
        wolfSSL_BN_clear_free(rsa->d);
1126
        wolfSSL_BN_free(rsa->e);
1127
        wolfSSL_BN_free(rsa->n);
1128
1129
    #if defined(OPENSSL_EXTRA)
1130
        if (rsa->meth) {
1131
            wolfSSL_RSA_meth_free((WOLFSSL_RSA_METHOD*)rsa->meth);
1132
        }
1133
    #endif
1134
1135
        /* Set back to NULLs for safety. */
1136
        ForceZero(rsa, sizeof(*rsa));
1137
1138
        XFREE(rsa, heap, DYNAMIC_TYPE_RSA);
1139
        (void)heap;
1140
    }
1141
}
1142
1143
/* Allocate and initialize a new RSA key.
1144
 *
1145
 * Not OpenSSL API.
1146
 *
1147
 * @param [in] heap   Heap hint for dynamic memory allocation.
1148
 * @param [in] devId  Device identifier value.
1149
 * @return  RSA key on success.
1150
 * @return  NULL on failure.
1151
 */
1152
WOLFSSL_RSA* wolfSSL_RSA_new_ex(void* heap, int devId)
1153
{
1154
    WOLFSSL_RSA* rsa = NULL;
1155
    RsaKey* key = NULL;
1156
    int err = 0;
1157
    int rsaKeyInited = 0;
1158
1159
    WOLFSSL_ENTER("wolfSSL_RSA_new");
1160
1161
    /* Allocate memory for new wolfCrypt RSA key. */
1162
    key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
1163
    if (key == NULL) {
1164
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_new malloc RsaKey failure");
1165
        err = 1;
1166
    }
1167
    if (!err) {
1168
        /* Allocate memory for new RSA key. */
1169
        rsa = (WOLFSSL_RSA*)XMALLOC(sizeof(WOLFSSL_RSA), heap,
1170
            DYNAMIC_TYPE_RSA);
1171
        if (rsa == NULL) {
1172
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure");
1173
            err = 1;
1174
        }
1175
    }
1176
    if (!err) {
1177
        /* Clear all fields of RSA key. */
1178
        XMEMSET(rsa, 0, sizeof(WOLFSSL_RSA));
1179
        /* Cache heap to use for all allocations. */
1180
        rsa->heap = heap;
1181
    #ifdef OPENSSL_EXTRA
1182
        /* Always have a method set. */
1183
        rsa->meth = wolfSSL_RSA_get_default_method();
1184
    #endif
1185
1186
        /* Initialize reference counting. */
1187
        wolfSSL_RefInit(&rsa->ref, &err);
1188
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
1189
    }
1190
    if (!err) {
1191
#endif
1192
        /* Initialize wolfCrypt RSA key. */
1193
        if (wc_InitRsaKey_ex(key, heap, devId) != 0) {
1194
            WOLFSSL_ERROR_MSG("InitRsaKey WOLFSSL_RSA failure");
1195
            err = 1;
1196
        }
1197
        else {
1198
            rsaKeyInited = 1;
1199
        }
1200
    }
1201
    #if !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING)
1202
    if (!err) {
1203
        WC_RNG* rng;
1204
1205
        /* Create a local RNG. */
1206
        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG);
1207
        if ((rng != NULL) && (wc_InitRng_ex(rng, heap, devId) != 0)) {
1208
            WOLFSSL_MSG("InitRng failure, attempting to use global RNG");
1209
            XFREE(rng, heap, DYNAMIC_TYPE_RNG);
1210
            rng = NULL;
1211
        }
1212
1213
        rsa->ownRng = 1;
1214
        if (rng == NULL) {
1215
            /* Get the wolfSSL global RNG - not thread safe. */
1216
            rng = wolfssl_get_global_rng();
1217
            rsa->ownRng = 0;
1218
        }
1219
        if (rng == NULL) {
1220
            /* Couldn't create global either. */
1221
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_new no WC_RNG for blinding");
1222
            err = 1;
1223
        }
1224
        else {
1225
            /* Set the local or global RNG into the wolfCrypt RSA key. */
1226
            (void)wc_RsaSetRNG(key, rng);
1227
            /* Won't fail as key and rng are not NULL. */
1228
        }
1229
    }
1230
    #endif /* !HAVE_FIPS && WC_RSA_BLINDING */
1231
    if (!err) {
1232
        /* Set wolfCrypt RSA key into RSA key. */
1233
        rsa->internal = key;
1234
        /* Data from external RSA key has not been set into internal one. */
1235
        rsa->inSet = 0;
1236
    }
1237
1238
    if (err) {
1239
        /* Dispose of any allocated data on error. */
1240
        /* No failure after RNG allocation - no need to free RNG. */
1241
        if (rsaKeyInited) {
1242
            wc_FreeRsaKey(key);
1243
        }
1244
        XFREE(key, heap, DYNAMIC_TYPE_RSA);
1245
        XFREE(rsa, heap, DYNAMIC_TYPE_RSA);
1246
        /* Return NULL. */
1247
        rsa = NULL;
1248
    }
1249
    return rsa;
1250
}
1251
1252
/* Allocate and initialize a new RSA key.
1253
 *
1254
 * @return  RSA key on success.
1255
 * @return  NULL on failure.
1256
 */
1257
WOLFSSL_RSA* wolfSSL_RSA_new(void)
1258
{
1259
    /* Call wolfSSL API to do work. */
1260
    return wolfSSL_RSA_new_ex(NULL, INVALID_DEVID);
1261
}
1262
1263
/* Increments ref count of RSA key.
1264
 *
1265
 * @param [in, out] rsa  RSA key.
1266
 * @return  1 on success
1267
 * @return  0 on error
1268
 */
1269
int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa)
1270
{
1271
    int err = 0;
1272
    if (rsa != NULL) {
1273
        wolfSSL_RefInc(&rsa->ref, &err);
1274
    }
1275
    return !err;
1276
}
1277
1278
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1279
1280
#ifdef OPENSSL_EXTRA
1281
1282
#if defined(WOLFSSL_KEY_GEN)
1283
1284
/* Allocate a new RSA key and make it a copy.
1285
 *
1286
 * Encodes to and from DER to copy.
1287
 *
1288
 * @param [in] rsa  RSA key to duplicate.
1289
 * @return  RSA key on success.
1290
 * @return  NULL on error.
1291
 */
1292
WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa)
1293
{
1294
    WOLFSSL_RSA* ret = NULL;
1295
    int derSz = 0;
1296
    byte* derBuf = NULL;
1297
    int err;
1298
1299
    WOLFSSL_ENTER("wolfSSL_RSAPublicKey_dup");
1300
1301
    err = (rsa == NULL);
1302
    if (!err) {
1303
        /* Create a new RSA key to return. */
1304
        ret = wolfSSL_RSA_new();
1305
        if (ret == NULL) {
1306
            WOLFSSL_ERROR_MSG("Error creating a new WOLFSSL_RSA structure");
1307
            err = 1;
1308
        }
1309
    }
1310
    if (!err) {
1311
        /* Encode RSA public key to copy to DER - allocates DER buffer. */
1312
        if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, rsa->heap)) < 0) {
1313
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
1314
            err = 1;
1315
        }
1316
    }
1317
    if (!err) {
1318
        /* Decode DER of the RSA public key into new key. */
1319
        if (wolfSSL_RSA_LoadDer_ex(ret, derBuf, derSz,
1320
                WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
1321
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_LoadDer_ex failed");
1322
            err = 1;
1323
        }
1324
    }
1325
1326
    /* Dispose of any allocated DER buffer. */
1327
    XFREE(derBuf, rsa ? rsa->heap : NULL, DYNAMIC_TYPE_ASN1);
1328
    if (err) {
1329
        /* Disposes of any created RSA key - on error. */
1330
        wolfSSL_RSA_free(ret);
1331
        ret = NULL;
1332
    }
1333
    return ret;
1334
}
1335
1336
/* wolfSSL_RSAPrivateKey_dup not supported */
1337
1338
#endif /* WOLFSSL_KEY_GEN */
1339
1340
static int wolfSSL_RSA_To_Der_ex(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey,
1341
    void* heap);
1342
1343
/*
1344
 * RSA to/from bin APIs
1345
 */
1346
1347
/* Convert RSA public key data to internal.
1348
 *
1349
 * Creates new RSA key from the DER encoded RSA public key.
1350
 *
1351
 * @param [out]     out      Pointer to RSA key to return through. May be NULL.
1352
 * @param [in, out] derBuf   Pointer to start of DER encoded data.
1353
 * @param [in]      derSz    Length of the data in the DER buffer.
1354
 * @return  RSA key on success.
1355
 * @return  NULL on failure.
1356
 */
1357
WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **out,
1358
    const unsigned char **derBuf, long derSz)
1359
{
1360
    WOLFSSL_RSA *rsa = NULL;
1361
    int err = 0;
1362
1363
    WOLFSSL_ENTER("wolfSSL_d2i_RSAPublicKey");
1364
1365
    /* Validate parameters. */
1366
    if (derBuf == NULL) {
1367
        WOLFSSL_ERROR_MSG("Bad argument");
1368
        err = 1;
1369
    }
1370
    /* Create a new RSA key to return. */
1371
    if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) {
1372
        WOLFSSL_ERROR_MSG("RSA_new failed");
1373
        err = 1;
1374
    }
1375
    /* Decode RSA key from DER. */
1376
    if ((!err) && (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz,
1377
            WOLFSSL_RSA_LOAD_PUBLIC) != 1)) {
1378
        WOLFSSL_ERROR_MSG("RSA_LoadDer failed");
1379
        err = 1;
1380
    }
1381
    if ((!err) && (out != NULL)) {
1382
        /* Return through parameter too. */
1383
        *out = rsa;
1384
        /* Move buffer on by the used amount. */
1385
        *derBuf += wolfssl_der_length(*derBuf, (int)derSz);
1386
    }
1387
1388
    if (err) {
1389
        /* Dispose of any created RSA key. */
1390
        wolfSSL_RSA_free(rsa);
1391
        rsa = NULL;
1392
    }
1393
    return rsa;
1394
}
1395
1396
/* Convert RSA private key data to internal.
1397
 *
1398
 * Create a new RSA key from the DER encoded RSA private key.
1399
 *
1400
 * @param [out]     out      Pointer to RSA key to return through. May be NULL.
1401
 * @param [in, out] derBuf   Pointer to start of DER encoded data.
1402
 * @param [in]      derSz    Length of the data in the DER buffer.
1403
 * @return  RSA key on success.
1404
 * @return  NULL on failure.
1405
 */
1406
WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **out,
1407
    const unsigned char **derBuf, long derSz)
1408
{
1409
    WOLFSSL_RSA *rsa = NULL;
1410
    int err = 0;
1411
1412
    WOLFSSL_ENTER("wolfSSL_d2i_RSAPublicKey");
1413
1414
    /* Validate parameters. */
1415
    if (derBuf == NULL) {
1416
        WOLFSSL_ERROR_MSG("Bad argument");
1417
        err = 1;
1418
    }
1419
    /* Create a new RSA key to return. */
1420
    if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) {
1421
        WOLFSSL_ERROR_MSG("RSA_new failed");
1422
        err = 1;
1423
    }
1424
    /* Decode RSA key from DER. */
1425
    if ((!err) && (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz,
1426
            WOLFSSL_RSA_LOAD_PRIVATE) != 1)) {
1427
        WOLFSSL_ERROR_MSG("RSA_LoadDer failed");
1428
        err = 1;
1429
    }
1430
    if ((!err) && (out != NULL)) {
1431
        /* Return through parameter too. */
1432
        *out = rsa;
1433
        /* Move buffer on by the used amount. */
1434
        *derBuf += wolfssl_der_length(*derBuf, (int)derSz);
1435
    }
1436
1437
    if (err) {
1438
        /* Dispose of any created RSA key. */
1439
        wolfSSL_RSA_free(rsa);
1440
        rsa = NULL;
1441
    }
1442
    return rsa;
1443
}
1444
1445
/* Converts an internal RSA structure to DER format for the private key.
1446
 *
1447
 * If "pp" is null then buffer size only is returned.
1448
 * If "*pp" is null then a created buffer is set in *pp and the caller is
1449
 *  responsible for free'ing it.
1450
 *
1451
 * @param [in]      rsa  RSA key.
1452
 * @param [in, out] pp   On in, pointer to allocated buffer or NULL.
1453
 *                       May be NULL.
1454
 *                       On out, newly allocated buffer or pointer to byte after
1455
 *                       encoding in passed in buffer.
1456
 *
1457
 * @return  Size of DER encoding on success
1458
 * @return  BAD_FUNC_ARG when rsa is NULL.
1459
 * @return  0 on failure.
1460
 */
1461
int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp)
1462
{
1463
    int ret;
1464
1465
    WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey");
1466
1467
    /* Validate parameters. */
1468
    if (rsa == NULL) {
1469
        WOLFSSL_ERROR_MSG("Bad Function Arguments");
1470
        ret = BAD_FUNC_ARG;
1471
    }
1472
    /* Encode the RSA key as a DER. Call allocates buffer into pp.
1473
     * No heap hint as this gets returned to the user */
1474
    else if ((ret = wolfSSL_RSA_To_Der_ex(rsa, pp, 0, NULL)) < 0) {
1475
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
1476
        ret = 0;
1477
    }
1478
1479
    /* Size of DER encoding. */
1480
    return ret;
1481
}
1482
1483
/* Converts an internal RSA structure to DER format for the public key.
1484
 *
1485
 * If "pp" is null then buffer size only is returned.
1486
 * If "*pp" is null then a created buffer is set in *pp and the caller is
1487
 *  responsible for free'ing it.
1488
 *
1489
 * @param [in]      rsa  RSA key.
1490
 * @param [in, out] pp   On in, pointer to allocated buffer or NULL.
1491
 *                       May be NULL.
1492
 *                       On out, newly allocated buffer or pointer to byte after
1493
 *                       encoding in passed in buffer.
1494
 * @return  Size of DER encoding on success
1495
 * @return  BAD_FUNC_ARG when rsa is NULL.
1496
 * @return  0 on failure.
1497
 */
1498
int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, unsigned char **pp)
1499
{
1500
    int ret;
1501
1502
    WOLFSSL_ENTER("wolfSSL_i2d_RSAPublicKey");
1503
1504
    /* check for bad functions arguments */
1505
    if (rsa == NULL) {
1506
        WOLFSSL_ERROR_MSG("Bad Function Arguments");
1507
        ret = BAD_FUNC_ARG;
1508
    }
1509
    /* Encode the RSA key as a DER. Call allocates buffer into pp.
1510
     * No heap hint as this gets returned to the user */
1511
    else if ((ret = wolfSSL_RSA_To_Der_ex(rsa, pp, 1, NULL)) < 0) {
1512
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
1513
        ret = 0;
1514
    }
1515
1516
    return ret;
1517
}
1518
1519
#endif /* OPENSSL_EXTRA */
1520
1521
/*
1522
 * RSA to/from BIO APIs
1523
 */
1524
1525
/* wolfSSL_d2i_RSAPublicKey_bio not supported */
1526
1527
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
1528
    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
1529
1530
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_BIO)
1531
1532
/* Read DER data from a BIO.
1533
 *
1534
 * DER structures start with a constructed sequence. Use this to calculate the
1535
 * total length of the DER data.
1536
 *
1537
 * @param [in]  bio   BIO object to read from.
1538
 * @param [out] out   Buffer holding DER encoding.
1539
 * @return  Number of bytes to DER encoding on success.
1540
 * @return  0 on failure.
1541
 */
1542
static int wolfssl_read_der_bio(WOLFSSL_BIO* bio, unsigned char** out)
1543
{
1544
    int err = 0;
1545
    unsigned char seq[MAX_SEQ_SZ];
1546
    unsigned char* der = NULL;
1547
    int derLen = 0;
1548
1549
    /* Read in a minimal amount to get a SEQUENCE header of any size. */
1550
    if (wolfSSL_BIO_read(bio, seq, sizeof(seq)) != sizeof(seq)) {
1551
        WOLFSSL_ERROR_MSG("wolfSSL_BIO_read() of sequence failure");
1552
        err = 1;
1553
    }
1554
    /* Calculate complete DER encoding length. */
1555
    if ((!err) && ((derLen = wolfssl_der_length(seq, sizeof(seq))) <= 0)) {
1556
        WOLFSSL_ERROR_MSG("DER SEQUENCE decode failed");
1557
        err = 1;
1558
    }
1559
    /* Allocate a buffer to read DER data into. */
1560
    if ((!err) && ((der = (unsigned char*)XMALLOC((size_t)derLen, bio->heap,
1561
            DYNAMIC_TYPE_TMP_BUFFER)) == NULL)) {
1562
        WOLFSSL_ERROR_MSG("Malloc failure");
1563
        err = 1;
1564
    }
1565
    if ((!err) && (derLen <= (int)sizeof(seq))) {
1566
        /* Copy the previously read data into the buffer. */
1567
        XMEMCPY(der, seq, derLen);
1568
    }
1569
    else if (!err) {
1570
        /* Calculate the unread amount. */
1571
        int len = derLen - (int)sizeof(seq);
1572
        /* Copy the previously read data into the buffer. */
1573
        XMEMCPY(der, seq, sizeof(seq));
1574
        /* Read rest of DER data from BIO. */
1575
        if (wolfSSL_BIO_read(bio, der + sizeof(seq), len) != len) {
1576
            WOLFSSL_ERROR_MSG("wolfSSL_BIO_read() failure");
1577
            err = 1;
1578
        }
1579
    }
1580
    if (!err) {
1581
        /* Return buffer through parameter. */
1582
        *out = der;
1583
    }
1584
1585
    if (err) {
1586
        /* Dispose of any allocated buffer on error. */
1587
        XFREE(der, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
1588
        derLen = 0;
1589
    }
1590
    return derLen;
1591
}
1592
1593
/* Reads the RSA private key data from a BIO to the internal form.
1594
 *
1595
 * Creates new RSA key from the DER encoded RSA private key read from the BIO.
1596
 *
1597
 * @param [in]  bio  BIO object to read from.
1598
 * @param [out] out  Pointer to RSA key to return through. May be NULL.
1599
 * @return  RSA key on success.
1600
 * @return  NULL on failure.
1601
 */
1602
WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
1603
{
1604
    WOLFSSL_RSA* key = NULL;
1605
    unsigned char* der = NULL;
1606
    int derLen = 0;
1607
    int err;
1608
1609
    WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey_bio");
1610
1611
    /* Validate parameters. */
1612
    err = (bio == NULL);
1613
    /* Read just DER encoding from BIO - buffer allocated in call. */
1614
    if ((!err) && ((derLen = wolfssl_read_der_bio(bio, &der)) == 0)) {
1615
        err = 1;
1616
    }
1617
    if (!err) {
1618
        /* Keep der for call to deallocate. */
1619
        const unsigned char* cder = der;
1620
        /* Create an RSA key from the data from the BIO. */
1621
        key = wolfSSL_d2i_RSAPrivateKey(NULL, &cder, derLen);
1622
        err = (key == NULL);
1623
    }
1624
    if ((!err) && (out != NULL)) {
1625
        /* Return the created RSA key through the parameter. */
1626
        *out = key;
1627
    }
1628
1629
    if (err) {
1630
        /* Dispose of created key on error. */
1631
        wolfSSL_RSA_free(key);
1632
        key = NULL;
1633
    }
1634
    /* Dispose of allocated data. */
1635
    XFREE(der, bio ? bio->heap : NULL, DYNAMIC_TYPE_TMP_BUFFER);
1636
    return key;
1637
}
1638
#endif /* defined(WOLFSSL_KEY_GEN) && !NO_BIO */
1639
1640
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
1641
1642
/*
1643
 * RSA DER APIs
1644
 */
1645
1646
#ifdef OPENSSL_EXTRA
1647
1648
/* Create a DER encoding of key.
1649
 *
1650
 * Not OpenSSL API.
1651
 *
1652
 * @param [in]  rsa        RSA key.
1653
 * @param [out] outBuf     Allocated buffer containing DER encoding.
1654
 *                         May be NULL.
1655
 * @param [in]  publicKey  Whether to encode as public key.
1656
 * @param [in]  heap       Heap hint.
1657
 * @return  Encoding size on success.
1658
 * @return  Negative on failure.
1659
 */
1660
int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey,
1661
    void* heap)
1662
{
1663
    byte* p = NULL;
1664
    int ret;
1665
1666
    if (outBuf != NULL) {
1667
        p = *outBuf;
1668
    }
1669
    ret = wolfSSL_RSA_To_Der_ex(rsa, outBuf, publicKey, heap);
1670
    if ((ret > 0) && (p != NULL)) {
1671
        *outBuf = p;
1672
    }
1673
    return ret;
1674
}
1675
1676
/* Create a DER encoding of key.
1677
 *
1678
 * Buffer allocated with heap and DYNAMIC_TYPE_TMP_BUFFER.
1679
 *
1680
 * @param [in]      rsa        RSA key.
1681
 * @param [in, out] outBuf     On in, pointer to allocated buffer or NULL.
1682
 *                             May be NULL.
1683
 *                             On out, newly allocated buffer or pointer to byte
1684
 *                             after encoding in passed in buffer.
1685
 * @param [in]      publicKey  Whether to encode as public key.
1686
 * @param [in]      heap       Heap hint.
1687
 * @return  Encoding size on success.
1688
 * @return  Negative on failure.
1689
 */
1690
static int wolfSSL_RSA_To_Der_ex(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey,
1691
    void* heap)
1692
{
1693
    int ret = 1;
1694
    int derSz = 0;
1695
    byte* derBuf = NULL;
1696
1697
    WOLFSSL_ENTER("wolfSSL_RSA_To_Der");
1698
1699
    /* Unused if memory is disabled. */
1700
    (void)heap;
1701
1702
    /* Validate parameters. */
1703
    if ((rsa == NULL) || ((publicKey != 0) && (publicKey != 1))) {
1704
        WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", BAD_FUNC_ARG);
1705
        ret = BAD_FUNC_ARG;
1706
    }
1707
    /* Push external RSA data into internal RSA key if not set. */
1708
    if ((ret == 1) && (!rsa->inSet)) {
1709
        ret = SetRsaInternal(rsa);
1710
    }
1711
    /* wc_RsaKeyToPublicDer encode regardless of values. */
1712
    if ((ret == 1) && publicKey && (mp_iszero(&((RsaKey*)rsa->internal)->n) ||
1713
            mp_iszero(&((RsaKey*)rsa->internal)->e))) {
1714
        ret = BAD_FUNC_ARG;
1715
    }
1716
1717
    if (ret == 1) {
1718
        if (publicKey) {
1719
            /* Calculate length of DER encoded RSA public key. */
1720
            derSz = wc_RsaPublicKeyDerSize((RsaKey*)rsa->internal, 1);
1721
            if (derSz < 0) {
1722
                WOLFSSL_ERROR_MSG("wc_RsaPublicKeyDerSize failed");
1723
                ret = derSz;
1724
            }
1725
        }
1726
        else {
1727
            /* Calculate length of DER encoded RSA private key. */
1728
            derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, NULL, 0);
1729
            if (derSz < 0) {
1730
                WOLFSSL_ERROR_MSG("wc_RsaKeyToDer failed");
1731
                ret = derSz;
1732
            }
1733
        }
1734
    }
1735
1736
    if ((ret == 1) && (outBuf != NULL)) {
1737
        derBuf = *outBuf;
1738
        if (derBuf == NULL) {
1739
            /* Allocate buffer to hold DER encoded RSA key. */
1740
            derBuf = (byte*)XMALLOC((size_t)derSz, heap,
1741
                DYNAMIC_TYPE_TMP_BUFFER);
1742
            if (derBuf == NULL) {
1743
                WOLFSSL_ERROR_MSG("Memory allocation failed");
1744
                ret = MEMORY_ERROR;
1745
            }
1746
        }
1747
    }
1748
    if ((ret == 1) && (outBuf != NULL)) {
1749
        if (publicKey > 0) {
1750
            /* RSA public key to DER. */
1751
            derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf,
1752
                (word32)derSz);
1753
        }
1754
        else {
1755
            /* RSA private key to DER. */
1756
            derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf,
1757
                (word32)derSz);
1758
        }
1759
        if (derSz < 0) {
1760
            WOLFSSL_ERROR_MSG("RSA key encoding failed");
1761
            ret = derSz;
1762
        }
1763
        else if ((*outBuf) != NULL) {
1764
            derBuf = NULL;
1765
            *outBuf += derSz;
1766
        }
1767
        else {
1768
            /* Return allocated buffer. */
1769
            *outBuf = derBuf;
1770
        }
1771
    }
1772
    if (ret == 1) {
1773
        /* Success - return DER encoding size. */
1774
        ret = derSz;
1775
    }
1776
1777
    if ((outBuf != NULL) && (*outBuf != derBuf)) {
1778
        /* Not returning buffer, needs to be disposed of. */
1779
        XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
1780
    }
1781
    WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", ret);
1782
    return ret;
1783
}
1784
1785
#endif /* OPENSSL_EXTRA */
1786
1787
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
1788
/* Load the DER encoded private RSA key.
1789
 *
1790
 * Not OpenSSL API.
1791
 *
1792
 * @param [in] rsa     RSA key.
1793
 * @param [in] derBuf  Buffer holding DER encoding.
1794
 * @param [in] derSz   Length of DER encoding.
1795
 * @return  1 on success.
1796
 * @return  -1 on failure.
1797
 */
1798
int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
1799
    int derSz)
1800
{
1801
    /* Call implementation that handles both private and public keys. */
1802
    return wolfSSL_RSA_LoadDer_ex(rsa, derBuf, derSz, WOLFSSL_RSA_LOAD_PRIVATE);
1803
}
1804
1805
/* Load the DER encoded public or private RSA key.
1806
 *
1807
 * Not OpenSSL API.
1808
 *
1809
 * @param [in] rsa     RSA key.
1810
 * @param [in] derBuf  Buffer holding DER encoding.
1811
 * @param [in] derSz   Length of DER encoding.
1812
 * @param [in] opt     Indicates public or private key.
1813
 *                     (WOLFSSL_RSA_LOAD_PUBLIC or WOLFSSL_RSA_LOAD_PRIVATE)
1814
 * @return  1 on success.
1815
 * @return  -1 on failure.
1816
 */
1817
int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
1818
    int derSz, int opt)
1819
{
1820
    int ret = 1;
1821
    int res;
1822
    word32 idx = 0;
1823
    word32 algId;
1824
1825
    WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
1826
1827
    /* Validate parameters. */
1828
    if ((rsa == NULL) || (rsa->internal == NULL) || (derBuf == NULL) ||
1829
            (derSz <= 0)) {
1830
        WOLFSSL_ERROR_MSG("Bad function arguments");
1831
        ret = WOLFSSL_FATAL_ERROR;
1832
    }
1833
1834
    if (ret == 1) {
1835
        rsa->pkcs8HeaderSz = 0;
1836
        /* Check if input buffer has PKCS8 header. In the case that it does not
1837
         * have a PKCS8 header then do not error out. */
1838
        res = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz,
1839
            &algId);
1840
        if (res > 0) {
1841
            /* Store size of PKCS#8 header for encoding. */
1842
            WOLFSSL_MSG("Found PKCS8 header");
1843
            rsa->pkcs8HeaderSz = (word16)idx;
1844
        }
1845
        /* When decoding and not PKCS#8, return will be ASN_PARSE_E. */
1846
        else if (res != WC_NO_ERR_TRACE(ASN_PARSE_E)) {
1847
            /* Something went wrong while decoding. */
1848
            WOLFSSL_ERROR_MSG("Unexpected error with trying to remove PKCS#8 "
1849
                              "header");
1850
            ret = WOLFSSL_FATAL_ERROR;
1851
        }
1852
    }
1853
    if (ret == 1) {
1854
        /* Decode private or public key data. */
1855
        if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
1856
            res = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal,
1857
                (word32)derSz);
1858
        }
1859
        else {
1860
            res = wc_RsaPublicKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal,
1861
                (word32)derSz);
1862
        }
1863
        /* Check for error. */
1864
        if (res < 0) {
1865
            if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
1866
                 WOLFSSL_ERROR_MSG("RsaPrivateKeyDecode failed");
1867
            }
1868
            else {
1869
                 WOLFSSL_ERROR_MSG("RsaPublicKeyDecode failed");
1870
            }
1871
            WOLFSSL_ERROR_VERBOSE(res);
1872
            ret = WOLFSSL_FATAL_ERROR;
1873
        }
1874
    }
1875
    if (ret == 1) {
1876
        /* Set external RSA key data from wolfCrypt key. */
1877
        if (SetRsaExternal(rsa) != 1) {
1878
            ret = WOLFSSL_FATAL_ERROR;
1879
        }
1880
        else {
1881
            rsa->inSet = 1;
1882
        }
1883
    }
1884
1885
    return ret;
1886
}
1887
1888
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1889
1890
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1891
1892
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
1893
/* Load DER encoded data into WOLFSSL_RSA object.
1894
 *
1895
 * Creates a new WOLFSSL_RSA object if one is not passed in.
1896
 *
1897
 * @param [in, out] rsa   WOLFSSL_RSA object to load into.
1898
 *                        When rsa or *rsa is NULL a new object is created.
1899
 *                        When not NULL and *rsa is NULL then new object
1900
 *                        returned through pointer.
1901
 * @param [in]      in    DER encoded RSA key data.
1902
 * @param [in]      inSz  Size of DER encoded data in bytes.
1903
 * @param [in]      opt   Public or private key encoded in data. Valid values:
1904
 *                        WOLFSSL_RSA_LOAD_PRIVATE, WOLFSSL_RSA_LOAD_PUBLIC.
1905
 * @return  NULL on failure.
1906
 * @return  WOLFSSL_RSA object on success.
1907
 */
1908
static WOLFSSL_RSA* wolfssl_rsa_d2i(WOLFSSL_RSA** rsa, const unsigned char* in,
1909
    long inSz, int opt)
1910
{
1911
    WOLFSSL_RSA* ret = NULL;
1912
1913
    if ((rsa != NULL) && (*rsa != NULL)) {
1914
        ret = *rsa;
1915
    }
1916
    else {
1917
        ret = wolfSSL_RSA_new();
1918
    }
1919
    if ((ret != NULL) && (wolfSSL_RSA_LoadDer_ex(ret, in, (int)inSz, opt)
1920
            != 1)) {
1921
        if ((rsa == NULL) || (ret != *rsa)) {
1922
            wolfSSL_RSA_free(ret);
1923
        }
1924
        ret = NULL;
1925
    }
1926
1927
    if ((rsa != NULL) && (*rsa == NULL)) {
1928
        *rsa = ret;
1929
    }
1930
    return ret;
1931
}
1932
#endif
1933
1934
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
1935
1936
/*
1937
 * RSA PEM APIs
1938
 */
1939
1940
#ifdef OPENSSL_EXTRA
1941
1942
#ifndef NO_BIO
1943
#if defined(WOLFSSL_KEY_GEN)
1944
/* Writes PEM encoding of an RSA public key to a BIO.
1945
 *
1946
 * @param [in] bio  BIO object to write to.
1947
 * @param [in] rsa  RSA key to write.
1948
 * @return  1 on success.
1949
 * @return  0 on failure.
1950
 */
1951
int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa)
1952
{
1953
    int ret = 1;
1954
    int derSz = 0;
1955
    byte* derBuf = NULL;
1956
1957
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSA_PUBKEY");
1958
1959
    /* Validate parameters. */
1960
    if ((bio == NULL) || (rsa == NULL)) {
1961
        WOLFSSL_ERROR_MSG("Bad Function Arguments");
1962
        return 0;
1963
    }
1964
1965
    if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, bio->heap)) < 0) {
1966
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
1967
        ret = 0;
1968
    }
1969
    if (derBuf == NULL) {
1970
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed to get buffer");
1971
        ret = 0;
1972
    }
1973
    if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
1974
            PUBLICKEY_TYPE) != 1)) {
1975
        ret = 0;
1976
    }
1977
1978
    /* Dispose of DER buffer. */
1979
    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
1980
    return ret;
1981
}
1982
1983
#endif /* WOLFSSL_KEY_GEN */
1984
#endif /* !NO_BIO */
1985
1986
#if defined(WOLFSSL_KEY_GEN)
1987
#ifndef NO_FILESYSTEM
1988
1989
/* Writes PEM encoding of an RSA public key to a file pointer.
1990
 *
1991
 * @param [in] fp    File pointer to write to.
1992
 * @param [in] rsa   RSA key to write.
1993
 * @param [in] type  PEM type to write out.
1994
 * @return  1 on success.
1995
 * @return  0 on failure.
1996
 */
1997
static int wolfssl_pem_write_rsa_public_key(XFILE fp, WOLFSSL_RSA* rsa,
1998
    int type)
1999
{
2000
    int ret = 1;
2001
    int derSz;
2002
    byte* derBuf = NULL;
2003
2004
    /* Validate parameters. */
2005
    if ((fp == XBADFILE) || (rsa == NULL)) {
2006
        WOLFSSL_ERROR_MSG("Bad Function Arguments");
2007
        return 0;
2008
    }
2009
2010
    if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, rsa->heap)) < 0) {
2011
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
2012
        ret = 0;
2013
    }
2014
    if (derBuf == NULL) {
2015
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed to get buffer");
2016
        ret = 0;
2017
    }
2018
    if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp, type,
2019
            rsa->heap) != 1)) {
2020
        ret = 0;
2021
    }
2022
2023
    /* Dispose of DER buffer. */
2024
    XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
2025
2026
    return ret;
2027
}
2028
2029
/* Writes PEM encoding of an RSA public key to a file pointer.
2030
 *
2031
 * Header/footer will contain: PUBLIC KEY
2032
 *
2033
 * @param [in] fp   File pointer to write to.
2034
 * @param [in] rsa  RSA key to write.
2035
 * @return  1 on success.
2036
 * @return  0 on failure.
2037
 */
2038
int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA* rsa)
2039
{
2040
    return wolfssl_pem_write_rsa_public_key(fp, rsa, PUBLICKEY_TYPE);
2041
}
2042
2043
/* Writes PEM encoding of an RSA public key to a file pointer.
2044
 *
2045
 * Header/footer will contain: RSA PUBLIC KEY
2046
 *
2047
 * @param [in] fp   File pointer to write to.
2048
 * @param [in] rsa  RSA key to write.
2049
 * @return  1 on success.
2050
 * @return  0 on failure.
2051
 */
2052
int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA* rsa)
2053
{
2054
    return wolfssl_pem_write_rsa_public_key(fp, rsa, RSA_PUBLICKEY_TYPE);
2055
}
2056
#endif /* !NO_FILESYSTEM */
2057
#endif /* WOLFSSL_KEY_GEN */
2058
2059
#ifndef NO_BIO
2060
/* Create an RSA public key by reading the PEM encoded data from the BIO.
2061
 *
2062
 * @param [in]  bio   BIO object to read from.
2063
 * @param [out] out   RSA key created.
2064
 * @param [in]  cb    Password callback when PEM encrypted.
2065
 * @param [in]  pass  NUL terminated string for passphrase when PEM encrypted.
2066
 * @return  RSA key on success.
2067
 * @return  NULL on failure.
2068
 */
2069
WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio,
2070
    WOLFSSL_RSA** out, wc_pem_password_cb* cb, void *pass)
2071
{
2072
    WOLFSSL_RSA* rsa = NULL;
2073
    DerBuffer*   der = NULL;
2074
    int          keyFormat = 0;
2075
2076
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_RSA_PUBKEY");
2077
2078
    if ((bio != NULL) && (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE,
2079
            &keyFormat, &der) >= 0)) {
2080
        rsa = wolfssl_rsa_d2i(out, der->buffer, der->length,
2081
            WOLFSSL_RSA_LOAD_PUBLIC);
2082
        if (rsa == NULL) {
2083
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_RSA");
2084
        }
2085
    }
2086
2087
    FreeDer(&der);
2088
    if ((out != NULL) && (rsa != NULL)) {
2089
        *out = rsa;
2090
    }
2091
    return rsa;
2092
}
2093
2094
WOLFSSL_RSA *wolfSSL_d2i_RSA_PUBKEY_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
2095
{
2096
    char* data = NULL;
2097
    int dataSz = 0;
2098
    int memAlloced = 0;
2099
    WOLFSSL_RSA* rsa = NULL;
2100
2101
    WOLFSSL_ENTER("wolfSSL_d2i_RSA_PUBKEY_bio");
2102
2103
    if (bio == NULL)
2104
        return NULL;
2105
2106
    if (wolfssl_read_bio(bio, &data, &dataSz, &memAlloced) != 0) {
2107
        if (memAlloced)
2108
            XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2109
        return NULL;
2110
    }
2111
2112
    rsa = wolfssl_rsa_d2i(out, (const unsigned char*)data, dataSz,
2113
            WOLFSSL_RSA_LOAD_PUBLIC);
2114
    if (memAlloced)
2115
        XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2116
2117
    return rsa;
2118
}
2119
#endif /* !NO_BIO */
2120
2121
#ifndef NO_FILESYSTEM
2122
/* Create an RSA public key by reading the PEM encoded data from the BIO.
2123
 *
2124
 * Header/footer should contain: PUBLIC KEY
2125
 * PEM decoder supports either 'RSA PUBLIC KEY' or 'PUBLIC KEY'.
2126
 *
2127
 * @param [in]  fp    File pointer to read from.
2128
 * @param [out] out   RSA key created.
2129
 * @param [in]  cb    Password callback when PEM encrypted.
2130
 * @param [in]  pass  NUL terminated string for passphrase when PEM encrypted.
2131
 * @return  RSA key on success.
2132
 * @return  NULL on failure.
2133
 */
2134
WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp,
2135
    WOLFSSL_RSA** out, wc_pem_password_cb* cb, void *pass)
2136
{
2137
    WOLFSSL_RSA* rsa = NULL;
2138
    DerBuffer*   der = NULL;
2139
    int          keyFormat = 0;
2140
2141
    WOLFSSL_ENTER("wolfSSL_PEM_read_RSA_PUBKEY");
2142
2143
    if ((fp != XBADFILE) && (pem_read_file_key(fp, cb, pass, PUBLICKEY_TYPE,
2144
            &keyFormat, &der) >= 0)) {
2145
        rsa = wolfssl_rsa_d2i(out, der->buffer, der->length,
2146
            WOLFSSL_RSA_LOAD_PUBLIC);
2147
        if (rsa == NULL) {
2148
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_RSA");
2149
        }
2150
    }
2151
2152
    FreeDer(&der);
2153
    if ((out != NULL) && (rsa != NULL)) {
2154
        *out = rsa;
2155
    }
2156
    return rsa;
2157
}
2158
2159
/* Create an RSA public key by reading the PEM encoded data from the BIO.
2160
 *
2161
 * Header/footer should contain: RSA PUBLIC KEY
2162
 * PEM decoder supports either 'RSA PUBLIC KEY' or 'PUBLIC KEY'.
2163
 *
2164
 * @param [in]  fp    File pointer to read from.
2165
 * @param [out] rsa   RSA key created.
2166
 * @param [in]  cb    Password callback when PEM encrypted. May be NULL.
2167
 * @param [in]  pass  NUL terminated string for passphrase when PEM encrypted.
2168
 *                    May be NULL.
2169
 * @return  RSA key on success.
2170
 * @return  NULL on failure.
2171
 */
2172
WOLFSSL_RSA* wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA** rsa,
2173
    wc_pem_password_cb* cb, void* pass)
2174
{
2175
    return wolfSSL_PEM_read_RSA_PUBKEY(fp, rsa, cb, pass);
2176
}
2177
2178
#endif /* NO_FILESYSTEM */
2179
2180
#if defined(WOLFSSL_KEY_GEN) && \
2181
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM))
2182
2183
/* Writes PEM encoding of an RSA private key to newly allocated buffer.
2184
 *
2185
 * Buffer returned was allocated with: DYNAMIC_TYPE_KEY.
2186
 *
2187
 * @param [in]  rsa       RSA key to write.
2188
 * @param [in]  cipher    Cipher to use when PEM encrypted. May be NULL.
2189
 * @param [in]  passwd    Password string when PEM encrypted. May be NULL.
2190
 * @param [in]  passwdSz  Length of password string when PEM encrypted.
2191
 * @param [out] pem       Allocated buffer with PEM encoding.
2192
 * @param [out] pLen      Length of PEM encoding.
2193
 * @return  1 on success.
2194
 * @return  0 on failure.
2195
 */
2196
int wolfSSL_PEM_write_mem_RSAPrivateKey(WOLFSSL_RSA* rsa,
2197
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
2198
    unsigned char **pem, int *pLen)
2199
{
2200
    int ret = 1;
2201
    byte* derBuf = NULL;
2202
    int  derSz = 0;
2203
2204
    WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey");
2205
2206
    /* Validate parameters. */
2207
    if ((pem == NULL) || (pLen == NULL) || (rsa == NULL) ||
2208
            (rsa->internal == NULL)) {
2209
        WOLFSSL_ERROR_MSG("Bad function arguments");
2210
        ret = 0;
2211
    }
2212
2213
    /* Set the RSA key data into the wolfCrypt RSA key if not done so. */
2214
    if ((ret == 1) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) {
2215
        ret = 0;
2216
    }
2217
2218
    /* Encode wolfCrypt RSA key to DER - derBuf allocated in call. */
2219
    if ((ret == 1) && ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0,
2220
            rsa->heap)) < 0)) {
2221
        WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
2222
        ret = 0;
2223
    }
2224
2225
    if ((ret == 1) && (der_to_enc_pem_alloc(derBuf, derSz, cipher, passwd,
2226
            passwdSz, PRIVATEKEY_TYPE, NULL, pem, pLen) != 1)) {
2227
        WOLFSSL_ERROR_MSG("der_to_enc_pem_alloc failed");
2228
        ret = 0;
2229
    }
2230
2231
    return ret;
2232
}
2233
2234
#ifndef NO_BIO
2235
/* Writes PEM encoding of an RSA private key to a BIO.
2236
 *
2237
 * @param [in] bio     BIO object to write to.
2238
 * @param [in] rsa     RSA key to write.
2239
 * @param [in] cipher  Cipher to use when PEM encrypted.
2240
 * @param [in] passwd  Password string when PEM encrypted.
2241
 * @param [in] len     Length of password string when PEM encrypted.
2242
 * @param [in] cb      Password callback to use when PEM encrypted.
2243
 * @param [in] arg     NUL terminated string for passphrase when PEM encrypted.
2244
 * @return  1 on success.
2245
 * @return  0 on failure.
2246
 */
2247
int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa,
2248
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
2249
    wc_pem_password_cb* cb, void* arg)
2250
{
2251
    int ret = 1;
2252
    byte* pem = NULL;
2253
    int pLen = 0;
2254
2255
    (void)cb;
2256
    (void)arg;
2257
2258
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSAPrivateKey");
2259
2260
    /* Validate parameters. */
2261
    if ((bio == NULL) || (rsa == NULL) || (rsa->internal == NULL)) {
2262
        WOLFSSL_ERROR_MSG("Bad function arguments");
2263
        ret = 0;
2264
    }
2265
2266
    if (ret == 1) {
2267
        /* Write PEM to buffer that is allocated in the call. */
2268
        ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, cipher, passwd, len,
2269
            &pem, &pLen);
2270
        if (ret != 1) {
2271
            WOLFSSL_ERROR_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
2272
        }
2273
    }
2274
    /* Write PEM to BIO. */
2275
    if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) <= 0)) {
2276
        WOLFSSL_ERROR_MSG("RSA private key BIO write failed");
2277
        ret = 0;
2278
    }
2279
2280
    /* Dispose of any allocated PEM buffer. */
2281
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
2282
    return ret;
2283
}
2284
#endif /* !NO_BIO */
2285
2286
#ifndef NO_FILESYSTEM
2287
/* Writes PEM encoding of an RSA private key to a file pointer.
2288
 *
2289
 * TODO: Support use of the password callback and callback context.
2290
 *
2291
 * @param [in] fp        File pointer to write to.
2292
 * @param [in] rsa       RSA key to write.
2293
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
2294
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
2295
 * @param [in] passwdSz  Length of password string when PEM encrypted.
2296
 * @param [in] cb        Password callback to use when PEM encrypted. Unused.
2297
 * @param [in] arg       NUL terminated string for passphrase when PEM
2298
 *                       encrypted. Unused.
2299
 * @return  1 on success.
2300
 * @return  0 on failure.
2301
 */
2302
int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa,
2303
    const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
2304
    wc_pem_password_cb *cb, void *arg)
2305
{
2306
    int ret = 1;
2307
    byte* pem = NULL;
2308
    int pLen = 0;
2309
2310
    (void)cb;
2311
    (void)arg;
2312
2313
    WOLFSSL_ENTER("wolfSSL_PEM_write_RSAPrivateKey");
2314
2315
    /* Validate parameters. */
2316
    if ((fp == XBADFILE) || (rsa == NULL) || (rsa->internal == NULL)) {
2317
        WOLFSSL_ERROR_MSG("Bad function arguments");
2318
        ret = 0;
2319
    }
2320
2321
    if (ret == 1) {
2322
        /* Write PEM to buffer that is allocated in the call. */
2323
        ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, cipher, passwd, passwdSz,
2324
            &pem, &pLen);
2325
        if (ret != 1) {
2326
            WOLFSSL_ERROR_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
2327
        }
2328
    }
2329
    /* Write PEM to file pointer. */
2330
    if ((ret == 1) && ((int)XFWRITE(pem, 1, (size_t)pLen, fp) != pLen)) {
2331
        WOLFSSL_ERROR_MSG("RSA private key file write failed");
2332
        ret = 0;
2333
    }
2334
2335
    /* Dispose of any allocated PEM buffer. */
2336
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
2337
    return ret;
2338
}
2339
#endif /* NO_FILESYSTEM */
2340
#endif /* WOLFSSL_KEY_GEN && WOLFSSL_PEM_TO_DER */
2341
2342
#ifndef NO_BIO
2343
/* Create an RSA private key by reading the PEM encoded data from the BIO.
2344
 *
2345
 * @param [in]  bio   BIO object to read from.
2346
 * @param [out] out   RSA key created.
2347
 * @param [in]  cb    Password callback when PEM encrypted.
2348
 * @param [in]  pass  NUL terminated string for passphrase when PEM encrypted.
2349
 * @return  RSA key on success.
2350
 * @return  NULL on failure.
2351
 */
2352
WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio,
2353
    WOLFSSL_RSA** out, wc_pem_password_cb* cb, void* pass)
2354
{
2355
    WOLFSSL_RSA* rsa = NULL;
2356
    DerBuffer*   der = NULL;
2357
    int          keyFormat = 0;
2358
2359
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_RSAPrivateKey");
2360
2361
    if ((bio != NULL) && (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE,
2362
            &keyFormat, &der) >= 0)) {
2363
        rsa = wolfssl_rsa_d2i(out, der->buffer, der->length,
2364
            WOLFSSL_RSA_LOAD_PRIVATE);
2365
        if (rsa == NULL) {
2366
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_RSA");
2367
        }
2368
    }
2369
2370
    FreeDer(&der);
2371
    if ((out != NULL) && (rsa != NULL)) {
2372
        *out = rsa;
2373
    }
2374
    return rsa;
2375
}
2376
#endif /* !NO_BIO */
2377
2378
/* Create an RSA private key by reading the PEM encoded data from the file
2379
 * pointer.
2380
 *
2381
 * @param [in]  fp    File pointer to read from.
2382
 * @param [out] out   RSA key created.
2383
 * @param [in]  cb    Password callback when PEM encrypted.
2384
 * @param [in]  pass  NUL terminated string for passphrase when PEM encrypted.
2385
 * @return  RSA key on success.
2386
 * @return  NULL on failure.
2387
 */
2388
#ifndef NO_FILESYSTEM
2389
WOLFSSL_RSA* wolfSSL_PEM_read_RSAPrivateKey(XFILE fp, WOLFSSL_RSA** out,
2390
    wc_pem_password_cb* cb, void* pass)
2391
{
2392
    WOLFSSL_RSA* rsa = NULL;
2393
    DerBuffer*   der = NULL;
2394
    int          keyFormat = 0;
2395
2396
    WOLFSSL_ENTER("wolfSSL_PEM_read_RSAPrivateKey");
2397
2398
    if ((fp != XBADFILE) && (pem_read_file_key(fp, cb, pass, PRIVATEKEY_TYPE,
2399
            &keyFormat, &der) >= 0)) {
2400
        rsa = wolfssl_rsa_d2i(out, der->buffer, der->length,
2401
            WOLFSSL_RSA_LOAD_PRIVATE);
2402
        if (rsa == NULL) {
2403
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_RSA");
2404
        }
2405
    }
2406
2407
    FreeDer(&der);
2408
    if ((out != NULL) && (rsa != NULL)) {
2409
        *out = rsa;
2410
    }
2411
    return rsa;
2412
}
2413
#endif /* !NO_FILESYSTEM */
2414
2415
/*
2416
 * RSA print APIs
2417
 */
2418
2419
#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
2420
    !defined(NO_STDIO_FILESYSTEM)
2421
/* Print an RSA key to a file pointer.
2422
 *
2423
 * @param [in] fp      File pointer to write to.
2424
 * @param [in] rsa     RSA key to write.
2425
 * @param [in] indent  Number of spaces to prepend to each line.
2426
 * @return  1 on success.
2427
 * @return  0 on failure.
2428
 */
2429
int wolfSSL_RSA_print_fp(XFILE fp, WOLFSSL_RSA* rsa, int indent)
2430
{
2431
    int ret = 1;
2432
2433
    WOLFSSL_ENTER("wolfSSL_RSA_print_fp");
2434
2435
    /* Validate parameters. */
2436
    if ((fp == XBADFILE) || (rsa == NULL)) {
2437
        ret = 0;
2438
    }
2439
2440
    /* Set the external data from the wolfCrypt RSA key if not done. */
2441
    if ((ret == 1) && (!rsa->exSet)) {
2442
        ret = SetRsaExternal(rsa);
2443
    }
2444
2445
    /* Get the key size from modulus if available. */
2446
    if ((ret == 1) && (rsa->n != NULL)) {
2447
        int keySize = wolfSSL_BN_num_bits(rsa->n);
2448
        if (keySize == 0) {
2449
            ret = 0;
2450
        }
2451
        else {
2452
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
2453
                ret = 0;
2454
            else if (XFPRINTF(fp, "RSA Private-Key: (%d bit, 2 primes)\n",
2455
                              keySize) < 0)
2456
                ret = 0;
2457
        }
2458
    }
2459
    /* Print out any components available. */
2460
    if ((ret == 1) && (rsa->n != NULL)) {
2461
        ret = pk_bn_field_print_fp(fp, indent, "modulus", rsa->n);
2462
    }
2463
    if ((ret == 1) && (rsa->d != NULL)) {
2464
        ret = pk_bn_field_print_fp(fp, indent, "privateExponent", rsa->d);
2465
    }
2466
    if ((ret == 1) && (rsa->p != NULL)) {
2467
        ret = pk_bn_field_print_fp(fp, indent, "prime1", rsa->p);
2468
    }
2469
    if ((ret == 1) && (rsa->q != NULL)) {
2470
        ret = pk_bn_field_print_fp(fp, indent, "prime2", rsa->q);
2471
    }
2472
    if ((ret == 1) && (rsa->dmp1 != NULL)) {
2473
        ret = pk_bn_field_print_fp(fp, indent, "exponent1", rsa->dmp1);
2474
    }
2475
    if ((ret == 1) && (rsa->dmq1 != NULL)) {
2476
        ret = pk_bn_field_print_fp(fp, indent, "exponent2", rsa->dmq1);
2477
    }
2478
    if ((ret == 1) && (rsa->iqmp != NULL)) {
2479
        ret = pk_bn_field_print_fp(fp, indent, "coefficient", rsa->iqmp);
2480
    }
2481
2482
    WOLFSSL_LEAVE("wolfSSL_RSA_print_fp", ret);
2483
2484
    return ret;
2485
}
2486
#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
2487
2488
#if defined(XSNPRINTF) && !defined(NO_BIO)
2489
/* snprintf() must be available */
2490
2491
/* Maximum size of a header line. */
2492
#define RSA_PRINT_MAX_HEADER_LINE   PRINT_NUM_MAX_INDENT
2493
2494
/* Writes the human readable form of RSA to a BIO.
2495
 *
2496
 * @param [in] bio     BIO object to write to.
2497
 * @param [in] rsa     RSA key to write.
2498
 * @param [in] indent  Number of spaces before each line.
2499
 * @return  1 on success.
2500
 * @return  0 on failure.
2501
 */
2502
int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int indent)
2503
{
2504
    int ret = 1;
2505
    int sz = 0;
2506
    RsaKey* key = NULL;
2507
    char line[RSA_PRINT_MAX_HEADER_LINE];
2508
    int i = 0;
2509
    mp_int *num = NULL;
2510
    /* Header strings. */
2511
    const char *name[] = {
2512
        "Modulus:", "Exponent:", "PrivateExponent:", "Prime1:", "Prime2:",
2513
        "Exponent1:", "Exponent2:", "Coefficient:"
2514
    };
2515
2516
    WOLFSSL_ENTER("wolfSSL_RSA_print");
2517
2518
    /* Validate parameters. */
2519
    if ((bio == NULL) || (rsa == NULL) || (indent > PRINT_NUM_MAX_INDENT)) {
2520
        ret = WOLFSSL_FATAL_ERROR;
2521
    }
2522
2523
    if (ret == 1) {
2524
        key = (RsaKey*)rsa->internal;
2525
2526
        /* Get size in bits of key for printing out. */
2527
        sz = wolfSSL_RSA_bits(rsa);
2528
        if (sz <= 0) {
2529
            WOLFSSL_ERROR_MSG("Error getting RSA key size");
2530
            ret = 0;
2531
        }
2532
    }
2533
    if (ret == 1) {
2534
        /* Print any indent spaces. */
2535
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
2536
    }
2537
    if (ret == 1) {
2538
        /* Print header line. */
2539
        int len = XSNPRINTF(line, sizeof(line), "\nRSA %s: (%d bit)\n",
2540
            (!mp_iszero(&key->d)) ? "Private-Key" : "Public-Key", sz);
2541
        if (len >= (int)sizeof(line)) {
2542
            WOLFSSL_ERROR_MSG("Buffer overflow while formatting key preamble");
2543
            ret = 0;
2544
        }
2545
        else {
2546
            if (wolfSSL_BIO_write(bio, line, len) <= 0) {
2547
                ret = 0;
2548
            }
2549
        }
2550
    }
2551
2552
    for (i = 0; (ret == 1) && (i < RSA_INTS); i++) {
2553
        /* Get mp_int for index. */
2554
        switch (i) {
2555
            case 0:
2556
                /* Print out modulus */
2557
                num = &key->n;
2558
                break;
2559
            case 1:
2560
                num = &key->e;
2561
                break;
2562
            case 2:
2563
                num = &key->d;
2564
                break;
2565
            case 3:
2566
                num = &key->p;
2567
                break;
2568
            case 4:
2569
                num = &key->q;
2570
                break;
2571
            case 5:
2572
                num = &key->dP;
2573
                break;
2574
            case 6:
2575
                num = &key->dQ;
2576
                break;
2577
            case 7:
2578
                num = &key->u;
2579
                break;
2580
            default:
2581
                WOLFSSL_ERROR_MSG("Bad index value");
2582
        }
2583
2584
        if (i == 1) {
2585
            /* Print exponent as a 32-bit value. */
2586
            ret = wolfssl_print_value(bio, num, name[i], indent);
2587
        }
2588
        else if (!mp_iszero(num)) {
2589
            /* Print name and MP integer. */
2590
            ret = wolfssl_print_number(bio, num, name[i], indent);
2591
        }
2592
    }
2593
2594
    return ret;
2595
}
2596
#endif /* XSNPRINTF && !NO_BIO */
2597
2598
#endif /* OPENSSL_EXTRA */
2599
2600
/*
2601
 * RSA get/set/test APIs
2602
 */
2603
2604
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2605
/* Set RSA key data (external) from wolfCrypt RSA key (internal).
2606
 *
2607
 * @param [in, out] rsa  RSA key.
2608
 * @return  1 on success.
2609
 * @return  0 on failure.
2610
 */
2611
int SetRsaExternal(WOLFSSL_RSA* rsa)
2612
{
2613
    int ret = 1;
2614
2615
    WOLFSSL_ENTER("SetRsaExternal");
2616
2617
    /* Validate parameters. */
2618
    if ((rsa == NULL) || (rsa->internal == NULL)) {
2619
        WOLFSSL_ERROR_MSG("rsa key NULL error");
2620
        ret = WOLFSSL_FATAL_ERROR;
2621
    }
2622
2623
    if (ret == 1) {
2624
        RsaKey* key = (RsaKey*)rsa->internal;
2625
2626
        /* Copy modulus. */
2627
        ret = wolfssl_bn_set_value(&rsa->n, &key->n);
2628
        if (ret != 1) {
2629
            WOLFSSL_ERROR_MSG("rsa n error");
2630
        }
2631
        if (ret == 1) {
2632
            /* Copy public exponent. */
2633
            ret = wolfssl_bn_set_value(&rsa->e, &key->e);
2634
            if (ret != 1) {
2635
                WOLFSSL_ERROR_MSG("rsa e error");
2636
            }
2637
        }
2638
2639
        if (key->type == RSA_PRIVATE) {
2640
    #ifndef WOLFSSL_RSA_PUBLIC_ONLY
2641
            if (ret == 1) {
2642
                /* Copy private exponent. */
2643
                ret = wolfssl_bn_set_value(&rsa->d, &key->d);
2644
                if (ret != 1) {
2645
                    WOLFSSL_ERROR_MSG("rsa d error");
2646
                }
2647
            }
2648
            if (ret == 1) {
2649
                /* Copy first prime. */
2650
                ret = wolfssl_bn_set_value(&rsa->p, &key->p);
2651
                if (ret != 1) {
2652
                    WOLFSSL_ERROR_MSG("rsa p error");
2653
                }
2654
            }
2655
            if (ret == 1) {
2656
                /* Copy second prime. */
2657
                ret = wolfssl_bn_set_value(&rsa->q, &key->q);
2658
                if (ret != 1) {
2659
                    WOLFSSL_ERROR_MSG("rsa q error");
2660
                }
2661
            }
2662
        #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
2663
            !defined(RSA_LOW_MEM)
2664
            if (ret == 1) {
2665
                /* Copy d mod p-1. */
2666
                ret = wolfssl_bn_set_value(&rsa->dmp1, &key->dP);
2667
                if (ret != 1) {
2668
                    WOLFSSL_ERROR_MSG("rsa dP error");
2669
                }
2670
            }
2671
            if (ret == 1) {
2672
                /* Copy d mod q-1. */
2673
                ret = wolfssl_bn_set_value(&rsa->dmq1, &key->dQ);
2674
                if (ret != 1) {
2675
                    WOLFSSL_ERROR_MSG("rsa dq error");
2676
                }
2677
            }
2678
            if (ret == 1) {
2679
                /* Copy 1/q mod p. */
2680
                ret = wolfssl_bn_set_value(&rsa->iqmp, &key->u);
2681
                if (ret != 1) {
2682
                    WOLFSSL_ERROR_MSG("rsa u error");
2683
                }
2684
            }
2685
        #endif
2686
    #else
2687
            WOLFSSL_ERROR_MSG("rsa private key not compiled in ");
2688
            ret = 0;
2689
    #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
2690
        }
2691
    }
2692
    if (ret == 1) {
2693
        /* External values set. */
2694
        rsa->exSet = 1;
2695
    }
2696
    else {
2697
        /* Return 0 on failure. */
2698
        ret = 0;
2699
    }
2700
2701
    return ret;
2702
}
2703
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
2704
2705
#ifdef OPENSSL_EXTRA
2706
2707
/* Set wolfCrypt RSA key data (internal) from RSA key (external).
2708
 *
2709
 * @param [in, out] rsa  RSA key.
2710
 * @return  1 on success.
2711
 * @return  0 on failure.
2712
 */
2713
int SetRsaInternal(WOLFSSL_RSA* rsa)
2714
{
2715
    int ret = 1;
2716
2717
    WOLFSSL_ENTER("SetRsaInternal");
2718
2719
    /* Validate parameters. */
2720
    if ((rsa == NULL) || (rsa->internal == NULL)) {
2721
        WOLFSSL_ERROR_MSG("rsa key NULL error");
2722
        ret = WOLFSSL_FATAL_ERROR;
2723
    }
2724
2725
    if (ret == 1) {
2726
        RsaKey* key = (RsaKey*)rsa->internal;
2727
2728
        /* Copy down modulus if available. */
2729
        if ((rsa->n != NULL) && (wolfssl_bn_get_value(rsa->n, &key->n) != 1)) {
2730
            WOLFSSL_ERROR_MSG("rsa n key error");
2731
            ret = WOLFSSL_FATAL_ERROR;
2732
        }
2733
2734
        /* Copy down public exponent if available. */
2735
        if ((ret == 1) && (rsa->e != NULL) &&
2736
                (wolfssl_bn_get_value(rsa->e, &key->e) != 1)) {
2737
            WOLFSSL_ERROR_MSG("rsa e key error");
2738
            ret = WOLFSSL_FATAL_ERROR;
2739
        }
2740
2741
        /* Enough numbers for public key */
2742
        key->type = RSA_PUBLIC;
2743
2744
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
2745
        /* Copy down private exponent if available. */
2746
        if ((ret == 1) && (rsa->d != NULL)) {
2747
            if (wolfssl_bn_get_value(rsa->d, &key->d) != 1) {
2748
                WOLFSSL_ERROR_MSG("rsa d key error");
2749
                ret = WOLFSSL_FATAL_ERROR;
2750
            }
2751
            else {
2752
                /* Enough numbers for private key */
2753
                key->type = RSA_PRIVATE;
2754
           }
2755
        }
2756
2757
        /* Copy down first prime if available. */
2758
        if ((ret == 1) && (rsa->p != NULL) &&
2759
                (wolfssl_bn_get_value(rsa->p, &key->p) != 1)) {
2760
            WOLFSSL_ERROR_MSG("rsa p key error");
2761
            ret = WOLFSSL_FATAL_ERROR;
2762
        }
2763
2764
        /* Copy down second prime if available. */
2765
        if ((ret == 1) && (rsa->q != NULL) &&
2766
                (wolfssl_bn_get_value(rsa->q, &key->q) != 1)) {
2767
            WOLFSSL_ERROR_MSG("rsa q key error");
2768
            ret = WOLFSSL_FATAL_ERROR;
2769
        }
2770
2771
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
2772
        /* Copy down d mod p-1 if available. */
2773
        if ((ret == 1) && (rsa->dmp1 != NULL) &&
2774
                (wolfssl_bn_get_value(rsa->dmp1, &key->dP) != 1)) {
2775
            WOLFSSL_ERROR_MSG("rsa dP key error");
2776
            ret = WOLFSSL_FATAL_ERROR;
2777
        }
2778
2779
        /* Copy down d mod q-1 if available. */
2780
        if ((ret == 1) && (rsa->dmq1 != NULL) &&
2781
                (wolfssl_bn_get_value(rsa->dmq1, &key->dQ) != 1)) {
2782
            WOLFSSL_ERROR_MSG("rsa dQ key error");
2783
            ret = WOLFSSL_FATAL_ERROR;
2784
        }
2785
2786
        /* Copy down 1/q mod p if available. */
2787
        if ((ret == 1) && (rsa->iqmp != NULL) &&
2788
                (wolfssl_bn_get_value(rsa->iqmp, &key->u) != 1)) {
2789
            WOLFSSL_ERROR_MSG("rsa u key error");
2790
            ret = WOLFSSL_FATAL_ERROR;
2791
        }
2792
#endif
2793
#endif
2794
2795
        if (ret == 1) {
2796
            /* All available numbers have been set down. */
2797
            rsa->inSet = 1;
2798
        }
2799
    }
2800
2801
    return ret;
2802
}
2803
2804
/* Set the RSA method into object.
2805
 *
2806
 * @param [in, out] rsa   RSA key.
2807
 * @param [in]      meth  RSA method.
2808
 * @return  1 always.
2809
 */
2810
int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth)
2811
{
2812
    if (rsa != NULL) {
2813
        /* Store the method into object. */
2814
        rsa->meth = meth;
2815
        /* Copy over flags. */
2816
        rsa->flags = meth->flags;
2817
    }
2818
    /* OpenSSL always assumes it will work. */
2819
    return 1;
2820
}
2821
2822
/* Get the RSA method from the RSA object.
2823
 *
2824
 * @param [in] rsa  RSA key.
2825
 * @return  RSA method on success.
2826
 * @return  NULL when RSA is NULL or no method set.
2827
 */
2828
const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa)
2829
{
2830
    return (rsa != NULL) ? rsa->meth : NULL;
2831
}
2832
2833
/* Get the size in bytes of the RSA key.
2834
 *
2835
 * Return compliant with OpenSSL
2836
 *
2837
 * @param [in] rsa  RSA key.
2838
 * @return  RSA modulus size in bytes.
2839
 * @return  0 on error.
2840
 */
2841
int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa)
2842
{
2843
    int ret = 0;
2844
2845
    WOLFSSL_ENTER("wolfSSL_RSA_size");
2846
2847
    if (rsa != NULL) {
2848
        /* Make sure we have set the RSA values into wolfCrypt RSA key. */
2849
        if (rsa->inSet || (SetRsaInternal((WOLFSSL_RSA*)rsa) == 1)) {
2850
            /* Get key size in bytes using wolfCrypt RSA key. */
2851
            ret = wc_RsaEncryptSize((RsaKey*)rsa->internal);
2852
        }
2853
    }
2854
2855
    return ret;
2856
}
2857
2858
/* Get the size in bits of the RSA key.
2859
 *
2860
 * Uses external modulus field.
2861
 *
2862
 * @param [in] rsa  RSA key.
2863
 * @return  RSA modulus size in bits.
2864
 * @return  0 on error.
2865
 */
2866
int wolfSSL_RSA_bits(const WOLFSSL_RSA* rsa)
2867
{
2868
    int ret = 0;
2869
2870
    WOLFSSL_ENTER("wolfSSL_RSA_bits");
2871
2872
    if (rsa != NULL) {
2873
        /* Get number of bits in external modulus. */
2874
        ret = wolfSSL_BN_num_bits(rsa->n);
2875
    }
2876
2877
    return ret;
2878
}
2879
2880
/* Get the BN objects that are the Chinese-Remainder Theorem (CRT) parameters.
2881
 *
2882
 * Only for those that are not NULL parameters.
2883
 *
2884
 * @param [in]  rsa   RSA key.
2885
 * @param [out] dmp1  BN that is d mod (p - 1). May be NULL.
2886
 * @param [out] dmq1  BN that is d mod (q - 1). May be NULL.
2887
 * @param [out] iqmp  BN that is 1/q mod p. May be NULL.
2888
 */
2889
void wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA *rsa,
2890
    const WOLFSSL_BIGNUM **dmp1, const WOLFSSL_BIGNUM **dmq1,
2891
    const WOLFSSL_BIGNUM **iqmp)
2892
{
2893
    WOLFSSL_ENTER("wolfSSL_RSA_get0_crt_params");
2894
2895
    /* For any parameters not NULL, return the BN from the key or NULL. */
2896
    if (dmp1 != NULL) {
2897
        *dmp1 = (rsa != NULL) ? rsa->dmp1 : NULL;
2898
    }
2899
    if (dmq1 != NULL) {
2900
        *dmq1 = (rsa != NULL) ? rsa->dmq1 : NULL;
2901
    }
2902
    if (iqmp != NULL) {
2903
        *iqmp = (rsa != NULL) ? rsa->iqmp : NULL;
2904
    }
2905
}
2906
2907
/* Set the BN objects that are the Chinese-Remainder Theorem (CRT) parameters
2908
 * into RSA key.
2909
 *
2910
 * If CRT parameter is NULL then there must be one in the RSA key already.
2911
 *
2912
 * @param [in, out] rsa   RSA key.
2913
 * @param [in]      dmp1  BN that is d mod (p - 1). May be NULL.
2914
 * @param [in]      dmq1  BN that is d mod (q - 1). May be NULL.
2915
 * @param [in]      iqmp  BN that is 1/q mod p. May be NULL.
2916
 * @return  1 on success.
2917
 * @return  0 on failure.
2918
 */
2919
int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *rsa, WOLFSSL_BIGNUM *dmp1,
2920
                                WOLFSSL_BIGNUM *dmq1, WOLFSSL_BIGNUM *iqmp)
2921
{
2922
    int ret = 1;
2923
2924
    WOLFSSL_ENTER("wolfSSL_RSA_set0_crt_params");
2925
2926
    /* If a param is NULL in rsa then it must be non-NULL in the
2927
     * corresponding user input. */
2928
    if ((rsa == NULL) || ((rsa->dmp1 == NULL) && (dmp1 == NULL)) ||
2929
            ((rsa->dmq1 == NULL) && (dmq1 == NULL)) ||
2930
            ((rsa->iqmp == NULL) && (iqmp == NULL))) {
2931
        WOLFSSL_ERROR_MSG("Bad parameters");
2932
        ret = 0;
2933
    }
2934
    if (ret == 1) {
2935
        /* Replace the BNs. */
2936
        if (dmp1 != NULL) {
2937
            wolfSSL_BN_clear_free(rsa->dmp1);
2938
            rsa->dmp1 = dmp1;
2939
        }
2940
        if (dmq1 != NULL) {
2941
            wolfSSL_BN_clear_free(rsa->dmq1);
2942
            rsa->dmq1 = dmq1;
2943
        }
2944
        if (iqmp != NULL) {
2945
            wolfSSL_BN_clear_free(rsa->iqmp);
2946
            rsa->iqmp = iqmp;
2947
        }
2948
2949
        /* Set the values into the wolfCrypt RSA key. */
2950
        if (SetRsaInternal(rsa) != 1) {
2951
            if (dmp1 != NULL) {
2952
                rsa->dmp1 = NULL;
2953
            }
2954
            if (dmq1 != NULL) {
2955
                rsa->dmq1 = NULL;
2956
            }
2957
            if (iqmp != NULL) {
2958
                rsa->iqmp = NULL;
2959
            }
2960
            ret = 0;
2961
        }
2962
    }
2963
2964
    return ret;
2965
}
2966
2967
/* Get the BN objects that are the factors of the RSA key (two primes p and q).
2968
 *
2969
 * @param [in]  rsa  RSA key.
2970
 * @param [out] p    BN that is first prime. May be NULL.
2971
 * @param [out] q    BN that is second prime. May be NULL.
2972
 */
2973
void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *rsa, const WOLFSSL_BIGNUM **p,
2974
                              const WOLFSSL_BIGNUM **q)
2975
{
2976
    WOLFSSL_ENTER("wolfSSL_RSA_get0_factors");
2977
2978
    /* For any primes not NULL, return the BN from the key or NULL. */
2979
    if (p != NULL) {
2980
        *p = (rsa != NULL) ? rsa->p : NULL;
2981
    }
2982
    if (q != NULL) {
2983
        *q = (rsa != NULL) ? rsa->q : NULL;
2984
    }
2985
}
2986
2987
/* Set the BN objects that are the factors of the RSA key (two primes p and q).
2988
 *
2989
 * If factor parameter is NULL then there must be one in the RSA key already.
2990
 *
2991
 * @param [in, out] rsa  RSA key.
2992
 * @param [in]      p    BN that is first prime. May be NULL.
2993
 * @param [in]      q    BN that is second prime. May be NULL.
2994
 * @return  1 on success.
2995
 * @return  0 on failure.
2996
 */
2997
int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *rsa, WOLFSSL_BIGNUM *p,
2998
    WOLFSSL_BIGNUM *q)
2999
{
3000
    int ret = 1;
3001
3002
    WOLFSSL_ENTER("wolfSSL_RSA_set0_factors");
3003
3004
    /* If a param is null in r then it must be non-null in the
3005
     * corresponding user input. */
3006
    if (rsa == NULL || ((rsa->p == NULL) && (p == NULL)) ||
3007
            ((rsa->q == NULL) && (q == NULL))) {
3008
        WOLFSSL_ERROR_MSG("Bad parameters");
3009
        ret = 0;
3010
    }
3011
    if (ret == 1) {
3012
        /* Replace the BNs. */
3013
        if (p != NULL) {
3014
            wolfSSL_BN_clear_free(rsa->p);
3015
            rsa->p = p;
3016
        }
3017
        if (q != NULL) {
3018
            wolfSSL_BN_clear_free(rsa->q);
3019
            rsa->q = q;
3020
        }
3021
3022
        /* Set the values into the wolfCrypt RSA key. */
3023
        if (SetRsaInternal(rsa) != 1) {
3024
             if (p != NULL) {
3025
                 rsa->p = NULL;
3026
             }
3027
             if (q != NULL) {
3028
                 rsa->q = NULL;
3029
             }
3030
             ret = 0;
3031
        }
3032
    }
3033
3034
    return ret;
3035
}
3036
3037
/* Get the BN objects for the basic key numbers of the RSA key (modulus, public
3038
 * exponent, private exponent).
3039
 *
3040
 * @param [in]  rsa  RSA key.
3041
 * @param [out] n    BN that is the modulus. May be NULL.
3042
 * @param [out] e    BN that is the public exponent. May be NULL.
3043
 * @param [out] d    BN that is the private exponent. May be NULL.
3044
 */
3045
void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *rsa, const WOLFSSL_BIGNUM **n,
3046
    const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d)
3047
{
3048
    WOLFSSL_ENTER("wolfSSL_RSA_get0_key");
3049
3050
    /* For any parameters not NULL, return the BN from the key or NULL. */
3051
    if (n != NULL) {
3052
        *n = (rsa != NULL) ? rsa->n : NULL;
3053
    }
3054
    if (e != NULL) {
3055
        *e = (rsa != NULL) ? rsa->e : NULL;
3056
    }
3057
    if (d != NULL) {
3058
        *d = (rsa != NULL) ? rsa->d : NULL;
3059
    }
3060
}
3061
3062
/* Set the BN objects for the basic key numbers into the RSA key (modulus,
3063
 * public exponent, private exponent).
3064
 *
3065
 * If BN parameter is NULL then there must be one in the RSA key already.
3066
 *
3067
 * @param [in,out]  rsa  RSA key.
3068
 * @param [in]      n    BN that is the modulus. May be NULL.
3069
 * @param [in]      e    BN that is the public exponent. May be NULL.
3070
 * @param [in]      d    BN that is the private exponent. May be NULL.
3071
 * @return  1 on success.
3072
 * @return  0 on failure.
3073
 */
3074
int wolfSSL_RSA_set0_key(WOLFSSL_RSA *rsa, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e,
3075
     WOLFSSL_BIGNUM *d)
3076
{
3077
    int ret = 1;
3078
3079
    /* If the fields n and e in r are NULL, the corresponding input
3080
     * parameters MUST be non-NULL for n and e.  d may be
3081
     * left NULL (in case only the public key is used).
3082
     */
3083
    if ((rsa == NULL) || ((rsa->n == NULL) && (n == NULL)) ||
3084
            ((rsa->e == NULL) && (e == NULL))) {
3085
        ret = 0;
3086
    }
3087
    if (ret == 1) {
3088
        /* Replace the BNs. */
3089
        if (n != NULL) {
3090
            wolfSSL_BN_free(rsa->n);
3091
            rsa->n = n;
3092
        }
3093
        if (e != NULL) {
3094
            wolfSSL_BN_free(rsa->e);
3095
            rsa->e = e;
3096
        }
3097
        if (d != NULL) {
3098
            /* Private key is sensitive data. */
3099
            wolfSSL_BN_clear_free(rsa->d);
3100
            rsa->d = d;
3101
        }
3102
3103
        /* Set the values into the wolfCrypt RSA key. */
3104
        if (SetRsaInternal(rsa) != 1) {
3105
            if (n != NULL) {
3106
                rsa->n = NULL;
3107
            }
3108
            if (e != NULL) {
3109
                rsa->e = NULL;
3110
            }
3111
            if (d != NULL) {
3112
                rsa->d = NULL;
3113
            }
3114
            ret = 0;
3115
        }
3116
    }
3117
3118
    return ret;
3119
}
3120
3121
/* Get the flags of the RSA key.
3122
 *
3123
 * @param [in] rsa  RSA key.
3124
 * @return  Flags set in RSA key on success.
3125
 * @return  0 when RSA key is NULL.
3126
 */
3127
int wolfSSL_RSA_flags(const WOLFSSL_RSA *rsa)
3128
{
3129
    int ret = 0;
3130
3131
    /* Get flags from the RSA key if available. */
3132
    if (rsa != NULL) {
3133
        ret = rsa->flags;
3134
    }
3135
3136
    return ret;
3137
}
3138
3139
/* Set the flags into the RSA key.
3140
 *
3141
 * @param [in, out] rsa    RSA key.
3142
 * @param [in]      flags  Flags to set.
3143
 */
3144
void wolfSSL_RSA_set_flags(WOLFSSL_RSA *rsa, int flags)
3145
{
3146
    /* Add the flags into RSA key if available. */
3147
    if (rsa != NULL) {
3148
        rsa->flags |= flags;
3149
    }
3150
}
3151
3152
/* Clear the flags in the RSA key.
3153
 *
3154
 * @param [in, out] rsa    RSA key.
3155
 * @param [in]      flags  Flags to clear.
3156
 */
3157
void wolfSSL_RSA_clear_flags(WOLFSSL_RSA *rsa, int flags)
3158
{
3159
    /* Clear the flags passed in that are on the RSA key if available. */
3160
    if (rsa != NULL) {
3161
        rsa->flags &= ~flags;
3162
    }
3163
}
3164
3165
/* Test the flags in the RSA key.
3166
 *
3167
 * @param [in] rsa  RSA key.
3168
 * @return  Matching flags of RSA key on success.
3169
 * @return  0 when RSA key is NULL.
3170
 */
3171
int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *rsa, int flags)
3172
{
3173
    /* Return the flags passed in that are set on the RSA key if available. */
3174
    return (rsa != NULL) ?  (rsa->flags & flags) : 0;
3175
}
3176
3177
/* Get the extra data, by index, associated with the RSA key.
3178
 *
3179
 * @param [in] rsa  RSA key.
3180
 * @param [in] idx  Index of extra data.
3181
 * @return  Extra data (anonymous type) on success.
3182
 * @return  NULL on failure.
3183
 */
3184
void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx)
3185
{
3186
    WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data");
3187
3188
#ifdef HAVE_EX_DATA
3189
    return (rsa == NULL) ? NULL :
3190
        wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx);
3191
#else
3192
    (void)rsa;
3193
    (void)idx;
3194
3195
    return NULL;
3196
#endif
3197
}
3198
3199
/* Set extra data against the RSA key at an index.
3200
 *
3201
 * @param [in, out] rsa   RSA key.
3202
 * @param [in]      idx   Index set set extra data at.
3203
 * @param [in]      data  Extra data of anonymous type.
3204
 * @return 1 on success.
3205
 * @return 0 on failure.
3206
 */
3207
int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data)
3208
{
3209
    WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data");
3210
3211
#ifdef HAVE_EX_DATA
3212
    return (rsa == NULL) ? 0 :
3213
        wolfSSL_CRYPTO_set_ex_data(&rsa->ex_data, idx, data);
3214
#else
3215
    (void)rsa;
3216
    (void)idx;
3217
    (void)data;
3218
3219
    return 0;
3220
#endif
3221
}
3222
3223
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
3224
/* Set the extra data and cleanup callback against the RSA key at an index.
3225
 *
3226
 * Not OpenSSL API.
3227
 *
3228
 * @param [in, out] rsa     RSA key.
3229
 * @param [in]      idx     Index set set extra data at.
3230
 * @param [in]      data    Extra data of anonymous type.
3231
 * @param [in]      freeCb  Callback function to free extra data.
3232
 * @return 1 on success.
3233
 * @return 0 on failure.
3234
 */
3235
int wolfSSL_RSA_set_ex_data_with_cleanup(WOLFSSL_RSA *rsa, int idx, void *data,
3236
    wolfSSL_ex_data_cleanup_routine_t freeCb)
3237
{
3238
    WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data_with_cleanup");
3239
3240
    return (rsa == NULL) ? 0 :
3241
        wolfSSL_CRYPTO_set_ex_data_with_cleanup(&rsa->ex_data, idx, data,
3242
            freeCb);
3243
}
3244
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
3245
3246
/*
3247
 * RSA check key APIs
3248
 */
3249
3250
#ifdef WOLFSSL_RSA_KEY_CHECK
3251
/* Check that the RSA key is valid using wolfCrypt.
3252
 *
3253
 * @param [in] rsa  RSA key.
3254
 * @return  1 on success.
3255
 * @return  0 on failure.
3256
 */
3257
int wolfSSL_RSA_check_key(const WOLFSSL_RSA* rsa)
3258
{
3259
    int ret = 1;
3260
3261
    WOLFSSL_ENTER("wolfSSL_RSA_check_key");
3262
3263
    /* Validate parameters. */
3264
    if ((rsa == NULL) || (rsa->internal == NULL)) {
3265
        ret = 0;
3266
    }
3267
3268
    /* Constant RSA - assume internal data has been set. */
3269
3270
    /* Check wolfCrypt RSA key. */
3271
    if ((ret == 1) && (wc_CheckRsaKey((RsaKey*)rsa->internal) != 0)) {
3272
        ret = 0;
3273
    }
3274
3275
    WOLFSSL_LEAVE("wolfSSL_RSA_check_key", ret);
3276
3277
    return ret;
3278
}
3279
#endif /* WOLFSSL_RSA_KEY_CHECK */
3280
3281
/*
3282
 * RSA generate APIs
3283
 */
3284
3285
/* Get a random number generator associated with the RSA key.
3286
 *
3287
 * If not able, then get the global if possible.
3288
 * *tmpRng must not be an initialized RNG.
3289
 * *tmpRng is allocated when WOLFSSL_SMALL_STACK is defined and an RNG isn't
3290
 * associated with the wolfCrypt RSA key.
3291
 *
3292
 * @param [in]  rsa         RSA key.
3293
 * @param [out] tmpRng      Temporary random number generator.
3294
 * @param [out] initTmpRng  Temporary random number generator was initialized.
3295
 *
3296
 * @return  A wolfCrypt RNG to use on success.
3297
 * @return  NULL on error.
3298
 */
3299
WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA* rsa, WC_RNG** tmpRng, int* initTmpRng)
3300
{
3301
    WC_RNG* rng = NULL;
3302
    int err = 0;
3303
3304
    /* Check validity of parameters. */
3305
    if ((rsa == NULL) || (initTmpRng == NULL)) {
3306
        err = 1;
3307
    }
3308
    if (!err) {
3309
        /* Haven't initialized any RNG passed through tmpRng. */
3310
        *initTmpRng = 0;
3311
3312
    #if !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING)
3313
        /* Use wolfCrypt RSA key's RNG if available/set. */
3314
        rng = ((RsaKey*)rsa->internal)->rng;
3315
    #endif
3316
    }
3317
    if ((!err) && (rng == NULL) && (tmpRng != NULL)) {
3318
        /* Make an RNG with tmpRng or get global. */
3319
        rng = wolfssl_make_rng(*tmpRng, initTmpRng);
3320
        if ((rng != NULL) && *initTmpRng) {
3321
            *tmpRng = rng;
3322
        }
3323
    }
3324
3325
    return rng;
3326
}
3327
3328
/* Use the wolfCrypt RSA APIs to generate a new RSA key.
3329
 *
3330
 * @param [in, out] rsa   RSA key.
3331
 * @param [in]      bits  Number of bits that the modulus must have.
3332
 * @param [in]      e     A BN object holding the public exponent to use.
3333
 * @param [in]      cb    Status callback. Unused.
3334
 * @return 0 on success.
3335
 * @return wolfSSL native error code on error.
3336
 */
3337
static int wolfssl_rsa_generate_key_native(WOLFSSL_RSA* rsa, int bits,
3338
    WOLFSSL_BIGNUM* e, void* cb)
3339
{
3340
#ifdef WOLFSSL_KEY_GEN
3341
    int ret = 0;
3342
#ifdef WOLFSSL_SMALL_STACK
3343
    WC_RNG* tmpRng = NULL;
3344
#else
3345
    WC_RNG  _tmpRng[1];
3346
    WC_RNG* tmpRng = _tmpRng;
3347
#endif
3348
    int initTmpRng = 0;
3349
    WC_RNG* rng = NULL;
3350
    long en = 0;
3351
#endif
3352
3353
    (void)cb;
3354
3355
    WOLFSSL_ENTER("wolfssl_rsa_generate_key_native");
3356
3357
#ifdef WOLFSSL_KEY_GEN
3358
    /* Get RNG in wolfCrypt RSA key or initialize a new one (or global). */
3359
    rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
3360
    if (rng == NULL) {
3361
        /* Something went wrong so return memory error. */
3362
        ret = MEMORY_E;
3363
    }
3364
    if ((ret == 0) && ((en = (long)wolfSSL_BN_get_word(e)) <= 0)) {
3365
        ret = BAD_FUNC_ARG;
3366
    }
3367
    if (ret == 0) {
3368
        /* Generate an RSA key. */
3369
        ret = wc_MakeRsaKey((RsaKey*)rsa->internal, bits, en, rng);
3370
        if (ret != MP_OKAY) {
3371
            WOLFSSL_ERROR_MSG("wc_MakeRsaKey failed");
3372
        }
3373
    }
3374
    if (ret == 0) {
3375
        /* Get the values from wolfCrypt RSA key into external RSA key. */
3376
        ret = SetRsaExternal(rsa);
3377
        if (ret == 1) {
3378
            /* Internal matches external. */
3379
            rsa->inSet = 1;
3380
            /* Return success. */
3381
            ret = 0;
3382
        }
3383
        else {
3384
            /* Something went wrong so return memory error. */
3385
            ret = MEMORY_E;
3386
        }
3387
    }
3388
3389
    /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */
3390
    if (initTmpRng) {
3391
        wc_FreeRng(tmpRng);
3392
    }
3393
#ifdef WOLFSSL_SMALL_STACK
3394
    /* Dispose of any allocated RNG. */
3395
    XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
3396
#endif
3397
3398
    return ret;
3399
#else
3400
    WOLFSSL_ERROR_MSG("No Key Gen built in");
3401
3402
    (void)rsa;
3403
    (void)e;
3404
    (void)bits;
3405
3406
    return NOT_COMPILED_IN;
3407
#endif
3408
}
3409
3410
/* Generate an RSA key that has the specified modulus size and public exponent.
3411
 *
3412
 * Note: Because of wc_MakeRsaKey an RSA key size generated can be rounded
3413
 *       down to nearest multiple of 8. For example generating a key of size
3414
 *       2999 bits will make a key of size 374 bytes instead of 375 bytes.
3415
 *
3416
 * @param [in]      bits  Number of bits that the modulus must have i.e. 2048.
3417
 * @param [in]      e     Public exponent to use i.e. 65537.
3418
 * @param [in]      cb    Status callback. Unused.
3419
 * @param [in]      data  Data to pass to status callback. Unused.
3420
 * @return  A new RSA key on success.
3421
 * @return  NULL on failure.
3422
 */
3423
WOLFSSL_RSA* wolfSSL_RSA_generate_key(int bits, unsigned long e,
3424
    void(*cb)(int, int, void*), void* data)
3425
{
3426
    WOLFSSL_RSA*    rsa = NULL;
3427
    WOLFSSL_BIGNUM* bn  = NULL;
3428
    int             err = 0;
3429
3430
    WOLFSSL_ENTER("wolfSSL_RSA_generate_key");
3431
3432
    (void)cb;
3433
    (void)data;
3434
3435
    /* Validate bits. */
3436
    if (bits < 0) {
3437
        WOLFSSL_ERROR_MSG("Bad argument: bits was less than 0");
3438
        err = 1;
3439
    }
3440
    /* Create a new BN to hold public exponent - for when wolfCrypt supports
3441
     * longer values. */
3442
    if ((!err) && ((bn = wolfSSL_BN_new()) == NULL)) {
3443
        WOLFSSL_ERROR_MSG("Error creating big number");
3444
        err = 1;
3445
    }
3446
    /* Set public exponent. */
3447
    if ((!err) && (wolfSSL_BN_set_word(bn, e) != 1)) {
3448
        WOLFSSL_ERROR_MSG("Error using e value");
3449
        err = 1;
3450
    }
3451
3452
    /* Create an RSA key object to hold generated key. */
3453
    if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) {
3454
        WOLFSSL_ERROR_MSG("memory error");
3455
        err = 1;
3456
    }
3457
    while (!err) {
3458
        int ret;
3459
3460
        /* Use wolfCrypt to generate RSA key. */
3461
        ret = wolfssl_rsa_generate_key_native(rsa, bits, bn, NULL);
3462
    #ifdef HAVE_FIPS
3463
        /* Keep trying if failed to find a prime. */
3464
        if (ret == WC_NO_ERR_TRACE(PRIME_GEN_E)) {
3465
            continue;
3466
        }
3467
    #endif
3468
        if (ret != WOLFSSL_ERROR_NONE) {
3469
            /* Unrecoverable error in generation. */
3470
            err = 1;
3471
        }
3472
        /* Done generating - unrecoverable error or success. */
3473
        break;
3474
    }
3475
    if (err) {
3476
        /* Dispose of RSA key object if generation didn't work. */
3477
        wolfSSL_RSA_free(rsa);
3478
        /* Returning NULL on error. */
3479
        rsa = NULL;
3480
    }
3481
    /* Dispose of the temporary BN used for the public exponent. */
3482
    wolfSSL_BN_free(bn);
3483
3484
    return rsa;
3485
}
3486
3487
/* Generate an RSA key that has the specified modulus size and public exponent.
3488
 *
3489
 * Note: Because of wc_MakeRsaKey an RSA key size generated can be rounded
3490
 *       down to nearest multiple of 8. For example generating a key of size
3491
 *       2999 bits will make a key of size 374 bytes instead of 375 bytes.
3492
 *
3493
 * @param [in]      bits  Number of bits that the modulus must have i.e. 2048.
3494
 * @param [in]      e     Public exponent to use, i.e. 65537, as a BN.
3495
 * @param [in]      cb    Status callback. Unused.
3496
 * @return 1 on success.
3497
 * @return 0 on failure.
3498
 */
3499
int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* e,
3500
    void* cb)
3501
{
3502
    int ret = 1;
3503
3504
    /* Validate parameters. */
3505
    if ((rsa == NULL) || (rsa->internal == NULL)) {
3506
        WOLFSSL_ERROR_MSG("bad arguments");
3507
        ret = 0;
3508
    }
3509
    else {
3510
        for (;;) {
3511
            /* Use wolfCrypt to generate RSA key. */
3512
            int gen_ret = wolfssl_rsa_generate_key_native(rsa, bits, e, cb);
3513
        #ifdef HAVE_FIPS
3514
            /* Keep trying again if public key value didn't work. */
3515
            if (gen_ret == WC_NO_ERR_TRACE(PRIME_GEN_E)) {
3516
                continue;
3517
            }
3518
        #endif
3519
            if (gen_ret != WOLFSSL_ERROR_NONE) {
3520
                /* Unrecoverable error in generation. */
3521
                ret = 0;
3522
            }
3523
            /* Done generating - unrecoverable error or success. */
3524
            break;
3525
        }
3526
    }
3527
3528
    return ret;
3529
}
3530
3531
#endif /* OPENSSL_EXTRA */
3532
3533
/*
3534
 * RSA padding APIs
3535
 */
3536
3537
#ifdef WC_RSA_PSS
3538
3539
#if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) && \
3540
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
3541
static int rsa_pss_calc_salt(int saltLen, int hashLen, int emLen)
3542
{
3543
    /* Calculate the salt length to use for special cases. */
3544
    switch (saltLen) {
3545
        /* Negative saltLen values are treated differently. */
3546
        case WC_RSA_PSS_SALTLEN_DIGEST:
3547
            saltLen = hashLen;
3548
            break;
3549
        case WC_RSA_PSS_SALTLEN_MAX_SIGN:
3550
        case WC_RSA_PSS_SALTLEN_MAX:
3551
        #ifdef WOLFSSL_PSS_LONG_SALT
3552
            saltLen = emLen - hashLen - 2;
3553
        #else
3554
            saltLen = hashLen;
3555
            (void)emLen;
3556
        #endif
3557
            break;
3558
        default:
3559
            break;
3560
    }
3561
    if (saltLen < 0) {
3562
        /* log invalid salt, let wolfCrypt handle error */
3563
        WOLFSSL_ERROR_MSG("invalid saltLen");
3564
        saltLen = -3; /* for wolfCrypt to produce error must be < -2 */
3565
    }
3566
    return saltLen;
3567
}
3568
#endif /* OPENSSL_EXTRA && !HAVE_SELFTEST */
3569
3570
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \
3571
     defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)) && \
3572
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
3573
3574
/* Add PKCS#1 PSS padding to hash.
3575
 *
3576
 *
3577
 *                                +-----------+
3578
 *                                |     M     |
3579
 *                                +-----------+
3580
 *                                      |
3581
 *                                      V
3582
 *                                    Hash
3583
 *                                      |
3584
 *                                      V
3585
 *                        +--------+----------+----------+
3586
 *                   M' = |Padding1|  mHash   |   salt   |
3587
 *                        +--------+----------+----------+
3588
 *                                       |
3589
 *             +--------+----------+     V
3590
 *       DB =  |Padding2|maskedseed|   Hash
3591
 *             +--------+----------+     |
3592
 *                       |               |
3593
 *                       V               |    +--+
3594
 *                      xor <--- MGF <---|    |bc|
3595
 *                       |               |    +--+
3596
 *                       |               |      |
3597
 *                       V               V      V
3598
 *             +-------------------+----------+--+
3599
 *       EM =  |    maskedDB       |maskedseed|bc|
3600
 *             +-------------------+----------+--+
3601
 * Diagram taken from https://tools.ietf.org/html/rfc3447#section-9.1
3602
 *
3603
 * @param [in]  rsa      RSA key.
3604
 * @param [out] em       Encoded message.
3605
 * @param [in[  mHash    Message hash.
3606
 * @param [in]  hashAlg  Hash algorithm.
3607
 * @param [in]  mgf1Hash MGF algorithm.
3608
 * @param [in]  saltLen  Length of salt to generate.
3609
 * @return  1 on success.
3610
 * @return  0 on failure.
3611
 */
3612
3613
int wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa, unsigned char *em,
3614
        const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg,
3615
        const WOLFSSL_EVP_MD *mgf1Hash, int saltLen)
3616
{
3617
    int ret = 1;
3618
    enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3619
    int hashLen = 0;
3620
    int emLen = 0;
3621
    int mgf = 0;
3622
    int initTmpRng = 0;
3623
    WC_RNG *rng = NULL;
3624
#ifdef WOLFSSL_SMALL_STACK
3625
    WC_RNG* tmpRng = NULL;
3626
#else
3627
    WC_RNG  _tmpRng[1];
3628
    WC_RNG* tmpRng = _tmpRng;
3629
#endif
3630
3631
    WOLFSSL_ENTER("wolfSSL_RSA_padding_add_PKCS1_PSS");
3632
3633
    /* Validate parameters. */
3634
    if ((rsa == NULL) || (em == NULL) || (mHash == NULL) || (hashAlg == NULL)) {
3635
        ret = 0;
3636
    }
3637
3638
    if (mgf1Hash == NULL)
3639
        mgf1Hash = hashAlg;
3640
3641
    if (ret == 1) {
3642
        /* Get/create an RNG. */
3643
        rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
3644
        if (rng == NULL) {
3645
            WOLFSSL_ERROR_MSG("WOLFSSL_RSA_GetRNG error");
3646
            ret = 0;
3647
        }
3648
    }
3649
3650
    /* TODO: use wolfCrypt RSA key to get emLen and bits? */
3651
    /* Set the external data from the wolfCrypt RSA key if not done. */
3652
    if ((ret == 1) && (!rsa->exSet)) {
3653
        ret = SetRsaExternal(rsa);
3654
    }
3655
3656
    if (ret == 1) {
3657
        /* Get the wolfCrypt hash algorithm type. */
3658
        hashType = EvpMd2MacType(hashAlg);
3659
        if (hashType > WC_HASH_TYPE_MAX) {
3660
            WOLFSSL_ERROR_MSG("EvpMd2MacType error");
3661
            ret = 0;
3662
        }
3663
    }
3664
    if (ret == 1) {
3665
        /* Get the wolfCrypt MGF algorithm from hash algorithm. */
3666
        mgf = wc_hash2mgf(EvpMd2MacType(mgf1Hash));
3667
        if (mgf == WC_MGF1NONE) {
3668
            WOLFSSL_ERROR_MSG("wc_hash2mgf error");
3669
            ret = 0;
3670
        }
3671
    }
3672
    if (ret == 1) {
3673
        /* Get the length of the hash output. */
3674
        hashLen = wolfSSL_EVP_MD_size(hashAlg);
3675
        if (hashLen < 0) {
3676
            WOLFSSL_ERROR_MSG("wolfSSL_EVP_MD_size error");
3677
            ret = 0;
3678
        }
3679
    }
3680
3681
    if (ret == 1) {
3682
        /* Get length of RSA key - encrypted message length. */
3683
        emLen = wolfSSL_RSA_size(rsa);
3684
        if (emLen <= 0) {
3685
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_size error");
3686
            ret = 0;
3687
        }
3688
    }
3689
3690
    if (ret == 1) {
3691
        saltLen = rsa_pss_calc_salt(saltLen, hashLen, emLen);
3692
    }
3693
3694
    if (ret == 1) {
3695
        /* Generate RSA PKCS#1 PSS padding for hash using wolfCrypt. */
3696
        if (wc_RsaPad_ex(mHash, (word32)hashLen, em, (word32)emLen,
3697
                RSA_BLOCK_TYPE_1, rng, WC_RSA_PSS_PAD, hashType, mgf, NULL, 0,
3698
                saltLen, wolfSSL_BN_num_bits(rsa->n), NULL) != MP_OKAY) {
3699
            WOLFSSL_ERROR_MSG("wc_RsaPad_ex error");
3700
            ret = 0;
3701
        }
3702
    }
3703
3704
    /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */
3705
    if (initTmpRng) {
3706
        wc_FreeRng(tmpRng);
3707
    }
3708
#ifdef WOLFSSL_SMALL_STACK
3709
    /* Dispose of any allocated RNG. */
3710
    XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
3711
#endif
3712
3713
    return ret;
3714
}
3715
3716
int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
3717
    const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, int saltLen)
3718
{
3719
    return wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(rsa, em, mHash, hashAlg, NULL,
3720
            saltLen);
3721
}
3722
3723
/* Checks that the hash is valid for the RSA PKCS#1 PSS encoded message.
3724
 *
3725
 * Refer to wolfSSL_RSA_padding_add_PKCS1_PSS for a diagram.
3726
 *
3727
 * @param [in]  rsa      RSA key.
3728
 * @param [in[  mHash    Message hash.
3729
 * @param [in]  hashAlg  Hash algorithm.
3730
 * @param [in]  mgf1Hash MGF algorithm.
3731
 * @param [in]  em       Encoded message.
3732
 * @param [in]  saltLen  Length of salt to generate.
3733
 * @return  1 on success.
3734
 * @return  0 on failure.
3735
 */
3736
int wolfSSL_RSA_verify_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa,
3737
        const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg,
3738
        const WOLFSSL_EVP_MD *mgf1Hash, const unsigned char *em, int saltLen)
3739
{
3740
    int ret = 1;
3741
    int hashLen = 0;
3742
    int mgf = 0;
3743
    int emLen = 0;
3744
    int mPrimeLen = 0;
3745
    enum wc_HashType hashType = WC_HASH_TYPE_NONE;
3746
    byte *mPrime = NULL;
3747
    byte *buf = NULL;
3748
3749
    WOLFSSL_ENTER("wolfSSL_RSA_verify_PKCS1_PSS");
3750
3751
    /* Validate parameters. */
3752
    if ((rsa == NULL) || (mHash == NULL) || (hashAlg == NULL) || (em == NULL)) {
3753
        ret = 0;
3754
    }
3755
3756
    if (mgf1Hash == NULL)
3757
        mgf1Hash = hashAlg;
3758
3759
    /* TODO: use wolfCrypt RSA key to get emLen and bits? */
3760
    /* Set the external data from the wolfCrypt RSA key if not done. */
3761
    if ((ret == 1) && (!rsa->exSet)) {
3762
        ret = SetRsaExternal(rsa);
3763
    }
3764
3765
    if (ret == 1) {
3766
        /* Get hash length for hash algorithm. */
3767
        hashLen = wolfSSL_EVP_MD_size(hashAlg);
3768
        if (hashLen < 0) {
3769
            ret = 0;
3770
        }
3771
    }
3772
3773
    if (ret == 1) {
3774
        /* Get length of RSA key - encrypted message length. */
3775
        emLen = wolfSSL_RSA_size(rsa);
3776
        if (emLen <= 0) {
3777
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_size error");
3778
            ret = 0;
3779
        }
3780
    }
3781
3782
    if (ret == 1) {
3783
        saltLen = rsa_pss_calc_salt(saltLen, hashLen, emLen);
3784
    }
3785
3786
    if (ret == 1) {
3787
        /* Get the wolfCrypt hash algorithm type. */
3788
        hashType = EvpMd2MacType(hashAlg);
3789
        if (hashType > WC_HASH_TYPE_MAX) {
3790
            WOLFSSL_ERROR_MSG("EvpMd2MacType error");
3791
            ret = 0;
3792
        }
3793
    }
3794
3795
    if (ret == 1) {
3796
        /* Get the wolfCrypt MGF algorithm from hash algorithm. */
3797
        if ((mgf = wc_hash2mgf(EvpMd2MacType(mgf1Hash))) == WC_MGF1NONE) {
3798
            WOLFSSL_ERROR_MSG("wc_hash2mgf error");
3799
            ret = 0;
3800
        }
3801
    }
3802
3803
    if (ret == 1) {
3804
        /* Allocate buffer to unpad inline with. */
3805
        buf = (byte*)XMALLOC((size_t)emLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3806
        if (buf == NULL) {
3807
            WOLFSSL_ERROR_MSG("malloc error");
3808
            ret = 0;
3809
        }
3810
    }
3811
3812
    if (ret == 1) {
3813
        /* Copy encrypted message to temp for inline unpadding. */
3814
        XMEMCPY(buf, em, (size_t)emLen);
3815
3816
        /* Remove and verify the PSS padding. */
3817
        mPrimeLen = wc_RsaUnPad_ex(buf, (word32)emLen, &mPrime,
3818
            RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, hashType, mgf, NULL, 0, saltLen,
3819
            wolfSSL_BN_num_bits(rsa->n), NULL);
3820
        if (mPrimeLen < 0) {
3821
            WOLFSSL_ERROR_MSG("wc_RsaPad_ex error");
3822
            ret = 0;
3823
        }
3824
    }
3825
3826
    if (ret == 1) {
3827
        /* Verify the hash is correct. */
3828
        if (wc_RsaPSS_CheckPadding_ex(mHash, (word32)hashLen, mPrime,
3829
                (word32)mPrimeLen, hashType, saltLen,
3830
                wolfSSL_BN_num_bits(rsa->n)) != MP_OKAY) {
3831
            WOLFSSL_ERROR_MSG("wc_RsaPSS_CheckPadding_ex error");
3832
            ret = 0;
3833
        }
3834
    }
3835
3836
    /* Dispose of any allocated buffer. */
3837
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3838
    return ret;
3839
}
3840
3841
int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
3842
                                 const WOLFSSL_EVP_MD *hashAlg,
3843
                                 const unsigned char *em, int saltLen)
3844
{
3845
    return wolfSSL_RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, hashAlg, NULL, em,
3846
            saltLen);
3847
}
3848
#endif /* (!HAVE_FIPS || FIPS_VERSION_GT(2,0)) && \
3849
          (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_NGINX) */
3850
#endif /* WC_RSA_PSS */
3851
3852
/*
3853
 * RSA sign/verify APIs
3854
 */
3855
3856
#if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \
3857
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1))
3858
    #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
3859
        #define DEF_PSS_SALT_LEN    RSA_PSS_SALT_LEN_DEFAULT
3860
    #else
3861
        #define DEF_PSS_SALT_LEN    RSA_PSS_SALT_LEN_DISCOVER
3862
    #endif
3863
#else
3864
    #define DEF_PSS_SALT_LEN 0 /* not used */
3865
#endif
3866
3867
#if defined(OPENSSL_EXTRA)
3868
3869
/* Encode the message hash.
3870
 *
3871
 * Used by signing and verification.
3872
 *
3873
 * @param [in]  hashAlg   Hash algorithm OID.
3874
 * @param [in]  hash      Hash of message to encode for signing.
3875
 * @param [in]  hLen      Length of hash of message.
3876
 * @param [out] enc       Encoded message hash.
3877
 * @param [out] encLen    Length of encoded message hash.
3878
 * @param [in]  padding   Which padding scheme is being used.
3879
 * @return  1 on success.
3880
 * @return  0 on failure.
3881
 */
3882
static int wolfssl_rsa_sig_encode(int hashAlg, const unsigned char* hash,
3883
    unsigned int hLen, unsigned char* enc, unsigned int* encLen, int padding)
3884
{
3885
    int ret = 1;
3886
    int hType = WC_HASH_TYPE_NONE;
3887
3888
    /* Validate parameters. */
3889
    if ((hash == NULL) || (enc == NULL) || (encLen == NULL)) {
3890
        ret = 0;
3891
    }
3892
3893
    if ((ret == 1) && (hashAlg != WC_NID_undef) &&
3894
            (padding == WC_RSA_PKCS1_PADDING)) {
3895
        /* Convert hash algorithm to hash type for PKCS#1.5 padding. */
3896
        hType = (int)nid2oid(hashAlg, oidHashType);
3897
        if (hType == -1) {
3898
            ret = 0;
3899
        }
3900
    }
3901
    if ((ret == 1) && (padding == WC_RSA_PKCS1_PADDING)) {
3902
        /* PKCS#1.5 encoding. */
3903
        word32 encSz = wc_EncodeSignature(enc, hash, hLen, hType);
3904
        if (encSz == 0) {
3905
            WOLFSSL_ERROR_MSG("Bad Encode Signature");
3906
            ret = 0;
3907
        }
3908
        else  {
3909
            *encLen = (unsigned int)encSz;
3910
        }
3911
    }
3912
    /* Other padding schemes require the hash as is. */
3913
    if ((ret == 1) && (padding != WC_RSA_PKCS1_PADDING)) {
3914
        XMEMCPY(enc, hash, hLen);
3915
        *encLen = hLen;
3916
    }
3917
3918
    return ret;
3919
}
3920
3921
/* Sign the message hash using hash algorithm and RSA key.
3922
 *
3923
 * @param [in]  hashAlg   Hash algorithm OID.
3924
 * @param [in]  hash      Hash of message to encode for signing.
3925
 * @param [in]  hLen      Length of hash of message.
3926
 * @param [out] enc       Encoded message hash.
3927
 * @param [out] encLen    Length of encoded message hash.
3928
 * @param [in]  rsa       RSA key.
3929
 * @return  1 on success.
3930
 * @return  0 on failure.
3931
 */
3932
int wolfSSL_RSA_sign(int hashAlg, const unsigned char* hash, unsigned int hLen,
3933
    unsigned char* sigRet, unsigned int* sigLen, WOLFSSL_RSA* rsa)
3934
{
3935
    if (sigLen != NULL) {
3936
        /* No size checking in this API */
3937
        *sigLen = RSA_MAX_SIZE / CHAR_BIT;
3938
    }
3939
    /* flag is 1: output complete signature. */
3940
    return wolfSSL_RSA_sign_generic_padding(hashAlg, hash, hLen, sigRet,
3941
        sigLen, rsa, 1, WC_RSA_PKCS1_PADDING);
3942
}
3943
3944
/* Sign the message hash using hash algorithm and RSA key.
3945
 *
3946
 * Not OpenSSL API.
3947
 *
3948
 * @param [in]  hashAlg   Hash algorithm NID.
3949
 * @param [in]  hash      Hash of message to encode for signing.
3950
 * @param [in]  hLen      Length of hash of message.
3951
 * @param [out] enc       Encoded message hash.
3952
 * @param [out] encLen    Length of encoded message hash.
3953
 * @param [in]  rsa       RSA key.
3954
 * @param [in]  flag      When 1: Output encrypted signature.
3955
 *                        When 0: Output encoded hash.
3956
 * @return  1 on success.
3957
 * @return  0 on failure.
3958
 */
3959
int wolfSSL_RSA_sign_ex(int hashAlg, const unsigned char* hash,
3960
    unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen,
3961
    WOLFSSL_RSA* rsa, int flag)
3962
{
3963
    int ret = 0;
3964
3965
    if ((flag == 0) || (flag == 1)) {
3966
        if (sigLen != NULL) {
3967
            /* No size checking in this API */
3968
            *sigLen = RSA_MAX_SIZE / CHAR_BIT;
3969
        }
3970
        ret = wolfSSL_RSA_sign_generic_padding(hashAlg, hash, hLen, sigRet,
3971
            sigLen, rsa, flag, WC_RSA_PKCS1_PADDING);
3972
    }
3973
3974
    return ret;
3975
}
3976
3977
int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
3978
    unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen,
3979
    WOLFSSL_RSA* rsa, int flag, int padding)
3980
{
3981
    return wolfSSL_RSA_sign_mgf(hashAlg, hash, hLen, sigRet, sigLen, rsa, flag,
3982
        padding, hashAlg, DEF_PSS_SALT_LEN);
3983
}
3984
3985
/**
3986
 * Sign a message hash with the chosen message digest, padding, and RSA key.
3987
 *
3988
 * Not OpenSSL API.
3989
 *
3990
 * @param [in]      hashAlg  Hash NID
3991
 * @param [in]      hash     Message hash to sign.
3992
 * @param [in]      mLen     Length of message hash to sign.
3993
 * @param [out]     sigRet   Output buffer.
3994
 * @param [in, out] sigLen   On Input: length of sigRet buffer.
3995
 *                           On Output: length of data written to sigRet.
3996
 * @param [in]      rsa      RSA key used to sign the input.
3997
 * @param [in]      flag     1: Output the signature.
3998
 *                           0: Output the value that the unpadded signature
3999
 *                              should be compared to.
4000
 * @param [in]      padding  Padding to use. Only RSA_PKCS1_PSS_PADDING and
4001
 *                           WC_RSA_PKCS1_PADDING are currently supported for
4002
 *                           signing.
4003
 * @param [in]      mgf1Hash MGF1 Hash NID
4004
 * @param [in]      saltLen  Length of RSA PSS salt
4005
 * @return  1 on success.
4006
 * @return  0 on failure.
4007
 */
4008
int wolfSSL_RSA_sign_mgf(int hashAlg, const unsigned char* hash,
4009
    unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen,
4010
    WOLFSSL_RSA* rsa, int flag, int padding, int mgf1Hash, int saltLen)
4011
{
4012
    int     ret        = 1;
4013
    word32  outLen     = 0;
4014
    int     signSz     = 0;
4015
    WC_RNG* rng        = NULL;
4016
    int     initTmpRng = 0;
4017
#ifdef WOLFSSL_SMALL_STACK
4018
    WC_RNG* tmpRng     = NULL;
4019
    byte*   encodedSig = NULL;
4020
#else
4021
    WC_RNG  _tmpRng[1];
4022
    WC_RNG* tmpRng = _tmpRng;
4023
    byte    encodedSig[MAX_ENCODED_SIG_SZ];
4024
#endif
4025
    unsigned int encSz = 0;
4026
4027
    WOLFSSL_ENTER("wolfSSL_RSA_sign_mgf");
4028
4029
    if (flag == 0) {
4030
        /* Only encode message. */
4031
        return wolfssl_rsa_sig_encode(hashAlg, hash, hLen, sigRet, sigLen,
4032
            padding);
4033
    }
4034
4035
    /* Validate parameters. */
4036
    if ((hash == NULL) || (sigRet == NULL) || sigLen == NULL || rsa == NULL) {
4037
        WOLFSSL_ERROR_MSG("Bad function arguments");
4038
        ret = 0;
4039
    }
4040
4041
    /* Set wolfCrypt RSA key data from external if not already done. */
4042
    if ((ret == 1) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) {
4043
        ret = 0;
4044
    }
4045
4046
    if (ret == 1) {
4047
        /* Get the maximum signature length. */
4048
        outLen = (word32)wolfSSL_BN_num_bytes(rsa->n);
4049
        /* Check not an error return. */
4050
        if (outLen == 0) {
4051
            WOLFSSL_ERROR_MSG("Bad RSA size");
4052
            ret = 0;
4053
        }
4054
        /* Check signature buffer is big enough. */
4055
        else if (outLen > *sigLen) {
4056
            WOLFSSL_ERROR_MSG("Output buffer too small");
4057
            ret = 0;
4058
        }
4059
    }
4060
4061
#ifdef WOLFSSL_SMALL_STACK
4062
    if (ret == 1) {
4063
        /* Allocate encoded signature buffer if doing PKCS#1 padding. */
4064
        encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
4065
            DYNAMIC_TYPE_SIGNATURE);
4066
        if (encodedSig == NULL) {
4067
            ret = 0;
4068
        }
4069
    }
4070
#endif
4071
4072
    if (ret == 1) {
4073
        /* Get/create an RNG. */
4074
        rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
4075
        if (rng == NULL) {
4076
            WOLFSSL_ERROR_MSG("WOLFSSL_RSA_GetRNG error");
4077
            ret = 0;
4078
        }
4079
    }
4080
4081
    /* Either encodes with PKCS#1.5 or copies hash into encodedSig. */
4082
    if ((ret == 1) && (wolfssl_rsa_sig_encode(hashAlg, hash, hLen, encodedSig,
4083
            &encSz, padding) == 0)) {
4084
        WOLFSSL_ERROR_MSG("Bad Encode Signature");
4085
        ret = 0;
4086
    }
4087
4088
    if (ret == 1) {
4089
        switch (padding) {
4090
    #if defined(WC_RSA_NO_PADDING) || defined(WC_RSA_DIRECT)
4091
        case WC_RSA_NO_PAD:
4092
            if ((signSz = wc_RsaDirect(encodedSig, encSz, sigRet, &outLen,
4093
                (RsaKey*)rsa->internal, RSA_PRIVATE_ENCRYPT, rng)) <= 0) {
4094
                WOLFSSL_ERROR_MSG("Bad RSA Sign no pad");
4095
                ret = 0;
4096
            }
4097
            break;
4098
    #endif
4099
    #if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \
4100
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1))
4101
        case WC_RSA_PKCS1_PSS_PADDING:
4102
        {
4103
            RsaKey* key = (RsaKey*)rsa->internal;
4104
            enum wc_HashType mgf1, hType;
4105
            hType = wc_OidGetHash((int)nid2oid(hashAlg, oidHashType));
4106
            if (mgf1Hash == WC_NID_undef)
4107
                mgf1Hash = hashAlg;
4108
            mgf1 = wc_OidGetHash((int)nid2oid(mgf1Hash, oidHashType));
4109
            /* handle compat layer salt special cases */
4110
            saltLen = rsa_pss_calc_salt(saltLen, wc_HashGetDigestSize(hType),
4111
                wolfSSL_RSA_size(rsa));
4112
4113
            /* Create RSA PSS signature. */
4114
            if ((signSz = wc_RsaPSS_Sign_ex(encodedSig, encSz, sigRet, outLen,
4115
                hType, wc_hash2mgf(mgf1), saltLen, key, rng)) <= 0) {
4116
                WOLFSSL_ERROR_MSG("Bad RSA PSS Sign");
4117
                ret = 0;
4118
            }
4119
            break;
4120
        }
4121
    #endif
4122
    #ifndef WC_NO_RSA_OAEP
4123
        case WC_RSA_PKCS1_OAEP_PADDING:
4124
            /* Not a signature padding scheme. */
4125
            WOLFSSL_ERROR_MSG("RSA_PKCS1_OAEP_PADDING not supported for "
4126
                              "signing");
4127
            ret = 0;
4128
            break;
4129
    #endif
4130
        case WC_RSA_PKCS1_PADDING:
4131
        {
4132
            /* Sign (private encrypt) PKCS#1 encoded signature. */
4133
            if ((signSz = wc_RsaSSL_Sign(encodedSig, encSz, sigRet, outLen,
4134
                    (RsaKey*)rsa->internal, rng)) <= 0) {
4135
                WOLFSSL_ERROR_MSG("Bad PKCS1 RSA Sign");
4136
                ret = 0;
4137
            }
4138
            break;
4139
        }
4140
        default:
4141
            WOLFSSL_ERROR_MSG("Unsupported padding");
4142
            (void)mgf1Hash;
4143
            (void)saltLen;
4144
            ret = 0;
4145
            break;
4146
        }
4147
    }
4148
4149
    if (ret == 1) {
4150
        /* Return the size of signature generated. */
4151
        *sigLen = (unsigned int)signSz;
4152
    }
4153
4154
    /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */
4155
    if (initTmpRng) {
4156
        wc_FreeRng(tmpRng);
4157
    }
4158
#ifdef WOLFSSL_SMALL_STACK
4159
    /* Dispose of any allocated RNG and encoded signature. */
4160
    XFREE(tmpRng,     NULL, DYNAMIC_TYPE_RNG);
4161
    XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE);
4162
#endif
4163
4164
    WOLFSSL_LEAVE("wolfSSL_RSA_sign_mgf", ret);
4165
    return ret;
4166
}
4167
4168
/**
4169
 * Verify a message hash with the chosen message digest, padding, and RSA key.
4170
 *
4171
 * @param [in]  hashAlg  Hash NID
4172
 * @param [in]  hash     Message hash.
4173
 * @param [in]  mLen     Length of message hash.
4174
 * @param [in]  sigRet   Signature data.
4175
 * @param [in]  sigLen   Length of signature data.
4176
 * @param [in]  rsa      RSA key used to sign the input
4177
 * @return  1 on success.
4178
 * @return  0 on failure.
4179
 */
4180
int wolfSSL_RSA_verify(int hashAlg, const unsigned char* hash,
4181
    unsigned int hLen, const unsigned char* sig, unsigned int sigLen,
4182
    WOLFSSL_RSA* rsa)
4183
{
4184
    return wolfSSL_RSA_verify_ex(hashAlg, hash, hLen, sig, sigLen, rsa,
4185
        WC_RSA_PKCS1_PADDING);
4186
}
4187
4188
int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash,
4189
    unsigned int hLen, const unsigned char* sig, unsigned int sigLen,
4190
    WOLFSSL_RSA* rsa, int padding)
4191
{
4192
    return wolfSSL_RSA_verify_mgf(hashAlg, hash, hLen, sig, sigLen, rsa,
4193
        padding, hashAlg, DEF_PSS_SALT_LEN);
4194
}
4195
4196
/**
4197
 * Verify a message hash with the chosen message digest, padding, and RSA key.
4198
 *
4199
 * Not OpenSSL API.
4200
 *
4201
 * @param [in]  hashAlg  Hash NID
4202
 * @param [in]  hash     Message hash.
4203
 * @param [in]  mLen     Length of message hash.
4204
 * @param [in]  sigRet   Signature data.
4205
 * @param [in]  sigLen   Length of signature data.
4206
 * @param [in]  rsa      RSA key used to sign the input
4207
 * @param [in]  padding  Padding to use. Only RSA_PKCS1_PSS_PADDING and
4208
 *                       WC_RSA_PKCS1_PADDING are currently supported for
4209
 *                       signing.
4210
 * @param [in]  mgf1Hash MGF1 Hash NID
4211
 * @param [in]  saltLen  Length of RSA PSS salt
4212
 * @return  1 on success.
4213
 * @return  0 on failure.
4214
 */
4215
int wolfSSL_RSA_verify_mgf(int hashAlg, const unsigned char* hash,
4216
    unsigned int hLen, const unsigned char* sig, unsigned int sigLen,
4217
    WOLFSSL_RSA* rsa, int padding, int mgf1Hash, int saltLen)
4218
{
4219
    int              ret    = 1;
4220
#ifdef WOLFSSL_SMALL_STACK
4221
    unsigned char*   encodedSig = NULL;
4222
#else
4223
    unsigned char    encodedSig[MAX_ENCODED_SIG_SZ];
4224
#endif
4225
    unsigned char*   sigDec = NULL;
4226
    unsigned int     len    = MAX_ENCODED_SIG_SZ;
4227
    int              verLen = 0;
4228
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1)) && !defined(HAVE_SELFTEST)
4229
    enum wc_HashType hType = WC_HASH_TYPE_NONE;
4230
#endif
4231
4232
    WOLFSSL_ENTER("wolfSSL_RSA_verify_mgf");
4233
4234
    /* Validate parameters. */
4235
    if ((hash == NULL) || (sig == NULL) || (rsa == NULL)) {
4236
        WOLFSSL_ERROR_MSG("Bad function arguments");
4237
        ret = 0;
4238
    }
4239
4240
    if (ret == 1) {
4241
        /* Allocate memory for decrypted signature. */
4242
        sigDec = (unsigned char *)XMALLOC(sigLen, NULL,
4243
            DYNAMIC_TYPE_TMP_BUFFER);
4244
        if (sigDec == NULL) {
4245
            WOLFSSL_ERROR_MSG("Memory allocation failure");
4246
            ret = 0;
4247
        }
4248
    }
4249
    if (ret == 1 && padding == WC_RSA_PKCS1_PSS_PADDING) {
4250
        #if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \
4251
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1))
4252
        RsaKey* key = (RsaKey*)rsa->internal;
4253
        enum wc_HashType mgf1;
4254
        hType = wc_OidGetHash((int)nid2oid(hashAlg, oidHashType));
4255
        if (mgf1Hash == WC_NID_undef)
4256
            mgf1Hash = hashAlg;
4257
        mgf1 = wc_OidGetHash((int)nid2oid(mgf1Hash, oidHashType));
4258
4259
        /* handle compat layer salt special cases */
4260
        saltLen = rsa_pss_calc_salt(saltLen, wc_HashGetDigestSize(hType),
4261
            wolfSSL_RSA_size(rsa));
4262
4263
        verLen = wc_RsaPSS_Verify_ex((byte*)sig, sigLen, sigDec, sigLen,
4264
            hType, wc_hash2mgf(mgf1), saltLen, key);
4265
        if (verLen > 0) {
4266
            /* Check PSS padding is valid. */
4267
            if (wc_RsaPSS_CheckPadding_ex(hash, hLen, sigDec, (word32)verLen,
4268
                hType, saltLen, mp_count_bits(&key->n)) != 0) {
4269
                WOLFSSL_ERROR_MSG("wc_RsaPSS_CheckPadding_ex error");
4270
                ret = WOLFSSL_FAILURE;
4271
            }
4272
            else {
4273
                /* Success! Free resources and return early */
4274
                XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4275
                return WOLFSSL_SUCCESS;
4276
            }
4277
        }
4278
        else {
4279
            WOLFSSL_ERROR_MSG("wc_RsaPSS_Verify_ex failed!");
4280
            ret = WOLFSSL_FAILURE;
4281
        }
4282
    #else
4283
        (void)mgf1Hash;
4284
        (void)saltLen;
4285
        WOLFSSL_ERROR_MSG("RSA PSS not compiled in!");
4286
        ret = WOLFSSL_FAILURE;
4287
    #endif
4288
    }
4289
4290
#ifdef WOLFSSL_SMALL_STACK
4291
    if (ret == 1) {
4292
        /* Allocate memory for encoded signature. */
4293
        encodedSig = (unsigned char *)XMALLOC(len, NULL,
4294
            DYNAMIC_TYPE_TMP_BUFFER);
4295
        if (encodedSig == NULL) {
4296
            WOLFSSL_ERROR_MSG("Memory allocation failure");
4297
            ret = 0;
4298
        }
4299
    }
4300
#endif
4301
    if (ret == 1) {
4302
        /* Make encoded signature to compare with decrypted signature. */
4303
        if (wolfssl_rsa_sig_encode(hashAlg, hash, hLen, encodedSig, &len,
4304
                padding) <= 0) {
4305
            WOLFSSL_ERROR_MSG("Message Digest Error");
4306
            ret = 0;
4307
        }
4308
    }
4309
    if (ret == 1) {
4310
        /* Decrypt signature */
4311
    #if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1)) && \
4312
        !defined(HAVE_SELFTEST)
4313
        hType = wc_OidGetHash((int)nid2oid(hashAlg, oidHashType));
4314
        if ((verLen = wc_RsaSSL_Verify_ex2(sig, sigLen, (unsigned char *)sigDec,
4315
                sigLen, (RsaKey*)rsa->internal, padding, hType)) <= 0) {
4316
            WOLFSSL_ERROR_MSG("RSA Decrypt error");
4317
            ret = 0;
4318
        }
4319
    #else
4320
        verLen = wc_RsaSSL_Verify(sig, sigLen, (unsigned char *)sigDec, sigLen,
4321
            (RsaKey*)rsa->internal);
4322
        if (verLen < 0) {
4323
            ret = 0;
4324
        }
4325
    #endif
4326
    }
4327
    if (ret == 1) {
4328
        /* Compare decrypted signature to encoded signature. */
4329
        if (((int)len != verLen) ||
4330
                (XMEMCMP(encodedSig, sigDec, (size_t)verLen) != 0)) {
4331
            WOLFSSL_ERROR_MSG("wolfSSL_RSA_verify_ex failed");
4332
            ret = 0;
4333
        }
4334
    }
4335
4336
    /* Dispose of any allocated data. */
4337
#ifdef WOLFSSL_SMALL_STACK
4338
    XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4339
#endif
4340
    XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4341
4342
    WOLFSSL_LEAVE("wolfSSL_RSA_verify_mgf", ret);
4343
    return ret;
4344
}
4345
4346
/*
4347
 * RSA public/private encrypt/decrypt APIs
4348
 */
4349
4350
/* Encrypt with the RSA public key.
4351
 *
4352
 * Return compliant with OpenSSL.
4353
 *
4354
 * @param [in]  len      Length of data to encrypt.
4355
 * @param [in]  from     Data to encrypt.
4356
 * @param [out] to       Encrypted data.
4357
 * @param [in]  rsa      RSA key.
4358
 * @param [in]  padding  Type of padding to place around plaintext.
4359
 * @return  Size of encrypted data on success.
4360
 * @return  -1 on failure.
4361
 */
4362
int wolfSSL_RSA_public_encrypt(int len, const unsigned char* from,
4363
    unsigned char* to, WOLFSSL_RSA* rsa, int padding)
4364
{
4365
    int ret = 0;
4366
    int initTmpRng = 0;
4367
    WC_RNG *rng = NULL;
4368
#ifdef WOLFSSL_SMALL_STACK
4369
    WC_RNG* tmpRng = NULL;
4370
#else
4371
    WC_RNG  _tmpRng[1];
4372
    WC_RNG* tmpRng = _tmpRng;
4373
#endif
4374
#if !defined(HAVE_FIPS)
4375
    int  mgf = WC_MGF1NONE;
4376
    enum wc_HashType hash = WC_HASH_TYPE_NONE;
4377
    int pad_type = WC_RSA_NO_PAD;
4378
#endif
4379
    int outLen = 0;
4380
4381
    WOLFSSL_ENTER("wolfSSL_RSA_public_encrypt");
4382
4383
    /* Validate parameters. */
4384
    if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) ||
4385
            (from == NULL)) {
4386
        WOLFSSL_ERROR_MSG("Bad function arguments");
4387
        ret = WOLFSSL_FATAL_ERROR;
4388
    }
4389
4390
    if (ret == 0) {
4391
    #if !defined(HAVE_FIPS)
4392
        /* Convert to wolfCrypt padding, hash and MGF. */
4393
        switch (padding) {
4394
        case WC_RSA_PKCS1_PADDING:
4395
            pad_type = WC_RSA_PKCSV15_PAD;
4396
            break;
4397
        case WC_RSA_PKCS1_OAEP_PADDING:
4398
            pad_type = WC_RSA_OAEP_PAD;
4399
            hash = WC_HASH_TYPE_SHA;
4400
            mgf = WC_MGF1SHA1;
4401
            break;
4402
        case WC_RSA_NO_PAD:
4403
            pad_type = WC_RSA_NO_PAD;
4404
            break;
4405
        default:
4406
            WOLFSSL_ERROR_MSG("RSA_public_encrypt doesn't support padding "
4407
                              "scheme");
4408
            ret = WOLFSSL_FATAL_ERROR;
4409
        }
4410
    #else
4411
        /* Check for supported padding schemes in FIPS. */
4412
        /* TODO: Do we support more schemes in later versions of FIPS? */
4413
        if (padding != WC_RSA_PKCS1_PADDING) {
4414
            WOLFSSL_ERROR_MSG("RSA_public_encrypt pad type not supported in "
4415
                              "FIPS");
4416
            ret = WOLFSSL_FATAL_ERROR;
4417
        }
4418
    #endif
4419
    }
4420
4421
    /* Set wolfCrypt RSA key data from external if not already done. */
4422
    if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) {
4423
        ret = WOLFSSL_FATAL_ERROR;
4424
    }
4425
4426
    if (ret == 0) {
4427
        /* Calculate maximum length of encrypted data. */
4428
        outLen = wolfSSL_RSA_size(rsa);
4429
        if (outLen == 0) {
4430
            WOLFSSL_ERROR_MSG("Bad RSA size");
4431
            ret = WOLFSSL_FATAL_ERROR;
4432
        }
4433
    }
4434
4435
    if (ret == 0) {
4436
        /* Get an RNG. */
4437
        rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
4438
        if (rng == NULL) {
4439
            ret = WOLFSSL_FATAL_ERROR;
4440
        }
4441
    }
4442
4443
    if (ret == 0) {
4444
        /* Use wolfCrypt to public-encrypt with RSA key. */
4445
    #if !defined(HAVE_FIPS)
4446
        ret = wc_RsaPublicEncrypt_ex(from, (word32)len, to, (word32)outLen,
4447
            (RsaKey*)rsa->internal, rng, pad_type, hash, mgf, NULL, 0);
4448
    #else
4449
        ret = wc_RsaPublicEncrypt(from, (word32)len, to, (word32)outLen,
4450
            (RsaKey*)rsa->internal, rng);
4451
    #endif
4452
    }
4453
4454
    /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */
4455
    if (initTmpRng) {
4456
        wc_FreeRng(tmpRng);
4457
    }
4458
#ifdef WOLFSSL_SMALL_STACK
4459
    /* Dispose of any allocated RNG. */
4460
    XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
4461
#endif
4462
4463
    /* wolfCrypt error means return -1. */
4464
    if (ret <= 0) {
4465
        ret = WOLFSSL_FATAL_ERROR;
4466
    }
4467
    WOLFSSL_LEAVE("wolfSSL_RSA_public_encrypt", ret);
4468
    return ret;
4469
}
4470
4471
/* Decrypt with the RSA public key.
4472
 *
4473
 * Return compliant with OpenSSL.
4474
 *
4475
 * @param [in]  len      Length of encrypted data.
4476
 * @param [in]  from     Encrypted data.
4477
 * @param [out] to       Decrypted data.
4478
 * @param [in]  rsa      RSA key.
4479
 * @param [in]  padding  Type of padding to around plaintext to remove.
4480
 * @return  Size of decrypted data on success.
4481
 * @return  -1 on failure.
4482
 */
4483
int wolfSSL_RSA_private_decrypt(int len, const unsigned char* from,
4484
    unsigned char* to, WOLFSSL_RSA* rsa, int padding)
4485
{
4486
    int ret = 0;
4487
#if !defined(HAVE_FIPS)
4488
    int mgf = WC_MGF1NONE;
4489
    enum wc_HashType hash = WC_HASH_TYPE_NONE;
4490
    int pad_type = WC_RSA_NO_PAD;
4491
#endif
4492
    int outLen = 0;
4493
4494
    WOLFSSL_ENTER("wolfSSL_RSA_private_decrypt");
4495
4496
    /* Validate parameters. */
4497
    if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) ||
4498
            (from == NULL)) {
4499
        WOLFSSL_ERROR_MSG("Bad function arguments");
4500
        ret = WOLFSSL_FATAL_ERROR;
4501
    }
4502
4503
    if (ret == 0) {
4504
    #if !defined(HAVE_FIPS)
4505
        switch (padding) {
4506
        case WC_RSA_PKCS1_PADDING:
4507
            pad_type = WC_RSA_PKCSV15_PAD;
4508
            break;
4509
        case WC_RSA_PKCS1_OAEP_PADDING:
4510
            pad_type = WC_RSA_OAEP_PAD;
4511
            hash = WC_HASH_TYPE_SHA;
4512
            mgf = WC_MGF1SHA1;
4513
            break;
4514
        case WC_RSA_NO_PAD:
4515
            pad_type = WC_RSA_NO_PAD;
4516
            break;
4517
        default:
4518
            WOLFSSL_ERROR_MSG("RSA_private_decrypt unsupported padding");
4519
            ret = WOLFSSL_FATAL_ERROR;
4520
        }
4521
    #else
4522
        /* Check for supported padding schemes in FIPS. */
4523
        /* TODO: Do we support more schemes in later versions of FIPS? */
4524
        if (padding != WC_RSA_PKCS1_PADDING) {
4525
            WOLFSSL_ERROR_MSG("RSA_public_encrypt pad type not supported in "
4526
                              "FIPS");
4527
            ret = WOLFSSL_FATAL_ERROR;
4528
        }
4529
    #endif
4530
    }
4531
4532
    /* Set wolfCrypt RSA key data from external if not already done. */
4533
    if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) {
4534
        ret = WOLFSSL_FATAL_ERROR;
4535
    }
4536
4537
    if (ret == 0) {
4538
        /* Calculate maximum length of decrypted data. */
4539
        outLen = wolfSSL_RSA_size(rsa);
4540
        if (outLen == 0) {
4541
            WOLFSSL_ERROR_MSG("Bad RSA size");
4542
            ret = WOLFSSL_FATAL_ERROR;
4543
        }
4544
    }
4545
4546
    if (ret == 0) {
4547
        /* Use wolfCrypt to private-decrypt with RSA key.
4548
         * Size of 'to' buffer must be size of RSA key */
4549
    #if !defined(HAVE_FIPS)
4550
        ret = wc_RsaPrivateDecrypt_ex(from, (word32)len, to, (word32)outLen,
4551
            (RsaKey*)rsa->internal, pad_type, hash, mgf, NULL, 0);
4552
    #else
4553
        ret = wc_RsaPrivateDecrypt(from, (word32)len, to, (word32)outLen,
4554
            (RsaKey*)rsa->internal);
4555
    #endif
4556
    }
4557
4558
    /* wolfCrypt error means return -1. */
4559
    if (ret <= 0) {
4560
        ret = WOLFSSL_FATAL_ERROR;
4561
    }
4562
    WOLFSSL_LEAVE("wolfSSL_RSA_private_decrypt", ret);
4563
    return ret;
4564
}
4565
4566
/* Decrypt with the RSA public key.
4567
 *
4568
 * @param [in]  len      Length of encrypted data.
4569
 * @param [in]  from     Encrypted data.
4570
 * @param [out] to       Decrypted data.
4571
 * @param [in]  rsa      RSA key.
4572
 * @param [in]  padding  Type of padding to around plaintext to remove.
4573
 * @return  Size of decrypted data on success.
4574
 * @return  -1 on failure.
4575
 */
4576
int wolfSSL_RSA_public_decrypt(int len, const unsigned char* from,
4577
    unsigned char* to, WOLFSSL_RSA* rsa, int padding)
4578
{
4579
    int ret = 0;
4580
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
4581
    int pad_type = WC_RSA_NO_PAD;
4582
#endif
4583
    int outLen = 0;
4584
4585
    WOLFSSL_ENTER("wolfSSL_RSA_public_decrypt");
4586
4587
    /* Validate parameters. */
4588
    if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) ||
4589
            (from == NULL)) {
4590
        WOLFSSL_ERROR_MSG("Bad function arguments");
4591
        ret = WOLFSSL_FATAL_ERROR;
4592
    }
4593
4594
    if (ret == 0) {
4595
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
4596
        switch (padding) {
4597
        case WC_RSA_PKCS1_PADDING:
4598
            pad_type = WC_RSA_PKCSV15_PAD;
4599
            break;
4600
        case WC_RSA_NO_PAD:
4601
            pad_type = WC_RSA_NO_PAD;
4602
            break;
4603
        /* TODO: RSA_X931_PADDING not supported */
4604
        default:
4605
            WOLFSSL_ERROR_MSG("RSA_public_decrypt unsupported padding");
4606
            ret = WOLFSSL_FATAL_ERROR;
4607
        }
4608
    #else
4609
        if (padding != WC_RSA_PKCS1_PADDING) {
4610
            WOLFSSL_ERROR_MSG("RSA_public_decrypt pad type not supported in "
4611
                              "FIPS");
4612
            ret = WOLFSSL_FATAL_ERROR;
4613
        }
4614
    #endif
4615
    }
4616
4617
    /* Set wolfCrypt RSA key data from external if not already done. */
4618
    if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) {
4619
        ret = WOLFSSL_FATAL_ERROR;
4620
    }
4621
4622
    if (ret == 0) {
4623
        /* Calculate maximum length of encrypted data. */
4624
        outLen = wolfSSL_RSA_size(rsa);
4625
        if (outLen == 0) {
4626
            WOLFSSL_ERROR_MSG("Bad RSA size");
4627
            ret = WOLFSSL_FATAL_ERROR;
4628
        }
4629
    }
4630
4631
    if (ret == 0) {
4632
        /* Use wolfCrypt to public-decrypt with RSA key. */
4633
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
4634
        /* Size of 'to' buffer must be size of RSA key. */
4635
        ret = wc_RsaSSL_Verify_ex(from, (word32)len, to, (word32)outLen,
4636
            (RsaKey*)rsa->internal, pad_type);
4637
    #else
4638
        /* For FIPS v1/v2 only PKCSV15 padding is supported */
4639
        ret = wc_RsaSSL_Verify(from, (word32)len, to, (word32)outLen,
4640
            (RsaKey*)rsa->internal);
4641
    #endif
4642
    }
4643
4644
    /* wolfCrypt error means return -1. */
4645
    if (ret <= 0) {
4646
        ret = WOLFSSL_FATAL_ERROR;
4647
    }
4648
    WOLFSSL_LEAVE("wolfSSL_RSA_public_decrypt", ret);
4649
    return ret;
4650
}
4651
4652
/* Encrypt with the RSA private key.
4653
 *
4654
 * Calls wc_RsaSSL_Sign.
4655
 *
4656
 * @param [in]  len      Length of data to encrypt.
4657
 * @param [in]  from     Data to encrypt.
4658
 * @param [out] to       Encrypted data.
4659
 * @param [in]  rsa      RSA key.
4660
 * @param [in]  padding  Type of padding to place around plaintext.
4661
 * @return  Size of encrypted data on success.
4662
 * @return  -1 on failure.
4663
 */
4664
int wolfSSL_RSA_private_encrypt(int len, const unsigned char* from,
4665
    unsigned char* to, WOLFSSL_RSA* rsa, int padding)
4666
{
4667
    int ret = 0;
4668
    int initTmpRng = 0;
4669
    WC_RNG *rng = NULL;
4670
#ifdef WOLFSSL_SMALL_STACK
4671
    WC_RNG* tmpRng = NULL;
4672
#else
4673
    WC_RNG  _tmpRng[1];
4674
    WC_RNG* tmpRng = _tmpRng;
4675
#endif
4676
4677
    WOLFSSL_ENTER("wolfSSL_RSA_private_encrypt");
4678
4679
    /* Validate parameters. */
4680
    if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) ||
4681
            (from == NULL)) {
4682
        WOLFSSL_ERROR_MSG("Bad function arguments");
4683
        ret = WOLFSSL_FATAL_ERROR;
4684
    }
4685
4686
    if (ret == 0) {
4687
        switch (padding) {
4688
        case WC_RSA_PKCS1_PADDING:
4689
    #ifdef WC_RSA_NO_PADDING
4690
        case WC_RSA_NO_PAD:
4691
    #endif
4692
            break;
4693
        /* TODO: RSA_X931_PADDING not supported */
4694
        default:
4695
            WOLFSSL_ERROR_MSG("RSA_private_encrypt unsupported padding");
4696
            ret = WOLFSSL_FATAL_ERROR;
4697
        }
4698
    }
4699
4700
    /* Set wolfCrypt RSA key data from external if not already done. */
4701
    if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) {
4702
        ret = WOLFSSL_FATAL_ERROR;
4703
    }
4704
4705
    if (ret == 0) {
4706
        /* Get an RNG. */
4707
        rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
4708
        if (rng == NULL) {
4709
            ret = WOLFSSL_FATAL_ERROR;
4710
        }
4711
    }
4712
4713
    if (ret == 0) {
4714
        /* Use wolfCrypt to private-encrypt with RSA key.
4715
         * Size of output buffer must be size of RSA key. */
4716
        if (padding == WC_RSA_PKCS1_PADDING) {
4717
            ret = wc_RsaSSL_Sign(from, (word32)len, to,
4718
                (word32)wolfSSL_RSA_size(rsa), (RsaKey*)rsa->internal, rng);
4719
        }
4720
    #ifdef WC_RSA_NO_PADDING
4721
        else if (padding == WC_RSA_NO_PAD) {
4722
            word32 outLen = (word32)wolfSSL_RSA_size(rsa);
4723
            ret = wc_RsaFunction(from, (word32)len, to, &outLen,
4724
                    RSA_PRIVATE_ENCRYPT, (RsaKey*)rsa->internal, rng);
4725
            if (ret == 0)
4726
                ret = (int)outLen;
4727
        }
4728
    #endif
4729
    }
4730
4731
    /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */
4732
    if (initTmpRng) {
4733
        wc_FreeRng(tmpRng);
4734
    }
4735
#ifdef WOLFSSL_SMALL_STACK
4736
    /* Dispose of any allocated RNG. */
4737
    XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
4738
#endif
4739
4740
    /* wolfCrypt error means return -1. */
4741
    if (ret <= 0) {
4742
        ret = WOLFSSL_FATAL_ERROR;
4743
    }
4744
    WOLFSSL_LEAVE("wolfSSL_RSA_private_encrypt", ret);
4745
    return ret;
4746
}
4747
4748
/*
4749
 * RSA misc operation APIs
4750
 */
4751
4752
/* Calculate d mod p-1 and q-1 into BNs.
4753
 *
4754
 * Not OpenSSL API.
4755
 *
4756
 * @param [in, out] rsa  RSA key.
4757
 * @return 1 on success.
4758
 * @return -1 on failure.
4759
 */
4760
int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
4761
{
4762
    int     ret = 1;
4763
    int     err;
4764
    mp_int* t = NULL;
4765
#ifdef WOLFSSL_SMALL_STACK
4766
    mp_int  *tmp = NULL;
4767
#else
4768
    mp_int  tmp[1];
4769
#endif
4770
4771
    WOLFSSL_ENTER("wolfSSL_RsaGenAdd");
4772
4773
    /* Validate parameters. */
4774
    if ((rsa == NULL) || (rsa->p == NULL) || (rsa->q == NULL) ||
4775
            (rsa->d == NULL) || (rsa->dmp1 == NULL) || (rsa->dmq1 == NULL)) {
4776
        WOLFSSL_ERROR_MSG("rsa no init error");
4777
        ret = WOLFSSL_FATAL_ERROR;
4778
    }
4779
4780
#ifdef WOLFSSL_SMALL_STACK
4781
    if (ret == 1) {
4782
        tmp = (mp_int *)XMALLOC(sizeof(*tmp), rsa->heap,
4783
                                     DYNAMIC_TYPE_TMP_BUFFER);
4784
        if (tmp == NULL) {
4785
            WOLFSSL_ERROR_MSG("Memory allocation failure");
4786
            ret = WOLFSSL_FATAL_ERROR;
4787
        }
4788
    }
4789
#endif
4790
4791
    if (ret == 1) {
4792
        /* Initialize temp MP integer. */
4793
        if (mp_init(tmp) != MP_OKAY) {
4794
            WOLFSSL_ERROR_MSG("mp_init error");
4795
            ret = WOLFSSL_FATAL_ERROR;
4796
        }
4797
    }
4798
4799
    if (ret == 1) {
4800
        t = tmp;
4801
4802
        /* Sub 1 from p into temp. */
4803
        err = mp_sub_d((mp_int*)rsa->p->internal, 1, tmp);
4804
        if (err != MP_OKAY) {
4805
            WOLFSSL_ERROR_MSG("mp_sub_d error");
4806
            ret = WOLFSSL_FATAL_ERROR;
4807
        }
4808
    }
4809
    if (ret == 1) {
4810
        /* Calculate d mod (p - 1) into dmp1 MP integer of BN. */
4811
        err = mp_mod((mp_int*)rsa->d->internal, tmp,
4812
            (mp_int*)rsa->dmp1->internal);
4813
        if (err != MP_OKAY) {
4814
            WOLFSSL_ERROR_MSG("mp_mod error");
4815
            ret = WOLFSSL_FATAL_ERROR;
4816
        }
4817
    }
4818
    if (ret == 1) {
4819
        /* Sub 1 from q into temp. */
4820
        err = mp_sub_d((mp_int*)rsa->q->internal, 1, tmp);
4821
        if (err != MP_OKAY) {
4822
            WOLFSSL_ERROR_MSG("mp_sub_d error");
4823
            ret = WOLFSSL_FATAL_ERROR;
4824
        }
4825
    }
4826
    if (ret == 1) {
4827
        /* Calculate d mod (q - 1) into dmq1 MP integer of BN. */
4828
        err = mp_mod((mp_int*)rsa->d->internal, tmp,
4829
            (mp_int*)rsa->dmq1->internal);
4830
        if (err != MP_OKAY) {
4831
            WOLFSSL_ERROR_MSG("mp_mod error");
4832
            ret = WOLFSSL_FATAL_ERROR;
4833
        }
4834
    }
4835
4836
    mp_clear(t);
4837
4838
#ifdef WOLFSSL_SMALL_STACK
4839
    if (rsa != NULL) {
4840
        XFREE(tmp, rsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
4841
    }
4842
#endif
4843
4844
    return ret;
4845
}
4846
4847
4848
#ifndef NO_WOLFSSL_STUB
4849
/* Enable blinding for RSA key operations.
4850
 *
4851
 * Blinding is a compile time option in wolfCrypt.
4852
 *
4853
 * @param [in] rsa    RSA key. Unused.
4854
 * @param [in] bnCtx  BN context to use for blinding. Unused.
4855
 * @return 1 always.
4856
 */
4857
int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bnCtx)
4858
{
4859
    WOLFSSL_STUB("RSA_blinding_on");
4860
    WOLFSSL_ENTER("wolfSSL_RSA_blinding_on");
4861
4862
    (void)rsa;
4863
    (void)bnCtx;
4864
4865
    return 1;  /* on by default */
4866
}
4867
#endif
4868
4869
#endif /* OPENSSL_EXTRA */
4870
4871
#endif /* !NO_RSA */
4872
4873
/*******************************************************************************
4874
 * END OF RSA API
4875
 ******************************************************************************/
4876
4877
4878
/*******************************************************************************
4879
 * START OF DSA API
4880
 ******************************************************************************/
4881
4882
#ifndef NO_DSA
4883
4884
#if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
4885
    !defined(NO_STDIO_FILESYSTEM)
4886
/* return code compliant with OpenSSL :
4887
 *   1 if success, 0 if error
4888
 */
4889
int wolfSSL_DSA_print_fp(XFILE fp, WOLFSSL_DSA* dsa, int indent)
4890
{
4891
    int ret = 1;
4892
4893
    WOLFSSL_ENTER("wolfSSL_DSA_print_fp");
4894
4895
    if (fp == XBADFILE || dsa == NULL) {
4896
        ret = 0;
4897
    }
4898
4899
    if (ret == 1 && dsa->p != NULL) {
4900
        int pBits = wolfSSL_BN_num_bits(dsa->p);
4901
        if (pBits == 0) {
4902
            ret = 0;
4903
        }
4904
        else {
4905
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
4906
                ret = 0;
4907
            else if (XFPRINTF(fp, "Private-Key: (%d bit)\n", pBits) < 0)
4908
                ret = 0;
4909
        }
4910
    }
4911
    if (ret == 1 && dsa->priv_key != NULL) {
4912
        ret = pk_bn_field_print_fp(fp, indent, "priv", dsa->priv_key);
4913
    }
4914
    if (ret == 1 && dsa->pub_key != NULL) {
4915
        ret = pk_bn_field_print_fp(fp, indent, "pub", dsa->pub_key);
4916
    }
4917
    if (ret == 1 && dsa->p != NULL) {
4918
        ret = pk_bn_field_print_fp(fp, indent, "P", dsa->p);
4919
    }
4920
    if (ret == 1 && dsa->q != NULL) {
4921
        ret = pk_bn_field_print_fp(fp, indent, "Q", dsa->q);
4922
    }
4923
    if (ret == 1 && dsa->g != NULL) {
4924
        ret = pk_bn_field_print_fp(fp, indent, "G", dsa->g);
4925
    }
4926
4927
    WOLFSSL_LEAVE("wolfSSL_DSA_print_fp", ret);
4928
4929
    return ret;
4930
}
4931
#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_FILESYSTEM && NO_STDIO_FILESYSTEM */
4932
4933
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
4934
static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
4935
{
4936
    if (dsa) {
4937
        dsa->p        = NULL;
4938
        dsa->q        = NULL;
4939
        dsa->g        = NULL;
4940
        dsa->pub_key  = NULL;
4941
        dsa->priv_key = NULL;
4942
        dsa->internal = NULL;
4943
        dsa->inSet    = 0;
4944
        dsa->exSet    = 0;
4945
    }
4946
}
4947
4948
4949
WOLFSSL_DSA* wolfSSL_DSA_new(void)
4950
{
4951
    WOLFSSL_DSA* external;
4952
    DsaKey*     key;
4953
4954
    WOLFSSL_MSG("wolfSSL_DSA_new");
4955
4956
    key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
4957
    if (key == NULL) {
4958
        WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
4959
        return NULL;
4960
    }
4961
4962
    external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
4963
                                    DYNAMIC_TYPE_DSA);
4964
    if (external == NULL) {
4965
        WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
4966
        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
4967
        return NULL;
4968
    }
4969
4970
    InitwolfSSL_DSA(external);
4971
    if (wc_InitDsaKey(key) != 0) {
4972
        WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
4973
        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
4974
        wolfSSL_DSA_free(external);
4975
        return NULL;
4976
    }
4977
    external->internal = key;
4978
4979
    return external;
4980
}
4981
4982
4983
void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
4984
{
4985
    WOLFSSL_MSG("wolfSSL_DSA_free");
4986
4987
    if (dsa) {
4988
        if (dsa->internal) {
4989
            FreeDsaKey((DsaKey*)dsa->internal);
4990
            XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
4991
            dsa->internal = NULL;
4992
        }
4993
        wolfSSL_BN_free(dsa->priv_key);
4994
        wolfSSL_BN_free(dsa->pub_key);
4995
        wolfSSL_BN_free(dsa->g);
4996
        wolfSSL_BN_free(dsa->q);
4997
        wolfSSL_BN_free(dsa->p);
4998
        InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
4999
5000
        XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
5001
5002
        /* dsa = NULL, don't try to access or double free it */
5003
    }
5004
}
5005
5006
/* wolfSSL -> OpenSSL */
5007
int SetDsaExternal(WOLFSSL_DSA* dsa)
5008
{
5009
    DsaKey* key;
5010
    WOLFSSL_MSG("Entering SetDsaExternal");
5011
5012
    if (dsa == NULL || dsa->internal == NULL) {
5013
        WOLFSSL_MSG("dsa key NULL error");
5014
        return WOLFSSL_FATAL_ERROR;
5015
    }
5016
5017
    key = (DsaKey*)dsa->internal;
5018
5019
    if (wolfssl_bn_set_value(&dsa->p, &key->p) != 1) {
5020
        WOLFSSL_MSG("dsa p key error");
5021
        return WOLFSSL_FATAL_ERROR;
5022
    }
5023
5024
    if (wolfssl_bn_set_value(&dsa->q, &key->q) != 1) {
5025
        WOLFSSL_MSG("dsa q key error");
5026
        return WOLFSSL_FATAL_ERROR;
5027
    }
5028
5029
    if (wolfssl_bn_set_value(&dsa->g, &key->g) != 1) {
5030
        WOLFSSL_MSG("dsa g key error");
5031
        return WOLFSSL_FATAL_ERROR;
5032
    }
5033
5034
    if (wolfssl_bn_set_value(&dsa->pub_key, &key->y) != 1) {
5035
        WOLFSSL_MSG("dsa y key error");
5036
        return WOLFSSL_FATAL_ERROR;
5037
    }
5038
5039
    if (wolfssl_bn_set_value(&dsa->priv_key, &key->x) != 1) {
5040
        WOLFSSL_MSG("dsa x key error");
5041
        return WOLFSSL_FATAL_ERROR;
5042
    }
5043
5044
    dsa->exSet = 1;
5045
5046
    return 1;
5047
}
5048
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
5049
5050
#ifdef OPENSSL_EXTRA
5051
/* Openssl -> WolfSSL */
5052
int SetDsaInternal(WOLFSSL_DSA* dsa)
5053
{
5054
    DsaKey* key;
5055
    WOLFSSL_MSG("Entering SetDsaInternal");
5056
5057
    if (dsa == NULL || dsa->internal == NULL) {
5058
        WOLFSSL_MSG("dsa key NULL error");
5059
        return WOLFSSL_FATAL_ERROR;
5060
    }
5061
5062
    key = (DsaKey*)dsa->internal;
5063
5064
    if (dsa->p != NULL &&
5065
        wolfssl_bn_get_value(dsa->p, &key->p) != 1) {
5066
        WOLFSSL_MSG("rsa p key error");
5067
        return WOLFSSL_FATAL_ERROR;
5068
    }
5069
5070
    if (dsa->q != NULL &&
5071
        wolfssl_bn_get_value(dsa->q, &key->q) != 1) {
5072
        WOLFSSL_MSG("rsa q key error");
5073
        return WOLFSSL_FATAL_ERROR;
5074
    }
5075
5076
    if (dsa->g != NULL &&
5077
        wolfssl_bn_get_value(dsa->g, &key->g) != 1) {
5078
        WOLFSSL_MSG("rsa g key error");
5079
        return WOLFSSL_FATAL_ERROR;
5080
    }
5081
5082
    if (dsa->pub_key != NULL) {
5083
        if (wolfssl_bn_get_value(dsa->pub_key, &key->y) != 1) {
5084
            WOLFSSL_MSG("rsa pub_key error");
5085
            return WOLFSSL_FATAL_ERROR;
5086
        }
5087
5088
        /* public key */
5089
        key->type = DSA_PUBLIC;
5090
    }
5091
5092
    if (dsa->priv_key != NULL) {
5093
        if (wolfssl_bn_get_value(dsa->priv_key, &key->x) != 1) {
5094
            WOLFSSL_MSG("rsa priv_key error");
5095
            return WOLFSSL_FATAL_ERROR;
5096
        }
5097
5098
        /* private key */
5099
        key->type = DSA_PRIVATE;
5100
    }
5101
5102
    dsa->inSet = 1;
5103
5104
    return 1;
5105
}
5106
5107
/* return code compliant with OpenSSL :
5108
 *   1 if success, 0 if error
5109
 */
5110
int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
5111
{
5112
    int ret = 0;
5113
5114
    WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
5115
5116
    if (dsa == NULL || dsa->internal == NULL) {
5117
        WOLFSSL_MSG("Bad arguments");
5118
        return 0;
5119
    }
5120
5121
    if (dsa->inSet == 0) {
5122
        WOLFSSL_MSG("No DSA internal set, do it");
5123
5124
        if (SetDsaInternal(dsa) != 1) {
5125
            WOLFSSL_MSG("SetDsaInternal failed");
5126
            return ret;
5127
        }
5128
    }
5129
5130
#ifdef WOLFSSL_KEY_GEN
5131
    {
5132
        int initTmpRng = 0;
5133
        WC_RNG *rng = NULL;
5134
#ifdef WOLFSSL_SMALL_STACK
5135
        WC_RNG *tmpRng;
5136
#else
5137
        WC_RNG tmpRng[1];
5138
#endif
5139
5140
#ifdef WOLFSSL_SMALL_STACK
5141
        tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
5142
        if (tmpRng == NULL)
5143
            return WOLFSSL_FATAL_ERROR;
5144
#endif
5145
        if (wc_InitRng(tmpRng) == 0) {
5146
            rng = tmpRng;
5147
            initTmpRng = 1;
5148
        }
5149
        else {
5150
            WOLFSSL_MSG("Bad RNG Init, trying global");
5151
            rng = wolfssl_get_global_rng();
5152
        }
5153
5154
        if (rng) {
5155
            /* These were allocated above by SetDsaInternal(). They should
5156
             * be cleared before wc_MakeDsaKey() which reinitializes
5157
             * x and y. */
5158
            mp_clear(&((DsaKey*)dsa->internal)->x);
5159
            mp_clear(&((DsaKey*)dsa->internal)->y);
5160
5161
            if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
5162
                WOLFSSL_MSG("wc_MakeDsaKey failed");
5163
            else if (SetDsaExternal(dsa) != 1)
5164
                WOLFSSL_MSG("SetDsaExternal failed");
5165
            else
5166
                ret = 1;
5167
        }
5168
5169
        if (initTmpRng)
5170
            wc_FreeRng(tmpRng);
5171
5172
#ifdef WOLFSSL_SMALL_STACK
5173
        XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
5174
#endif
5175
    }
5176
#else /* WOLFSSL_KEY_GEN */
5177
    WOLFSSL_MSG("No Key Gen built in");
5178
#endif
5179
    return ret;
5180
}
5181
5182
5183
/* Returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
5184
 */
5185
WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed,
5186
        int seedLen, int* counterRet, unsigned long* hRet,
5187
        WOLFSSL_BN_CB cb, void* CBArg)
5188
{
5189
    WOLFSSL_DSA* dsa;
5190
5191
    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters");
5192
5193
    (void)cb;
5194
    (void)CBArg;
5195
    dsa = wolfSSL_DSA_new();
5196
    if (dsa == NULL) {
5197
        return NULL;
5198
    }
5199
5200
    if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen,
5201
                                  counterRet, hRet, NULL) != 1) {
5202
        wolfSSL_DSA_free(dsa);
5203
        return NULL;
5204
    }
5205
5206
    return dsa;
5207
}
5208
5209
5210
/* return code compliant with OpenSSL :
5211
 *   1 if success, 0 if error
5212
 */
5213
int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
5214
                                       unsigned char* seed, int seedLen,
5215
                                       int* counterRet,
5216
                                       unsigned long* hRet, void* cb)
5217
{
5218
    int ret = 0;
5219
5220
    (void)bits;
5221
    (void)seed;
5222
    (void)seedLen;
5223
    (void)counterRet;
5224
    (void)hRet;
5225
    (void)cb;
5226
5227
    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
5228
5229
    if (dsa == NULL || dsa->internal == NULL) {
5230
        WOLFSSL_MSG("Bad arguments");
5231
        return 0;
5232
    }
5233
5234
#ifdef WOLFSSL_KEY_GEN
5235
    {
5236
        int initTmpRng = 0;
5237
        WC_RNG *rng = NULL;
5238
#ifdef WOLFSSL_SMALL_STACK
5239
        WC_RNG *tmpRng;
5240
#else
5241
        WC_RNG tmpRng[1];
5242
#endif
5243
5244
#ifdef WOLFSSL_SMALL_STACK
5245
        tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
5246
        if (tmpRng == NULL)
5247
            return WOLFSSL_FATAL_ERROR;
5248
#endif
5249
        if (wc_InitRng(tmpRng) == 0) {
5250
            rng = tmpRng;
5251
            initTmpRng = 1;
5252
        }
5253
        else {
5254
            WOLFSSL_MSG("Bad RNG Init, trying global");
5255
            rng = wolfssl_get_global_rng();
5256
        }
5257
5258
        if (rng) {
5259
            if (wc_MakeDsaParameters(rng, bits,
5260
                                     (DsaKey*)dsa->internal) != MP_OKAY)
5261
                WOLFSSL_MSG("wc_MakeDsaParameters failed");
5262
            else if (SetDsaExternal(dsa) != 1)
5263
                WOLFSSL_MSG("SetDsaExternal failed");
5264
            else
5265
                ret = 1;
5266
        }
5267
5268
        if (initTmpRng)
5269
            wc_FreeRng(tmpRng);
5270
5271
#ifdef WOLFSSL_SMALL_STACK
5272
        XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
5273
#endif
5274
    }
5275
#else /* WOLFSSL_KEY_GEN */
5276
    WOLFSSL_MSG("No Key Gen built in");
5277
#endif
5278
5279
    return ret;
5280
}
5281
5282
void wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA *d, const WOLFSSL_BIGNUM **p,
5283
        const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
5284
{
5285
    WOLFSSL_ENTER("wolfSSL_DSA_get0_pqg");
5286
    if (d != NULL) {
5287
        if (p != NULL)
5288
            *p = d->p;
5289
        if (q != NULL)
5290
            *q = d->q;
5291
        if (g != NULL)
5292
            *g = d->g;
5293
    }
5294
}
5295
5296
int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p,
5297
        WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
5298
{
5299
    WOLFSSL_ENTER("wolfSSL_DSA_set0_pqg");
5300
    if (d == NULL || p == NULL || q == NULL || g == NULL) {
5301
        WOLFSSL_MSG("Bad parameter");
5302
        return 0;
5303
    }
5304
    wolfSSL_BN_free(d->p);
5305
    wolfSSL_BN_free(d->q);
5306
    wolfSSL_BN_free(d->g);
5307
    d->p = p;
5308
    d->q = q;
5309
    d->g = g;
5310
    return 1;
5311
}
5312
5313
void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d,
5314
        const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key)
5315
{
5316
    WOLFSSL_ENTER("wolfSSL_DSA_get0_key");
5317
    if (d != NULL) {
5318
        if (pub_key != NULL)
5319
            *pub_key = d->pub_key;
5320
        if (priv_key != NULL)
5321
            *priv_key = d->priv_key;
5322
    }
5323
}
5324
5325
int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key,
5326
        WOLFSSL_BIGNUM *priv_key)
5327
{
5328
    WOLFSSL_ENTER("wolfSSL_DSA_set0_key");
5329
5330
    /* The private key may be NULL */
5331
    if (d->pub_key == NULL && pub_key == NULL) {
5332
        WOLFSSL_MSG("Bad parameter");
5333
        return 0;
5334
    }
5335
5336
    if (pub_key != NULL) {
5337
        wolfSSL_BN_free(d->pub_key);
5338
        d->pub_key = pub_key;
5339
    }
5340
    if (priv_key != NULL) {
5341
        wolfSSL_BN_free(d->priv_key);
5342
        d->priv_key = priv_key;
5343
    }
5344
5345
    return 1;
5346
}
5347
5348
WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void)
5349
{
5350
    WOLFSSL_DSA_SIG* sig;
5351
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_new");
5352
    sig = (WOLFSSL_DSA_SIG*)XMALLOC(sizeof(WOLFSSL_DSA_SIG), NULL,
5353
        DYNAMIC_TYPE_OPENSSL);
5354
    if (sig)
5355
        XMEMSET(sig, 0, sizeof(WOLFSSL_DSA_SIG));
5356
    return sig;
5357
}
5358
5359
void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig)
5360
{
5361
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_free");
5362
    if (sig) {
5363
        if (sig->r) {
5364
            wolfSSL_BN_free(sig->r);
5365
        }
5366
        if (sig->s) {
5367
            wolfSSL_BN_free(sig->s);
5368
        }
5369
        XFREE(sig, NULL, DYNAMIC_TYPE_OPENSSL);
5370
    }
5371
}
5372
5373
void wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG *sig,
5374
        const WOLFSSL_BIGNUM **r, const WOLFSSL_BIGNUM **s)
5375
{
5376
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_get0");
5377
    if (sig != NULL) {
5378
        *r = sig->r;
5379
        *s = sig->s;
5380
    }
5381
}
5382
5383
int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r,
5384
        WOLFSSL_BIGNUM *s)
5385
{
5386
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_set0");
5387
    if (r == NULL || s == NULL) {
5388
        WOLFSSL_MSG("Bad parameter");
5389
        return 0;
5390
    }
5391
5392
    wolfSSL_BN_clear_free(sig->r);
5393
    wolfSSL_BN_clear_free(sig->s);
5394
    sig->r = r;
5395
    sig->s = s;
5396
5397
    return 1;
5398
}
5399
5400
#ifndef HAVE_SELFTEST
5401
/**
5402
 *
5403
 * @param sig The input signature to encode
5404
 * @param out The output buffer. If *out is NULL then a new buffer is
5405
 *            allocated. Otherwise the output is written to the buffer.
5406
 * @return length on success and -1 on error
5407
 */
5408
int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out)
5409
{
5410
    /* Space for sequence + two asn ints */
5411
    byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_MAX_HALF_SIZE)];
5412
    word32 bufLen = sizeof(buf);
5413
5414
    WOLFSSL_ENTER("wolfSSL_i2d_DSA_SIG");
5415
5416
    if (sig == NULL || sig->r == NULL || sig->s == NULL ||
5417
            out == NULL) {
5418
        WOLFSSL_MSG("Bad function arguments");
5419
        return WOLFSSL_FATAL_ERROR;
5420
    }
5421
5422
    if (StoreECC_DSA_Sig(buf, &bufLen,
5423
            (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != 0) {
5424
        WOLFSSL_MSG("StoreECC_DSA_Sig error");
5425
        return WOLFSSL_FATAL_ERROR;
5426
    }
5427
5428
    if (*out == NULL) {
5429
        byte* tmp = (byte*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_ASN1);
5430
        if (tmp == NULL) {
5431
            WOLFSSL_MSG("malloc error");
5432
            return WOLFSSL_FATAL_ERROR;
5433
        }
5434
        *out = tmp;
5435
    }
5436
5437
   XMEMCPY(*out, buf, bufLen);
5438
5439
    return (int)bufLen;
5440
}
5441
5442
/**
5443
 * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums as well.
5444
 * @return New WOLFSSL_DSA_SIG with r and s created as well
5445
 */
5446
static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void)
5447
{
5448
    WOLFSSL_DSA_SIG* ret;
5449
5450
    if ((ret = wolfSSL_DSA_SIG_new()) == NULL) {
5451
        WOLFSSL_MSG("wolfSSL_DSA_SIG_new error");
5452
        return NULL;
5453
    }
5454
5455
    if ((ret->r = wolfSSL_BN_new()) == NULL) {
5456
        WOLFSSL_MSG("wolfSSL_BN_new error");
5457
        wolfSSL_DSA_SIG_free(ret);
5458
        return NULL;
5459
    }
5460
5461
    if ((ret->s = wolfSSL_BN_new()) == NULL) {
5462
        WOLFSSL_MSG("wolfSSL_BN_new error");
5463
        wolfSSL_DSA_SIG_free(ret);
5464
        return NULL;
5465
    }
5466
5467
    return ret;
5468
}
5469
5470
/**
5471
 * This parses a DER encoded ASN.1 structure. The ASN.1 encoding is:
5472
 * ASN1_SEQUENCE
5473
 *   ASN1_INTEGER (DSA r)
5474
 *   ASN1_INTEGER (DSA s)
5475
 * Alternatively, if the input is DSA_160_SIG_SIZE or DSA_256_SIG_SIZE in
5476
 * length then this API interprets this as two unsigned binary numbers.
5477
 * @param sig    If non-null then free'd first and then newly created
5478
 *               WOLFSSL_DSA_SIG is assigned
5479
 * @param pp     Input buffer that is moved forward on success
5480
 * @param length Length of input buffer
5481
 * @return Newly created WOLFSSL_DSA_SIG on success or NULL on failure
5482
 */
5483
WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig,
5484
        const unsigned char **pp, long length)
5485
{
5486
    WOLFSSL_DSA_SIG* ret;
5487
    mp_int* r;
5488
    mp_int* s;
5489
5490
    WOLFSSL_ENTER("wolfSSL_d2i_DSA_SIG");
5491
5492
    if (pp == NULL || *pp == NULL || length < 0) {
5493
        WOLFSSL_MSG("Bad function arguments");
5494
        return NULL;
5495
    }
5496
5497
    if ((ret = wolfSSL_DSA_SIG_new_bn()) == NULL) {
5498
        WOLFSSL_MSG("wolfSSL_DSA_SIG_new_bn error");
5499
        return NULL;
5500
    }
5501
5502
    r = (mp_int*)ret->r->internal;
5503
    s = (mp_int*)ret->s->internal;
5504
5505
    if (DecodeECC_DSA_Sig(*pp, (word32)length, r, s) != 0) {
5506
        if (length == DSA_160_SIG_SIZE || length == DSA_256_SIG_SIZE) {
5507
            /* Two raw numbers of length/2 size each */
5508
            if (mp_read_unsigned_bin(r, *pp, (word32)length/2) != 0) {
5509
                WOLFSSL_MSG("r mp_read_unsigned_bin error");
5510
                wolfSSL_DSA_SIG_free(ret);
5511
                return NULL;
5512
            }
5513
5514
            if (mp_read_unsigned_bin(s, *pp + (length/2), (word32)length/2) !=
5515
                    0) {
5516
                WOLFSSL_MSG("s mp_read_unsigned_bin error");
5517
                wolfSSL_DSA_SIG_free(ret);
5518
                return NULL;
5519
            }
5520
5521
            *pp += length;
5522
        }
5523
        else {
5524
            WOLFSSL_MSG("DecodeECC_DSA_Sig error");
5525
            wolfSSL_DSA_SIG_free(ret);
5526
            return NULL;
5527
        }
5528
    }
5529
    else {
5530
        /* DecodeECC_DSA_Sig success move pointer forward */
5531
#ifndef NO_STRICT_ECDSA_LEN
5532
        *pp += length;
5533
#else
5534
        {
5535
            /* We need to figure out how much to move by ourselves */
5536
            word32 idx = 0;
5537
            int len = 0;
5538
            if (GetSequence(*pp, &idx, &len, (word32)length) < 0) {
5539
                WOLFSSL_MSG("GetSequence error");
5540
                wolfSSL_DSA_SIG_free(ret);
5541
                return NULL;
5542
            }
5543
            *pp += len;
5544
        }
5545
#endif
5546
    }
5547
5548
    if (sig != NULL) {
5549
        if (*sig != NULL)
5550
            wolfSSL_DSA_SIG_free(*sig);
5551
        *sig = ret;
5552
    }
5553
5554
    return ret;
5555
}
5556
5557
#endif /* !HAVE_SELFTEST */
5558
5559
static int dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet,
5560
        WOLFSSL_DSA* dsa)
5561
{
5562
    int     ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
5563
    int     initTmpRng = 0;
5564
    WC_RNG* rng = NULL;
5565
#ifdef WOLFSSL_SMALL_STACK
5566
    WC_RNG* tmpRng = NULL;
5567
#else
5568
    WC_RNG  tmpRng[1];
5569
#endif
5570
5571
    if (d == NULL || sigRet == NULL || dsa == NULL) {
5572
        WOLFSSL_MSG("Bad function arguments");
5573
        return WOLFSSL_FATAL_ERROR;
5574
    }
5575
5576
    if (dsa->inSet == 0) {
5577
        WOLFSSL_MSG("No DSA internal set, do it");
5578
        if (SetDsaInternal(dsa) != 1) {
5579
            WOLFSSL_MSG("SetDsaInternal failed");
5580
            return WOLFSSL_FATAL_ERROR;
5581
        }
5582
    }
5583
5584
#ifdef WOLFSSL_SMALL_STACK
5585
    tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
5586
    if (tmpRng == NULL)
5587
        return WOLFSSL_FATAL_ERROR;
5588
#endif
5589
5590
    if (wc_InitRng(tmpRng) == 0) {
5591
        rng = tmpRng;
5592
        initTmpRng = 1;
5593
    }
5594
    else {
5595
        WOLFSSL_MSG("Bad RNG Init, trying global");
5596
#ifdef WOLFSSL_SMALL_STACK
5597
        XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
5598
        tmpRng = NULL;
5599
#endif
5600
        rng = wolfssl_get_global_rng();
5601
        if (! rng)
5602
            return WOLFSSL_FATAL_ERROR;
5603
    }
5604
5605
    if (rng) {
5606
#ifdef HAVE_SELFTEST
5607
        if (dLen != WC_SHA_DIGEST_SIZE ||
5608
                wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
5609
            WOLFSSL_MSG("wc_DsaSign failed or dLen wrong length");
5610
            ret = WOLFSSL_FATAL_ERROR;
5611
        }
5612
#else
5613
        if (wc_DsaSign_ex(d, dLen, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
5614
            WOLFSSL_MSG("wc_DsaSign_ex failed");
5615
            ret = WOLFSSL_FATAL_ERROR;
5616
        }
5617
#endif
5618
        else
5619
            ret = WOLFSSL_SUCCESS;
5620
    }
5621
5622
    if (initTmpRng)
5623
        wc_FreeRng(tmpRng);
5624
#ifdef WOLFSSL_SMALL_STACK
5625
    XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
5626
#endif
5627
5628
    return ret;
5629
}
5630
5631
/* return 1 on success, < 0 otherwise */
5632
int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
5633
                       WOLFSSL_DSA* dsa)
5634
{
5635
    WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
5636
5637
    return dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa);
5638
}
5639
5640
#ifndef HAVE_SELFTEST
5641
WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
5642
                                        int inLen, WOLFSSL_DSA* dsa)
5643
{
5644
    byte sigBin[DSA_MAX_SIG_SIZE];
5645
    const byte *tmp = sigBin;
5646
    int sigLen;
5647
5648
    WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
5649
5650
    if (!digest || !dsa) {
5651
        WOLFSSL_MSG("Bad function arguments");
5652
        return NULL;
5653
    }
5654
5655
    if (dsa_do_sign(digest, inLen, sigBin, dsa) != 1) {
5656
        WOLFSSL_MSG("wolfSSL_DSA_do_sign error");
5657
        return NULL;
5658
    }
5659
5660
    if (dsa->internal == NULL) {
5661
        WOLFSSL_MSG("dsa->internal is null");
5662
        return NULL;
5663
    }
5664
5665
    sigLen = mp_unsigned_bin_size(&((DsaKey*)dsa->internal)->q);
5666
    if (sigLen <= 0) {
5667
        WOLFSSL_MSG("mp_unsigned_bin_size error");
5668
        return NULL;
5669
    }
5670
5671
    /* 2 * sigLen for the two points r and s */
5672
    return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen);
5673
}
5674
#endif
5675
5676
static int dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig,
5677
                        WOLFSSL_DSA* dsa, int *dsacheck)
5678
{
5679
    int    ret;
5680
5681
    if (d == NULL || sig == NULL || dsa == NULL) {
5682
        WOLFSSL_MSG("Bad function arguments");
5683
        return WOLFSSL_FATAL_ERROR;
5684
    }
5685
    if (dsa->inSet == 0)
5686
    {
5687
        WOLFSSL_MSG("No DSA internal set, do it");
5688
5689
        if (SetDsaInternal(dsa) != 1) {
5690
            WOLFSSL_MSG("SetDsaInternal failed");
5691
            return WOLFSSL_FATAL_ERROR;
5692
        }
5693
    }
5694
5695
#ifdef HAVE_SELFTEST
5696
    ret = dLen == WC_SHA_DIGEST_SIZE ?
5697
          wc_DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck) : BAD_FUNC_ARG;
5698
#else
5699
    ret = wc_DsaVerify_ex(d, (word32)dLen, sig, (DsaKey*)dsa->internal,
5700
        dsacheck);
5701
#endif
5702
    if (ret != 0) {
5703
        WOLFSSL_MSG("DsaVerify failed");
5704
        return WOLFSSL_FATAL_ERROR;
5705
    }
5706
    if (*dsacheck != 1) {
5707
        WOLFSSL_MSG("DsaVerify sig failed");
5708
        return WOLFSSL_FAILURE;
5709
    }
5710
5711
    return WOLFSSL_SUCCESS;
5712
}
5713
5714
int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
5715
                        WOLFSSL_DSA* dsa, int *dsacheck)
5716
{
5717
    WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
5718
5719
    return dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck);
5720
}
5721
5722
5723
int wolfSSL_DSA_bits(const WOLFSSL_DSA *d)
5724
{
5725
    if (!d)
5726
        return 0;
5727
    if (!d->exSet && SetDsaExternal((WOLFSSL_DSA*)d) != 1)
5728
        return 0;
5729
    return wolfSSL_BN_num_bits(d->p);
5730
}
5731
5732
#ifndef HAVE_SELFTEST
5733
int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
5734
                             WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa)
5735
{
5736
    int dsacheck, sz;
5737
    byte sigBin[DSA_MAX_SIG_SIZE];
5738
    byte* sigBinPtr = sigBin;
5739
    DsaKey* key;
5740
    int qSz;
5741
5742
    WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
5743
5744
    if (!digest || !sig || !dsa) {
5745
        WOLFSSL_MSG("Bad function arguments");
5746
        return 0;
5747
    }
5748
5749
    if (!sig->r || !sig->s) {
5750
        WOLFSSL_MSG("No signature found in DSA_SIG");
5751
        return 0;
5752
    }
5753
5754
    if (dsa->inSet == 0) {
5755
        WOLFSSL_MSG("No DSA internal set, do it");
5756
        if (SetDsaInternal(dsa) != 1) {
5757
            WOLFSSL_MSG("SetDsaInternal failed");
5758
            return 0;
5759
        }
5760
    }
5761
5762
    key = (DsaKey*)dsa->internal;
5763
5764
    if (key == NULL) {
5765
        WOLFSSL_MSG("dsa->internal is null");
5766
        return 0;
5767
    }
5768
5769
    qSz = mp_unsigned_bin_size(&key->q);
5770
    if (qSz < 0 || qSz > DSA_MAX_HALF_SIZE) {
5771
        WOLFSSL_MSG("mp_unsigned_bin_size error");
5772
        return 0;
5773
    }
5774
5775
    /* read r */
5776
    /* front pad with zeros */
5777
    if ((sz = wolfSSL_BN_num_bytes(sig->r)) < 0 || sz > DSA_MAX_HALF_SIZE)
5778
        return 0;
5779
    while (sz++ < qSz)
5780
        *sigBinPtr++ = 0;
5781
    if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == -1)
5782
        return 0;
5783
5784
    /* Move to s */
5785
    sigBinPtr = sigBin + qSz;
5786
5787
    /* read s */
5788
    /* front pad with zeros */
5789
    if ((sz = wolfSSL_BN_num_bytes(sig->s)) < 0 || sz > DSA_MAX_HALF_SIZE)
5790
        return 0;
5791
    while (sz++ < qSz)
5792
        *sigBinPtr++ = 0;
5793
    if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1)
5794
        return 0;
5795
5796
    if ((dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck)
5797
                                         != 1) || dsacheck != 1) {
5798
        return 0;
5799
    }
5800
5801
    return 1;
5802
}
5803
#endif
5804
5805
int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
5806
    unsigned char** out)
5807
{
5808
    int ret = 0;
5809
    word32 derLen = 0;
5810
    int preAllocated = 1;
5811
    DsaKey* key = NULL;
5812
5813
    WOLFSSL_ENTER("wolfSSL_i2d_DSAparams");
5814
5815
    if (dsa == NULL || dsa->internal == NULL || out == NULL) {
5816
        ret = BAD_FUNC_ARG;
5817
    }
5818
5819
    if (ret == 0) {
5820
        key = (DsaKey*)dsa->internal;
5821
        ret = wc_DsaKeyToParamsDer_ex(key, NULL, &derLen);
5822
        if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
5823
            ret = 0;
5824
        }
5825
    }
5826
    if (ret == 0 && *out == NULL) {
5827
        /* If we're allocating out for the caller, we don't increment out just
5828
           past the end of the DER buffer. If out is already allocated, we do.
5829
           (OpenSSL convention) */
5830
        preAllocated = 0;
5831
        *out = (unsigned char*)XMALLOC(derLen, key->heap, DYNAMIC_TYPE_OPENSSL);
5832
        if (*out == NULL) {
5833
            ret = MEMORY_E;
5834
        }
5835
    }
5836
    if (ret == 0) {
5837
        ret = wc_DsaKeyToParamsDer_ex(key, *out, &derLen);
5838
    }
5839
    if (ret >= 0 && preAllocated == 1) {
5840
        *out += derLen;
5841
    }
5842
5843
    if (ret < 0 && preAllocated == 0) {
5844
        XFREE(*out, key ? key->heap : NULL, DYNAMIC_TYPE_OPENSSL);
5845
    }
5846
5847
    WOLFSSL_LEAVE("wolfSSL_i2d_DSAparams", ret);
5848
5849
    return ret;
5850
}
5851
5852
WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa, const unsigned char** der,
5853
    long derLen)
5854
{
5855
    WOLFSSL_DSA* ret = NULL;
5856
    int err = 0;
5857
    word32 idx = 0;
5858
    int asnLen;
5859
    DsaKey* internalKey = NULL;
5860
5861
    WOLFSSL_ENTER("wolfSSL_d2i_DSAparams");
5862
5863
    if (der == NULL || *der == NULL || derLen <= 0) {
5864
        err = 1;
5865
    }
5866
    if (err == 0) {
5867
        ret = wolfSSL_DSA_new();
5868
        err = ret == NULL;
5869
    }
5870
    if (err == 0) {
5871
        err = GetSequence(*der, &idx, &asnLen, (word32)derLen) <= 0;
5872
    }
5873
    if (err == 0) {
5874
        internalKey = (DsaKey*)ret->internal;
5875
        err = GetInt(&internalKey->p, *der, &idx, (word32)derLen) != 0;
5876
    }
5877
    if (err == 0) {
5878
        err = GetInt(&internalKey->q, *der, &idx, (word32)derLen) != 0;
5879
    }
5880
    if (err == 0) {
5881
        err = GetInt(&internalKey->g, *der, &idx, (word32)derLen) != 0;
5882
    }
5883
    if (err == 0) {
5884
        err = wolfssl_bn_set_value(&ret->p, &internalKey->p)
5885
                != 1;
5886
    }
5887
    if (err == 0) {
5888
        err = wolfssl_bn_set_value(&ret->q, &internalKey->q)
5889
                != 1;
5890
    }
5891
    if (err == 0) {
5892
        err = wolfssl_bn_set_value(&ret->g, &internalKey->g)
5893
                != 1;
5894
    }
5895
    if (err == 0 && dsa != NULL) {
5896
        *dsa = ret;
5897
    }
5898
5899
    if (err != 0 && ret != NULL) {
5900
        wolfSSL_DSA_free(ret);
5901
        ret = NULL;
5902
    }
5903
5904
    return ret;
5905
}
5906
5907
#if defined(WOLFSSL_KEY_GEN)
5908
#ifndef NO_BIO
5909
5910
/* Takes a DSA Privatekey and writes it out to a WOLFSSL_BIO
5911
 * Returns 1 or 0
5912
 */
5913
int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
5914
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
5915
    wc_pem_password_cb* cb, void* arg)
5916
{
5917
    int ret = 1;
5918
    byte *pem = NULL;
5919
    int pLen = 0;
5920
5921
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSAPrivateKey");
5922
5923
    (void)cb;
5924
    (void)arg;
5925
5926
    /* Validate parameters. */
5927
    if ((bio == NULL) || (dsa == NULL)) {
5928
        WOLFSSL_MSG("Bad Function Arguments");
5929
        ret = 0;
5930
    }
5931
5932
    if (ret == 1) {
5933
        ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, cipher, passwd, passwdSz,
5934
            &pem, &pLen);
5935
    }
5936
5937
    /* Write PEM to BIO. */
5938
    if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) != pLen)) {
5939
        WOLFSSL_ERROR_MSG("DSA private key BIO write failed");
5940
        ret = 0;
5941
    }
5942
5943
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
5944
    return ret;
5945
}
5946
5947
#ifndef HAVE_SELFTEST
5948
/* Encode the DSA public key as DER.
5949
 *
5950
 * @param [in]  key   DSA key to encode.
5951
 * @param [out] der   Pointer through which buffer is returned.
5952
 * @param [in]  heap  Heap hint.
5953
 * @return  Size of encoding on success.
5954
 * @return  0 on error.
5955
 */
5956
static int wolfssl_dsa_key_to_pubkey_der(WOLFSSL_DSA* key, unsigned char** der,
5957
    void* heap)
5958
{
5959
    int sz;
5960
    unsigned char* buf = NULL;
5961
5962
    /* Use maximum encoded size to allocate. */
5963
    sz = MAX_DSA_PUBKEY_SZ;
5964
    /* Allocate memory to hold encoding. */
5965
    buf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
5966
    if (buf == NULL) {
5967
        WOLFSSL_MSG("malloc failed");
5968
        sz = 0;
5969
    }
5970
    if (sz > 0) {
5971
        /* Encode public key to DER using wolfSSL.  */
5972
        sz = wc_DsaKeyToPublicDer((DsaKey*)key->internal, buf, (word32)sz);
5973
        if (sz < 0) {
5974
            WOLFSSL_MSG("wc_DsaKeyToPublicDer failed");
5975
            sz = 0;
5976
        }
5977
    }
5978
5979
    /* Return buffer on success. */
5980
    if (sz > 0) {
5981
        *der = buf;
5982
    }
5983
    else {
5984
        /* Dispose of any dynamically allocated data not returned. */
5985
        XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
5986
    }
5987
5988
    return sz;
5989
}
5990
5991
/* Takes a DSA public key and writes it out to a WOLFSSL_BIO
5992
 * Returns 1 or 0
5993
 */
5994
int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa)
5995
{
5996
    int ret = 1;
5997
    unsigned char* derBuf = NULL;
5998
    int derSz = 0;
5999
6000
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSA_PUBKEY");
6001
6002
    /* Validate parameters. */
6003
    if ((bio == NULL) || (dsa == NULL)) {
6004
        WOLFSSL_MSG("Bad Function Arguments");
6005
        return 0;
6006
    }
6007
6008
    /* Encode public key in EC key as DER. */
6009
    derSz = wolfssl_dsa_key_to_pubkey_der(dsa, &derBuf, bio->heap);
6010
    if (derSz == 0) {
6011
        ret = 0;
6012
    }
6013
6014
    /* Write out to BIO the PEM encoding of the DSA public key. */
6015
    if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
6016
            PUBLICKEY_TYPE) != 1)) {
6017
        ret = 0;
6018
    }
6019
6020
    /* Dispose of any dynamically allocated data. */
6021
    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
6022
6023
    return ret;
6024
}
6025
#endif /* HAVE_SELFTEST */
6026
#endif /* !NO_BIO */
6027
6028
/* return code compliant with OpenSSL :
6029
 *   1 if success, 0 if error
6030
 */
6031
int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
6032
                                        const WOLFSSL_EVP_CIPHER* cipher,
6033
                                        unsigned char* passwd, int passwdSz,
6034
                                        unsigned char **pem, int *pLen)
6035
{
6036
#if (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
6037
    !defined(NO_MD5)
6038
    byte *derBuf, *tmp, *cipherInfo = NULL;
6039
    int  der_max_len = 0, derSz = 0;
6040
    const int type = DSA_PRIVATEKEY_TYPE;
6041
    const char* header = NULL;
6042
    const char* footer = NULL;
6043
6044
    WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
6045
6046
    if (pem == NULL || pLen == NULL || dsa == NULL || dsa->internal == NULL) {
6047
        WOLFSSL_MSG("Bad function arguments");
6048
        return 0;
6049
    }
6050
6051
    if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
6052
        return 0;
6053
6054
    if (dsa->inSet == 0) {
6055
        WOLFSSL_MSG("No DSA internal set, do it");
6056
6057
        if (SetDsaInternal(dsa) != 1) {
6058
            WOLFSSL_MSG("SetDsaInternal failed");
6059
            return 0;
6060
        }
6061
    }
6062
6063
    der_max_len = MAX_DSA_PRIVKEY_SZ;
6064
6065
    derBuf = (byte*)XMALLOC((size_t)der_max_len, NULL, DYNAMIC_TYPE_DER);
6066
    if (derBuf == NULL) {
6067
        WOLFSSL_MSG("malloc failed");
6068
        return 0;
6069
    }
6070
6071
    /* Key to DER */
6072
    derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, (word32)der_max_len);
6073
    if (derSz < 0) {
6074
        WOLFSSL_MSG("wc_DsaKeyToDer failed");
6075
        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
6076
        return 0;
6077
    }
6078
6079
    /* encrypt DER buffer if required */
6080
    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
6081
        int ret;
6082
6083
        ret = EncryptDerKey(derBuf, &derSz, cipher, passwd, passwdSz,
6084
            &cipherInfo, der_max_len, WC_MD5);
6085
        if (ret != 1) {
6086
            WOLFSSL_MSG("EncryptDerKey failed");
6087
            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
6088
            return ret;
6089
        }
6090
        /* tmp buffer with a max size */
6091
        *pLen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
6092
            (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
6093
    }
6094
    else { /* tmp buffer with a max size */
6095
        *pLen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
6096
            (int)XSTRLEN(footer) + 1;
6097
    }
6098
6099
    tmp = (byte*)XMALLOC((size_t)*pLen, NULL, DYNAMIC_TYPE_PEM);
6100
    if (tmp == NULL) {
6101
        WOLFSSL_MSG("malloc failed");
6102
        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
6103
        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
6104
        return 0;
6105
    }
6106
6107
    /* DER to PEM */
6108
    *pLen = wc_DerToPemEx(derBuf, (word32)derSz, tmp, (word32)*pLen, cipherInfo,
6109
        type);
6110
    if (*pLen <= 0) {
6111
        WOLFSSL_MSG("wc_DerToPemEx failed");
6112
        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
6113
        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
6114
        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
6115
        return 0;
6116
    }
6117
    XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
6118
    XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
6119
6120
    *pem = (byte*)XMALLOC((size_t)((*pLen)+1), NULL, DYNAMIC_TYPE_KEY);
6121
    if (*pem == NULL) {
6122
        WOLFSSL_MSG("malloc failed");
6123
        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
6124
        return 0;
6125
    }
6126
    XMEMSET(*pem, 0, (size_t)((*pLen)+1));
6127
6128
    if (XMEMCPY(*pem, tmp, (size_t)*pLen) == NULL) {
6129
        WOLFSSL_MSG("XMEMCPY failed");
6130
        XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
6131
        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
6132
        return 0;
6133
    }
6134
    XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
6135
6136
    return 1;
6137
#else
6138
    (void)dsa;
6139
    (void)cipher;
6140
    (void)passwd;
6141
    (void)passwdSz;
6142
    (void)pem;
6143
    (void)pLen;
6144
    return 0;
6145
#endif /* (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) && !NO_MD5 */
6146
}
6147
6148
#ifndef NO_FILESYSTEM
6149
/* return code compliant with OpenSSL :
6150
 *   1 if success, 0 if error
6151
 */
6152
int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
6153
                                    const WOLFSSL_EVP_CIPHER *enc,
6154
                                    unsigned char *kstr, int klen,
6155
                                    wc_pem_password_cb *cb, void *u)
6156
{
6157
    byte *pem;
6158
    int  pLen, ret;
6159
6160
    (void)cb;
6161
    (void)u;
6162
6163
    WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
6164
6165
    if (fp == XBADFILE || dsa == NULL || dsa->internal == NULL) {
6166
        WOLFSSL_MSG("Bad function arguments");
6167
        return 0;
6168
    }
6169
6170
    ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem,
6171
        &pLen);
6172
    if (ret != 1) {
6173
        WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
6174
        return 0;
6175
    }
6176
6177
    ret = (int)XFWRITE(pem, (size_t)pLen, 1, fp);
6178
    if (ret != 1) {
6179
        WOLFSSL_MSG("DSA private key file write failed");
6180
        return 0;
6181
    }
6182
6183
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
6184
    return 1;
6185
}
6186
6187
#endif /* NO_FILESYSTEM */
6188
#endif /* defined(WOLFSSL_KEY_GEN) */
6189
6190
#ifndef NO_FILESYSTEM
6191
/* return code compliant with OpenSSL :
6192
 *   1 if success, 0 if error
6193
 */
6194
#ifndef NO_WOLFSSL_STUB
6195
int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x)
6196
{
6197
    (void)fp;
6198
    (void)x;
6199
    WOLFSSL_STUB("PEM_write_DSA_PUBKEY");
6200
    WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
6201
6202
    return 0;
6203
}
6204
#endif
6205
#endif /* NO_FILESYSTEM */
6206
6207
#ifndef NO_BIO
6208
6209
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && (!defined(NO_CERTS) && \
6210
       !defined(NO_FILESYSTEM) && defined(WOLFSSL_KEY_GEN))
6211
/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
6212
 * the results to be an DSA key.
6213
 *
6214
 * bio  structure to read DSA private key from
6215
 * dsa  if not null is then set to the result
6216
 * cb   password callback for reading PEM
6217
 * pass password string
6218
 *
6219
 * returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
6220
 */
6221
WOLFSSL_DSA* wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO* bio,
6222
                                                WOLFSSL_DSA** dsa,
6223
                                                wc_pem_password_cb* cb,
6224
                                                void* pass)
6225
{
6226
    WOLFSSL_EVP_PKEY* pkey = NULL;
6227
    WOLFSSL_DSA* local;
6228
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAPrivateKey");
6229
6230
6231
    pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
6232
    if (pkey == NULL) {
6233
        WOLFSSL_MSG("Error in PEM_read_bio_PrivateKey");
6234
         return NULL;
6235
     }
6236
     /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
6237
     * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
6238
     * to avoid having it free'd */
6239
    pkey->ownDsa = 0;
6240
    local = pkey->dsa;
6241
    if (dsa != NULL) {
6242
        *dsa = local;
6243
    }
6244
     wolfSSL_EVP_PKEY_free(pkey);
6245
    return local;
6246
}
6247
6248
/* Reads an DSA public key from a WOLFSSL_BIO into a WOLFSSL_DSA.
6249
 * Returns 1 or 0
6250
 */
6251
WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa,
6252
                                             wc_pem_password_cb* cb, void* pass)
6253
{
6254
    WOLFSSL_EVP_PKEY* pkey;
6255
    WOLFSSL_DSA* local;
6256
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSA_PUBKEY");
6257
6258
    pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
6259
    if (pkey == NULL) {
6260
        WOLFSSL_MSG("wolfSSL_PEM_read_bio_PUBKEY failed");
6261
        return NULL;
6262
    }
6263
6264
    /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
6265
     * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
6266
     * to avoid having it free'd */
6267
    pkey->ownDsa = 0;
6268
    local = pkey->dsa;
6269
    if (dsa != NULL) {
6270
        *dsa = local;
6271
    }
6272
6273
    wolfSSL_EVP_PKEY_free(pkey);
6274
    return local;
6275
}
6276
#endif /* (OPENSSL_EXTRA || OPENSSL_ALL) && (!NO_CERTS &&
6277
          !NO_FILESYSTEM && WOLFSSL_KEY_GEN) */
6278
6279
#endif /* NO_BIO */
6280
6281
#endif /* OPENSSL_EXTRA */
6282
6283
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
6284
/* return 1 if success, -1 if error */
6285
int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz)
6286
{
6287
    word32 idx = 0;
6288
    int    ret;
6289
6290
    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
6291
6292
    if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
6293
        WOLFSSL_MSG("Bad function arguments");
6294
        return WOLFSSL_FATAL_ERROR;
6295
    }
6296
6297
    ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
6298
        (word32)derSz);
6299
    if (ret < 0) {
6300
        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
6301
        return WOLFSSL_FATAL_ERROR;
6302
    }
6303
6304
    if (SetDsaExternal(dsa) != 1) {
6305
        WOLFSSL_MSG("SetDsaExternal failed");
6306
        return WOLFSSL_FATAL_ERROR;
6307
    }
6308
6309
    dsa->inSet = 1;
6310
6311
    return 1;
6312
}
6313
6314
/* Loads DSA key from DER buffer. opt = DSA_LOAD_PRIVATE or DSA_LOAD_PUBLIC.
6315
    returns 1 on success, or 0 on failure.  */
6316
int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
6317
                                                            int derSz, int opt)
6318
{
6319
    word32 idx = 0;
6320
    int    ret;
6321
6322
    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
6323
6324
    if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
6325
        WOLFSSL_MSG("Bad function arguments");
6326
        return WOLFSSL_FATAL_ERROR;
6327
    }
6328
6329
    if (opt == WOLFSSL_DSA_LOAD_PRIVATE) {
6330
        ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
6331
            (word32)derSz);
6332
    }
6333
    else {
6334
        ret = DsaPublicKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
6335
            (word32)derSz);
6336
    }
6337
6338
    if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PRIVATE) {
6339
        WOLFSSL_ERROR_VERBOSE(ret);
6340
        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
6341
        return WOLFSSL_FATAL_ERROR;
6342
    }
6343
    else if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PUBLIC) {
6344
        WOLFSSL_ERROR_VERBOSE(ret);
6345
        WOLFSSL_MSG("DsaPublicKeyDecode failed");
6346
        return WOLFSSL_FATAL_ERROR;
6347
    }
6348
6349
    if (SetDsaExternal(dsa) != 1) {
6350
        WOLFSSL_MSG("SetDsaExternal failed");
6351
        return WOLFSSL_FATAL_ERROR;
6352
    }
6353
6354
    dsa->inSet = 1;
6355
6356
    return 1;
6357
}
6358
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
6359
6360
#ifdef OPENSSL_EXTRA
6361
#ifndef NO_BIO
6362
WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
6363
        wc_pem_password_cb *cb, void *u)
6364
{
6365
    WOLFSSL_DSA* dsa;
6366
    DsaKey* key;
6367
    int    length;
6368
    unsigned char*  buf;
6369
    word32 bufSz;
6370
    int ret;
6371
    word32 idx = 0;
6372
    DerBuffer* pDer;
6373
6374
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
6375
6376
    ret = wolfSSL_BIO_get_mem_data(bp, &buf);
6377
    if (ret <= 0) {
6378
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
6379
        return NULL;
6380
    }
6381
6382
    bufSz = (word32)ret;
6383
6384
    if (cb != NULL || u != NULL) {
6385
        /*
6386
         * cb is for a call back when encountering encrypted PEM files
6387
         * if cb == NULL and u != NULL then u = null terminated password string
6388
         */
6389
        WOLFSSL_MSG("Not yet supporting call back or password for encrypted PEM");
6390
    }
6391
6392
    if (PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
6393
                    NULL) < 0 ) {
6394
        WOLFSSL_MSG("Issue converting from PEM to DER");
6395
        return NULL;
6396
    }
6397
6398
    if (GetSequence(pDer->buffer, &idx, &length, pDer->length) < 0) {
6399
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
6400
        FreeDer(&pDer);
6401
        return NULL;
6402
    }
6403
6404
    dsa = wolfSSL_DSA_new();
6405
    if (dsa == NULL) {
6406
        FreeDer(&pDer);
6407
        WOLFSSL_MSG("Error creating DSA struct");
6408
        return NULL;
6409
    }
6410
6411
    key = (DsaKey*)dsa->internal;
6412
    if (key == NULL) {
6413
        FreeDer(&pDer);
6414
        wolfSSL_DSA_free(dsa);
6415
        WOLFSSL_MSG("Error finding DSA key struct");
6416
        return NULL;
6417
    }
6418
6419
    if (GetInt(&key->p,  pDer->buffer, &idx, pDer->length) < 0 ||
6420
        GetInt(&key->q,  pDer->buffer, &idx, pDer->length) < 0 ||
6421
        GetInt(&key->g,  pDer->buffer, &idx, pDer->length) < 0 ) {
6422
        WOLFSSL_MSG("dsa key error");
6423
        FreeDer(&pDer);
6424
        wolfSSL_DSA_free(dsa);
6425
        return NULL;
6426
    }
6427
6428
    if (wolfssl_bn_set_value(&dsa->p, &key->p) != 1) {
6429
        WOLFSSL_MSG("dsa p key error");
6430
        FreeDer(&pDer);
6431
        wolfSSL_DSA_free(dsa);
6432
        return NULL;
6433
    }
6434
6435
    if (wolfssl_bn_set_value(&dsa->q, &key->q) != 1) {
6436
        WOLFSSL_MSG("dsa q key error");
6437
        FreeDer(&pDer);
6438
        wolfSSL_DSA_free(dsa);
6439
        return NULL;
6440
    }
6441
6442
    if (wolfssl_bn_set_value(&dsa->g, &key->g) != 1) {
6443
        WOLFSSL_MSG("dsa g key error");
6444
        FreeDer(&pDer);
6445
        wolfSSL_DSA_free(dsa);
6446
        return NULL;
6447
    }
6448
6449
    if (x != NULL) {
6450
        *x = dsa;
6451
    }
6452
6453
    FreeDer(&pDer);
6454
    return dsa;
6455
}
6456
#endif /* !NO_BIO */
6457
6458
#if !defined(NO_DH)
6459
WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
6460
{
6461
    WOLFSSL_DH* dh;
6462
    DhKey*      key;
6463
6464
    WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
6465
6466
    if (dsa == NULL) {
6467
        return NULL;
6468
    }
6469
6470
    dh = wolfSSL_DH_new();
6471
    if (dh == NULL) {
6472
        return NULL;
6473
    }
6474
    key = (DhKey*)dh->internal;
6475
6476
    if (dsa->p != NULL &&
6477
        wolfssl_bn_get_value(((WOLFSSL_DSA*)dsa)->p, &key->p)
6478
                                                           != 1) {
6479
        WOLFSSL_MSG("rsa p key error");
6480
        wolfSSL_DH_free(dh);
6481
        return NULL;
6482
    }
6483
    if (dsa->g != NULL &&
6484
        wolfssl_bn_get_value(((WOLFSSL_DSA*)dsa)->g, &key->g)
6485
                                                           != 1) {
6486
        WOLFSSL_MSG("rsa g key error");
6487
        wolfSSL_DH_free(dh);
6488
        return NULL;
6489
    }
6490
6491
    if (wolfssl_bn_set_value(&dh->p, &key->p) != 1) {
6492
        WOLFSSL_MSG("dsa p key error");
6493
        wolfSSL_DH_free(dh);
6494
        return NULL;
6495
    }
6496
    if (wolfssl_bn_set_value(&dh->g, &key->g) != 1) {
6497
        WOLFSSL_MSG("dsa g key error");
6498
        wolfSSL_DH_free(dh);
6499
        return NULL;
6500
    }
6501
6502
    return dh;
6503
}
6504
#endif /* !NO_DH */
6505
6506
#endif /* OPENSSL_EXTRA */
6507
6508
#endif /* !NO_DSA */
6509
6510
/*******************************************************************************
6511
 * END OF DSA API
6512
 ******************************************************************************/
6513
6514
6515
/*******************************************************************************
6516
 * START OF DH API
6517
 ******************************************************************************/
6518
6519
#ifndef NO_DH
6520
6521
#ifdef OPENSSL_EXTRA
6522
6523
/*
6524
 * DH constructor/deconstructor APIs
6525
 */
6526
6527
/* Allocate and initialize a new DH key.
6528
 *
6529
 * @return  DH key on success.
6530
 * @return  NULL on failure.
6531
 */
6532
WOLFSSL_DH* wolfSSL_DH_new(void)
6533
{
6534
    int err = 0;
6535
    WOLFSSL_DH* dh = NULL;
6536
    DhKey* key = NULL;
6537
6538
    WOLFSSL_ENTER("wolfSSL_DH_new");
6539
6540
    /* Allocate OpenSSL DH key. */
6541
    dh = (WOLFSSL_DH*)XMALLOC(sizeof(WOLFSSL_DH), NULL, DYNAMIC_TYPE_DH);
6542
    if (dh == NULL) {
6543
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
6544
        err = 1;
6545
    }
6546
6547
    if (!err) {
6548
        /* Clear key data. */
6549
        XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
6550
        /* Initialize reference counting. */
6551
        wolfSSL_RefInit(&dh->ref, &err);
6552
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
6553
    }
6554
    if (!err) {
6555
#endif
6556
        /* Allocate wolfSSL DH key. */
6557
        key = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
6558
        if (key == NULL) {
6559
            WOLFSSL_ERROR_MSG("wolfSSL_DH_new malloc DhKey failure");
6560
            err = 1;
6561
        }
6562
    }
6563
    if (!err) {
6564
        /* Set and initialize wolfSSL DH key. */
6565
        dh->internal = key;
6566
        if (wc_InitDhKey(key) != 0) {
6567
            WOLFSSL_ERROR_MSG("wolfSSL_DH_new InitDhKey failure");
6568
            err = 1;
6569
        }
6570
    }
6571
6572
    if (err && (dh != NULL)) {
6573
        /* Dispose of the allocated memory. */
6574
        XFREE(key, NULL, DYNAMIC_TYPE_DH);
6575
        wolfSSL_RefFree(&dh->ref);
6576
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
6577
        dh = NULL;
6578
    }
6579
    return dh;
6580
}
6581
6582
#if defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && FIPS_VERSION_EQ(2,0))
6583
/* Set the DH parameters based on the NID.
6584
 *
6585
 * @param [in, out] dh   DH key to set.
6586
 * @param [in]      nid  Numeric ID of predefined DH parameters.
6587
 * @return  0 on success.
6588
 * @return  1 on failure.
6589
 */
6590
static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
6591
{
6592
    int err = 0;
6593
    const DhParams* params = NULL;
6594
6595
    /* HAVE_PUBLIC_FFDHE not required to expose wc_Dh_ffdhe* functions in
6596
     * FIPS v2 module */
6597
    switch (nid) {
6598
#ifdef HAVE_FFDHE_2048
6599
    case WC_NID_ffdhe2048:
6600
        params = wc_Dh_ffdhe2048_Get();
6601
        break;
6602
#endif /* HAVE_FFDHE_2048 */
6603
#ifdef HAVE_FFDHE_3072
6604
    case WC_NID_ffdhe3072:
6605
        params = wc_Dh_ffdhe3072_Get();
6606
        break;
6607
#endif /* HAVE_FFDHE_3072 */
6608
#ifdef HAVE_FFDHE_4096
6609
    case WC_NID_ffdhe4096:
6610
        params = wc_Dh_ffdhe4096_Get();
6611
        break;
6612
#endif /* HAVE_FFDHE_4096 */
6613
    default:
6614
        break;
6615
    }
6616
    if (params == NULL) {
6617
        WOLFSSL_ERROR_MSG("Unable to find DH params for nid.");
6618
        err = 1;
6619
    }
6620
6621
    if (!err) {
6622
        /* Set prime from data retrieved. */
6623
        dh->p = wolfSSL_BN_bin2bn(params->p, (int)params->p_len, NULL);
6624
        if (dh->p == NULL) {
6625
            WOLFSSL_ERROR_MSG("Error converting p hex to WOLFSSL_BIGNUM.");
6626
            err = 1;
6627
        }
6628
    }
6629
    if (!err) {
6630
        /* Set generator from data retrieved. */
6631
        dh->g = wolfSSL_BN_bin2bn(params->g, (int)params->g_len, NULL);
6632
        if (dh->g == NULL) {
6633
            WOLFSSL_ERROR_MSG("Error converting g hex to WOLFSSL_BIGNUM.");
6634
            err = 1;
6635
        }
6636
    }
6637
#ifdef HAVE_FFDHE_Q
6638
    if (!err) {
6639
        /* Set order from data retrieved. */
6640
        dh->q = wolfSSL_BN_bin2bn(params->q, params->q_len, NULL);
6641
        if (dh->q == NULL) {
6642
            WOLFSSL_ERROR_MSG("Error converting q hex to WOLFSSL_BIGNUM.");
6643
            err = 1;
6644
        }
6645
    }
6646
#endif
6647
6648
    /* Synchronize the external into internal DH key's parameters. */
6649
    if ((!err) && (SetDhInternal(dh) != 1)) {
6650
        WOLFSSL_ERROR_MSG("Failed to set internal DH params.");
6651
        err = 1;
6652
    }
6653
    if (!err) {
6654
        /* External DH key parameters were set. */
6655
        dh->exSet = 1;
6656
    }
6657
6658
    if (err == 1) {
6659
        /* Dispose of any external parameters. */
6660
    #ifdef HAVE_FFDHE_Q
6661
        wolfSSL_BN_free(dh->q);
6662
        dh->q = NULL;
6663
    #endif
6664
        wolfSSL_BN_free(dh->p);
6665
        dh->p = NULL;
6666
        wolfSSL_BN_free(dh->g);
6667
        dh->g = NULL;
6668
    }
6669
6670
    return err;
6671
}
6672
#elif !defined(HAVE_PUBLIC_FFDHE) && (!defined(HAVE_FIPS) || \
6673
      FIPS_VERSION_GT(2,0))
6674
/* Set the DH parameters based on the NID.
6675
 *
6676
 * FIPS v2 and lower doesn't support wc_DhSetNamedKey.
6677
 *
6678
 * @param [in, out] dh   DH key to set.
6679
 * @param [in]      nid  Numeric ID of predefined DH parameters.
6680
 * @return  0 on success.
6681
 * @return  1 on failure.
6682
 */
6683
static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
6684
{
6685
    int err = 0;
6686
    int name = 0;
6687
#ifdef HAVE_FFDHE_Q
6688
    int elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q;
6689
#else
6690
    int elements = ELEMENT_P | ELEMENT_G;
6691
#endif /* HAVE_FFDHE_Q */
6692
6693
    switch (nid) {
6694
#ifdef HAVE_FFDHE_2048
6695
    case WC_NID_ffdhe2048:
6696
        name = WC_FFDHE_2048;
6697
        break;
6698
#endif /* HAVE_FFDHE_2048 */
6699
#ifdef HAVE_FFDHE_3072
6700
    case WC_NID_ffdhe3072:
6701
        name = WC_FFDHE_3072;
6702
        break;
6703
#endif /* HAVE_FFDHE_3072 */
6704
#ifdef HAVE_FFDHE_4096
6705
    case WC_NID_ffdhe4096:
6706
        name = WC_FFDHE_4096;
6707
        break;
6708
#endif /* HAVE_FFDHE_4096 */
6709
    default:
6710
        err = 1;
6711
        WOLFSSL_ERROR_MSG("Unable to find DH params for nid.");
6712
        break;
6713
    }
6714
    /* Set the internal DH key's parameters based on name. */
6715
    if ((!err) && (wc_DhSetNamedKey((DhKey*)dh->internal, name) != 0)) {
6716
        WOLFSSL_ERROR_MSG("wc_DhSetNamedKey failed.");
6717
        err = 1;
6718
    }
6719
    /* Synchronize the internal into external DH key's parameters. */
6720
    if (!err && (SetDhExternal_ex(dh, elements) != 1)) {
6721
        WOLFSSL_ERROR_MSG("Failed to set external DH params.");
6722
        err = 1;
6723
    }
6724
6725
    return err;
6726
}
6727
#else
6728
/* Set the DH parameters based on the NID.
6729
 *
6730
 * Pre-defined DH parameters not available.
6731
 *
6732
 * @param [in, out] dh   DH key to set.
6733
 * @param [in]      nid  Numeric ID of predefined DH parameters.
6734
 * @return  1 for failure.
6735
 */
6736
static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
6737
{
6738
    return 1;
6739
}
6740
#endif
6741
6742
/* Allocate and initialize a new DH key with the parameters based on the NID.
6743
 *
6744
 * @param [in] nid  Numeric ID of DH parameters.
6745
 *
6746
 * @return  DH key on success.
6747
 * @return  NULL on failure.
6748
 */
6749
WOLFSSL_DH* wolfSSL_DH_new_by_nid(int nid)
6750
{
6751
    WOLFSSL_DH* dh = NULL;
6752
    int err = 0;
6753
6754
    WOLFSSL_ENTER("wolfSSL_DH_new_by_nid");
6755
6756
    /* Allocate a new DH key. */
6757
    dh = wolfSSL_DH_new();
6758
    if (dh == NULL) {
6759
        WOLFSSL_ERROR_MSG("Failed to create WOLFSSL_DH.");
6760
        err = 1;
6761
    }
6762
    if (!err) {
6763
        /* Set the parameters based on NID. */
6764
        err = wolfssl_dh_set_nid(dh, nid);
6765
    }
6766
6767
    if (err && (dh != NULL)) {
6768
        /* Dispose of the key on failure to set. */
6769
        wolfSSL_DH_free(dh);
6770
        dh = NULL;
6771
    }
6772
6773
    WOLFSSL_LEAVE("wolfSSL_DH_new_by_nid", err);
6774
6775
    return dh;
6776
}
6777
6778
/* Dispose of DH key and allocated data.
6779
 *
6780
 * Cannot use dh after this call.
6781
 *
6782
 * @param [in] dh  DH key to free.
6783
 */
6784
void wolfSSL_DH_free(WOLFSSL_DH* dh)
6785
{
6786
    int doFree = 0;
6787
6788
    WOLFSSL_ENTER("wolfSSL_DH_free");
6789
6790
    if (dh != NULL) {
6791
        int err;
6792
6793
        /* Only free if all references to it are done */
6794
        wolfSSL_RefDec(&dh->ref, &doFree, &err);
6795
        /* Ignore errors - doFree will be 0 on error. */
6796
        (void)err;
6797
    }
6798
    if (doFree) {
6799
        /* Dispose of allocated reference counting data. */
6800
        wolfSSL_RefFree(&dh->ref);
6801
6802
        /* Dispose of wolfSSL DH key. */
6803
        if (dh->internal) {
6804
            wc_FreeDhKey((DhKey*)dh->internal);
6805
            XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
6806
            dh->internal = NULL;
6807
        }
6808
6809
        /* Dispose of any allocated BNs. */
6810
        wolfSSL_BN_free(dh->priv_key);
6811
        wolfSSL_BN_free(dh->pub_key);
6812
        wolfSSL_BN_free(dh->g);
6813
        wolfSSL_BN_free(dh->p);
6814
        wolfSSL_BN_free(dh->q);
6815
        /* Set back to NULLs for safety. */
6816
        XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
6817
6818
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
6819
    }
6820
}
6821
6822
/* Increments ref count of DH key.
6823
 *
6824
 * @param [in, out] dh  DH key.
6825
 * @return  1 on success
6826
 * @return  0 on error
6827
 */
6828
int wolfSSL_DH_up_ref(WOLFSSL_DH* dh)
6829
{
6830
    int err = 1;
6831
6832
    WOLFSSL_ENTER("wolfSSL_DH_up_ref");
6833
6834
    if (dh != NULL) {
6835
        wolfSSL_RefInc(&dh->ref, &err);
6836
    }
6837
6838
    return !err;
6839
}
6840
6841
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) || \
6842
    defined(OPENSSL_EXTRA)
6843
6844
#ifdef WOLFSSL_DH_EXTRA
6845
/* Duplicate the DH key.
6846
 *
6847
 * Internal DH key in 'dh' is updated if necessary.
6848
 *
6849
 * @param [in, out] dh  DH key to duplicate.
6850
 * @return  NULL on failure.
6851
 * @return  DH key on success.
6852
 */
6853
WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh)
6854
{
6855
    WOLFSSL_DH* ret = NULL;
6856
    int err = 0;
6857
6858
    WOLFSSL_ENTER("wolfSSL_DH_dup");
6859
6860
    /* Validate parameters. */
6861
    if (dh == NULL) {
6862
        WOLFSSL_ERROR_MSG("Bad parameter");
6863
        err = 1;
6864
    }
6865
6866
    /* Ensure internal DH key is set. */
6867
    if ((!err) && (dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
6868
        WOLFSSL_ERROR_MSG("Bad DH set internal");
6869
        err = 1;
6870
    }
6871
6872
    /* Create a new DH key object. */
6873
    if ((!err) && (!(ret = wolfSSL_DH_new()))) {
6874
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new error");
6875
        err = 1;
6876
    }
6877
    /* Copy internal DH key from original to new. */
6878
    if ((!err) && (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) !=
6879
            MP_OKAY)) {
6880
        WOLFSSL_ERROR_MSG("wc_DhKeyCopy error");
6881
        err = 1;
6882
    }
6883
    if (!err) {
6884
        ret->inSet = 1;
6885
6886
         /* Synchronize the internal into external DH key's parameters. */
6887
        if (SetDhExternal(ret) != 1) {
6888
            WOLFSSL_ERROR_MSG("SetDhExternal error");
6889
            err = 1;
6890
        }
6891
    }
6892
6893
    /* Dispose of any allocated DH key on error. */
6894
    if (err && (ret != NULL)) {
6895
        wolfSSL_DH_free(ret);
6896
        ret = NULL;
6897
    }
6898
    return ret;
6899
}
6900
#endif /* WOLFSSL_DH_EXTRA */
6901
6902
#endif
6903
6904
/* Allocate and initialize a new DH key with 2048-bit parameters.
6905
 *
6906
 * See RFC 5114 section 2.3, "2048-bit MODP Group with 256-bit Prime Order
6907
 * Subgroup."
6908
 *
6909
 * @return  NULL on failure.
6910
 * @return  DH Key on success.
6911
 */
6912
WOLFSSL_DH* wolfSSL_DH_get_2048_256(void)
6913
{
6914
    WOLFSSL_DH* dh;
6915
    int err = 0;
6916
    static const byte pHex[] = {
6917
        0x87, 0xA8, 0xE6, 0x1D, 0xB4, 0xB6, 0x66, 0x3C, 0xFF, 0xBB, 0xD1, 0x9C,
6918
        0x65, 0x19, 0x59, 0x99, 0x8C, 0xEE, 0xF6, 0x08, 0x66, 0x0D, 0xD0, 0xF2,
6919
        0x5D, 0x2C, 0xEE, 0xD4, 0x43, 0x5E, 0x3B, 0x00, 0xE0, 0x0D, 0xF8, 0xF1,
6920
        0xD6, 0x19, 0x57, 0xD4, 0xFA, 0xF7, 0xDF, 0x45, 0x61, 0xB2, 0xAA, 0x30,
6921
        0x16, 0xC3, 0xD9, 0x11, 0x34, 0x09, 0x6F, 0xAA, 0x3B, 0xF4, 0x29, 0x6D,
6922
        0x83, 0x0E, 0x9A, 0x7C, 0x20, 0x9E, 0x0C, 0x64, 0x97, 0x51, 0x7A, 0xBD,
6923
        0x5A, 0x8A, 0x9D, 0x30, 0x6B, 0xCF, 0x67, 0xED, 0x91, 0xF9, 0xE6, 0x72,
6924
        0x5B, 0x47, 0x58, 0xC0, 0x22, 0xE0, 0xB1, 0xEF, 0x42, 0x75, 0xBF, 0x7B,
6925
        0x6C, 0x5B, 0xFC, 0x11, 0xD4, 0x5F, 0x90, 0x88, 0xB9, 0x41, 0xF5, 0x4E,
6926
        0xB1, 0xE5, 0x9B, 0xB8, 0xBC, 0x39, 0xA0, 0xBF, 0x12, 0x30, 0x7F, 0x5C,
6927
        0x4F, 0xDB, 0x70, 0xC5, 0x81, 0xB2, 0x3F, 0x76, 0xB6, 0x3A, 0xCA, 0xE1,
6928
        0xCA, 0xA6, 0xB7, 0x90, 0x2D, 0x52, 0x52, 0x67, 0x35, 0x48, 0x8A, 0x0E,
6929
        0xF1, 0x3C, 0x6D, 0x9A, 0x51, 0xBF, 0xA4, 0xAB, 0x3A, 0xD8, 0x34, 0x77,
6930
        0x96, 0x52, 0x4D, 0x8E, 0xF6, 0xA1, 0x67, 0xB5, 0xA4, 0x18, 0x25, 0xD9,
6931
        0x67, 0xE1, 0x44, 0xE5, 0x14, 0x05, 0x64, 0x25, 0x1C, 0xCA, 0xCB, 0x83,
6932
        0xE6, 0xB4, 0x86, 0xF6, 0xB3, 0xCA, 0x3F, 0x79, 0x71, 0x50, 0x60, 0x26,
6933
        0xC0, 0xB8, 0x57, 0xF6, 0x89, 0x96, 0x28, 0x56, 0xDE, 0xD4, 0x01, 0x0A,
6934
        0xBD, 0x0B, 0xE6, 0x21, 0xC3, 0xA3, 0x96, 0x0A, 0x54, 0xE7, 0x10, 0xC3,
6935
        0x75, 0xF2, 0x63, 0x75, 0xD7, 0x01, 0x41, 0x03, 0xA4, 0xB5, 0x43, 0x30,
6936
        0xC1, 0x98, 0xAF, 0x12, 0x61, 0x16, 0xD2, 0x27, 0x6E, 0x11, 0x71, 0x5F,
6937
        0x69, 0x38, 0x77, 0xFA, 0xD7, 0xEF, 0x09, 0xCA, 0xDB, 0x09, 0x4A, 0xE9,
6938
        0x1E, 0x1A, 0x15, 0x97
6939
    };
6940
    static const byte gHex[] = {
6941
        0x3F, 0xB3, 0x2C, 0x9B, 0x73, 0x13, 0x4D, 0x0B, 0x2E, 0x77, 0x50, 0x66,
6942
        0x60, 0xED, 0xBD, 0x48, 0x4C, 0xA7, 0xB1, 0x8F, 0x21, 0xEF, 0x20, 0x54,
6943
        0x07, 0xF4, 0x79, 0x3A, 0x1A, 0x0B, 0xA1, 0x25, 0x10, 0xDB, 0xC1, 0x50,
6944
        0x77, 0xBE, 0x46, 0x3F, 0xFF, 0x4F, 0xED, 0x4A, 0xAC, 0x0B, 0xB5, 0x55,
6945
        0xBE, 0x3A, 0x6C, 0x1B, 0x0C, 0x6B, 0x47, 0xB1, 0xBC, 0x37, 0x73, 0xBF,
6946
        0x7E, 0x8C, 0x6F, 0x62, 0x90, 0x12, 0x28, 0xF8, 0xC2, 0x8C, 0xBB, 0x18,
6947
        0xA5, 0x5A, 0xE3, 0x13, 0x41, 0x00, 0x0A, 0x65, 0x01, 0x96, 0xF9, 0x31,
6948
        0xC7, 0x7A, 0x57, 0xF2, 0xDD, 0xF4, 0x63, 0xE5, 0xE9, 0xEC, 0x14, 0x4B,
6949
        0x77, 0x7D, 0xE6, 0x2A, 0xAA, 0xB8, 0xA8, 0x62, 0x8A, 0xC3, 0x76, 0xD2,
6950
        0x82, 0xD6, 0xED, 0x38, 0x64, 0xE6, 0x79, 0x82, 0x42, 0x8E, 0xBC, 0x83,
6951
        0x1D, 0x14, 0x34, 0x8F, 0x6F, 0x2F, 0x91, 0x93, 0xB5, 0x04, 0x5A, 0xF2,
6952
        0x76, 0x71, 0x64, 0xE1, 0xDF, 0xC9, 0x67, 0xC1, 0xFB, 0x3F, 0x2E, 0x55,
6953
        0xA4, 0xBD, 0x1B, 0xFF, 0xE8, 0x3B, 0x9C, 0x80, 0xD0, 0x52, 0xB9, 0x85,
6954
        0xD1, 0x82, 0xEA, 0x0A, 0xDB, 0x2A, 0x3B, 0x73, 0x13, 0xD3, 0xFE, 0x14,
6955
        0xC8, 0x48, 0x4B, 0x1E, 0x05, 0x25, 0x88, 0xB9, 0xB7, 0xD2, 0xBB, 0xD2,
6956
        0xDF, 0x01, 0x61, 0x99, 0xEC, 0xD0, 0x6E, 0x15, 0x57, 0xCD, 0x09, 0x15,
6957
        0xB3, 0x35, 0x3B, 0xBB, 0x64, 0xE0, 0xEC, 0x37, 0x7F, 0xD0, 0x28, 0x37,
6958
        0x0D, 0xF9, 0x2B, 0x52, 0xC7, 0x89, 0x14, 0x28, 0xCD, 0xC6, 0x7E, 0xB6,
6959
        0x18, 0x4B, 0x52, 0x3D, 0x1D, 0xB2, 0x46, 0xC3, 0x2F, 0x63, 0x07, 0x84,
6960
        0x90, 0xF0, 0x0E, 0xF8, 0xD6, 0x47, 0xD1, 0x48, 0xD4, 0x79, 0x54, 0x51,
6961
        0x5E, 0x23, 0x27, 0xCF, 0xEF, 0x98, 0xC5, 0x82, 0x66, 0x4B, 0x4C, 0x0F,
6962
        0x6C, 0xC4, 0x16, 0x59
6963
    };
6964
    static const byte qHex[] = {
6965
        0x8C, 0xF8, 0x36, 0x42, 0xA7, 0x09, 0xA0, 0x97, 0xB4, 0x47, 0x99, 0x76,
6966
        0x40, 0x12, 0x9D, 0xA2, 0x99, 0xB1, 0xA4, 0x7D, 0x1E, 0xB3, 0x75, 0x0B,
6967
        0xA3, 0x08, 0xB0, 0xFE, 0x64, 0xF5, 0xFB, 0xD3
6968
    };
6969
6970
    /* Create a new DH key to return. */
6971
    dh = wolfSSL_DH_new();
6972
    if (dh == NULL) {
6973
        err = 1;
6974
    }
6975
    if (!err) {
6976
        /* Set prime. */
6977
        dh->p = wolfSSL_BN_bin2bn(pHex, (int)sizeof(pHex), NULL);
6978
        if (dh->p == NULL) {
6979
            WOLFSSL_ERROR_MSG("Error converting p hex to WOLFSSL_BIGNUM.");
6980
            err = 1;
6981
        }
6982
    }
6983
    if (!err) {
6984
        /* Set generator. */
6985
        dh->g = wolfSSL_BN_bin2bn(gHex, (int)sizeof(gHex), NULL);
6986
        if (dh->g == NULL) {
6987
            WOLFSSL_ERROR_MSG("Error converting g hex to WOLFSSL_BIGNUM.");
6988
            err = 1;
6989
        }
6990
    }
6991
    if (!err) {
6992
        /* Set order. */
6993
        dh->q = wolfSSL_BN_bin2bn(qHex, (int)sizeof(qHex), NULL);
6994
        if (dh->q == NULL) {
6995
            WOLFSSL_ERROR_MSG("Error converting q hex to WOLFSSL_BIGNUM.");
6996
            err = 1;
6997
        }
6998
    }
6999
    /* Set values into wolfSSL DH key. */
7000
    if ((!err) && (SetDhInternal(dh) != 1)) {
7001
        WOLFSSL_ERROR_MSG("Error setting DH parameters.");
7002
        err = 1;
7003
    }
7004
    if (!err) {
7005
        /* External DH key parameters were set. */
7006
        dh->exSet = 1;
7007
    }
7008
7009
    /* Dispose of any allocated DH key on error. */
7010
    if (err && (dh != NULL)) {
7011
        wolfSSL_DH_free(dh);
7012
        dh = NULL;
7013
    }
7014
7015
    return dh;
7016
}
7017
7018
/* TODO: consider changing strings to byte arrays. */
7019
7020
/* Returns a big number with the 768-bit prime from RFC 2409.
7021
 *
7022
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7023
 *                      If NULL then a new BN is created, set and returned.
7024
 *
7025
 * @return  NULL on failure.
7026
 * @return  WOLFSSL_BIGNUM with value set to 768-bit prime on success.
7027
 */
7028
WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn)
7029
{
7030
#if WOLFSSL_MAX_BN_BITS >= 768
7031
    static const char prm[] = {
7032
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7033
        "C4C6628B80DC1CD129024E088A67CC74"
7034
        "020BBEA63B139B22514A08798E3404DD"
7035
        "EF9519B3CD3A431B302B0A6DF25F1437"
7036
        "4FE1356D6D51C245E485B576625E7EC6"
7037
        "F44C42E9A63A3620FFFFFFFFFFFFFFFF"
7038
    };
7039
7040
    WOLFSSL_ENTER("wolfSSL_DH_768_prime");
7041
7042
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7043
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7044
        WOLFSSL_ERROR_MSG("Error converting DH 768 prime to big number");
7045
        bn = NULL;
7046
    }
7047
7048
    return bn;
7049
#else
7050
    (void)bn;
7051
    return NULL;
7052
#endif
7053
}
7054
7055
/* Returns a big number with the 1024-bit prime from RFC 2409.
7056
 *
7057
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7058
 *                      If NULL then a new BN is created, set and returned.
7059
 *
7060
 * @return  NULL on failure.
7061
 * @return  WOLFSSL_BIGNUM with value set to 1024-bit prime on success.
7062
 */
7063
WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn)
7064
{
7065
#if WOLFSSL_MAX_BN_BITS >= 1024
7066
    static const char prm[] = {
7067
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7068
        "C4C6628B80DC1CD129024E088A67CC74"
7069
        "020BBEA63B139B22514A08798E3404DD"
7070
        "EF9519B3CD3A431B302B0A6DF25F1437"
7071
        "4FE1356D6D51C245E485B576625E7EC6"
7072
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7073
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7074
        "49286651ECE65381FFFFFFFFFFFFFFFF"
7075
    };
7076
7077
    WOLFSSL_ENTER("wolfSSL_DH_1024_prime");
7078
7079
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7080
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7081
        WOLFSSL_ERROR_MSG("Error converting DH 1024 prime to big number");
7082
        bn = NULL;
7083
    }
7084
7085
    return bn;
7086
#else
7087
    (void)bn;
7088
    return NULL;
7089
#endif
7090
}
7091
7092
/* Returns a big number with the 1536-bit prime from RFC 3526.
7093
 *
7094
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7095
 *                      If NULL then a new BN is created, set and returned.
7096
 *
7097
 * @return  NULL on failure.
7098
 * @return  WOLFSSL_BIGNUM with value set to 1536-bit prime on success.
7099
 */
7100
WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn)
7101
{
7102
#if WOLFSSL_MAX_BN_BITS >= 1536
7103
    static const char prm[] = {
7104
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7105
        "C4C6628B80DC1CD129024E088A67CC74"
7106
        "020BBEA63B139B22514A08798E3404DD"
7107
        "EF9519B3CD3A431B302B0A6DF25F1437"
7108
        "4FE1356D6D51C245E485B576625E7EC6"
7109
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7110
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7111
        "49286651ECE45B3DC2007CB8A163BF05"
7112
        "98DA48361C55D39A69163FA8FD24CF5F"
7113
        "83655D23DCA3AD961C62F356208552BB"
7114
        "9ED529077096966D670C354E4ABC9804"
7115
        "F1746C08CA237327FFFFFFFFFFFFFFFF"
7116
    };
7117
7118
    WOLFSSL_ENTER("wolfSSL_DH_1536_prime");
7119
7120
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7121
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7122
        WOLFSSL_ERROR_MSG("Error converting DH 1536 prime to big number");
7123
        bn = NULL;
7124
    }
7125
7126
    return bn;
7127
#else
7128
    (void)bn;
7129
    return NULL;
7130
#endif
7131
}
7132
7133
/* Returns a big number with the 2048-bit prime from RFC 3526.
7134
 *
7135
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7136
 *                      If NULL then a new BN is created, set and returned.
7137
 *
7138
 * @return  NULL on failure.
7139
 * @return  WOLFSSL_BIGNUM with value set to 2048-bit prime on success.
7140
 */
7141
WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn)
7142
{
7143
#if WOLFSSL_MAX_BN_BITS >= 2048
7144
    static const char prm[] = {
7145
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7146
        "C4C6628B80DC1CD129024E088A67CC74"
7147
        "020BBEA63B139B22514A08798E3404DD"
7148
        "EF9519B3CD3A431B302B0A6DF25F1437"
7149
        "4FE1356D6D51C245E485B576625E7EC6"
7150
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7151
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7152
        "49286651ECE45B3DC2007CB8A163BF05"
7153
        "98DA48361C55D39A69163FA8FD24CF5F"
7154
        "83655D23DCA3AD961C62F356208552BB"
7155
        "9ED529077096966D670C354E4ABC9804"
7156
        "F1746C08CA18217C32905E462E36CE3B"
7157
        "E39E772C180E86039B2783A2EC07A28F"
7158
        "B5C55DF06F4C52C9DE2BCBF695581718"
7159
        "3995497CEA956AE515D2261898FA0510"
7160
        "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
7161
    };
7162
7163
    WOLFSSL_ENTER("wolfSSL_DH_2048_prime");
7164
7165
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7166
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7167
        WOLFSSL_ERROR_MSG("Error converting DH 2048 prime to big number");
7168
        bn = NULL;
7169
    }
7170
7171
    return bn;
7172
#else
7173
    (void)bn;
7174
    return NULL;
7175
#endif
7176
}
7177
7178
/* Returns a big number with the 3072-bit prime from RFC 3526.
7179
 *
7180
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7181
 *                      If NULL then a new BN is created, set and returned.
7182
 *
7183
 * @return  NULL on failure.
7184
 * @return  WOLFSSL_BIGNUM with value set to 3072-bit prime on success.
7185
 */
7186
WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn)
7187
{
7188
#if WOLFSSL_MAX_BN_BITS >= 3072
7189
    static const char prm[] = {
7190
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7191
        "C4C6628B80DC1CD129024E088A67CC74"
7192
        "020BBEA63B139B22514A08798E3404DD"
7193
        "EF9519B3CD3A431B302B0A6DF25F1437"
7194
        "4FE1356D6D51C245E485B576625E7EC6"
7195
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7196
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7197
        "49286651ECE45B3DC2007CB8A163BF05"
7198
        "98DA48361C55D39A69163FA8FD24CF5F"
7199
        "83655D23DCA3AD961C62F356208552BB"
7200
        "9ED529077096966D670C354E4ABC9804"
7201
        "F1746C08CA18217C32905E462E36CE3B"
7202
        "E39E772C180E86039B2783A2EC07A28F"
7203
        "B5C55DF06F4C52C9DE2BCBF695581718"
7204
        "3995497CEA956AE515D2261898FA0510"
7205
        "15728E5A8AAAC42DAD33170D04507A33"
7206
        "A85521ABDF1CBA64ECFB850458DBEF0A"
7207
        "8AEA71575D060C7DB3970F85A6E1E4C7"
7208
        "ABF5AE8CDB0933D71E8C94E04A25619D"
7209
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
7210
        "D87602733EC86A64521F2B18177B200C"
7211
        "BBE117577A615D6C770988C0BAD946E2"
7212
        "08E24FA074E5AB3143DB5BFCE0FD108E"
7213
        "4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
7214
    };
7215
7216
    WOLFSSL_ENTER("wolfSSL_DH_3072_prime");
7217
7218
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7219
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7220
        WOLFSSL_ERROR_MSG("Error converting DH 3072 prime to big number");
7221
        bn = NULL;
7222
    }
7223
7224
    return bn;
7225
#else
7226
    (void)bn;
7227
    return NULL;
7228
#endif
7229
}
7230
7231
/* Returns a big number with the 4096-bit prime from RFC 3526.
7232
 *
7233
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7234
 *                      If NULL then a new BN is created, set and returned.
7235
 *
7236
 * @return  NULL on failure.
7237
 * @return  WOLFSSL_BIGNUM with value set to 4096-bit prime on success.
7238
 */
7239
WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn)
7240
{
7241
#if WOLFSSL_MAX_BN_BITS >= 4096
7242
    static const char prm[] = {
7243
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7244
        "C4C6628B80DC1CD129024E088A67CC74"
7245
        "020BBEA63B139B22514A08798E3404DD"
7246
        "EF9519B3CD3A431B302B0A6DF25F1437"
7247
        "4FE1356D6D51C245E485B576625E7EC6"
7248
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7249
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7250
        "49286651ECE45B3DC2007CB8A163BF05"
7251
        "98DA48361C55D39A69163FA8FD24CF5F"
7252
        "83655D23DCA3AD961C62F356208552BB"
7253
        "9ED529077096966D670C354E4ABC9804"
7254
        "F1746C08CA18217C32905E462E36CE3B"
7255
        "E39E772C180E86039B2783A2EC07A28F"
7256
        "B5C55DF06F4C52C9DE2BCBF695581718"
7257
        "3995497CEA956AE515D2261898FA0510"
7258
        "15728E5A8AAAC42DAD33170D04507A33"
7259
        "A85521ABDF1CBA64ECFB850458DBEF0A"
7260
        "8AEA71575D060C7DB3970F85A6E1E4C7"
7261
        "ABF5AE8CDB0933D71E8C94E04A25619D"
7262
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
7263
        "D87602733EC86A64521F2B18177B200C"
7264
        "BBE117577A615D6C770988C0BAD946E2"
7265
        "08E24FA074E5AB3143DB5BFCE0FD108E"
7266
        "4B82D120A92108011A723C12A787E6D7"
7267
        "88719A10BDBA5B2699C327186AF4E23C"
7268
        "1A946834B6150BDA2583E9CA2AD44CE8"
7269
        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
7270
        "287C59474E6BC05D99B2964FA090C3A2"
7271
        "233BA186515BE7ED1F612970CEE2D7AF"
7272
        "B81BDD762170481CD0069127D5B05AA9"
7273
        "93B4EA988D8FDDC186FFB7DC90A6C08F"
7274
        "4DF435C934063199FFFFFFFFFFFFFFFF"
7275
    };
7276
7277
    WOLFSSL_ENTER("wolfSSL_DH_4096_prime");
7278
7279
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7280
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7281
        WOLFSSL_ERROR_MSG("Error converting DH 4096 prime to big number");
7282
        bn = NULL;
7283
    }
7284
7285
    return bn;
7286
#else
7287
    (void)bn;
7288
    return NULL;
7289
#endif
7290
}
7291
7292
/* Returns a big number with the 6144-bit prime from RFC 3526.
7293
 *
7294
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7295
 *                      If NULL then a new BN is created, set and returned.
7296
 *
7297
 * @return  NULL on failure.
7298
 * @return  WOLFSSL_BIGNUM with value set to 6144-bit prime on success.
7299
 */
7300
WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn)
7301
{
7302
#if WOLFSSL_MAX_BN_BITS >= 6144
7303
    static const char prm[] = {
7304
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7305
        "C4C6628B80DC1CD129024E088A67CC74"
7306
        "020BBEA63B139B22514A08798E3404DD"
7307
        "EF9519B3CD3A431B302B0A6DF25F1437"
7308
        "4FE1356D6D51C245E485B576625E7EC6"
7309
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7310
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7311
        "49286651ECE45B3DC2007CB8A163BF05"
7312
        "98DA48361C55D39A69163FA8FD24CF5F"
7313
        "83655D23DCA3AD961C62F356208552BB"
7314
        "9ED529077096966D670C354E4ABC9804"
7315
        "F1746C08CA18217C32905E462E36CE3B"
7316
        "E39E772C180E86039B2783A2EC07A28F"
7317
        "B5C55DF06F4C52C9DE2BCBF695581718"
7318
        "3995497CEA956AE515D2261898FA0510"
7319
        "15728E5A8AAAC42DAD33170D04507A33"
7320
        "A85521ABDF1CBA64ECFB850458DBEF0A"
7321
        "8AEA71575D060C7DB3970F85A6E1E4C7"
7322
        "ABF5AE8CDB0933D71E8C94E04A25619D"
7323
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
7324
        "D87602733EC86A64521F2B18177B200C"
7325
        "BBE117577A615D6C770988C0BAD946E2"
7326
        "08E24FA074E5AB3143DB5BFCE0FD108E"
7327
        "4B82D120A92108011A723C12A787E6D7"
7328
        "88719A10BDBA5B2699C327186AF4E23C"
7329
        "1A946834B6150BDA2583E9CA2AD44CE8"
7330
        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
7331
        "287C59474E6BC05D99B2964FA090C3A2"
7332
        "233BA186515BE7ED1F612970CEE2D7AF"
7333
        "B81BDD762170481CD0069127D5B05AA9"
7334
        "93B4EA988D8FDDC186FFB7DC90A6C08F"
7335
        "4DF435C93402849236C3FAB4D27C7026"
7336
        "C1D4DCB2602646DEC9751E763DBA37BD"
7337
        "F8FF9406AD9E530EE5DB382F413001AE"
7338
        "B06A53ED9027D831179727B0865A8918"
7339
        "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
7340
        "DB7F1447E6CC254B332051512BD7AF42"
7341
        "6FB8F401378CD2BF5983CA01C64B92EC"
7342
        "F032EA15D1721D03F482D7CE6E74FEF6"
7343
        "D55E702F46980C82B5A84031900B1C9E"
7344
        "59E7C97FBEC7E8F323A97A7E36CC88BE"
7345
        "0F1D45B7FF585AC54BD407B22B4154AA"
7346
        "CC8F6D7EBF48E1D814CC5ED20F8037E0"
7347
        "A79715EEF29BE32806A1D58BB7C5DA76"
7348
        "F550AA3D8A1FBFF0EB19CCB1A313D55C"
7349
        "DA56C9EC2EF29632387FE8D76E3C0468"
7350
        "043E8F663F4860EE12BF2D5B0B7474D6"
7351
        "E694F91E6DCC4024FFFFFFFFFFFFFFFF"
7352
    };
7353
7354
    WOLFSSL_ENTER("wolfSSL_DH_6144_prime");
7355
7356
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7357
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7358
        WOLFSSL_ERROR_MSG("Error converting DH 6144 prime to big number");
7359
        bn = NULL;
7360
    }
7361
7362
    return bn;
7363
#else
7364
    (void)bn;
7365
    return NULL;
7366
#endif
7367
}
7368
7369
7370
/* Returns a big number with the 8192-bit prime from RFC 3526.
7371
 *
7372
 * @param [in, out] bn  If not NULL then this BN is set and returned.
7373
 *                      If NULL then a new BN is created, set and returned.
7374
 *
7375
 * @return  NULL on failure.
7376
 * @return  WOLFSSL_BIGNUM with value set to 8192-bit prime on success.
7377
 */
7378
WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
7379
{
7380
#if WOLFSSL_MAX_BN_BITS >= 8192
7381
    static const char prm[] = {
7382
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
7383
        "C4C6628B80DC1CD129024E088A67CC74"
7384
        "020BBEA63B139B22514A08798E3404DD"
7385
        "EF9519B3CD3A431B302B0A6DF25F1437"
7386
        "4FE1356D6D51C245E485B576625E7EC6"
7387
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
7388
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
7389
        "49286651ECE45B3DC2007CB8A163BF05"
7390
        "98DA48361C55D39A69163FA8FD24CF5F"
7391
        "83655D23DCA3AD961C62F356208552BB"
7392
        "9ED529077096966D670C354E4ABC9804"
7393
        "F1746C08CA18217C32905E462E36CE3B"
7394
        "E39E772C180E86039B2783A2EC07A28F"
7395
        "B5C55DF06F4C52C9DE2BCBF695581718"
7396
        "3995497CEA956AE515D2261898FA0510"
7397
        "15728E5A8AAAC42DAD33170D04507A33"
7398
        "A85521ABDF1CBA64ECFB850458DBEF0A"
7399
        "8AEA71575D060C7DB3970F85A6E1E4C7"
7400
        "ABF5AE8CDB0933D71E8C94E04A25619D"
7401
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
7402
        "D87602733EC86A64521F2B18177B200C"
7403
        "BBE117577A615D6C770988C0BAD946E2"
7404
        "08E24FA074E5AB3143DB5BFCE0FD108E"
7405
        "4B82D120A92108011A723C12A787E6D7"
7406
        "88719A10BDBA5B2699C327186AF4E23C"
7407
        "1A946834B6150BDA2583E9CA2AD44CE8"
7408
        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
7409
        "287C59474E6BC05D99B2964FA090C3A2"
7410
        "233BA186515BE7ED1F612970CEE2D7AF"
7411
        "B81BDD762170481CD0069127D5B05AA9"
7412
        "93B4EA988D8FDDC186FFB7DC90A6C08F"
7413
        "4DF435C93402849236C3FAB4D27C7026"
7414
        "C1D4DCB2602646DEC9751E763DBA37BD"
7415
        "F8FF9406AD9E530EE5DB382F413001AE"
7416
        "B06A53ED9027D831179727B0865A8918"
7417
        "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
7418
        "DB7F1447E6CC254B332051512BD7AF42"
7419
        "6FB8F401378CD2BF5983CA01C64B92EC"
7420
        "F032EA15D1721D03F482D7CE6E74FEF6"
7421
        "D55E702F46980C82B5A84031900B1C9E"
7422
        "59E7C97FBEC7E8F323A97A7E36CC88BE"
7423
        "0F1D45B7FF585AC54BD407B22B4154AA"
7424
        "CC8F6D7EBF48E1D814CC5ED20F8037E0"
7425
        "A79715EEF29BE32806A1D58BB7C5DA76"
7426
        "F550AA3D8A1FBFF0EB19CCB1A313D55C"
7427
        "DA56C9EC2EF29632387FE8D76E3C0468"
7428
        "043E8F663F4860EE12BF2D5B0B7474D6"
7429
        "E694F91E6DBE115974A3926F12FEE5E4"
7430
        "38777CB6A932DF8CD8BEC4D073B931BA"
7431
        "3BC832B68D9DD300741FA7BF8AFC47ED"
7432
        "2576F6936BA424663AAB639C5AE4F568"
7433
        "3423B4742BF1C978238F16CBE39D652D"
7434
        "E3FDB8BEFC848AD922222E04A4037C07"
7435
        "13EB57A81A23F0C73473FC646CEA306B"
7436
        "4BCBC8862F8385DDFA9D4B7FA2C087E8"
7437
        "79683303ED5BDD3A062B3CF5B3A278A6"
7438
        "6D2A13F83F44F82DDF310EE074AB6A36"
7439
        "4597E899A0255DC164F31CC50846851D"
7440
        "F9AB48195DED7EA1B1D510BD7EE74D73"
7441
        "FAF36BC31ECFA268359046F4EB879F92"
7442
        "4009438B481C6CD7889A002ED5EE382B"
7443
        "C9190DA6FC026E479558E4475677E9AA"
7444
        "9E3050E2765694DFC81F56E880B96E71"
7445
        "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
7446
    };
7447
7448
    WOLFSSL_ENTER("wolfSSL_DH_8192_prime");
7449
7450
    /* Set prime into BN. Creates a new BN when bn is NULL. */
7451
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
7452
        WOLFSSL_ERROR_MSG("Error converting DH 8192 prime to big number");
7453
        bn = NULL;
7454
    }
7455
7456
    return bn;
7457
#else
7458
    (void)bn;
7459
    return NULL;
7460
#endif
7461
}
7462
7463
/*
7464
 * DH to/from bin APIs
7465
 */
7466
7467
#ifndef NO_CERTS
7468
7469
/* Load the DER encoded DH parameters into DH key.
7470
 *
7471
 * @param [in, out] dh      DH key to load parameters into.
7472
 * @param [in]      der     Buffer holding DER encoded parameters data.
7473
 * @param [in, out] idx     On in, index at which DH key DER data starts.
7474
 *                          On out, index after DH key DER data.
7475
 * @param [in]      derSz   Size of DER buffer in bytes.
7476
 *
7477
 * @return  0 on success.
7478
 * @return  1 when decoding DER or setting the external key fails.
7479
 */
7480
static int wolfssl_dh_load_params(WOLFSSL_DH* dh, const unsigned char* der,
7481
    word32* idx, word32 derSz)
7482
{
7483
    int err = 0;
7484
7485
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
7486
    int ret;
7487
7488
    /* Decode DH parameters/key from DER. */
7489
    ret = wc_DhKeyDecode(der, idx, (DhKey*)dh->internal, derSz);
7490
    if (ret != 0) {
7491
        WOLFSSL_ERROR_MSG("DhKeyDecode() failed");
7492
        err = 1;
7493
    }
7494
    if (!err) {
7495
        /* wolfSSL DH key set. */
7496
        dh->inSet = 1;
7497
7498
        /* Set the external DH key based on wolfSSL DH key. */
7499
        if (SetDhExternal(dh) != 1) {
7500
            WOLFSSL_ERROR_MSG("SetDhExternal failed");
7501
            err = 1;
7502
        }
7503
    }
7504
#else
7505
    byte* p;
7506
    byte* g;
7507
    word32 pSz = MAX_DH_SIZE;
7508
    word32 gSz = MAX_DH_SIZE;
7509
7510
    /* Only DH parameters supported. */
7511
    /* Load external and set internal. */
7512
    p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
7513
    g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
7514
    if ((p == NULL) || (g == NULL)) {
7515
        err = 1;
7516
    }
7517
    /* Extract the p and g as data from the DER encoded DH parameters. */
7518
    if ((!err) && (wc_DhParamsLoad(der + *idx, derSz - *idx, p, &pSz, g,
7519
            &gSz) < 0)) {
7520
        err = 1;
7521
    }
7522
    if (!err) {
7523
        /* Put p and g in as big numbers - free existing BNs. */
7524
        if (dh->p != NULL) {
7525
            wolfSSL_BN_free(dh->p);
7526
            dh->p = NULL;
7527
        }
7528
        if (dh->g != NULL) {
7529
            wolfSSL_BN_free(dh->g);
7530
            dh->g = NULL;
7531
        }
7532
        dh->p = wolfSSL_BN_bin2bn(p, (int)pSz, NULL);
7533
        dh->g = wolfSSL_BN_bin2bn(g, (int)gSz, NULL);
7534
        if (dh->p == NULL || dh->g == NULL) {
7535
            err = 1;
7536
        }
7537
        else {
7538
            /* External DH key parameters were set. */
7539
            dh->exSet = 1;
7540
        }
7541
    }
7542
7543
    /* Set internal as the outside has been updated. */
7544
    if ((!err) && (SetDhInternal(dh) != 1)) {
7545
        WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
7546
        err = 1;
7547
    }
7548
7549
    if (!err) {
7550
        *idx += wolfssl_der_length(der + *idx, derSz - *idx);
7551
    }
7552
7553
    XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
7554
    XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
7555
#endif
7556
7557
    return err;
7558
}
7559
7560
#ifdef OPENSSL_ALL
7561
7562
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
7563
/* Convert DER encoded DH parameters to a WOLFSSL_DH structure.
7564
 *
7565
 * @param [out]     dh      DH key to put parameters into. May be NULL.
7566
 * @param [in, out] pp      Pointer to DER encoded DH parameters.
7567
 *                          Value updated to end of data when dh is not NULL.
7568
 * @param [in]      length  Length of data available in bytes.
7569
 *
7570
 * @return  DH key on success.
7571
 * @return  NULL on failure.
7572
 */
7573
WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH** dh, const unsigned char** pp,
7574
    long length)
7575
{
7576
    WOLFSSL_DH *newDh = NULL;
7577
    word32 idx = 0;
7578
    int err = 0;
7579
7580
    WOLFSSL_ENTER("wolfSSL_d2i_DHparams");
7581
7582
    /* Validate parameters. */
7583
    if ((pp == NULL) || (length <= 0)) {
7584
        WOLFSSL_ERROR_MSG("bad argument");
7585
        err = 1;
7586
    }
7587
7588
    /* Create new DH key to return. */
7589
    if ((!err) && ((newDh = wolfSSL_DH_new()) == NULL)) {
7590
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed");
7591
        err = 1;
7592
    }
7593
    if ((!err) && (wolfssl_dh_load_params(newDh, *pp, &idx,
7594
            (word32)length) != 0)) {
7595
        WOLFSSL_ERROR_MSG("Loading DH parameters failed");
7596
        err = 1;
7597
    }
7598
7599
    if ((!err) && (dh != NULL)) {
7600
        /* Return through parameter too. */
7601
        *dh = newDh;
7602
        /* Move buffer on by the used amount. */
7603
        *pp += idx;
7604
    }
7605
7606
    if (err && (newDh != NULL)) {
7607
        /* Dispose of any created DH key. */
7608
        wolfSSL_DH_free(newDh);
7609
        newDh = NULL;
7610
    }
7611
    return newDh;
7612
}
7613
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
7614
7615
/* Converts internal WOLFSSL_DH structure to DER encoded DH parameters.
7616
 *
7617
 * @params [in]      dh   DH key with parameters to encode.
7618
 * @params [in, out] out  Pointer to buffer to encode into.
7619
 *                        When NULL or pointer to NULL, only length returned.
7620
 * @return  0 on error.
7621
 * @return  Size of DER encoding in bytes on success.
7622
 */
7623
int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out)
7624
{
7625
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GT(5,0)) && defined(WOLFSSL_DH_EXTRA)
7626
    /* Set length to an arbitrarily large value for wc_DhParamsToDer(). */
7627
    word32 len = (word32)-1;
7628
    int err = 0;
7629
7630
    /* Validate parameters. */
7631
    if (dh == NULL) {
7632
        WOLFSSL_ERROR_MSG("Bad parameters");
7633
        err = 1;
7634
    }
7635
7636
    /* Push external DH data into internal DH key if not set. */
7637
    if ((!err) && (!dh->inSet) && (SetDhInternal((WOLFSSL_DH*)dh) != 1)) {
7638
        WOLFSSL_ERROR_MSG("Bad DH set internal");
7639
        err = 1;
7640
    }
7641
    if (!err) {
7642
        int ret;
7643
        unsigned char* der = NULL;
7644
7645
        /* Use *out when available otherwise NULL. */
7646
        if (out != NULL) {
7647
            der = *out;
7648
        }
7649
        /* Get length and/or encode. */
7650
        ret = wc_DhParamsToDer((DhKey*)dh->internal, der, &len);
7651
        /* Length of encoded data is returned on success. */
7652
        if (ret > 0) {
7653
            *out += len;
7654
        }
7655
        /* An error occurred unless only length returned. */
7656
        else if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
7657
            err = 1;
7658
        }
7659
    }
7660
7661
    /* Set return to 0 on error. */
7662
    if (err) {
7663
        len = 0;
7664
    }
7665
    return (int)len;
7666
#else
7667
    word32 len;
7668
    int ret = 0;
7669
    int pSz;
7670
    int gSz;
7671
7672
    WOLFSSL_ENTER("wolfSSL_i2d_DHparams");
7673
7674
    /* Validate parameters. */
7675
    if (dh == NULL) {
7676
        WOLFSSL_ERROR_MSG("Bad parameters");
7677
        len = 0;
7678
    }
7679
    else {
7680
        /* SEQ <len>
7681
         *   INT <len> [0x00] <prime>
7682
         *   INT <len> [0x00] <generator>
7683
         * Integers have 0x00 prepended if the top bit of positive number is
7684
         * set.
7685
         */
7686
        /* Get total length of prime including any prepended zeros. */
7687
        pSz = mp_unsigned_bin_size((mp_int*)dh->p->internal) +
7688
              mp_leading_bit((mp_int*)dh->p->internal);
7689
        /* Get total length of generator including any prepended zeros. */
7690
        gSz = mp_unsigned_bin_size((mp_int*)dh->g->internal) +
7691
              mp_leading_bit((mp_int*)dh->g->internal);
7692
        /* Calculate length of data in sequence. */
7693
        len = 1 + ASN_LEN_SIZE(pSz) + pSz +
7694
              1 + ASN_LEN_SIZE(gSz) + gSz;
7695
        /* Add in the length of the SEQUENCE. */
7696
        len += 1 + ASN_LEN_SIZE(len);
7697
7698
        if ((out != NULL) && (*out != NULL)) {
7699
            /* Encode parameters. */
7700
            ret = StoreDHparams(*out, &len, (mp_int*)dh->p->internal,
7701
                (mp_int*)dh->g->internal);
7702
            if (ret != MP_OKAY) {
7703
                WOLFSSL_ERROR_MSG("StoreDHparams error");
7704
                len = 0;
7705
            }
7706
            else {
7707
                /* Move pointer on if encoded. */
7708
                *out += len;
7709
            }
7710
        }
7711
    }
7712
7713
    return (int)len;
7714
#endif
7715
}
7716
7717
#endif /* OPENSSL_ALL */
7718
7719
#endif /* !NO_CERTS */
7720
7721
#endif /* OPENSSL_EXTRA */
7722
7723
#if defined(OPENSSL_EXTRA) ||  \
7724
 ((!defined(NO_BIO) || !defined(NO_FILESYSTEM)) && \
7725
  defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) || \
7726
  defined(WOLFSSL_MYSQL_COMPATIBLE))
7727
7728
/* Load the DER encoded DH parameters into DH key.
7729
 *
7730
 * @param [in, out] dh      DH key to load parameters into.
7731
 * @param [in]      derBuf  Buffer holding DER encoded parameters data.
7732
 * @param [in]      derSz   Size of DER data in buffer in bytes.
7733
 *
7734
 * @return  1 on success.
7735
 * @return  -1 when DH or derBuf is NULL,
7736
 *                  internal DH key in DH is NULL,
7737
 *                  derSz is 0 or less,
7738
 *                  error decoding DER data or
7739
 *                  setting external parameter values fails.
7740
 */
7741
int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
7742
{
7743
    int    ret = 1;
7744
    word32 idx = 0;
7745
7746
    /* Validate parameters. */
7747
    if ((dh == NULL) || (dh->internal == NULL) || (derBuf == NULL) ||
7748
            (derSz <= 0)) {
7749
        WOLFSSL_ERROR_MSG("Bad function arguments");
7750
        ret = WOLFSSL_FATAL_ERROR;
7751
    }
7752
7753
    if ((ret == 1) && (wolfssl_dh_load_params(dh, derBuf, &idx,
7754
            (word32)derSz) != 0)) {
7755
        WOLFSSL_ERROR_MSG("DH key decode failed");
7756
        ret = WOLFSSL_FATAL_ERROR;
7757
    }
7758
7759
    return ret;
7760
}
7761
7762
#endif
7763
7764
/*
7765
 * DH PEM APIs
7766
 */
7767
7768
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
7769
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
7770
7771
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
7772
/* Create a DH key by reading the PEM encoded data from the BIO.
7773
 *
7774
 * @param [in]      bio         BIO object to read from.
7775
 * @param [in, out] dh          DH key to use. May be NULL.
7776
 * @param [in]      pem         PEM data to decode.
7777
 * @param [in]      pemSz       Size of PEM data in bytes.
7778
 * @param [in]      memAlloced  Indicates that pem was allocated and is to be
7779
 *                              freed after use.
7780
 * @return  DH key on success.
7781
 * @return  NULL on failure.
7782
 */
7783
static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **dh,
7784
    unsigned char* pem, int pemSz, int memAlloced)
7785
{
7786
    WOLFSSL_DH* localDh = NULL;
7787
    DerBuffer *der = NULL;
7788
    int err = 0;
7789
7790
    /* Convert PEM to DER assuming DH Parameter format. */
7791
    if ((!err) && (PemToDer(pem, pemSz, DH_PARAM_TYPE, &der, NULL, NULL,
7792
            NULL) < 0)) {
7793
        /* Convert PEM to DER assuming X9.42 DH Parameter format. */
7794
        if (PemToDer(pem, pemSz, X942_PARAM_TYPE, &der, NULL, NULL, NULL)
7795
                != 0) {
7796
            err = 1;
7797
        }
7798
        /* If Success on X9.42 DH format, clear error from failed DH format */
7799
        else {
7800
            unsigned long error;
7801
            CLEAR_ASN_NO_PEM_HEADER_ERROR(error);
7802
        }
7803
    }
7804
    if (memAlloced) {
7805
        /* PEM data no longer needed.  */
7806
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7807
    }
7808
7809
    if (!err) {
7810
        /* Use the DH key passed in or allocate a new one. */
7811
        if (dh != NULL) {
7812
            localDh = *dh;
7813
        }
7814
        if (localDh == NULL) {
7815
            localDh = wolfSSL_DH_new();
7816
            if (localDh == NULL) {
7817
                err = 1;
7818
            }
7819
        }
7820
    }
7821
    /* Load the DER encoded DH parameters from buffer into a DH key. */
7822
    if ((!err) && (wolfSSL_DH_LoadDer(localDh, der->buffer, (int)der->length)
7823
            != 1)) {
7824
        /* Free an allocated DH key. */
7825
        if ((dh == NULL) || (localDh != *dh)) {
7826
            wolfSSL_DH_free(localDh);
7827
        }
7828
        localDh = NULL;
7829
        err = 1;
7830
    }
7831
    /* Return the DH key on success. */
7832
    if ((!err) && (dh != NULL)) {
7833
        *dh = localDh;
7834
    }
7835
7836
    /* Dispose of DER data. */
7837
    if (der != NULL) {
7838
        FreeDer(&der);
7839
    }
7840
    return localDh;
7841
}
7842
#endif /* !NO_BIO || !NO_FILESYSTEM */
7843
7844
#ifndef NO_BIO
7845
/* Create a DH key by reading the PEM encoded data from the BIO.
7846
 *
7847
 * DH parameters are public data and are not expected to be encrypted.
7848
 *
7849
 * @param [in]      bio   BIO object to read from.
7850
 * @param [in, out] dh    DH key to   When pointer to
7851
 *                        NULL, a new DH key is created.
7852
 * @param [in]      cb    Password callback when PEM encrypted. Not used.
7853
 * @param [in]      pass  NUL terminated string for passphrase when PEM
7854
 *                        encrypted. Not used.
7855
 * @return  DH key on success.
7856
 * @return  NULL on failure.
7857
 */
7858
WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **dh,
7859
    wc_pem_password_cb *cb, void *pass)
7860
{
7861
    WOLFSSL_DH* localDh = NULL;
7862
    int err = 0;
7863
    unsigned char* mem = NULL;
7864
    int size = 0;
7865
    int memAlloced = 0;
7866
7867
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
7868
7869
    (void)cb;
7870
    (void)pass;
7871
7872
    /* Validate parameters. */
7873
    if (bio == NULL) {
7874
        WOLFSSL_ERROR_MSG("Bad Function Argument bio is NULL");
7875
        err = 1;
7876
    }
7877
7878
    /* Get buffer of data from BIO or read data from the BIO into a new buffer.
7879
     */
7880
    if ((!err) && (wolfssl_read_bio(bio, (char**)&mem, &size, &memAlloced)
7881
            != 0)) {
7882
        err = 1;
7883
    }
7884
    if (!err) {
7885
        /* Create a DH key from the PEM - try two different headers. */
7886
        localDh = wolfssl_dhparams_read_pem(dh, mem, size, memAlloced);
7887
    }
7888
7889
    return localDh;
7890
}
7891
7892
#endif /* !NO_BIO */
7893
7894
#ifndef NO_FILESYSTEM
7895
/* Read DH parameters from a file pointer into DH key.
7896
 *
7897
 * DH parameters are public data and are not expected to be encrypted.
7898
 *
7899
 * @param [in]      fp    File pointer to read DH parameter file from.
7900
 * @param [in, out] dh    DH key with parameters if not NULL. When pointer to
7901
 *                        NULL, a new DH key is created.
7902
 * @param [in]      cb    Password callback when PEM encrypted. Not used.
7903
 * @param [in]      pass  NUL terminated string for passphrase when PEM
7904
 *                        encrypted. Not used.
7905
 *
7906
 * @return  NULL on failure.
7907
 * @return  DH key with parameters set on success.
7908
 */
7909
WOLFSSL_DH* wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH** dh,
7910
    wc_pem_password_cb* cb, void* pass)
7911
{
7912
    WOLFSSL_DH* localDh = NULL;
7913
    int err = 0;
7914
    unsigned char* mem = NULL;
7915
    int size = 0;
7916
7917
    (void)cb;
7918
    (void)pass;
7919
7920
    /* Read data from file pointer. */
7921
    if (wolfssl_read_file(fp, (char**)&mem, &size) != 0) {
7922
        err = 1;
7923
    }
7924
    if (!err) {
7925
        localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1);
7926
    }
7927
7928
    return localDh;
7929
}
7930
#endif /* !NO_FILESYSTEM */
7931
7932
#if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
7933
/* Encoded parameter data in DH key as DER.
7934
 *
7935
 * @param [in, out] dh    DH key object to encode.
7936
 * @param [out]     out   Buffer containing DER encoding.
7937
 * @param [in]      heap  Heap hint.
7938
 * @return  <0 on error.
7939
 * @return  Length of DER encoded DH parameters in bytes.
7940
 */
7941
static int wolfssl_dhparams_to_der(WOLFSSL_DH* dh, unsigned char** out,
7942
    void* heap)
7943
{
7944
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
7945
    int err = 0;
7946
    byte* der = NULL;
7947
    word32 derSz = 0;
7948
    DhKey* key = NULL;
7949
7950
    (void)heap;
7951
7952
    /* Set internal parameters based on external parameters. */
7953
    if ((dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
7954
        WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
7955
        err = 1;
7956
    }
7957
    if (!err) {
7958
        /* Use wolfSSL API to get length of DER encode DH parameters. */
7959
        key = (DhKey*)dh->internal;
7960
        ret = wc_DhParamsToDer(key, NULL, &derSz);
7961
        if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
7962
            WOLFSSL_ERROR_MSG("Failed to get size of DH params");
7963
            err = 1;
7964
        }
7965
    }
7966
7967
    if (!err) {
7968
        /* Allocate memory for DER encoding. */
7969
        der = (byte*)XMALLOC(derSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
7970
        if (der == NULL) {
7971
            WOLFSSL_LEAVE("wolfssl_dhparams_to_der", MEMORY_E);
7972
            err = 1;
7973
        }
7974
    }
7975
    if (!err) {
7976
        /* Encode DH parameters into DER buffer. */
7977
        ret = wc_DhParamsToDer(key, der, &derSz);
7978
        if (ret < 0) {
7979
            WOLFSSL_ERROR_MSG("Failed to export DH params");
7980
            err = 1;
7981
        }
7982
    }
7983
7984
    if (!err) {
7985
        *out = der;
7986
        der = NULL;
7987
    }
7988
    XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
7989
7990
    return ret;
7991
}
7992
7993
/* Writes the DH parameters in PEM format from "dh" out to the file pointer
7994
 * passed in.
7995
 *
7996
 * @param [in]  fp  File pointer to write to.
7997
 * @param [in]  dh  DH key to write.
7998
 * @return  1 on success.
7999
 * @return  0 on failure.
8000
 */
8001
int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
8002
{
8003
    int ret = 1;
8004
    int derSz = 0;
8005
    byte* derBuf = NULL;
8006
    void* heap = NULL;
8007
8008
    WOLFSSL_ENTER("wolfSSL_PEM_write_DHparams");
8009
8010
    /* Validate parameters. */
8011
    if ((fp == XBADFILE) || (dh == NULL)) {
8012
        WOLFSSL_ERROR_MSG("Bad Function Arguments");
8013
        ret = 0;
8014
    }
8015
8016
    if (ret == 1) {
8017
        DhKey* key = (DhKey*)dh->internal;
8018
        if (key)
8019
            heap = key->heap;
8020
        if ((derSz = wolfssl_dhparams_to_der(dh, &derBuf, heap)) < 0) {
8021
            WOLFSSL_ERROR_MSG("DER encoding failed");
8022
            ret = 0;
8023
        }
8024
        if (derBuf == NULL) {
8025
            WOLFSSL_ERROR_MSG("DER encoding failed to get buffer");
8026
            ret = 0;
8027
        }
8028
    }
8029
    if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
8030
            DH_PARAM_TYPE, NULL) != 1)) {
8031
        ret = 0;
8032
    }
8033
8034
    /* Dispose of DER buffer. */
8035
    XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
8036
8037
    WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
8038
8039
    return ret;
8040
}
8041
#endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */
8042
8043
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE ||
8044
        * OPENSSL_EXTRA */
8045
8046
/*
8047
 * DH get/set APIs
8048
 */
8049
8050
#ifdef OPENSSL_EXTRA
8051
8052
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) \
8053
    || defined(WOLFSSL_OPENSSH) || defined(OPENSSL_EXTRA)
8054
8055
/* Set the members of DhKey into WOLFSSL_DH
8056
 * Specify elements to set via the 2nd parameter
8057
 *
8058
 * @param [in, out] dh   DH key to synchronize.
8059
 * @param [in]      elm  Elements to synchronize.
8060
 * @return  1 on success.
8061
 * @return  -1 on failure.
8062
 */
8063
int SetDhExternal_ex(WOLFSSL_DH *dh, int elm)
8064
{
8065
    int ret = 1;
8066
    DhKey *key = NULL;
8067
8068
    WOLFSSL_ENTER("SetDhExternal_ex");
8069
8070
    /* Validate parameters. */
8071
    if ((dh == NULL) || (dh->internal == NULL)) {
8072
        WOLFSSL_ERROR_MSG("dh key NULL error");
8073
        ret = WOLFSSL_FATAL_ERROR;
8074
    }
8075
8076
    if (ret == 1) {
8077
        /* Get the wolfSSL DH key. */
8078
        key = (DhKey*)dh->internal;
8079
    }
8080
8081
    if ((ret == 1) && (elm & ELEMENT_P)) {
8082
        /* Set the prime. */
8083
        if (wolfssl_bn_set_value(&dh->p, &key->p) != 1) {
8084
            WOLFSSL_ERROR_MSG("dh param p error");
8085
            ret = WOLFSSL_FATAL_ERROR;
8086
        }
8087
    }
8088
    if ((ret == 1) && (elm & ELEMENT_G)) {
8089
        /* Set the generator. */
8090
        if (wolfssl_bn_set_value(&dh->g, &key->g) != 1) {
8091
            WOLFSSL_ERROR_MSG("dh param g error");
8092
            ret = WOLFSSL_FATAL_ERROR;
8093
        }
8094
    }
8095
    if ((ret == 1) && (elm & ELEMENT_Q)) {
8096
        /* Set the order. */
8097
        if (wolfssl_bn_set_value(&dh->q, &key->q) != 1) {
8098
            WOLFSSL_ERROR_MSG("dh param q error");
8099
            ret = WOLFSSL_FATAL_ERROR;
8100
        }
8101
    }
8102
#ifdef WOLFSSL_DH_EXTRA
8103
    if ((ret == 1) && (elm & ELEMENT_PRV)) {
8104
        /* Set the private key. */
8105
        if (wolfssl_bn_set_value(&dh->priv_key, &key->priv) != 1) {
8106
            WOLFSSL_ERROR_MSG("No DH Private Key");
8107
            ret = WOLFSSL_FATAL_ERROR;
8108
        }
8109
    }
8110
    if ((ret == 1) && (elm & ELEMENT_PUB)) {
8111
        /* Set the public key. */
8112
        if (wolfssl_bn_set_value(&dh->pub_key, &key->pub) != 1) {
8113
            WOLFSSL_ERROR_MSG("No DH Public Key");
8114
            ret = WOLFSSL_FATAL_ERROR;
8115
        }
8116
    }
8117
#endif /* WOLFSSL_DH_EXTRA */
8118
8119
    if (ret == 1) {
8120
        /* On success record that the external values have been set. */
8121
        dh->exSet = 1;
8122
    }
8123
8124
    return ret;
8125
}
8126
/* Set the members of DhKey into WOLFSSL_DH
8127
 * DhKey was populated from wc_DhKeyDecode
8128
 * p, g, pub_key and priv_key are set.
8129
 *
8130
 * @param [in, out] dh   DH key to synchronize.
8131
 * @return  1 on success.
8132
 * @return  -1 on failure.
8133
 */
8134
int SetDhExternal(WOLFSSL_DH *dh)
8135
{
8136
    /* Assuming Q not required when using this API. */
8137
    int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV;
8138
    WOLFSSL_ENTER("SetDhExternal");
8139
    return SetDhExternal_ex(dh, elements);
8140
}
8141
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH || OPENSSL_EXTRA */
8142
8143
/* Set the internal/wolfSSL DH key with data from the external parts.
8144
 *
8145
 * @param [in, out] dh   DH key to synchronize.
8146
 * @return  1 on success.
8147
 * @return  -1 on failure.
8148
 */
8149
int SetDhInternal(WOLFSSL_DH* dh)
8150
{
8151
    int ret = 1;
8152
    DhKey *key = NULL;
8153
8154
    WOLFSSL_ENTER("SetDhInternal");
8155
8156
    /* Validate parameters. */
8157
    if ((dh == NULL) || (dh->p == NULL) || (dh->g == NULL)) {
8158
        WOLFSSL_ERROR_MSG("Bad function arguments");
8159
        ret = WOLFSSL_FATAL_ERROR;
8160
    }
8161
    if (ret == 1) {
8162
        /* Get the wolfSSL DH key. */
8163
        key = (DhKey*)dh->internal;
8164
8165
        /* Clear out key and initialize. */
8166
        wc_FreeDhKey(key);
8167
        if (wc_InitDhKey(key) != 0) {
8168
            ret = WOLFSSL_FATAL_ERROR;
8169
        }
8170
    }
8171
    if (ret == 1) {
8172
        /* Transfer prime. */
8173
        if (wolfssl_bn_get_value(dh->p, &key->p) != 1) {
8174
            ret = WOLFSSL_FATAL_ERROR;
8175
        }
8176
    }
8177
    if (ret == 1) {
8178
        /* Transfer generator. */
8179
        if (wolfssl_bn_get_value(dh->g, &key->g) != 1) {
8180
            ret = WOLFSSL_FATAL_ERROR;
8181
        }
8182
    }
8183
#ifdef HAVE_FFDHE_Q
8184
    /* Transfer order if available. */
8185
    if ((ret == 1) && (dh->q != NULL)) {
8186
        if (wolfssl_bn_get_value(dh->q, &key->q) != 1) {
8187
            ret = WOLFSSL_FATAL_ERROR;
8188
        }
8189
    }
8190
#endif
8191
#ifdef WOLFSSL_DH_EXTRA
8192
    /* Transfer private key if available. */
8193
    if ((ret == 1) && (dh->priv_key != NULL) &&
8194
            (!wolfSSL_BN_is_zero(dh->priv_key))) {
8195
        if (wolfssl_bn_get_value(dh->priv_key, &key->priv) != 1) {
8196
            ret = WOLFSSL_FATAL_ERROR;
8197
        }
8198
    }
8199
    /* Transfer public key if available. */
8200
    if ((ret == 1) && (dh->pub_key != NULL) &&
8201
            (!wolfSSL_BN_is_zero(dh->pub_key))) {
8202
        if (wolfssl_bn_get_value(dh->pub_key, &key->pub) != 1) {
8203
            ret = WOLFSSL_FATAL_ERROR;
8204
        }
8205
    }
8206
#endif /* WOLFSSL_DH_EXTRA */
8207
8208
    if (ret == 1) {
8209
        /* On success record that the internal values have been set. */
8210
        dh->inSet = 1;
8211
    }
8212
8213
    return ret;
8214
}
8215
8216
/* Get the size, in bytes, of the DH key.
8217
 *
8218
 * Return code compliant with OpenSSL.
8219
 *
8220
 * @param [in] dh  DH key.
8221
 * @return  -1 on error.
8222
 * @return  Size of DH key in bytes on success.
8223
 */
8224
int wolfSSL_DH_size(WOLFSSL_DH* dh)
8225
{
8226
    WOLFSSL_ENTER("wolfSSL_DH_size");
8227
8228
    if (dh == NULL)
8229
        return WOLFSSL_FATAL_ERROR;
8230
8231
    /* Validate parameter. */
8232
    /* Size of key is size of prime in bytes. */
8233
    return wolfSSL_BN_num_bytes(dh->p);
8234
}
8235
8236
/**
8237
 * Return parameters p, q and/or g of the DH key.
8238
 *
8239
 * @param [in]  dh  DH key to retrieve parameters from.
8240
 * @param [out] p   Pointer to return prime in. May be NULL.
8241
 * @param [out] q   Pointer to return order in. May be NULL.
8242
 * @param [out] g   Pointer to return generator in. May be NULL.
8243
 */
8244
void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
8245
    const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
8246
{
8247
    WOLFSSL_ENTER("wolfSSL_DH_get0_pqg");
8248
8249
    if (dh != NULL) {
8250
        /* Return prime if required. */
8251
        if (p != NULL) {
8252
            *p = dh->p;
8253
        }
8254
        /* Return order if required. */
8255
        if (q != NULL) {
8256
            *q = dh->q;
8257
        }
8258
        /* Return generator if required. */
8259
        if (g != NULL) {
8260
            *g = dh->g;
8261
        }
8262
    }
8263
}
8264
8265
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
8266
 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
8267
#if defined(OPENSSL_ALL) || \
8268
    defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
8269
/* Sets the parameters p, g and optionally q into the DH key.
8270
 *
8271
 * Ownership of p, q and g get taken over by "dh" on success and should be
8272
 * free'd with a call to wolfSSL_DH_free -- not individually.
8273
 *
8274
 * @param [in, out] dh   DH key to set.
8275
 * @param [in]      p    Prime value to set. May be NULL when value already
8276
 *                       present.
8277
 * @param [in]      q    Order value to set. May be NULL.
8278
 * @param [in]      g    Generator value to set. May be NULL when value already
8279
 *                       present.
8280
 * @return  1 on success.
8281
 * @return  0 on failure.
8282
 */
8283
int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
8284
    WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
8285
{
8286
    int ret = 1;
8287
8288
    WOLFSSL_ENTER("wolfSSL_DH_set0_pqg");
8289
8290
    /* Validate parameters - q is optional. */
8291
    if (dh == NULL) {
8292
        WOLFSSL_ERROR_MSG("Bad function arguments");
8293
        ret = 0;
8294
    }
8295
    /* p can be NULL if we already have one set. */
8296
    if ((ret == 1) && (p == NULL) && (dh->p == NULL)) {
8297
        WOLFSSL_ERROR_MSG("Bad function arguments");
8298
        ret = 0;
8299
    }
8300
    /* g can be NULL if we already have one set. */
8301
    if ((ret == 1) && (g == NULL) && (dh->g == NULL)) {
8302
        WOLFSSL_ERROR_MSG("Bad function arguments");
8303
        ret = 0;
8304
    }
8305
8306
    if (ret == 1) {
8307
        /* Invalidate internal key. */
8308
        dh->inSet = 0;
8309
8310
        /* Free external representation of parameters and set with those passed
8311
         * in. */
8312
        if (p != NULL) {
8313
            wolfSSL_BN_free(dh->p);
8314
            dh->p = p;
8315
        }
8316
        if (q != NULL) {
8317
            wolfSSL_BN_free(dh->q);
8318
            dh->q = q;
8319
        }
8320
        if (g != NULL) {
8321
            wolfSSL_BN_free(dh->g);
8322
            dh->g = g;
8323
        }
8324
        /* External DH key parameters were set. */
8325
        dh->exSet = 1;
8326
8327
        /* Set internal/wolfSSL DH key as well. */
8328
        if (SetDhInternal(dh) != 1) {
8329
            WOLFSSL_ERROR_MSG("Unable to set internal DH key");
8330
            /* Don't keep parameters on failure. */
8331
            dh->p = NULL;
8332
            dh->q = NULL;
8333
            dh->g = NULL;
8334
            /* Internal and external DH key not set. */
8335
            dh->inSet = 0;
8336
            dh->exSet = 0;
8337
            ret = 0;
8338
        }
8339
    }
8340
8341
    return ret;
8342
}
8343
8344
/* Set the length of the DH private key in bits.
8345
 *
8346
 * Length field is checked at generation.
8347
 *
8348
 * @param [in, out] dh   DH key to set.
8349
 * @param [in]      len  Length of DH private key in bytes.
8350
 * @return  0 on failure.
8351
 * @return  1 on success.
8352
 */
8353
int wolfSSL_DH_set_length(WOLFSSL_DH *dh, long len)
8354
{
8355
    int ret = 1;
8356
8357
    WOLFSSL_ENTER("wolfSSL_DH_set_length");
8358
8359
    /* Validate parameter. */
8360
    if (dh == NULL) {
8361
        WOLFSSL_ERROR_MSG("Bad function arguments");
8362
        ret = 0;
8363
    }
8364
    else {
8365
        /* Store length. */
8366
        dh->length = (int)len;
8367
    }
8368
8369
    return ret;
8370
}
8371
#endif /* OPENSSL_ALL || (v1.1.0 or later) */
8372
#endif
8373
8374
/* Get the public and private keys requested.
8375
 *
8376
 * @param [in]  dh         DH key to get keys from.
8377
 * @param [out] pub_key    Pointer to return public key in. May be NULL.
8378
 * @param [out] priv_key   Pointer to return private key in. May be NULL.
8379
 */
8380
void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **pub_key,
8381
    const WOLFSSL_BIGNUM **priv_key)
8382
{
8383
    WOLFSSL_ENTER("wolfSSL_DH_get0_key");
8384
8385
    /* Get only when valid DH passed in. */
8386
    if (dh != NULL) {
8387
        /* Return public key if required and available. */
8388
        if ((pub_key != NULL) && (dh->pub_key != NULL)) {
8389
            *pub_key = dh->pub_key;
8390
        }
8391
        /* Return private key if required and available. */
8392
        if ((priv_key != NULL) && (dh->priv_key != NULL)) {
8393
            *priv_key = dh->priv_key;
8394
        }
8395
    }
8396
}
8397
8398
/* Set the public and/or private key.
8399
 *
8400
 * @param [in, out] dh        DH key to have keys set into.
8401
 * @param [in]      pub_key   Public key to set. May be NULL.
8402
 * @param [in]      priv_key  Private key to set. May be NULL.
8403
 * @return  0 on failure.
8404
 * @return  1 on success.
8405
 */
8406
int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key,
8407
    WOLFSSL_BIGNUM *priv_key)
8408
{
8409
    int ret = 1;
8410
#ifdef WOLFSSL_DH_EXTRA
8411
    DhKey *key = NULL;
8412
#endif
8413
8414
    WOLFSSL_ENTER("wolfSSL_DH_set0_key");
8415
8416
    /* Validate parameters. */
8417
    if (dh == NULL) {
8418
        ret = 0;
8419
    }
8420
#ifdef WOLFSSL_DH_EXTRA
8421
    else {
8422
        key = (DhKey*)dh->internal;
8423
    }
8424
#endif
8425
8426
    /* Replace public key when one passed in. */
8427
    if ((ret == 1) && (pub_key != NULL)) {
8428
        wolfSSL_BN_free(dh->pub_key);
8429
        dh->pub_key = pub_key;
8430
    #ifdef WOLFSSL_DH_EXTRA
8431
        if (wolfssl_bn_get_value(dh->pub_key, &key->pub) != 1) {
8432
            ret = 0;
8433
        }
8434
    #endif
8435
    }
8436
8437
    /* Replace private key when one passed in. */
8438
    if ((ret == 1) && (priv_key != NULL)) {
8439
        wolfSSL_BN_clear_free(dh->priv_key);
8440
        dh->priv_key = priv_key;
8441
    #ifdef WOLFSSL_DH_EXTRA
8442
        if (wolfssl_bn_get_value(dh->priv_key, &key->priv) != 1) {
8443
            ret = 0;
8444
        }
8445
    #endif
8446
    }
8447
8448
    return ret;
8449
}
8450
8451
#endif /* OPENSSL_EXTRA */
8452
8453
/*
8454
 * DH check APIs
8455
 */
8456
8457
#ifdef OPENSSL_EXTRA
8458
8459
#ifndef NO_CERTS
8460
8461
#ifdef OPENSSL_ALL
8462
/* Check whether BN number is a prime.
8463
 *
8464
 * @param [in]  n        Number to check.
8465
 * @param [out] isPrime  MP_YES when prime and MP_NO when not.
8466
 * @return  1 on success.
8467
 * @return  0 on error.
8468
 */
8469
static int wolfssl_dh_check_prime(WOLFSSL_BIGNUM* n, int* isPrime)
8470
{
8471
    int ret = 1;
8472
#ifdef WOLFSSL_SMALL_STACK
8473
    WC_RNG* tmpRng = NULL;
8474
#else
8475
    WC_RNG  tmpRng[1];
8476
#endif
8477
    WC_RNG* rng;
8478
    int localRng;
8479
8480
    /* Make an RNG with tmpRng or get global. */
8481
    rng = wolfssl_make_rng(tmpRng, &localRng);
8482
    if (rng == NULL) {
8483
        ret = 0;
8484
    }
8485
    if (ret == 1) {
8486
        mp_int* prime = (mp_int*)n->internal;
8487
8488
        if (mp_prime_is_prime_ex(prime, 8, isPrime, rng) != 0) {
8489
            ret = 0;
8490
        }
8491
        /* Free local random number generator if created. */
8492
        if (localRng) {
8493
            wc_FreeRng(rng);
8494
        #ifdef WOLFSSL_SMALL_STACK
8495
            XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8496
        #endif
8497
        }
8498
    }
8499
8500
    return ret;
8501
}
8502
8503
/* Checks the Diffie-Hellman parameters.
8504
 *
8505
 * Checks that the generator and prime are available.
8506
 * Checks that the prime is prime.
8507
 * OpenSSL expects codes to be non-NULL.
8508
 *
8509
 * @param [in]  dh     DH key to check.
8510
 * @param [out] codes  Codes of checks that failed.
8511
 * @return  1 on success.
8512
 * @return  0 when DH is NULL, there were errors or failed to create a random
8513
 *          number generator.
8514
 */
8515
int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
8516
{
8517
    int ret = 1;
8518
    int errors = 0;
8519
8520
    WOLFSSL_ENTER("wolfSSL_DH_check");
8521
8522
    /* Validate parameters. */
8523
    if (dh == NULL) {
8524
        ret = 0;
8525
    }
8526
8527
    /* Check generator available. */
8528
    if ((ret == 1) && ((dh->g == NULL) || (dh->g->internal == NULL))) {
8529
        errors |= DH_NOT_SUITABLE_GENERATOR;
8530
    }
8531
8532
    if (ret == 1) {
8533
        /* Check prime available. */
8534
        if ((dh->p == NULL) || (dh->p->internal == NULL)) {
8535
            errors |= DH_CHECK_P_NOT_PRIME;
8536
        }
8537
        else {
8538
            /* Test if dh->p is prime. */
8539
            int isPrime = MP_NO;
8540
            ret = wolfssl_dh_check_prime(dh->p, &isPrime);
8541
            /* Set error code if parameter p is not prime. */
8542
            if ((ret == 1) && (isPrime != MP_YES)) {
8543
                errors |= DH_CHECK_P_NOT_PRIME;
8544
            }
8545
        }
8546
    }
8547
8548
    /* Return errors when user wants exact issues. */
8549
    if (codes != NULL) {
8550
        *codes = errors;
8551
    }
8552
    else if (errors) {
8553
        ret = 0;
8554
    }
8555
8556
    return ret;
8557
}
8558
8559
#endif /* OPENSSL_ALL */
8560
8561
#endif /* !NO_CERTS */
8562
8563
#endif /* OPENSSL_EXTRA */
8564
8565
/*
8566
 * DH generate APIs
8567
 */
8568
8569
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
8570
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
8571
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
8572
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
8573
8574
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST)
8575
/* Generate DH parameters.
8576
 *
8577
 * @param [in] prime_len  Length of prime in bits.
8578
 * @param [in] generator  Generator value to use.
8579
 * @param [in] callback   Called with progress information. Unused.
8580
 * @param [in] cb_arg     User callback argument. Unused.
8581
 * @return  NULL on failure.
8582
 * @return  DH key on success.
8583
 */
8584
WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
8585
                           void (*callback) (int, int, void *), void *cb_arg)
8586
{
8587
    WOLFSSL_DH* dh = NULL;
8588
8589
    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
8590
    /* Not supported by wolfSSl APIs. */
8591
    (void)callback;
8592
    (void)cb_arg;
8593
8594
    /* Create an empty DH key. */
8595
    if ((dh = wolfSSL_DH_new()) == NULL) {
8596
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new error");
8597
    }
8598
    /* Generate parameters into DH key. */
8599
    else if (wolfSSL_DH_generate_parameters_ex(dh, prime_len, generator, NULL)
8600
            != 1) {
8601
        WOLFSSL_ERROR_MSG("wolfSSL_DH_generate_parameters_ex error");
8602
        wolfSSL_DH_free(dh);
8603
        dh = NULL;
8604
    }
8605
8606
    return dh;
8607
}
8608
8609
/* Generate DH parameters.
8610
 *
8611
 * @param [in] dh         DH key to generate parameters into.
8612
 * @param [in] prime_len  Length of prime in bits.
8613
 * @param [in] generator  Generator value to use.
8614
 * @param [in] callback   Called with progress information. Unused.
8615
 * @param [in] cb_arg     User callback argument. Unused.
8616
 * @return  0 on failure.
8617
 * @return  1 on success.
8618
 */
8619
int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len,
8620
    int generator, void (*callback) (int, int, void *))
8621
{
8622
    int ret = 1;
8623
    DhKey* key = NULL;
8624
#ifdef WOLFSSL_SMALL_STACK
8625
    WC_RNG* tmpRng = NULL;
8626
#else
8627
    WC_RNG  tmpRng[1];
8628
#endif
8629
    WC_RNG* rng = NULL;
8630
    int localRng = 0;
8631
8632
    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
8633
    /* Not supported by wolfSSL APIs. */
8634
    (void)callback;
8635
    (void)generator;
8636
8637
    /* Validate parameters. */
8638
    if (dh == NULL) {
8639
        WOLFSSL_ERROR_MSG("Bad parameter");
8640
        ret = 0;
8641
    }
8642
8643
    if (ret == 1) {
8644
        /* Make an RNG with tmpRng or get global. */
8645
        rng = wolfssl_make_rng(tmpRng, &localRng);
8646
        if (rng == NULL) {
8647
            WOLFSSL_ERROR_MSG("No RNG to use");
8648
            ret = 0;
8649
        }
8650
    }
8651
8652
    if (ret == 1) {
8653
        /* Get internal/wolfSSL DH key. */
8654
        key = (DhKey*)dh->internal;
8655
8656
        /* Clear out data from internal DH key. */
8657
        wc_FreeDhKey(key);
8658
        /* Re-initialize internal DH key. */
8659
        if (wc_InitDhKey(key) != 0) {
8660
            ret = 0;
8661
        }
8662
    }
8663
    if (ret == 1) {
8664
        /* Generate parameters into internal DH key. */
8665
        if (wc_DhGenerateParams(rng, prime_len, key) != 0) {
8666
            WOLFSSL_ERROR_MSG("wc_DhGenerateParams error");
8667
            ret = 0;
8668
        }
8669
    }
8670
8671
    /* Free local random number generator if created. */
8672
    if (localRng) {
8673
        wc_FreeRng(rng);
8674
    #ifdef WOLFSSL_SMALL_STACK
8675
        XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
8676
    #endif
8677
    }
8678
8679
    if (ret == 1) {
8680
        /* Internal parameters set by generation. */
8681
        dh->inSet = 1;
8682
8683
        WOLFSSL_MSG("wolfSSL does not support using a custom generator.");
8684
8685
        /* Synchronize the external to the internal parameters. */
8686
        if (SetDhExternal(dh) != 1) {
8687
            WOLFSSL_ERROR_MSG("SetDhExternal error");
8688
            ret = 0;
8689
        }
8690
    }
8691
8692
    return ret;
8693
}
8694
#endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST */
8695
8696
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
8697
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
8698
        * HAVE_SBLIM_SFCB)) */
8699
8700
#ifdef OPENSSL_EXTRA
8701
8702
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
8703
 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
8704
/* Generate a public/private key pair base on parameters.
8705
 *
8706
 * @param [in, out] dh  DH key to generate keys into.
8707
 * @return  1 on success.
8708
 * @return  0 on error.
8709
 */
8710
int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
8711
{
8712
    int     ret    = 1;
8713
    word32  pubSz  = 0;
8714
    word32  privSz = 0;
8715
    int     localRng = 0;
8716
    WC_RNG* rng    = NULL;
8717
#ifdef WOLFSSL_SMALL_STACK
8718
    WC_RNG* tmpRng = NULL;
8719
#else
8720
    WC_RNG  tmpRng[1];
8721
#endif
8722
    unsigned char* pub    = NULL;
8723
    unsigned char* priv   = NULL;
8724
8725
    WOLFSSL_ENTER("wolfSSL_DH_generate_key");
8726
8727
    /* Validate parameters. */
8728
    if ((dh == NULL) || (dh->p == NULL) || (dh->g == NULL)) {
8729
        WOLFSSL_ERROR_MSG("Bad function arguments");
8730
        ret = 0;
8731
    }
8732
8733
    /* Synchronize the external and internal parameters. */
8734
    if ((ret == 1) && (dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
8735
        WOLFSSL_ERROR_MSG("Bad DH set internal");
8736
        ret = 0;
8737
    }
8738
8739
    if (ret == 1) {
8740
        /* Make a new RNG or use global. */
8741
        rng = wolfssl_make_rng(tmpRng, &localRng);
8742
        /* Check we have a random number generator. */
8743
        if (rng == NULL) {
8744
            ret = 0;
8745
        }
8746
    }
8747
8748
    if (ret == 1) {
8749
        /* Get the size of the prime in bytes. */
8750
        pubSz = (word32)wolfSSL_BN_num_bytes(dh->p);
8751
        if (pubSz == 0) {
8752
            WOLFSSL_ERROR_MSG("Prime parameter invalid");
8753
            ret = 0;
8754
        }
8755
    }
8756
    if (ret == 1) {
8757
        /* Private key size can be as much as the size of the prime. */
8758
        if (dh->length) {
8759
            privSz = (word32)(dh->length / 8); /* to bytes */
8760
            /* Special case where priv key is larger than dh->length / 8
8761
             * See GeneratePrivateDh */
8762
            if (dh->length == 128)
8763
                privSz = 21;
8764
        }
8765
        else {
8766
            privSz = pubSz;
8767
        }
8768
        /* Allocate public and private key arrays. */
8769
        pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
8770
        priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
8771
        if (pub == NULL || priv == NULL) {
8772
            WOLFSSL_ERROR_MSG("Unable to malloc memory");
8773
            ret = 0;
8774
        }
8775
    }
8776
    if (ret == 1) {
8777
        /* Dispose of old public and private keys. */
8778
        wolfSSL_BN_free(dh->pub_key);
8779
        wolfSSL_BN_free(dh->priv_key);
8780
8781
        /* Allocate new public and private keys. */
8782
        dh->pub_key = wolfSSL_BN_new();
8783
        dh->priv_key = wolfSSL_BN_new();
8784
        if (dh->pub_key == NULL) {
8785
            WOLFSSL_ERROR_MSG("Bad DH new pub");
8786
            ret = 0;
8787
        }
8788
        if (dh->priv_key == NULL) {
8789
            WOLFSSL_ERROR_MSG("Bad DH new priv");
8790
            ret = 0;
8791
        }
8792
    }
8793
8794
    PRIVATE_KEY_UNLOCK();
8795
    /* Generate public and private keys into arrays. */
8796
    if ((ret == 1) && (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv,
8797
            &privSz, pub, &pubSz) < 0)) {
8798
        WOLFSSL_ERROR_MSG("Bad wc_DhGenerateKeyPair");
8799
        ret = 0;
8800
    }
8801
    /* Set public key from array. */
8802
    if ((ret == 1) && (wolfSSL_BN_bin2bn(pub, (int)pubSz, dh->pub_key) ==
8803
            NULL)) {
8804
        WOLFSSL_ERROR_MSG("Bad DH bn2bin error pub");
8805
        ret = 0;
8806
    }
8807
    /* Set private key from array. */
8808
    if ((ret == 1) && (wolfSSL_BN_bin2bn(priv, (int)privSz, dh->priv_key) ==
8809
            NULL)) {
8810
        WOLFSSL_ERROR_MSG("Bad DH bn2bin error priv");
8811
        ret = 0;
8812
    }
8813
    PRIVATE_KEY_LOCK();
8814
8815
    if (localRng) {
8816
        /* Free an initialized local random number generator. */
8817
        wc_FreeRng(rng);
8818
    #ifdef WOLFSSL_SMALL_STACK
8819
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
8820
    #endif
8821
    }
8822
    /* Dispose of allocated data. */
8823
    XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
8824
    XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
8825
8826
    return ret;
8827
}
8828
8829
8830
static int _DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
8831
    WOLFSSL_DH* dh, int ct)
8832
{
8833
    int            ret    = 0;
8834
    word32         keySz  = 0;
8835
    int            pubSz  = MAX_DHKEY_SZ;
8836
    int            privSz = MAX_DHKEY_SZ;
8837
    int            sz     = 0;
8838
#ifdef WOLFSSL_SMALL_STACK
8839
    unsigned char* pub    = NULL;
8840
    unsigned char* priv   = NULL;
8841
#else
8842
    unsigned char  pub [MAX_DHKEY_SZ];
8843
    unsigned char  priv[MAX_DHKEY_SZ];
8844
#endif
8845
8846
    WOLFSSL_ENTER("wolfSSL_DH_compute_key");
8847
8848
    /* Validate parameters. */
8849
    if ((dh == NULL) || (dh->priv_key == NULL) || (otherPub == NULL)) {
8850
        WOLFSSL_ERROR_MSG("Bad function arguments");
8851
        ret = WOLFSSL_FATAL_ERROR;
8852
    }
8853
    /* Get the maximum size of computed DH key. */
8854
    if ((ret == 0) && ((keySz = (word32)wolfSSL_DH_size(dh)) == 0)) {
8855
        WOLFSSL_ERROR_MSG("Bad DH_size");
8856
        ret = WOLFSSL_FATAL_ERROR;
8857
    }
8858
    if (ret == 0) {
8859
        /* Validate the size of the private key. */
8860
        sz = wolfSSL_BN_num_bytes(dh->priv_key);
8861
        if (sz > (int)privSz) {
8862
            WOLFSSL_ERROR_MSG("Bad priv internal size");
8863
            ret = WOLFSSL_FATAL_ERROR;
8864
        }
8865
    }
8866
    if (ret == 0) {
8867
    #ifdef WOLFSSL_SMALL_STACK
8868
        /* Keep real private key size to minimize amount allocated. */
8869
        privSz = sz;
8870
    #endif
8871
8872
        /* Validate the size of the public key. */
8873
        sz = wolfSSL_BN_num_bytes(otherPub);
8874
        if (sz > pubSz) {
8875
            WOLFSSL_ERROR_MSG("Bad otherPub size");
8876
            ret = WOLFSSL_FATAL_ERROR;
8877
        }
8878
    }
8879
8880
    if (ret == 0) {
8881
    #ifdef WOLFSSL_SMALL_STACK
8882
        /* Allocate memory for the public key array. */
8883
        pub = (unsigned char*)XMALLOC((size_t)sz, NULL,
8884
            DYNAMIC_TYPE_PUBLIC_KEY);
8885
        if (pub == NULL)
8886
            ret = WOLFSSL_FATAL_ERROR;
8887
    }
8888
    if (ret == 0) {
8889
        /* Allocate memory for the private key array. */
8890
        priv = (unsigned char*)XMALLOC((size_t)privSz, NULL,
8891
            DYNAMIC_TYPE_PRIVATE_KEY);
8892
        if (priv == NULL) {
8893
            ret = WOLFSSL_FATAL_ERROR;
8894
        }
8895
    }
8896
    if (ret == 0) {
8897
    #endif
8898
        /* Get the private key into the array. */
8899
        privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
8900
        if (privSz <= 0) {
8901
            ret = WOLFSSL_FATAL_ERROR;
8902
        }
8903
    }
8904
    if (ret == 0) {
8905
        /* Get the public key into the array. */
8906
        pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
8907
        if (pubSz <= 0) {
8908
            ret = WOLFSSL_FATAL_ERROR;
8909
        }
8910
    }
8911
    /* Synchronize the external into the internal parameters. */
8912
    if ((ret == 0) && ((dh->inSet == 0) && (SetDhInternal(dh) != 1))) {
8913
        WOLFSSL_ERROR_MSG("Bad DH set internal");
8914
        ret = WOLFSSL_FATAL_ERROR;
8915
    }
8916
8917
    PRIVATE_KEY_UNLOCK();
8918
    /* Calculate shared secret from private and public keys. */
8919
    if (ret == 0) {
8920
        word32 padded_keySz = keySz;
8921
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) && !defined(HAVE_SELFTEST)
8922
        if (ct) {
8923
            if (wc_DhAgree_ct((DhKey*)dh->internal, key, &keySz, priv,
8924
                           (word32)privSz, pub, (word32)pubSz) < 0) {
8925
                WOLFSSL_ERROR_MSG("wc_DhAgree_ct failed");
8926
                ret = WOLFSSL_FATAL_ERROR;
8927
            }
8928
        }
8929
        else
8930
#endif /* (!HAVE_FIPS || FIPS_VERSION_GE(7,0)) && !HAVE_SELFTEST */
8931
        {
8932
            if (wc_DhAgree((DhKey*)dh->internal, key, &keySz, priv,
8933
                           (word32)privSz, pub, (word32)pubSz) < 0) {
8934
                WOLFSSL_ERROR_MSG("wc_DhAgree failed");
8935
                ret = WOLFSSL_FATAL_ERROR;
8936
            }
8937
        }
8938
8939
        if ((ret == 0) && ct) {
8940
            /* Arrange for correct fixed-length, right-justified key, even if
8941
             * the crypto back end doesn't support it.  With some crypto back
8942
             * ends this forgoes formal constant-timeness on the key agreement,
8943
             * but assured that wolfSSL_DH_compute_key_padded() functions
8944
             * correctly.
8945
             */
8946
            if (keySz < padded_keySz) {
8947
                XMEMMOVE(key, key + (padded_keySz - keySz),
8948
                         padded_keySz - keySz);
8949
                XMEMSET(key, 0, padded_keySz - keySz);
8950
                keySz = padded_keySz;
8951
            }
8952
        }
8953
    }
8954
    if (ret == 0) {
8955
        /* Return actual length. */
8956
        ret = (int)keySz;
8957
    }
8958
    PRIVATE_KEY_LOCK();
8959
8960
#ifdef WOLFSSL_SMALL_STACK
8961
    if (priv != NULL)
8962
#endif
8963
    {
8964
        /* Zeroize sensitive data. */
8965
        ForceZero(priv, (word32)privSz);
8966
    }
8967
#ifdef WOLFSSL_SMALL_STACK
8968
    XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
8969
    XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
8970
#endif
8971
8972
    WOLFSSL_LEAVE("wolfSSL_DH_compute_key", ret);
8973
8974
    return ret;
8975
}
8976
8977
/* Compute the shared key from the private key and peer's public key.
8978
 *
8979
 * Return code compliant with OpenSSL.
8980
 * OpenSSL returns 0 when number of bits in p are smaller than minimum
8981
 * supported.
8982
 *
8983
 * @param [out] key       Buffer to place shared key.
8984
 * @param [in]  otherPub  Peer's public key.
8985
 * @param [in]  dh        DH key containing private key.
8986
 * @return  -1 on error.
8987
 * @return  Size of shared secret in bytes on success.
8988
 */
8989
int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
8990
    WOLFSSL_DH* dh)
8991
{
8992
    return _DH_compute_key(key, otherPub, dh, 0);
8993
}
8994
8995
/* Compute the shared key from the private key and peer's public key as in
8996
 * wolfSSL_DH_compute_key, but using constant time processing, with an output
8997
 * key length fixed at the nominal DH key size.  Leading zeros are retained.
8998
 *
8999
 * Return code compliant with OpenSSL.
9000
 * OpenSSL returns 0 when number of bits in p are smaller than minimum
9001
 * supported.
9002
 *
9003
 * @param [out] key       Buffer to place shared key.
9004
 * @param [in]  otherPub  Peer's public key.
9005
 * @param [in]  dh        DH key containing private key.
9006
 * @return  -1 on error.
9007
 * @return  Size of shared secret in bytes on success.
9008
 */
9009
int wolfSSL_DH_compute_key_padded(unsigned char* key,
9010
    const WOLFSSL_BIGNUM* otherPub, WOLFSSL_DH* dh)
9011
{
9012
    return _DH_compute_key(key, otherPub, dh, 1);
9013
}
9014
9015
#endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) ||
9016
        * HAVE_FIPS_VERSION > 2 */
9017
9018
#endif /* OPENSSL_EXTRA */
9019
9020
#endif /* NO_DH */
9021
9022
/*******************************************************************************
9023
 * END OF DH API
9024
 ******************************************************************************/
9025
9026
9027
/*******************************************************************************
9028
 * START OF EC API
9029
 ******************************************************************************/
9030
9031
#ifdef HAVE_ECC
9032
9033
#if defined(OPENSSL_EXTRA)
9034
9035
/* Start EC_curve */
9036
9037
/* Get the NIST name for the numeric ID.
9038
 *
9039
 * @param [in] nid  Numeric ID of an EC curve.
9040
 * @return  String representing NIST name of EC curve on success.
9041
 * @return  NULL on error.
9042
 */
9043
const char* wolfSSL_EC_curve_nid2nist(int nid)
9044
{
9045
    const char* name = NULL;
9046
    const WOLF_EC_NIST_NAME* nist_name;
9047
9048
    /* Attempt to find the curve info matching the NID passed in. */
9049
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
9050
        if (nist_name->nid == nid) {
9051
            /* NID found - return name. */
9052
            name = nist_name->name;
9053
            break;
9054
        }
9055
    }
9056
9057
    return name;
9058
}
9059
9060
/* Get the numeric ID for the NIST name.
9061
 *
9062
 * @param [in] name  NIST name of EC curve.
9063
 * @return  NID matching NIST name on success.
9064
 * @return  0 on error.
9065
 */
9066
int wolfSSL_EC_curve_nist2nid(const char* name)
9067
{
9068
    int nid = 0;
9069
    const WOLF_EC_NIST_NAME* nist_name;
9070
9071
    /* Attempt to find the curve info matching the NIST name passed in. */
9072
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
9073
        if (XSTRCMP(nist_name->name, name) == 0) {
9074
            /* Name found - return NID. */
9075
            nid = nist_name->nid;
9076
            break;
9077
        }
9078
    }
9079
9080
    return nid;
9081
}
9082
9083
#endif /* OPENSSL_EXTRA */
9084
9085
/* End EC_curve */
9086
9087
/* Start EC_METHOD */
9088
9089
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9090
/* Get the EC method of the EC group object.
9091
 *
9092
 * wolfSSL doesn't use method tables. Implementation used is dependent upon
9093
 * the NID.
9094
 *
9095
 * @param [in] group  EC group object.
9096
 * @return  EC method.
9097
 */
9098
const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
9099
    const WOLFSSL_EC_GROUP *group)
9100
{
9101
    /* No method table used so just return the same object. */
9102
    return group;
9103
}
9104
9105
/* Get field type for method.
9106
 *
9107
 * Only prime fields are supported.
9108
 *
9109
 * @param [in] meth  EC method.
9110
 * @return  X9.63 prime field NID on success.
9111
 * @return  0 on error.
9112
 */
9113
int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth)
9114
{
9115
    int nid = 0;
9116
9117
    if (meth != NULL) {
9118
        /* Only field type supported by code base. */
9119
        nid = WC_NID_X9_62_prime_field;
9120
    }
9121
9122
    return nid;
9123
}
9124
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9125
9126
/* End EC_METHOD */
9127
9128
/* Start EC_GROUP */
9129
9130
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9131
/* Converts ECC curve enum values in ecc_curve_id to the associated OpenSSL NID
9132
 * value.
9133
 *
9134
 * @param [in] n  ECC curve id.
9135
 * @return  ECC curve NID (OpenSSL compatible value).
9136
 */
9137
int EccEnumToNID(int n)
9138
{
9139
    WOLFSSL_ENTER("EccEnumToNID");
9140
9141
    switch(n) {
9142
        case ECC_SECP192R1:
9143
            return WC_NID_X9_62_prime192v1;
9144
        case ECC_PRIME192V2:
9145
            return WC_NID_X9_62_prime192v2;
9146
        case ECC_PRIME192V3:
9147
            return WC_NID_X9_62_prime192v3;
9148
        case ECC_PRIME239V1:
9149
            return WC_NID_X9_62_prime239v1;
9150
        case ECC_PRIME239V2:
9151
            return WC_NID_X9_62_prime239v2;
9152
        case ECC_PRIME239V3:
9153
            return WC_NID_X9_62_prime239v3;
9154
        case ECC_SECP256R1:
9155
            return WC_NID_X9_62_prime256v1;
9156
        case ECC_SECP112R1:
9157
            return WC_NID_secp112r1;
9158
        case ECC_SECP112R2:
9159
            return WC_NID_secp112r2;
9160
        case ECC_SECP128R1:
9161
            return WC_NID_secp128r1;
9162
        case ECC_SECP128R2:
9163
            return WC_NID_secp128r2;
9164
        case ECC_SECP160R1:
9165
            return WC_NID_secp160r1;
9166
        case ECC_SECP160R2:
9167
            return WC_NID_secp160r2;
9168
        case ECC_SECP224R1:
9169
            return WC_NID_secp224r1;
9170
        case ECC_SECP384R1:
9171
            return WC_NID_secp384r1;
9172
        case ECC_SECP521R1:
9173
            return WC_NID_secp521r1;
9174
        case ECC_SECP160K1:
9175
            return WC_NID_secp160k1;
9176
        case ECC_SECP192K1:
9177
            return WC_NID_secp192k1;
9178
        case ECC_SECP224K1:
9179
            return WC_NID_secp224k1;
9180
        case ECC_SECP256K1:
9181
            return WC_NID_secp256k1;
9182
        case ECC_BRAINPOOLP160R1:
9183
            return WC_NID_brainpoolP160r1;
9184
        case ECC_BRAINPOOLP192R1:
9185
            return WC_NID_brainpoolP192r1;
9186
        case ECC_BRAINPOOLP224R1:
9187
            return WC_NID_brainpoolP224r1;
9188
        case ECC_BRAINPOOLP256R1:
9189
            return WC_NID_brainpoolP256r1;
9190
        case ECC_BRAINPOOLP320R1:
9191
            return WC_NID_brainpoolP320r1;
9192
        case ECC_BRAINPOOLP384R1:
9193
            return WC_NID_brainpoolP384r1;
9194
        case ECC_BRAINPOOLP512R1:
9195
            return WC_NID_brainpoolP512r1;
9196
    #ifdef WOLFSSL_SM2
9197
        case ECC_SM2P256V1:
9198
            return WC_NID_sm2;
9199
    #endif
9200
        default:
9201
            WOLFSSL_MSG("NID not found");
9202
            return WOLFSSL_FATAL_ERROR;
9203
    }
9204
}
9205
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9206
9207
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9208
/* Converts OpenSSL NID of EC curve to the enum value in ecc_curve_id
9209
 *
9210
 * Used by ecc_sets[].
9211
 *
9212
 * @param [in] n  OpenSSL NID of EC curve.
9213
 * @return  wolfCrypt EC curve id.
9214
 * @return  -1 on error.
9215
 */
9216
int NIDToEccEnum(int nid)
9217
{
9218
    int id;
9219
9220
    WOLFSSL_ENTER("NIDToEccEnum");
9221
9222
    switch (nid) {
9223
        case WC_NID_X9_62_prime192v1:
9224
            id = ECC_SECP192R1;
9225
            break;
9226
        case WC_NID_X9_62_prime192v2:
9227
            id = ECC_PRIME192V2;
9228
            break;
9229
        case WC_NID_X9_62_prime192v3:
9230
            id = ECC_PRIME192V3;
9231
            break;
9232
        case WC_NID_X9_62_prime239v1:
9233
            id = ECC_PRIME239V1;
9234
            break;
9235
        case WC_NID_X9_62_prime239v2:
9236
            id = ECC_PRIME239V2;
9237
            break;
9238
        case WC_NID_X9_62_prime239v3:
9239
            id = ECC_PRIME239V3;
9240
            break;
9241
        case WC_NID_X9_62_prime256v1:
9242
            id = ECC_SECP256R1;
9243
            break;
9244
        case WC_NID_secp112r1:
9245
            id = ECC_SECP112R1;
9246
            break;
9247
        case WC_NID_secp112r2:
9248
            id = ECC_SECP112R2;
9249
            break;
9250
        case WC_NID_secp128r1:
9251
            id = ECC_SECP128R1;
9252
            break;
9253
        case WC_NID_secp128r2:
9254
            id = ECC_SECP128R2;
9255
            break;
9256
        case WC_NID_secp160r1:
9257
            id = ECC_SECP160R1;
9258
            break;
9259
        case WC_NID_secp160r2:
9260
            id = ECC_SECP160R2;
9261
            break;
9262
        case WC_NID_secp224r1:
9263
            id = ECC_SECP224R1;
9264
            break;
9265
        case WC_NID_secp384r1:
9266
            id = ECC_SECP384R1;
9267
            break;
9268
        case WC_NID_secp521r1:
9269
            id = ECC_SECP521R1;
9270
            break;
9271
        case WC_NID_secp160k1:
9272
            id = ECC_SECP160K1;
9273
            break;
9274
        case WC_NID_secp192k1:
9275
            id = ECC_SECP192K1;
9276
            break;
9277
        case WC_NID_secp224k1:
9278
            id = ECC_SECP224K1;
9279
            break;
9280
        case WC_NID_secp256k1:
9281
            id = ECC_SECP256K1;
9282
            break;
9283
        case WC_NID_brainpoolP160r1:
9284
            id = ECC_BRAINPOOLP160R1;
9285
            break;
9286
        case WC_NID_brainpoolP192r1:
9287
            id = ECC_BRAINPOOLP192R1;
9288
            break;
9289
        case WC_NID_brainpoolP224r1:
9290
            id = ECC_BRAINPOOLP224R1;
9291
            break;
9292
        case WC_NID_brainpoolP256r1:
9293
            id = ECC_BRAINPOOLP256R1;
9294
            break;
9295
        case WC_NID_brainpoolP320r1:
9296
            id = ECC_BRAINPOOLP320R1;
9297
            break;
9298
        case WC_NID_brainpoolP384r1:
9299
            id = ECC_BRAINPOOLP384R1;
9300
            break;
9301
        case WC_NID_brainpoolP512r1:
9302
            id = ECC_BRAINPOOLP512R1;
9303
            break;
9304
        default:
9305
            WOLFSSL_MSG("NID not found");
9306
            /* -1 on error. */
9307
            id = WOLFSSL_FATAL_ERROR;
9308
    }
9309
9310
    return id;
9311
}
9312
9313
/* Set the fields of the EC group based on numeric ID.
9314
 *
9315
 * @param [in, out] group  EC group.
9316
 * @param [in]      nid    Numeric ID of an EC curve.
9317
 */
9318
static void ec_group_set_nid(WOLFSSL_EC_GROUP* group, int nid)
9319
{
9320
    int eccEnum;
9321
    int realNid;
9322
9323
    /* Convert ecc_curve_id enum to NID. */
9324
    if ((realNid = EccEnumToNID(nid)) != -1) {
9325
        /* ecc_curve_id enum passed in - have real NID value set. */
9326
        eccEnum = nid;
9327
    }
9328
    else {
9329
        /* NID passed in is OpenSSL type. */
9330
        realNid = nid;
9331
        /* Convert NID to ecc_curve_id enum. */
9332
        eccEnum = NIDToEccEnum(nid);
9333
    }
9334
9335
    /* Set the numeric ID of the curve */
9336
    group->curve_nid = realNid;
9337
    /* Initialize index to -1 (i.e. wolfCrypt doesn't support curve). */
9338
    group->curve_idx = -1;
9339
9340
    /* Find index and OID sum for curve if wolfCrypt supports it. */
9341
    if (eccEnum != -1) {
9342
        int i;
9343
9344
        /* Find id and set the internal curve idx and OID sum. */
9345
        for (i = 0; ecc_sets[i].size != 0; i++) {
9346
            if (ecc_sets[i].id == eccEnum) {
9347
                /* Found id in wolfCrypt supported EC curves. */
9348
                group->curve_idx = i;
9349
                group->curve_oid = (int)ecc_sets[i].oidSum;
9350
                break;
9351
            }
9352
        }
9353
    }
9354
}
9355
9356
/* Create a new EC group with the numeric ID for an EC curve.
9357
 *
9358
 * @param [in] nid  Numeric ID of an EC curve.
9359
 * @return  New, allocated EC group on success.
9360
 * @return  NULL on error.
9361
 */
9362
WOLFSSL_EC_GROUP* wolfSSL_EC_GROUP_new_by_curve_name(int nid)
9363
{
9364
    int err = 0;
9365
    WOLFSSL_EC_GROUP* group;
9366
9367
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
9368
9369
    /* Allocate EC group. */
9370
    group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
9371
        DYNAMIC_TYPE_ECC);
9372
    if (group == NULL) {
9373
        WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
9374
        err = 1;
9375
    }
9376
9377
    if (!err) {
9378
        /* Reset all fields. */
9379
        XMEMSET(group, 0, sizeof(WOLFSSL_EC_GROUP));
9380
9381
        /* Set the fields of group based on the numeric ID. */
9382
        ec_group_set_nid(group, nid);
9383
    }
9384
9385
    return group;
9386
}
9387
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9388
9389
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9390
/* Dispose of the EC group.
9391
 *
9392
 * Cannot use group after this call.
9393
 *
9394
 * @param [in] group  EC group to free.
9395
 */
9396
void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
9397
{
9398
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
9399
9400
    /* Dispose of EC group. */
9401
    XFREE(group, NULL, DYNAMIC_TYPE_ECC);
9402
}
9403
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9404
9405
#ifdef OPENSSL_EXTRA
9406
#ifndef NO_BIO
9407
9408
/* Creates an EC group from the DER encoding.
9409
 *
9410
 * Only named curves supported.
9411
 *
9412
 * @param [out] group  Reference to EC group object.
9413
 * @param [in]  in     Buffer holding DER encoding of curve.
9414
 * @param [in]  inSz   Length of data in buffer.
9415
 * @return  EC group on success.
9416
 * @return  NULL on error.
9417
 */
9418
static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group,
9419
    const unsigned char** in_pp, long inSz)
9420
{
9421
    int err = 0;
9422
    WOLFSSL_EC_GROUP* ret = NULL;
9423
    word32 idx = 0;
9424
    word32 oid = 0;
9425
    int id = 0;
9426
    const unsigned char* in;
9427
9428
    if (in_pp == NULL || *in_pp == NULL)
9429
        return NULL;
9430
9431
    in = *in_pp;
9432
9433
    /* Use the group passed in. */
9434
    if ((group != NULL) && (*group != NULL)) {
9435
        ret = *group;
9436
    }
9437
9438
    /* Only support named curves. */
9439
    if (in[0] != ASN_OBJECT_ID) {
9440
        WOLFSSL_ERROR_MSG("Invalid or unsupported encoding");
9441
        err = 1;
9442
    }
9443
    /* Decode the OBJECT ID - expecting an EC curve OID. */
9444
    if ((!err) && (GetObjectId(in, &idx, &oid, oidCurveType, (word32)inSz) !=
9445
            0)) {
9446
        err = 1;
9447
    }
9448
    if (!err) {
9449
        /* Get the internal ID for OID. */
9450
        id = wc_ecc_get_oid(oid, NULL, NULL);
9451
        if (id < 0) {
9452
            err = 1;
9453
        }
9454
    }
9455
    if (!err) {
9456
        /* Get the NID for the internal ID. */
9457
        int nid = EccEnumToNID(id);
9458
        if (ret == NULL) {
9459
            /* Create a new EC group with the numeric ID. */
9460
            ret = wolfSSL_EC_GROUP_new_by_curve_name(nid);
9461
            if (ret == NULL) {
9462
                err = 1;
9463
            }
9464
        }
9465
        else {
9466
            ec_group_set_nid(ret, nid);
9467
        }
9468
    }
9469
    if ((!err) && (group != NULL)) {
9470
        /* Return the EC group through reference. */
9471
        *group = ret;
9472
    }
9473
9474
    if (err) {
9475
        if ((ret != NULL) && (ret != *group)) {
9476
            wolfSSL_EC_GROUP_free(ret);
9477
        }
9478
        ret = NULL;
9479
    }
9480
    else {
9481
        *in_pp += idx;
9482
    }
9483
    return ret;
9484
}
9485
9486
/* Creates a new EC group from the PEM encoding in the BIO.
9487
 *
9488
 * @param [in]  bio    BIO to read PEM encoding from.
9489
 * @param [out] group  Reference to EC group object.
9490
 * @param [in]  cb     Password callback when PEM encrypted.
9491
 * @param [in]  pass   NUL terminated string for passphrase when PEM encrypted.
9492
 * @return  EC group on success.
9493
 * @return  NULL on error.
9494
 */
9495
WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio,
9496
    WOLFSSL_EC_GROUP** group, wc_pem_password_cb* cb, void* pass)
9497
{
9498
    int err = 0;
9499
    WOLFSSL_EC_GROUP* ret = NULL;
9500
    DerBuffer*        der = NULL;
9501
    int               keyFormat = 0;
9502
9503
     if (bio == NULL) {
9504
         err = 1;
9505
     }
9506
9507
    /* Read parameters from BIO and convert PEM to DER. */
9508
    if ((!err) && (pem_read_bio_key(bio, cb, pass, ECC_PARAM_TYPE,
9509
            &keyFormat, &der) < 0)) {
9510
        err = 1;
9511
    }
9512
    if (!err) {
9513
        /* Create EC group from DER encoding. */
9514
        const byte** p = (const byte**)&der->buffer;
9515
        ret = wolfssl_ec_group_d2i(group, p, der->length);
9516
        if (ret == NULL) {
9517
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_GROUP");
9518
        }
9519
    }
9520
9521
    /* Dispose of any allocated data. */
9522
    FreeDer(&der);
9523
    return ret;
9524
}
9525
9526
WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out,
9527
        const unsigned char **in, long len)
9528
{
9529
    return wolfssl_ec_group_d2i(out, in, len);
9530
}
9531
9532
int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp)
9533
{
9534
    unsigned char* out = NULL;
9535
    int len = 0;
9536
    int idx;
9537
    const byte* oid = NULL;
9538
    word32 oidSz = 0;
9539
9540
    if (grp == NULL || !wc_ecc_is_valid_idx(grp->curve_idx) ||
9541
            grp->curve_idx < 0)
9542
        return WOLFSSL_FATAL_ERROR;
9543
9544
    /* Get the actual DER encoding of the OID. ecc_sets[grp->curve_idx].oid
9545
     * is just the numerical representation. */
9546
    if (wc_ecc_get_oid((word32)grp->curve_oid, &oid, &oidSz) < 0)
9547
        return WOLFSSL_FATAL_ERROR;
9548
9549
    len = SetObjectId((int)oidSz, NULL) + (int)oidSz;
9550
9551
    if (pp == NULL)
9552
        return len;
9553
9554
    if (*pp == NULL) {
9555
        out = (unsigned char*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
9556
        if (out == NULL)
9557
            return WOLFSSL_FATAL_ERROR;
9558
    }
9559
    else {
9560
        out = *pp;
9561
    }
9562
9563
    idx = SetObjectId((int)oidSz, out);
9564
    XMEMCPY(out + idx, oid, oidSz);
9565
    if (*pp == NULL)
9566
        *pp = out;
9567
    else
9568
        *pp += len;
9569
9570
    return len;
9571
}
9572
#endif /* !NO_BIO */
9573
9574
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
9575
/* Copy an EC group.
9576
 *
9577
 * Only used by wolfSSL_EC_KEY_dup at this time.
9578
 *
9579
 * @param [in, out] dst  Destination EC group.
9580
 * @param [in]      src  Source EC group.
9581
 * @return  0 on success.
9582
 */
9583
static int wolfssl_ec_group_copy(WOLFSSL_EC_GROUP* dst,
9584
    const WOLFSSL_EC_GROUP* src)
9585
{
9586
    /* Copy the fields. */
9587
    dst->curve_idx = src->curve_idx;
9588
    dst->curve_nid = src->curve_nid;
9589
    dst->curve_oid = src->curve_oid;
9590
9591
    return 0;
9592
}
9593
#endif /* OPENSSL_ALL && !NO_CERTS */
9594
9595
/* Copies ecc_key into new WOLFSSL_EC_GROUP object
9596
 *
9597
 * @param [in] src  EC group to duplicate.
9598
 *
9599
 * @return  EC group on success.
9600
 * @return  NULL on error.
9601
 */
9602
WOLFSSL_EC_GROUP* wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP *src)
9603
{
9604
    WOLFSSL_EC_GROUP* newGroup = NULL;
9605
9606
    if (src != NULL) {
9607
        /* Create new group base on NID in original EC group. */
9608
        newGroup = wolfSSL_EC_GROUP_new_by_curve_name(src->curve_nid);
9609
     }
9610
9611
    return newGroup;
9612
}
9613
9614
/* Compare two EC groups.
9615
 *
9616
 * Return code compliant with OpenSSL.
9617
 *
9618
 * @param [in] a    First EC group.
9619
 * @param [in] b    Second EC group.
9620
 * @param [in] ctx  Big number context to use when comparing fields. Unused.
9621
 *
9622
 * @return  0 if equal.
9623
 * @return  1 if not equal.
9624
 * @return  -1 on error.
9625
 */
9626
int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
9627
                         WOLFSSL_BN_CTX *ctx)
9628
{
9629
    int ret;
9630
9631
    /* No BN operations performed. */
9632
    (void)ctx;
9633
9634
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
9635
9636
    /* Validate parameters. */
9637
    if ((a == NULL) || (b == NULL)) {
9638
        WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
9639
        /* Return error value. */
9640
        ret = WOLFSSL_FATAL_ERROR;
9641
    }
9642
    /* Compare NID and wolfSSL curve index. */
9643
    else {
9644
        /* 0 when same, 1 when not. */
9645
        ret = ((a->curve_nid == b->curve_nid) &&
9646
               (a->curve_idx == b->curve_idx)) ? 0 : 1;
9647
    }
9648
9649
    return ret;
9650
}
9651
9652
#ifndef NO_WOLFSSL_STUB
9653
/* Set the ASN.1 flag that indicate encoding of curve.
9654
 *
9655
 * Stub function - flag not used elsewhere.
9656
 * Always encoded as named curve.
9657
 *
9658
 * @param [in] group  EC group to modify.
9659
 * @param [in] flag   ASN.1 flag to set. Valid values:
9660
 *                    OPENSSL_EC_EXPLICIT_CURVE, OPENSSL_EC_NAMED_CURVE
9661
 */
9662
void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
9663
{
9664
    (void)group;
9665
    (void)flag;
9666
9667
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
9668
    WOLFSSL_STUB("EC_GROUP_set_asn1_flag");
9669
}
9670
#endif
9671
9672
/* Get the curve NID of the group.
9673
 *
9674
 * Return code compliant with OpenSSL.
9675
 *
9676
 * @param [in] group  EC group.
9677
 * @return  Curve NID on success.
9678
 * @return  0 on error.
9679
 */
9680
int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
9681
{
9682
    int nid = 0;
9683
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
9684
9685
    if (group == NULL) {
9686
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
9687
    }
9688
    else {
9689
        nid = group->curve_nid;
9690
    }
9691
9692
    return nid;
9693
}
9694
9695
/* Get the degree (curve size in bits) of the EC group.
9696
 *
9697
 * Return code compliant with OpenSSL.
9698
 *
9699
 * @return  Degree of the curve on success.
9700
 * @return  0 on error.
9701
 */
9702
int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
9703
{
9704
    int degree = 0;
9705
9706
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
9707
9708
    if (group == NULL) {
9709
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
9710
    }
9711
    else {
9712
        switch (group->curve_nid) {
9713
            case WC_NID_secp112r1:
9714
            case WC_NID_secp112r2:
9715
                degree = 112;
9716
                break;
9717
            case WC_NID_secp128r1:
9718
            case WC_NID_secp128r2:
9719
                degree = 128;
9720
                break;
9721
            case WC_NID_secp160k1:
9722
            case WC_NID_secp160r1:
9723
            case WC_NID_secp160r2:
9724
            case WC_NID_brainpoolP160r1:
9725
                degree = 160;
9726
                break;
9727
            case WC_NID_secp192k1:
9728
            case WC_NID_brainpoolP192r1:
9729
            case WC_NID_X9_62_prime192v1:
9730
            case WC_NID_X9_62_prime192v2:
9731
            case WC_NID_X9_62_prime192v3:
9732
                degree = 192;
9733
                break;
9734
            case WC_NID_secp224k1:
9735
            case WC_NID_secp224r1:
9736
            case WC_NID_brainpoolP224r1:
9737
                degree = 224;
9738
                break;
9739
            case WC_NID_X9_62_prime239v1:
9740
            case WC_NID_X9_62_prime239v2:
9741
            case WC_NID_X9_62_prime239v3:
9742
                degree = 239;
9743
                break;
9744
            case WC_NID_secp256k1:
9745
            case WC_NID_brainpoolP256r1:
9746
            case WC_NID_X9_62_prime256v1:
9747
                degree = 256;
9748
                break;
9749
            case WC_NID_brainpoolP320r1:
9750
                degree = 320;
9751
                break;
9752
            case WC_NID_secp384r1:
9753
            case WC_NID_brainpoolP384r1:
9754
                degree = 384;
9755
                break;
9756
            case WC_NID_brainpoolP512r1:
9757
                degree = 512;
9758
                break;
9759
            case WC_NID_secp521r1:
9760
                degree = 521;
9761
                break;
9762
        }
9763
    }
9764
9765
    return degree;
9766
}
9767
#endif /* OPENSSL_EXTRA */
9768
9769
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9770
/* Get the length of the order in bits of the EC group.
9771
 *
9772
 * TODO: consider switch statement or calculating directly from hex string
9773
 * array instead of using mp_int.
9774
 *
9775
 * @param [in] group  EC group.
9776
 * @return  Length of order in bits on success.
9777
 * @return  0 on error.
9778
 */
9779
int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group)
9780
{
9781
    int ret = 0;
9782
#ifdef WOLFSSL_SMALL_STACK
9783
    mp_int *order = NULL;
9784
#else
9785
    mp_int order[1];
9786
#endif
9787
9788
    /* Validate parameter. */
9789
    if ((group == NULL) || (group->curve_idx < 0)) {
9790
        WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error");
9791
        ret = WOLFSSL_FATAL_ERROR;
9792
    }
9793
9794
#ifdef WOLFSSL_SMALL_STACK
9795
    if (ret == 0) {
9796
        /* Allocate memory for mp_int that will hold order value. */
9797
        order = (mp_int *)XMALLOC(sizeof(*order), NULL,
9798
            DYNAMIC_TYPE_TMP_BUFFER);
9799
        if (order == NULL) {
9800
            ret = WOLFSSL_FATAL_ERROR;
9801
        }
9802
    }
9803
#endif
9804
9805
    if (ret == 0) {
9806
        /* Initialize mp_int. */
9807
        ret = mp_init(order);
9808
    }
9809
9810
    if (ret == 0) {
9811
        /* Read hex string of order from wolfCrypt array of curves. */
9812
        ret = mp_read_radix(order, ecc_sets[group->curve_idx].order,
9813
            MP_RADIX_HEX);
9814
        if (ret == 0) {
9815
            /* Get bits of order. */
9816
            ret = mp_count_bits(order);
9817
        }
9818
        /* Clear and free mp_int. */
9819
        mp_clear(order);
9820
    }
9821
9822
#ifdef WOLFSSL_SMALL_STACK
9823
    /* Deallocate order. */
9824
    XFREE(order, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9825
#endif
9826
9827
    /* Convert error code to length of 0. */
9828
    if (ret < 0) {
9829
        ret = 0;
9830
    }
9831
9832
    return ret;
9833
}
9834
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9835
9836
#if defined(OPENSSL_EXTRA)
9837
/* Get the order of the group as a BN.
9838
 *
9839
 * Return code compliant with OpenSSL.
9840
 *
9841
 * @param [in]      group  EC group.
9842
 * @param [in, out] order  BN to hold order value.
9843
 * @param [in]      ctx    Context to use for BN operations. Unused.
9844
 * @return  1 on success.
9845
 * @return  0 on error.
9846
 */
9847
int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
9848
    WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
9849
{
9850
    int ret = 1;
9851
    mp_int* mp = NULL;
9852
9853
    /* No BN operations performed - done with mp_int in BN. */
9854
    (void)ctx;
9855
9856
    /* Validate parameters. */
9857
    if ((group == NULL) || (order == NULL) || (order->internal == NULL)) {
9858
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
9859
        ret = 0;
9860
    }
9861
9862
    if (ret == 1 &&
9863
            (group->curve_idx < 0 || !wc_ecc_is_valid_idx(group->curve_idx))) {
9864
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad group idx");
9865
        ret = 0;
9866
    }
9867
9868
    if (ret == 1) {
9869
        mp = (mp_int*)order->internal;
9870
    }
9871
    /* Initialize */
9872
    if ((ret == 1) && (mp_init(mp) != MP_OKAY)) {
9873
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
9874
        ret = 0;
9875
    }
9876
    /* Read hex string of order from wolfCrypt array of curves. */
9877
    if ((ret == 1) && (mp_read_radix(mp, ecc_sets[group->curve_idx].order,
9878
            MP_RADIX_HEX) != MP_OKAY)) {
9879
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
9880
        /* Zero out any partial value but don't free. */
9881
        mp_zero(mp);
9882
        ret = 0;
9883
    }
9884
9885
    return ret;
9886
}
9887
9888
#endif /* OPENSSL_EXTRA */
9889
9890
/* End EC_GROUP */
9891
9892
/* Start EC_POINT */
9893
9894
#if defined(OPENSSL_EXTRA)
9895
9896
/* Set data of EC point into internal, wolfCrypt EC point object.
9897
 *
9898
 * EC_POINT Openssl -> WolfSSL
9899
 *
9900
 * @param [in, out] p  EC point to update.
9901
 * @return  1 on success.
9902
 * @return  -1 on failure.
9903
 */
9904
static int ec_point_internal_set(WOLFSSL_EC_POINT *p)
9905
{
9906
    int ret = 1;
9907
9908
    WOLFSSL_ENTER("ec_point_internal_set");
9909
9910
    /* Validate parameter. */
9911
    if ((p == NULL) || (p->internal == NULL)) {
9912
        WOLFSSL_MSG("ECPoint NULL error");
9913
        ret = WOLFSSL_FATAL_ERROR;
9914
    }
9915
    else {
9916
        /* Get internal point as a wolfCrypt EC point. */
9917
        ecc_point* point = (ecc_point*)p->internal;
9918
9919
        /* Set X ordinate if available. */
9920
        if ((p->X != NULL) && (wolfssl_bn_get_value(p->X, point->x) != 1)) {
9921
            WOLFSSL_MSG("ecc point X error");
9922
            ret = WOLFSSL_FATAL_ERROR;
9923
        }
9924
        /* Set Y ordinate if available. */
9925
        if ((ret == 1) && (p->Y != NULL) && (wolfssl_bn_get_value(p->Y,
9926
                point->y) != 1)) {
9927
            WOLFSSL_MSG("ecc point Y error");
9928
            ret = WOLFSSL_FATAL_ERROR;
9929
        }
9930
        /* Set Z ordinate if available. */
9931
        if ((ret == 1) && (p->Z != NULL) && (wolfssl_bn_get_value(p->Z,
9932
                point->z) != 1)) {
9933
            WOLFSSL_MSG("ecc point Z error");
9934
            ret = WOLFSSL_FATAL_ERROR;
9935
        }
9936
        /* Internal values set when operations succeeded. */
9937
        p->inSet = (ret == 1);
9938
    }
9939
9940
    return ret;
9941
}
9942
9943
/* Set data of internal, wolfCrypt EC point object into EC point.
9944
 *
9945
 * EC_POINT WolfSSL -> OpenSSL
9946
 *
9947
 * @param [in, out] p  EC point to update.
9948
 * @return  1 on success.
9949
 * @return  -1 on failure.
9950
 */
9951
static int ec_point_external_set(WOLFSSL_EC_POINT *p)
9952
{
9953
    int ret = 1;
9954
9955
    WOLFSSL_ENTER("ec_point_external_set");
9956
9957
    /* Validate parameter. */
9958
    if ((p == NULL) || (p->internal == NULL)) {
9959
        WOLFSSL_MSG("ECPoint NULL error");
9960
        ret = WOLFSSL_FATAL_ERROR;
9961
    }
9962
    else {
9963
        /* Get internal point as a wolfCrypt EC point. */
9964
        ecc_point* point = (ecc_point*)p->internal;
9965
9966
        /* Set X ordinate. */
9967
        if (wolfssl_bn_set_value(&p->X, point->x) != 1) {
9968
            WOLFSSL_MSG("ecc point X error");
9969
            ret = WOLFSSL_FATAL_ERROR;
9970
        }
9971
        /* Set Y ordinate. */
9972
        if ((ret == 1) && (wolfssl_bn_set_value(&p->Y, point->y) != 1)) {
9973
            WOLFSSL_MSG("ecc point Y error");
9974
            ret = WOLFSSL_FATAL_ERROR;
9975
        }
9976
        /* Set Z ordinate. */
9977
        if ((ret == 1) && (wolfssl_bn_set_value(&p->Z, point->z) != 1)) {
9978
            WOLFSSL_MSG("ecc point Z error");
9979
            ret = WOLFSSL_FATAL_ERROR;
9980
        }
9981
        /* External values set when operations succeeded. */
9982
        p->exSet = (ret == 1);
9983
    }
9984
9985
    return ret;
9986
}
9987
9988
/* Setup internals of EC point.
9989
 *
9990
 * Assumes point is not NULL.
9991
 *
9992
 * @param [in, out] point  EC point to update.
9993
 * @return  1 on success.
9994
 * @return  0 on failure.
9995
 */
9996
static int ec_point_setup(const WOLFSSL_EC_POINT *point) {
9997
    int ret = 1;
9998
9999
    /* Check if internal values need setting. */
10000
    if (!point->inSet) {
10001
        WOLFSSL_MSG("No ECPoint internal set, do it");
10002
10003
        /* Forcing to non-constant type to update internals. */
10004
        if (ec_point_internal_set((WOLFSSL_EC_POINT *)point) != 1) {
10005
            WOLFSSL_MSG("ec_point_internal_set failed");
10006
            ret = 0;
10007
        }
10008
    }
10009
10010
    return ret;
10011
}
10012
10013
/* Create a new EC point from the group.
10014
 *
10015
 * @param [in] group  EC group.
10016
 * @return  EC point on success.
10017
 * @return  NULL on error.
10018
 */
10019
WOLFSSL_EC_POINT* wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP* group)
10020
{
10021
    int err = 0;
10022
    WOLFSSL_EC_POINT* point = NULL;
10023
10024
    WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
10025
10026
    /* Validate parameter. */
10027
    if (group == NULL) {
10028
        WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
10029
        err = 1;
10030
    }
10031
10032
    if (!err) {
10033
        /* Allocate memory for new EC point. */
10034
        point = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
10035
            DYNAMIC_TYPE_ECC);
10036
        if (point == NULL) {
10037
            WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
10038
            err = 1;
10039
        }
10040
    }
10041
    if (!err) {
10042
        /* Clear fields of EC point. */
10043
        XMEMSET(point, 0, sizeof(WOLFSSL_EC_POINT));
10044
10045
        /* Allocate internal EC point. */
10046
        point->internal = wc_ecc_new_point();
10047
        if (point->internal == NULL) {
10048
            WOLFSSL_MSG("ecc_new_point failure");
10049
            err = 1;
10050
        }
10051
    }
10052
10053
    if (err) {
10054
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
10055
        point = NULL;
10056
    }
10057
    return point;
10058
}
10059
10060
#endif /* OPENSSL_EXTRA */
10061
10062
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
10063
/* Dispose of the EC point.
10064
 *
10065
 * Cannot use point after this call.
10066
 *
10067
 * @param [in, out] point  EC point to free.
10068
 */
10069
void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *point)
10070
{
10071
    WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
10072
10073
    if (point != NULL) {
10074
        if (point->internal != NULL) {
10075
            wc_ecc_del_point((ecc_point*)point->internal);
10076
            point->internal = NULL;
10077
        }
10078
10079
        /* Free ordinates. */
10080
        wolfSSL_BN_free(point->X);
10081
        wolfSSL_BN_free(point->Y);
10082
        wolfSSL_BN_free(point->Z);
10083
        /* Clear fields. */
10084
        point->X = NULL;
10085
        point->Y = NULL;
10086
        point->Z = NULL;
10087
        point->inSet = 0;
10088
        point->exSet = 0;
10089
10090
        /* Dispose of EC point. */
10091
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
10092
    }
10093
}
10094
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
10095
10096
#ifdef OPENSSL_EXTRA
10097
10098
/* Clear and dispose of the EC point.
10099
 *
10100
 * Cannot use point after this call.
10101
 *
10102
 * @param [in, out] point  EC point to free.
10103
 */
10104
void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point)
10105
{
10106
    WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
10107
10108
    if (point != NULL) {
10109
        if (point->internal != NULL) {
10110
            /* Force internal point to be zeros. */
10111
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10112
            wc_ecc_forcezero_point((ecc_point*)point->internal);
10113
    #else
10114
            ecc_point* p = (ecc_point*)point->internal;
10115
            mp_forcezero(p->x);
10116
            mp_forcezero(p->y);
10117
            mp_forcezero(p->z);
10118
    #endif
10119
            wc_ecc_del_point((ecc_point*)point->internal);
10120
            point->internal = NULL;
10121
        }
10122
10123
        /* Clear the ordinates before freeing. */
10124
        wolfSSL_BN_clear_free(point->X);
10125
        wolfSSL_BN_clear_free(point->Y);
10126
        wolfSSL_BN_clear_free(point->Z);
10127
        /* Clear fields. */
10128
        point->X = NULL;
10129
        point->Y = NULL;
10130
        point->Z = NULL;
10131
        point->inSet = 0;
10132
        point->exSet = 0;
10133
10134
        /* Dispose of EC point. */
10135
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
10136
    }
10137
}
10138
10139
/* Print out the internals of EC point in debug and when logging callback set.
10140
 *
10141
 * Not an OpenSSL API.
10142
 *
10143
 * TODO: Use WOLFSSL_MSG_EX()?
10144
 *
10145
 * @param [in] msg    Message to prepend.
10146
 * @param [in] point  EC point to print.
10147
 */
10148
void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *point)
10149
{
10150
#if defined(DEBUG_WOLFSSL)
10151
    char *num;
10152
10153
    WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
10154
10155
    /* Only print when debugging on. */
10156
    if (WOLFSSL_IS_DEBUG_ON()) {
10157
        if (point == NULL) {
10158
            /* No point passed in so just put out "NULL". */
10159
            WOLFSSL_MSG_EX("%s = NULL\n", msg);
10160
        }
10161
        else {
10162
            /* Put out message and status of internal/external data set. */
10163
            WOLFSSL_MSG_EX("%s:\n\tinSet=%d, exSet=%d\n", msg, point->inSet,
10164
                point->exSet);
10165
            /* Get x-ordinate as a hex string and print. */
10166
            num = wolfSSL_BN_bn2hex(point->X);
10167
            WOLFSSL_MSG_EX("\tX = %s\n", num);
10168
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
10169
            /* Get x-ordinate as a hex string and print. */
10170
            num = wolfSSL_BN_bn2hex(point->Y);
10171
            WOLFSSL_MSG_EX("\tY = %s\n", num);
10172
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
10173
            /* Get z-ordinate as a hex string and print. */
10174
            num = wolfSSL_BN_bn2hex(point->Z);
10175
            WOLFSSL_MSG_EX("\tZ = %s\n", num);
10176
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
10177
        }
10178
    }
10179
#else
10180
    (void)msg;
10181
    (void)point;
10182
#endif
10183
}
10184
10185
/* Convert EC point to hex string that as either uncompressed or compressed.
10186
 *
10187
 * ECC point compression types were not included in selftest ecc.h
10188
 *
10189
 * @param [in] group  EC group for point.
10190
 * @param [in] point  EC point to encode.
10191
 * @param [in] form   Format of encoding. Valid values:
10192
 *                    POINT_CONVERSION_UNCOMPRESSED, POINT_CONVERSION_COMPRESSED
10193
 * @param [in] ctx    Context to use for BN operations. Unused.
10194
 * @return  Allocated hex string on success.
10195
 * @return  NULL on error.
10196
 */
10197
char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
10198
    const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BN_CTX* ctx)
10199
{
10200
    static const char* hexDigit = "0123456789ABCDEF";
10201
    char* hex = NULL;
10202
    int i;
10203
    int sz = 0;
10204
    int len = 0;
10205
    int err = 0;
10206
10207
    /* No BN operations performed. */
10208
    (void)ctx;
10209
10210
    /* Validate parameters. */
10211
    if ((group == NULL) || (point == NULL)) {
10212
        err = 1;
10213
    }
10214
    /* Get curve id expects a positive index. */
10215
    if ((!err) && (group->curve_idx < 0)) {
10216
        err = 1;
10217
    }
10218
10219
    if (!err) {
10220
        /* Get curve id to look up ordinate size. */
10221
        int id = wc_ecc_get_curve_id(group->curve_idx);
10222
        /* Get size of ordinate. */
10223
        if ((sz = wc_ecc_get_curve_size_from_id(id)) < 0) {
10224
            err = 1;
10225
        }
10226
    }
10227
    if (!err) {
10228
        /* <format byte> <x-ordinate> [<y-ordinate>] */
10229
        len = sz + 1;
10230
        if (form == WC_POINT_CONVERSION_UNCOMPRESSED) {
10231
            /* Include y ordinate when uncompressed. */
10232
            len += sz;
10233
        }
10234
10235
        /* Hex string: allocate 2 bytes to represent each byte plus 1 for '\0'.
10236
         */
10237
        hex = (char*)XMALLOC((size_t)(2 * len + 1), NULL, DYNAMIC_TYPE_ECC);
10238
        if (hex == NULL) {
10239
            err = 1;
10240
        }
10241
    }
10242
    if (!err) {
10243
        /* Make bytes all zeros to allow for ordinate values less than max size.
10244
         */
10245
        XMEMSET(hex, 0, (size_t)(2 * len + 1));
10246
10247
        /* Calculate offset as leading zeros not encoded. */
10248
        i = sz - mp_unsigned_bin_size((mp_int*)point->X->internal) + 1;
10249
        /* Put in x-ordinate after format byte. */
10250
        if (mp_to_unsigned_bin((mp_int*)point->X->internal, (byte*)(hex + i)) <
10251
                0) {
10252
            err = 1;
10253
        }
10254
    }
10255
    if (!err) {
10256
        if (form == WC_POINT_CONVERSION_COMPRESSED) {
10257
            /* Compressed format byte value dependent on whether y-ordinate is
10258
             * odd.
10259
             */
10260
            hex[0] = mp_isodd((mp_int*)point->Y->internal) ?
10261
                ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
10262
            /* No y-ordinate. */
10263
        }
10264
        else {
10265
            /* Put in uncompressed format byte. */
10266
            hex[0] = ECC_POINT_UNCOMP;
10267
            /* Calculate offset as leading zeros not encoded. */
10268
            i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal);
10269
            /* Put in y-ordinate after x-ordinate. */
10270
            if (mp_to_unsigned_bin((mp_int*)point->Y->internal,
10271
                    (byte*)(hex + i)) < 0) {
10272
                err = 1;
10273
            }
10274
        }
10275
    }
10276
    if (!err) {
10277
        /* Convert binary encoding to hex string. */
10278
        /* Start at end so as not to overwrite. */
10279
        for (i = len-1; i >= 0; i--) {
10280
            /* Get byte value and store has hex string. */
10281
            byte b = (byte)hex[i];
10282
            hex[i * 2 + 1] = hexDigit[b  & 0xf];
10283
            hex[i * 2    ] = hexDigit[b >>   4];
10284
        }
10285
        /* Memset put trailing zero or '\0' on end of string. */
10286
    }
10287
10288
    if (err && (hex != NULL)) {
10289
        /* Dispose of allocated data not being returned. */
10290
        XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
10291
        hex = NULL;
10292
    }
10293
    /* Return hex string encoding. */
10294
    return hex;
10295
}
10296
10297
static size_t hex_to_bytes(const char *hex, unsigned char *output, size_t sz)
10298
{
10299
    word32 i;
10300
    for (i = 0; i < sz; i++) {
10301
        signed char ch1, ch2;
10302
        ch1 = HexCharToByte(hex[i * 2]);
10303
        ch2 = HexCharToByte(hex[i * 2 + 1]);
10304
        if ((ch1 < 0) || (ch2 < 0)) {
10305
            WOLFSSL_MSG("hex_to_bytes: syntax error");
10306
            return 0;
10307
        }
10308
        output[i] = (unsigned char)((ch1 << 4) + ch2);
10309
    }
10310
    return sz;
10311
}
10312
10313
WOLFSSL_EC_POINT* wolfSSL_EC_POINT_hex2point(const WOLFSSL_EC_GROUP *group,
10314
            const char *hex, WOLFSSL_EC_POINT*p, WOLFSSL_BN_CTX *ctx)
10315
{
10316
    /* for uncompressed mode */
10317
    size_t str_sz;
10318
    WOLFSSL_BIGNUM *Gx  = NULL;
10319
    WOLFSSL_BIGNUM *Gy  = NULL;
10320
    char   strGx[MAX_ECC_BYTES * 2 + 1];
10321
10322
    /* for compressed mode */
10323
    int    key_sz;
10324
    byte   *octGx = (byte *)strGx; /* octGx[MAX_ECC_BYTES] */
10325
10326
    int p_alloc = 0;
10327
    int ret;
10328
10329
    WOLFSSL_ENTER("wolfSSL_EC_POINT_hex2point");
10330
10331
    if (group == NULL || hex == NULL || ctx == NULL)
10332
        return NULL;
10333
10334
    if (p == NULL) {
10335
        if ((p = wolfSSL_EC_POINT_new(group)) == NULL) {
10336
            WOLFSSL_MSG("wolfSSL_EC_POINT_new");
10337
            goto err;
10338
        }
10339
        p_alloc = 1;
10340
    }
10341
10342
    key_sz = (wolfSSL_EC_GROUP_get_degree(group) + 7) / 8;
10343
    if (hex[0] ==  '0' && hex[1] == '4') { /* uncompressed mode */
10344
        str_sz = (size_t)key_sz * 2;
10345
10346
        XMEMSET(strGx, 0x0, str_sz + 1);
10347
        XMEMCPY(strGx, hex + 2, str_sz);
10348
10349
        if (wolfSSL_BN_hex2bn(&Gx, strGx) == 0)
10350
            goto err;
10351
10352
        if (wolfSSL_BN_hex2bn(&Gy, hex + 2 + str_sz) == 0)
10353
            goto err;
10354
10355
        ret = wolfSSL_EC_POINT_set_affine_coordinates_GFp
10356
                                            (group, p, Gx, Gy, ctx);
10357
10358
        if (ret != WOLFSSL_SUCCESS) {
10359
            WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
10360
            goto err;
10361
        }
10362
    }
10363
    else if (hex[0] == '0' && (hex[1] == '2' || hex[1] == '3')) {
10364
        size_t sz = XSTRLEN(hex + 2) / 2;
10365
        /* compressed mode */
10366
        octGx[0] = ECC_POINT_COMP_ODD;
10367
        if (hex_to_bytes(hex + 2, octGx + 1, sz) != sz) {
10368
            goto err;
10369
        }
10370
        if (wolfSSL_ECPoint_d2i(octGx, (word32)key_sz + 1, group, p)
10371
                                            != WOLFSSL_SUCCESS) {
10372
            goto err;
10373
        }
10374
    }
10375
    else
10376
        goto err;
10377
10378
    wolfSSL_BN_free(Gx);
10379
    wolfSSL_BN_free(Gy);
10380
    return p;
10381
10382
err:
10383
    wolfSSL_BN_free(Gx);
10384
    wolfSSL_BN_free(Gy);
10385
    if (p_alloc) {
10386
        wolfSSL_EC_POINT_free(p);
10387
    }
10388
    return NULL;
10389
10390
}
10391
10392
/* Encode the EC point as an uncompressed point in DER.
10393
 *
10394
 * Return code compliant with OpenSSL.
10395
 * Not OpenSSL API.
10396
 *
10397
 * @param [in]      group  EC group point belongs to.
10398
 * @param [in]      point  EC point to encode.
10399
 * @param [out]     out    Buffer to encode into. May be NULL.
10400
 * @param [in, out] len    On in, length of buffer in bytes.
10401
 *                         On out, length of encoding in bytes.
10402
 * @return  1 on success.
10403
 * @return  0 on error.
10404
 */
10405
int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
10406
    const WOLFSSL_EC_POINT *point, unsigned char *out, unsigned int *len)
10407
{
10408
    int res = 1;
10409
10410
    WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
10411
10412
    /* Validate parameters. */
10413
    if ((group == NULL) || (point == NULL) || (len == NULL)) {
10414
        WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
10415
        res = 0;
10416
    }
10417
10418
    /* Ensure points internals are set up. */
10419
    if ((res == 1) && (ec_point_setup(point) != 1)) {
10420
        res = 0;
10421
    }
10422
10423
    /* Dump the point if encoding. */
10424
    if ((res == 1) && (out != NULL)) {
10425
        wolfSSL_EC_POINT_dump("i2d p", point);
10426
    }
10427
10428
    if (res == 1) {
10429
        /* DER encode point in uncompressed format. */
10430
        int ret = wc_ecc_export_point_der(group->curve_idx,
10431
            (ecc_point*)point->internal, out, len);
10432
        /* Check return. When out is NULL, return will be length only error. */
10433
        if ((ret != MP_OKAY) && ((out != NULL) ||
10434
                                 (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)))) {
10435
            WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
10436
            res = 0;
10437
        }
10438
    }
10439
10440
    return res;
10441
}
10442
10443
/* Decode the uncompressed point in DER into EC point.
10444
 *
10445
 * Return code compliant with OpenSSL.
10446
 * Not OpenSSL API.
10447
 *
10448
 * @param [in]      in     Buffer containing DER encoded point.
10449
 * @param [in]      len    Length of data in bytes.
10450
 * @param [in]      group  EC group associated with point.
10451
 * @param [in, out] point  EC point to set data into.
10452
 * @return  1 on success.
10453
 * @return  0 on error.
10454
 */
10455
int wolfSSL_ECPoint_d2i(const unsigned char *in, unsigned int len,
10456
    const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *point)
10457
{
10458
    int ret = 1;
10459
    WOLFSSL_BIGNUM* x = NULL;
10460
    WOLFSSL_BIGNUM* y = NULL;
10461
10462
    WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
10463
10464
    /* Validate parameters. */
10465
    if ((in == NULL) || (group == NULL) || (point == NULL) ||
10466
            (point->internal == NULL)) {
10467
        WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
10468
        ret = 0;
10469
    }
10470
10471
    if (ret == 1) {
10472
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10473
        /* Import point into internal EC point. */
10474
        if (wc_ecc_import_point_der_ex(in, len, group->curve_idx,
10475
                (ecc_point*)point->internal, 0) != MP_OKAY) {
10476
            WOLFSSL_MSG("wc_ecc_import_point_der_ex failed");
10477
            ret = 0;
10478
        }
10479
    #else
10480
        /* ECC_POINT_UNCOMP is not defined CAVP self test so use magic number */
10481
        if (in[0] == 0x04) {
10482
            /* Import point into internal EC point. */
10483
            if (wc_ecc_import_point_der((unsigned char *)in, len,
10484
                    group->curve_idx, (ecc_point*)point->internal) != MP_OKAY) {
10485
                WOLFSSL_MSG("wc_ecc_import_point_der failed");
10486
                ret = 0;
10487
            }
10488
        }
10489
        else {
10490
            WOLFSSL_MSG("Only uncompressed points supported with "
10491
                        "HAVE_SELFTEST");
10492
            ret = 0;
10493
        }
10494
    #endif
10495
    }
10496
10497
    if (ret == 1)
10498
        point->inSet = 1;
10499
10500
    /* Set new external point. */
10501
    if (ret == 1 && ec_point_external_set(point) != 1) {
10502
        WOLFSSL_MSG("ec_point_external_set failed");
10503
        ret = 0;
10504
    }
10505
10506
    if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) {
10507
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
10508
        x = wolfSSL_BN_new();
10509
        y = wolfSSL_BN_new();
10510
        if (x == NULL || y == NULL)
10511
            ret = 0;
10512
10513
        if (ret == 1 && wolfSSL_EC_POINT_get_affine_coordinates_GFp(group,
10514
                point, x, y, NULL) != 1) {
10515
            WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp failed");
10516
            ret = 0;
10517
        }
10518
10519
        /* wolfSSL_EC_POINT_set_affine_coordinates_GFp check that the point is
10520
         * on the curve. */
10521
        if (ret == 1 && wolfSSL_EC_POINT_set_affine_coordinates_GFp(group,
10522
                point, x, y, NULL) != 1) {
10523
            WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp failed");
10524
            ret = 0;
10525
        }
10526
#else
10527
        WOLFSSL_MSG("Importing non-affine point. This may cause issues in math "
10528
                    "operations later on.");
10529
#endif
10530
    }
10531
10532
    if (ret == 1) {
10533
        /* Dump new point. */
10534
        wolfSSL_EC_POINT_dump("d2i p", point);
10535
    }
10536
10537
    wolfSSL_BN_free(x);
10538
    wolfSSL_BN_free(y);
10539
10540
    return ret;
10541
}
10542
10543
/* Encode point as octet string.
10544
 *
10545
 * HYBRID not supported.
10546
 *
10547
 * @param [in]  group  EC group that point belongs to.
10548
 * @param [in]  point  EC point to encode.
10549
 * @param [in]  form   Format of encoding. Valid values:
10550
 *                     POINT_CONVERSION_UNCOMPRESSED,POINT_CONVERSION_COMPRESSED
10551
 * @param [out] buf    Buffer to write encoding into.
10552
 * @param [in]  len    Length of buffer.
10553
 * @param [in]  ctx    Context to use for BN operations. Unused.
10554
 * @return  Length of encoded data on success.
10555
 * @return  0 on error.
10556
 */
10557
size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group,
10558
   const WOLFSSL_EC_POINT *point, int form, byte *buf, size_t len,
10559
   WOLFSSL_BN_CTX *ctx)
10560
{
10561
    int err = 0;
10562
    word32 enc_len = (word32)len;
10563
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10564
    int compressed = ((form == WC_POINT_CONVERSION_COMPRESSED) ? 1 : 0);
10565
#endif /* !HAVE_SELFTEST */
10566
10567
    WOLFSSL_ENTER("wolfSSL_EC_POINT_point2oct");
10568
10569
    /* No BN operations performed. */
10570
    (void)ctx;
10571
10572
    /* Validate parameters. */
10573
    if ((group == NULL) || (point == NULL)) {
10574
        err = 1;
10575
    }
10576
10577
    /* Ensure points internals are set up. */
10578
    if ((!err) && (ec_point_setup(point) != 1)) {
10579
        err = 1;
10580
    }
10581
10582
    /* Special case when point is infinity. */
10583
    if ((!err) && wolfSSL_EC_POINT_is_at_infinity(group, point)) {
10584
        /* Encoding is a single octet: 0x00. */
10585
        enc_len = 1;
10586
        if (buf != NULL) {
10587
            /* Check whether buffer has space. */
10588
            if (len < 1) {
10589
                wolfSSL_ECerr(WOLFSSL_EC_F_EC_GFP_SIMPLE_POINT2OCT, BUFFER_E);
10590
                err = 1;
10591
            }
10592
            else {
10593
                /* Put in encoding of infinity. */
10594
                buf[0] = 0x00;
10595
            }
10596
        }
10597
    }
10598
    /* Not infinity. */
10599
    else if (!err) {
10600
        /* Validate format. */
10601
        if (form != WC_POINT_CONVERSION_UNCOMPRESSED
10602
        #ifndef HAVE_SELFTEST
10603
                && form != WC_POINT_CONVERSION_COMPRESSED
10604
        #endif /* !HAVE_SELFTEST */
10605
            ) {
10606
            WOLFSSL_MSG("Unsupported point form");
10607
            err = 1;
10608
        }
10609
10610
        if (!err) {
10611
            int ret;
10612
10613
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10614
            /* Encode as compressed or uncompressed. */
10615
            ret = wc_ecc_export_point_der_ex(group->curve_idx,
10616
                (ecc_point*)point->internal, buf, &enc_len, compressed);
10617
    #else
10618
            /* Encode uncompressed point in DER format. */
10619
            ret = wc_ecc_export_point_der(group->curve_idx,
10620
                (ecc_point*)point->internal, buf, &enc_len);
10621
    #endif /* !HAVE_SELFTEST */
10622
            /* Check return. When buf is NULL, return will be length only
10623
             * error.
10624
             */
10625
            if (ret != ((buf != NULL) ? MP_OKAY : WC_NO_ERR_TRACE(LENGTH_ONLY_E))) {
10626
                err = 1;
10627
            }
10628
        }
10629
    }
10630
10631
#if defined(DEBUG_WOLFSSL)
10632
    if (!err) {
10633
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_point2oct point", point);
10634
        WOLFSSL_MSG("\twolfSSL_EC_POINT_point2oct output:");
10635
        WOLFSSL_BUFFER(buf, enc_len);
10636
    }
10637
#endif
10638
10639
    /* On error, return encoding length of 0. */
10640
    if (err) {
10641
        enc_len = 0;
10642
    }
10643
    return (size_t)enc_len;
10644
}
10645
10646
10647
/* Convert octet string to EC point.
10648
 *
10649
 * @param [in]      group  EC group.
10650
 * @param [in, out] point  EC point to set data into.
10651
 * @param [in]      buf    Buffer holding octet string.
10652
 * @param [in]      len    Length of data in buffer in bytes.
10653
 * @param [in]      ctx    Context to use for BN operations. Unused.
10654
 */
10655
int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group,
10656
    WOLFSSL_EC_POINT *point, const unsigned char *buf, size_t len,
10657
    WOLFSSL_BN_CTX *ctx)
10658
{
10659
    int ret;
10660
10661
    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
10662
10663
    /* No BN operations performed. */
10664
    (void)ctx;
10665
10666
    /* Validate parameters. */
10667
    if ((group == NULL) || (point == NULL)) {
10668
        ret = 0;
10669
    }
10670
    else {
10671
        /* Decode DER encoding into EC point. */
10672
        ret = wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group,
10673
            point);
10674
    }
10675
10676
    return ret;
10677
}
10678
10679
/* Convert an EC point to a single BN.
10680
 *
10681
 * @param [in]      group  EC group.
10682
 * @param [in]      point  EC point.
10683
 * @param [in]      form   Format of encoding. Valid values:
10684
 *                         WC_POINT_CONVERSION_UNCOMPRESSED,
10685
 *                         WC_POINT_CONVERSION_COMPRESSED.
10686
 * @param [in, out] bn     BN to hold point value.
10687
 *                         When NULL a new BN is allocated otherwise this is
10688
 *                         returned on success.
10689
 * @param [in]      ctx    Context to use for BN operations. Unused.
10690
 * @return  BN object with point as a value on success.
10691
 * @return  NULL on error.
10692
 */
10693
WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP* group,
10694
    const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BIGNUM* bn,
10695
    WOLFSSL_BN_CTX* ctx)
10696
{
10697
    int err = 0;
10698
    size_t len = 0;
10699
    byte *buf = NULL;
10700
    WOLFSSL_BIGNUM *ret = NULL;
10701
10702
    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
10703
10704
    /* Validate parameters. */
10705
    if ((group == NULL) || (point == NULL)) {
10706
        err = 1;
10707
    }
10708
10709
    /* Calculate length of octet encoding. */
10710
    if ((!err) && ((len = wolfSSL_EC_POINT_point2oct(group, point, form, NULL,
10711
            0, ctx)) == 0)) {
10712
        err = 1;
10713
    }
10714
    /* Allocate buffer to hold octet encoding. */
10715
    if ((!err) && ((buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER)) ==
10716
            NULL)) {
10717
        WOLFSSL_MSG("malloc failed");
10718
        err = 1;
10719
    }
10720
    /* Encode EC point as an octet string. */
10721
    if ((!err) && (wolfSSL_EC_POINT_point2oct(group, point, form, buf, len,
10722
            ctx) != len)) {
10723
        err = 1;
10724
    }
10725
    /* Load BN with octet string data. */
10726
    if (!err) {
10727
        ret = wolfSSL_BN_bin2bn(buf, (int)len, bn);
10728
    }
10729
10730
    /* Dispose of any allocated data. */
10731
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10732
10733
    return ret;
10734
}
10735
10736
#if defined(USE_ECC_B_PARAM) && !defined(HAVE_SELFTEST) && \
10737
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10738
/* Check if EC point is on the the curve defined by the EC group.
10739
 *
10740
 * @param [in] group  EC group defining curve.
10741
 * @param [in] point  EC point to check.
10742
 * @param [in] ctx    Context to use for BN operations. Unused.
10743
 * @return  1 when point is on curve.
10744
 * @return  0 when point is not on curve or error.
10745
 */
10746
int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group,
10747
    const WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx)
10748
{
10749
    int err = 0;
10750
10751
    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_on_curve");
10752
10753
    /* No BN operations performed. */
10754
    (void)ctx;
10755
10756
    /* Validate parameters. */
10757
    if ((group == NULL) || (point == NULL)) {
10758
        WOLFSSL_MSG("Invalid arguments");
10759
        err = 1;
10760
    }
10761
10762
    /* Ensure internal EC point set. */
10763
    if ((!err) && (!point->inSet) && ec_point_internal_set(
10764
            (WOLFSSL_EC_POINT*)point) != 1) {
10765
        WOLFSSL_MSG("ec_point_internal_set error");
10766
        err = 1;
10767
    }
10768
10769
    /* Check point is on curve from group. */
10770
    if ((!err) && (wc_ecc_point_is_on_curve((ecc_point*)point->internal,
10771
            group->curve_idx) != MP_OKAY)) {
10772
        err = 1;
10773
    }
10774
10775
    /* Return boolean of on curve. No error means on curve. */
10776
    return !err;
10777
}
10778
#endif /* USE_ECC_B_PARAM && !HAVE_SELFTEST && !(FIPS_VERSION <= 2) */
10779
10780
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
10781
/* Convert Jacobian ordinates to affine.
10782
 *
10783
 * @param [in]      group  EC group.
10784
 * @param [in]      point  EC point to get coordinates from.
10785
 * @return  1 on success.
10786
 * @return  0 on error.
10787
 */
10788
int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group,
10789
    WOLFSSL_EC_POINT *point)
10790
{
10791
    int err = 0;
10792
    mp_digit mp = 0;
10793
#ifdef WOLFSSL_SMALL_STACK
10794
    mp_int* modulus;
10795
#else
10796
    mp_int modulus[1];
10797
#endif
10798
10799
#ifdef WOLFSSL_SMALL_STACK
10800
    /* Allocate memory for curve's prime modulus. */
10801
    modulus = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10802
    if (modulus == NULL) {
10803
        err = 1;
10804
    }
10805
#endif
10806
    /* Initialize the MP integer. */
10807
    if ((!err) && (mp_init(modulus) != MP_OKAY)) {
10808
        WOLFSSL_MSG("mp_init failed");
10809
        err = 1;
10810
    }
10811
10812
    if (!err) {
10813
        /* Get the modulus from the hex string in the EC curve set. */
10814
        if (mp_read_radix(modulus, ecc_sets[group->curve_idx].prime,
10815
                MP_RADIX_HEX) != MP_OKAY) {
10816
            WOLFSSL_MSG("mp_read_radix failed");
10817
            err = 1;
10818
        }
10819
        /* Get Montgomery multiplier for the modulus as ordinates in
10820
         * Montgomery form.
10821
         */
10822
        if ((!err) && (mp_montgomery_setup(modulus, &mp) != MP_OKAY)) {
10823
            WOLFSSL_MSG("mp_montgomery_setup failed");
10824
            err = 1;
10825
        }
10826
        /* Map internal EC point from Jacobian to affine. */
10827
        if ((!err) && (ecc_map((ecc_point*)point->internal, modulus, mp) !=
10828
                MP_OKAY)) {
10829
            WOLFSSL_MSG("ecc_map failed");
10830
            err = 1;
10831
        }
10832
        /* Set new ordinates into external EC point. */
10833
        if ((!err) && (ec_point_external_set((WOLFSSL_EC_POINT *)point) != 1)) {
10834
            WOLFSSL_MSG("ec_point_external_set failed");
10835
            err = 1;
10836
        }
10837
10838
        point->exSet = !err;
10839
        mp_clear(modulus);
10840
    }
10841
10842
#ifdef WOLFSSL_SMALL_STACK
10843
    XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT);
10844
#endif
10845
10846
    return err;
10847
}
10848
10849
/* Get the affine coordinates of the EC point on a Prime curve.
10850
 *
10851
 * When z-ordinate is not one then coordinates are Jacobian and need to be
10852
 * converted to affine before storing in BNs.
10853
 *
10854
 * Return code compliant with OpenSSL.
10855
 *
10856
 * TODO: OpenSSL doesn't change point when Jacobian. Do the same?
10857
 *
10858
 * @param [in]      group  EC group.
10859
 * @param [in]      point  EC point to get coordinates from.
10860
 * @param [in, out] x      BN to hold x-ordinate.
10861
 * @param [in, out] y      BN to hold y-ordinate.
10862
 * @param [in]      ctx    Context to use for BN operations. Unused.
10863
 * @return  1 on success.
10864
 * @return  0 on error.
10865
 */
10866
int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
10867
    const WOLFSSL_EC_POINT* point, WOLFSSL_BIGNUM* x, WOLFSSL_BIGNUM* y,
10868
    WOLFSSL_BN_CTX* ctx)
10869
{
10870
    int ret = 1;
10871
10872
    /* BN operations don't need context. */
10873
    (void)ctx;
10874
10875
    WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
10876
10877
    /* Validate parameters. */
10878
    if ((group == NULL) || (point == NULL) || (point->internal == NULL) ||
10879
            (x == NULL) || (y == NULL)) {
10880
        WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
10881
        ret = 0;
10882
    }
10883
    /* Don't return point at infinity. */
10884
    if ((ret == 1) && wolfSSL_EC_POINT_is_at_infinity(group, point)) {
10885
        ret = 0;
10886
    }
10887
10888
    /* Ensure internal EC point has values of external EC point. */
10889
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
10890
        ret = 0;
10891
    }
10892
10893
    /* Check whether ordinates are in Jacobian form. */
10894
    if ((ret == 1) && (!wolfSSL_BN_is_one(point->Z))) {
10895
        /* Convert from Jacobian to affine. */
10896
        if (ec_point_convert_to_affine(group, (WOLFSSL_EC_POINT*)point) == 1) {
10897
            ret = 0;
10898
        }
10899
    }
10900
10901
    /* Copy the externally set x and y ordinates. */
10902
    if ((ret == 1) && (wolfSSL_BN_copy(x, point->X) == NULL)) {
10903
        ret = 0;
10904
    }
10905
    if ((ret == 1) && (wolfSSL_BN_copy(y, point->Y) == NULL)) {
10906
        ret = 0;
10907
    }
10908
10909
    return ret;
10910
}
10911
#endif /* !WOLFSSL_SP_MATH && !WOLF_CRYPTO_CB_ONLY_ECC */
10912
10913
/* Sets the affine coordinates that belong on a prime curve.
10914
 *
10915
 * @param [in]      group  EC group.
10916
 * @param [in, out] point  EC point to set coordinates into.
10917
 * @param [in]      x      BN holding x-ordinate.
10918
 * @param [in]      y      BN holding y-ordinate.
10919
 * @param [in]      ctx    Context to use for BN operations. Unused.
10920
 * @return  1 on success.
10921
 * @return  0 on error.
10922
 */
10923
int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
10924
    WOLFSSL_EC_POINT* point, const WOLFSSL_BIGNUM* x, const WOLFSSL_BIGNUM* y,
10925
    WOLFSSL_BN_CTX* ctx)
10926
{
10927
    int ret = 1;
10928
10929
    /* BN operations don't need context. */
10930
    (void)ctx;
10931
10932
    WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
10933
10934
    /* Validate parameters. */
10935
    if ((group == NULL) || (point == NULL) || (point->internal == NULL) ||
10936
            (x == NULL) || (y == NULL)) {
10937
        WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error");
10938
        ret = 0;
10939
    }
10940
10941
    /* Ensure we have a object for x-ordinate. */
10942
    if ((ret == 1) && (point->X == NULL) &&
10943
            ((point->X = wolfSSL_BN_new()) == NULL)) {
10944
        WOLFSSL_MSG("wolfSSL_BN_new failed");
10945
        ret = 0;
10946
    }
10947
    /* Ensure we have a object for y-ordinate. */
10948
    if ((ret == 1) && (point->Y == NULL) &&
10949
            ((point->Y = wolfSSL_BN_new()) == NULL)) {
10950
        WOLFSSL_MSG("wolfSSL_BN_new failed");
10951
        ret = 0;
10952
    }
10953
    /* Ensure we have a object for z-ordinate. */
10954
    if ((ret == 1) && (point->Z == NULL) &&
10955
            ((point->Z = wolfSSL_BN_new()) == NULL)) {
10956
        WOLFSSL_MSG("wolfSSL_BN_new failed");
10957
        ret = 0;
10958
    }
10959
10960
    /* Copy the x-ordinate. */
10961
    if ((ret == 1) && ((wolfSSL_BN_copy(point->X, x)) == NULL)) {
10962
        WOLFSSL_MSG("wolfSSL_BN_copy failed");
10963
        ret = 0;
10964
    }
10965
    /* Copy the y-ordinate. */
10966
    if ((ret == 1) && ((wolfSSL_BN_copy(point->Y, y)) == NULL)) {
10967
        WOLFSSL_MSG("wolfSSL_BN_copy failed");
10968
        ret = 0;
10969
    }
10970
    /* z-ordinate is one for affine coordinates. */
10971
    if ((ret == 1) && ((wolfSSL_BN_one(point->Z)) == 0)) {
10972
        WOLFSSL_MSG("wolfSSL_BN_one failed");
10973
        ret = 0;
10974
    }
10975
10976
    /* Copy the new point data to internal object. */
10977
    if ((ret == 1) && (ec_point_internal_set((WOLFSSL_EC_POINT *)point) != 1)) {
10978
        WOLFSSL_MSG("ec_point_internal_set failed");
10979
        ret = 0;
10980
    }
10981
10982
#if defined(USE_ECC_B_PARAM) && !defined(HAVE_SELFTEST) && \
10983
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10984
    /* Check that the point is valid. */
10985
    if ((ret == 1) && (wolfSSL_EC_POINT_is_on_curve(group,
10986
            (WOLFSSL_EC_POINT *)point, ctx) != 1)) {
10987
        WOLFSSL_MSG("EC_POINT_is_on_curve failed");
10988
        ret = 0;
10989
    }
10990
#endif
10991
10992
    return ret;
10993
}
10994
10995
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
10996
    !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
10997
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
10998
/* Add two points on the same together.
10999
 *
11000
 * @param [in]  curveIdx  Index of curve in ecc_set.
11001
 * @param [out] r         Result point.
11002
 * @param [in]  p1        First point to add.
11003
 * @param [in]  p2        Second point to add.
11004
 * @return  1 on success.
11005
 * @return  0 on error.
11006
 */
11007
static int wolfssl_ec_point_add(int curveIdx, ecc_point* r, ecc_point* p1,
11008
    ecc_point* p2)
11009
{
11010
    int ret = 1;
11011
#ifdef WOLFSSL_SMALL_STACK
11012
    mp_int* a = NULL;
11013
    mp_int* prime = NULL;
11014
    mp_int* mu = NULL;
11015
#else
11016
    mp_int a[1];
11017
    mp_int prime[1];
11018
    mp_int mu[1];
11019
#endif
11020
    mp_digit mp = 0;
11021
    ecc_point* montP1 = NULL;
11022
    ecc_point* montP2 = NULL;
11023
11024
#ifdef WOLFSSL_SMALL_STACK
11025
    if (ret == 1) {
11026
        /* Allocate memory for curve parameter: a. */
11027
        a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11028
        if (a == NULL) {
11029
            WOLFSSL_MSG("Failed to allocate memory for mp_int a");
11030
            ret = 0;
11031
        }
11032
    }
11033
    if (ret == 1) {
11034
        /* Allocate memory for curve parameter: prime. */
11035
        prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11036
        if (prime == NULL) {
11037
            WOLFSSL_MSG("Failed to allocate memory for mp_int prime");
11038
            ret = 0;
11039
        }
11040
    }
11041
    if (ret == 1) {
11042
        /* Allocate memory for mu (Montgomery normalizer). */
11043
        mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11044
        if (mu == NULL) {
11045
            WOLFSSL_MSG("Failed to allocate memory for mp_int mu");
11046
            ret = 0;
11047
        }
11048
    }
11049
    if (ret == 1) {
11050
        /* Zero out all MP int data in case initialization fails. */
11051
        XMEMSET(a, 0, sizeof(mp_int));
11052
        XMEMSET(prime, 0, sizeof(mp_int));
11053
        XMEMSET(mu, 0, sizeof(mp_int));
11054
    }
11055
#endif
11056
11057
    /* Initialize the MP ints. */
11058
    if ((ret == 1) && (mp_init_multi(prime, a, mu, NULL, NULL, NULL) !=
11059
            MP_OKAY)) {
11060
        WOLFSSL_MSG("mp_init_multi error");
11061
        ret = 0;
11062
    }
11063
11064
    /* Read the curve parameter: a. */
11065
    if ((ret == 1) && (mp_read_radix(a, ecc_sets[curveIdx].Af, MP_RADIX_HEX) !=
11066
            MP_OKAY)) {
11067
        WOLFSSL_MSG("mp_read_radix a error");
11068
        ret = 0;
11069
    }
11070
11071
    /* Read the curve parameter: prime. */
11072
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
11073
            MP_RADIX_HEX) != MP_OKAY)) {
11074
        WOLFSSL_MSG("mp_read_radix prime error");
11075
        ret = 0;
11076
    }
11077
11078
    /* Calculate the Montgomery product. */
11079
    if ((ret == 1) && (mp_montgomery_setup(prime, &mp) != MP_OKAY)) {
11080
        WOLFSSL_MSG("mp_montgomery_setup nqm error");
11081
        ret = 0;
11082
    }
11083
11084
    /* TODO: use the heap filed of one of the points? */
11085
    /* Allocate new points to hold the Montgomery form values. */
11086
    if ((ret == 1) && (((montP1 = wc_ecc_new_point_h(NULL)) == NULL) ||
11087
            ((montP2 = wc_ecc_new_point_h(NULL)) == NULL))) {
11088
        WOLFSSL_MSG("wc_ecc_new_point_h nqm error");
11089
        ret = 0;
11090
    }
11091
11092
    /* Calculate the Montgomery normalizer. */
11093
    if ((ret == 1) && (mp_montgomery_calc_normalization(mu, prime) !=
11094
            MP_OKAY)) {
11095
        WOLFSSL_MSG("mp_montgomery_calc_normalization error");
11096
        ret = 0;
11097
    }
11098
11099
    /* Convert to Montgomery form. */
11100
    if ((ret == 1) && (mp_cmp_d(mu, 1) == MP_EQ)) {
11101
        /* Copy the points if the normalizer is 1.  */
11102
        if ((wc_ecc_copy_point(p1, montP1) != MP_OKAY) ||
11103
                (wc_ecc_copy_point(p2, montP2) != MP_OKAY)) {
11104
            WOLFSSL_MSG("wc_ecc_copy_point error");
11105
            ret = 0;
11106
        }
11107
    }
11108
    else if (ret == 1) {
11109
        /* Multiply each ordinate by the Montgomery normalizer.  */
11110
        if ((mp_mulmod(p1->x, mu, prime, montP1->x) != MP_OKAY) ||
11111
                (mp_mulmod(p1->y, mu, prime, montP1->y) != MP_OKAY) ||
11112
                (mp_mulmod(p1->z, mu, prime, montP1->z) != MP_OKAY)) {
11113
            WOLFSSL_MSG("mp_mulmod error");
11114
            ret = 0;
11115
        }
11116
        /* Multiply each ordinate by the Montgomery normalizer.  */
11117
        if ((mp_mulmod(p2->x, mu, prime, montP2->x) != MP_OKAY) ||
11118
                (mp_mulmod(p2->y, mu, prime, montP2->y) != MP_OKAY) ||
11119
                (mp_mulmod(p2->z, mu, prime, montP2->z) != MP_OKAY)) {
11120
            WOLFSSL_MSG("mp_mulmod error");
11121
            ret = 0;
11122
        }
11123
    }
11124
11125
    /* Perform point addition with internal EC point objects - Jacobian form
11126
     * result.
11127
     */
11128
    if ((ret == 1) && (ecc_projective_add_point(montP1, montP2, r, a, prime,
11129
            mp) != MP_OKAY)) {
11130
        WOLFSSL_MSG("ecc_projective_add_point error");
11131
        ret = 0;
11132
    }
11133
11134
    /* Map point back to affine coordinates. Converts from Montogomery form. */
11135
    if ((ret == 1) && (ecc_map(r, prime, mp) != MP_OKAY)) {
11136
        WOLFSSL_MSG("ecc_map error");
11137
        ret = 0;
11138
    }
11139
11140
    /* Dispose of allocated memory. */
11141
    mp_clear(a);
11142
    mp_clear(prime);
11143
    mp_clear(mu);
11144
    wc_ecc_del_point_h(montP1, NULL);
11145
    wc_ecc_del_point_h(montP2, NULL);
11146
#ifdef WOLFSSL_SMALL_STACK
11147
    XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
11148
    XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT);
11149
    XFREE(mu, NULL, DYNAMIC_TYPE_BIGINT);
11150
#endif
11151
    return ret;
11152
}
11153
11154
/* Add two points on the same curve together.
11155
 *
11156
 * @param [in]  group  EC group.
11157
 * @param [out] r      EC point that is result of point addition.
11158
 * @param [in]  p1     First EC point to add.
11159
 * @param [in]  p2     Second EC point to add.
11160
 * @param [in]  ctx    Context to use for BN operations. Unused.
11161
 * @return  1 on success.
11162
 * @return  0 on error.
11163
 */
11164
int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP* group, WOLFSSL_EC_POINT* r,
11165
    const WOLFSSL_EC_POINT* p1, const WOLFSSL_EC_POINT* p2, WOLFSSL_BN_CTX* ctx)
11166
{
11167
    int ret = 1;
11168
11169
    /* No BN operations performed. */
11170
    (void)ctx;
11171
11172
    /* Validate parameters. */
11173
    if ((group == NULL) || (r == NULL) || (p1 == NULL) || (p2 == NULL)) {
11174
        WOLFSSL_MSG("wolfSSL_EC_POINT_add error");
11175
        ret = 0;
11176
    }
11177
11178
    /* Ensure the internal objects of the EC points are setup. */
11179
    if ((ret == 1) && ((ec_point_setup(r) != 1) || (ec_point_setup(p1) != 1) ||
11180
            (ec_point_setup(p2) != 1))) {
11181
        WOLFSSL_MSG("ec_point_setup error");
11182
        ret = 0;
11183
    }
11184
11185
#ifdef DEBUG_WOLFSSL
11186
    if (ret == 1) {
11187
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
11188
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
11189
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
11190
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p1", p1);
11191
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p2", p2);
11192
        if (curve != NULL)
11193
            WOLFSSL_MSG_EX("curve name: %s", curve);
11194
        if (nistName != NULL)
11195
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
11196
    }
11197
#endif
11198
11199
    if (ret == 1) {
11200
        /* Add points using wolfCrypt objects. */
11201
        ret = wolfssl_ec_point_add(group->curve_idx, (ecc_point*)r->internal,
11202
            (ecc_point*)p1->internal, (ecc_point*)p2->internal);
11203
    }
11204
11205
    /* Copy internal EC point values out to external EC point. */
11206
    if ((ret == 1) && (ec_point_external_set(r) != 1)) {
11207
        WOLFSSL_MSG("ec_point_external_set error");
11208
        ret = 0;
11209
    }
11210
11211
#ifdef DEBUG_WOLFSSL
11212
    if (ret == 1) {
11213
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add result", r);
11214
    }
11215
#endif
11216
11217
    return ret;
11218
}
11219
11220
/* Sum the scalar multiplications of the base point and n, and q and m.
11221
 *
11222
 * r = base point * n + q * m
11223
 *
11224
 * @param [out] r      EC point that is result of operation.
11225
 * @param [in]  b      Base point of curve.
11226
 * @param [in]  n      Scalar to multiply by base point.
11227
 * @param [in]  q      EC point to be scalar multiplied.
11228
 * @param [in]  m      Scalar to multiply q by.
11229
 * @param [in]  a      Parameter A of curve.
11230
 * @param [in]  prime  Prime (modulus) of curve.
11231
 * @return  1 on success.
11232
 * @return  0 on error.
11233
 */
11234
static int ec_mul2add(ecc_point* r, ecc_point* b, mp_int* n, ecc_point* q,
11235
    mp_int* m, mp_int* a, mp_int* prime)
11236
{
11237
    int ret = 1;
11238
#if defined(ECC_SHAMIR) && !defined(WOLFSSL_KCAPI_ECC)
11239
    if (ecc_mul2add(b, n, q, m, r, a, prime, NULL) != MP_OKAY) {
11240
        WOLFSSL_MSG("ecc_mul2add error");
11241
        ret = 0;
11242
    }
11243
#else
11244
    ecc_point* tmp = NULL;
11245
    mp_digit mp = 0;
11246
11247
    /* Calculate Montgomery product. */
11248
    if (mp_montgomery_setup(prime, &mp) != MP_OKAY) {
11249
        WOLFSSL_MSG("mp_montgomery_setup nqm error");
11250
        ret = 0;
11251
    }
11252
    /* Create temporary point to hold: q * m */
11253
    if ((ret == 1) && ((tmp = wc_ecc_new_point()) == NULL)) {
11254
        WOLFSSL_MSG("wolfSSL_EC_POINT_new nqm error");
11255
        ret = 0;
11256
    }
11257
    /* r = base point * n */
11258
    if ((ret == 1) && (wc_ecc_mulmod(n, b, r, a, prime, 0) !=
11259
            MP_OKAY)) {
11260
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
11261
        ret = 0;
11262
    }
11263
    /* tmp = q * m */
11264
    if ((ret == 1) && (wc_ecc_mulmod(m, q, tmp, a, prime, 0) != MP_OKAY)) {
11265
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
11266
        ret = 0;
11267
    }
11268
    /* r = r + tmp */
11269
    if ((ret == 1) && (ecc_projective_add_point(tmp, r, r, a, prime, mp) !=
11270
            MP_OKAY)) {
11271
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
11272
        ret = 0;
11273
    }
11274
    /* Map point back to affine coordinates. Converts from Montogomery
11275
     * form. */
11276
    if ((ret == 1) && (ecc_map(r, prime, mp) != MP_OKAY)) {
11277
        WOLFSSL_MSG("ecc_map nqm error");
11278
        ret = 0;
11279
    }
11280
11281
    /* Dispose of allocated temporary point. */
11282
    wc_ecc_del_point(tmp);
11283
#endif
11284
11285
    return ret;
11286
}
11287
11288
/* Sum the scalar multiplications of the base point and n, and q and m.
11289
 *
11290
 * r = base point * n + q * m
11291
 *
11292
 * @param [in]  curveIdx  Index of curve in ecc_set.
11293
 * @param [out] r         EC point that is result of operation.
11294
 * @param [in]  n         Scalar to multiply by base point. May be NULL.
11295
 * @param [in]  q         EC point to be scalar multiplied. May be NULL.
11296
 * @param [in]  m         Scalar to multiply q by. May be NULL.
11297
 * @return  1 on success.
11298
 * @return  0 on error.
11299
 */
11300
static int wolfssl_ec_point_mul(int curveIdx, ecc_point* r, mp_int* n,
11301
    ecc_point* q, mp_int* m)
11302
{
11303
    int ret = 1;
11304
#ifdef WOLFSSL_SMALL_STACK
11305
    mp_int* a = NULL;
11306
    mp_int* prime = NULL;
11307
#else
11308
    mp_int a[1], prime[1];
11309
#endif
11310
11311
#ifdef WOLFSSL_SMALL_STACK
11312
    /* Allocate MP integer for curve parameter: a. */
11313
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11314
    if (a == NULL) {
11315
        ret = 0;
11316
    }
11317
    if (ret == 1) {
11318
        /* Allocate MP integer for curve parameter: prime. */
11319
        prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11320
        if (prime == NULL)  {
11321
            ret = 0;
11322
        }
11323
    }
11324
#endif
11325
11326
    /* Initialize the MP ints. */
11327
    if ((ret == 1) && (mp_init_multi(prime, a, NULL, NULL, NULL, NULL) !=
11328
             MP_OKAY)) {
11329
        WOLFSSL_MSG("mp_init_multi error");
11330
        ret = 0;
11331
    }
11332
11333
    /* Read the curve parameter: prime. */
11334
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
11335
            MP_RADIX_HEX) != MP_OKAY)) {
11336
        WOLFSSL_MSG("mp_read_radix prime error");
11337
        ret = 0;
11338
    }
11339
11340
    /* Read the curve parameter: a. */
11341
    if ((ret == 1) && (mp_read_radix(a, ecc_sets[curveIdx].Af,
11342
            MP_RADIX_HEX) != MP_OKAY)) {
11343
        WOLFSSL_MSG("mp_read_radix a error");
11344
        ret = 0;
11345
    }
11346
11347
    if ((ret == 1) && (n != NULL)) {
11348
        /* Get generator - base point. */
11349
    #if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
11350
        if ((ret == 1) && (wc_ecc_get_generator(r, curveIdx) != MP_OKAY)) {
11351
            WOLFSSL_MSG("wc_ecc_get_generator error");
11352
            ret = 0;
11353
        }
11354
    #else
11355
        /* wc_ecc_get_generator is not defined in the FIPS v2 module. */
11356
        /* Read generator (base point) x-ordinate. */
11357
        if ((ret == 1) && (mp_read_radix(r->x, ecc_sets[curveIdx].Gx,
11358
                MP_RADIX_HEX) != MP_OKAY)) {
11359
            WOLFSSL_MSG("mp_read_radix Gx error");
11360
            ret = 0;
11361
        }
11362
        /* Read generator (base point) y-ordinate. */
11363
        if ((ret == 1) && (mp_read_radix(r->y, ecc_sets[curveIdx].Gy,
11364
                MP_RADIX_HEX) != MP_OKAY)) {
11365
            WOLFSSL_MSG("mp_read_radix Gy error");
11366
            ret = 0;
11367
        }
11368
        /* z-ordinate is one as point is affine. */
11369
        if ((ret == 1) && (mp_set(r->z, 1) != MP_OKAY)) {
11370
            WOLFSSL_MSG("mp_set Gz error");
11371
            ret = 0;
11372
        }
11373
    #endif /* NOPT_FIPS_VERSION == 2 */
11374
    }
11375
11376
    if ((ret == 1) && (n != NULL) && (q != NULL) && (m != NULL)) {
11377
        /* r = base point * n + q * m */
11378
        ret = ec_mul2add(r, r, n, q, m, a, prime);
11379
    }
11380
    /* Not all values present, see if we are only doing base point * n. */
11381
    else if ((ret == 1) && (n != NULL)) {
11382
        /* r = base point * n */
11383
        if (wc_ecc_mulmod(n, r, r, a, prime, 1) != MP_OKAY) {
11384
            WOLFSSL_MSG("wc_ecc_mulmod gn error");
11385
            ret = 0;
11386
        }
11387
    }
11388
    /* Not all values present, see if we are only doing q * m. */
11389
    else if ((ret == 1) && (q != NULL) && (m != NULL)) {
11390
        /* r = q * m */
11391
        if (wc_ecc_mulmod(m, q, r, a, prime, 1) != MP_OKAY) {
11392
            WOLFSSL_MSG("wc_ecc_mulmod qm error");
11393
            ret = 0;
11394
        }
11395
    }
11396
    /* No values to use. */
11397
    else if (ret == 1) {
11398
        /* Set result to infinity as no values passed in. */
11399
        mp_zero(r->x);
11400
        mp_zero(r->y);
11401
        mp_zero(r->z);
11402
    }
11403
11404
    mp_clear(a);
11405
    mp_clear(prime);
11406
#ifdef WOLFSSL_SMALL_STACK
11407
    XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
11408
    XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT);
11409
#endif
11410
    return ret;
11411
}
11412
11413
/* Sum the scalar multiplications of the base point and n, and q and m.
11414
 *
11415
 * r = base point * n + q * m
11416
 *
11417
 * Return code compliant with OpenSSL.
11418
 *
11419
 * @param [in]  group  EC group.
11420
 * @param [out] r      EC point that is result of operation.
11421
 * @param [in]  n      Scalar to multiply by base point. May be NULL.
11422
 * @param [in]  q      EC point to be scalar multiplied. May be NULL.
11423
 * @param [in]  m      Scalar to multiply q by. May be NULL.
11424
 * @param [in]  ctx    Context to use for BN operations. Unused.
11425
 * @return  1 on success.
11426
 * @return  0 on error.
11427
 */
11428
int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
11429
    const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m,
11430
    WOLFSSL_BN_CTX *ctx)
11431
{
11432
    int ret = 1;
11433
11434
    /* No BN operations performed. */
11435
    (void)ctx;
11436
11437
    WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
11438
11439
    /* Validate parameters. */
11440
    if ((group == NULL) || (r == NULL)) {
11441
        WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
11442
        ret = 0;
11443
    }
11444
11445
    /* Ensure the internal representation of the EC point q is setup. */
11446
    if ((ret == 1) && (q != NULL) && (ec_point_setup(q) != 1)) {
11447
        WOLFSSL_MSG("ec_point_setup error");
11448
        ret = 0;
11449
    }
11450
11451
#ifdef DEBUG_WOLFSSL
11452
    if (ret == 1) {
11453
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
11454
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
11455
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
11456
        char* num;
11457
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul input q", q);
11458
        num = wolfSSL_BN_bn2hex(n);
11459
        WOLFSSL_MSG_EX("\tn = %s", num);
11460
        XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
11461
        num = wolfSSL_BN_bn2hex(m);
11462
        WOLFSSL_MSG_EX("\tm = %s", num);
11463
        XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
11464
        if (curve != NULL)
11465
            WOLFSSL_MSG_EX("curve name: %s", curve);
11466
        if (nistName != NULL)
11467
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
11468
    }
11469
#endif
11470
11471
    if (ret == 1) {
11472
        mp_int* ni = (n != NULL) ? (mp_int*)n->internal : NULL;
11473
        ecc_point* qi = (q != NULL) ? (ecc_point*)q->internal : NULL;
11474
        mp_int* mi = (m != NULL) ? (mp_int*)m->internal : NULL;
11475
11476
        /* Perform multiplication with wolfCrypt objects. */
11477
        ret = wolfssl_ec_point_mul(group->curve_idx, (ecc_point*)r->internal,
11478
            ni, qi, mi);
11479
    }
11480
11481
    /* Only on success is the internal point guaranteed to be set. */
11482
    if (r != NULL) {
11483
        r->inSet = (ret == 1);
11484
    }
11485
    /* Copy internal EC point values out to external EC point. */
11486
    if ((ret == 1) && (ec_point_external_set(r) != 1)) {
11487
        WOLFSSL_MSG("ec_point_external_set error");
11488
        ret = 0;
11489
    }
11490
11491
#ifdef DEBUG_WOLFSSL
11492
    if (ret == 1) {
11493
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul result", r);
11494
    }
11495
#endif
11496
11497
    return ret;
11498
}
11499
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !HAVE_SELFTEST &&
11500
        * !WOLFSSL_SP_MATH */
11501
11502
/* Invert the point on the curve.
11503
 * (x, y) -> (x, -y) = (x, (prime - y) % prime)
11504
 *
11505
 * @param [in]      curveIdx  Index of curve in ecc_set.
11506
 * @param [in, out] point     EC point to invert.
11507
 * @return  1 on success.
11508
 * @return  0 on error.
11509
 */
11510
static int wolfssl_ec_point_invert(int curveIdx, ecc_point* point)
11511
{
11512
    int ret = 1;
11513
#ifdef WOLFSSL_SMALL_STACK
11514
    mp_int* prime = NULL;
11515
#else
11516
    mp_int prime[1];
11517
#endif
11518
11519
#ifdef WOLFSSL_SMALL_STACK
11520
    /* Allocate memory for an MP int to hold the prime of the curve. */
11521
    prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11522
    if (prime == NULL) {
11523
        ret = 0;
11524
    }
11525
#endif
11526
11527
    /* Initialize MP int. */
11528
    if ((ret == 1) && (mp_init(prime) != MP_OKAY)) {
11529
        WOLFSSL_MSG("mp_init_multi error");
11530
        ret = 0;
11531
    }
11532
11533
    /* Read the curve parameter: prime. */
11534
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
11535
            MP_RADIX_HEX) != MP_OKAY)) {
11536
        WOLFSSL_MSG("mp_read_radix prime error");
11537
        ret = 0;
11538
    }
11539
11540
    /* y = (prime - y) mod prime. */
11541
    if ((ret == 1) && (!mp_iszero(point->y)) && (mp_sub(prime, point->y,
11542
            point->y) != MP_OKAY)) {
11543
        WOLFSSL_MSG("mp_sub error");
11544
        ret = 0;
11545
    }
11546
11547
    /* Dispose of memory associated with MP. */
11548
    mp_free(prime);
11549
#ifdef WOLFSSL_SMALL_STACK
11550
    /* Dispose of dynamically allocated temporaries. */
11551
    XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT);
11552
#endif
11553
    return ret;
11554
}
11555
11556
/* Invert the point on the curve.
11557
 * (x, y) -> (x, -y) = (x, (prime - y) % prime)
11558
 *
11559
 * @param [in]      group  EC group.
11560
 * @param [in, out] point  EC point to invert.
11561
 * @param [in]      ctx    Context to use for BN operations. Unused.
11562
 * @return  1 on success.
11563
 * @return  0 on error.
11564
 */
11565
int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group,
11566
    WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx)
11567
{
11568
    int ret = 1;
11569
11570
    /* No BN operations performed. */
11571
    (void)ctx;
11572
11573
    WOLFSSL_ENTER("wolfSSL_EC_POINT_invert");
11574
11575
    /* Validate parameters. */
11576
    if ((group == NULL) || (point == NULL) || (point->internal == NULL)) {
11577
        ret = 0;
11578
    }
11579
11580
    /* Ensure internal representation of point is setup. */
11581
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
11582
        ret = 0;
11583
    }
11584
11585
#ifdef DEBUG_WOLFSSL
11586
    if (ret == 1) {
11587
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
11588
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
11589
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
11590
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert input", point);
11591
        if (curve != NULL)
11592
            WOLFSSL_MSG_EX("curve name: %s", curve);
11593
        if (nistName != NULL)
11594
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
11595
11596
    }
11597
#endif
11598
11599
    if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) {
11600
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
11601
        if (ec_point_convert_to_affine(group, point) != 0)
11602
            ret = 0;
11603
#else
11604
        WOLFSSL_MSG("wolfSSL_EC_POINT_invert called on non-affine point");
11605
        ret = 0;
11606
#endif
11607
    }
11608
11609
    if (ret == 1) {
11610
        /* Perform inversion using wolfCrypt objects. */
11611
        ret = wolfssl_ec_point_invert(group->curve_idx,
11612
            (ecc_point*)point->internal);
11613
    }
11614
11615
    /* Set the external EC point representation based on internal. */
11616
    if ((ret == 1) && (ec_point_external_set(point) != 1)) {
11617
        WOLFSSL_MSG("ec_point_external_set error");
11618
        ret = 0;
11619
    }
11620
11621
#ifdef DEBUG_WOLFSSL
11622
    if (ret == 1) {
11623
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert result", point);
11624
    }
11625
#endif
11626
11627
    return ret;
11628
}
11629
11630
#ifdef WOLFSSL_EC_POINT_CMP_JACOBIAN
11631
/* Compare two points on a the same curve.
11632
 *
11633
 * (Ax, Ay, Az) => (Ax / (Az ^ 2), Ay / (Az ^ 3))
11634
 * (Bx, By, Bz) => (Bx / (Bz ^ 2), By / (Bz ^ 3))
11635
 * When equal:
11636
 *      (Ax / (Az ^ 2), Ay / (Az ^ 3)) = (Bx / (Bz ^ 2), By / (Bz ^ 3))
11637
 *   => (Ax * (Bz ^ 2), Ay * (Bz ^ 3)) = (Bx * (Az ^ 2), By * (Az ^ 3))
11638
 *
11639
 * @param [in] group  EC group.
11640
 * @param [in] a      EC point to compare.
11641
 * @param [in] b      EC point to compare.
11642
 * @return  0 when equal.
11643
 * @return  1 when different.
11644
 * @return  -1 on error.
11645
 */
11646
static int ec_point_cmp_jacobian(const WOLFSSL_EC_GROUP* group,
11647
    const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, WOLFSSL_BN_CTX *ctx)
11648
{
11649
    int ret = 0;
11650
    BIGNUM* at = BN_new();
11651
    BIGNUM* bt = BN_new();
11652
    BIGNUM* az = BN_new();
11653
    BIGNUM* bz = BN_new();
11654
    BIGNUM* mod = BN_new();
11655
11656
    /* Check that the big numbers were allocated. */
11657
    if ((at == NULL) || (bt == NULL) || (az == NULL) || (bz == NULL) ||
11658
            (mod == NULL)) {
11659
        ret = WOLFSSL_FATAL_ERROR;
11660
    }
11661
    /* Get the modulus for the curve. */
11662
    if ((ret == 0) &&
11663
            (BN_hex2bn(&mod, ecc_sets[group->curve_idx].prime) != 1)) {
11664
        ret = WOLFSSL_FATAL_ERROR;
11665
    }
11666
    if (ret == 0) {
11667
        /* bt = Bx * (Az ^ 2). When Az is one then just copy. */
11668
        if (BN_is_one(a->Z)) {
11669
            if (BN_copy(bt, b->X) == NULL) {
11670
                ret = WOLFSSL_FATAL_ERROR;
11671
            }
11672
        }
11673
        /* az = Az ^ 2 */
11674
        else if ((BN_mod_mul(az, a->Z, a->Z, mod, ctx) != 1)) {
11675
            ret = WOLFSSL_FATAL_ERROR;
11676
        }
11677
        /* bt = Bx * az = Bx * (Az ^ 2) */
11678
        else if (BN_mod_mul(bt, b->X, az, mod, ctx) != 1) {
11679
            ret = WOLFSSL_FATAL_ERROR;
11680
        }
11681
    }
11682
    if (ret == 0) {
11683
        /* at = Ax * (Bz ^ 2). When Bz is one then just copy. */
11684
        if (BN_is_one(b->Z)) {
11685
            if (BN_copy(at, a->X) == NULL) {
11686
                ret = WOLFSSL_FATAL_ERROR;
11687
            }
11688
        }
11689
        /* bz = Bz ^ 2 */
11690
        else if (BN_mod_mul(bz, b->Z, b->Z, mod, ctx) != 1) {
11691
            ret = WOLFSSL_FATAL_ERROR;
11692
        }
11693
        /* at = Ax * bz = Ax * (Bz ^ 2) */
11694
        else if (BN_mod_mul(at, a->X, bz, mod, ctx) != 1) {
11695
            ret = WOLFSSL_FATAL_ERROR;
11696
        }
11697
    }
11698
    /* Compare x-ordinates. */
11699
    if ((ret == 0) && (BN_cmp(at, bt) != 0)) {
11700
        ret = 1;
11701
    }
11702
    if (ret == 0) {
11703
        /* bt = By * (Az ^ 3). When Az is one then just copy. */
11704
        if (BN_is_one(a->Z)) {
11705
            if (BN_copy(bt, b->Y) == NULL) {
11706
                ret = WOLFSSL_FATAL_ERROR;
11707
            }
11708
        }
11709
        /* az = az * Az = Az ^ 3 */
11710
        else if ((BN_mod_mul(az, az, a->Z, mod, ctx) != 1)) {
11711
            ret = WOLFSSL_FATAL_ERROR;
11712
        }
11713
        /* bt = By * az = By * (Az ^ 3) */
11714
        else if (BN_mod_mul(bt, b->Y, az, mod, ctx) != 1) {
11715
            ret = WOLFSSL_FATAL_ERROR;
11716
        }
11717
    }
11718
    if (ret == 0) {
11719
        /* at = Ay * (Bz ^ 3). When Bz is one then just copy. */
11720
        if (BN_is_one(b->Z)) {
11721
            if (BN_copy(at, a->Y) == NULL) {
11722
                ret = WOLFSSL_FATAL_ERROR;
11723
            }
11724
        }
11725
        /* bz = bz * Bz = Bz ^ 3 */
11726
        else if (BN_mod_mul(bz, bz, b->Z, mod, ctx) != 1) {
11727
            ret = WOLFSSL_FATAL_ERROR;
11728
        }
11729
        /* at = Ay * bz = Ay * (Bz ^ 3) */
11730
        else if (BN_mod_mul(at, a->Y, bz, mod, ctx) != 1) {
11731
            ret = WOLFSSL_FATAL_ERROR;
11732
        }
11733
    }
11734
    /* Compare y-ordinates. */
11735
    if ((ret == 0) && (BN_cmp(at, bt) != 0)) {
11736
        ret = 1;
11737
    }
11738
11739
    BN_free(mod);
11740
    BN_free(bz);
11741
    BN_free(az);
11742
    BN_free(bt);
11743
    BN_free(at);
11744
    return ret;
11745
}
11746
#endif
11747
11748
/* Compare two points on a the same curve.
11749
 *
11750
 * Return code compliant with OpenSSL.
11751
 *
11752
 * @param [in] group  EC group.
11753
 * @param [in] a      EC point to compare.
11754
 * @param [in] b      EC point to compare.
11755
 * @param [in] ctx    Context to use for BN operations. Unused.
11756
 * @return  0 when equal.
11757
 * @return  1 when different.
11758
 * @return  -1 on error.
11759
 */
11760
int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
11761
    const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, WOLFSSL_BN_CTX *ctx)
11762
{
11763
    int ret = 0;
11764
11765
    WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
11766
11767
    /* Validate parameters. */
11768
    if ((group == NULL) || (a == NULL) || (a->internal == NULL) ||
11769
            (b == NULL) || (b->internal == NULL)) {
11770
        WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
11771
        ret = WOLFSSL_FATAL_ERROR;
11772
    }
11773
    if (ret != -1) {
11774
    #ifdef WOLFSSL_EC_POINT_CMP_JACOBIAN
11775
        /* If same Z ordinate then no need to convert to affine. */
11776
        if (BN_cmp(a->Z, b->Z) == 0) {
11777
            /* Compare */
11778
            ret = ((BN_cmp(a->X, b->X) != 0) || (BN_cmp(a->Y, b->Y) != 0));
11779
        }
11780
        else {
11781
            ret = ec_point_cmp_jacobian(group, a, b, ctx);
11782
        }
11783
    #else
11784
        /* No BN operations performed. */
11785
        (void)ctx;
11786
11787
        ret = (wc_ecc_cmp_point((ecc_point*)a->internal,
11788
            (ecc_point*)b->internal) != MP_EQ);
11789
    #endif
11790
    }
11791
11792
    return ret;
11793
}
11794
11795
/* Copy EC point.
11796
 *
11797
 * @param [out] dest  EC point to copy into.
11798
 * @param [in]  src   EC point to copy.
11799
 * @return  1 on success.
11800
 * @return  0 on error.
11801
 */
11802
int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src)
11803
{
11804
    int ret = 1;
11805
11806
    WOLFSSL_ENTER("wolfSSL_EC_POINT_copy");
11807
11808
    /* Validate parameters. */
11809
    if ((dest == NULL) || (src == NULL)) {
11810
        ret = 0;
11811
    }
11812
11813
    /* Ensure internal EC point of src is setup. */
11814
    if ((ret == 1) && (ec_point_setup(src) != 1)) {
11815
        ret = 0;
11816
    }
11817
11818
    /* Copy internal EC points. */
11819
    if ((ret == 1) && (wc_ecc_copy_point((ecc_point*)src->internal,
11820
            (ecc_point*)dest->internal) != MP_OKAY)) {
11821
        ret = 0;
11822
    }
11823
11824
    if (ret == 1) {
11825
        /* Destinatation internal point is set. */
11826
        dest->inSet = 1;
11827
11828
        /* Set the external EC point of dest based on internal. */
11829
        if (ec_point_external_set(dest) != 1) {
11830
            ret = 0;
11831
        }
11832
    }
11833
11834
    return ret;
11835
}
11836
11837
/* Checks whether point is at infinity.
11838
 *
11839
 * Return code compliant with OpenSSL.
11840
 *
11841
 * @param [in] group  EC group.
11842
 * @param [in] point  EC point to check.
11843
 * @return  1 when at infinity.
11844
 * @return  0 when not at infinity.
11845
 */
11846
int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
11847
    const WOLFSSL_EC_POINT *point)
11848
{
11849
    int ret = 1;
11850
11851
    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
11852
11853
    /* Validate parameters. */
11854
    if ((group == NULL) || (point == NULL) || (point->internal == NULL)) {
11855
        WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
11856
        ret = 0;
11857
    }
11858
11859
    /* Ensure internal EC point is setup. */
11860
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
11861
        ret = 0;
11862
    }
11863
    if (ret == 1) {
11864
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
11865
        /* Check for infinity. */
11866
        ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
11867
        if (ret < 0) {
11868
            WOLFSSL_MSG("ecc_point_is_at_infinity failure");
11869
            /* Error return is 0 by OpenSSL. */
11870
            ret = 0;
11871
        }
11872
    #else
11873
        WOLFSSL_MSG("ecc_point_is_at_infinitiy compiled out");
11874
        ret = 0;
11875
    #endif
11876
    }
11877
11878
    return ret;
11879
}
11880
11881
#endif /* OPENSSL_EXTRA */
11882
11883
/* End EC_POINT */
11884
11885
/* Start EC_KEY */
11886
11887
#ifdef OPENSSL_EXTRA
11888
11889
/*
11890
 * EC key constructor/deconstructor APIs
11891
 */
11892
11893
/* Allocate a new EC key.
11894
 *
11895
 * Not OpenSSL API.
11896
 *
11897
 * @param [in] heap   Heap hint for dynamic memory allocation.
11898
 * @param [in] devId  Device identifier value.
11899
 * @return  New, allocated EC key on success.
11900
 * @return  NULL on error.
11901
 */
11902
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId)
11903
{
11904
    WOLFSSL_EC_KEY *key = NULL;
11905
    int err = 0;
11906
11907
    WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
11908
11909
    /* Allocate memory for EC key. */
11910
    key = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), heap,
11911
        DYNAMIC_TYPE_ECC);
11912
    if (key == NULL) {
11913
        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
11914
        err = 1;
11915
    }
11916
    if (!err) {
11917
        /* Reset all fields to 0. */
11918
        XMEMSET(key, 0, sizeof(WOLFSSL_EC_KEY));
11919
        /* Cache heap hint. */
11920
        key->heap = heap;
11921
        /* Initialize fields to defaults. */
11922
        key->form     = WC_POINT_CONVERSION_UNCOMPRESSED;
11923
11924
        /* Initialize reference count. */
11925
        wolfSSL_RefInit(&key->ref, &err);
11926
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
11927
    }
11928
    if (!err) {
11929
#endif
11930
        /* Allocate memory for internal EC key representation. */
11931
        key->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), heap,
11932
            DYNAMIC_TYPE_ECC);
11933
        if (key->internal == NULL) {
11934
            WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
11935
            err = 1;
11936
        }
11937
    }
11938
    if (!err) {
11939
        /* Initialize wolfCrypt EC key. */
11940
        if (wc_ecc_init_ex((ecc_key*)key->internal, heap, devId) != 0) {
11941
            WOLFSSL_MSG("wolfSSL_EC_KEY_new init ecc key failure");
11942
            err = 1;
11943
        }
11944
    }
11945
11946
    if (!err) {
11947
        /* Group unknown at creation */
11948
        key->group = wolfSSL_EC_GROUP_new_by_curve_name(WC_NID_undef);
11949
        if (key->group == NULL) {
11950
            WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
11951
            err = 1;
11952
        }
11953
    }
11954
11955
    if (!err) {
11956
        /* Allocate a point as public key. */
11957
        key->pub_key = wolfSSL_EC_POINT_new(key->group);
11958
        if (key->pub_key == NULL) {
11959
            WOLFSSL_MSG("wolfSSL_EC_POINT_new failure");
11960
            err = 1;
11961
        }
11962
    }
11963
11964
    if (!err) {
11965
        /* Allocate a BN as private key. */
11966
        key->priv_key = wolfSSL_BN_new();
11967
        if (key->priv_key == NULL) {
11968
            WOLFSSL_MSG("wolfSSL_BN_new failure");
11969
            err = 1;
11970
        }
11971
    }
11972
11973
    if (err) {
11974
        /* Dispose of EC key on error. */
11975
        wolfSSL_EC_KEY_free(key);
11976
        key = NULL;
11977
    }
11978
    /* Return new EC key object. */
11979
    return key;
11980
}
11981
11982
/* Allocate a new EC key.
11983
 *
11984
 * @return  New, allocated EC key on success.
11985
 * @return  NULL on error.
11986
 */
11987
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
11988
{
11989
    return wolfSSL_EC_KEY_new_ex(NULL, INVALID_DEVID);
11990
}
11991
11992
/* Create new EC key with the group having the specified numeric ID.
11993
 *
11994
 * @param [in] nid  Numeric ID.
11995
 * @return  New, allocated EC key on success.
11996
 * @return  NULL on error.
11997
 */
11998
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
11999
{
12000
    WOLFSSL_EC_KEY *key;
12001
    int err = 0;
12002
12003
    WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
12004
12005
    /* Allocate empty, EC key. */
12006
    key = wolfSSL_EC_KEY_new();
12007
    if (key == NULL) {
12008
        WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
12009
        err = 1;
12010
    }
12011
12012
    if (!err) {
12013
        /* Set group to be nid. */
12014
        ec_group_set_nid(key->group, nid);
12015
        if (key->group->curve_idx == -1) {
12016
            wolfSSL_EC_KEY_free(key);
12017
            key = NULL;
12018
        }
12019
    }
12020
12021
    /* Return the new EC key object. */
12022
    return key;
12023
}
12024
12025
/* Dispose of the EC key and allocated data.
12026
 *
12027
 * Cannot use key after this call.
12028
 *
12029
 * @param [in] key  EC key to free.
12030
 */
12031
void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
12032
{
12033
    int doFree = 0;
12034
    int err;
12035
12036
    (void)err;
12037
12038
    WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
12039
12040
    if (key != NULL) {
12041
        void* heap = key->heap;
12042
12043
        /* Decrement reference count. */
12044
        wolfSSL_RefDec(&key->ref, &doFree, &err);
12045
        if (doFree) {
12046
            /* Dispose of allocated reference counting data. */
12047
            wolfSSL_RefFree(&key->ref);
12048
12049
            /* Dispose of private key. */
12050
            wolfSSL_BN_free(key->priv_key);
12051
            wolfSSL_EC_POINT_free(key->pub_key);
12052
            wolfSSL_EC_GROUP_free(key->group);
12053
            if (key->internal != NULL) {
12054
                /* Dispose of wolfCrypt representation of EC key. */
12055
                wc_ecc_free((ecc_key*)key->internal);
12056
                XFREE(key->internal, heap, DYNAMIC_TYPE_ECC);
12057
            }
12058
12059
            /* Set back to NULLs for safety. */
12060
            ForceZero(key, sizeof(*key));
12061
12062
            /* Dispose of the memory associated with the EC key. */
12063
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
12064
            (void)heap;
12065
        }
12066
    }
12067
}
12068
12069
/* Increments ref count of EC key.
12070
 *
12071
 * @param [in, out] key  EC key.
12072
 * @return  1 on success
12073
 * @return  0 on error
12074
 */
12075
int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key)
12076
{
12077
    int err = 1;
12078
12079
    if (key != NULL) {
12080
        wolfSSL_RefInc(&key->ref, &err);
12081
    }
12082
12083
    return !err;
12084
}
12085
12086
#ifndef NO_CERTS
12087
12088
#if defined(OPENSSL_ALL)
12089
/* Copy the internal, wolfCrypt EC key.
12090
 *
12091
 * @param [in, out] dst  Destination wolfCrypt EC key.
12092
 * @param [in]      src  Source wolfCrypt EC key.
12093
 * @return  0 on success.
12094
 * @return  Negative on error.
12095
 */
12096
static int wolfssl_ec_key_int_copy(ecc_key* dst, const ecc_key* src)
12097
{
12098
    int ret;
12099
12100
    /* Copy public key. */
12101
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
12102
    ret = wc_ecc_copy_point(&src->pubkey, &dst->pubkey);
12103
#else
12104
    ret = wc_ecc_copy_point((ecc_point*)&src->pubkey, &dst->pubkey);
12105
#endif
12106
    if (ret != MP_OKAY) {
12107
        WOLFSSL_MSG("wc_ecc_copy_point error");
12108
    }
12109
12110
    if (ret == 0) {
12111
        /* Copy private key. */
12112
        ret = mp_copy(wc_ecc_key_get_priv((ecc_key*)src),
12113
            wc_ecc_key_get_priv(dst));
12114
        if (ret != MP_OKAY) {
12115
            WOLFSSL_MSG("mp_copy error");
12116
        }
12117
    }
12118
12119
    if (ret == 0) {
12120
        /* Copy domain parameters. */
12121
        if (src->dp) {
12122
            ret = wc_ecc_set_curve(dst, 0, src->dp->id);
12123
            if (ret != 0) {
12124
                WOLFSSL_MSG("wc_ecc_set_curve error");
12125
            }
12126
        }
12127
    }
12128
12129
    if (ret == 0) {
12130
        /* Copy the other components. */
12131
        dst->type  = src->type;
12132
        dst->idx   = src->idx;
12133
        dst->state = src->state;
12134
        dst->flags = src->flags;
12135
    }
12136
12137
    return ret;
12138
}
12139
12140
/* Copies ecc_key into new WOLFSSL_EC_KEY object
12141
 *
12142
 * Copies the internal representation as well.
12143
 *
12144
 * @param [in] src  EC key to duplicate.
12145
 *
12146
 * @return  EC key on success.
12147
 * @return  NULL on error.
12148
 */
12149
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src)
12150
{
12151
    int err = 0;
12152
    WOLFSSL_EC_KEY* newKey = NULL;
12153
12154
    WOLFSSL_ENTER("wolfSSL_EC_KEY_dup");
12155
12156
    /* Validate EC key. */
12157
    if ((src == NULL) || (src->internal == NULL) || (src->group == NULL) ||
12158
         (src->pub_key == NULL) || (src->priv_key == NULL)) {
12159
        WOLFSSL_MSG("src NULL error");
12160
        err = 1;
12161
    }
12162
12163
    if (!err) {
12164
        /* Create a new, empty key. */
12165
        newKey = wolfSSL_EC_KEY_new();
12166
        if (newKey == NULL) {
12167
            WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
12168
            err = 1;
12169
        }
12170
    }
12171
12172
    if (!err) {
12173
        /* Copy internal EC key. */
12174
        if (wolfssl_ec_key_int_copy((ecc_key*)newKey->internal,
12175
                (ecc_key*)src->internal) != 0) {
12176
            WOLFSSL_MSG("Copying internal EC key error");
12177
            err = 1;
12178
        }
12179
    }
12180
    if (!err) {
12181
        /* Internal key set. */
12182
        newKey->inSet = 1;
12183
12184
        /* Copy group */
12185
        err = wolfssl_ec_group_copy(newKey->group, src->group);
12186
    }
12187
    /* Copy public key. */
12188
    if ((!err) && (wolfSSL_EC_POINT_copy(newKey->pub_key, src->pub_key) != 1)) {
12189
        WOLFSSL_MSG("Copying EC public key error");
12190
        err = 1;
12191
    }
12192
12193
    if (!err) {
12194
        /* Set header size of private key in PKCS#8 format.*/
12195
        newKey->pkcs8HeaderSz = src->pkcs8HeaderSz;
12196
12197
        /* Copy private key. */
12198
        if (wolfSSL_BN_copy(newKey->priv_key, src->priv_key) == NULL) {
12199
            WOLFSSL_MSG("Copying EC private key error");
12200
            err = 1;
12201
        }
12202
    }
12203
12204
    if (err) {
12205
        /* Dispose of EC key on error. */
12206
        wolfSSL_EC_KEY_free(newKey);
12207
        newKey = NULL;
12208
    }
12209
    /* Return the new EC key. */
12210
    return newKey;
12211
}
12212
12213
#endif /* OPENSSL_ALL */
12214
12215
#endif /* !NO_CERTS */
12216
12217
/*
12218
 * EC key to/from bin/octet APIs
12219
 */
12220
12221
/* Create an EC key from the octet encoded public key.
12222
 *
12223
 * Behaviour checked against OpenSSL.
12224
 *
12225
 * @param [out]     key  Reference to EC key. Must pass in a valid object with
12226
 *                       group set.
12227
 * @param [in, out] in   On in, reference to buffer that contains data.
12228
 *                       On out, reference to buffer after public key data.
12229
 * @param [in]      len  Length of data in the buffer. Must be length of the
12230
 *                       encoded public key.
12231
 * @return  Allocated EC key on success.
12232
 * @return  NULL on error.
12233
 */
12234
WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **key,
12235
   const unsigned char **in, long len)
12236
{
12237
    int err = 0;
12238
    WOLFSSL_EC_KEY* ret = NULL;
12239
12240
    WOLFSSL_ENTER("wolfSSL_o2i_ECPublicKey");
12241
12242
    /* Validate parameters: EC group needed to perform import. */
12243
    if ((key == NULL) || (*key == NULL) || ((*key)->group == NULL) ||
12244
            (in == NULL) || (*in == NULL) || (len <= 0)) {
12245
        WOLFSSL_MSG("wolfSSL_o2i_ECPublicKey Bad arguments");
12246
        err = 1;
12247
    }
12248
12249
    if (!err) {
12250
        /* Return the EC key object passed in. */
12251
        ret = *key;
12252
12253
        /* Import point into public key field. */
12254
        if (wolfSSL_EC_POINT_oct2point(ret->group, ret->pub_key, *in,
12255
                (size_t)len, NULL) != 1) {
12256
            WOLFSSL_MSG("wolfSSL_EC_POINT_oct2point error");
12257
            ret = NULL;
12258
            err = 1;
12259
        }
12260
    }
12261
    if (!err) {
12262
        /* Assumed length passed in is all the data. */
12263
        *in += len;
12264
    }
12265
12266
    return ret;
12267
}
12268
12269
/* Puts the encoded public key into out.
12270
 *
12271
 * Passing in NULL for out returns length only.
12272
 * Passing in NULL for *out has buffer allocated, encoded into and passed back.
12273
 * Passing non-NULL for *out has it encoded into and pointer moved past.
12274
 *
12275
 * @param [in]      key  EC key to encode.
12276
 * @param [in, out] out  Reference to buffer to encode into. May be NULL or
12277
 *                       point to NULL.
12278
 * @return  Length of encoding in bytes on success.
12279
 * @return  0 on error.
12280
 */
12281
int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *key, unsigned char **out)
12282
{
12283
    int ret = 1;
12284
    size_t len = 0;
12285
    int form = WC_POINT_CONVERSION_UNCOMPRESSED;
12286
12287
    WOLFSSL_ENTER("wolfSSL_i2o_ECPublicKey");
12288
12289
    /* Validate parameters. */
12290
    if (key == NULL) {
12291
        WOLFSSL_MSG("wolfSSL_i2o_ECPublicKey Bad arguments");
12292
        ret = 0;
12293
    }
12294
12295
    /* Ensure the external key data is set from the internal EC key. */
12296
    if ((ret == 1) && (!key->exSet) && (SetECKeyExternal((WOLFSSL_EC_KEY*)
12297
            key) != 1)) {
12298
        WOLFSSL_MSG("SetECKeyExternal failure");
12299
        ret = 0;
12300
    }
12301
12302
    if (ret == 1) {
12303
    #ifdef HAVE_COMP_KEY
12304
        /* Default to compressed form if not set */
12305
        form = (key->form == WC_POINT_CONVERSION_UNCOMPRESSED) ?
12306
               WC_POINT_CONVERSION_UNCOMPRESSED :
12307
               WC_POINT_CONVERSION_COMPRESSED;
12308
    #endif
12309
12310
        /* Calculate length of point encoding. */
12311
        len = wolfSSL_EC_POINT_point2oct(key->group, key->pub_key, form, NULL,
12312
            0, NULL);
12313
    }
12314
    /* Encode if length calculated and pointer supplied to update. */
12315
    if ((ret == 1) && (len != 0) && (out != NULL)) {
12316
        unsigned char *tmp = NULL;
12317
12318
        /* Allocate buffer for encoding if no buffer supplied. */
12319
        if (*out == NULL) {
12320
            tmp = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
12321
            if (tmp == NULL) {
12322
                WOLFSSL_MSG("malloc failed");
12323
                ret = 0;
12324
            }
12325
        }
12326
        else {
12327
            /* Get buffer to encode into. */
12328
            tmp = *out;
12329
        }
12330
12331
        /* Encode public key into buffer. */
12332
        if ((ret == 1) && (wolfSSL_EC_POINT_point2oct(key->group, key->pub_key,
12333
                form, tmp, len, NULL) == 0)) {
12334
            ret = 0;
12335
        }
12336
12337
        if (ret == 1) {
12338
            /* Return buffer if allocated. */
12339
            if (*out == NULL) {
12340
                *out = tmp;
12341
            }
12342
            else {
12343
                /* Step over encoded data if not allocated. */
12344
                *out += len;
12345
            }
12346
        }
12347
        else if (*out == NULL) {
12348
            /* Dispose of allocated buffer. */
12349
            XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
12350
        }
12351
    }
12352
12353
    if (ret == 1) {
12354
        /* Return length on success. */
12355
        ret = (int)len;
12356
    }
12357
    return ret;
12358
}
12359
12360
#ifdef HAVE_ECC_KEY_IMPORT
12361
/* Create a EC key from the DER encoded private key.
12362
 *
12363
 * @param [out]     key   Reference to EC key.
12364
 * @param [in, out] in    On in, reference to buffer that contains DER data.
12365
 *                        On out, reference to buffer after private key data.
12366
 * @param [in]      long  Length of data in the buffer. May be larger than the
12367
 *                        length of the encoded private key.
12368
 * @return  Allocated EC key on success.
12369
 * @return  NULL on error.
12370
 */
12371
WOLFSSL_EC_KEY* wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY** key,
12372
    const unsigned char** in, long len)
12373
{
12374
    int err = 0;
12375
    word32 idx = 0;
12376
    WOLFSSL_EC_KEY* ret = NULL;
12377
12378
    WOLFSSL_ENTER("wolfSSL_d2i_ECPrivateKey");
12379
12380
    /* Validate parameters. */
12381
    if ((in == NULL) || (*in == NULL) || (len <= 0)) {
12382
        WOLFSSL_MSG("wolfSSL_d2i_ECPrivateKey Bad arguments");
12383
        err = 1;
12384
    }
12385
12386
    /* Create a new, empty EC key.  */
12387
    if ((!err) && ((ret = wolfSSL_EC_KEY_new()) == NULL)) {
12388
        WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
12389
        err = 1;
12390
    }
12391
12392
    /* Decode the private key DER data into internal EC key. */
12393
    if ((!err) && (wc_EccPrivateKeyDecode(*in, &idx, (ecc_key*)ret->internal,
12394
            (word32)len) != 0)) {
12395
        WOLFSSL_MSG("wc_EccPrivateKeyDecode error");
12396
        err = 1;
12397
    }
12398
12399
    if (!err) {
12400
        /* Internal EC key setup. */
12401
        ret->inSet = 1;
12402
12403
        /* Set the EC key from the internal values. */
12404
        if (SetECKeyExternal(ret) != 1) {
12405
            WOLFSSL_MSG("SetECKeyExternal error");
12406
            err = 1;
12407
        }
12408
    }
12409
12410
    if (!err) {
12411
        /* Move buffer on to next byte after data used. */
12412
        *in += idx;
12413
        if (key) {
12414
            /* Return new EC key through reference. */
12415
            *key = ret;
12416
        }
12417
    }
12418
12419
    if (err && (ret != NULL)) {
12420
        /* Dispose of allocated EC key. */
12421
        wolfSSL_EC_KEY_free(ret);
12422
        ret = NULL;
12423
    }
12424
    return ret;
12425
}
12426
#endif /* HAVE_ECC_KEY_IMPORT */
12427
12428
/* Enecode the private key of the EC key into the buffer as DER.
12429
 *
12430
 * @param [in]      key  EC key to encode.
12431
 * @param [in, out] out  On in, reference to buffer to place DER encoding into.
12432
 *                       On out, reference to buffer after the encoding.
12433
 *                       May be NULL.
12434
 * @return  Length of DER encoding on success.
12435
 * @return  0 on error.
12436
 */
12437
int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *key, unsigned char **out)
12438
{
12439
    int err = 0;
12440
    word32 len = 0;
12441
12442
    WOLFSSL_ENTER("wolfSSL_i2d_ECPrivateKey");
12443
12444
    /* Validate parameters. */
12445
    if (key == NULL) {
12446
        WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments");
12447
        err = 1;
12448
    }
12449
12450
    /* Update the internal EC key if not set. */
12451
    if ((!err) && (!key->inSet) && (SetECKeyInternal((WOLFSSL_EC_KEY*)key) !=
12452
            1)) {
12453
        WOLFSSL_MSG("SetECKeyInternal error");
12454
        err = 1;
12455
    }
12456
12457
    /* Calculate the length of the private key DER encoding using internal EC
12458
     * key. */
12459
    if ((!err) && ((int)(len = (word32)wc_EccKeyDerSize((ecc_key*)key->internal,
12460
           0)) <= 0)) {
12461
        WOLFSSL_MSG("wc_EccKeyDerSize error");
12462
        err = 1;
12463
    }
12464
12465
    /* Only return length when out is NULL. */
12466
    if ((!err) && (out != NULL)) {
12467
        unsigned char* buf = NULL;
12468
12469
        /* Must have a buffer to encode into. */
12470
        if (*out == NULL) {
12471
            /* Allocate a new buffer of appropriate length. */
12472
            buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12473
            if (buf == NULL) {
12474
                /* Error and return 0. */
12475
                err = 1;
12476
                len = 0;
12477
            }
12478
            else {
12479
                /* Return the allocated buffer. */
12480
                *out = buf;
12481
            }
12482
        }
12483
        /* Encode the internal EC key as a private key in DER format. */
12484
        if ((!err) && wc_EccPrivateKeyToDer((ecc_key*)key->internal, *out,
12485
                len) < 0) {
12486
            WOLFSSL_MSG("wc_EccPrivateKeyToDer error");
12487
            err = 1;
12488
        }
12489
        else if (buf != *out) {
12490
            /* Move the reference to byte past encoded private key. */
12491
            *out += len;
12492
        }
12493
12494
        /* Dispose of any allocated buffer on error. */
12495
        if (err && (*out == buf)) {
12496
            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12497
            *out = NULL;
12498
        }
12499
    }
12500
12501
    return (int)len;
12502
}
12503
12504
/* Load private key into EC key from DER encoding.
12505
 *
12506
 * Not an OpenSSL compatibility API.
12507
 *
12508
 * @param [in, out] key     EC key to put private key values into.
12509
 * @param [in]      derBuf  Buffer holding DER encoding.
12510
 * @param [in]      derSz   Size of DER encoding in bytes.
12511
 * @return  1 on success.
12512
 * @return  -1 on error.
12513
 */
12514
int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
12515
                           int derSz)
12516
{
12517
    return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz,
12518
        WOLFSSL_EC_KEY_LOAD_PRIVATE);
12519
}
12520
12521
/* Load private/public key into EC key from DER encoding.
12522
 *
12523
 * Not an OpenSSL compatibility API.
12524
 *
12525
 * @param [in, out] key     EC key to put private/public key values into.
12526
 * @param [in]      derBuf  Buffer holding DER encoding.
12527
 * @param [in]      derSz   Size of DER encoding in bytes.
12528
 * @param [in]      opt     Key type option. Valid values:
12529
 *                            WOLFSSL_EC_KEY_LOAD_PRIVATE,
12530
 *                            WOLFSSL_EC_KEY_LOAD_PUBLIC.
12531
 * @return  1 on success.
12532
 * @return  -1 on error.
12533
 */
12534
int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
12535
                              int derSz, int opt)
12536
{
12537
    int res = 1;
12538
    int ret;
12539
    word32 idx = 0;
12540
    word32 algId;
12541
12542
    WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
12543
12544
    /* Validate parameters. */
12545
    if ((key == NULL) || (key->internal == NULL) || (derBuf == NULL) ||
12546
            (derSz <= 0)) {
12547
        WOLFSSL_MSG("Bad function arguments");
12548
        res = WOLFSSL_FATAL_ERROR;
12549
    }
12550
    if ((res == 1) && (opt != WOLFSSL_EC_KEY_LOAD_PRIVATE) &&
12551
            (opt != WOLFSSL_EC_KEY_LOAD_PUBLIC)) {
12552
        res = WOLFSSL_FATAL_ERROR;
12553
    }
12554
12555
    if (res == 1) {
12556
        /* Assume no PKCS#8 header. */
12557
        key->pkcs8HeaderSz = 0;
12558
12559
        /* Check if input buffer has PKCS8 header. In the case that it does not
12560
         * have a PKCS8 header then do not error out.
12561
         */
12562
        if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx,
12563
                (word32)derSz, &algId)) > 0) {
12564
            WOLFSSL_MSG("Found PKCS8 header");
12565
            key->pkcs8HeaderSz = (word16)idx;
12566
            res = 1;
12567
        }
12568
        /* Error out on parsing error. */
12569
        else if (ret != WC_NO_ERR_TRACE(ASN_PARSE_E)) {
12570
            WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
12571
            res = WOLFSSL_FATAL_ERROR;
12572
        }
12573
    }
12574
12575
    if (res == 1) {
12576
        /* Load into internal EC key based on key type option. */
12577
        if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
12578
            ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
12579
                (word32)derSz);
12580
        }
12581
        else {
12582
            ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
12583
                (word32)derSz);
12584
            if (ret < 0) {
12585
                ecc_key *tmp = (ecc_key*)XMALLOC(sizeof(ecc_key),
12586
                    ((ecc_key*)key->internal)->heap, DYNAMIC_TYPE_ECC);
12587
                if (tmp == NULL) {
12588
                    ret = WOLFSSL_FATAL_ERROR;
12589
                }
12590
                else {
12591
                    /* We now try again as x.963 [point type][x][opt y]. */
12592
                    ret = wc_ecc_init_ex(tmp, ((ecc_key*)key->internal)->heap,
12593
                                         INVALID_DEVID);
12594
                    if (ret == 0) {
12595
                        ret = wc_ecc_import_x963(derBuf, (word32)derSz, tmp);
12596
                        if (ret == 0) {
12597
                            /* Take ownership of new key - set tmp to the old
12598
                             * key which will then be freed below. */
12599
                            ecc_key *old = (ecc_key *)key->internal;
12600
                            key->internal = tmp;
12601
                            tmp = old;
12602
12603
                            idx = (word32)derSz;
12604
                        }
12605
                        wc_ecc_free(tmp);
12606
                    }
12607
                    XFREE(tmp, ((ecc_key*)key->internal)->heap,
12608
                          DYNAMIC_TYPE_ECC);
12609
                }
12610
            }
12611
        }
12612
        if (ret < 0) {
12613
            /* Error returned from wolfSSL. */
12614
            if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
12615
                WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
12616
            }
12617
            else {
12618
                WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
12619
            }
12620
            res = WOLFSSL_FATAL_ERROR;
12621
        }
12622
12623
        /* Internal key updated - update whether it is a valid key. */
12624
        key->inSet = (res == 1);
12625
    }
12626
12627
    /* Set the external EC key based on value in internal. */
12628
    if ((res == 1) && (SetECKeyExternal(key) != 1)) {
12629
        WOLFSSL_MSG("SetECKeyExternal failed");
12630
        res = WOLFSSL_FATAL_ERROR;
12631
    }
12632
12633
    return res;
12634
}
12635
12636
12637
#ifndef NO_BIO
12638
12639
WOLFSSL_EC_KEY *wolfSSL_d2i_EC_PUBKEY_bio(WOLFSSL_BIO *bio,
12640
        WOLFSSL_EC_KEY **out)
12641
{
12642
    char* data = NULL;
12643
    int dataSz = 0;
12644
    int memAlloced = 0;
12645
    WOLFSSL_EC_KEY* ec = NULL;
12646
    int err = 0;
12647
12648
    WOLFSSL_ENTER("wolfSSL_d2i_EC_PUBKEY_bio");
12649
12650
    if (bio == NULL)
12651
        return NULL;
12652
12653
    if (err == 0 && wolfssl_read_bio(bio, &data, &dataSz, &memAlloced) != 0) {
12654
        WOLFSSL_ERROR_MSG("wolfssl_read_bio failed");
12655
        err = 1;
12656
    }
12657
12658
    if (err == 0 && (ec = wolfSSL_EC_KEY_new()) == NULL) {
12659
        WOLFSSL_ERROR_MSG("wolfSSL_EC_KEY_new failed");
12660
        err = 1;
12661
    }
12662
12663
    /* Load the EC key with the public key from the DER encoding. */
12664
    if (err == 0 && wolfSSL_EC_KEY_LoadDer_ex(ec, (const unsigned char*)data,
12665
            dataSz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1) {
12666
        WOLFSSL_ERROR_MSG("wolfSSL_EC_KEY_LoadDer_ex failed");
12667
        err = 1;
12668
    }
12669
12670
    if (memAlloced)
12671
        XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12672
    if (err) { /* on error */
12673
        wolfSSL_EC_KEY_free(ec);
12674
        ec = NULL;
12675
    }
12676
    else { /* on success */
12677
        if (out != NULL)
12678
            *out = ec;
12679
    }
12680
12681
    return ec;
12682
}
12683
12684
#endif /* !NO_BIO */
12685
12686
/*
12687
 * EC key PEM APIs
12688
 */
12689
12690
#ifdef HAVE_ECC_KEY_EXPORT
12691
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_FILESYSTEM) || !defined(NO_BIO))
12692
/* Encode the EC public key as DER.
12693
 *
12694
 * @param [in]  key   EC key to encode.
12695
 * @param [out] der   Pointer through which buffer is returned.
12696
 * @param [in]  heap  Heap hint.
12697
 * @return  Size of encoding on success.
12698
 * @return  0 on error.
12699
 */
12700
static int wolfssl_ec_key_to_pubkey_der(WOLFSSL_EC_KEY* key,
12701
    unsigned char** der, void* heap)
12702
{
12703
    int sz;
12704
    unsigned char* buf = NULL;
12705
12706
    (void)heap;
12707
12708
    /* Calculate encoded size to allocate. */
12709
    sz = wc_EccPublicKeyDerSize((ecc_key*)key->internal, 1);
12710
    if (sz <= 0) {
12711
        WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
12712
        sz = 0;
12713
    }
12714
    if (sz > 0) {
12715
        /* Allocate memory to hold encoding. */
12716
        buf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
12717
        if (buf == NULL) {
12718
            WOLFSSL_MSG("malloc failed");
12719
            sz = 0;
12720
        }
12721
    }
12722
    if (sz > 0) {
12723
        /* Encode public key to DER using wolfSSL.  */
12724
        sz = wc_EccPublicKeyToDer((ecc_key*)key->internal, buf, (word32)sz, 1);
12725
        if (sz < 0) {
12726
            WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
12727
            sz = 0;
12728
        }
12729
    }
12730
12731
    /* Return buffer on success. */
12732
    if (sz > 0) {
12733
        *der = buf;
12734
    }
12735
    else {
12736
        /* Dispose of any dynamically allocated data not returned. */
12737
        XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
12738
    }
12739
12740
    return sz;
12741
}
12742
#endif
12743
12744
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_KEY_GEN)
12745
/*
12746
 * Return code compliant with OpenSSL.
12747
 *
12748
 * @param [in] fp   File pointer to write PEM encoding to.
12749
 * @param [in] key  EC key to encode and write.
12750
 * @return  1 on success.
12751
 * @return  0 on error.
12752
 */
12753
int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY* key)
12754
{
12755
    int ret = 1;
12756
    unsigned char* derBuf = NULL;
12757
    int derSz = 0;
12758
12759
    WOLFSSL_ENTER("wolfSSL_PEM_write_EC_PUBKEY");
12760
12761
    /* Validate parameters. */
12762
    if ((fp == XBADFILE) || (key == NULL)) {
12763
        WOLFSSL_MSG("Bad argument.");
12764
        return 0;
12765
    }
12766
12767
    /* Encode public key in EC key as DER. */
12768
    derSz = wolfssl_ec_key_to_pubkey_der(key, &derBuf, key->heap);
12769
    if (derSz == 0) {
12770
        ret = 0;
12771
    }
12772
12773
    /* Write out to file the PEM encoding of the DER. */
12774
    if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
12775
            ECC_PUBLICKEY_TYPE, key->heap) != 1)) {
12776
        ret = 0;
12777
    }
12778
12779
    /* Dispose of any dynamically allocated data. */
12780
    XFREE(derBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12781
12782
    WOLFSSL_LEAVE("wolfSSL_PEM_write_EC_PUBKEY", ret);
12783
12784
    return ret;
12785
}
12786
#endif
12787
#endif
12788
12789
#ifndef NO_BIO
12790
/* Read a PEM encoded EC public key from a BIO.
12791
 *
12792
 * @param [in]  bio   BIO to read EC public key from.
12793
 * @param [out] out   Pointer to return EC key object through. May be NULL.
12794
 * @param [in]  cb    Password callback when PEM encrypted.
12795
 * @param [in]  pass  NUL terminated string for passphrase when PEM
12796
 *                    encrypted.
12797
 * @return  New EC key object on success.
12798
 * @return  NULL on error.
12799
 */
12800
WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO* bio,
12801
    WOLFSSL_EC_KEY** out, wc_pem_password_cb* cb, void *pass)
12802
{
12803
    int             err = 0;
12804
    WOLFSSL_EC_KEY* ec = NULL;
12805
    DerBuffer*      der = NULL;
12806
    int             keyFormat = 0;
12807
12808
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_EC_PUBKEY");
12809
12810
    /* Validate parameters. */
12811
    if (bio == NULL) {
12812
        err = 1;
12813
    }
12814
12815
    if (!err) {
12816
        /* Create an empty EC key. */
12817
        ec = wolfSSL_EC_KEY_new();
12818
        if (ec == NULL) {
12819
            err = 1;
12820
        }
12821
    }
12822
    /* Read a PEM key in to a new DER buffer. */
12823
    if ((!err) && (pem_read_bio_key(bio, cb, pass, ECC_PUBLICKEY_TYPE,
12824
            &keyFormat, &der) <= 0)) {
12825
        err = 1;
12826
    }
12827
    /* Load the EC key with the public key from the DER encoding. */
12828
    if ((!err) && (wolfSSL_EC_KEY_LoadDer_ex(ec, der->buffer, (int)der->length,
12829
            WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1)) {
12830
        WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_KEY");
12831
        err = 1;
12832
    }
12833
12834
    /* Dispose of dynamically allocated data not needed anymore. */
12835
    FreeDer(&der);
12836
    if (err) {
12837
        wolfSSL_EC_KEY_free(ec);
12838
        ec = NULL;
12839
    }
12840
12841
    /* Return EC key through out if required. */
12842
    if ((out != NULL) && (ec != NULL)) {
12843
        *out = ec;
12844
    }
12845
    return ec;
12846
}
12847
12848
/* Read a PEM encoded EC private key from a BIO.
12849
 *
12850
 * @param [in]  bio   BIO to read EC private key from.
12851
 * @param [out] out   Pointer to return EC key object through. May be NULL.
12852
 * @param [in]  cb    Password callback when PEM encrypted.
12853
 * @param [in]  pass  NUL terminated string for passphrase when PEM
12854
 *                    encrypted.
12855
 * @return  New EC key object on success.
12856
 * @return  NULL on error.
12857
 */
12858
WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio,
12859
   WOLFSSL_EC_KEY** out, wc_pem_password_cb* cb, void *pass)
12860
{
12861
    int             err = 0;
12862
    WOLFSSL_EC_KEY* ec = NULL;
12863
    DerBuffer*      der = NULL;
12864
    int             keyFormat = 0;
12865
12866
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_ECPrivateKey");
12867
12868
    /* Validate parameters. */
12869
    if (bio == NULL) {
12870
        err = 1;
12871
    }
12872
12873
    if (!err) {
12874
        /* Create an empty EC key. */
12875
        ec = wolfSSL_EC_KEY_new();
12876
        if (ec == NULL) {
12877
            err = 1;
12878
        }
12879
    }
12880
    /* Read a PEM key in to a new DER buffer.
12881
     * To check ENC EC PRIVATE KEY, it uses PRIVATEKEY_TYPE to call
12882
     * pem_read_bio_key(), and then check key format if it is EC.
12883
     */
12884
    if ((!err) && (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE,
12885
            &keyFormat, &der) <= 0)) {
12886
        err = 1;
12887
    }
12888
    if (keyFormat != ECDSAk) {
12889
        WOLFSSL_ERROR_MSG("Error not EC key format");
12890
        err = 1;
12891
    }
12892
    /* Load the EC key with the private key from the DER encoding. */
12893
    if ((!err) && (wolfSSL_EC_KEY_LoadDer_ex(ec, der->buffer, (int)der->length,
12894
            WOLFSSL_EC_KEY_LOAD_PRIVATE) != 1)) {
12895
        WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_KEY");
12896
        err = 1;
12897
    }
12898
12899
    /* Dispose of dynamically allocated data not needed anymore. */
12900
    FreeDer(&der);
12901
    if (err) {
12902
        wolfSSL_EC_KEY_free(ec);
12903
        ec = NULL;
12904
    }
12905
12906
    /* Return EC key through out if required. */
12907
    if ((out != NULL) && (ec != NULL)) {
12908
        *out = ec;
12909
    }
12910
    return ec;
12911
}
12912
#endif /* !NO_BIO */
12913
12914
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ECC_KEY_EXPORT)
12915
#ifndef NO_BIO
12916
/* Write out the EC public key as PEM to the BIO.
12917
 *
12918
 * @param [in] bio  BIO to write PEM encoding to.
12919
 * @param [in] ec   EC public key to encode.
12920
 * @return  1 on success.
12921
 * @return  0 on error.
12922
 */
12923
int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec)
12924
{
12925
    int ret = 1;
12926
    unsigned char* derBuf = NULL;
12927
    int derSz = 0;
12928
12929
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_EC_PUBKEY");
12930
12931
    /* Validate parameters. */
12932
    if ((bio == NULL) || (ec == NULL)) {
12933
        WOLFSSL_MSG("Bad Function Arguments");
12934
        return 0;
12935
    }
12936
12937
    /* Encode public key in EC key as DER. */
12938
    derSz = wolfssl_ec_key_to_pubkey_der(ec, &derBuf, ec->heap);
12939
    if (derSz == 0) {
12940
        ret = 0;
12941
    }
12942
12943
    /* Write out to BIO the PEM encoding of the EC public key. */
12944
    if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
12945
            ECC_PUBLICKEY_TYPE) != 1)) {
12946
        ret = 0;
12947
    }
12948
12949
    /* Dispose of any dynamically allocated data. */
12950
    XFREE(derBuf, ec->heap, DYNAMIC_TYPE_TMP_BUFFER);
12951
12952
    return ret;
12953
}
12954
12955
/* Write out the EC private key as PEM to the BIO.
12956
 *
12957
 * Return code compliant with OpenSSL.
12958
 *
12959
 * @param [in] bio       BIO to write PEM encoding to.
12960
 * @param [in] ec        EC private key to encode.
12961
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
12962
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
12963
 * @param [in] passwdSz  Length of password string when PEM encrypted.
12964
 * @param [in] cb        Password callback when PEM encrypted. Unused.
12965
 * @param [in] pass      NUL terminated string for passphrase when PEM
12966
 *                       encrypted. Unused.
12967
 * @return  1 on success.
12968
 * @return  0 on error.
12969
 */
12970
int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec,
12971
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
12972
    wc_pem_password_cb* cb, void* arg)
12973
{
12974
    int ret = 1;
12975
    unsigned char* pem = NULL;
12976
    int pLen = 0;
12977
12978
    (void)cb;
12979
    (void)arg;
12980
12981
    /* Validate parameters. */
12982
    if ((bio == NULL) || (ec == NULL)) {
12983
        ret = 0;
12984
    }
12985
12986
    /* Write EC private key to PEM. */
12987
    if ((ret == 1) && (wolfSSL_PEM_write_mem_ECPrivateKey(ec, cipher, passwd,
12988
            passwdSz, &pem, &pLen) != 1)) {
12989
       ret = 0;
12990
    }
12991
    /* Write PEM to BIO. */
12992
    if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) != pLen)) {
12993
        WOLFSSL_ERROR_MSG("EC private key BIO write failed");
12994
        ret = 0;
12995
    }
12996
12997
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
12998
12999
    return ret;
13000
}
13001
13002
#endif /* !NO_BIO */
13003
13004
/* Encode the EC private key as PEM into buffer.
13005
 *
13006
 * Return code compliant with OpenSSL.
13007
 * Not an OpenSSL API.
13008
 *
13009
 * @param [in]  ec        EC private key to encode.
13010
 * @param [in]  cipher    Cipher to use when PEM encrypted. May be NULL.
13011
 * @param [in]  passwd    Password string when PEM encrypted. May be NULL.
13012
 * @param [in]  passwdSz  Length of password string when PEM encrypted.
13013
 * @param [out] pem       Newly allocated buffer holding PEM encoding.
13014
 * @param [out] pLen      Length of PEM encoding in bytes.
13015
 * @return  1 on success.
13016
 * @return  0 on error.
13017
 */
13018
int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ec,
13019
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
13020
    unsigned char **pem, int *pLen)
13021
{
13022
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
13023
    int ret = 1;
13024
    byte* derBuf = NULL;
13025
    word32 der_max_len = 0;
13026
    int derSz = 0;
13027
13028
    WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
13029
13030
    /* Validate parameters. */
13031
    if ((pem == NULL) || (pLen == NULL) || (ec == NULL) ||
13032
            (ec->internal == NULL)) {
13033
        WOLFSSL_MSG("Bad function arguments");
13034
        ret = 0;
13035
    }
13036
13037
    /* Ensure internal EC key is set from external. */
13038
    if ((ret == 1) && (ec->inSet == 0)) {
13039
        WOLFSSL_MSG("No ECC internal set, do it");
13040
13041
        if (SetECKeyInternal(ec) != 1) {
13042
            WOLFSSL_MSG("SetECKeyInternal failed");
13043
            ret = 0;
13044
        }
13045
    }
13046
13047
    if (ret == 1) {
13048
        /* Calculate maximum size of DER encoding.
13049
         * 4 > size of pub, priv + ASN.1 additional information */
13050
        der_max_len = 4 * (word32)wc_ecc_size((ecc_key*)ec->internal) +
13051
                      WC_AES_BLOCK_SIZE;
13052
13053
        /* Allocate buffer big enough to hold encoding. */
13054
        derBuf = (byte*)XMALLOC((size_t)der_max_len, NULL,
13055
            DYNAMIC_TYPE_TMP_BUFFER);
13056
        if (derBuf == NULL) {
13057
            WOLFSSL_MSG("malloc failed");
13058
            ret = 0;
13059
        }
13060
    }
13061
13062
    if (ret == 1) {
13063
        /* Encode EC private key as DER. */
13064
        derSz = wc_EccKeyToDer((ecc_key*)ec->internal, derBuf, der_max_len);
13065
        if (derSz < 0) {
13066
            WOLFSSL_MSG("wc_EccKeyToDer failed");
13067
            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
13068
            ret = 0;
13069
        }
13070
    }
13071
13072
    /* Convert DER to PEM - possibly encrypting. */
13073
    if ((ret == 1) && (der_to_enc_pem_alloc(derBuf, derSz, cipher, passwd,
13074
            passwdSz, ECC_PRIVATEKEY_TYPE, NULL, pem, pLen) != 1)) {
13075
        WOLFSSL_ERROR_MSG("der_to_enc_pem_alloc failed");
13076
        ret = 0;
13077
    }
13078
13079
    return ret;
13080
#else
13081
    (void)ec;
13082
    (void)cipher;
13083
    (void)passwd;
13084
    (void)passwdSz;
13085
    (void)pem;
13086
    (void)pLen;
13087
    return 0;
13088
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
13089
}
13090
13091
#ifndef NO_FILESYSTEM
13092
/* Write out the EC private key as PEM to file.
13093
 *
13094
 * Return code compliant with OpenSSL.
13095
 *
13096
 * @param [in] fp        File pointer to write PEM encoding to.
13097
 * @param [in] ec        EC private key to encode.
13098
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
13099
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
13100
 * @param [in] passwdSz  Length of password string when PEM encrypted.
13101
 * @param [in] cb        Password callback when PEM encrypted. Unused.
13102
 * @param [in] pass      NUL terminated string for passphrase when PEM
13103
 *                       encrypted. Unused.
13104
 * @return  1 on success.
13105
 * @return  0 on error.
13106
 */
13107
int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ec,
13108
    const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
13109
    wc_pem_password_cb *cb, void *pass)
13110
{
13111
    int ret = 1;
13112
    byte *pem = NULL;
13113
    int pLen = 0;
13114
13115
    (void)cb;
13116
    (void)pass;
13117
13118
    WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
13119
13120
    /* Validate parameters. */
13121
    if ((fp == XBADFILE) || (ec == NULL) || (ec->internal == NULL)) {
13122
        WOLFSSL_MSG("Bad function arguments");
13123
        ret = 0;
13124
    }
13125
13126
    /* Write EC private key to PEM. */
13127
    if ((ret == 1) && (wolfSSL_PEM_write_mem_ECPrivateKey(ec, cipher, passwd,
13128
            passwdSz, &pem, &pLen) != 1)) {
13129
        WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
13130
        ret = 0;
13131
    }
13132
13133
    /* Write out to file the PEM encoding of the EC private key. */
13134
    if ((ret == 1) && ((int)XFWRITE(pem, 1, (size_t)pLen, fp) != pLen)) {
13135
        WOLFSSL_MSG("ECC private key file write failed");
13136
        ret = 0;
13137
    }
13138
13139
    /* Dispose of any dynamically allocated data. */
13140
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
13141
13142
    return ret;
13143
}
13144
13145
#endif /* NO_FILESYSTEM */
13146
#endif /* WOLFSSL_KEY_GEN && HAVE_ECC_KEY_EXPORT */
13147
13148
/*
13149
 * EC key print APIs
13150
 */
13151
13152
#ifndef NO_CERTS
13153
13154
#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
13155
    !defined(NO_STDIO_FILESYSTEM)
13156
/* Print the EC key to a file pointer as text.
13157
 *
13158
 * @param [in] fp      File pointer.
13159
 * @param [in] key     EC key to print.
13160
 * @param [in] indent  Number of spaces to place before each line printed.
13161
 * @return  1 on success.
13162
 * @return  0 on failure.
13163
 */
13164
int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent)
13165
{
13166
    int ret = 1;
13167
    int bits = 0;
13168
    int priv = 0;
13169
13170
    WOLFSSL_ENTER("wolfSSL_EC_KEY_print_fp");
13171
13172
    /* Validate parameters. */
13173
    if ((fp == XBADFILE) || (key == NULL) || (key->group == NULL) ||
13174
            (indent < 0)) {
13175
        ret = 0;
13176
    }
13177
13178
    if (ret == 1) {
13179
        /* Get EC groups order size in bits. */
13180
        bits = wolfSSL_EC_GROUP_order_bits(key->group);
13181
        if (bits <= 0) {
13182
            WOLFSSL_MSG("Failed to get group order bits.");
13183
            ret = 0;
13184
        }
13185
    }
13186
    if (ret == 1) {
13187
        const char* keyType;
13188
13189
        /* Determine whether this is a private or public key. */
13190
        if ((key->priv_key != NULL) && (!wolfSSL_BN_is_zero(key->priv_key))) {
13191
            keyType = "Private-Key";
13192
            priv = 1;
13193
        }
13194
        else {
13195
            keyType = "Public-Key";
13196
        }
13197
13198
        /* Print key header. */
13199
        if (XFPRINTF(fp, "%*s%s: (%d bit)\n", indent, "", keyType, bits) < 0) {
13200
            ret = 0;
13201
        }
13202
    }
13203
    if ((ret == 1) && priv) {
13204
        /* Print the private key BN. */
13205
        ret = pk_bn_field_print_fp(fp, indent, "priv", key->priv_key);
13206
    }
13207
    /* Check for public key data in EC key. */
13208
    if ((ret == 1) && (key->pub_key != NULL) && (key->pub_key->exSet)) {
13209
        /* Get the public key point as one BN. */
13210
        WOLFSSL_BIGNUM* pubBn = wolfSSL_EC_POINT_point2bn(key->group,
13211
            key->pub_key, WC_POINT_CONVERSION_UNCOMPRESSED, NULL, NULL);
13212
        if (pubBn == NULL) {
13213
            WOLFSSL_MSG("wolfSSL_EC_POINT_point2bn failed.");
13214
            ret = 0;
13215
        }
13216
        else {
13217
            /* Print the public key in a BN. */
13218
            ret = pk_bn_field_print_fp(fp, indent, "pub", pubBn);
13219
            wolfSSL_BN_free(pubBn);
13220
        }
13221
    }
13222
    if (ret == 1) {
13223
        /* Get the NID of the group. */
13224
        int nid = wolfSSL_EC_GROUP_get_curve_name(key->group);
13225
        if (nid > 0) {
13226
            /* Convert the NID into a long name and NIST name. */
13227
            const char* curve = wolfSSL_OBJ_nid2ln(nid);
13228
            const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
13229
13230
            /* Print OID name if known. */
13231
            if ((curve != NULL) &&
13232
                (XFPRINTF(fp, "%*sASN1 OID: %s\n", indent, "", curve) < 0)) {
13233
                ret = 0;
13234
            }
13235
            /* Print NIST curve name if known. */
13236
            if ((nistName != NULL) &&
13237
                (XFPRINTF(fp, "%*sNIST CURVE: %s\n", indent, "",
13238
                    nistName) < 0)) {
13239
                ret = 0;
13240
            }
13241
        }
13242
    }
13243
13244
13245
    WOLFSSL_LEAVE("wolfSSL_EC_KEY_print_fp", ret);
13246
13247
    return ret;
13248
}
13249
#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
13250
13251
#endif /* !NO_CERTS */
13252
13253
/*
13254
 * EC_KEY get/set/test APIs
13255
 */
13256
13257
/* Set data of internal, wolfCrypt EC key object into EC key.
13258
 *
13259
 * EC_KEY wolfSSL -> OpenSSL
13260
 *
13261
 * @param [in, out] p  EC key to update.
13262
 * @return  1 on success.
13263
 * @return  -1 on failure.
13264
 */
13265
int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
13266
{
13267
    int ret = 1;
13268
13269
    WOLFSSL_ENTER("SetECKeyExternal");
13270
13271
    /* Validate parameter. */
13272
    if ((eckey == NULL) || (eckey->internal == NULL)) {
13273
        WOLFSSL_MSG("ec key NULL error");
13274
        ret = WOLFSSL_FATAL_ERROR;
13275
    }
13276
    else {
13277
        ecc_key* key = (ecc_key*)eckey->internal;
13278
13279
        /* Set group (OID, nid and idx) from wolfCrypt EC key. */
13280
        eckey->group->curve_oid = (int)key->dp->oidSum;
13281
        eckey->group->curve_nid = EccEnumToNID(key->dp->id);
13282
        eckey->group->curve_idx = key->idx;
13283
13284
        if (eckey->pub_key->internal != NULL) {
13285
            /* Copy internal public point from internal key's public point. */
13286
            if (wc_ecc_copy_point(&key->pubkey,
13287
                    (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
13288
                WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
13289
                ret = WOLFSSL_FATAL_ERROR;
13290
            }
13291
13292
            /* Set external public key from internal wolfCrypt, public key. */
13293
            if ((ret == 1) && (ec_point_external_set(eckey->pub_key) != 1)) {
13294
                WOLFSSL_MSG("SetECKeyExternal ec_point_external_set failed");
13295
                ret = WOLFSSL_FATAL_ERROR;
13296
            }
13297
        }
13298
13299
        /* set the external privkey */
13300
        if ((ret == 1) && (key->type == ECC_PRIVATEKEY) &&
13301
                (wolfssl_bn_set_value(&eckey->priv_key,
13302
                wc_ecc_key_get_priv(key)) != 1)) {
13303
            WOLFSSL_MSG("ec priv key error");
13304
            ret = WOLFSSL_FATAL_ERROR;
13305
        }
13306
13307
        /* External values set when operations succeeded. */
13308
        eckey->exSet = (ret == 1);
13309
    }
13310
13311
    return ret;
13312
}
13313
13314
/* Set data of EC key into internal, wolfCrypt EC key object.
13315
 *
13316
 * EC_KEY Openssl -> WolfSSL
13317
 *
13318
 * @param [in, out] p  EC key to update.
13319
 * @return  1 on success.
13320
 * @return  -1 on failure.
13321
 */
13322
int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
13323
{
13324
    int ret = 1;
13325
13326
    WOLFSSL_ENTER("SetECKeyInternal");
13327
13328
    /* Validate parameter. */
13329
    if ((eckey == NULL) || (eckey->internal == NULL) ||
13330
            (eckey->group == NULL)) {
13331
        WOLFSSL_MSG("ec key NULL error");
13332
        ret = WOLFSSL_FATAL_ERROR;
13333
    }
13334
    else {
13335
        ecc_key* key = (ecc_key*)eckey->internal;
13336
        int pubSet = 0;
13337
13338
        /* Validate group. */
13339
        if ((eckey->group->curve_idx < 0) ||
13340
            (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
13341
            WOLFSSL_MSG("invalid curve idx");
13342
            ret = WOLFSSL_FATAL_ERROR;
13343
        }
13344
13345
        if (ret == 1) {
13346
            /* Set group (idx of curve and corresponding domain parameters). */
13347
            key->idx = eckey->group->curve_idx;
13348
            key->dp = &ecc_sets[key->idx];
13349
            pubSet = (eckey->pub_key != NULL);
13350
        }
13351
        /* Set public key (point). */
13352
        if ((ret == 1) && pubSet) {
13353
            if (ec_point_internal_set(eckey->pub_key) != 1) {
13354
                WOLFSSL_MSG("ec key pub error");
13355
                ret = WOLFSSL_FATAL_ERROR;
13356
            }
13357
            /* Copy public point to key. */
13358
            if ((ret == 1) && (wc_ecc_copy_point(
13359
                    (ecc_point*)eckey->pub_key->internal, &key->pubkey) !=
13360
                    MP_OKAY)) {
13361
                WOLFSSL_MSG("wc_ecc_copy_point error");
13362
                ret = WOLFSSL_FATAL_ERROR;
13363
            }
13364
13365
            if (ret == 1) {
13366
                /* Set that the internal key is a public key */
13367
                key->type = ECC_PUBLICKEY;
13368
            }
13369
        }
13370
13371
        /* set privkey */
13372
        if ((ret == 1) && (eckey->priv_key != NULL)) {
13373
            if (wolfssl_bn_get_value(eckey->priv_key,
13374
                    wc_ecc_key_get_priv(key)) != 1) {
13375
                WOLFSSL_MSG("ec key priv error");
13376
                ret = WOLFSSL_FATAL_ERROR;
13377
            }
13378
            /* private key */
13379
            if ((ret == 1) && (!mp_iszero(wc_ecc_key_get_priv(key)))) {
13380
                if (pubSet) {
13381
                    key->type = ECC_PRIVATEKEY;
13382
                }
13383
                else {
13384
                    key->type = ECC_PRIVATEKEY_ONLY;
13385
                }
13386
            }
13387
        }
13388
13389
        /* Internal values set when operations succeeded. */
13390
        eckey->inSet = (ret == 1);
13391
    }
13392
13393
    return ret;
13394
}
13395
13396
/* Get point conversion format of EC key.
13397
 *
13398
 * @param [in] key  EC key.
13399
 * @return  Point conversion format on success.
13400
 * @return  -1 on error.
13401
 */
13402
wc_point_conversion_form_t wolfSSL_EC_KEY_get_conv_form(
13403
    const WOLFSSL_EC_KEY* key)
13404
{
13405
    if (key == NULL)
13406
        return WOLFSSL_FATAL_ERROR;
13407
    return key->form;
13408
}
13409
13410
/* Set point conversion format into EC key.
13411
 *
13412
 * @param [in, out] key   EC key to set format into.
13413
 * @param [in]      form  Point conversion format. Valid values:
13414
 *                          WC_POINT_CONVERSION_UNCOMPRESSED,
13415
 *                          WC_POINT_CONVERSION_COMPRESSED (when HAVE_COMP_KEY)
13416
 */
13417
void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *key, int form)
13418
{
13419
    if (key == NULL) {
13420
        WOLFSSL_MSG("Key passed in NULL");
13421
    }
13422
    else if (form == WC_POINT_CONVERSION_UNCOMPRESSED
13423
#ifdef HAVE_COMP_KEY
13424
          || form == WC_POINT_CONVERSION_COMPRESSED
13425
#endif
13426
             ) {
13427
        key->form = (unsigned char)form;
13428
    }
13429
    else {
13430
        WOLFSSL_MSG("Incorrect form or HAVE_COMP_KEY not compiled in");
13431
    }
13432
}
13433
13434
/* Get the EC group object that is in EC key.
13435
 *
13436
 * @param [in] key  EC key.
13437
 * @return  EC group object on success.
13438
 * @return  NULL when key is NULL.
13439
 */
13440
const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
13441
{
13442
    WOLFSSL_EC_GROUP* group = NULL;
13443
13444
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
13445
13446
    if (key != NULL) {
13447
        group = key->group;
13448
    }
13449
13450
    return group;
13451
}
13452
13453
/* Set the group in WOLFSSL_EC_KEY
13454
 *
13455
 * @param [in, out] key    EC key to update.
13456
 * @param [in]      group  EC group to copy.
13457
 * @return  1 on success
13458
 * @return  0 on failure.
13459
 */
13460
int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
13461
{
13462
    int ret = 1;
13463
13464
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
13465
13466
    /* Validate parameters. */
13467
    if ((key == NULL) || (group == NULL)) {
13468
        ret = 0;
13469
    }
13470
13471
    if (ret == 1) {
13472
        /* Dispose of the current group. */
13473
        if (key->group != NULL) {
13474
            wolfSSL_EC_GROUP_free(key->group);
13475
        }
13476
        /* Duplicate the passed in group into EC key. */
13477
        key->group = wolfSSL_EC_GROUP_dup(group);
13478
        if (key->group == NULL) {
13479
            ret = 0;
13480
        }
13481
    }
13482
13483
    return ret;
13484
}
13485
13486
/* Get the BN object that is the private key in the EC key.
13487
 *
13488
 * @param [in] key  EC key.
13489
 * @return  BN object on success.
13490
 * @return  NULL when key is NULL or private key is not set.
13491
 */
13492
WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
13493
{
13494
    WOLFSSL_BIGNUM* priv_key = NULL;
13495
13496
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
13497
13498
    /* Validate parameter. */
13499
    if (key == NULL) {
13500
        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
13501
    }
13502
    /* Only return private key if it is not 0. */
13503
    else if (!wolfSSL_BN_is_zero(key->priv_key)) {
13504
        priv_key = key->priv_key;
13505
    }
13506
13507
    return priv_key;
13508
}
13509
13510
/* Sets the private key value into EC key.
13511
 *
13512
 * Return code compliant with OpenSSL.
13513
 *
13514
 * @param [in, out] key       EC key to set.
13515
 * @param [in]      priv_key  Private key value in a BN.
13516
 * @return  1 on success
13517
 * @return  0 on failure.
13518
 */
13519
int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
13520
    const WOLFSSL_BIGNUM *priv_key)
13521
{
13522
    int ret = 1;
13523
13524
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
13525
13526
    /* Validate parameters. */
13527
    if ((key == NULL) || (priv_key == NULL)) {
13528
        WOLFSSL_MSG("Bad arguments");
13529
        ret = 0;
13530
    }
13531
13532
    /* Check for obvious invalid values. */
13533
    if (wolfSSL_BN_is_negative(priv_key) || wolfSSL_BN_is_zero(priv_key) ||
13534
            wolfSSL_BN_is_one(priv_key)) {
13535
        WOLFSSL_MSG("Invalid private key value");
13536
        ret = 0;
13537
    }
13538
13539
    if (ret == 1) {
13540
        /* Free key if previously set. */
13541
        if (key->priv_key != NULL) {
13542
            wolfSSL_BN_free(key->priv_key);
13543
        }
13544
13545
        /* Duplicate the BN passed in. */
13546
        key->priv_key = wolfSSL_BN_dup(priv_key);
13547
        if (key->priv_key == NULL) {
13548
            WOLFSSL_MSG("key ecc priv key NULL");
13549
            ret = 0;
13550
        }
13551
    }
13552
    /* Set the external values into internal EC key. */
13553
    if ((ret == 1) && (SetECKeyInternal(key) != 1)) {
13554
        WOLFSSL_MSG("SetECKeyInternal failed");
13555
        /* Dispose of new private key on error. */
13556
        wolfSSL_BN_free(key->priv_key);
13557
        key->priv_key = NULL;
13558
        ret = 0;
13559
    }
13560
13561
    return ret;
13562
}
13563
13564
/* Get the public key EC point object that is in EC key.
13565
 *
13566
 * @param [in] key  EC key.
13567
 * @return  EC point object that is the public key on success.
13568
 * @return  NULL when key is NULL.
13569
 */
13570
WOLFSSL_EC_POINT* wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
13571
{
13572
    WOLFSSL_EC_POINT* pub_key = NULL;
13573
13574
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
13575
13576
    if (key != NULL) {
13577
        pub_key = key->pub_key;
13578
    }
13579
13580
    return pub_key;
13581
}
13582
13583
/*
13584
 * Return code compliant with OpenSSL.
13585
 *
13586
 * @param [in, out] key  EC key.
13587
 * @param [in]      pub  Public key as an EC point.
13588
 * @return  1 on success
13589
 * @return  0 on failure.
13590
 */
13591
int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
13592
    const WOLFSSL_EC_POINT *pub)
13593
{
13594
    int ret = 1;
13595
    ecc_point *pub_p = NULL;
13596
    ecc_point *key_p = NULL;
13597
13598
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
13599
13600
    /* Validate parameters. */
13601
    if ((key == NULL) || (key->internal == NULL) || (pub == NULL) ||
13602
            (pub->internal == NULL)) {
13603
        WOLFSSL_MSG("wolfSSL_EC_KEY_set_public_key Bad arguments");
13604
        ret = 0;
13605
    }
13606
13607
    /* Ensure the internal EC key is set. */
13608
    if ((ret == 1) && (key->inSet == 0) && (SetECKeyInternal(key) != 1)) {
13609
        WOLFSSL_MSG("SetECKeyInternal failed");
13610
        ret = 0;
13611
    }
13612
13613
    /* Ensure the internal EC point of pub is setup. */
13614
    if ((ret == 1) && (ec_point_setup(pub) != 1)) {
13615
        ret = 0;
13616
    }
13617
13618
    if (ret == 1) {
13619
        /* Get the internal point of pub and the public key in key. */
13620
        pub_p = (ecc_point*)pub->internal;
13621
        key_p = (ecc_point*)key->pub_key->internal;
13622
13623
        /* Create new point if required. */
13624
        if (key_p == NULL) {
13625
            key_p = wc_ecc_new_point();
13626
            key->pub_key->internal = (void*)key_p;
13627
        }
13628
        /* Check point available. */
13629
        if (key_p == NULL) {
13630
            WOLFSSL_MSG("key ecc point NULL");
13631
            ret = 0;
13632
        }
13633
    }
13634
13635
    /* Copy the internal pub point into internal key point. */
13636
    if ((ret == 1) && (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY)) {
13637
        WOLFSSL_MSG("ecc_copy_point failure");
13638
        ret = 0;
13639
    }
13640
13641
    /* Copy the internal point data into external. */
13642
    if ((ret == 1) && (ec_point_external_set(key->pub_key) != 1)) {
13643
        WOLFSSL_MSG("SetECKeyInternal failed");
13644
        ret = 0;
13645
    }
13646
13647
    /* Copy the internal key into external. */
13648
    if ((ret == 1) && (SetECKeyInternal(key) != 1)) {
13649
        WOLFSSL_MSG("SetECKeyInternal failed");
13650
        ret = 0;
13651
    }
13652
13653
    if (ret == 1) {
13654
        /* Dump out the point and the key's public key for debug. */
13655
        wolfSSL_EC_POINT_dump("pub", pub);
13656
        wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key);
13657
    }
13658
13659
    return ret;
13660
}
13661
13662
#ifndef NO_WOLFSSL_STUB
13663
/* Set the ASN.1 encoding flag against the EC key.
13664
 *
13665
 * No implementation as only named curves supported for encoding.
13666
 *
13667
 * @param [in, out] key   EC key.
13668
 * @param [in]      flag  ASN.1 flag to set. Valid values:
13669
 *                        OPENSSL_EC_EXPLICIT_CURVE, OPENSSL_EC_NAMED_CURVE
13670
 */
13671
void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
13672
{
13673
    (void)key;
13674
    (void)asn1_flag;
13675
13676
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
13677
    WOLFSSL_STUB("EC_KEY_set_asn1_flag");
13678
}
13679
#endif
13680
13681
/*
13682
 * EC key generate key APIs
13683
 */
13684
13685
/* Generate an EC key.
13686
 *
13687
 * Uses the internal curve index set in the EC key or the default.
13688
 *
13689
 * @param [in, out] key  EC key.
13690
 * @return  1 on success
13691
 * @return  0 on failure.
13692
 */
13693
int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
13694
{
13695
    int res = 1;
13696
    int initTmpRng = 0;
13697
    WC_RNG* rng = NULL;
13698
#ifdef WOLFSSL_SMALL_STACK
13699
    WC_RNG* tmpRng = NULL;
13700
#else
13701
    WC_RNG  tmpRng[1];
13702
#endif
13703
13704
    WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
13705
13706
    /* Validate parameters. */
13707
    if ((key == NULL) || (key->internal == NULL) || (key->group == NULL)) {
13708
        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
13709
        res = 0;
13710
    }
13711
    if (res == 1) {
13712
        /* Check if we know which internal curve index to use. */
13713
        if (key->group->curve_idx < 0) {
13714
            /* Generate key using the default curve. */
13715
#if FIPS_VERSION3_GE(6,0,0)
13716
            key->group->curve_idx = ECC_SECP256R1; /* FIPS default to 256 */
13717
#else
13718
            key->group->curve_idx = ECC_CURVE_DEF;
13719
#endif
13720
        }
13721
13722
        /* Create a random number generator. */
13723
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
13724
        if (rng == NULL) {
13725
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
13726
            res = 0;
13727
        }
13728
    }
13729
    if (res == 1) {
13730
        /* NIDToEccEnum returns -1 for invalid NID so if key->group->curve_nid
13731
         * is 0 then pass ECC_CURVE_DEF as arg */
13732
        int eccEnum = key->group->curve_nid ?
13733
#if FIPS_VERSION3_GE(6,0,0)
13734
            NIDToEccEnum(key->group->curve_nid) : ECC_SECP256R1;
13735
#else
13736
            NIDToEccEnum(key->group->curve_nid) : ECC_CURVE_DEF;
13737
#endif
13738
        /* Get the internal EC key. */
13739
        ecc_key* ecKey = (ecc_key*)key->internal;
13740
        /* Make the key using internal API. */
13741
        int ret = 0;
13742
13743
#if FIPS_VERSION3_GE(6,0,0)
13744
        /* In the case of FIPS only allow key generation with approved curves */
13745
        if (eccEnum != ECC_SECP256R1 && eccEnum != ECC_SECP224R1 &&
13746
            eccEnum != ECC_SECP384R1 && eccEnum != ECC_SECP521R1) {
13747
            WOLFSSL_MSG("Unsupported curve selected in FIPS mode");
13748
            res = 0;
13749
        }
13750
        if (res == 1) {
13751
#endif
13752
        ret  = wc_ecc_make_key_ex(rng, 0, ecKey, eccEnum);
13753
#if FIPS_VERSION3_GE(6,0,0)
13754
        }
13755
#endif
13756
13757
    #if defined(WOLFSSL_ASYNC_CRYPT)
13758
        /* Wait on asynchronouse operation. */
13759
        ret = wc_AsyncWait(ret, &ecKey->asyncDev, WC_ASYNC_FLAG_NONE);
13760
    #endif
13761
        if (ret != 0) {
13762
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
13763
            res = 0;
13764
        }
13765
    }
13766
13767
    /* Dispose of local random number generator if initialized. */
13768
    if (initTmpRng) {
13769
        wc_FreeRng(rng);
13770
    #ifdef WOLFSSL_SMALL_STACK
13771
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
13772
    #endif
13773
    }
13774
13775
    /* Set the external key from new internal key values. */
13776
    if ((res == 1) && (SetECKeyExternal(key) != 1)) {
13777
        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
13778
        res = 0;
13779
    }
13780
13781
    return res;
13782
}
13783
13784
/*
13785
 * EC key check key APIs
13786
 */
13787
13788
/* Check that the EC key is valid.
13789
 *
13790
 * @param [in] key  EC key.
13791
 * @return  1 on valid.
13792
 * @return  0 on invalid or error.
13793
 */
13794
int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key)
13795
{
13796
    int ret = 1;
13797
13798
    WOLFSSL_ENTER("wolfSSL_EC_KEY_check_key");
13799
13800
    /* Validate parameter. */
13801
    if ((key == NULL) || (key->internal == NULL)) {
13802
        WOLFSSL_MSG("Bad parameter");
13803
        ret = 0;
13804
    }
13805
13806
    /* Set the external EC key values into internal if not already. */
13807
    if ((ret == 1) && (key->inSet == 0) && (SetECKeyInternal(
13808
            (WOLFSSL_EC_KEY*)key) != 1)) {
13809
        WOLFSSL_MSG("SetECKeyInternal failed");
13810
        ret = 0;
13811
    }
13812
13813
    if (ret == 1) {
13814
        /* Have internal EC implementation check key. */
13815
        ret = wc_ecc_check_key((ecc_key*)key->internal) == 0;
13816
    }
13817
13818
    return ret;
13819
}
13820
13821
/* End EC_KEY */
13822
13823
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
13824
/* Get the supported, built-in EC curves
13825
 *
13826
 * @param [in, out] curves  Pre-allocated list to put supported curves into.
13827
 * @param [in]      len     Maximum number of items to place in list.
13828
 * @return  Number of built-in EC curves when curves is NULL or len is 0.
13829
 * @return  Number of items placed in list otherwise.
13830
 */
13831
size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *curves,
13832
    size_t len)
13833
{
13834
    size_t i;
13835
    size_t cnt;
13836
#ifdef HAVE_SELFTEST
13837
    /* Defined in ecc.h when available. */
13838
    size_t ecc_sets_count;
13839
13840
    /* Count the pre-defined curves since global not available. */
13841
    for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) {
13842
        /* Do nothing. */
13843
    }
13844
    ecc_sets_count = i;
13845
#endif
13846
13847
    /* Assume we are going to return total count. */
13848
    cnt = ecc_sets_count;
13849
    /* Check we have a list that can hold data. */
13850
    if ((curves != NULL) && (len != 0)) {
13851
        /* Limit count to length of list. */
13852
        if (cnt > len) {
13853
            cnt = len;
13854
        }
13855
13856
        /* Put in built-in EC curve nid and short name. */
13857
        for (i = 0; i < cnt; i++) {
13858
            curves[i].nid = EccEnumToNID(ecc_sets[i].id);
13859
            curves[i].comment = wolfSSL_OBJ_nid2sn(curves[i].nid);
13860
        }
13861
    }
13862
13863
    return cnt;
13864
}
13865
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
13866
13867
/* Start ECDSA_SIG */
13868
13869
/* Allocate a new ECDSA signature object.
13870
 *
13871
 * @return  New, allocated ECDSA signature object on success.
13872
 * @return  NULL on error.
13873
 */
13874
WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
13875
{
13876
    int err = 0;
13877
    WOLFSSL_ECDSA_SIG *sig;
13878
13879
    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
13880
13881
    /* Allocate memory for ECDSA signature object. */
13882
    sig = (WOLFSSL_ECDSA_SIG*)XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
13883
        DYNAMIC_TYPE_ECC);
13884
    if (sig == NULL) {
13885
        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
13886
        err = 1;
13887
    }
13888
13889
    if (!err) {
13890
        /* Set s to NULL in case of error. */
13891
        sig->s = NULL;
13892
        /* Allocate BN into r. */
13893
        sig->r = wolfSSL_BN_new();
13894
        if (sig->r == NULL) {
13895
            WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
13896
            err = 1;
13897
        }
13898
    }
13899
    if (!err) {
13900
        /* Allocate BN into s. */
13901
        sig->s = wolfSSL_BN_new();
13902
        if (sig->s == NULL) {
13903
            WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
13904
            err = 1;
13905
        }
13906
    }
13907
13908
    if (err && (sig != NULL)) {
13909
        /* Dispose of allocated memory. */
13910
        wolfSSL_ECDSA_SIG_free(sig);
13911
        sig = NULL;
13912
    }
13913
    return sig;
13914
}
13915
13916
/* Dispose of ECDSA signature object.
13917
 *
13918
 * Cannot use object after this call.
13919
 *
13920
 * @param [in] sig  ECDSA signature object to free.
13921
 */
13922
void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
13923
{
13924
    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
13925
13926
    if (sig != NULL) {
13927
        /* Dispose of BNs allocated for r and s. */
13928
        wolfSSL_BN_free(sig->r);
13929
        wolfSSL_BN_free(sig->s);
13930
13931
        /* Dispose of memory associated with ECDSA signature object. */
13932
        XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
13933
    }
13934
}
13935
13936
/* Create an ECDSA signature from the DER encoding.
13937
 *
13938
 * @param [in, out] sig  Reference to ECDSA signature object. May be NULL.
13939
 * @param [in, out] pp   On in, reference to buffer containing DER encoding.
13940
 *                       On out, reference to buffer after signature data.
13941
 * @param [in]      len  Length of the data in the buffer. May be more than
13942
 *                       the length of the signature.
13943
 * @return  ECDSA signature object on success.
13944
 * @return  NULL on error.
13945
 */
13946
WOLFSSL_ECDSA_SIG* wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG** sig,
13947
    const unsigned char** pp, long len)
13948
{
13949
    int err = 0;
13950
    /* ECDSA signature object to return. */
13951
    WOLFSSL_ECDSA_SIG *s = NULL;
13952
13953
    /* Validate parameter. */
13954
    if (pp == NULL) {
13955
        err = 1;
13956
    }
13957
    if (!err) {
13958
        if (sig != NULL) {
13959
            /* Use the ECDSA signature object passed in. */
13960
            s = *sig;
13961
        }
13962
        if (s == NULL) {
13963
            /* No ECDSA signature object passed in - create a new one. */
13964
            s = wolfSSL_ECDSA_SIG_new();
13965
            if (s == NULL) {
13966
                err = 1;
13967
            }
13968
        }
13969
    }
13970
    if (!err) {
13971
        /* DecodeECC_DSA_Sig calls mp_init, so free these. */
13972
        mp_free((mp_int*)s->r->internal);
13973
        mp_free((mp_int*)s->s->internal);
13974
13975
        /* Decode the signature into internal r and s fields. */
13976
        if (DecodeECC_DSA_Sig(*pp, (word32)len, (mp_int*)s->r->internal,
13977
                (mp_int*)s->s->internal) != MP_OKAY) {
13978
            err = 1;
13979
        }
13980
    }
13981
13982
    if (!err) {
13983
        /* Move pointer passed signature data successfully decoded. */
13984
        *pp += wolfssl_der_length(*pp, (int)len);
13985
        if (sig != NULL) {
13986
            /* Update reference to ECDSA signature object. */
13987
            *sig = s;
13988
        }
13989
    }
13990
13991
    /* Dispose of newly allocated object on error. */
13992
    if (err) {
13993
        if ((s != NULL) && ((sig == NULL) || (*sig != s))) {
13994
            wolfSSL_ECDSA_SIG_free(s);
13995
        }
13996
        /* Return NULL for object on error. */
13997
        s = NULL;
13998
    }
13999
    return s;
14000
}
14001
14002
/* Encode the ECDSA signature as DER.
14003
 *
14004
 * @param [in]      sig  ECDSA signature object.
14005
 * @param [in, out] pp   On in, reference to buffer in which to place encoding.
14006
 *                       On out, reference to buffer after encoding.
14007
 *                       May be NULL or point to NULL in which case no encoding
14008
 *                       is done.
14009
 * @return  Length of encoding on success.
14010
 * @return  0 on error.
14011
 */
14012
int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp)
14013
{
14014
    word32 len = 0;
14015
    int    update_p = 1;
14016
14017
    /* Validate parameter. */
14018
    if (sig != NULL) {
14019
        /* ASN.1: SEQ + INT + INT
14020
         *   ASN.1 Integer must be a positive value - prepend zero if number has
14021
         *   top bit set.
14022
         */
14023
        /* Get total length of r including any prepended zero. */
14024
        word32 rLen = (word32)(mp_leading_bit((mp_int*)sig->r->internal) +
14025
               mp_unsigned_bin_size((mp_int*)sig->r->internal));
14026
        /* Get total length of s including any prepended zero. */
14027
        word32 sLen = (word32)(mp_leading_bit((mp_int*)sig->s->internal) +
14028
               mp_unsigned_bin_size((mp_int*)sig->s->internal));
14029
        /* Calculate length of data in sequence. */
14030
        len = (word32)1 + ASN_LEN_SIZE(rLen) + rLen +
14031
              (word32)1 + ASN_LEN_SIZE(sLen) + sLen;
14032
        /* Add in the length of the SEQUENCE. */
14033
        len += (word32)1 + ASN_LEN_SIZE(len);
14034
14035
        #ifdef WOLFSSL_I2D_ECDSA_SIG_ALLOC
14036
        if ((pp != NULL) && (*pp == NULL)) {
14037
            *pp = (unsigned char *)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
14038
            if (*pp != NULL) {
14039
                WOLFSSL_MSG("malloc error");
14040
                return 0;
14041
            }
14042
            update_p = 0;
14043
        }
14044
        #endif
14045
14046
        /* Encode only if there is a buffer to encode into. */
14047
        if ((pp != NULL) && (*pp != NULL)) {
14048
            /* Encode using the internal representations of r and s. */
14049
            if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal,
14050
                    (mp_int*)sig->s->internal) != MP_OKAY) {
14051
                /* No bytes encoded. */
14052
                len = 0;
14053
            }
14054
            else if (update_p) {
14055
                /* Update pointer to after encoding. */
14056
                *pp += len;
14057
            }
14058
        }
14059
    }
14060
14061
    return (int)len;
14062
}
14063
14064
/* Get the pointer to the fields of the ECDSA signature.
14065
 *
14066
 * r and s untouched when sig is NULL.
14067
 *
14068
 * @param [in]  sig  ECDSA signature object.
14069
 * @param [out] r    R field of ECDSA signature as a BN. May be NULL.
14070
 * @param [out] s    S field of ECDSA signature as a BN. May be NULL.
14071
 */
14072
void wolfSSL_ECDSA_SIG_get0(const WOLFSSL_ECDSA_SIG* sig,
14073
    const WOLFSSL_BIGNUM** r, const WOLFSSL_BIGNUM** s)
14074
{
14075
    /* Validate parameter. */
14076
    if (sig != NULL) {
14077
        /* Return the r BN when pointer to return through. */
14078
        if (r != NULL) {
14079
            *r = sig->r;
14080
        }
14081
        /* Return the s BN when pointer to return through. */
14082
        if (s != NULL) {
14083
            *s = sig->s;
14084
        }
14085
    }
14086
}
14087
14088
/* Set the pointers to the fields of the ECDSA signature.
14089
 *
14090
 * @param [in, out] sig  ECDSA signature object to update.
14091
 * @param [in]      r    R field of ECDSA signature as a BN.
14092
 * @param [in]      s    S field of ECDSA signature as a BN.
14093
 * @return  1 on success.
14094
 * @return  0 on error.
14095
 */
14096
int wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG* sig, WOLFSSL_BIGNUM* r,
14097
    WOLFSSL_BIGNUM* s)
14098
{
14099
    int ret = 1;
14100
14101
    /* Validate parameters. */
14102
    if ((sig == NULL) || (r == NULL) || (s == NULL)) {
14103
        ret = 0;
14104
    }
14105
14106
    if (ret == 1) {
14107
        /* Dispose of old BN objects. */
14108
        wolfSSL_BN_free(sig->r);
14109
        wolfSSL_BN_free(sig->s);
14110
14111
        /* Assign new BN objects. */
14112
        sig->r = r;
14113
        sig->s = s;
14114
    }
14115
14116
    return ret;
14117
}
14118
14119
/* End ECDSA_SIG */
14120
14121
/* Start ECDSA */
14122
14123
/* Calculate maximum size of the DER encoded ECDSA signature for the curve.
14124
 *
14125
 * @param [in] key  EC key.
14126
 * @return  Size of DER encoded signature on success.
14127
 * @return  0 on error.
14128
 */
14129
int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key)
14130
{
14131
    int err = 0;
14132
    int len = 0;
14133
    const WOLFSSL_EC_GROUP *group = NULL;
14134
    int bits = 0;
14135
14136
    /* Validate parameter. */
14137
    if (key == NULL) {
14138
        err = 1;
14139
    }
14140
14141
    /* Get group from key to get order bits. */
14142
    if ((!err) && ((group = wolfSSL_EC_KEY_get0_group(key)) == NULL)) {
14143
        err = 1;
14144
    }
14145
    /* Get order bits of group. */
14146
    if ((!err) && ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0)) {
14147
        /* Group is not set. */
14148
        err = 1;
14149
    }
14150
14151
    if (!err) {
14152
        /* r and s are mod order. */
14153
        int bytes = (bits + 7) / 8;  /* Bytes needed to hold bits. */
14154
        len = SIG_HEADER_SZ + /* 2*ASN_TAG + 2*LEN(ENUM) */
14155
            ECC_MAX_PAD_SZ +  /* possible leading zeroes in r and s */
14156
            bytes + bytes;    /* max r and s in bytes */
14157
    }
14158
14159
    return len;
14160
}
14161
14162
/* Create ECDSA signature by signing digest with key.
14163
 *
14164
 * @param [in] dgst  Digest to sign.
14165
 * @param [in] dLen  Length of digest in bytes.
14166
 * @param [in] key   EC key to sign with.
14167
 * @return  ECDSA signature object on success.
14168
 * @return  NULL on error.
14169
 */
14170
WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *dgst, int dLen,
14171
    WOLFSSL_EC_KEY *key)
14172
{
14173
    int err = 0;
14174
    WOLFSSL_ECDSA_SIG *sig = NULL;
14175
#ifdef WOLFSSL_SMALL_STACK
14176
    byte*   out = NULL;
14177
#else
14178
    byte    out[ECC_BUFSIZE];
14179
#endif
14180
    unsigned int outLen = ECC_BUFSIZE;
14181
14182
    WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
14183
14184
    /* Validate parameters. */
14185
    if ((dgst == NULL) || (key == NULL) || (key->internal == NULL)) {
14186
        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
14187
        err = 1;
14188
    }
14189
14190
    /* Ensure internal EC key is set from external. */
14191
    if ((!err) && (key->inSet == 0)) {
14192
        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
14193
14194
        if (SetECKeyInternal(key) != 1) {
14195
            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
14196
            err = 1;
14197
        }
14198
    }
14199
14200
#ifdef WOLFSSL_SMALL_STACK
14201
    if (!err) {
14202
        /* Allocate buffer to hold encoded signature. */
14203
        out = (byte*)XMALLOC(outLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14204
        if (out == NULL) {
14205
            err = 1;
14206
        }
14207
    }
14208
#endif
14209
14210
    /* Sign the digest with the key to create encoded ECDSA signature. */
14211
    if ((!err) && (wolfSSL_ECDSA_sign(0, dgst, dLen, out, &outLen, key) != 1)) {
14212
        err = 1;
14213
    }
14214
14215
    if (!err) {
14216
        const byte* p = out;
14217
        /* Decode the ECDSA signature into a new object. */
14218
        sig = wolfSSL_d2i_ECDSA_SIG(NULL, &p, outLen);
14219
    }
14220
14221
#ifdef WOLFSSL_SMALL_STACK
14222
    /* Dispose of any temporary dynamically allocated data. */
14223
    XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14224
#endif
14225
14226
    return sig;
14227
}
14228
14229
/* Verify ECDSA signature in the object using digest and key.
14230
 *
14231
 * Return code compliant with OpenSSL.
14232
 *
14233
 * @param [in] dgst  Digest to verify.
14234
 * @param [in] dLen  Length of the digest in bytes.
14235
 * @param [in] sig   ECDSA signature object.
14236
 * @param [in] key   EC key containing public key.
14237
 * @return  1 when signature is valid.
14238
 * @return  0 when signature is invalid.
14239
 * @return  -1 on error.
14240
 */
14241
int wolfSSL_ECDSA_do_verify(const unsigned char *dgst, int dLen,
14242
    const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
14243
{
14244
    int ret = 1;
14245
    int verified = 0;
14246
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
14247
    byte signature[ECC_MAX_SIG_SIZE];
14248
    int signatureLen;
14249
    byte* p = signature;
14250
#endif
14251
14252
    WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
14253
14254
    /* Validate parameters. */
14255
    if ((dgst == NULL) || (sig == NULL) || (key == NULL) ||
14256
            (key->internal == NULL)) {
14257
        WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
14258
        ret = WOLFSSL_FATAL_ERROR;
14259
    }
14260
14261
    /* Ensure internal EC key is set from external. */
14262
    if ((ret == 1) && (key->inSet == 0)) {
14263
        WOLFSSL_MSG("No EC key internal set, do it");
14264
14265
        if (SetECKeyInternal(key) != 1) {
14266
            WOLFSSL_MSG("SetECKeyInternal failed");
14267
            ret = WOLFSSL_FATAL_ERROR;
14268
        }
14269
    }
14270
14271
    if (ret == 1) {
14272
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
14273
        /* Verify hash using digest, r and s as MP ints and internal EC key. */
14274
        if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
14275
                (mp_int*)sig->s->internal, dgst, (word32)dLen, &verified,
14276
                (ecc_key *)key->internal) != MP_OKAY) {
14277
            WOLFSSL_MSG("wc_ecc_verify_hash failed");
14278
            ret = WOLFSSL_FATAL_ERROR;
14279
        }
14280
        else if (verified == 0) {
14281
            WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
14282
            ret = 0;
14283
        }
14284
#else
14285
        signatureLen = i2d_ECDSA_SIG(sig, &p);
14286
        if (signatureLen > 0) {
14287
            /* verify hash. expects to call wc_CryptoCb_EccVerify internally */
14288
            ret = wc_ecc_verify_hash(signature, signatureLen, dgst,
14289
                (word32)dLen, &verified, (ecc_key*)key->internal);
14290
            if (ret != MP_OKAY) {
14291
                WOLFSSL_MSG("wc_ecc_verify_hash failed");
14292
                ret = WOLFSSL_FATAL_ERROR;
14293
            }
14294
            else if (verified == 0) {
14295
                WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
14296
                ret = 0;
14297
            }
14298
        }
14299
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
14300
    }
14301
14302
    return ret;
14303
}
14304
14305
/* Sign the digest with the key to produce a DER encode signature.
14306
 *
14307
 * @param [in]      type      Digest algorithm used to create digest. Unused.
14308
 * @param [in]      digest    Digest of the message to sign.
14309
 * @param [in]      digestSz  Size of the digest in bytes.
14310
 * @param [out]     sig       Buffer to hold signature.
14311
 * @param [in, out] sigSz     On in, size of buffer in bytes.
14312
 *                            On out, size of signatre in bytes.
14313
 * @param [in]      key       EC key containing private key.
14314
 * @return  1 on success.
14315
 * @return  0 on error.
14316
 */
14317
int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, int digestSz,
14318
    unsigned char *sig, unsigned int *sigSz, WOLFSSL_EC_KEY *key)
14319
{
14320
    int ret = 1;
14321
    WC_RNG* rng = NULL;
14322
#ifdef WOLFSSL_SMALL_STACK
14323
    WC_RNG* tmpRng = NULL;
14324
#else
14325
    WC_RNG  tmpRng[1];
14326
#endif
14327
    int initTmpRng = 0;
14328
14329
    WOLFSSL_ENTER("wolfSSL_ECDSA_sign");
14330
14331
    /* Digest algorithm not used in DER encoding. */
14332
    (void)type;
14333
14334
    /* Validate parameters. */
14335
    if (key == NULL) {
14336
        ret = 0;
14337
    }
14338
14339
    if (ret == 1) {
14340
        /* Make an RNG - create local or get global. */
14341
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
14342
        if (rng == NULL) {
14343
            ret = 0;
14344
        }
14345
    }
14346
    /* Sign the digest with the key using the RNG and put signature into buffer
14347
     * update sigSz to be actual length.
14348
     */
14349
    if ((ret == 1) && (wc_ecc_sign_hash(digest, (word32)digestSz, sig, sigSz,
14350
            rng, (ecc_key*)key->internal) != 0)) {
14351
        ret = 0;
14352
    }
14353
14354
    if (initTmpRng) {
14355
        wc_FreeRng(rng);
14356
    #ifdef WOLFSSL_SMALL_STACK
14357
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
14358
    #endif
14359
    }
14360
14361
    return ret;
14362
}
14363
14364
/* Verify the signature with the digest and key.
14365
 *
14366
 * @param [in] type      Digest algorithm used to create digest. Unused.
14367
 * @param [in] digest    Digest of the message to verify.
14368
 * @param [in] digestSz  Size of the digest in bytes.
14369
 * @param [in] sig       Buffer holding signature.
14370
 * @param [in] sigSz     Size of signature data in bytes.
14371
 * @param [in] key       EC key containing public key.
14372
 * @return  1 when signature is valid.
14373
 * @return  0 when signature is invalid or error.
14374
 */
14375
int wolfSSL_ECDSA_verify(int type, const unsigned char *digest, int digestSz,
14376
    const unsigned char *sig, int sigSz, WOLFSSL_EC_KEY *key)
14377
{
14378
    int ret = 1;
14379
    int verify = 0;
14380
14381
    WOLFSSL_ENTER("wolfSSL_ECDSA_verify");
14382
14383
    /* Digest algorithm not used in DER encoding. */
14384
    (void)type;
14385
14386
    /* Validate parameters. */
14387
    if (key == NULL) {
14388
        ret = 0;
14389
    }
14390
14391
    /* Verify signature using digest and key. */
14392
    if ((ret == 1) && (wc_ecc_verify_hash(sig, (word32)sigSz, digest,
14393
            (word32)digestSz, &verify, (ecc_key*)key->internal) != 0)) {
14394
        ret = 0;
14395
    }
14396
    /* When no error, verification may still have failed - check now. */
14397
    if ((ret == 1) && (verify != 1)) {
14398
        WOLFSSL_MSG("wolfSSL_ECDSA_verify failed");
14399
        ret = 0;
14400
    }
14401
14402
    return ret;
14403
}
14404
14405
/* End ECDSA */
14406
14407
/* Start ECDH */
14408
14409
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
14410
/* Compute the shared secret (key) using ECDH.
14411
 *
14412
 * KDF not supported.
14413
 *
14414
 * Return code compliant with OpenSSL.
14415
 *
14416
 * @param [out] out      Buffer to hold key.
14417
 * @param [in]  outLen   Length of buffer in bytes.
14418
 * @param [in]  pubKey   Public key as an EC point.
14419
 * @param [in]  privKey  EC key holding a private key.
14420
 * @param [in]  kdf      Key derivation function to apply to secret.
14421
 * @return  Length of computed key on success
14422
 * @return  0 on error.
14423
 */
14424
int wolfSSL_ECDH_compute_key(void *out, size_t outLen,
14425
    const WOLFSSL_EC_POINT *pubKey, WOLFSSL_EC_KEY *privKey,
14426
    void *(*kdf) (const void *in, size_t inlen, void *out, size_t *outLen))
14427
{
14428
    int err = 0;
14429
    word32 len = 0;
14430
    ecc_key* key = NULL;
14431
#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
14432
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
14433
    int setGlobalRNG = 0;
14434
#endif
14435
14436
    /* TODO: support using the KDF. */
14437
    (void)kdf;
14438
14439
    WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
14440
14441
    /* Validate parameters. */
14442
    if ((out == NULL) || (pubKey == NULL) || (pubKey->internal == NULL) ||
14443
        (privKey == NULL) || (privKey->internal == NULL)) {
14444
        WOLFSSL_MSG("Bad function arguments");
14445
        err = 1;
14446
    }
14447
14448
    /* Ensure internal EC key is set from external. */
14449
    if ((!err) && (privKey->inSet == 0)) {
14450
        WOLFSSL_MSG("No EC key internal set, do it");
14451
14452
        if (SetECKeyInternal(privKey) != 1) {
14453
            WOLFSSL_MSG("SetECKeyInternal failed");
14454
            err = 1;
14455
        }
14456
    }
14457
14458
    if (!err) {
14459
        int ret;
14460
14461
        /* Get the internal key. */
14462
        key = (ecc_key*)privKey->internal;
14463
        /* Set length into variable of type suitable for wolfSSL API. */
14464
        len = (word32)outLen;
14465
14466
    #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
14467
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
14468
        /* An RNG is needed. */
14469
        if (key->rng == NULL) {
14470
            key->rng = wolfssl_make_global_rng();
14471
            /* RNG set and needs to be unset. */
14472
            setGlobalRNG = 1;
14473
        }
14474
    #endif
14475
14476
        PRIVATE_KEY_UNLOCK();
14477
        /* Create secret using wolfSSL. */
14478
        ret = wc_ecc_shared_secret_ex(key, (ecc_point*)pubKey->internal,
14479
            (byte *)out, &len);
14480
        PRIVATE_KEY_LOCK();
14481
        if (ret != MP_OKAY) {
14482
            WOLFSSL_MSG("wc_ecc_shared_secret failed");
14483
            err = 1;
14484
        }
14485
    }
14486
14487
#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
14488
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
14489
    /* Remove global from key. */
14490
    if (setGlobalRNG) {
14491
        key->rng = NULL;
14492
    }
14493
#endif
14494
14495
    if (err) {
14496
        /* Make returned value zero. */
14497
        len = 0;
14498
    }
14499
    return (int)len;
14500
}
14501
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
14502
14503
/* End ECDH */
14504
14505
#ifndef NO_WOLFSSL_STUB
14506
const WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_OpenSSL(void)
14507
{
14508
    WOLFSSL_STUB("wolfSSL_EC_KEY_OpenSSL");
14509
14510
    return NULL;
14511
}
14512
14513
WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_METHOD_new(
14514
        const WOLFSSL_EC_KEY_METHOD *meth)
14515
{
14516
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_new");
14517
14518
    (void)meth;
14519
14520
    return NULL;
14521
}
14522
14523
void wolfSSL_EC_KEY_METHOD_free(WOLFSSL_EC_KEY_METHOD *meth)
14524
{
14525
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_free");
14526
14527
    (void)meth;
14528
}
14529
14530
void wolfSSL_EC_KEY_METHOD_set_init(WOLFSSL_EC_KEY_METHOD *meth,
14531
        void* a1, void* a2, void* a3, void* a4, void* a5, void* a6)
14532
{
14533
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_set_init");
14534
14535
    (void)meth;
14536
    (void)a1;
14537
    (void)a2;
14538
    (void)a3;
14539
    (void)a4;
14540
    (void)a5;
14541
    (void)a6;
14542
}
14543
14544
void wolfSSL_EC_KEY_METHOD_set_sign(WOLFSSL_EC_KEY_METHOD *meth,
14545
        void* a1, void* a2, void* a3)
14546
{
14547
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_set_sign");
14548
14549
    (void)meth;
14550
    (void)a1;
14551
    (void)a2;
14552
    (void)a3;
14553
}
14554
14555
const WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_get_method(
14556
        const WOLFSSL_EC_KEY *key)
14557
{
14558
    WOLFSSL_STUB("wolfSSL_EC_KEY_get_method");
14559
14560
    (void)key;
14561
14562
    return NULL;
14563
}
14564
14565
int wolfSSL_EC_KEY_set_method(WOLFSSL_EC_KEY *key,
14566
        const WOLFSSL_EC_KEY_METHOD *meth)
14567
{
14568
    WOLFSSL_STUB("wolfSSL_EC_KEY_set_method");
14569
14570
    (void)key;
14571
    (void)meth;
14572
14573
    return 0;
14574
}
14575
14576
#endif /* !NO_WOLFSSL_STUB */
14577
14578
#endif /* OPENSSL_EXTRA */
14579
14580
#endif /* HAVE_ECC */
14581
14582
/*******************************************************************************
14583
 * END OF EC API
14584
 ******************************************************************************/
14585
14586
/*******************************************************************************
14587
 * START OF EC25519 API
14588
 ******************************************************************************/
14589
14590
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
14591
14592
/* Generate an EC25519 key pair.
14593
 *
14594
 * Output keys are in little endian format.
14595
 *
14596
 * @param [out]     priv    EC25519 private key data.
14597
 * @param [in, out] privSz  On in, the size of priv in bytes.
14598
 *                          On out, the length of the private key data in bytes.
14599
 * @param [out]     pub     EC25519 public key data.
14600
 * @param [in, out] pubSz   On in, the size of pub in bytes.
14601
 *                          On out, the length of the public key data in bytes.
14602
 * @return  1 on success
14603
 * @return  0 on failure.
14604
 */
14605
int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
14606
    unsigned char *pub, unsigned int *pubSz)
14607
{
14608
#ifdef WOLFSSL_KEY_GEN
14609
    int res = 1;
14610
    int initTmpRng = 0;
14611
    WC_RNG *rng = NULL;
14612
#ifdef WOLFSSL_SMALL_STACK
14613
    WC_RNG *tmpRng = NULL;
14614
#else
14615
    WC_RNG tmpRng[1];
14616
#endif
14617
    curve25519_key key;
14618
14619
    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
14620
14621
    /* Validate parameters. */
14622
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE25519_KEYSIZE) ||
14623
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE25519_KEYSIZE)) {
14624
        WOLFSSL_MSG("Bad arguments");
14625
        res = 0;
14626
    }
14627
14628
    if (res) {
14629
        /* Create a random number generator. */
14630
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
14631
        if (rng == NULL) {
14632
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
14633
            res = 0;
14634
        }
14635
    }
14636
14637
    /* Initialize a Curve25519 key. */
14638
    if (res && (wc_curve25519_init(&key) != 0)) {
14639
        WOLFSSL_MSG("wc_curve25519_init failed");
14640
        res = 0;
14641
    }
14642
    if (res) {
14643
        /* Make a Curve25519 key pair. */
14644
        int ret = wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key);
14645
        if (ret != MP_OKAY) {
14646
            WOLFSSL_MSG("wc_curve25519_make_key failed");
14647
            res = 0;
14648
        }
14649
        if (res) {
14650
            /* Export Curve25519 key pair to buffers. */
14651
            ret = wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
14652
                pubSz, EC25519_LITTLE_ENDIAN);
14653
            if (ret != MP_OKAY) {
14654
                WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
14655
                res = 0;
14656
            }
14657
        }
14658
14659
        /* Dispose of key. */
14660
        wc_curve25519_free(&key);
14661
    }
14662
14663
    if (initTmpRng) {
14664
        wc_FreeRng(rng);
14665
    #ifdef WOLFSSL_SMALL_STACK
14666
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
14667
    #endif
14668
    }
14669
14670
    return res;
14671
#else
14672
    WOLFSSL_MSG("No Key Gen built in");
14673
14674
    (void)priv;
14675
    (void)privSz;
14676
    (void)pub;
14677
    (void)pubSz;
14678
14679
    return 0;
14680
#endif /* WOLFSSL_KEY_GEN */
14681
}
14682
14683
/* Compute a shared secret from private and public EC25519 keys.
14684
 *
14685
 * Input and output keys are in little endian format
14686
 *
14687
 * @param [out]     shared    Shared secret buffer.
14688
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
14689
 *                            On out, the length of the secret in bytes.
14690
 * @param [in]      priv      EC25519 private key data.
14691
 * @param [in]      privSz    Length of the private key data in bytes.
14692
 * @param [in]      pub       EC25519 public key data.
14693
 * @param [in]      pubSz     Length of the public key data in bytes.
14694
 * @return  1 on success
14695
 * @return  0 on failure.
14696
 */
14697
int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
14698
    const unsigned char *priv, unsigned int privSz, const unsigned char *pub,
14699
    unsigned int pubSz)
14700
{
14701
#ifdef WOLFSSL_KEY_GEN
14702
    int res = 1;
14703
    curve25519_key privkey;
14704
    curve25519_key pubkey;
14705
14706
    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
14707
14708
    /* Validate parameters. */
14709
    if ((shared == NULL) || (sharedSz == NULL) ||
14710
            (*sharedSz < CURVE25519_KEYSIZE) || (priv == NULL) ||
14711
            (privSz < CURVE25519_KEYSIZE) || (pub == NULL) ||
14712
            (pubSz < CURVE25519_KEYSIZE)) {
14713
        WOLFSSL_MSG("Bad arguments");
14714
        res = 0;
14715
    }
14716
14717
    /* Initialize private key object. */
14718
    if (res && (wc_curve25519_init(&privkey) != 0)) {
14719
        WOLFSSL_MSG("wc_curve25519_init privkey failed");
14720
        res = 0;
14721
    }
14722
    if (res) {
14723
    #ifdef WOLFSSL_CURVE25519_BLINDING
14724
        /* An RNG is needed. */
14725
        if (wc_curve25519_set_rng(&privkey, wolfssl_make_global_rng()) != 0) {
14726
            res = 0;
14727
        }
14728
        else
14729
    #endif
14730
        /* Initialize public key object. */
14731
        if (wc_curve25519_init(&pubkey) != MP_OKAY) {
14732
            WOLFSSL_MSG("wc_curve25519_init pubkey failed");
14733
            res = 0;
14734
        }
14735
        if (res) {
14736
            /* Import our private key. */
14737
            int ret = wc_curve25519_import_private_ex(priv, privSz, &privkey,
14738
                EC25519_LITTLE_ENDIAN);
14739
            if (ret != 0) {
14740
                WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
14741
                res = 0;
14742
            }
14743
14744
            if (res) {
14745
                /* Import peer's public key. */
14746
                ret = wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
14747
                    EC25519_LITTLE_ENDIAN);
14748
                if (ret != 0) {
14749
                    WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
14750
                    res = 0;
14751
                }
14752
            }
14753
            if (res) {
14754
                /* Compute shared secret. */
14755
                ret = wc_curve25519_shared_secret_ex(&privkey, &pubkey, shared,
14756
                    sharedSz, EC25519_LITTLE_ENDIAN);
14757
                if (ret != 0) {
14758
                    WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
14759
                    res = 0;
14760
                }
14761
            }
14762
14763
            wc_curve25519_free(&pubkey);
14764
        }
14765
        wc_curve25519_free(&privkey);
14766
    }
14767
14768
    return res;
14769
#else
14770
    WOLFSSL_MSG("No Key Gen built in");
14771
14772
    (void)shared;
14773
    (void)sharedSz;
14774
    (void)priv;
14775
    (void)privSz;
14776
    (void)pub;
14777
    (void)pubSz;
14778
14779
    return 0;
14780
#endif /* WOLFSSL_KEY_GEN */
14781
}
14782
#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
14783
14784
/*******************************************************************************
14785
 * END OF EC25519 API
14786
 ******************************************************************************/
14787
14788
/*******************************************************************************
14789
 * START OF ED25519 API
14790
 ******************************************************************************/
14791
14792
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
14793
/* Generate an ED25519 key pair.
14794
 *
14795
 * Output keys are in little endian format.
14796
 *
14797
 * @param [out]     priv    ED25519 private key data.
14798
 * @param [in, out] privSz  On in, the size of priv in bytes.
14799
 *                          On out, the length of the private key data in bytes.
14800
 * @param [out]     pub     ED25519 public key data.
14801
 * @param [in, out] pubSz   On in, the size of pub in bytes.
14802
 *                          On out, the length of the public key data in bytes.
14803
 * @return  1 on success
14804
 * @return  0 on failure.
14805
 */
14806
int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
14807
    unsigned char *pub, unsigned int *pubSz)
14808
{
14809
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED25519_KEY_EXPORT)
14810
    int res = 1;
14811
    int initTmpRng = 0;
14812
    WC_RNG *rng = NULL;
14813
#ifdef WOLFSSL_SMALL_STACK
14814
    WC_RNG *tmpRng = NULL;
14815
#else
14816
    WC_RNG tmpRng[1];
14817
#endif
14818
    ed25519_key key;
14819
14820
    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
14821
14822
    /* Validate parameters. */
14823
    if ((priv == NULL) || (privSz == NULL) ||
14824
            (*privSz < ED25519_PRV_KEY_SIZE) || (pub == NULL) ||
14825
            (pubSz == NULL) || (*pubSz < ED25519_PUB_KEY_SIZE)) {
14826
        WOLFSSL_MSG("Bad arguments");
14827
        res = 0;
14828
    }
14829
14830
    if (res) {
14831
        /* Create a random number generator. */
14832
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
14833
        if (rng == NULL) {
14834
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
14835
            res = 0;
14836
        }
14837
    }
14838
14839
    /* Initialize an Ed25519 key. */
14840
    if (res && (wc_ed25519_init(&key) != 0)) {
14841
        WOLFSSL_MSG("wc_ed25519_init failed");
14842
        res = 0;
14843
    }
14844
    if (res) {
14845
        /* Make an Ed25519 key pair. */
14846
        int ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key);
14847
        if (ret != 0) {
14848
            WOLFSSL_MSG("wc_ed25519_make_key failed");
14849
            res = 0;
14850
        }
14851
        if (res) {
14852
            /* Export Curve25519 key pair to buffers. */
14853
            ret = wc_ed25519_export_key(&key, priv, privSz, pub, pubSz);
14854
            if (ret != 0) {
14855
                WOLFSSL_MSG("wc_ed25519_export_key failed");
14856
                res = 0;
14857
            }
14858
        }
14859
14860
        wc_ed25519_free(&key);
14861
    }
14862
14863
    if (initTmpRng) {
14864
        wc_FreeRng(rng);
14865
    #ifdef WOLFSSL_SMALL_STACK
14866
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
14867
    #endif
14868
    }
14869
14870
    return res;
14871
#else
14872
#ifndef WOLFSSL_KEY_GEN
14873
    WOLFSSL_MSG("No Key Gen built in");
14874
#else
14875
    WOLFSSL_MSG("No ED25519 key export built in");
14876
#endif
14877
14878
    (void)priv;
14879
    (void)privSz;
14880
    (void)pub;
14881
    (void)pubSz;
14882
14883
    return 0;
14884
#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
14885
}
14886
14887
/* Sign a message with Ed25519 using the private key.
14888
 *
14889
 * Input and output keys are in little endian format.
14890
 * Priv is a buffer containing private and public part of key.
14891
 *
14892
 * @param [in]      msg     Message to be signed.
14893
 * @param [in]      msgSz   Length of message in bytes.
14894
 * @param [in]      priv    ED25519 private key data.
14895
 * @param [in]      privSz  Length in bytes of private key data.
14896
 * @param [out]     sig     Signature buffer.
14897
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
14898
 *                          On out, the length of the signature in bytes.
14899
 * @return  1 on success
14900
 * @return  0 on failure.
14901
 */
14902
int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
14903
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
14904
    unsigned int *sigSz)
14905
{
14906
#if defined(HAVE_ED25519_SIGN) && defined(WOLFSSL_KEY_GEN) && \
14907
    defined(HAVE_ED25519_KEY_IMPORT)
14908
    ed25519_key key;
14909
    int res = 1;
14910
14911
    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
14912
14913
    /* Validate parameters. */
14914
    if ((priv == NULL) || (privSz != ED25519_PRV_KEY_SIZE) ||
14915
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
14916
            (*sigSz < ED25519_SIG_SIZE)) {
14917
        WOLFSSL_MSG("Bad arguments");
14918
        res = 0;
14919
    }
14920
14921
    /* Initialize Ed25519 key. */
14922
    if (res && (wc_ed25519_init(&key) != 0)) {
14923
        WOLFSSL_MSG("wc_curve25519_init failed");
14924
        res = 0;
14925
    }
14926
    if (res) {
14927
        /* Import private and public key. */
14928
        int ret = wc_ed25519_import_private_key(priv, privSz / 2,
14929
            priv + (privSz / 2), ED25519_PUB_KEY_SIZE, &key);
14930
        if (ret != 0) {
14931
            WOLFSSL_MSG("wc_ed25519_import_private failed");
14932
            res = 0;
14933
        }
14934
14935
        if (res) {
14936
            /* Sign message with Ed25519. */
14937
            ret = wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key);
14938
            if (ret != 0) {
14939
                WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
14940
                res = 0;
14941
            }
14942
        }
14943
14944
        wc_ed25519_free(&key);
14945
    }
14946
14947
    return res;
14948
#else
14949
#if !defined(HAVE_ED25519_SIGN)
14950
    WOLFSSL_MSG("No ED25519 sign built in");
14951
#elif !defined(WOLFSSL_KEY_GEN)
14952
    WOLFSSL_MSG("No Key Gen built in");
14953
#elif !defined(HAVE_ED25519_KEY_IMPORT)
14954
    WOLFSSL_MSG("No ED25519 Key import built in");
14955
#endif
14956
14957
    (void)msg;
14958
    (void)msgSz;
14959
    (void)priv;
14960
    (void)privSz;
14961
    (void)sig;
14962
    (void)sigSz;
14963
14964
    return 0;
14965
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
14966
}
14967
14968
/* Verify a message with Ed25519 using the public key.
14969
 *
14970
 * Input keys are in little endian format.
14971
 *
14972
 * @param [in] msg     Message to be verified.
14973
 * @param [in] msgSz   Length of message in bytes.
14974
 * @param [in] pub     ED25519 public key data.
14975
 * @param [in] privSz  Length in bytes of public key data.
14976
 * @param [in] sig     Signature buffer.
14977
 * @param [in] sigSz   Length of the signature in bytes.
14978
 * @return  1 on success
14979
 * @return  0 on failure.
14980
 */
14981
int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
14982
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
14983
    unsigned int sigSz)
14984
{
14985
#if defined(HAVE_ED25519_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
14986
    defined(HAVE_ED25519_KEY_IMPORT)
14987
    ed25519_key key;
14988
    int res = 1;
14989
14990
    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
14991
14992
    /* Validate parameters. */
14993
    if ((pub == NULL) || (pubSz != ED25519_PUB_KEY_SIZE) || (msg == NULL) ||
14994
            (sig == NULL) || (sigSz != ED25519_SIG_SIZE)) {
14995
        WOLFSSL_MSG("Bad arguments");
14996
        res = 0;
14997
    }
14998
14999
    /* Initialize Ed25519 key. */
15000
    if (res && (wc_ed25519_init(&key) != 0)) {
15001
        WOLFSSL_MSG("wc_curve25519_init failed");
15002
        res = 0;
15003
    }
15004
    if (res) {
15005
        /* Import public key. */
15006
        int ret = wc_ed25519_import_public(pub, pubSz, &key);
15007
        if (ret != 0) {
15008
            WOLFSSL_MSG("wc_ed25519_import_public failed");
15009
            res = 0;
15010
        }
15011
15012
        if (res) {
15013
            int check = 0;
15014
15015
            /* Verify signature with message and public key. */
15016
            ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
15017
                &key);
15018
            /* Check for errors in verification process. */
15019
            if (ret != 0) {
15020
                WOLFSSL_MSG("wc_ed25519_verify_msg failed");
15021
                res = 0;
15022
            }
15023
            /* Check signature is valid. */
15024
            else if (!check) {
15025
                WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
15026
                res = 0;
15027
            }
15028
        }
15029
15030
        wc_ed25519_free(&key);
15031
    }
15032
15033
    return res;
15034
#else
15035
#if !defined(HAVE_ED25519_VERIFY)
15036
    WOLFSSL_MSG("No ED25519 verify built in");
15037
#elif !defined(WOLFSSL_KEY_GEN)
15038
    WOLFSSL_MSG("No Key Gen built in");
15039
#elif !defined(HAVE_ED25519_KEY_IMPORT)
15040
    WOLFSSL_MSG("No ED25519 Key import built in");
15041
#endif
15042
15043
    (void)msg;
15044
    (void)msgSz;
15045
    (void)pub;
15046
    (void)pubSz;
15047
    (void)sig;
15048
    (void)sigSz;
15049
15050
    return 0;
15051
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
15052
}
15053
15054
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
15055
15056
/*******************************************************************************
15057
 * END OF ED25519 API
15058
 ******************************************************************************/
15059
15060
/*******************************************************************************
15061
 * START OF EC448 API
15062
 ******************************************************************************/
15063
15064
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
15065
/* Generate an EC448 key pair.
15066
 *
15067
 * Output keys are in little endian format.
15068
 *
15069
 * @param [out]     priv    EC448 private key data.
15070
 * @param [in, out] privSz  On in, the size of priv in bytes.
15071
 *                          On out, the length of the private key data in bytes.
15072
 * @param [out]     pub     EC448 public key data.
15073
 * @param [in, out] pubSz   On in, the size of pub in bytes.
15074
 *                          On out, the length of the public key data in bytes.
15075
 * @return  1 on success
15076
 * @return  0 on failure.
15077
 */
15078
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
15079
                               unsigned char *pub, unsigned int *pubSz)
15080
{
15081
#ifdef WOLFSSL_KEY_GEN
15082
    int res = 1;
15083
    int initTmpRng = 0;
15084
    WC_RNG *rng = NULL;
15085
#ifdef WOLFSSL_SMALL_STACK
15086
    WC_RNG *tmpRng = NULL;
15087
#else
15088
    WC_RNG tmpRng[1];
15089
#endif
15090
    curve448_key key;
15091
15092
    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
15093
15094
    /* Validate parameters. */
15095
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE448_KEY_SIZE) ||
15096
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE448_KEY_SIZE)) {
15097
        WOLFSSL_MSG("Bad arguments");
15098
        res = 0;
15099
    }
15100
15101
    if (res) {
15102
        /* Create a random number generator. */
15103
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
15104
        if (rng == NULL) {
15105
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
15106
            res = 0;
15107
        }
15108
    }
15109
15110
    /* Initialize a Curve448 key. */
15111
    if (res && (wc_curve448_init(&key) != 0)) {
15112
        WOLFSSL_MSG("wc_curve448_init failed");
15113
        res = 0;
15114
    }
15115
    if (res) {
15116
        /* Make a Curve448 key pair. */
15117
        int ret = wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key);
15118
        if (ret != 0) {
15119
            WOLFSSL_MSG("wc_curve448_make_key failed");
15120
            res = 0;
15121
        }
15122
        if (res) {
15123
            /* Export Curve448 key pair to buffers. */
15124
            ret = wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
15125
                EC448_LITTLE_ENDIAN);
15126
            if (ret != 0) {
15127
                WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
15128
                res = 0;
15129
            }
15130
        }
15131
15132
        /* Dispose of key. */
15133
        wc_curve448_free(&key);
15134
    }
15135
15136
    if (initTmpRng) {
15137
        wc_FreeRng(rng);
15138
    #ifdef WOLFSSL_SMALL_STACK
15139
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
15140
    #endif
15141
    }
15142
15143
    return res;
15144
#else
15145
    WOLFSSL_MSG("No Key Gen built in");
15146
15147
    (void)priv;
15148
    (void)privSz;
15149
    (void)pub;
15150
    (void)pubSz;
15151
15152
    return 0;
15153
#endif /* WOLFSSL_KEY_GEN */
15154
}
15155
15156
/* Compute a shared secret from private and public EC448 keys.
15157
 *
15158
 * Input and output keys are in little endian format
15159
 *
15160
 * @param [out]     shared    Shared secret buffer.
15161
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
15162
 *                            On out, the length of the secret in bytes.
15163
 * @param [in]      priv      EC448 private key data.
15164
 * @param [in]      privSz    Length of the private key data in bytes.
15165
 * @param [in]      pub       EC448 public key data.
15166
 * @param [in]      pubSz     Length of the public key data in bytes.
15167
 * @return  1 on success
15168
 * @return  0 on failure.
15169
 */
15170
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
15171
                             const unsigned char *priv, unsigned int privSz,
15172
                             const unsigned char *pub, unsigned int pubSz)
15173
{
15174
#ifdef WOLFSSL_KEY_GEN
15175
    int res = 1;
15176
    curve448_key privkey;
15177
    curve448_key pubkey;
15178
15179
    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
15180
15181
    /* Validate parameters. */
15182
    if ((shared == NULL) || (sharedSz == NULL) ||
15183
            (*sharedSz < CURVE448_KEY_SIZE) || (priv == NULL) ||
15184
            (privSz < CURVE448_KEY_SIZE) || (pub == NULL) ||
15185
            (pubSz < CURVE448_KEY_SIZE)) {
15186
        WOLFSSL_MSG("Bad arguments");
15187
        res = 0;
15188
    }
15189
15190
    /* Initialize private key object. */
15191
    if (res && (wc_curve448_init(&privkey) != 0)) {
15192
        WOLFSSL_MSG("wc_curve448_init privkey failed");
15193
        res = 0;
15194
    }
15195
    if (res) {
15196
        /* Initialize public key object. */
15197
        if (wc_curve448_init(&pubkey) != MP_OKAY) {
15198
            WOLFSSL_MSG("wc_curve448_init pubkey failed");
15199
            res = 0;
15200
        }
15201
        if (res) {
15202
            /* Import our private key. */
15203
            int ret = wc_curve448_import_private_ex(priv, privSz, &privkey,
15204
                EC448_LITTLE_ENDIAN);
15205
            if (ret != 0) {
15206
                WOLFSSL_MSG("wc_curve448_import_private_ex failed");
15207
                res = 0;
15208
            }
15209
15210
            if (res) {
15211
                /* Import peer's public key. */
15212
                ret = wc_curve448_import_public_ex(pub, pubSz, &pubkey,
15213
                    EC448_LITTLE_ENDIAN);
15214
                if (ret != 0) {
15215
                    WOLFSSL_MSG("wc_curve448_import_public_ex failed");
15216
                    res = 0;
15217
                }
15218
            }
15219
            if (res) {
15220
                /* Compute shared secret. */
15221
                ret = wc_curve448_shared_secret_ex(&privkey, &pubkey, shared,
15222
                    sharedSz, EC448_LITTLE_ENDIAN);
15223
                if (ret != 0) {
15224
                    WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
15225
                    res = 0;
15226
                }
15227
            }
15228
15229
            wc_curve448_free(&pubkey);
15230
        }
15231
        wc_curve448_free(&privkey);
15232
    }
15233
15234
    return res;
15235
#else
15236
    WOLFSSL_MSG("No Key Gen built in");
15237
15238
    (void)shared;
15239
    (void)sharedSz;
15240
    (void)priv;
15241
    (void)privSz;
15242
    (void)pub;
15243
    (void)pubSz;
15244
15245
    return 0;
15246
#endif /* WOLFSSL_KEY_GEN */
15247
}
15248
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
15249
15250
/*******************************************************************************
15251
 * END OF EC448 API
15252
 ******************************************************************************/
15253
15254
/*******************************************************************************
15255
 * START OF ED448 API
15256
 ******************************************************************************/
15257
15258
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
15259
/* Generate an ED448 key pair.
15260
 *
15261
 * Output keys are in little endian format.
15262
 *
15263
 * @param [out]     priv    ED448 private key data.
15264
 * @param [in, out] privSz  On in, the size of priv in bytes.
15265
 *                          On out, the length of the private key data in bytes.
15266
 * @param [out]     pub     ED448 public key data.
15267
 * @param [in, out] pubSz   On in, the size of pub in bytes.
15268
 *                          On out, the length of the public key data in bytes.
15269
 * @return  1 on success
15270
 * @return  0 on failure.
15271
 */
15272
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
15273
    unsigned char *pub, unsigned int *pubSz)
15274
{
15275
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED448_KEY_EXPORT)
15276
    int res = 1;
15277
    int initTmpRng = 0;
15278
    WC_RNG *rng = NULL;
15279
#ifdef WOLFSSL_SMALL_STACK
15280
    WC_RNG *tmpRng = NULL;
15281
#else
15282
    WC_RNG tmpRng[1];
15283
#endif
15284
    ed448_key key;
15285
15286
    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
15287
15288
    /* Validate parameters. */
15289
    if ((priv == NULL) || (privSz == NULL) ||
15290
            (*privSz < ED448_PRV_KEY_SIZE) || (pub == NULL) ||
15291
            (pubSz == NULL) || (*pubSz < ED448_PUB_KEY_SIZE)) {
15292
        WOLFSSL_MSG("Bad arguments");
15293
        res = 0;
15294
    }
15295
15296
    if (res) {
15297
        /* Create a random number generator. */
15298
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
15299
        if (rng == NULL) {
15300
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
15301
            res = 0;
15302
        }
15303
    }
15304
15305
    /* Initialize an Ed448 key. */
15306
    if (res && (wc_ed448_init(&key) != 0)) {
15307
        WOLFSSL_MSG("wc_ed448_init failed");
15308
        res = 0;
15309
    }
15310
    if (res) {
15311
        /* Make an Ed448 key pair. */
15312
        int ret = wc_ed448_make_key(rng, ED448_KEY_SIZE, &key);
15313
        if (ret != 0) {
15314
            WOLFSSL_MSG("wc_ed448_make_key failed");
15315
            res = 0;
15316
        }
15317
        if (res) {
15318
            /* Export Curve448 key pair to buffers. */
15319
            ret = wc_ed448_export_key(&key, priv, privSz, pub, pubSz);
15320
            if (ret != 0) {
15321
                WOLFSSL_MSG("wc_ed448_export_key failed");
15322
                res = 0;
15323
            }
15324
        }
15325
15326
        wc_ed448_free(&key);
15327
    }
15328
15329
    if (initTmpRng) {
15330
        wc_FreeRng(rng);
15331
    #ifdef WOLFSSL_SMALL_STACK
15332
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
15333
    #endif
15334
    }
15335
15336
    return res;
15337
#else
15338
#ifndef WOLFSSL_KEY_GEN
15339
    WOLFSSL_MSG("No Key Gen built in");
15340
#else
15341
    WOLFSSL_MSG("No ED448 key export built in");
15342
#endif
15343
15344
    (void)priv;
15345
    (void)privSz;
15346
    (void)pub;
15347
    (void)pubSz;
15348
15349
    return 0;
15350
#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
15351
}
15352
15353
/* Sign a message with Ed448 using the private key.
15354
 *
15355
 * Input and output keys are in little endian format.
15356
 * Priv is a buffer containing private and public part of key.
15357
 *
15358
 * @param [in]      msg     Message to be signed.
15359
 * @param [in]      msgSz   Length of message in bytes.
15360
 * @param [in]      priv    ED448 private key data.
15361
 * @param [in]      privSz  Length in bytes of private key data.
15362
 * @param [out]     sig     Signature buffer.
15363
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
15364
 *                          On out, the length of the signature in bytes.
15365
 * @return  1 on success
15366
 * @return  0 on failure.
15367
 */
15368
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
15369
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
15370
    unsigned int *sigSz)
15371
{
15372
#if defined(HAVE_ED448_SIGN) && defined(WOLFSSL_KEY_GEN) && \
15373
    defined(HAVE_ED448_KEY_IMPORT)
15374
    ed448_key key;
15375
    int res = 1;
15376
15377
    WOLFSSL_ENTER("wolfSSL_ED448_sign");
15378
15379
    /* Validate parameters. */
15380
    if ((priv == NULL) || (privSz != ED448_PRV_KEY_SIZE) ||
15381
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
15382
            (*sigSz < ED448_SIG_SIZE)) {
15383
        WOLFSSL_MSG("Bad arguments");
15384
        res = 0;
15385
    }
15386
15387
    /* Initialize Ed448 key. */
15388
    if (res && (wc_ed448_init(&key) != 0)) {
15389
        WOLFSSL_MSG("wc_curve448_init failed");
15390
        res = 0;
15391
    }
15392
    if (res) {
15393
        /* Import private and public key. */
15394
        int ret = wc_ed448_import_private_key(priv, privSz / 2,
15395
            priv + (privSz / 2), ED448_PUB_KEY_SIZE, &key);
15396
        if (ret != 0) {
15397
            WOLFSSL_MSG("wc_ed448_import_private failed");
15398
            res = 0;
15399
        }
15400
15401
        if (res) {
15402
            /* Sign message with Ed448 - no context. */
15403
            ret = wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0);
15404
            if (ret != 0) {
15405
                WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
15406
                res = 0;
15407
            }
15408
        }
15409
15410
        wc_ed448_free(&key);
15411
    }
15412
15413
    return res;
15414
#else
15415
#if !defined(HAVE_ED448_SIGN)
15416
    WOLFSSL_MSG("No ED448 sign built in");
15417
#elif !defined(WOLFSSL_KEY_GEN)
15418
    WOLFSSL_MSG("No Key Gen built in");
15419
#elif !defined(HAVE_ED448_KEY_IMPORT)
15420
    WOLFSSL_MSG("No ED448 Key import built in");
15421
#endif
15422
15423
    (void)msg;
15424
    (void)msgSz;
15425
    (void)priv;
15426
    (void)privSz;
15427
    (void)sig;
15428
    (void)sigSz;
15429
15430
    return 0;
15431
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
15432
}
15433
15434
/* Verify a message with Ed448 using the public key.
15435
 *
15436
 * Input keys are in little endian format.
15437
 *
15438
 * @param [in] msg     Message to be verified.
15439
 * @param [in] msgSz   Length of message in bytes.
15440
 * @param [in] pub     ED448 public key data.
15441
 * @param [in] privSz  Length in bytes of public key data.
15442
 * @param [in] sig     Signature buffer.
15443
 * @param [in] sigSz   Length of the signature in bytes.
15444
 * @return  1 on success
15445
 * @return  0 on failure.
15446
 */
15447
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
15448
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
15449
    unsigned int sigSz)
15450
{
15451
#if defined(HAVE_ED448_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
15452
    defined(HAVE_ED448_KEY_IMPORT)
15453
    ed448_key key;
15454
    int res = 1;
15455
15456
    WOLFSSL_ENTER("wolfSSL_ED448_verify");
15457
15458
    /* Validate parameters. */
15459
    if ((pub == NULL) || (pubSz != ED448_PUB_KEY_SIZE) || (msg == NULL) ||
15460
            (sig == NULL) || (sigSz != ED448_SIG_SIZE)) {
15461
        WOLFSSL_MSG("Bad arguments");
15462
        res = 0;
15463
    }
15464
15465
    /* Initialize Ed448 key. */
15466
    if (res && (wc_ed448_init(&key) != 0)) {
15467
        WOLFSSL_MSG("wc_curve448_init failed");
15468
        res = 0;
15469
    }
15470
    if (res) {
15471
        /* Import public key. */
15472
        int ret = wc_ed448_import_public(pub, pubSz, &key);
15473
        if (ret != 0) {
15474
            WOLFSSL_MSG("wc_ed448_import_public failed");
15475
            res = 0;
15476
        }
15477
15478
        if (res) {
15479
            int check = 0;
15480
15481
            /* Verify signature with message and public key - no context. */
15482
            ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
15483
                &key, NULL, 0);
15484
            /* Check for errors in verification process. */
15485
            if (ret != 0) {
15486
                WOLFSSL_MSG("wc_ed448_verify_msg failed");
15487
                res = 0;
15488
            }
15489
            /* Check signature is valid. */
15490
            else if (!check) {
15491
                WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
15492
                res = 0;
15493
            }
15494
        }
15495
15496
        wc_ed448_free(&key);
15497
    }
15498
15499
    return res;
15500
#else
15501
#if !defined(HAVE_ED448_VERIFY)
15502
    WOLFSSL_MSG("No ED448 verify built in");
15503
#elif !defined(WOLFSSL_KEY_GEN)
15504
    WOLFSSL_MSG("No Key Gen built in");
15505
#elif !defined(HAVE_ED448_KEY_IMPORT)
15506
    WOLFSSL_MSG("No ED448 Key import built in");
15507
#endif
15508
15509
    (void)msg;
15510
    (void)msgSz;
15511
    (void)pub;
15512
    (void)pubSz;
15513
    (void)sig;
15514
    (void)sigSz;
15515
15516
    return 0;
15517
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
15518
}
15519
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
15520
15521
/*******************************************************************************
15522
 * END OF ED448 API
15523
 ******************************************************************************/
15524
15525
/*******************************************************************************
15526
 * START OF GENERIC PUBLIC KEY PEM APIs
15527
 ******************************************************************************/
15528
15529
#ifdef OPENSSL_EXTRA
15530
/* Sets default callback password for PEM.
15531
 *
15532
 * @param [out] buf       Buffer to hold password.
15533
 * @param [in]  num       Number of characters in buffer.
15534
 * @param [in]  rwFlag    Read/write flag. Ignored.
15535
 * @param [in]  userData  User data - assumed to be default password.
15536
 * @return  Password size on success.
15537
 * @return  0 on failure.
15538
 */
15539
int wolfSSL_PEM_def_callback(char* buf, int num, int rwFlag, void* userData)
15540
{
15541
    int sz = 0;
15542
15543
    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
15544
15545
    (void)rwFlag;
15546
15547
    /* We assume that the user passes a default password as userdata */
15548
    if ((buf != NULL) && (userData != NULL)) {
15549
        sz = (int)XSTRLEN((const char*)userData);
15550
        sz = (int)min((word32)sz, (word32)num);
15551
        XMEMCPY(buf, userData, (size_t)sz);
15552
    }
15553
    else {
15554
        WOLFSSL_MSG("Error, default password cannot be created.");
15555
    }
15556
15557
    return sz;
15558
}
15559
15560
#ifndef NO_BIO
15561
/* Writes a public key to a WOLFSSL_BIO encoded in PEM format.
15562
 *
15563
 * @param [in] bio  BIO to write to.
15564
 * @param [in] key  Public key to write in PEM format.
15565
 * @return  1 on success.
15566
 * @return  0 on failure.
15567
 */
15568
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
15569
{
15570
    int ret = 0;
15571
15572
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
15573
15574
    if ((bio != NULL) && (key != NULL)) {
15575
        switch (key->type) {
15576
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
15577
            case WC_EVP_PKEY_RSA:
15578
                ret = wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key->rsa);
15579
                break;
15580
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
15581
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
15582
    (defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN))
15583
            case WC_EVP_PKEY_DSA:
15584
                ret = wolfSSL_PEM_write_bio_DSA_PUBKEY(bio, key->dsa);
15585
                break;
15586
#endif /* !NO_DSA && !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
15587
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
15588
    defined(WOLFSSL_KEY_GEN)
15589
            case WC_EVP_PKEY_EC:
15590
                ret = wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key->ecc);
15591
                break;
15592
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
15593
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
15594
            case WC_EVP_PKEY_DH:
15595
                /* DH public key not supported. */
15596
                WOLFSSL_MSG("Writing DH PUBKEY not supported!");
15597
                break;
15598
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
15599
            default:
15600
                /* Key type not supported. */
15601
                WOLFSSL_MSG("Unknown Key type!");
15602
                break;
15603
        }
15604
    }
15605
15606
    return ret;
15607
}
15608
15609
/* Writes a private key to a WOLFSSL_BIO encoded in PEM format.
15610
 *
15611
 * @param [in] bio     BIO to write to.
15612
 * @param [in] key     Public key to write in PEM format.
15613
 * @param [in] cipher  Encryption cipher to use.
15614
 * @param [in] passwd  Password to use when encrypting.
15615
 * @param [in] len     Length of password.
15616
 * @param [in] cb      Password callback.
15617
 * @param [in] arg     Password callback argument.
15618
 * @return  1 on success.
15619
 * @return  0 on failure.
15620
 */
15621
int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
15622
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
15623
    wc_pem_password_cb* cb, void* arg)
15624
{
15625
    int ret = 1;
15626
15627
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
15628
15629
    (void)cipher;
15630
    (void)passwd;
15631
    (void)len;
15632
    (void)cb;
15633
    (void)arg;
15634
15635
    /* Validate parameters. */
15636
    if ((bio == NULL) || (key == NULL)) {
15637
        WOLFSSL_MSG("Bad Function Arguments");
15638
        ret = 0;
15639
    }
15640
15641
    if (ret == 1) {
15642
    #ifdef WOLFSSL_KEY_GEN
15643
        switch (key->type) {
15644
        #ifndef NO_RSA
15645
            case WC_EVP_PKEY_RSA:
15646
                /* Write using RSA specific API. */
15647
                ret = wolfSSL_PEM_write_bio_RSAPrivateKey(bio, key->rsa,
15648
                    cipher, passwd, len, cb, arg);
15649
                break;
15650
        #endif
15651
        #ifndef NO_DSA
15652
            case WC_EVP_PKEY_DSA:
15653
                /* Write using DSA specific API. */
15654
                ret = wolfSSL_PEM_write_bio_DSAPrivateKey(bio, key->dsa,
15655
                    cipher, passwd, len, cb, arg);
15656
                break;
15657
        #endif
15658
        #ifdef HAVE_ECC
15659
            case WC_EVP_PKEY_EC:
15660
            #if defined(HAVE_ECC_KEY_EXPORT)
15661
                /* Write using EC specific API. */
15662
                ret = wolfSSL_PEM_write_bio_ECPrivateKey(bio, key->ecc,
15663
                    cipher, passwd, len, cb, arg);
15664
            #else
15665
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
15666
                    key->pkey_sz, bio, EC_PRIVATEKEY_TYPE);
15667
            #endif
15668
                break;
15669
        #endif
15670
        #ifndef NO_DH
15671
            case WC_EVP_PKEY_DH:
15672
                /* Write using generic API with DH type. */
15673
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
15674
                    key->pkey_sz, bio, DH_PRIVATEKEY_TYPE);
15675
                break;
15676
        #endif
15677
            default:
15678
                WOLFSSL_MSG("Unknown Key type!");
15679
                ret = 0;
15680
                break;
15681
        }
15682
    #else
15683
        int type = 0;
15684
15685
        switch (key->type) {
15686
        #ifndef NO_DSA
15687
            case WC_EVP_PKEY_DSA:
15688
                type = DSA_PRIVATEKEY_TYPE;
15689
                break;
15690
        #endif
15691
        #ifdef HAVE_ECC
15692
            case WC_EVP_PKEY_EC:
15693
                type = ECC_PRIVATEKEY_TYPE;
15694
                break;
15695
        #endif
15696
        #ifndef NO_DH
15697
            case WC_EVP_PKEY_DH:
15698
                type = DH_PRIVATEKEY_TYPE;
15699
                break;
15700
        #endif
15701
        #ifndef NO_RSA
15702
            case WC_EVP_PKEY_RSA:
15703
                type = PRIVATEKEY_TYPE;
15704
                break;
15705
        #endif
15706
            default:
15707
                ret = 0;
15708
                break;
15709
        }
15710
        if (ret == 1) {
15711
            /* Write using generic API with generic type. */
15712
            ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr, key->pkey_sz,
15713
                bio, type);
15714
        }
15715
    #endif
15716
    }
15717
15718
    return ret;
15719
}
15720
#endif /* !NO_BIO */
15721
15722
#ifndef NO_BIO
15723
/* Create a private key object from the data in the BIO.
15724
 *
15725
 * @param [in]      bio   BIO to read from.
15726
 * @param [in, out] key   Public key object. Object used if passed in.
15727
 * @param [in]      cb    Password callback.
15728
 * @param [in]      arg   Password callback argument.
15729
 * @return  A WOLFSSL_EVP_PKEY object on success.
15730
 * @return  NULL on failure.
15731
 */
15732
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
15733
    WOLFSSL_EVP_PKEY **key, wc_pem_password_cb *cb, void *arg)
15734
{
15735
    int err = 0;
15736
    WOLFSSL_EVP_PKEY* pkey = NULL;
15737
    DerBuffer* der = NULL;
15738
15739
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
15740
15741
    if (bio == NULL) {
15742
        err = 1;
15743
    }
15744
15745
    /* Read the PEM public key from the BIO and convert to DER. */
15746
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PUBLICKEY_TYPE, NULL,
15747
            &der) < 0)) {
15748
        err = 1;
15749
    }
15750
15751
    if (!err) {
15752
        const unsigned char* ptr = der->buffer;
15753
15754
        /* Use key passed in if set. */
15755
        if ((key != NULL) && (*key != NULL)) {
15756
            pkey = *key;
15757
        }
15758
15759
        /* Convert DER data to a public key object. */
15760
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
15761
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15762
            pkey = NULL;
15763
            err = 1;
15764
        }
15765
    }
15766
15767
    /* Return the key if possible. */
15768
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15769
        *key = pkey;
15770
    }
15771
    /* Dispose of the DER encoding. */
15772
    FreeDer(&der);
15773
15774
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
15775
15776
    return pkey;
15777
}
15778
15779
/* Create a private key object from the data in the BIO.
15780
 *
15781
 * @param [in]      bio   BIO to read from.
15782
 * @param [in, out] key   Private key object. Object used if passed in.
15783
 * @param [in]      cb    Password callback.
15784
 * @param [in]      arg   Password callback argument.
15785
 * @return  A WOLFSSL_EVP_PKEY object on success.
15786
 * @return  NULL on failure.
15787
 */
15788
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
15789
    WOLFSSL_EVP_PKEY** key, wc_pem_password_cb* cb, void* arg)
15790
{
15791
    int err = 0;
15792
    WOLFSSL_EVP_PKEY* pkey = NULL;
15793
    DerBuffer* der = NULL;
15794
    int keyFormat = 0;
15795
15796
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
15797
15798
    /* Validate parameters. */
15799
    if (bio == NULL) {
15800
        err = 1;
15801
    }
15802
15803
    /* Read the PEM private key from the BIO and convert to DER. */
15804
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
15805
            &der) < 0)) {
15806
        err = 1;
15807
    }
15808
15809
    if (!err) {
15810
        const unsigned char* ptr = der->buffer;
15811
        int type;
15812
15813
        /* Set key type based on format returned. */
15814
        switch (keyFormat) {
15815
            /* No key format set - default to RSA. */
15816
            case 0:
15817
            case RSAk:
15818
                type = WC_EVP_PKEY_RSA;
15819
                break;
15820
            case DSAk:
15821
                type = WC_EVP_PKEY_DSA;
15822
                break;
15823
            case ECDSAk:
15824
                type = WC_EVP_PKEY_EC;
15825
                break;
15826
            case DHk:
15827
                type = WC_EVP_PKEY_DH;
15828
                break;
15829
            default:
15830
                type = WOLFSSL_FATAL_ERROR;
15831
                break;
15832
        }
15833
15834
        /* Use key passed in if set. */
15835
        if ((key != NULL) && (*key != NULL)) {
15836
            pkey = *key;
15837
        }
15838
15839
        /* Convert DER data to a private key object. */
15840
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
15841
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15842
            pkey = NULL;
15843
            err = 1;
15844
        }
15845
    }
15846
15847
    /* Return the key if possible. */
15848
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15849
        *key = pkey;
15850
    }
15851
    /* Dispose of the DER encoding. */
15852
    FreeDer(&der);
15853
15854
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", err);
15855
15856
    return pkey;
15857
}
15858
15859
15860
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(
15861
    WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb,
15862
    void* arg)
15863
{
15864
    return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
15865
}
15866
#endif /* !NO_BIO */
15867
15868
#if !defined(NO_FILESYSTEM)
15869
/* Create a private key object from the data in a file.
15870
 *
15871
 * @param [in]      fp    File pointer.
15872
 * @param [in, out] key   Public key object. Object used if passed in.
15873
 * @param [in]      cb    Password callback.
15874
 * @param [in]      arg   Password callback argument.
15875
 * @return  A WOLFSSL_EVP_PKEY object on success.
15876
 * @return  NULL on failure.
15877
 */
15878
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **key,
15879
    wc_pem_password_cb *cb, void *arg)
15880
{
15881
    int err = 0;
15882
    WOLFSSL_EVP_PKEY* pkey = NULL;
15883
    DerBuffer* der = NULL;
15884
15885
    WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
15886
15887
    /* Validate parameters. */
15888
    if (fp == XBADFILE) {
15889
        err = 1;
15890
    }
15891
15892
    /* Read the PEM public key from the file and convert to DER. */
15893
    if ((!err) && ((pem_read_file_key(fp, cb, arg, PUBLICKEY_TYPE, NULL,
15894
            &der) < 0) || (der == NULL))) {
15895
        err = 1;
15896
    }
15897
    if (!err) {
15898
        const unsigned char* ptr = der->buffer;
15899
15900
        /* Use key passed in if set. */
15901
        if ((key != NULL) && (*key != NULL)) {
15902
            pkey = *key;
15903
        }
15904
15905
        /* Convert DER data to a public key object. */
15906
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
15907
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15908
            pkey = NULL;
15909
            err = 1;
15910
        }
15911
    }
15912
15913
    /* Return the key if possible. */
15914
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15915
        *key = pkey;
15916
    }
15917
    /* Dispose of the DER encoding. */
15918
    FreeDer(&der);
15919
15920
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
15921
15922
    return pkey;
15923
}
15924
15925
#ifndef NO_CERTS
15926
/* Create a private key object from the data in a file.
15927
 *
15928
 * @param [in]      fp    File pointer.
15929
 * @param [in, out] key   Private key object. Object used if passed in.
15930
 * @param [in]      cb    Password callback.
15931
 * @param [in]      arg   Password callback argument.
15932
 * @return  A WOLFSSL_EVP_PKEY object on success.
15933
 * @return  NULL on failure.
15934
 */
15935
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
15936
    wc_pem_password_cb *cb, void *arg)
15937
{
15938
    int err = 0;
15939
    WOLFSSL_EVP_PKEY* pkey = NULL;
15940
    DerBuffer* der = NULL;
15941
    int keyFormat = 0;
15942
15943
    WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
15944
15945
    /* Validate parameters. */
15946
    if (fp == XBADFILE) {
15947
        err = 1;
15948
    }
15949
15950
    /* Read the PEM private key from the file and convert to DER. */
15951
    if ((!err) && (pem_read_file_key(fp, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
15952
            &der)) < 0) {
15953
        err = 1;
15954
    }
15955
15956
    if (!err) {
15957
        const unsigned char* ptr = der->buffer;
15958
        int type;
15959
15960
        /* Set key type based on format returned. */
15961
        switch (keyFormat) {
15962
            /* No key format set - default to RSA. */
15963
            case 0:
15964
            case RSAk:
15965
                type = WC_EVP_PKEY_RSA;
15966
                break;
15967
            case DSAk:
15968
                type = WC_EVP_PKEY_DSA;
15969
                break;
15970
            case ECDSAk:
15971
                type = WC_EVP_PKEY_EC;
15972
                break;
15973
            case DHk:
15974
                type = WC_EVP_PKEY_DH;
15975
                break;
15976
            default:
15977
                type = WOLFSSL_FATAL_ERROR;
15978
                break;
15979
        }
15980
15981
        /* Use key passed in if set. */
15982
        if ((key != NULL) && (*key != NULL)) {
15983
            pkey = *key;
15984
        }
15985
15986
        /* Convert DER data to a private key object. */
15987
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
15988
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15989
            pkey = NULL;
15990
            err = 1;
15991
        }
15992
    }
15993
15994
    /* Return the key if possible. */
15995
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15996
        *key = pkey;
15997
    }
15998
    /* Dispose of the DER encoding. */
15999
    FreeDer(&der);
16000
16001
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PrivateKey", 0);
16002
16003
    return pkey;
16004
}
16005
#endif /* !NO_CERTS */
16006
#endif /* !NO_FILESYSTEM */
16007
16008
#ifndef NO_CERTS
16009
16010
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
16011
#define PEM_BEGIN              "-----BEGIN "
16012
#define PEM_BEGIN_SZ           11
16013
#define PEM_END                "-----END "
16014
#define PEM_END_SZ             9
16015
#define PEM_HDR_FIN            "-----"
16016
#define PEM_HDR_FIN_SZ         5
16017
#define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
16018
#define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
16019
#define PEM_HDR_FIN_EOL_SZ     6
16020
16021
/* Find strings and return middle offsets.
16022
 *
16023
 * Find first string in pem as a prefix and then locate second string as a
16024
 * postfix.
16025
 * len returning with 0 indicates not found.
16026
 *
16027
 * @param [in]  pem      PEM data.
16028
 * @param [in]  pemLen   Length of PEM data.
16029
 * @param [in]  idx      Current index.
16030
 * @param [in]  prefix   First string to find.
16031
 * @param [in]  postfix  Second string to find after first.
16032
 * @param [out] start    Start index of data between strings.
16033
 * @param [out] len      Length of data between strings.
16034
 */
16035
static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,
16036
    const char* postfix, int* start, int* len)
16037
{
16038
    int prefixLen = (int)XSTRLEN(prefix);
16039
    int postfixLen = (int)XSTRLEN(postfix);
16040
16041
    *start = *len = 0;
16042
    /* Find prefix part. */
16043
    for (; idx < pemLen - prefixLen; idx++) {
16044
        if ((pem[idx] == prefix[0]) &&
16045
                (XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) {
16046
            idx += prefixLen;
16047
            *start = idx;
16048
            break;
16049
        }
16050
    }
16051
    /* Find postfix part. */
16052
    for (; idx < pemLen - postfixLen; idx++) {
16053
        if ((pem[idx] == postfix[0]) &&
16054
                (XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) {
16055
            *len = idx - *start;
16056
            break;
16057
        }
16058
    }
16059
}
16060
16061
/* Parse out content type name, any encryption headers and DER encoding.
16062
 *
16063
 * @param [in]  pem     PEM data.
16064
 * @param [in]  pemLen  Length of PEM data.
16065
 * @param [out] name    Name of content type.
16066
 * @param [out] header  Encryption headers.
16067
 * @param [out] data    DER encoding from PEM.
16068
 * @param [out] len     Length of DER data.
16069
 * @return  0 on success.
16070
 * @return  MEMORY_E when dynamic memory allocation fails.
16071
 * @return  ASN_NO_PEM_HEADER when no header found or different names found.
16072
 */
16073
static int pem_read_data(char* pem, int pemLen, char **name, char **header,
16074
    unsigned char **data, long *len)
16075
{
16076
    int ret = 0;
16077
    int start;
16078
    int nameLen;
16079
    int startHdr = 0;
16080
    int hdrLen = 0;
16081
    int startEnd = 0;
16082
    int endLen;
16083
16084
    *name = NULL;
16085
    *header = NULL;
16086
16087
    /* Find header. */
16088
    pem_find_pattern(pem, pemLen, 0, PEM_BEGIN, PEM_HDR_FIN, &start, &nameLen);
16089
    /* Allocate memory for header name. */
16090
    *name = (char*)XMALLOC((size_t)nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16091
    if (*name == NULL) {
16092
        ret = MEMORY_E;
16093
    }
16094
    if (ret == 0) {
16095
        /* Put in header name. */
16096
        (*name)[nameLen] = '\0';
16097
        if (nameLen == 0) {
16098
            ret = ASN_NO_PEM_HEADER;
16099
        }
16100
        else {
16101
            XMEMCPY(*name, pem + start, (size_t)nameLen);
16102
        }
16103
    }
16104
    if (ret == 0) {
16105
        /* Find encryption headers after header. */
16106
        start += nameLen + PEM_HDR_FIN_SZ;
16107
        pem_find_pattern(pem, pemLen, start, "\n", "\n\n", &startHdr, &hdrLen);
16108
        if (hdrLen > 0) {
16109
            /* Include first of two '\n' characters. */
16110
            hdrLen++;
16111
        }
16112
        /* Allocate memory for encryption header string. */
16113
        *header = (char*)XMALLOC((size_t)hdrLen + 1, NULL,
16114
                                    DYNAMIC_TYPE_TMP_BUFFER);
16115
        if (*header == NULL) {
16116
            ret = MEMORY_E;
16117
        }
16118
    }
16119
    if (ret == 0) {
16120
        /* Put in encryption header string. */
16121
        (*header)[hdrLen] = '\0';
16122
        if (hdrLen > 0) {
16123
            XMEMCPY(*header, pem + startHdr, (size_t)hdrLen);
16124
            start = startHdr + hdrLen + 1;
16125
        }
16126
16127
        /* Find footer. */
16128
        pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
16129
            &endLen);
16130
        /* Validate header name and footer name are the same. */
16131
        if ((endLen != nameLen) ||
16132
                 (XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
16133
            ret = ASN_NO_PEM_HEADER;
16134
        }
16135
    }
16136
    if (ret == 0) {
16137
        unsigned char* der = (unsigned char*)pem;
16138
        word32 derLen;
16139
16140
        /* Convert PEM body to DER. */
16141
        derLen = (word32)(startEnd - PEM_END_SZ - start);
16142
        ret = Base64_Decode(der + start, derLen, der, &derLen);
16143
        if (ret == 0) {
16144
            /* Return the DER data. */
16145
            *data = der;
16146
            *len = derLen;
16147
        }
16148
    }
16149
16150
    return ret;
16151
}
16152
16153
/* Encode the DER data in PEM format into a newly allocated buffer.
16154
 *
16155
 * @param [in]  name       Header/footer name.
16156
 * @param [in]  header     Encryption header.
16157
 * @param [in]  data       DER data.
16158
 * @param [in]  len        Length of DER data.
16159
 * @param [out] pemOut     PEM encoded data.
16160
 * @param [out] pemOutLen  Length of PEM encoded data.
16161
 * @return  0 on success.
16162
 * @return  MEMORY_E when dynamic memory allocation fails.
16163
 */
16164
static int pem_write_data(const char *name, const char *header,
16165
    const unsigned char *data, long len, char** pemOut, word32* pemOutLen)
16166
{
16167
    int ret = 0;
16168
    int nameLen;
16169
    int headerLen;
16170
    char* pem = NULL;
16171
    word32 pemLen;
16172
    word32 derLen = (word32)len;
16173
    byte* p;
16174
16175
    nameLen = (int)XSTRLEN(name);
16176
    headerLen = (int)XSTRLEN(header);
16177
16178
    /* DER encode for PEM. */
16179
    pemLen  = (derLen + 2) / 3 * 4;
16180
    pemLen += (pemLen + 63) / 64;
16181
    /* Header */
16182
    pemLen += (word32)(PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
16183
    if (headerLen > 0) {
16184
        /* Encryption lines plus extra carriage return. */
16185
        pemLen += (word32)headerLen + 1;
16186
    }
16187
    /* Trailer */
16188
    pemLen += (word32)(PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
16189
16190
    pem = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16191
    if (pem == NULL) {
16192
        ret = MEMORY_E;
16193
    }
16194
    p = (byte*)pem;
16195
16196
    if (ret == 0) {
16197
        /* Add header. */
16198
        XMEMCPY(p, PEM_BEGIN, PEM_BEGIN_SZ);
16199
        p += PEM_BEGIN_SZ;
16200
        XMEMCPY(p, name, (size_t)nameLen);
16201
        p += nameLen;
16202
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
16203
        p += PEM_HDR_FIN_EOL_SZ;
16204
16205
        if (headerLen > 0) {
16206
            /* Add encryption header. */
16207
            XMEMCPY(p, header, (size_t)headerLen);
16208
            p += headerLen;
16209
            /* Blank line after a header and before body. */
16210
            *(p++) = '\n';
16211
        }
16212
16213
        /* Add DER data as PEM. */
16214
        pemLen -= (word32)((size_t)p - (size_t)pem);
16215
        ret = Base64_Encode(data, derLen, p, &pemLen);
16216
    }
16217
    if (ret == 0) {
16218
        p += pemLen;
16219
16220
        /* Add trailer. */
16221
        XMEMCPY(p, PEM_END, PEM_END_SZ);
16222
        p += PEM_END_SZ;
16223
        XMEMCPY(p, name, (size_t)nameLen);
16224
        p += nameLen;
16225
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
16226
        p += PEM_HDR_FIN_EOL_SZ;
16227
16228
        /* Return buffer and length of data. */
16229
        *pemOut = pem;
16230
        *pemOutLen = (word32)((size_t)p - (size_t)pem);
16231
    }
16232
    else {
16233
        /* Dispose of any allocated memory. */
16234
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16235
        pem = NULL;
16236
    }
16237
16238
    return ret;
16239
}
16240
#endif /* !NO_BIO || !NO_FILESYSTEM */
16241
16242
#ifndef NO_BIO
16243
/* Read PEM encoded data from a BIO.
16244
 *
16245
 * Reads the entire contents in.
16246
 *
16247
 * @param [in]  bio     BIO to read from.
16248
 * @param [out] name    Name of content type.
16249
 * @param [out] header  Encryption headers.
16250
 * @param [out] data    DER encoding from PEM.
16251
 * @param [out] len     Length of DER data.
16252
 * @return  1 on success.
16253
 * @return  0 on failure.
16254
 */
16255
int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
16256
    unsigned char **data, long *len)
16257
{
16258
    int res = 1;
16259
    char* pem = NULL;
16260
    int pemLen = 0;
16261
    int memAlloced = 1;
16262
16263
    /* Validate parameters. */
16264
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL) ||
16265
            (len == NULL)) {
16266
        res = 0;
16267
    }
16268
16269
    /* Load all the data from the BIO. */
16270
    if ((res == 1) && (wolfssl_read_bio(bio, &pem, &pemLen, &memAlloced) !=
16271
             0)) {
16272
        res = 0;
16273
    }
16274
    if ((res == 1) && (!memAlloced)) {
16275
        /* Need to return allocated memory - make sure it is allocated. */
16276
        char* p = (char*)XMALLOC((size_t)pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16277
        if (p == NULL) {
16278
            res = 0;
16279
        }
16280
        else {
16281
            /* Copy the data into new buffer. */
16282
            XMEMCPY(p, pem, (size_t)pemLen);
16283
            pem = p;
16284
        }
16285
    }
16286
16287
    /* Read the PEM data. */
16288
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
16289
            0)) {
16290
        /* Dispose of any allocated memory. */
16291
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16292
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16293
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16294
        *name = NULL;
16295
        *header = NULL;
16296
        res = 0;
16297
    }
16298
16299
    return res;
16300
}
16301
16302
/* Encode the DER data in PEM format into a BIO.
16303
 *
16304
 * @param [in] bio     BIO to write to.
16305
 * @param [in] name    Header/footer name.
16306
 * @param [in] header  Encryption header.
16307
 * @param [in] data    DER data.
16308
 * @param [in] len     Length of DER data.
16309
 * @return  0 on failure.
16310
 */
16311
int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
16312
    const char *header, const unsigned char *data, long len)
16313
{
16314
    int err = 0;
16315
    char* pem = NULL;
16316
    word32 pemLen = 0;
16317
16318
    /* Validate parameters. */
16319
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL)) {
16320
        err = BAD_FUNC_ARG;
16321
    }
16322
16323
    /* Encode into a buffer. */
16324
    if (!err) {
16325
        err = pem_write_data(name, header, data, len, &pem, &pemLen);
16326
    }
16327
16328
    /* Write PEM into BIO. */
16329
    if ((!err) && (wolfSSL_BIO_write(bio, pem, (int)pemLen) != (int)pemLen)) {
16330
        err = IO_FAILED_E;
16331
    }
16332
16333
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16334
    return (!err) ? (int)pemLen : 0;
16335
}
16336
#endif /* !NO_BIO */
16337
16338
#if !defined(NO_FILESYSTEM)
16339
/* Read PEM encoded data from a file.
16340
 *
16341
 * Reads the entire contents in.
16342
 *
16343
 * @param [in]  bio     BIO to read from.
16344
 * @param [out] name    Name of content type.
16345
 * @param [out] header  Encryption headers.
16346
 * @param [out] data    DER encoding from PEM.
16347
 * @param [out] len     Length of DER data.
16348
 * @return  1 on success.
16349
 * @return  0 on failure.
16350
 */
16351
int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data,
16352
    long *len)
16353
{
16354
    int res = 1;
16355
    char* pem = NULL;
16356
    int pemLen = 0;
16357
16358
    /* Validate parameters. */
16359
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
16360
            (data == NULL) || (len == NULL)) {
16361
        res = 0;
16362
    }
16363
16364
    /* Load all the data from the file. */
16365
    if ((res == 1) && (wolfssl_read_file(fp, &pem, &pemLen) != 0)) {
16366
        res = 0;
16367
    }
16368
16369
    /* Read the PEM data. */
16370
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
16371
            0)) {
16372
        /* Dispose of any allocated memory. */
16373
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16374
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16375
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16376
        *name = NULL;
16377
        *header = NULL;
16378
        res = 0;
16379
    }
16380
16381
    return res;
16382
}
16383
16384
/* Encode the DER data in PEM format into a file.
16385
 *
16386
 * @param [in] fp      File pointer to write to.
16387
 * @param [in] name    Header/footer name.
16388
 * @param [in] header  Encryption header.
16389
 * @param [in] data    DER data.
16390
 * @param [in] len     Length of DER data.
16391
 * @return  0 on success.
16392
 * @return  MEMORY_E when dynamic memory allocation fails.
16393
 */
16394
int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
16395
    const unsigned char *data, long len)
16396
{
16397
    int err = 0;
16398
    char* pem = NULL;
16399
    word32 pemLen = 0;
16400
16401
    /* Validate parameters. */
16402
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
16403
            (data == NULL)) {
16404
        err = 1;
16405
    }
16406
16407
    /* Encode into a buffer. */
16408
    if ((!err) && (pem_write_data(name, header, data, len, &pem, &pemLen) !=
16409
            0)) {
16410
        pemLen = 0;
16411
        err = 1;
16412
    }
16413
16414
    /* Write PEM to a file. */
16415
    if ((!err) && (XFWRITE(pem, 1, pemLen, fp) != pemLen)) {
16416
        pemLen = 0;
16417
    }
16418
16419
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16420
    return (int)pemLen;
16421
}
16422
#endif
16423
16424
/* Get EVP cipher info from encryption header string.
16425
 *
16426
 * @param [in]  header  Encryption header.
16427
 * @param [out] cipher  EVP Cipher info.
16428
 * @return  1 on success.
16429
 * @return  0 on failure.
16430
 */
16431
int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, EncryptedInfo* cipher)
16432
{
16433
    int res = 1;
16434
16435
    /* Validate parameters. */
16436
    if ((header == NULL) || (cipher == NULL)) {
16437
        res = 0;
16438
    }
16439
16440
    if (res == 1) {
16441
        XMEMSET(cipher, 0, sizeof(*cipher));
16442
16443
        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0) {
16444
            res = 0;
16445
        }
16446
    }
16447
16448
    return res;
16449
}
16450
16451
/* Apply cipher to DER data.
16452
 *
16453
 * @param [in]      cipher  EVP cipher info.
16454
 * @param [in, out] data    On in, encrypted DER data.
16455
 *                          On out, unencrypted DER data.
16456
 * @param [in, out] len     On in, length of encrypted DER data.
16457
 *                          On out, length of unencrypted DER data.
16458
 * @param [in]      cb      Password callback.
16459
 * @param [in]      ctx     Context for password callback.
16460
 * @return  1 on success.
16461
 * @return  0 on failure.
16462
 */
16463
int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
16464
    wc_pem_password_cb* cb, void* ctx)
16465
{
16466
    int ret = 1;
16467
    char password[NAME_SZ];
16468
    int passwordSz = 0;
16469
16470
    /* Validate parameters. */
16471
    if ((cipher == NULL) || (data == NULL) || (len == NULL) || (cb == NULL)) {
16472
        ret = 0;
16473
    }
16474
16475
    if (ret == 1) {
16476
        /* Get password and length. */
16477
        passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
16478
        if (passwordSz < 0) {
16479
            ret = 0;
16480
        }
16481
    }
16482
16483
    if (ret == 1) {
16484
        /* Decrypt the data using password and MD5. */
16485
        if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
16486
                passwordSz, WC_MD5) != 0) {
16487
            ret = WOLFSSL_FAILURE;
16488
        }
16489
    }
16490
16491
    if (passwordSz > 0) {
16492
        /* Ensure password is erased from memory. */
16493
        ForceZero(password, (word32)passwordSz);
16494
    }
16495
16496
    return ret;
16497
}
16498
16499
#endif /* !NO_CERTS */
16500
#endif /* OPENSSL_EXTRA */
16501
16502
#ifdef OPENSSL_ALL
16503
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
16504
16505
/* Encrypt the key into a buffer using PKCS$8 and a password.
16506
 *
16507
 * @param [in]      pkey      Private key to encrypt.
16508
 * @param [in]      enc       EVP cipher.
16509
 * @param [in]      passwd    Password to encrypt with.
16510
 * @param [in]      passwdSz  Number of bytes in password.
16511
 * @param [in]      key       Buffer to hold encrypted key.
16512
 * @param [in, out] keySz     On in, size of buffer in bytes.
16513
 *                            On out, size of encrypted key in bytes.
16514
 * @return  0 on success.
16515
 * @return  BAD_FUNC_ARG when EVP cipher not supported.
16516
 */
16517
int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
16518
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
16519
    word32* keySz)
16520
{
16521
    int ret;
16522
    WC_RNG rng;
16523
16524
    /* Initialize a new random number generator. */
16525
    ret = wc_InitRng(&rng);
16526
    if (ret == 0) {
16527
        int encAlgId = 0;
16528
16529
        /* Convert EVP cipher to a support encryption id. */
16530
    #ifndef NO_DES3
16531
        if (enc == EVP_DES_CBC) {
16532
            encAlgId = DESb;
16533
        }
16534
        else if (enc == EVP_DES_EDE3_CBC) {
16535
            encAlgId = DES3b;
16536
        }
16537
        else
16538
    #endif
16539
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
16540
    #ifdef WOLFSSL_AES_128
16541
        if (enc == EVP_AES_128_CBC) {
16542
            encAlgId = AES128CBCb;
16543
        }
16544
        else
16545
     #endif
16546
    #ifdef WOLFSSL_AES_256
16547
        if (enc == EVP_AES_256_CBC) {
16548
            encAlgId = AES256CBCb;
16549
        }
16550
        else
16551
     #endif
16552
#endif
16553
        {
16554
            ret = BAD_FUNC_ARG;
16555
        }
16556
16557
        if (ret == 0) {
16558
            /* Encrypt private into buffer. */
16559
            ret = TraditionalEnc((byte*)pkey->pkey.ptr + pkey->pkcs8HeaderSz,
16560
                (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
16561
                key, keySz, passwd, passwdSz, PKCS5, PBES2, encAlgId,
16562
                NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL);
16563
            if (ret > 0) {
16564
                *keySz = (word32)ret;
16565
            }
16566
        }
16567
        /* Dispose of random number generator. */
16568
        wc_FreeRng(&rng);
16569
    }
16570
16571
    return ret;
16572
}
16573
16574
/* Encode private key in PKCS#8 format.
16575
 *
16576
 * @param [in]      pkey   Private key.
16577
 * @param [out]     key    Buffer to hold encoding.
16578
 * @param [in, out] keySz  On in, size of buffer in bytes.
16579
 * @param                  On out, size of encoded key in bytes.
16580
 * @return  0 on success.
16581
 */
16582
int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
16583
{
16584
    int ret = 0;
16585
    int algId = 0;
16586
    const byte* curveOid = 0;
16587
    word32 oidSz = 0;
16588
16589
    /* Get the details of the private key. */
16590
#ifdef HAVE_ECC
16591
    if (pkey->type == WC_EVP_PKEY_EC) {
16592
        /* ECC private and get curve OID information. */
16593
        algId = ECDSAk;
16594
        ret = wc_ecc_get_oid((word32)pkey->ecc->group->curve_oid, &curveOid,
16595
            &oidSz);
16596
    }
16597
    else
16598
#endif
16599
    if (pkey->type == WC_EVP_PKEY_RSA) {
16600
        /* RSA private has no curve information. */
16601
        algId = RSAk;
16602
        curveOid = NULL;
16603
        oidSz = 0;
16604
    }
16605
    else if (pkey->type == WC_EVP_PKEY_DSA) {
16606
        /* DSA has no curve information. */
16607
        algId = DSAk;
16608
        curveOid = NULL;
16609
        oidSz = 0;
16610
    }
16611
#ifndef NO_DH
16612
    else if (pkey->type == WC_EVP_PKEY_DH) {
16613
        if (pkey->dh == NULL)
16614
            return BAD_FUNC_ARG;
16615
16616
        if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
16617
            /* Special case. DH buffer is always in PKCS8 format */
16618
            if (keySz == NULL)
16619
                return BAD_FUNC_ARG;
16620
16621
            *keySz = (word32)pkey->pkey_sz;
16622
            if (key == NULL)
16623
                return LENGTH_ONLY_E;
16624
16625
            XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
16626
            return pkey->pkey_sz;
16627
        }
16628
16629
        /* DH has no curve information. */
16630
        algId = DHk;
16631
        curveOid = NULL;
16632
        oidSz = 0;
16633
    }
16634
#endif
16635
    else {
16636
        ret = NOT_COMPILED_IN;
16637
    }
16638
16639
    if (ret >= 0) {
16640
        /* Encode private key in PKCS#8 format. */
16641
        ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr +
16642
            pkey->pkcs8HeaderSz, (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
16643
            algId, curveOid, oidSz);
16644
    }
16645
16646
    return ret;
16647
}
16648
16649
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
16650
    !defined(NO_STDIO_FILESYSTEM))
16651
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
16652
 *
16653
 * @param [out] pem       Buffer holding PEM encoding.
16654
 * @param [out] pemSz     Size of data in buffer in bytes.
16655
 * @param [in]  pkey      Private key to write.
16656
 * @param [in]  enc       Encryption information to use. May be NULL.
16657
 * @param [in]  passwd    Password to use when encrypting. May be NULL.
16658
 * @param [in]  passwdSz  Size of password in bytes.
16659
 * @param [in]  cb        Password callback. Used when passwd is NULL. May be
16660
 *                        NULL.
16661
 * @param [in]  ctx       Context for password callback.
16662
 * @return  Length of PEM encoding on success.
16663
 * @return  0 on failure.
16664
 */
16665
static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
16666
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
16667
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
16668
{
16669
    int res = 1;
16670
    int ret = 0;
16671
    char password[NAME_SZ];
16672
    byte* key = NULL;
16673
    word32 keySz = 0;
16674
    int type = PKCS8_PRIVATEKEY_TYPE;
16675
16676
    /* Validate parameters. */
16677
    if (pkey == NULL) {
16678
        res = 0;
16679
    }
16680
16681
    if (res == 1) {
16682
        /* Guestimate key size and PEM size. */
16683
        if (pkcs8_encode(pkey, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
16684
            res = 0;
16685
        }
16686
    }
16687
    if (res == 1) {
16688
        if (enc != NULL) {
16689
            /* Add on enough for extra DER data when encrypting. */
16690
            keySz += 128;
16691
        }
16692
        /* PEM encoding size from DER size. */
16693
        *pemSz  = (int)(keySz + 2) / 3 * 4;
16694
        *pemSz += (*pemSz + 63) / 64;
16695
        /* Header and footer. */
16696
        if (enc != NULL) {
16697
            /* Name is: 'ENCRYPTED PRIVATE KEY'. */
16698
            *pemSz += 74;
16699
        }
16700
        else {
16701
            /* Name is: 'PRIVATE KEY'. */
16702
            *pemSz += 54;
16703
        }
16704
16705
        /* Allocate enough memory to hold PEM encoded encrypted key. */
16706
        *pem = (byte*)XMALLOC((size_t)*pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16707
        if (*pem == NULL) {
16708
            res = 0;
16709
        }
16710
        else {
16711
            /* Use end of PEM buffer for key data. */
16712
            key = *pem + *pemSz - keySz;
16713
        }
16714
    }
16715
16716
    if ((res == 1) && (enc != NULL)) {
16717
        /* Set type for PEM. */
16718
        type = PKCS8_ENC_PRIVATEKEY_TYPE;
16719
16720
        if (passwd == NULL) {
16721
            /* Get the password by using callback. */
16722
            passwdSz = cb(password, sizeof(password), 1, ctx);
16723
            if (passwdSz < 0) {
16724
                res = 0;
16725
            }
16726
            passwd = password;
16727
        }
16728
16729
        if (res == 1) {
16730
            /* Encrypt the private key. */
16731
            ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
16732
            if (ret <= 0) {
16733
                res = 0;
16734
            }
16735
        }
16736
16737
        /* Zeroize the password from memory. */
16738
        if ((password == passwd) && (passwdSz > 0)) {
16739
            ForceZero(password, (word32)passwdSz);
16740
        }
16741
    }
16742
    else if ((res == 1) && (enc == NULL)) {
16743
        /* Set type for PEM. */
16744
        type = PKCS8_PRIVATEKEY_TYPE;
16745
16746
        /* Encode private key in PKCS#8 format. */
16747
        ret = pkcs8_encode(pkey, key, &keySz);
16748
        if (ret < 0) {
16749
            res = 0;
16750
        }
16751
    }
16752
16753
    if (res == 1) {
16754
        /* Encode PKCS#8 formatted key to PEM. */
16755
        ret = wc_DerToPemEx(key, keySz, *pem, (word32)*pemSz, NULL, type);
16756
        if (ret < 0) {
16757
            res = 0;
16758
        }
16759
        else {
16760
            *pemSz = ret;
16761
        }
16762
    }
16763
16764
    /* Return appropriate return code. */
16765
    return (res == 0) ? 0 : ret;
16766
16767
}
16768
#endif /* !NO_BIO || (!NO_FILESYSTEM && !NO_STDIO_FILESYSTEM) */
16769
16770
#ifndef NO_BIO
16771
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
16772
 *
16773
 * TODO: OpenSSL returns 1 and 0 only.
16774
 *
16775
 * @param [in] bio       BIO to write to.
16776
 * @param [in] pkey      Private key to write.
16777
 * @param [in] enc       Encryption information to use. May be NULL.
16778
 * @param [in] passwd    Password to use when encrypting. May be NULL.
16779
 * @param [in] passwdSz  Size of password in bytes.
16780
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
16781
 *                       NULL.
16782
 * @param [in] ctx       Context for password callback.
16783
 * @return  Length of PEM encoding on success.
16784
 * @return  0 on failure.
16785
 */
16786
int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
16787
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
16788
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
16789
{
16790
    byte* pem = NULL;
16791
    int pemSz = 0;
16792
    int res = 1;
16793
16794
    /* Validate parameters. */
16795
    if (bio == NULL) {
16796
        res = 0;
16797
    }
16798
    if (res == 1) {
16799
        /* Write private key to memory. */
16800
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
16801
            passwdSz, cb, ctx);
16802
    }
16803
16804
    /* Write encoded key to BIO. */
16805
    if ((res >= 1) && (wolfSSL_BIO_write(bio, pem, pemSz) != pemSz)) {
16806
        res = 0;
16807
    }
16808
16809
    /* Dispose of dynamically allocated memory (pem and key). */
16810
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16811
    return res;
16812
}
16813
16814
int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
16815
        PKCS8_PRIV_KEY_INFO* keyInfo)
16816
{
16817
    return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
16818
            NULL, NULL);
16819
}
16820
#endif /* !NO_BIO */
16821
16822
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
16823
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
16824
 *
16825
 * TODO: OpenSSL returns 1 and 0 only.
16826
 *
16827
 * @param [in] f         File pointer.
16828
 * @param [in] pkey      Private key to write.
16829
 * @param [in] enc       Encryption information to use. May be NULL.
16830
 * @param [in] passwd    Password to use when encrypting. May be NULL.
16831
 * @param [in] passwdSz  Size of password in bytes.
16832
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
16833
 *                       NULL.
16834
 * @param [in] ctx       Context for password callback.
16835
 * @return  Length of PEM encoding on success.
16836
 * @return  0 on failure.
16837
 */
16838
int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
16839
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
16840
    wc_pem_password_cb* cb, void* ctx)
16841
{
16842
    byte* pem = NULL;
16843
    int pemSz = 0;
16844
    int res = 1;
16845
16846
    /* Validate parameters. */
16847
    if (f == XBADFILE) {
16848
        res = 0;
16849
    }
16850
    if (res == 1) {
16851
        /* Write private key to memory. */
16852
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
16853
            passwdSz, cb, ctx);
16854
    }
16855
16856
    /* Write encoded key to file. */
16857
    if ((res >= 1) && (XFWRITE(pem, 1, (size_t)pemSz, f) != (size_t)pemSz)) {
16858
        res = 0;
16859
    }
16860
16861
    /* Dispose of dynamically allocated memory (pem and key). */
16862
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16863
    return res;
16864
}
16865
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
16866
16867
#endif /* !NO_PWDBASED && HAVE_PKCS8 */
16868
#endif /* OPENSSL_ALL */
16869
16870
/*******************************************************************************
16871
 * END OF GENERIC PUBLIC KEY PEM APIs
16872
 ******************************************************************************/
16873
16874
#endif /* !WOLFSSL_PK_INCLUDED */
16875