Coverage Report

Created: 2025-10-13 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/src/pk.c
Line
Count
Source
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 > 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
    if (privSz > 0) {
8961
#ifdef WOLFSSL_SMALL_STACK
8962
        if (priv != NULL)
8963
#endif
8964
        {
8965
            /* Zeroize sensitive data. */
8966
            ForceZero(priv, (word32)privSz);
8967
        }
8968
    }
8969
#ifdef WOLFSSL_SMALL_STACK
8970
    XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
8971
    XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
8972
#endif
8973
8974
    WOLFSSL_LEAVE("wolfSSL_DH_compute_key", ret);
8975
8976
    return ret;
8977
}
8978
8979
/* Compute the shared key from the private key and peer's public key.
8980
 *
8981
 * Return code compliant with OpenSSL.
8982
 * OpenSSL returns 0 when number of bits in p are smaller than minimum
8983
 * supported.
8984
 *
8985
 * @param [out] key       Buffer to place shared key.
8986
 * @param [in]  otherPub  Peer's public key.
8987
 * @param [in]  dh        DH key containing private key.
8988
 * @return  -1 on error.
8989
 * @return  Size of shared secret in bytes on success.
8990
 */
8991
int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
8992
    WOLFSSL_DH* dh)
8993
{
8994
    return _DH_compute_key(key, otherPub, dh, 0);
8995
}
8996
8997
/* Compute the shared key from the private key and peer's public key as in
8998
 * wolfSSL_DH_compute_key, but using constant time processing, with an output
8999
 * key length fixed at the nominal DH key size.  Leading zeros are retained.
9000
 *
9001
 * Return code compliant with OpenSSL.
9002
 * OpenSSL returns 0 when number of bits in p are smaller than minimum
9003
 * supported.
9004
 *
9005
 * @param [out] key       Buffer to place shared key.
9006
 * @param [in]  otherPub  Peer's public key.
9007
 * @param [in]  dh        DH key containing private key.
9008
 * @return  -1 on error.
9009
 * @return  Size of shared secret in bytes on success.
9010
 */
9011
int wolfSSL_DH_compute_key_padded(unsigned char* key,
9012
    const WOLFSSL_BIGNUM* otherPub, WOLFSSL_DH* dh)
9013
{
9014
    return _DH_compute_key(key, otherPub, dh, 1);
9015
}
9016
9017
#endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) ||
9018
        * HAVE_FIPS_VERSION > 2 */
9019
9020
#endif /* OPENSSL_EXTRA */
9021
9022
#endif /* NO_DH */
9023
9024
/*******************************************************************************
9025
 * END OF DH API
9026
 ******************************************************************************/
9027
9028
9029
/*******************************************************************************
9030
 * START OF EC API
9031
 ******************************************************************************/
9032
9033
#ifdef HAVE_ECC
9034
9035
#if defined(OPENSSL_EXTRA)
9036
9037
/* Start EC_curve */
9038
9039
/* Get the NIST name for the numeric ID.
9040
 *
9041
 * @param [in] nid  Numeric ID of an EC curve.
9042
 * @return  String representing NIST name of EC curve on success.
9043
 * @return  NULL on error.
9044
 */
9045
const char* wolfSSL_EC_curve_nid2nist(int nid)
9046
{
9047
    const char* name = NULL;
9048
    const WOLF_EC_NIST_NAME* nist_name;
9049
9050
    /* Attempt to find the curve info matching the NID passed in. */
9051
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
9052
        if (nist_name->nid == nid) {
9053
            /* NID found - return name. */
9054
            name = nist_name->name;
9055
            break;
9056
        }
9057
    }
9058
9059
    return name;
9060
}
9061
9062
/* Get the numeric ID for the NIST name.
9063
 *
9064
 * @param [in] name  NIST name of EC curve.
9065
 * @return  NID matching NIST name on success.
9066
 * @return  0 on error.
9067
 */
9068
int wolfSSL_EC_curve_nist2nid(const char* name)
9069
{
9070
    int nid = 0;
9071
    const WOLF_EC_NIST_NAME* nist_name;
9072
9073
    /* Attempt to find the curve info matching the NIST name passed in. */
9074
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
9075
        if (XSTRCMP(nist_name->name, name) == 0) {
9076
            /* Name found - return NID. */
9077
            nid = nist_name->nid;
9078
            break;
9079
        }
9080
    }
9081
9082
    return nid;
9083
}
9084
9085
#endif /* OPENSSL_EXTRA */
9086
9087
/* End EC_curve */
9088
9089
/* Start EC_METHOD */
9090
9091
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9092
/* Get the EC method of the EC group object.
9093
 *
9094
 * wolfSSL doesn't use method tables. Implementation used is dependent upon
9095
 * the NID.
9096
 *
9097
 * @param [in] group  EC group object.
9098
 * @return  EC method.
9099
 */
9100
const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of(
9101
    const WOLFSSL_EC_GROUP *group)
9102
{
9103
    /* No method table used so just return the same object. */
9104
    return group;
9105
}
9106
9107
/* Get field type for method.
9108
 *
9109
 * Only prime fields are supported.
9110
 *
9111
 * @param [in] meth  EC method.
9112
 * @return  X9.63 prime field NID on success.
9113
 * @return  0 on error.
9114
 */
9115
int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth)
9116
{
9117
    int nid = 0;
9118
9119
    if (meth != NULL) {
9120
        /* Only field type supported by code base. */
9121
        nid = WC_NID_X9_62_prime_field;
9122
    }
9123
9124
    return nid;
9125
}
9126
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9127
9128
/* End EC_METHOD */
9129
9130
/* Start EC_GROUP */
9131
9132
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9133
/* Converts ECC curve enum values in ecc_curve_id to the associated OpenSSL NID
9134
 * value.
9135
 *
9136
 * @param [in] n  ECC curve id.
9137
 * @return  ECC curve NID (OpenSSL compatible value).
9138
 */
9139
int EccEnumToNID(int n)
9140
{
9141
    WOLFSSL_ENTER("EccEnumToNID");
9142
9143
    switch(n) {
9144
        case ECC_SECP192R1:
9145
            return WC_NID_X9_62_prime192v1;
9146
        case ECC_PRIME192V2:
9147
            return WC_NID_X9_62_prime192v2;
9148
        case ECC_PRIME192V3:
9149
            return WC_NID_X9_62_prime192v3;
9150
        case ECC_PRIME239V1:
9151
            return WC_NID_X9_62_prime239v1;
9152
        case ECC_PRIME239V2:
9153
            return WC_NID_X9_62_prime239v2;
9154
        case ECC_PRIME239V3:
9155
            return WC_NID_X9_62_prime239v3;
9156
        case ECC_SECP256R1:
9157
            return WC_NID_X9_62_prime256v1;
9158
        case ECC_SECP112R1:
9159
            return WC_NID_secp112r1;
9160
        case ECC_SECP112R2:
9161
            return WC_NID_secp112r2;
9162
        case ECC_SECP128R1:
9163
            return WC_NID_secp128r1;
9164
        case ECC_SECP128R2:
9165
            return WC_NID_secp128r2;
9166
        case ECC_SECP160R1:
9167
            return WC_NID_secp160r1;
9168
        case ECC_SECP160R2:
9169
            return WC_NID_secp160r2;
9170
        case ECC_SECP224R1:
9171
            return WC_NID_secp224r1;
9172
        case ECC_SECP384R1:
9173
            return WC_NID_secp384r1;
9174
        case ECC_SECP521R1:
9175
            return WC_NID_secp521r1;
9176
        case ECC_SECP160K1:
9177
            return WC_NID_secp160k1;
9178
        case ECC_SECP192K1:
9179
            return WC_NID_secp192k1;
9180
        case ECC_SECP224K1:
9181
            return WC_NID_secp224k1;
9182
        case ECC_SECP256K1:
9183
            return WC_NID_secp256k1;
9184
        case ECC_BRAINPOOLP160R1:
9185
            return WC_NID_brainpoolP160r1;
9186
        case ECC_BRAINPOOLP192R1:
9187
            return WC_NID_brainpoolP192r1;
9188
        case ECC_BRAINPOOLP224R1:
9189
            return WC_NID_brainpoolP224r1;
9190
        case ECC_BRAINPOOLP256R1:
9191
            return WC_NID_brainpoolP256r1;
9192
        case ECC_BRAINPOOLP320R1:
9193
            return WC_NID_brainpoolP320r1;
9194
        case ECC_BRAINPOOLP384R1:
9195
            return WC_NID_brainpoolP384r1;
9196
        case ECC_BRAINPOOLP512R1:
9197
            return WC_NID_brainpoolP512r1;
9198
    #ifdef WOLFSSL_SM2
9199
        case ECC_SM2P256V1:
9200
            return WC_NID_sm2;
9201
    #endif
9202
        default:
9203
            WOLFSSL_MSG("NID not found");
9204
            return WOLFSSL_FATAL_ERROR;
9205
    }
9206
}
9207
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9208
9209
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9210
/* Converts OpenSSL NID of EC curve to the enum value in ecc_curve_id
9211
 *
9212
 * Used by ecc_sets[].
9213
 *
9214
 * @param [in] n  OpenSSL NID of EC curve.
9215
 * @return  wolfCrypt EC curve id.
9216
 * @return  -1 on error.
9217
 */
9218
int NIDToEccEnum(int nid)
9219
{
9220
    int id;
9221
9222
    WOLFSSL_ENTER("NIDToEccEnum");
9223
9224
    switch (nid) {
9225
        case WC_NID_X9_62_prime192v1:
9226
            id = ECC_SECP192R1;
9227
            break;
9228
        case WC_NID_X9_62_prime192v2:
9229
            id = ECC_PRIME192V2;
9230
            break;
9231
        case WC_NID_X9_62_prime192v3:
9232
            id = ECC_PRIME192V3;
9233
            break;
9234
        case WC_NID_X9_62_prime239v1:
9235
            id = ECC_PRIME239V1;
9236
            break;
9237
        case WC_NID_X9_62_prime239v2:
9238
            id = ECC_PRIME239V2;
9239
            break;
9240
        case WC_NID_X9_62_prime239v3:
9241
            id = ECC_PRIME239V3;
9242
            break;
9243
        case WC_NID_X9_62_prime256v1:
9244
            id = ECC_SECP256R1;
9245
            break;
9246
        case WC_NID_secp112r1:
9247
            id = ECC_SECP112R1;
9248
            break;
9249
        case WC_NID_secp112r2:
9250
            id = ECC_SECP112R2;
9251
            break;
9252
        case WC_NID_secp128r1:
9253
            id = ECC_SECP128R1;
9254
            break;
9255
        case WC_NID_secp128r2:
9256
            id = ECC_SECP128R2;
9257
            break;
9258
        case WC_NID_secp160r1:
9259
            id = ECC_SECP160R1;
9260
            break;
9261
        case WC_NID_secp160r2:
9262
            id = ECC_SECP160R2;
9263
            break;
9264
        case WC_NID_secp224r1:
9265
            id = ECC_SECP224R1;
9266
            break;
9267
        case WC_NID_secp384r1:
9268
            id = ECC_SECP384R1;
9269
            break;
9270
        case WC_NID_secp521r1:
9271
            id = ECC_SECP521R1;
9272
            break;
9273
        case WC_NID_secp160k1:
9274
            id = ECC_SECP160K1;
9275
            break;
9276
        case WC_NID_secp192k1:
9277
            id = ECC_SECP192K1;
9278
            break;
9279
        case WC_NID_secp224k1:
9280
            id = ECC_SECP224K1;
9281
            break;
9282
        case WC_NID_secp256k1:
9283
            id = ECC_SECP256K1;
9284
            break;
9285
        case WC_NID_brainpoolP160r1:
9286
            id = ECC_BRAINPOOLP160R1;
9287
            break;
9288
        case WC_NID_brainpoolP192r1:
9289
            id = ECC_BRAINPOOLP192R1;
9290
            break;
9291
        case WC_NID_brainpoolP224r1:
9292
            id = ECC_BRAINPOOLP224R1;
9293
            break;
9294
        case WC_NID_brainpoolP256r1:
9295
            id = ECC_BRAINPOOLP256R1;
9296
            break;
9297
        case WC_NID_brainpoolP320r1:
9298
            id = ECC_BRAINPOOLP320R1;
9299
            break;
9300
        case WC_NID_brainpoolP384r1:
9301
            id = ECC_BRAINPOOLP384R1;
9302
            break;
9303
        case WC_NID_brainpoolP512r1:
9304
            id = ECC_BRAINPOOLP512R1;
9305
            break;
9306
        default:
9307
            WOLFSSL_MSG("NID not found");
9308
            /* -1 on error. */
9309
            id = WOLFSSL_FATAL_ERROR;
9310
    }
9311
9312
    return id;
9313
}
9314
9315
/* Set the fields of the EC group based on numeric ID.
9316
 *
9317
 * @param [in, out] group  EC group.
9318
 * @param [in]      nid    Numeric ID of an EC curve.
9319
 */
9320
static void ec_group_set_nid(WOLFSSL_EC_GROUP* group, int nid)
9321
{
9322
    int eccEnum;
9323
    int realNid;
9324
9325
    /* Convert ecc_curve_id enum to NID. */
9326
    if ((realNid = EccEnumToNID(nid)) != -1) {
9327
        /* ecc_curve_id enum passed in - have real NID value set. */
9328
        eccEnum = nid;
9329
    }
9330
    else {
9331
        /* NID passed in is OpenSSL type. */
9332
        realNid = nid;
9333
        /* Convert NID to ecc_curve_id enum. */
9334
        eccEnum = NIDToEccEnum(nid);
9335
    }
9336
9337
    /* Set the numeric ID of the curve */
9338
    group->curve_nid = realNid;
9339
    /* Initialize index to -1 (i.e. wolfCrypt doesn't support curve). */
9340
    group->curve_idx = -1;
9341
9342
    /* Find index and OID sum for curve if wolfCrypt supports it. */
9343
    if (eccEnum != -1) {
9344
        int i;
9345
9346
        /* Find id and set the internal curve idx and OID sum. */
9347
        for (i = 0; ecc_sets[i].size != 0; i++) {
9348
            if (ecc_sets[i].id == eccEnum) {
9349
                /* Found id in wolfCrypt supported EC curves. */
9350
                group->curve_idx = i;
9351
                group->curve_oid = (int)ecc_sets[i].oidSum;
9352
                break;
9353
            }
9354
        }
9355
    }
9356
}
9357
9358
/* Create a new EC group with the numeric ID for an EC curve.
9359
 *
9360
 * @param [in] nid  Numeric ID of an EC curve.
9361
 * @return  New, allocated EC group on success.
9362
 * @return  NULL on error.
9363
 */
9364
WOLFSSL_EC_GROUP* wolfSSL_EC_GROUP_new_by_curve_name(int nid)
9365
{
9366
    int err = 0;
9367
    WOLFSSL_EC_GROUP* group;
9368
9369
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_new_by_curve_name");
9370
9371
    /* Allocate EC group. */
9372
    group = (WOLFSSL_EC_GROUP*)XMALLOC(sizeof(WOLFSSL_EC_GROUP), NULL,
9373
        DYNAMIC_TYPE_ECC);
9374
    if (group == NULL) {
9375
        WOLFSSL_MSG("wolfSSL_EC_GROUP_new_by_curve_name malloc failure");
9376
        err = 1;
9377
    }
9378
9379
    if (!err) {
9380
        /* Reset all fields. */
9381
        XMEMSET(group, 0, sizeof(WOLFSSL_EC_GROUP));
9382
9383
        /* Set the fields of group based on the numeric ID. */
9384
        ec_group_set_nid(group, nid);
9385
    }
9386
9387
    return group;
9388
}
9389
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9390
9391
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9392
/* Dispose of the EC group.
9393
 *
9394
 * Cannot use group after this call.
9395
 *
9396
 * @param [in] group  EC group to free.
9397
 */
9398
void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group)
9399
{
9400
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_free");
9401
9402
    /* Dispose of EC group. */
9403
    XFREE(group, NULL, DYNAMIC_TYPE_ECC);
9404
}
9405
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9406
9407
#ifdef OPENSSL_EXTRA
9408
#ifndef NO_BIO
9409
9410
/* Creates an EC group from the DER encoding.
9411
 *
9412
 * Only named curves supported.
9413
 *
9414
 * @param [out] group  Reference to EC group object.
9415
 * @param [in]  in     Buffer holding DER encoding of curve.
9416
 * @param [in]  inSz   Length of data in buffer.
9417
 * @return  EC group on success.
9418
 * @return  NULL on error.
9419
 */
9420
static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group,
9421
    const unsigned char** in_pp, long inSz)
9422
{
9423
    int err = 0;
9424
    WOLFSSL_EC_GROUP* ret = NULL;
9425
    word32 idx = 0;
9426
    word32 oid = 0;
9427
    int id = 0;
9428
    const unsigned char* in;
9429
9430
    if (in_pp == NULL || *in_pp == NULL)
9431
        return NULL;
9432
9433
    in = *in_pp;
9434
9435
    /* Use the group passed in. */
9436
    if ((group != NULL) && (*group != NULL)) {
9437
        ret = *group;
9438
    }
9439
9440
    /* Only support named curves. */
9441
    if (in[0] != ASN_OBJECT_ID) {
9442
        WOLFSSL_ERROR_MSG("Invalid or unsupported encoding");
9443
        err = 1;
9444
    }
9445
    /* Decode the OBJECT ID - expecting an EC curve OID. */
9446
    if ((!err) && (GetObjectId(in, &idx, &oid, oidCurveType, (word32)inSz) !=
9447
            0)) {
9448
        err = 1;
9449
    }
9450
    if (!err) {
9451
        /* Get the internal ID for OID. */
9452
        id = wc_ecc_get_oid(oid, NULL, NULL);
9453
        if (id < 0) {
9454
            err = 1;
9455
        }
9456
    }
9457
    if (!err) {
9458
        /* Get the NID for the internal ID. */
9459
        int nid = EccEnumToNID(id);
9460
        if (ret == NULL) {
9461
            /* Create a new EC group with the numeric ID. */
9462
            ret = wolfSSL_EC_GROUP_new_by_curve_name(nid);
9463
            if (ret == NULL) {
9464
                err = 1;
9465
            }
9466
        }
9467
        else {
9468
            ec_group_set_nid(ret, nid);
9469
        }
9470
    }
9471
    if ((!err) && (group != NULL)) {
9472
        /* Return the EC group through reference. */
9473
        *group = ret;
9474
    }
9475
9476
    if (err) {
9477
        if ((ret != NULL) && (ret != *group)) {
9478
            wolfSSL_EC_GROUP_free(ret);
9479
        }
9480
        ret = NULL;
9481
    }
9482
    else {
9483
        *in_pp += idx;
9484
    }
9485
    return ret;
9486
}
9487
9488
/* Creates a new EC group from the PEM encoding in the BIO.
9489
 *
9490
 * @param [in]  bio    BIO to read PEM encoding from.
9491
 * @param [out] group  Reference to EC group object.
9492
 * @param [in]  cb     Password callback when PEM encrypted.
9493
 * @param [in]  pass   NUL terminated string for passphrase when PEM encrypted.
9494
 * @return  EC group on success.
9495
 * @return  NULL on error.
9496
 */
9497
WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio,
9498
    WOLFSSL_EC_GROUP** group, wc_pem_password_cb* cb, void* pass)
9499
{
9500
    int err = 0;
9501
    WOLFSSL_EC_GROUP* ret = NULL;
9502
    DerBuffer*        der = NULL;
9503
    int               keyFormat = 0;
9504
9505
     if (bio == NULL) {
9506
         err = 1;
9507
     }
9508
9509
    /* Read parameters from BIO and convert PEM to DER. */
9510
    if ((!err) && (pem_read_bio_key(bio, cb, pass, ECC_PARAM_TYPE,
9511
            &keyFormat, &der) < 0)) {
9512
        err = 1;
9513
    }
9514
    if (!err) {
9515
        /* Create EC group from DER encoding. */
9516
        const byte** p = (const byte**)&der->buffer;
9517
        ret = wolfssl_ec_group_d2i(group, p, der->length);
9518
        if (ret == NULL) {
9519
            WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_GROUP");
9520
        }
9521
    }
9522
9523
    /* Dispose of any allocated data. */
9524
    FreeDer(&der);
9525
    return ret;
9526
}
9527
9528
WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out,
9529
        const unsigned char **in, long len)
9530
{
9531
    return wolfssl_ec_group_d2i(out, in, len);
9532
}
9533
9534
int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp)
9535
{
9536
    unsigned char* out = NULL;
9537
    int len = 0;
9538
    int idx;
9539
    const byte* oid = NULL;
9540
    word32 oidSz = 0;
9541
9542
    if (grp == NULL || !wc_ecc_is_valid_idx(grp->curve_idx) ||
9543
            grp->curve_idx < 0)
9544
        return WOLFSSL_FATAL_ERROR;
9545
9546
    /* Get the actual DER encoding of the OID. ecc_sets[grp->curve_idx].oid
9547
     * is just the numerical representation. */
9548
    if (wc_ecc_get_oid((word32)grp->curve_oid, &oid, &oidSz) < 0)
9549
        return WOLFSSL_FATAL_ERROR;
9550
9551
    len = SetObjectId((int)oidSz, NULL) + (int)oidSz;
9552
9553
    if (pp == NULL)
9554
        return len;
9555
9556
    if (*pp == NULL) {
9557
        out = (unsigned char*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1);
9558
        if (out == NULL)
9559
            return WOLFSSL_FATAL_ERROR;
9560
    }
9561
    else {
9562
        out = *pp;
9563
    }
9564
9565
    idx = SetObjectId((int)oidSz, out);
9566
    XMEMCPY(out + idx, oid, oidSz);
9567
    if (*pp == NULL)
9568
        *pp = out;
9569
    else
9570
        *pp += len;
9571
9572
    return len;
9573
}
9574
#endif /* !NO_BIO */
9575
9576
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
9577
/* Copy an EC group.
9578
 *
9579
 * Only used by wolfSSL_EC_KEY_dup at this time.
9580
 *
9581
 * @param [in, out] dst  Destination EC group.
9582
 * @param [in]      src  Source EC group.
9583
 * @return  0 on success.
9584
 */
9585
static int wolfssl_ec_group_copy(WOLFSSL_EC_GROUP* dst,
9586
    const WOLFSSL_EC_GROUP* src)
9587
{
9588
    /* Copy the fields. */
9589
    dst->curve_idx = src->curve_idx;
9590
    dst->curve_nid = src->curve_nid;
9591
    dst->curve_oid = src->curve_oid;
9592
9593
    return 0;
9594
}
9595
#endif /* OPENSSL_ALL && !NO_CERTS */
9596
9597
/* Copies ecc_key into new WOLFSSL_EC_GROUP object
9598
 *
9599
 * @param [in] src  EC group to duplicate.
9600
 *
9601
 * @return  EC group on success.
9602
 * @return  NULL on error.
9603
 */
9604
WOLFSSL_EC_GROUP* wolfSSL_EC_GROUP_dup(const WOLFSSL_EC_GROUP *src)
9605
{
9606
    WOLFSSL_EC_GROUP* newGroup = NULL;
9607
9608
    if (src != NULL) {
9609
        /* Create new group base on NID in original EC group. */
9610
        newGroup = wolfSSL_EC_GROUP_new_by_curve_name(src->curve_nid);
9611
     }
9612
9613
    return newGroup;
9614
}
9615
9616
/* Compare two EC groups.
9617
 *
9618
 * Return code compliant with OpenSSL.
9619
 *
9620
 * @param [in] a    First EC group.
9621
 * @param [in] b    Second EC group.
9622
 * @param [in] ctx  Big number context to use when comparing fields. Unused.
9623
 *
9624
 * @return  0 if equal.
9625
 * @return  1 if not equal.
9626
 * @return  -1 on error.
9627
 */
9628
int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b,
9629
                         WOLFSSL_BN_CTX *ctx)
9630
{
9631
    int ret;
9632
9633
    /* No BN operations performed. */
9634
    (void)ctx;
9635
9636
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_cmp");
9637
9638
    /* Validate parameters. */
9639
    if ((a == NULL) || (b == NULL)) {
9640
        WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments");
9641
        /* Return error value. */
9642
        ret = WOLFSSL_FATAL_ERROR;
9643
    }
9644
    /* Compare NID and wolfSSL curve index. */
9645
    else {
9646
        /* 0 when same, 1 when not. */
9647
        ret = ((a->curve_nid == b->curve_nid) &&
9648
               (a->curve_idx == b->curve_idx)) ? 0 : 1;
9649
    }
9650
9651
    return ret;
9652
}
9653
9654
#ifndef NO_WOLFSSL_STUB
9655
/* Set the ASN.1 flag that indicate encoding of curve.
9656
 *
9657
 * Stub function - flag not used elsewhere.
9658
 * Always encoded as named curve.
9659
 *
9660
 * @param [in] group  EC group to modify.
9661
 * @param [in] flag   ASN.1 flag to set. Valid values:
9662
 *                    OPENSSL_EC_EXPLICIT_CURVE, OPENSSL_EC_NAMED_CURVE
9663
 */
9664
void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag)
9665
{
9666
    (void)group;
9667
    (void)flag;
9668
9669
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_set_asn1_flag");
9670
    WOLFSSL_STUB("EC_GROUP_set_asn1_flag");
9671
}
9672
#endif
9673
9674
/* Get the curve NID of the group.
9675
 *
9676
 * Return code compliant with OpenSSL.
9677
 *
9678
 * @param [in] group  EC group.
9679
 * @return  Curve NID on success.
9680
 * @return  0 on error.
9681
 */
9682
int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group)
9683
{
9684
    int nid = 0;
9685
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_curve_name");
9686
9687
    if (group == NULL) {
9688
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments");
9689
    }
9690
    else {
9691
        nid = group->curve_nid;
9692
    }
9693
9694
    return nid;
9695
}
9696
9697
/* Get the degree (curve size in bits) of the EC group.
9698
 *
9699
 * Return code compliant with OpenSSL.
9700
 *
9701
 * @return  Degree of the curve on success.
9702
 * @return  0 on error.
9703
 */
9704
int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group)
9705
{
9706
    int degree = 0;
9707
9708
    WOLFSSL_ENTER("wolfSSL_EC_GROUP_get_degree");
9709
9710
    if (group == NULL) {
9711
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments");
9712
    }
9713
    else {
9714
        switch (group->curve_nid) {
9715
            case WC_NID_secp112r1:
9716
            case WC_NID_secp112r2:
9717
                degree = 112;
9718
                break;
9719
            case WC_NID_secp128r1:
9720
            case WC_NID_secp128r2:
9721
                degree = 128;
9722
                break;
9723
            case WC_NID_secp160k1:
9724
            case WC_NID_secp160r1:
9725
            case WC_NID_secp160r2:
9726
            case WC_NID_brainpoolP160r1:
9727
                degree = 160;
9728
                break;
9729
            case WC_NID_secp192k1:
9730
            case WC_NID_brainpoolP192r1:
9731
            case WC_NID_X9_62_prime192v1:
9732
            case WC_NID_X9_62_prime192v2:
9733
            case WC_NID_X9_62_prime192v3:
9734
                degree = 192;
9735
                break;
9736
            case WC_NID_secp224k1:
9737
            case WC_NID_secp224r1:
9738
            case WC_NID_brainpoolP224r1:
9739
                degree = 224;
9740
                break;
9741
            case WC_NID_X9_62_prime239v1:
9742
            case WC_NID_X9_62_prime239v2:
9743
            case WC_NID_X9_62_prime239v3:
9744
                degree = 239;
9745
                break;
9746
            case WC_NID_secp256k1:
9747
            case WC_NID_brainpoolP256r1:
9748
            case WC_NID_X9_62_prime256v1:
9749
                degree = 256;
9750
                break;
9751
            case WC_NID_brainpoolP320r1:
9752
                degree = 320;
9753
                break;
9754
            case WC_NID_secp384r1:
9755
            case WC_NID_brainpoolP384r1:
9756
                degree = 384;
9757
                break;
9758
            case WC_NID_brainpoolP512r1:
9759
                degree = 512;
9760
                break;
9761
            case WC_NID_secp521r1:
9762
                degree = 521;
9763
                break;
9764
        }
9765
    }
9766
9767
    return degree;
9768
}
9769
#endif /* OPENSSL_EXTRA */
9770
9771
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9772
/* Get the length of the order in bits of the EC group.
9773
 *
9774
 * TODO: consider switch statement or calculating directly from hex string
9775
 * array instead of using mp_int.
9776
 *
9777
 * @param [in] group  EC group.
9778
 * @return  Length of order in bits on success.
9779
 * @return  0 on error.
9780
 */
9781
int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group)
9782
{
9783
    int ret = 0;
9784
#ifdef WOLFSSL_SMALL_STACK
9785
    mp_int *order = NULL;
9786
#else
9787
    mp_int order[1];
9788
#endif
9789
9790
    /* Validate parameter. */
9791
    if ((group == NULL) || (group->curve_idx < 0)) {
9792
        WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error");
9793
        ret = WOLFSSL_FATAL_ERROR;
9794
    }
9795
9796
#ifdef WOLFSSL_SMALL_STACK
9797
    if (ret == 0) {
9798
        /* Allocate memory for mp_int that will hold order value. */
9799
        order = (mp_int *)XMALLOC(sizeof(*order), NULL,
9800
            DYNAMIC_TYPE_TMP_BUFFER);
9801
        if (order == NULL) {
9802
            ret = WOLFSSL_FATAL_ERROR;
9803
        }
9804
    }
9805
#endif
9806
9807
    if (ret == 0) {
9808
        /* Initialize mp_int. */
9809
        ret = mp_init(order);
9810
    }
9811
9812
    if (ret == 0) {
9813
        /* Read hex string of order from wolfCrypt array of curves. */
9814
        ret = mp_read_radix(order, ecc_sets[group->curve_idx].order,
9815
            MP_RADIX_HEX);
9816
        if (ret == 0) {
9817
            /* Get bits of order. */
9818
            ret = mp_count_bits(order);
9819
        }
9820
        /* Clear and free mp_int. */
9821
        mp_clear(order);
9822
    }
9823
9824
#ifdef WOLFSSL_SMALL_STACK
9825
    /* Deallocate order. */
9826
    XFREE(order, NULL, DYNAMIC_TYPE_TMP_BUFFER);
9827
#endif
9828
9829
    /* Convert error code to length of 0. */
9830
    if (ret < 0) {
9831
        ret = 0;
9832
    }
9833
9834
    return ret;
9835
}
9836
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9837
9838
#if defined(OPENSSL_EXTRA)
9839
/* Get the order of the group as a BN.
9840
 *
9841
 * Return code compliant with OpenSSL.
9842
 *
9843
 * @param [in]      group  EC group.
9844
 * @param [in, out] order  BN to hold order value.
9845
 * @param [in]      ctx    Context to use for BN operations. Unused.
9846
 * @return  1 on success.
9847
 * @return  0 on error.
9848
 */
9849
int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
9850
    WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx)
9851
{
9852
    int ret = 1;
9853
    mp_int* mp = NULL;
9854
9855
    /* No BN operations performed - done with mp_int in BN. */
9856
    (void)ctx;
9857
9858
    /* Validate parameters. */
9859
    if ((group == NULL) || (order == NULL) || (order->internal == NULL)) {
9860
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error");
9861
        ret = 0;
9862
    }
9863
9864
    if (ret == 1 &&
9865
            (group->curve_idx < 0 || !wc_ecc_is_valid_idx(group->curve_idx))) {
9866
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad group idx");
9867
        ret = 0;
9868
    }
9869
9870
    if (ret == 1) {
9871
        mp = (mp_int*)order->internal;
9872
    }
9873
    /* Initialize */
9874
    if ((ret == 1) && (mp_init(mp) != MP_OKAY)) {
9875
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure");
9876
        ret = 0;
9877
    }
9878
    /* Read hex string of order from wolfCrypt array of curves. */
9879
    if ((ret == 1) && (mp_read_radix(mp, ecc_sets[group->curve_idx].order,
9880
            MP_RADIX_HEX) != MP_OKAY)) {
9881
        WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure");
9882
        /* Zero out any partial value but don't free. */
9883
        mp_zero(mp);
9884
        ret = 0;
9885
    }
9886
9887
    return ret;
9888
}
9889
9890
#endif /* OPENSSL_EXTRA */
9891
9892
/* End EC_GROUP */
9893
9894
/* Start EC_POINT */
9895
9896
#if defined(OPENSSL_EXTRA)
9897
9898
/* Set data of EC point into internal, wolfCrypt EC point object.
9899
 *
9900
 * EC_POINT Openssl -> WolfSSL
9901
 *
9902
 * @param [in, out] p  EC point to update.
9903
 * @return  1 on success.
9904
 * @return  -1 on failure.
9905
 */
9906
static int ec_point_internal_set(WOLFSSL_EC_POINT *p)
9907
{
9908
    int ret = 1;
9909
9910
    WOLFSSL_ENTER("ec_point_internal_set");
9911
9912
    /* Validate parameter. */
9913
    if ((p == NULL) || (p->internal == NULL)) {
9914
        WOLFSSL_MSG("ECPoint NULL error");
9915
        ret = WOLFSSL_FATAL_ERROR;
9916
    }
9917
    else {
9918
        /* Get internal point as a wolfCrypt EC point. */
9919
        ecc_point* point = (ecc_point*)p->internal;
9920
9921
        /* Set X ordinate if available. */
9922
        if ((p->X != NULL) && (wolfssl_bn_get_value(p->X, point->x) != 1)) {
9923
            WOLFSSL_MSG("ecc point X error");
9924
            ret = WOLFSSL_FATAL_ERROR;
9925
        }
9926
        /* Set Y ordinate if available. */
9927
        if ((ret == 1) && (p->Y != NULL) && (wolfssl_bn_get_value(p->Y,
9928
                point->y) != 1)) {
9929
            WOLFSSL_MSG("ecc point Y error");
9930
            ret = WOLFSSL_FATAL_ERROR;
9931
        }
9932
        /* Set Z ordinate if available. */
9933
        if ((ret == 1) && (p->Z != NULL) && (wolfssl_bn_get_value(p->Z,
9934
                point->z) != 1)) {
9935
            WOLFSSL_MSG("ecc point Z error");
9936
            ret = WOLFSSL_FATAL_ERROR;
9937
        }
9938
        /* Internal values set when operations succeeded. */
9939
        p->inSet = (ret == 1);
9940
    }
9941
9942
    return ret;
9943
}
9944
9945
/* Set data of internal, wolfCrypt EC point object into EC point.
9946
 *
9947
 * EC_POINT WolfSSL -> OpenSSL
9948
 *
9949
 * @param [in, out] p  EC point to update.
9950
 * @return  1 on success.
9951
 * @return  -1 on failure.
9952
 */
9953
static int ec_point_external_set(WOLFSSL_EC_POINT *p)
9954
{
9955
    int ret = 1;
9956
9957
    WOLFSSL_ENTER("ec_point_external_set");
9958
9959
    /* Validate parameter. */
9960
    if ((p == NULL) || (p->internal == NULL)) {
9961
        WOLFSSL_MSG("ECPoint NULL error");
9962
        ret = WOLFSSL_FATAL_ERROR;
9963
    }
9964
    else {
9965
        /* Get internal point as a wolfCrypt EC point. */
9966
        ecc_point* point = (ecc_point*)p->internal;
9967
9968
        /* Set X ordinate. */
9969
        if (wolfssl_bn_set_value(&p->X, point->x) != 1) {
9970
            WOLFSSL_MSG("ecc point X error");
9971
            ret = WOLFSSL_FATAL_ERROR;
9972
        }
9973
        /* Set Y ordinate. */
9974
        if ((ret == 1) && (wolfssl_bn_set_value(&p->Y, point->y) != 1)) {
9975
            WOLFSSL_MSG("ecc point Y error");
9976
            ret = WOLFSSL_FATAL_ERROR;
9977
        }
9978
        /* Set Z ordinate. */
9979
        if ((ret == 1) && (wolfssl_bn_set_value(&p->Z, point->z) != 1)) {
9980
            WOLFSSL_MSG("ecc point Z error");
9981
            ret = WOLFSSL_FATAL_ERROR;
9982
        }
9983
        /* External values set when operations succeeded. */
9984
        p->exSet = (ret == 1);
9985
    }
9986
9987
    return ret;
9988
}
9989
9990
/* Setup internals of EC point.
9991
 *
9992
 * Assumes point is not NULL.
9993
 *
9994
 * @param [in, out] point  EC point to update.
9995
 * @return  1 on success.
9996
 * @return  0 on failure.
9997
 */
9998
static int ec_point_setup(const WOLFSSL_EC_POINT *point) {
9999
    int ret = 1;
10000
10001
    /* Check if internal values need setting. */
10002
    if (!point->inSet) {
10003
        WOLFSSL_MSG("No ECPoint internal set, do it");
10004
10005
        /* Forcing to non-constant type to update internals. */
10006
        if (ec_point_internal_set((WOLFSSL_EC_POINT *)point) != 1) {
10007
            WOLFSSL_MSG("ec_point_internal_set failed");
10008
            ret = 0;
10009
        }
10010
    }
10011
10012
    return ret;
10013
}
10014
10015
/* Create a new EC point from the group.
10016
 *
10017
 * @param [in] group  EC group.
10018
 * @return  EC point on success.
10019
 * @return  NULL on error.
10020
 */
10021
WOLFSSL_EC_POINT* wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP* group)
10022
{
10023
    int err = 0;
10024
    WOLFSSL_EC_POINT* point = NULL;
10025
10026
    WOLFSSL_ENTER("wolfSSL_EC_POINT_new");
10027
10028
    /* Validate parameter. */
10029
    if (group == NULL) {
10030
        WOLFSSL_MSG("wolfSSL_EC_POINT_new NULL error");
10031
        err = 1;
10032
    }
10033
10034
    if (!err) {
10035
        /* Allocate memory for new EC point. */
10036
        point = (WOLFSSL_EC_POINT*)XMALLOC(sizeof(WOLFSSL_EC_POINT), NULL,
10037
            DYNAMIC_TYPE_ECC);
10038
        if (point == NULL) {
10039
            WOLFSSL_MSG("wolfSSL_EC_POINT_new malloc ecc point failure");
10040
            err = 1;
10041
        }
10042
    }
10043
    if (!err) {
10044
        /* Clear fields of EC point. */
10045
        XMEMSET(point, 0, sizeof(WOLFSSL_EC_POINT));
10046
10047
        /* Allocate internal EC point. */
10048
        point->internal = wc_ecc_new_point();
10049
        if (point->internal == NULL) {
10050
            WOLFSSL_MSG("ecc_new_point failure");
10051
            err = 1;
10052
        }
10053
    }
10054
10055
    if (err) {
10056
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
10057
        point = NULL;
10058
    }
10059
    return point;
10060
}
10061
10062
#endif /* OPENSSL_EXTRA */
10063
10064
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
10065
/* Dispose of the EC point.
10066
 *
10067
 * Cannot use point after this call.
10068
 *
10069
 * @param [in, out] point  EC point to free.
10070
 */
10071
void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *point)
10072
{
10073
    WOLFSSL_ENTER("wolfSSL_EC_POINT_free");
10074
10075
    if (point != NULL) {
10076
        if (point->internal != NULL) {
10077
            wc_ecc_del_point((ecc_point*)point->internal);
10078
            point->internal = NULL;
10079
        }
10080
10081
        /* Free ordinates. */
10082
        wolfSSL_BN_free(point->X);
10083
        wolfSSL_BN_free(point->Y);
10084
        wolfSSL_BN_free(point->Z);
10085
        /* Clear fields. */
10086
        point->X = NULL;
10087
        point->Y = NULL;
10088
        point->Z = NULL;
10089
        point->inSet = 0;
10090
        point->exSet = 0;
10091
10092
        /* Dispose of EC point. */
10093
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
10094
    }
10095
}
10096
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
10097
10098
#ifdef OPENSSL_EXTRA
10099
10100
/* Clear and dispose of the EC point.
10101
 *
10102
 * Cannot use point after this call.
10103
 *
10104
 * @param [in, out] point  EC point to free.
10105
 */
10106
void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point)
10107
{
10108
    WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free");
10109
10110
    if (point != NULL) {
10111
        if (point->internal != NULL) {
10112
            /* Force internal point to be zeros. */
10113
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10114
            wc_ecc_forcezero_point((ecc_point*)point->internal);
10115
    #else
10116
            ecc_point* p = (ecc_point*)point->internal;
10117
            mp_forcezero(p->x);
10118
            mp_forcezero(p->y);
10119
            mp_forcezero(p->z);
10120
    #endif
10121
            wc_ecc_del_point((ecc_point*)point->internal);
10122
            point->internal = NULL;
10123
        }
10124
10125
        /* Clear the ordinates before freeing. */
10126
        wolfSSL_BN_clear_free(point->X);
10127
        wolfSSL_BN_clear_free(point->Y);
10128
        wolfSSL_BN_clear_free(point->Z);
10129
        /* Clear fields. */
10130
        point->X = NULL;
10131
        point->Y = NULL;
10132
        point->Z = NULL;
10133
        point->inSet = 0;
10134
        point->exSet = 0;
10135
10136
        /* Dispose of EC point. */
10137
        XFREE(point, NULL, DYNAMIC_TYPE_ECC);
10138
    }
10139
}
10140
10141
/* Print out the internals of EC point in debug and when logging callback set.
10142
 *
10143
 * Not an OpenSSL API.
10144
 *
10145
 * TODO: Use WOLFSSL_MSG_EX()?
10146
 *
10147
 * @param [in] msg    Message to prepend.
10148
 * @param [in] point  EC point to print.
10149
 */
10150
void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *point)
10151
{
10152
#if defined(DEBUG_WOLFSSL)
10153
    char *num;
10154
10155
    WOLFSSL_ENTER("wolfSSL_EC_POINT_dump");
10156
10157
    /* Only print when debugging on. */
10158
    if (WOLFSSL_IS_DEBUG_ON()) {
10159
        if (point == NULL) {
10160
            /* No point passed in so just put out "NULL". */
10161
            WOLFSSL_MSG_EX("%s = NULL\n", msg);
10162
        }
10163
        else {
10164
            /* Put out message and status of internal/external data set. */
10165
            WOLFSSL_MSG_EX("%s:\n\tinSet=%d, exSet=%d\n", msg, point->inSet,
10166
                point->exSet);
10167
            /* Get x-ordinate as a hex string and print. */
10168
            num = wolfSSL_BN_bn2hex(point->X);
10169
            WOLFSSL_MSG_EX("\tX = %s\n", num);
10170
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
10171
            /* Get x-ordinate as a hex string and print. */
10172
            num = wolfSSL_BN_bn2hex(point->Y);
10173
            WOLFSSL_MSG_EX("\tY = %s\n", num);
10174
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
10175
            /* Get z-ordinate as a hex string and print. */
10176
            num = wolfSSL_BN_bn2hex(point->Z);
10177
            WOLFSSL_MSG_EX("\tZ = %s\n", num);
10178
            XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
10179
        }
10180
    }
10181
#else
10182
    (void)msg;
10183
    (void)point;
10184
#endif
10185
}
10186
10187
/* Convert EC point to hex string that as either uncompressed or compressed.
10188
 *
10189
 * ECC point compression types were not included in selftest ecc.h
10190
 *
10191
 * @param [in] group  EC group for point.
10192
 * @param [in] point  EC point to encode.
10193
 * @param [in] form   Format of encoding. Valid values:
10194
 *                    POINT_CONVERSION_UNCOMPRESSED, POINT_CONVERSION_COMPRESSED
10195
 * @param [in] ctx    Context to use for BN operations. Unused.
10196
 * @return  Allocated hex string on success.
10197
 * @return  NULL on error.
10198
 */
10199
char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
10200
    const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BN_CTX* ctx)
10201
{
10202
    static const char* hexDigit = "0123456789ABCDEF";
10203
    char* hex = NULL;
10204
    int i;
10205
    int sz = 0;
10206
    int len = 0;
10207
    int err = 0;
10208
10209
    /* No BN operations performed. */
10210
    (void)ctx;
10211
10212
    /* Validate parameters. */
10213
    if ((group == NULL) || (point == NULL)) {
10214
        err = 1;
10215
    }
10216
    /* Get curve id expects a positive index. */
10217
    if ((!err) && (group->curve_idx < 0)) {
10218
        err = 1;
10219
    }
10220
10221
    if (!err) {
10222
        /* Get curve id to look up ordinate size. */
10223
        int id = wc_ecc_get_curve_id(group->curve_idx);
10224
        /* Get size of ordinate. */
10225
        if ((sz = wc_ecc_get_curve_size_from_id(id)) < 0) {
10226
            err = 1;
10227
        }
10228
    }
10229
    if (!err) {
10230
        /* <format byte> <x-ordinate> [<y-ordinate>] */
10231
        len = sz + 1;
10232
        if (form == WC_POINT_CONVERSION_UNCOMPRESSED) {
10233
            /* Include y ordinate when uncompressed. */
10234
            len += sz;
10235
        }
10236
10237
        /* Hex string: allocate 2 bytes to represent each byte plus 1 for '\0'.
10238
         */
10239
        hex = (char*)XMALLOC((size_t)(2 * len + 1), NULL, DYNAMIC_TYPE_ECC);
10240
        if (hex == NULL) {
10241
            err = 1;
10242
        }
10243
    }
10244
    if (!err) {
10245
        /* Make bytes all zeros to allow for ordinate values less than max size.
10246
         */
10247
        XMEMSET(hex, 0, (size_t)(2 * len + 1));
10248
10249
        /* Calculate offset as leading zeros not encoded. */
10250
        i = sz - mp_unsigned_bin_size((mp_int*)point->X->internal) + 1;
10251
        /* Put in x-ordinate after format byte. */
10252
        if (mp_to_unsigned_bin((mp_int*)point->X->internal, (byte*)(hex + i)) <
10253
                0) {
10254
            err = 1;
10255
        }
10256
    }
10257
    if (!err) {
10258
        if (form == WC_POINT_CONVERSION_COMPRESSED) {
10259
            /* Compressed format byte value dependent on whether y-ordinate is
10260
             * odd.
10261
             */
10262
            hex[0] = mp_isodd((mp_int*)point->Y->internal) ?
10263
                ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
10264
            /* No y-ordinate. */
10265
        }
10266
        else {
10267
            /* Put in uncompressed format byte. */
10268
            hex[0] = ECC_POINT_UNCOMP;
10269
            /* Calculate offset as leading zeros not encoded. */
10270
            i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal);
10271
            /* Put in y-ordinate after x-ordinate. */
10272
            if (mp_to_unsigned_bin((mp_int*)point->Y->internal,
10273
                    (byte*)(hex + i)) < 0) {
10274
                err = 1;
10275
            }
10276
        }
10277
    }
10278
    if (!err) {
10279
        /* Convert binary encoding to hex string. */
10280
        /* Start at end so as not to overwrite. */
10281
        for (i = len-1; i >= 0; i--) {
10282
            /* Get byte value and store has hex string. */
10283
            byte b = (byte)hex[i];
10284
            hex[i * 2 + 1] = hexDigit[b  & 0xf];
10285
            hex[i * 2    ] = hexDigit[b >>   4];
10286
        }
10287
        /* Memset put trailing zero or '\0' on end of string. */
10288
    }
10289
10290
    if (err && (hex != NULL)) {
10291
        /* Dispose of allocated data not being returned. */
10292
        XFREE(hex,  NULL, DYNAMIC_TYPE_ECC);
10293
        hex = NULL;
10294
    }
10295
    /* Return hex string encoding. */
10296
    return hex;
10297
}
10298
10299
static size_t hex_to_bytes(const char *hex, unsigned char *output, size_t sz)
10300
{
10301
    word32 i;
10302
    for (i = 0; i < sz; i++) {
10303
        signed char ch1, ch2;
10304
        ch1 = HexCharToByte(hex[i * 2]);
10305
        ch2 = HexCharToByte(hex[i * 2 + 1]);
10306
        if ((ch1 < 0) || (ch2 < 0)) {
10307
            WOLFSSL_MSG("hex_to_bytes: syntax error");
10308
            return 0;
10309
        }
10310
        output[i] = (unsigned char)((ch1 << 4) + ch2);
10311
    }
10312
    return sz;
10313
}
10314
10315
WOLFSSL_EC_POINT* wolfSSL_EC_POINT_hex2point(const WOLFSSL_EC_GROUP *group,
10316
            const char *hex, WOLFSSL_EC_POINT*p, WOLFSSL_BN_CTX *ctx)
10317
{
10318
    /* for uncompressed mode */
10319
    size_t str_sz;
10320
    WOLFSSL_BIGNUM *Gx  = NULL;
10321
    WOLFSSL_BIGNUM *Gy  = NULL;
10322
    char   strGx[MAX_ECC_BYTES * 2 + 1];
10323
10324
    /* for compressed mode */
10325
    int    key_sz;
10326
    byte   *octGx = (byte *)strGx; /* octGx[MAX_ECC_BYTES] */
10327
10328
    int p_alloc = 0;
10329
    int ret;
10330
10331
    WOLFSSL_ENTER("wolfSSL_EC_POINT_hex2point");
10332
10333
    if (group == NULL || hex == NULL || ctx == NULL)
10334
        return NULL;
10335
10336
    if (p == NULL) {
10337
        if ((p = wolfSSL_EC_POINT_new(group)) == NULL) {
10338
            WOLFSSL_MSG("wolfSSL_EC_POINT_new");
10339
            goto err;
10340
        }
10341
        p_alloc = 1;
10342
    }
10343
10344
    key_sz = (wolfSSL_EC_GROUP_get_degree(group) + 7) / 8;
10345
    if (hex[0] ==  '0' && hex[1] == '4') { /* uncompressed mode */
10346
        str_sz = (size_t)key_sz * 2;
10347
10348
        XMEMSET(strGx, 0x0, str_sz + 1);
10349
        XMEMCPY(strGx, hex + 2, str_sz);
10350
10351
        if (wolfSSL_BN_hex2bn(&Gx, strGx) == 0)
10352
            goto err;
10353
10354
        if (wolfSSL_BN_hex2bn(&Gy, hex + 2 + str_sz) == 0)
10355
            goto err;
10356
10357
        ret = wolfSSL_EC_POINT_set_affine_coordinates_GFp
10358
                                            (group, p, Gx, Gy, ctx);
10359
10360
        if (ret != WOLFSSL_SUCCESS) {
10361
            WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
10362
            goto err;
10363
        }
10364
    }
10365
    else if (hex[0] == '0' && (hex[1] == '2' || hex[1] == '3')) {
10366
        size_t sz = XSTRLEN(hex + 2) / 2;
10367
        /* compressed mode */
10368
        octGx[0] = ECC_POINT_COMP_ODD;
10369
        if (hex_to_bytes(hex + 2, octGx + 1, sz) != sz) {
10370
            goto err;
10371
        }
10372
        if (wolfSSL_ECPoint_d2i(octGx, (word32)key_sz + 1, group, p)
10373
                                            != WOLFSSL_SUCCESS) {
10374
            goto err;
10375
        }
10376
    }
10377
    else
10378
        goto err;
10379
10380
    wolfSSL_BN_free(Gx);
10381
    wolfSSL_BN_free(Gy);
10382
    return p;
10383
10384
err:
10385
    wolfSSL_BN_free(Gx);
10386
    wolfSSL_BN_free(Gy);
10387
    if (p_alloc) {
10388
        wolfSSL_EC_POINT_free(p);
10389
    }
10390
    return NULL;
10391
10392
}
10393
10394
/* Encode the EC point as an uncompressed point in DER.
10395
 *
10396
 * Return code compliant with OpenSSL.
10397
 * Not OpenSSL API.
10398
 *
10399
 * @param [in]      group  EC group point belongs to.
10400
 * @param [in]      point  EC point to encode.
10401
 * @param [out]     out    Buffer to encode into. May be NULL.
10402
 * @param [in, out] len    On in, length of buffer in bytes.
10403
 *                         On out, length of encoding in bytes.
10404
 * @return  1 on success.
10405
 * @return  0 on error.
10406
 */
10407
int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group,
10408
    const WOLFSSL_EC_POINT *point, unsigned char *out, unsigned int *len)
10409
{
10410
    int res = 1;
10411
10412
    WOLFSSL_ENTER("wolfSSL_ECPoint_i2d");
10413
10414
    /* Validate parameters. */
10415
    if ((group == NULL) || (point == NULL) || (len == NULL)) {
10416
        WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error");
10417
        res = 0;
10418
    }
10419
10420
    /* Ensure points internals are set up. */
10421
    if ((res == 1) && (ec_point_setup(point) != 1)) {
10422
        res = 0;
10423
    }
10424
10425
    /* Dump the point if encoding. */
10426
    if ((res == 1) && (out != NULL)) {
10427
        wolfSSL_EC_POINT_dump("i2d p", point);
10428
    }
10429
10430
    if (res == 1) {
10431
        /* DER encode point in uncompressed format. */
10432
        int ret = wc_ecc_export_point_der(group->curve_idx,
10433
            (ecc_point*)point->internal, out, len);
10434
        /* Check return. When out is NULL, return will be length only error. */
10435
        if ((ret != MP_OKAY) && ((out != NULL) ||
10436
                                 (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)))) {
10437
            WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed");
10438
            res = 0;
10439
        }
10440
    }
10441
10442
    return res;
10443
}
10444
10445
/* Decode the uncompressed point in DER into EC point.
10446
 *
10447
 * Return code compliant with OpenSSL.
10448
 * Not OpenSSL API.
10449
 *
10450
 * @param [in]      in     Buffer containing DER encoded point.
10451
 * @param [in]      len    Length of data in bytes.
10452
 * @param [in]      group  EC group associated with point.
10453
 * @param [in, out] point  EC point to set data into.
10454
 * @return  1 on success.
10455
 * @return  0 on error.
10456
 */
10457
int wolfSSL_ECPoint_d2i(const unsigned char *in, unsigned int len,
10458
    const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *point)
10459
{
10460
    int ret = 1;
10461
    WOLFSSL_BIGNUM* x = NULL;
10462
    WOLFSSL_BIGNUM* y = NULL;
10463
10464
    WOLFSSL_ENTER("wolfSSL_ECPoint_d2i");
10465
10466
    /* Validate parameters. */
10467
    if ((in == NULL) || (group == NULL) || (point == NULL) ||
10468
            (point->internal == NULL)) {
10469
        WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error");
10470
        ret = 0;
10471
    }
10472
10473
    if (ret == 1) {
10474
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10475
        /* Import point into internal EC point. */
10476
        if (wc_ecc_import_point_der_ex(in, len, group->curve_idx,
10477
                (ecc_point*)point->internal, 0) != MP_OKAY) {
10478
            WOLFSSL_MSG("wc_ecc_import_point_der_ex failed");
10479
            ret = 0;
10480
        }
10481
    #else
10482
        /* ECC_POINT_UNCOMP is not defined CAVP self test so use magic number */
10483
        if (in[0] == 0x04) {
10484
            /* Import point into internal EC point. */
10485
            if (wc_ecc_import_point_der((unsigned char *)in, len,
10486
                    group->curve_idx, (ecc_point*)point->internal) != MP_OKAY) {
10487
                WOLFSSL_MSG("wc_ecc_import_point_der failed");
10488
                ret = 0;
10489
            }
10490
        }
10491
        else {
10492
            WOLFSSL_MSG("Only uncompressed points supported with "
10493
                        "HAVE_SELFTEST");
10494
            ret = 0;
10495
        }
10496
    #endif
10497
    }
10498
10499
    if (ret == 1)
10500
        point->inSet = 1;
10501
10502
    /* Set new external point. */
10503
    if (ret == 1 && ec_point_external_set(point) != 1) {
10504
        WOLFSSL_MSG("ec_point_external_set failed");
10505
        ret = 0;
10506
    }
10507
10508
    if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) {
10509
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
10510
        x = wolfSSL_BN_new();
10511
        y = wolfSSL_BN_new();
10512
        if (x == NULL || y == NULL)
10513
            ret = 0;
10514
10515
        if (ret == 1 && wolfSSL_EC_POINT_get_affine_coordinates_GFp(group,
10516
                point, x, y, NULL) != 1) {
10517
            WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp failed");
10518
            ret = 0;
10519
        }
10520
10521
        /* wolfSSL_EC_POINT_set_affine_coordinates_GFp check that the point is
10522
         * on the curve. */
10523
        if (ret == 1 && wolfSSL_EC_POINT_set_affine_coordinates_GFp(group,
10524
                point, x, y, NULL) != 1) {
10525
            WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp failed");
10526
            ret = 0;
10527
        }
10528
#else
10529
        WOLFSSL_MSG("Importing non-affine point. This may cause issues in math "
10530
                    "operations later on.");
10531
#endif
10532
    }
10533
10534
    if (ret == 1) {
10535
        /* Dump new point. */
10536
        wolfSSL_EC_POINT_dump("d2i p", point);
10537
    }
10538
10539
    wolfSSL_BN_free(x);
10540
    wolfSSL_BN_free(y);
10541
10542
    return ret;
10543
}
10544
10545
/* Encode point as octet string.
10546
 *
10547
 * HYBRID not supported.
10548
 *
10549
 * @param [in]  group  EC group that point belongs to.
10550
 * @param [in]  point  EC point to encode.
10551
 * @param [in]  form   Format of encoding. Valid values:
10552
 *                     POINT_CONVERSION_UNCOMPRESSED,POINT_CONVERSION_COMPRESSED
10553
 * @param [out] buf    Buffer to write encoding into.
10554
 * @param [in]  len    Length of buffer.
10555
 * @param [in]  ctx    Context to use for BN operations. Unused.
10556
 * @return  Length of encoded data on success.
10557
 * @return  0 on error.
10558
 */
10559
size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group,
10560
   const WOLFSSL_EC_POINT *point, int form, byte *buf, size_t len,
10561
   WOLFSSL_BN_CTX *ctx)
10562
{
10563
    int err = 0;
10564
    word32 enc_len = (word32)len;
10565
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10566
    int compressed = ((form == WC_POINT_CONVERSION_COMPRESSED) ? 1 : 0);
10567
#endif /* !HAVE_SELFTEST */
10568
10569
    WOLFSSL_ENTER("wolfSSL_EC_POINT_point2oct");
10570
10571
    /* No BN operations performed. */
10572
    (void)ctx;
10573
10574
    /* Validate parameters. */
10575
    if ((group == NULL) || (point == NULL)) {
10576
        err = 1;
10577
    }
10578
10579
    /* Ensure points internals are set up. */
10580
    if ((!err) && (ec_point_setup(point) != 1)) {
10581
        err = 1;
10582
    }
10583
10584
    /* Special case when point is infinity. */
10585
    if ((!err) && wolfSSL_EC_POINT_is_at_infinity(group, point)) {
10586
        /* Encoding is a single octet: 0x00. */
10587
        enc_len = 1;
10588
        if (buf != NULL) {
10589
            /* Check whether buffer has space. */
10590
            if (len < 1) {
10591
                wolfSSL_ECerr(WOLFSSL_EC_F_EC_GFP_SIMPLE_POINT2OCT, BUFFER_E);
10592
                err = 1;
10593
            }
10594
            else {
10595
                /* Put in encoding of infinity. */
10596
                buf[0] = 0x00;
10597
            }
10598
        }
10599
    }
10600
    /* Not infinity. */
10601
    else if (!err) {
10602
        /* Validate format. */
10603
        if (form != WC_POINT_CONVERSION_UNCOMPRESSED
10604
        #ifndef HAVE_SELFTEST
10605
                && form != WC_POINT_CONVERSION_COMPRESSED
10606
        #endif /* !HAVE_SELFTEST */
10607
            ) {
10608
            WOLFSSL_MSG("Unsupported point form");
10609
            err = 1;
10610
        }
10611
10612
        if (!err) {
10613
            int ret;
10614
10615
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10616
            /* Encode as compressed or uncompressed. */
10617
            ret = wc_ecc_export_point_der_ex(group->curve_idx,
10618
                (ecc_point*)point->internal, buf, &enc_len, compressed);
10619
    #else
10620
            /* Encode uncompressed point in DER format. */
10621
            ret = wc_ecc_export_point_der(group->curve_idx,
10622
                (ecc_point*)point->internal, buf, &enc_len);
10623
    #endif /* !HAVE_SELFTEST */
10624
            /* Check return. When buf is NULL, return will be length only
10625
             * error.
10626
             */
10627
            if (ret != ((buf != NULL) ? MP_OKAY : WC_NO_ERR_TRACE(LENGTH_ONLY_E))) {
10628
                err = 1;
10629
            }
10630
        }
10631
    }
10632
10633
#if defined(DEBUG_WOLFSSL)
10634
    if (!err) {
10635
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_point2oct point", point);
10636
        WOLFSSL_MSG("\twolfSSL_EC_POINT_point2oct output:");
10637
        WOLFSSL_BUFFER(buf, enc_len);
10638
    }
10639
#endif
10640
10641
    /* On error, return encoding length of 0. */
10642
    if (err) {
10643
        enc_len = 0;
10644
    }
10645
    return (size_t)enc_len;
10646
}
10647
10648
10649
/* Convert octet string to EC point.
10650
 *
10651
 * @param [in]      group  EC group.
10652
 * @param [in, out] point  EC point to set data into.
10653
 * @param [in]      buf    Buffer holding octet string.
10654
 * @param [in]      len    Length of data in buffer in bytes.
10655
 * @param [in]      ctx    Context to use for BN operations. Unused.
10656
 */
10657
int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group,
10658
    WOLFSSL_EC_POINT *point, const unsigned char *buf, size_t len,
10659
    WOLFSSL_BN_CTX *ctx)
10660
{
10661
    int ret;
10662
10663
    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
10664
10665
    /* No BN operations performed. */
10666
    (void)ctx;
10667
10668
    /* Validate parameters. */
10669
    if ((group == NULL) || (point == NULL)) {
10670
        ret = 0;
10671
    }
10672
    else {
10673
        /* Decode DER encoding into EC point. */
10674
        ret = wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group,
10675
            point);
10676
    }
10677
10678
    return ret;
10679
}
10680
10681
/* Convert an EC point to a single BN.
10682
 *
10683
 * @param [in]      group  EC group.
10684
 * @param [in]      point  EC point.
10685
 * @param [in]      form   Format of encoding. Valid values:
10686
 *                         WC_POINT_CONVERSION_UNCOMPRESSED,
10687
 *                         WC_POINT_CONVERSION_COMPRESSED.
10688
 * @param [in, out] bn     BN to hold point value.
10689
 *                         When NULL a new BN is allocated otherwise this is
10690
 *                         returned on success.
10691
 * @param [in]      ctx    Context to use for BN operations. Unused.
10692
 * @return  BN object with point as a value on success.
10693
 * @return  NULL on error.
10694
 */
10695
WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP* group,
10696
    const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BIGNUM* bn,
10697
    WOLFSSL_BN_CTX* ctx)
10698
{
10699
    int err = 0;
10700
    size_t len = 0;
10701
    byte *buf = NULL;
10702
    WOLFSSL_BIGNUM *ret = NULL;
10703
10704
    WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point");
10705
10706
    /* Validate parameters. */
10707
    if ((group == NULL) || (point == NULL)) {
10708
        err = 1;
10709
    }
10710
10711
    /* Calculate length of octet encoding. */
10712
    if ((!err) && ((len = wolfSSL_EC_POINT_point2oct(group, point, form, NULL,
10713
            0, ctx)) == 0)) {
10714
        err = 1;
10715
    }
10716
    /* Allocate buffer to hold octet encoding. */
10717
    if ((!err) && ((buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER)) ==
10718
            NULL)) {
10719
        WOLFSSL_MSG("malloc failed");
10720
        err = 1;
10721
    }
10722
    /* Encode EC point as an octet string. */
10723
    if ((!err) && (wolfSSL_EC_POINT_point2oct(group, point, form, buf, len,
10724
            ctx) != len)) {
10725
        err = 1;
10726
    }
10727
    /* Load BN with octet string data. */
10728
    if (!err) {
10729
        ret = wolfSSL_BN_bin2bn(buf, (int)len, bn);
10730
    }
10731
10732
    /* Dispose of any allocated data. */
10733
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
10734
10735
    return ret;
10736
}
10737
10738
#if defined(USE_ECC_B_PARAM) && !defined(HAVE_SELFTEST) && \
10739
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10740
/* Check if EC point is on the the curve defined by the EC group.
10741
 *
10742
 * @param [in] group  EC group defining curve.
10743
 * @param [in] point  EC point to check.
10744
 * @param [in] ctx    Context to use for BN operations. Unused.
10745
 * @return  1 when point is on curve.
10746
 * @return  0 when point is not on curve or error.
10747
 */
10748
int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group,
10749
    const WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx)
10750
{
10751
    int err = 0;
10752
10753
    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_on_curve");
10754
10755
    /* No BN operations performed. */
10756
    (void)ctx;
10757
10758
    /* Validate parameters. */
10759
    if ((group == NULL) || (point == NULL)) {
10760
        WOLFSSL_MSG("Invalid arguments");
10761
        err = 1;
10762
    }
10763
10764
    /* Ensure internal EC point set. */
10765
    if ((!err) && (!point->inSet) && ec_point_internal_set(
10766
            (WOLFSSL_EC_POINT*)point) != 1) {
10767
        WOLFSSL_MSG("ec_point_internal_set error");
10768
        err = 1;
10769
    }
10770
10771
    /* Check point is on curve from group. */
10772
    if ((!err) && (wc_ecc_point_is_on_curve((ecc_point*)point->internal,
10773
            group->curve_idx) != MP_OKAY)) {
10774
        err = 1;
10775
    }
10776
10777
    /* Return boolean of on curve. No error means on curve. */
10778
    return !err;
10779
}
10780
#endif /* USE_ECC_B_PARAM && !HAVE_SELFTEST && !(FIPS_VERSION <= 2) */
10781
10782
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
10783
/* Convert Jacobian ordinates to affine.
10784
 *
10785
 * @param [in]      group  EC group.
10786
 * @param [in]      point  EC point to get coordinates from.
10787
 * @return  1 on success.
10788
 * @return  0 on error.
10789
 */
10790
int ec_point_convert_to_affine(const WOLFSSL_EC_GROUP *group,
10791
    WOLFSSL_EC_POINT *point)
10792
{
10793
    int err = 0;
10794
    mp_digit mp = 0;
10795
#ifdef WOLFSSL_SMALL_STACK
10796
    mp_int* modulus;
10797
#else
10798
    mp_int modulus[1];
10799
#endif
10800
10801
#ifdef WOLFSSL_SMALL_STACK
10802
    /* Allocate memory for curve's prime modulus. */
10803
    modulus = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
10804
    if (modulus == NULL) {
10805
        err = 1;
10806
    }
10807
#endif
10808
    /* Initialize the MP integer. */
10809
    if ((!err) && (mp_init(modulus) != MP_OKAY)) {
10810
        WOLFSSL_MSG("mp_init failed");
10811
        err = 1;
10812
    }
10813
10814
    if (!err) {
10815
        /* Get the modulus from the hex string in the EC curve set. */
10816
        if (mp_read_radix(modulus, ecc_sets[group->curve_idx].prime,
10817
                MP_RADIX_HEX) != MP_OKAY) {
10818
            WOLFSSL_MSG("mp_read_radix failed");
10819
            err = 1;
10820
        }
10821
        /* Get Montgomery multiplier for the modulus as ordinates in
10822
         * Montgomery form.
10823
         */
10824
        if ((!err) && (mp_montgomery_setup(modulus, &mp) != MP_OKAY)) {
10825
            WOLFSSL_MSG("mp_montgomery_setup failed");
10826
            err = 1;
10827
        }
10828
        /* Map internal EC point from Jacobian to affine. */
10829
        if ((!err) && (ecc_map((ecc_point*)point->internal, modulus, mp) !=
10830
                MP_OKAY)) {
10831
            WOLFSSL_MSG("ecc_map failed");
10832
            err = 1;
10833
        }
10834
        /* Set new ordinates into external EC point. */
10835
        if ((!err) && (ec_point_external_set((WOLFSSL_EC_POINT *)point) != 1)) {
10836
            WOLFSSL_MSG("ec_point_external_set failed");
10837
            err = 1;
10838
        }
10839
10840
        point->exSet = !err;
10841
        mp_clear(modulus);
10842
    }
10843
10844
#ifdef WOLFSSL_SMALL_STACK
10845
    XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT);
10846
#endif
10847
10848
    return err;
10849
}
10850
10851
/* Get the affine coordinates of the EC point on a Prime curve.
10852
 *
10853
 * When z-ordinate is not one then coordinates are Jacobian and need to be
10854
 * converted to affine before storing in BNs.
10855
 *
10856
 * Return code compliant with OpenSSL.
10857
 *
10858
 * TODO: OpenSSL doesn't change point when Jacobian. Do the same?
10859
 *
10860
 * @param [in]      group  EC group.
10861
 * @param [in]      point  EC point to get coordinates from.
10862
 * @param [in, out] x      BN to hold x-ordinate.
10863
 * @param [in, out] y      BN to hold y-ordinate.
10864
 * @param [in]      ctx    Context to use for BN operations. Unused.
10865
 * @return  1 on success.
10866
 * @return  0 on error.
10867
 */
10868
int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
10869
    const WOLFSSL_EC_POINT* point, WOLFSSL_BIGNUM* x, WOLFSSL_BIGNUM* y,
10870
    WOLFSSL_BN_CTX* ctx)
10871
{
10872
    int ret = 1;
10873
10874
    /* BN operations don't need context. */
10875
    (void)ctx;
10876
10877
    WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp");
10878
10879
    /* Validate parameters. */
10880
    if ((group == NULL) || (point == NULL) || (point->internal == NULL) ||
10881
            (x == NULL) || (y == NULL)) {
10882
        WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error");
10883
        ret = 0;
10884
    }
10885
    /* Don't return point at infinity. */
10886
    if ((ret == 1) && wolfSSL_EC_POINT_is_at_infinity(group, point)) {
10887
        ret = 0;
10888
    }
10889
10890
    /* Ensure internal EC point has values of external EC point. */
10891
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
10892
        ret = 0;
10893
    }
10894
10895
    /* Check whether ordinates are in Jacobian form. */
10896
    if ((ret == 1) && (!wolfSSL_BN_is_one(point->Z))) {
10897
        /* Convert from Jacobian to affine. */
10898
        if (ec_point_convert_to_affine(group, (WOLFSSL_EC_POINT*)point) == 1) {
10899
            ret = 0;
10900
        }
10901
    }
10902
10903
    /* Copy the externally set x and y ordinates. */
10904
    if ((ret == 1) && (wolfSSL_BN_copy(x, point->X) == NULL)) {
10905
        ret = 0;
10906
    }
10907
    if ((ret == 1) && (wolfSSL_BN_copy(y, point->Y) == NULL)) {
10908
        ret = 0;
10909
    }
10910
10911
    return ret;
10912
}
10913
#endif /* !WOLFSSL_SP_MATH && !WOLF_CRYPTO_CB_ONLY_ECC */
10914
10915
/* Sets the affine coordinates that belong on a prime curve.
10916
 *
10917
 * @param [in]      group  EC group.
10918
 * @param [in, out] point  EC point to set coordinates into.
10919
 * @param [in]      x      BN holding x-ordinate.
10920
 * @param [in]      y      BN holding y-ordinate.
10921
 * @param [in]      ctx    Context to use for BN operations. Unused.
10922
 * @return  1 on success.
10923
 * @return  0 on error.
10924
 */
10925
int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP* group,
10926
    WOLFSSL_EC_POINT* point, const WOLFSSL_BIGNUM* x, const WOLFSSL_BIGNUM* y,
10927
    WOLFSSL_BN_CTX* ctx)
10928
{
10929
    int ret = 1;
10930
10931
    /* BN operations don't need context. */
10932
    (void)ctx;
10933
10934
    WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp");
10935
10936
    /* Validate parameters. */
10937
    if ((group == NULL) || (point == NULL) || (point->internal == NULL) ||
10938
            (x == NULL) || (y == NULL)) {
10939
        WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error");
10940
        ret = 0;
10941
    }
10942
10943
    /* Ensure we have a object for x-ordinate. */
10944
    if ((ret == 1) && (point->X == NULL) &&
10945
            ((point->X = wolfSSL_BN_new()) == NULL)) {
10946
        WOLFSSL_MSG("wolfSSL_BN_new failed");
10947
        ret = 0;
10948
    }
10949
    /* Ensure we have a object for y-ordinate. */
10950
    if ((ret == 1) && (point->Y == NULL) &&
10951
            ((point->Y = wolfSSL_BN_new()) == NULL)) {
10952
        WOLFSSL_MSG("wolfSSL_BN_new failed");
10953
        ret = 0;
10954
    }
10955
    /* Ensure we have a object for z-ordinate. */
10956
    if ((ret == 1) && (point->Z == NULL) &&
10957
            ((point->Z = wolfSSL_BN_new()) == NULL)) {
10958
        WOLFSSL_MSG("wolfSSL_BN_new failed");
10959
        ret = 0;
10960
    }
10961
10962
    /* Copy the x-ordinate. */
10963
    if ((ret == 1) && ((wolfSSL_BN_copy(point->X, x)) == NULL)) {
10964
        WOLFSSL_MSG("wolfSSL_BN_copy failed");
10965
        ret = 0;
10966
    }
10967
    /* Copy the y-ordinate. */
10968
    if ((ret == 1) && ((wolfSSL_BN_copy(point->Y, y)) == NULL)) {
10969
        WOLFSSL_MSG("wolfSSL_BN_copy failed");
10970
        ret = 0;
10971
    }
10972
    /* z-ordinate is one for affine coordinates. */
10973
    if ((ret == 1) && ((wolfSSL_BN_one(point->Z)) == 0)) {
10974
        WOLFSSL_MSG("wolfSSL_BN_one failed");
10975
        ret = 0;
10976
    }
10977
10978
    /* Copy the new point data to internal object. */
10979
    if ((ret == 1) && (ec_point_internal_set((WOLFSSL_EC_POINT *)point) != 1)) {
10980
        WOLFSSL_MSG("ec_point_internal_set failed");
10981
        ret = 0;
10982
    }
10983
10984
#if defined(USE_ECC_B_PARAM) && !defined(HAVE_SELFTEST) && \
10985
    (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
10986
    /* Check that the point is valid. */
10987
    if ((ret == 1) && (wolfSSL_EC_POINT_is_on_curve(group,
10988
            (WOLFSSL_EC_POINT *)point, ctx) != 1)) {
10989
        WOLFSSL_MSG("EC_POINT_is_on_curve failed");
10990
        ret = 0;
10991
    }
10992
#endif
10993
10994
    return ret;
10995
}
10996
10997
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
10998
    !defined(HAVE_SELFTEST) && !defined(WOLFSSL_SP_MATH) && \
10999
    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
11000
/* Add two points on the same together.
11001
 *
11002
 * @param [in]  curveIdx  Index of curve in ecc_set.
11003
 * @param [out] r         Result point.
11004
 * @param [in]  p1        First point to add.
11005
 * @param [in]  p2        Second point to add.
11006
 * @return  1 on success.
11007
 * @return  0 on error.
11008
 */
11009
static int wolfssl_ec_point_add(int curveIdx, ecc_point* r, ecc_point* p1,
11010
    ecc_point* p2)
11011
{
11012
    int ret = 1;
11013
#ifdef WOLFSSL_SMALL_STACK
11014
    mp_int* a = NULL;
11015
    mp_int* prime = NULL;
11016
    mp_int* mu = NULL;
11017
#else
11018
    mp_int a[1];
11019
    mp_int prime[1];
11020
    mp_int mu[1];
11021
#endif
11022
    mp_digit mp = 0;
11023
    ecc_point* montP1 = NULL;
11024
    ecc_point* montP2 = NULL;
11025
11026
#ifdef WOLFSSL_SMALL_STACK
11027
    if (ret == 1) {
11028
        /* Allocate memory for curve parameter: a. */
11029
        a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11030
        if (a == NULL) {
11031
            WOLFSSL_MSG("Failed to allocate memory for mp_int a");
11032
            ret = 0;
11033
        }
11034
    }
11035
    if (ret == 1) {
11036
        /* Allocate memory for curve parameter: prime. */
11037
        prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11038
        if (prime == NULL) {
11039
            WOLFSSL_MSG("Failed to allocate memory for mp_int prime");
11040
            ret = 0;
11041
        }
11042
    }
11043
    if (ret == 1) {
11044
        /* Allocate memory for mu (Montgomery normalizer). */
11045
        mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11046
        if (mu == NULL) {
11047
            WOLFSSL_MSG("Failed to allocate memory for mp_int mu");
11048
            ret = 0;
11049
        }
11050
    }
11051
    if (ret == 1) {
11052
        /* Zero out all MP int data in case initialization fails. */
11053
        XMEMSET(a, 0, sizeof(mp_int));
11054
        XMEMSET(prime, 0, sizeof(mp_int));
11055
        XMEMSET(mu, 0, sizeof(mp_int));
11056
    }
11057
#endif
11058
11059
    /* Initialize the MP ints. */
11060
    if ((ret == 1) && (mp_init_multi(prime, a, mu, NULL, NULL, NULL) !=
11061
            MP_OKAY)) {
11062
        WOLFSSL_MSG("mp_init_multi error");
11063
        ret = 0;
11064
    }
11065
11066
    /* Read the curve parameter: a. */
11067
    if ((ret == 1) && (mp_read_radix(a, ecc_sets[curveIdx].Af, MP_RADIX_HEX) !=
11068
            MP_OKAY)) {
11069
        WOLFSSL_MSG("mp_read_radix a error");
11070
        ret = 0;
11071
    }
11072
11073
    /* Read the curve parameter: prime. */
11074
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
11075
            MP_RADIX_HEX) != MP_OKAY)) {
11076
        WOLFSSL_MSG("mp_read_radix prime error");
11077
        ret = 0;
11078
    }
11079
11080
    /* Calculate the Montgomery product. */
11081
    if ((ret == 1) && (mp_montgomery_setup(prime, &mp) != MP_OKAY)) {
11082
        WOLFSSL_MSG("mp_montgomery_setup nqm error");
11083
        ret = 0;
11084
    }
11085
11086
    /* TODO: use the heap filed of one of the points? */
11087
    /* Allocate new points to hold the Montgomery form values. */
11088
    if ((ret == 1) && (((montP1 = wc_ecc_new_point_h(NULL)) == NULL) ||
11089
            ((montP2 = wc_ecc_new_point_h(NULL)) == NULL))) {
11090
        WOLFSSL_MSG("wc_ecc_new_point_h nqm error");
11091
        ret = 0;
11092
    }
11093
11094
    /* Calculate the Montgomery normalizer. */
11095
    if ((ret == 1) && (mp_montgomery_calc_normalization(mu, prime) !=
11096
            MP_OKAY)) {
11097
        WOLFSSL_MSG("mp_montgomery_calc_normalization error");
11098
        ret = 0;
11099
    }
11100
11101
    /* Convert to Montgomery form. */
11102
    if ((ret == 1) && (mp_cmp_d(mu, 1) == MP_EQ)) {
11103
        /* Copy the points if the normalizer is 1.  */
11104
        if ((wc_ecc_copy_point(p1, montP1) != MP_OKAY) ||
11105
                (wc_ecc_copy_point(p2, montP2) != MP_OKAY)) {
11106
            WOLFSSL_MSG("wc_ecc_copy_point error");
11107
            ret = 0;
11108
        }
11109
    }
11110
    else if (ret == 1) {
11111
        /* Multiply each ordinate by the Montgomery normalizer.  */
11112
        if ((mp_mulmod(p1->x, mu, prime, montP1->x) != MP_OKAY) ||
11113
                (mp_mulmod(p1->y, mu, prime, montP1->y) != MP_OKAY) ||
11114
                (mp_mulmod(p1->z, mu, prime, montP1->z) != MP_OKAY)) {
11115
            WOLFSSL_MSG("mp_mulmod error");
11116
            ret = 0;
11117
        }
11118
        /* Multiply each ordinate by the Montgomery normalizer.  */
11119
        if ((mp_mulmod(p2->x, mu, prime, montP2->x) != MP_OKAY) ||
11120
                (mp_mulmod(p2->y, mu, prime, montP2->y) != MP_OKAY) ||
11121
                (mp_mulmod(p2->z, mu, prime, montP2->z) != MP_OKAY)) {
11122
            WOLFSSL_MSG("mp_mulmod error");
11123
            ret = 0;
11124
        }
11125
    }
11126
11127
    /* Perform point addition with internal EC point objects - Jacobian form
11128
     * result.
11129
     */
11130
    if ((ret == 1) && (ecc_projective_add_point(montP1, montP2, r, a, prime,
11131
            mp) != MP_OKAY)) {
11132
        WOLFSSL_MSG("ecc_projective_add_point error");
11133
        ret = 0;
11134
    }
11135
11136
    /* Map point back to affine coordinates. Converts from Montogomery form. */
11137
    if ((ret == 1) && (ecc_map(r, prime, mp) != MP_OKAY)) {
11138
        WOLFSSL_MSG("ecc_map error");
11139
        ret = 0;
11140
    }
11141
11142
    /* Dispose of allocated memory. */
11143
    mp_clear(a);
11144
    mp_clear(prime);
11145
    mp_clear(mu);
11146
    wc_ecc_del_point_h(montP1, NULL);
11147
    wc_ecc_del_point_h(montP2, NULL);
11148
#ifdef WOLFSSL_SMALL_STACK
11149
    XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
11150
    XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT);
11151
    XFREE(mu, NULL, DYNAMIC_TYPE_BIGINT);
11152
#endif
11153
    return ret;
11154
}
11155
11156
/* Add two points on the same curve together.
11157
 *
11158
 * @param [in]  group  EC group.
11159
 * @param [out] r      EC point that is result of point addition.
11160
 * @param [in]  p1     First EC point to add.
11161
 * @param [in]  p2     Second EC point to add.
11162
 * @param [in]  ctx    Context to use for BN operations. Unused.
11163
 * @return  1 on success.
11164
 * @return  0 on error.
11165
 */
11166
int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP* group, WOLFSSL_EC_POINT* r,
11167
    const WOLFSSL_EC_POINT* p1, const WOLFSSL_EC_POINT* p2, WOLFSSL_BN_CTX* ctx)
11168
{
11169
    int ret = 1;
11170
11171
    /* No BN operations performed. */
11172
    (void)ctx;
11173
11174
    /* Validate parameters. */
11175
    if ((group == NULL) || (r == NULL) || (p1 == NULL) || (p2 == NULL)) {
11176
        WOLFSSL_MSG("wolfSSL_EC_POINT_add error");
11177
        ret = 0;
11178
    }
11179
11180
    /* Ensure the internal objects of the EC points are setup. */
11181
    if ((ret == 1) && ((ec_point_setup(r) != 1) || (ec_point_setup(p1) != 1) ||
11182
            (ec_point_setup(p2) != 1))) {
11183
        WOLFSSL_MSG("ec_point_setup error");
11184
        ret = 0;
11185
    }
11186
11187
#ifdef DEBUG_WOLFSSL
11188
    if (ret == 1) {
11189
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
11190
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
11191
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
11192
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p1", p1);
11193
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add p2", p2);
11194
        if (curve != NULL)
11195
            WOLFSSL_MSG_EX("curve name: %s", curve);
11196
        if (nistName != NULL)
11197
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
11198
    }
11199
#endif
11200
11201
    if (ret == 1) {
11202
        /* Add points using wolfCrypt objects. */
11203
        ret = wolfssl_ec_point_add(group->curve_idx, (ecc_point*)r->internal,
11204
            (ecc_point*)p1->internal, (ecc_point*)p2->internal);
11205
    }
11206
11207
    /* Copy internal EC point values out to external EC point. */
11208
    if ((ret == 1) && (ec_point_external_set(r) != 1)) {
11209
        WOLFSSL_MSG("ec_point_external_set error");
11210
        ret = 0;
11211
    }
11212
11213
#ifdef DEBUG_WOLFSSL
11214
    if (ret == 1) {
11215
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_add result", r);
11216
    }
11217
#endif
11218
11219
    return ret;
11220
}
11221
11222
/* Sum the scalar multiplications of the base point and n, and q and m.
11223
 *
11224
 * r = base point * n + q * m
11225
 *
11226
 * @param [out] r      EC point that is result of operation.
11227
 * @param [in]  b      Base point of curve.
11228
 * @param [in]  n      Scalar to multiply by base point.
11229
 * @param [in]  q      EC point to be scalar multiplied.
11230
 * @param [in]  m      Scalar to multiply q by.
11231
 * @param [in]  a      Parameter A of curve.
11232
 * @param [in]  prime  Prime (modulus) of curve.
11233
 * @return  1 on success.
11234
 * @return  0 on error.
11235
 */
11236
static int ec_mul2add(ecc_point* r, ecc_point* b, mp_int* n, ecc_point* q,
11237
    mp_int* m, mp_int* a, mp_int* prime)
11238
{
11239
    int ret = 1;
11240
#if defined(ECC_SHAMIR) && !defined(WOLFSSL_KCAPI_ECC)
11241
    if (ecc_mul2add(b, n, q, m, r, a, prime, NULL) != MP_OKAY) {
11242
        WOLFSSL_MSG("ecc_mul2add error");
11243
        ret = 0;
11244
    }
11245
#else
11246
    ecc_point* tmp = NULL;
11247
    mp_digit mp = 0;
11248
11249
    /* Calculate Montgomery product. */
11250
    if (mp_montgomery_setup(prime, &mp) != MP_OKAY) {
11251
        WOLFSSL_MSG("mp_montgomery_setup nqm error");
11252
        ret = 0;
11253
    }
11254
    /* Create temporary point to hold: q * m */
11255
    if ((ret == 1) && ((tmp = wc_ecc_new_point()) == NULL)) {
11256
        WOLFSSL_MSG("wolfSSL_EC_POINT_new nqm error");
11257
        ret = 0;
11258
    }
11259
    /* r = base point * n */
11260
    if ((ret == 1) && (wc_ecc_mulmod(n, b, r, a, prime, 0) !=
11261
            MP_OKAY)) {
11262
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
11263
        ret = 0;
11264
    }
11265
    /* tmp = q * m */
11266
    if ((ret == 1) && (wc_ecc_mulmod(m, q, tmp, a, prime, 0) != MP_OKAY)) {
11267
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
11268
        ret = 0;
11269
    }
11270
    /* r = r + tmp */
11271
    if ((ret == 1) && (ecc_projective_add_point(tmp, r, r, a, prime, mp) !=
11272
            MP_OKAY)) {
11273
        WOLFSSL_MSG("wc_ecc_mulmod nqm error");
11274
        ret = 0;
11275
    }
11276
    /* Map point back to affine coordinates. Converts from Montogomery
11277
     * form. */
11278
    if ((ret == 1) && (ecc_map(r, prime, mp) != MP_OKAY)) {
11279
        WOLFSSL_MSG("ecc_map nqm error");
11280
        ret = 0;
11281
    }
11282
11283
    /* Dispose of allocated temporary point. */
11284
    wc_ecc_del_point(tmp);
11285
#endif
11286
11287
    return ret;
11288
}
11289
11290
/* Sum the scalar multiplications of the base point and n, and q and m.
11291
 *
11292
 * r = base point * n + q * m
11293
 *
11294
 * @param [in]  curveIdx  Index of curve in ecc_set.
11295
 * @param [out] r         EC point that is result of operation.
11296
 * @param [in]  n         Scalar to multiply by base point. May be NULL.
11297
 * @param [in]  q         EC point to be scalar multiplied. May be NULL.
11298
 * @param [in]  m         Scalar to multiply q by. May be NULL.
11299
 * @return  1 on success.
11300
 * @return  0 on error.
11301
 */
11302
static int wolfssl_ec_point_mul(int curveIdx, ecc_point* r, mp_int* n,
11303
    ecc_point* q, mp_int* m)
11304
{
11305
    int ret = 1;
11306
#ifdef WOLFSSL_SMALL_STACK
11307
    mp_int* a = NULL;
11308
    mp_int* prime = NULL;
11309
#else
11310
    mp_int a[1], prime[1];
11311
#endif
11312
11313
#ifdef WOLFSSL_SMALL_STACK
11314
    /* Allocate MP integer for curve parameter: a. */
11315
    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11316
    if (a == NULL) {
11317
        ret = 0;
11318
    }
11319
    if (ret == 1) {
11320
        /* Allocate MP integer for curve parameter: prime. */
11321
        prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11322
        if (prime == NULL)  {
11323
            ret = 0;
11324
        }
11325
    }
11326
#endif
11327
11328
    /* Initialize the MP ints. */
11329
    if ((ret == 1) && (mp_init_multi(prime, a, NULL, NULL, NULL, NULL) !=
11330
             MP_OKAY)) {
11331
        WOLFSSL_MSG("mp_init_multi error");
11332
        ret = 0;
11333
    }
11334
11335
    /* Read the curve parameter: prime. */
11336
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
11337
            MP_RADIX_HEX) != MP_OKAY)) {
11338
        WOLFSSL_MSG("mp_read_radix prime error");
11339
        ret = 0;
11340
    }
11341
11342
    /* Read the curve parameter: a. */
11343
    if ((ret == 1) && (mp_read_radix(a, ecc_sets[curveIdx].Af,
11344
            MP_RADIX_HEX) != MP_OKAY)) {
11345
        WOLFSSL_MSG("mp_read_radix a error");
11346
        ret = 0;
11347
    }
11348
11349
    if ((ret == 1) && (n != NULL)) {
11350
        /* Get generator - base point. */
11351
    #if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
11352
        if ((ret == 1) && (wc_ecc_get_generator(r, curveIdx) != MP_OKAY)) {
11353
            WOLFSSL_MSG("wc_ecc_get_generator error");
11354
            ret = 0;
11355
        }
11356
    #else
11357
        /* wc_ecc_get_generator is not defined in the FIPS v2 module. */
11358
        /* Read generator (base point) x-ordinate. */
11359
        if ((ret == 1) && (mp_read_radix(r->x, ecc_sets[curveIdx].Gx,
11360
                MP_RADIX_HEX) != MP_OKAY)) {
11361
            WOLFSSL_MSG("mp_read_radix Gx error");
11362
            ret = 0;
11363
        }
11364
        /* Read generator (base point) y-ordinate. */
11365
        if ((ret == 1) && (mp_read_radix(r->y, ecc_sets[curveIdx].Gy,
11366
                MP_RADIX_HEX) != MP_OKAY)) {
11367
            WOLFSSL_MSG("mp_read_radix Gy error");
11368
            ret = 0;
11369
        }
11370
        /* z-ordinate is one as point is affine. */
11371
        if ((ret == 1) && (mp_set(r->z, 1) != MP_OKAY)) {
11372
            WOLFSSL_MSG("mp_set Gz error");
11373
            ret = 0;
11374
        }
11375
    #endif /* NOPT_FIPS_VERSION == 2 */
11376
    }
11377
11378
    if ((ret == 1) && (n != NULL) && (q != NULL) && (m != NULL)) {
11379
        /* r = base point * n + q * m */
11380
        ret = ec_mul2add(r, r, n, q, m, a, prime);
11381
    }
11382
    /* Not all values present, see if we are only doing base point * n. */
11383
    else if ((ret == 1) && (n != NULL)) {
11384
        /* r = base point * n */
11385
        if (wc_ecc_mulmod(n, r, r, a, prime, 1) != MP_OKAY) {
11386
            WOLFSSL_MSG("wc_ecc_mulmod gn error");
11387
            ret = 0;
11388
        }
11389
    }
11390
    /* Not all values present, see if we are only doing q * m. */
11391
    else if ((ret == 1) && (q != NULL) && (m != NULL)) {
11392
        /* r = q * m */
11393
        if (wc_ecc_mulmod(m, q, r, a, prime, 1) != MP_OKAY) {
11394
            WOLFSSL_MSG("wc_ecc_mulmod qm error");
11395
            ret = 0;
11396
        }
11397
    }
11398
    /* No values to use. */
11399
    else if (ret == 1) {
11400
        /* Set result to infinity as no values passed in. */
11401
        mp_zero(r->x);
11402
        mp_zero(r->y);
11403
        mp_zero(r->z);
11404
    }
11405
11406
    mp_clear(a);
11407
    mp_clear(prime);
11408
#ifdef WOLFSSL_SMALL_STACK
11409
    XFREE(a, NULL, DYNAMIC_TYPE_BIGINT);
11410
    XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT);
11411
#endif
11412
    return ret;
11413
}
11414
11415
/* Sum the scalar multiplications of the base point and n, and q and m.
11416
 *
11417
 * r = base point * n + q * m
11418
 *
11419
 * Return code compliant with OpenSSL.
11420
 *
11421
 * @param [in]  group  EC group.
11422
 * @param [out] r      EC point that is result of operation.
11423
 * @param [in]  n      Scalar to multiply by base point. May be NULL.
11424
 * @param [in]  q      EC point to be scalar multiplied. May be NULL.
11425
 * @param [in]  m      Scalar to multiply q by. May be NULL.
11426
 * @param [in]  ctx    Context to use for BN operations. Unused.
11427
 * @return  1 on success.
11428
 * @return  0 on error.
11429
 */
11430
int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r,
11431
    const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m,
11432
    WOLFSSL_BN_CTX *ctx)
11433
{
11434
    int ret = 1;
11435
11436
    /* No BN operations performed. */
11437
    (void)ctx;
11438
11439
    WOLFSSL_ENTER("wolfSSL_EC_POINT_mul");
11440
11441
    /* Validate parameters. */
11442
    if ((group == NULL) || (r == NULL)) {
11443
        WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error");
11444
        ret = 0;
11445
    }
11446
11447
    /* Ensure the internal representation of the EC point q is setup. */
11448
    if ((ret == 1) && (q != NULL) && (ec_point_setup(q) != 1)) {
11449
        WOLFSSL_MSG("ec_point_setup error");
11450
        ret = 0;
11451
    }
11452
11453
#ifdef DEBUG_WOLFSSL
11454
    if (ret == 1) {
11455
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
11456
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
11457
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
11458
        char* num;
11459
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul input q", q);
11460
        num = wolfSSL_BN_bn2hex(n);
11461
        WOLFSSL_MSG_EX("\tn = %s", num);
11462
        XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
11463
        num = wolfSSL_BN_bn2hex(m);
11464
        WOLFSSL_MSG_EX("\tm = %s", num);
11465
        XFREE(num, NULL, DYNAMIC_TYPE_OPENSSL);
11466
        if (curve != NULL)
11467
            WOLFSSL_MSG_EX("curve name: %s", curve);
11468
        if (nistName != NULL)
11469
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
11470
    }
11471
#endif
11472
11473
    if (ret == 1) {
11474
        mp_int* ni = (n != NULL) ? (mp_int*)n->internal : NULL;
11475
        ecc_point* qi = (q != NULL) ? (ecc_point*)q->internal : NULL;
11476
        mp_int* mi = (m != NULL) ? (mp_int*)m->internal : NULL;
11477
11478
        /* Perform multiplication with wolfCrypt objects. */
11479
        ret = wolfssl_ec_point_mul(group->curve_idx, (ecc_point*)r->internal,
11480
            ni, qi, mi);
11481
    }
11482
11483
    /* Only on success is the internal point guaranteed to be set. */
11484
    if (r != NULL) {
11485
        r->inSet = (ret == 1);
11486
    }
11487
    /* Copy internal EC point values out to external EC point. */
11488
    if ((ret == 1) && (ec_point_external_set(r) != 1)) {
11489
        WOLFSSL_MSG("ec_point_external_set error");
11490
        ret = 0;
11491
    }
11492
11493
#ifdef DEBUG_WOLFSSL
11494
    if (ret == 1) {
11495
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_mul result", r);
11496
    }
11497
#endif
11498
11499
    return ret;
11500
}
11501
#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !HAVE_SELFTEST &&
11502
        * !WOLFSSL_SP_MATH */
11503
11504
/* Invert the point on the curve.
11505
 * (x, y) -> (x, -y) = (x, (prime - y) % prime)
11506
 *
11507
 * @param [in]      curveIdx  Index of curve in ecc_set.
11508
 * @param [in, out] point     EC point to invert.
11509
 * @return  1 on success.
11510
 * @return  0 on error.
11511
 */
11512
static int wolfssl_ec_point_invert(int curveIdx, ecc_point* point)
11513
{
11514
    int ret = 1;
11515
#ifdef WOLFSSL_SMALL_STACK
11516
    mp_int* prime = NULL;
11517
#else
11518
    mp_int prime[1];
11519
#endif
11520
11521
#ifdef WOLFSSL_SMALL_STACK
11522
    /* Allocate memory for an MP int to hold the prime of the curve. */
11523
    prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11524
    if (prime == NULL) {
11525
        ret = 0;
11526
    }
11527
#endif
11528
11529
    /* Initialize MP int. */
11530
    if ((ret == 1) && (mp_init(prime) != MP_OKAY)) {
11531
        WOLFSSL_MSG("mp_init_multi error");
11532
        ret = 0;
11533
    }
11534
11535
    /* Read the curve parameter: prime. */
11536
    if ((ret == 1) && (mp_read_radix(prime, ecc_sets[curveIdx].prime,
11537
            MP_RADIX_HEX) != MP_OKAY)) {
11538
        WOLFSSL_MSG("mp_read_radix prime error");
11539
        ret = 0;
11540
    }
11541
11542
    /* y = (prime - y) mod prime. */
11543
    if ((ret == 1) && (!mp_iszero(point->y)) && (mp_sub(prime, point->y,
11544
            point->y) != MP_OKAY)) {
11545
        WOLFSSL_MSG("mp_sub error");
11546
        ret = 0;
11547
    }
11548
11549
    /* Dispose of memory associated with MP. */
11550
    mp_free(prime);
11551
#ifdef WOLFSSL_SMALL_STACK
11552
    /* Dispose of dynamically allocated temporaries. */
11553
    XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT);
11554
#endif
11555
    return ret;
11556
}
11557
11558
/* Invert the point on the curve.
11559
 * (x, y) -> (x, -y) = (x, (prime - y) % prime)
11560
 *
11561
 * @param [in]      group  EC group.
11562
 * @param [in, out] point  EC point to invert.
11563
 * @param [in]      ctx    Context to use for BN operations. Unused.
11564
 * @return  1 on success.
11565
 * @return  0 on error.
11566
 */
11567
int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group,
11568
    WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx)
11569
{
11570
    int ret = 1;
11571
11572
    /* No BN operations performed. */
11573
    (void)ctx;
11574
11575
    WOLFSSL_ENTER("wolfSSL_EC_POINT_invert");
11576
11577
    /* Validate parameters. */
11578
    if ((group == NULL) || (point == NULL) || (point->internal == NULL)) {
11579
        ret = 0;
11580
    }
11581
11582
    /* Ensure internal representation of point is setup. */
11583
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
11584
        ret = 0;
11585
    }
11586
11587
#ifdef DEBUG_WOLFSSL
11588
    if (ret == 1) {
11589
        int nid = wolfSSL_EC_GROUP_get_curve_name(group);
11590
        const char* curve = wolfSSL_OBJ_nid2ln(nid);
11591
        const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
11592
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert input", point);
11593
        if (curve != NULL)
11594
            WOLFSSL_MSG_EX("curve name: %s", curve);
11595
        if (nistName != NULL)
11596
            WOLFSSL_MSG_EX("nist curve name: %s", nistName);
11597
11598
    }
11599
#endif
11600
11601
    if (ret == 1 && !wolfSSL_BN_is_one(point->Z)) {
11602
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
11603
        if (ec_point_convert_to_affine(group, point) != 0)
11604
            ret = 0;
11605
#else
11606
        WOLFSSL_MSG("wolfSSL_EC_POINT_invert called on non-affine point");
11607
        ret = 0;
11608
#endif
11609
    }
11610
11611
    if (ret == 1) {
11612
        /* Perform inversion using wolfCrypt objects. */
11613
        ret = wolfssl_ec_point_invert(group->curve_idx,
11614
            (ecc_point*)point->internal);
11615
    }
11616
11617
    /* Set the external EC point representation based on internal. */
11618
    if ((ret == 1) && (ec_point_external_set(point) != 1)) {
11619
        WOLFSSL_MSG("ec_point_external_set error");
11620
        ret = 0;
11621
    }
11622
11623
#ifdef DEBUG_WOLFSSL
11624
    if (ret == 1) {
11625
        wolfSSL_EC_POINT_dump("wolfSSL_EC_POINT_invert result", point);
11626
    }
11627
#endif
11628
11629
    return ret;
11630
}
11631
11632
#ifdef WOLFSSL_EC_POINT_CMP_JACOBIAN
11633
/* Compare two points on a the same curve.
11634
 *
11635
 * (Ax, Ay, Az) => (Ax / (Az ^ 2), Ay / (Az ^ 3))
11636
 * (Bx, By, Bz) => (Bx / (Bz ^ 2), By / (Bz ^ 3))
11637
 * When equal:
11638
 *      (Ax / (Az ^ 2), Ay / (Az ^ 3)) = (Bx / (Bz ^ 2), By / (Bz ^ 3))
11639
 *   => (Ax * (Bz ^ 2), Ay * (Bz ^ 3)) = (Bx * (Az ^ 2), By * (Az ^ 3))
11640
 *
11641
 * @param [in] group  EC group.
11642
 * @param [in] a      EC point to compare.
11643
 * @param [in] b      EC point to compare.
11644
 * @return  0 when equal.
11645
 * @return  1 when different.
11646
 * @return  -1 on error.
11647
 */
11648
static int ec_point_cmp_jacobian(const WOLFSSL_EC_GROUP* group,
11649
    const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, WOLFSSL_BN_CTX *ctx)
11650
{
11651
    int ret = 0;
11652
    BIGNUM* at = BN_new();
11653
    BIGNUM* bt = BN_new();
11654
    BIGNUM* az = BN_new();
11655
    BIGNUM* bz = BN_new();
11656
    BIGNUM* mod = BN_new();
11657
11658
    /* Check that the big numbers were allocated. */
11659
    if ((at == NULL) || (bt == NULL) || (az == NULL) || (bz == NULL) ||
11660
            (mod == NULL)) {
11661
        ret = WOLFSSL_FATAL_ERROR;
11662
    }
11663
    /* Get the modulus for the curve. */
11664
    if ((ret == 0) &&
11665
            (BN_hex2bn(&mod, ecc_sets[group->curve_idx].prime) != 1)) {
11666
        ret = WOLFSSL_FATAL_ERROR;
11667
    }
11668
    if (ret == 0) {
11669
        /* bt = Bx * (Az ^ 2). When Az is one then just copy. */
11670
        if (BN_is_one(a->Z)) {
11671
            if (BN_copy(bt, b->X) == NULL) {
11672
                ret = WOLFSSL_FATAL_ERROR;
11673
            }
11674
        }
11675
        /* az = Az ^ 2 */
11676
        else if ((BN_mod_mul(az, a->Z, a->Z, mod, ctx) != 1)) {
11677
            ret = WOLFSSL_FATAL_ERROR;
11678
        }
11679
        /* bt = Bx * az = Bx * (Az ^ 2) */
11680
        else if (BN_mod_mul(bt, b->X, az, mod, ctx) != 1) {
11681
            ret = WOLFSSL_FATAL_ERROR;
11682
        }
11683
    }
11684
    if (ret == 0) {
11685
        /* at = Ax * (Bz ^ 2). When Bz is one then just copy. */
11686
        if (BN_is_one(b->Z)) {
11687
            if (BN_copy(at, a->X) == NULL) {
11688
                ret = WOLFSSL_FATAL_ERROR;
11689
            }
11690
        }
11691
        /* bz = Bz ^ 2 */
11692
        else if (BN_mod_mul(bz, b->Z, b->Z, mod, ctx) != 1) {
11693
            ret = WOLFSSL_FATAL_ERROR;
11694
        }
11695
        /* at = Ax * bz = Ax * (Bz ^ 2) */
11696
        else if (BN_mod_mul(at, a->X, bz, mod, ctx) != 1) {
11697
            ret = WOLFSSL_FATAL_ERROR;
11698
        }
11699
    }
11700
    /* Compare x-ordinates. */
11701
    if ((ret == 0) && (BN_cmp(at, bt) != 0)) {
11702
        ret = 1;
11703
    }
11704
    if (ret == 0) {
11705
        /* bt = By * (Az ^ 3). When Az is one then just copy. */
11706
        if (BN_is_one(a->Z)) {
11707
            if (BN_copy(bt, b->Y) == NULL) {
11708
                ret = WOLFSSL_FATAL_ERROR;
11709
            }
11710
        }
11711
        /* az = az * Az = Az ^ 3 */
11712
        else if ((BN_mod_mul(az, az, a->Z, mod, ctx) != 1)) {
11713
            ret = WOLFSSL_FATAL_ERROR;
11714
        }
11715
        /* bt = By * az = By * (Az ^ 3) */
11716
        else if (BN_mod_mul(bt, b->Y, az, mod, ctx) != 1) {
11717
            ret = WOLFSSL_FATAL_ERROR;
11718
        }
11719
    }
11720
    if (ret == 0) {
11721
        /* at = Ay * (Bz ^ 3). When Bz is one then just copy. */
11722
        if (BN_is_one(b->Z)) {
11723
            if (BN_copy(at, a->Y) == NULL) {
11724
                ret = WOLFSSL_FATAL_ERROR;
11725
            }
11726
        }
11727
        /* bz = bz * Bz = Bz ^ 3 */
11728
        else if (BN_mod_mul(bz, bz, b->Z, mod, ctx) != 1) {
11729
            ret = WOLFSSL_FATAL_ERROR;
11730
        }
11731
        /* at = Ay * bz = Ay * (Bz ^ 3) */
11732
        else if (BN_mod_mul(at, a->Y, bz, mod, ctx) != 1) {
11733
            ret = WOLFSSL_FATAL_ERROR;
11734
        }
11735
    }
11736
    /* Compare y-ordinates. */
11737
    if ((ret == 0) && (BN_cmp(at, bt) != 0)) {
11738
        ret = 1;
11739
    }
11740
11741
    BN_free(mod);
11742
    BN_free(bz);
11743
    BN_free(az);
11744
    BN_free(bt);
11745
    BN_free(at);
11746
    return ret;
11747
}
11748
#endif
11749
11750
/* Compare two points on a the same curve.
11751
 *
11752
 * Return code compliant with OpenSSL.
11753
 *
11754
 * @param [in] group  EC group.
11755
 * @param [in] a      EC point to compare.
11756
 * @param [in] b      EC point to compare.
11757
 * @param [in] ctx    Context to use for BN operations. Unused.
11758
 * @return  0 when equal.
11759
 * @return  1 when different.
11760
 * @return  -1 on error.
11761
 */
11762
int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group,
11763
    const WOLFSSL_EC_POINT *a, const WOLFSSL_EC_POINT *b, WOLFSSL_BN_CTX *ctx)
11764
{
11765
    int ret = 0;
11766
11767
    WOLFSSL_ENTER("wolfSSL_EC_POINT_cmp");
11768
11769
    /* Validate parameters. */
11770
    if ((group == NULL) || (a == NULL) || (a->internal == NULL) ||
11771
            (b == NULL) || (b->internal == NULL)) {
11772
        WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments");
11773
        ret = WOLFSSL_FATAL_ERROR;
11774
    }
11775
    if (ret != -1) {
11776
    #ifdef WOLFSSL_EC_POINT_CMP_JACOBIAN
11777
        /* If same Z ordinate then no need to convert to affine. */
11778
        if (BN_cmp(a->Z, b->Z) == 0) {
11779
            /* Compare */
11780
            ret = ((BN_cmp(a->X, b->X) != 0) || (BN_cmp(a->Y, b->Y) != 0));
11781
        }
11782
        else {
11783
            ret = ec_point_cmp_jacobian(group, a, b, ctx);
11784
        }
11785
    #else
11786
        /* No BN operations performed. */
11787
        (void)ctx;
11788
11789
        ret = (wc_ecc_cmp_point((ecc_point*)a->internal,
11790
            (ecc_point*)b->internal) != MP_EQ);
11791
    #endif
11792
    }
11793
11794
    return ret;
11795
}
11796
11797
/* Copy EC point.
11798
 *
11799
 * @param [out] dest  EC point to copy into.
11800
 * @param [in]  src   EC point to copy.
11801
 * @return  1 on success.
11802
 * @return  0 on error.
11803
 */
11804
int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src)
11805
{
11806
    int ret = 1;
11807
11808
    WOLFSSL_ENTER("wolfSSL_EC_POINT_copy");
11809
11810
    /* Validate parameters. */
11811
    if ((dest == NULL) || (src == NULL)) {
11812
        ret = 0;
11813
    }
11814
11815
    /* Ensure internal EC point of src is setup. */
11816
    if ((ret == 1) && (ec_point_setup(src) != 1)) {
11817
        ret = 0;
11818
    }
11819
11820
    /* Copy internal EC points. */
11821
    if ((ret == 1) && (wc_ecc_copy_point((ecc_point*)src->internal,
11822
            (ecc_point*)dest->internal) != MP_OKAY)) {
11823
        ret = 0;
11824
    }
11825
11826
    if (ret == 1) {
11827
        /* Destinatation internal point is set. */
11828
        dest->inSet = 1;
11829
11830
        /* Set the external EC point of dest based on internal. */
11831
        if (ec_point_external_set(dest) != 1) {
11832
            ret = 0;
11833
        }
11834
    }
11835
11836
    return ret;
11837
}
11838
11839
/* Checks whether point is at infinity.
11840
 *
11841
 * Return code compliant with OpenSSL.
11842
 *
11843
 * @param [in] group  EC group.
11844
 * @param [in] point  EC point to check.
11845
 * @return  1 when at infinity.
11846
 * @return  0 when not at infinity.
11847
 */
11848
int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
11849
    const WOLFSSL_EC_POINT *point)
11850
{
11851
    int ret = 1;
11852
11853
    WOLFSSL_ENTER("wolfSSL_EC_POINT_is_at_infinity");
11854
11855
    /* Validate parameters. */
11856
    if ((group == NULL) || (point == NULL) || (point->internal == NULL)) {
11857
        WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error");
11858
        ret = 0;
11859
    }
11860
11861
    /* Ensure internal EC point is setup. */
11862
    if ((ret == 1) && (ec_point_setup(point) != 1)) {
11863
        ret = 0;
11864
    }
11865
    if (ret == 1) {
11866
    #ifndef WOLF_CRYPTO_CB_ONLY_ECC
11867
        /* Check for infinity. */
11868
        ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal);
11869
        if (ret < 0) {
11870
            WOLFSSL_MSG("ecc_point_is_at_infinity failure");
11871
            /* Error return is 0 by OpenSSL. */
11872
            ret = 0;
11873
        }
11874
    #else
11875
        WOLFSSL_MSG("ecc_point_is_at_infinitiy compiled out");
11876
        ret = 0;
11877
    #endif
11878
    }
11879
11880
    return ret;
11881
}
11882
11883
#endif /* OPENSSL_EXTRA */
11884
11885
/* End EC_POINT */
11886
11887
/* Start EC_KEY */
11888
11889
#ifdef OPENSSL_EXTRA
11890
11891
/*
11892
 * EC key constructor/deconstructor APIs
11893
 */
11894
11895
/* Allocate a new EC key.
11896
 *
11897
 * Not OpenSSL API.
11898
 *
11899
 * @param [in] heap   Heap hint for dynamic memory allocation.
11900
 * @param [in] devId  Device identifier value.
11901
 * @return  New, allocated EC key on success.
11902
 * @return  NULL on error.
11903
 */
11904
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId)
11905
{
11906
    WOLFSSL_EC_KEY *key = NULL;
11907
    int err = 0;
11908
11909
    WOLFSSL_ENTER("wolfSSL_EC_KEY_new");
11910
11911
    /* Allocate memory for EC key. */
11912
    key = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), heap,
11913
        DYNAMIC_TYPE_ECC);
11914
    if (key == NULL) {
11915
        WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure");
11916
        err = 1;
11917
    }
11918
    if (!err) {
11919
        /* Reset all fields to 0. */
11920
        XMEMSET(key, 0, sizeof(WOLFSSL_EC_KEY));
11921
        /* Cache heap hint. */
11922
        key->heap = heap;
11923
        /* Initialize fields to defaults. */
11924
        key->form     = WC_POINT_CONVERSION_UNCOMPRESSED;
11925
11926
        /* Initialize reference count. */
11927
        wolfSSL_RefInit(&key->ref, &err);
11928
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
11929
    }
11930
    if (!err) {
11931
#endif
11932
        /* Allocate memory for internal EC key representation. */
11933
        key->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), heap,
11934
            DYNAMIC_TYPE_ECC);
11935
        if (key->internal == NULL) {
11936
            WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure");
11937
            err = 1;
11938
        }
11939
    }
11940
    if (!err) {
11941
        /* Initialize wolfCrypt EC key. */
11942
        if (wc_ecc_init_ex((ecc_key*)key->internal, heap, devId) != 0) {
11943
            WOLFSSL_MSG("wolfSSL_EC_KEY_new init ecc key failure");
11944
            err = 1;
11945
        }
11946
    }
11947
11948
    if (!err) {
11949
        /* Group unknown at creation */
11950
        key->group = wolfSSL_EC_GROUP_new_by_curve_name(WC_NID_undef);
11951
        if (key->group == NULL) {
11952
            WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_GROUP failure");
11953
            err = 1;
11954
        }
11955
    }
11956
11957
    if (!err) {
11958
        /* Allocate a point as public key. */
11959
        key->pub_key = wolfSSL_EC_POINT_new(key->group);
11960
        if (key->pub_key == NULL) {
11961
            WOLFSSL_MSG("wolfSSL_EC_POINT_new failure");
11962
            err = 1;
11963
        }
11964
    }
11965
11966
    if (!err) {
11967
        /* Allocate a BN as private key. */
11968
        key->priv_key = wolfSSL_BN_new();
11969
        if (key->priv_key == NULL) {
11970
            WOLFSSL_MSG("wolfSSL_BN_new failure");
11971
            err = 1;
11972
        }
11973
    }
11974
11975
    if (err) {
11976
        /* Dispose of EC key on error. */
11977
        wolfSSL_EC_KEY_free(key);
11978
        key = NULL;
11979
    }
11980
    /* Return new EC key object. */
11981
    return key;
11982
}
11983
11984
/* Allocate a new EC key.
11985
 *
11986
 * @return  New, allocated EC key on success.
11987
 * @return  NULL on error.
11988
 */
11989
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void)
11990
{
11991
    return wolfSSL_EC_KEY_new_ex(NULL, INVALID_DEVID);
11992
}
11993
11994
/* Create new EC key with the group having the specified numeric ID.
11995
 *
11996
 * @param [in] nid  Numeric ID.
11997
 * @return  New, allocated EC key on success.
11998
 * @return  NULL on error.
11999
 */
12000
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid)
12001
{
12002
    WOLFSSL_EC_KEY *key;
12003
    int err = 0;
12004
12005
    WOLFSSL_ENTER("wolfSSL_EC_KEY_new_by_curve_name");
12006
12007
    /* Allocate empty, EC key. */
12008
    key = wolfSSL_EC_KEY_new();
12009
    if (key == NULL) {
12010
        WOLFSSL_MSG("wolfSSL_EC_KEY_new failure");
12011
        err = 1;
12012
    }
12013
12014
    if (!err) {
12015
        /* Set group to be nid. */
12016
        ec_group_set_nid(key->group, nid);
12017
        if (key->group->curve_idx == -1) {
12018
            wolfSSL_EC_KEY_free(key);
12019
            key = NULL;
12020
        }
12021
    }
12022
12023
    /* Return the new EC key object. */
12024
    return key;
12025
}
12026
12027
/* Dispose of the EC key and allocated data.
12028
 *
12029
 * Cannot use key after this call.
12030
 *
12031
 * @param [in] key  EC key to free.
12032
 */
12033
void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key)
12034
{
12035
    int doFree = 0;
12036
    int err;
12037
12038
    (void)err;
12039
12040
    WOLFSSL_ENTER("wolfSSL_EC_KEY_free");
12041
12042
    if (key != NULL) {
12043
        void* heap = key->heap;
12044
12045
        /* Decrement reference count. */
12046
        wolfSSL_RefDec(&key->ref, &doFree, &err);
12047
        if (doFree) {
12048
            /* Dispose of allocated reference counting data. */
12049
            wolfSSL_RefFree(&key->ref);
12050
12051
            /* Dispose of private key. */
12052
            wolfSSL_BN_free(key->priv_key);
12053
            wolfSSL_EC_POINT_free(key->pub_key);
12054
            wolfSSL_EC_GROUP_free(key->group);
12055
            if (key->internal != NULL) {
12056
                /* Dispose of wolfCrypt representation of EC key. */
12057
                wc_ecc_free((ecc_key*)key->internal);
12058
                XFREE(key->internal, heap, DYNAMIC_TYPE_ECC);
12059
            }
12060
12061
            /* Set back to NULLs for safety. */
12062
            ForceZero(key, sizeof(*key));
12063
12064
            /* Dispose of the memory associated with the EC key. */
12065
            XFREE(key, heap, DYNAMIC_TYPE_ECC);
12066
            (void)heap;
12067
        }
12068
    }
12069
}
12070
12071
/* Increments ref count of EC key.
12072
 *
12073
 * @param [in, out] key  EC key.
12074
 * @return  1 on success
12075
 * @return  0 on error
12076
 */
12077
int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key)
12078
{
12079
    int err = 1;
12080
12081
    if (key != NULL) {
12082
        wolfSSL_RefInc(&key->ref, &err);
12083
    }
12084
12085
    return !err;
12086
}
12087
12088
#ifndef NO_CERTS
12089
12090
#if defined(OPENSSL_ALL)
12091
/* Copy the internal, wolfCrypt EC key.
12092
 *
12093
 * @param [in, out] dst  Destination wolfCrypt EC key.
12094
 * @param [in]      src  Source wolfCrypt EC key.
12095
 * @return  0 on success.
12096
 * @return  Negative on error.
12097
 */
12098
static int wolfssl_ec_key_int_copy(ecc_key* dst, const ecc_key* src)
12099
{
12100
    int ret;
12101
12102
    /* Copy public key. */
12103
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
12104
    ret = wc_ecc_copy_point(&src->pubkey, &dst->pubkey);
12105
#else
12106
    ret = wc_ecc_copy_point((ecc_point*)&src->pubkey, &dst->pubkey);
12107
#endif
12108
    if (ret != MP_OKAY) {
12109
        WOLFSSL_MSG("wc_ecc_copy_point error");
12110
    }
12111
12112
    if (ret == 0) {
12113
        /* Copy private key. */
12114
        ret = mp_copy(wc_ecc_key_get_priv((ecc_key*)src),
12115
            wc_ecc_key_get_priv(dst));
12116
        if (ret != MP_OKAY) {
12117
            WOLFSSL_MSG("mp_copy error");
12118
        }
12119
    }
12120
12121
    if (ret == 0) {
12122
        /* Copy domain parameters. */
12123
        if (src->dp) {
12124
            ret = wc_ecc_set_curve(dst, 0, src->dp->id);
12125
            if (ret != 0) {
12126
                WOLFSSL_MSG("wc_ecc_set_curve error");
12127
            }
12128
        }
12129
    }
12130
12131
    if (ret == 0) {
12132
        /* Copy the other components. */
12133
        dst->type  = src->type;
12134
        dst->idx   = src->idx;
12135
        dst->state = src->state;
12136
        dst->flags = src->flags;
12137
    }
12138
12139
    return ret;
12140
}
12141
12142
/* Copies ecc_key into new WOLFSSL_EC_KEY object
12143
 *
12144
 * Copies the internal representation as well.
12145
 *
12146
 * @param [in] src  EC key to duplicate.
12147
 *
12148
 * @return  EC key on success.
12149
 * @return  NULL on error.
12150
 */
12151
WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src)
12152
{
12153
    int err = 0;
12154
    WOLFSSL_EC_KEY* newKey = NULL;
12155
12156
    WOLFSSL_ENTER("wolfSSL_EC_KEY_dup");
12157
12158
    /* Validate EC key. */
12159
    if ((src == NULL) || (src->internal == NULL) || (src->group == NULL) ||
12160
         (src->pub_key == NULL) || (src->priv_key == NULL)) {
12161
        WOLFSSL_MSG("src NULL error");
12162
        err = 1;
12163
    }
12164
12165
    if (!err) {
12166
        /* Create a new, empty key. */
12167
        newKey = wolfSSL_EC_KEY_new();
12168
        if (newKey == NULL) {
12169
            WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
12170
            err = 1;
12171
        }
12172
    }
12173
12174
    if (!err) {
12175
        /* Copy internal EC key. */
12176
        if (wolfssl_ec_key_int_copy((ecc_key*)newKey->internal,
12177
                (ecc_key*)src->internal) != 0) {
12178
            WOLFSSL_MSG("Copying internal EC key error");
12179
            err = 1;
12180
        }
12181
    }
12182
    if (!err) {
12183
        /* Internal key set. */
12184
        newKey->inSet = 1;
12185
12186
        /* Copy group */
12187
        err = wolfssl_ec_group_copy(newKey->group, src->group);
12188
    }
12189
    /* Copy public key. */
12190
    if ((!err) && (wolfSSL_EC_POINT_copy(newKey->pub_key, src->pub_key) != 1)) {
12191
        WOLFSSL_MSG("Copying EC public key error");
12192
        err = 1;
12193
    }
12194
12195
    if (!err) {
12196
        /* Set header size of private key in PKCS#8 format.*/
12197
        newKey->pkcs8HeaderSz = src->pkcs8HeaderSz;
12198
12199
        /* Copy private key. */
12200
        if (wolfSSL_BN_copy(newKey->priv_key, src->priv_key) == NULL) {
12201
            WOLFSSL_MSG("Copying EC private key error");
12202
            err = 1;
12203
        }
12204
    }
12205
12206
    if (err) {
12207
        /* Dispose of EC key on error. */
12208
        wolfSSL_EC_KEY_free(newKey);
12209
        newKey = NULL;
12210
    }
12211
    /* Return the new EC key. */
12212
    return newKey;
12213
}
12214
12215
#endif /* OPENSSL_ALL */
12216
12217
#endif /* !NO_CERTS */
12218
12219
/*
12220
 * EC key to/from bin/octet APIs
12221
 */
12222
12223
/* Create an EC key from the octet encoded public key.
12224
 *
12225
 * Behaviour checked against OpenSSL.
12226
 *
12227
 * @param [out]     key  Reference to EC key. Must pass in a valid object with
12228
 *                       group set.
12229
 * @param [in, out] in   On in, reference to buffer that contains data.
12230
 *                       On out, reference to buffer after public key data.
12231
 * @param [in]      len  Length of data in the buffer. Must be length of the
12232
 *                       encoded public key.
12233
 * @return  Allocated EC key on success.
12234
 * @return  NULL on error.
12235
 */
12236
WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **key,
12237
   const unsigned char **in, long len)
12238
{
12239
    int err = 0;
12240
    WOLFSSL_EC_KEY* ret = NULL;
12241
12242
    WOLFSSL_ENTER("wolfSSL_o2i_ECPublicKey");
12243
12244
    /* Validate parameters: EC group needed to perform import. */
12245
    if ((key == NULL) || (*key == NULL) || ((*key)->group == NULL) ||
12246
            (in == NULL) || (*in == NULL) || (len <= 0)) {
12247
        WOLFSSL_MSG("wolfSSL_o2i_ECPublicKey Bad arguments");
12248
        err = 1;
12249
    }
12250
12251
    if (!err) {
12252
        /* Return the EC key object passed in. */
12253
        ret = *key;
12254
12255
        /* Import point into public key field. */
12256
        if (wolfSSL_EC_POINT_oct2point(ret->group, ret->pub_key, *in,
12257
                (size_t)len, NULL) != 1) {
12258
            WOLFSSL_MSG("wolfSSL_EC_POINT_oct2point error");
12259
            ret = NULL;
12260
            err = 1;
12261
        }
12262
    }
12263
    if (!err) {
12264
        /* Assumed length passed in is all the data. */
12265
        *in += len;
12266
    }
12267
12268
    return ret;
12269
}
12270
12271
/* Puts the encoded public key into out.
12272
 *
12273
 * Passing in NULL for out returns length only.
12274
 * Passing in NULL for *out has buffer allocated, encoded into and passed back.
12275
 * Passing non-NULL for *out has it encoded into and pointer moved past.
12276
 *
12277
 * @param [in]      key  EC key to encode.
12278
 * @param [in, out] out  Reference to buffer to encode into. May be NULL or
12279
 *                       point to NULL.
12280
 * @return  Length of encoding in bytes on success.
12281
 * @return  0 on error.
12282
 */
12283
int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *key, unsigned char **out)
12284
{
12285
    int ret = 1;
12286
    size_t len = 0;
12287
    int form = WC_POINT_CONVERSION_UNCOMPRESSED;
12288
12289
    WOLFSSL_ENTER("wolfSSL_i2o_ECPublicKey");
12290
12291
    /* Validate parameters. */
12292
    if (key == NULL) {
12293
        WOLFSSL_MSG("wolfSSL_i2o_ECPublicKey Bad arguments");
12294
        ret = 0;
12295
    }
12296
12297
    /* Ensure the external key data is set from the internal EC key. */
12298
    if ((ret == 1) && (!key->exSet) && (SetECKeyExternal((WOLFSSL_EC_KEY*)
12299
            key) != 1)) {
12300
        WOLFSSL_MSG("SetECKeyExternal failure");
12301
        ret = 0;
12302
    }
12303
12304
    if (ret == 1) {
12305
    #ifdef HAVE_COMP_KEY
12306
        /* Default to compressed form if not set */
12307
        form = (key->form == WC_POINT_CONVERSION_UNCOMPRESSED) ?
12308
               WC_POINT_CONVERSION_UNCOMPRESSED :
12309
               WC_POINT_CONVERSION_COMPRESSED;
12310
    #endif
12311
12312
        /* Calculate length of point encoding. */
12313
        len = wolfSSL_EC_POINT_point2oct(key->group, key->pub_key, form, NULL,
12314
            0, NULL);
12315
    }
12316
    /* Encode if length calculated and pointer supplied to update. */
12317
    if ((ret == 1) && (len != 0) && (out != NULL)) {
12318
        unsigned char *tmp = NULL;
12319
12320
        /* Allocate buffer for encoding if no buffer supplied. */
12321
        if (*out == NULL) {
12322
            tmp = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
12323
            if (tmp == NULL) {
12324
                WOLFSSL_MSG("malloc failed");
12325
                ret = 0;
12326
            }
12327
        }
12328
        else {
12329
            /* Get buffer to encode into. */
12330
            tmp = *out;
12331
        }
12332
12333
        /* Encode public key into buffer. */
12334
        if ((ret == 1) && (wolfSSL_EC_POINT_point2oct(key->group, key->pub_key,
12335
                form, tmp, len, NULL) == 0)) {
12336
            ret = 0;
12337
        }
12338
12339
        if (ret == 1) {
12340
            /* Return buffer if allocated. */
12341
            if (*out == NULL) {
12342
                *out = tmp;
12343
            }
12344
            else {
12345
                /* Step over encoded data if not allocated. */
12346
                *out += len;
12347
            }
12348
        }
12349
        else if (*out == NULL) {
12350
            /* Dispose of allocated buffer. */
12351
            XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
12352
        }
12353
    }
12354
12355
    if (ret == 1) {
12356
        /* Return length on success. */
12357
        ret = (int)len;
12358
    }
12359
    return ret;
12360
}
12361
12362
#ifdef HAVE_ECC_KEY_IMPORT
12363
/* Create a EC key from the DER encoded private key.
12364
 *
12365
 * @param [out]     key   Reference to EC key.
12366
 * @param [in, out] in    On in, reference to buffer that contains DER data.
12367
 *                        On out, reference to buffer after private key data.
12368
 * @param [in]      long  Length of data in the buffer. May be larger than the
12369
 *                        length of the encoded private key.
12370
 * @return  Allocated EC key on success.
12371
 * @return  NULL on error.
12372
 */
12373
WOLFSSL_EC_KEY* wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY** key,
12374
    const unsigned char** in, long len)
12375
{
12376
    int err = 0;
12377
    word32 idx = 0;
12378
    WOLFSSL_EC_KEY* ret = NULL;
12379
12380
    WOLFSSL_ENTER("wolfSSL_d2i_ECPrivateKey");
12381
12382
    /* Validate parameters. */
12383
    if ((in == NULL) || (*in == NULL) || (len <= 0)) {
12384
        WOLFSSL_MSG("wolfSSL_d2i_ECPrivateKey Bad arguments");
12385
        err = 1;
12386
    }
12387
12388
    /* Create a new, empty EC key.  */
12389
    if ((!err) && ((ret = wolfSSL_EC_KEY_new()) == NULL)) {
12390
        WOLFSSL_MSG("wolfSSL_EC_KEY_new error");
12391
        err = 1;
12392
    }
12393
12394
    /* Decode the private key DER data into internal EC key. */
12395
    if ((!err) && (wc_EccPrivateKeyDecode(*in, &idx, (ecc_key*)ret->internal,
12396
            (word32)len) != 0)) {
12397
        WOLFSSL_MSG("wc_EccPrivateKeyDecode error");
12398
        err = 1;
12399
    }
12400
12401
    if (!err) {
12402
        /* Internal EC key setup. */
12403
        ret->inSet = 1;
12404
12405
        /* Set the EC key from the internal values. */
12406
        if (SetECKeyExternal(ret) != 1) {
12407
            WOLFSSL_MSG("SetECKeyExternal error");
12408
            err = 1;
12409
        }
12410
    }
12411
12412
    if (!err) {
12413
        /* Move buffer on to next byte after data used. */
12414
        *in += idx;
12415
        if (key) {
12416
            /* Return new EC key through reference. */
12417
            *key = ret;
12418
        }
12419
    }
12420
12421
    if (err && (ret != NULL)) {
12422
        /* Dispose of allocated EC key. */
12423
        wolfSSL_EC_KEY_free(ret);
12424
        ret = NULL;
12425
    }
12426
    return ret;
12427
}
12428
#endif /* HAVE_ECC_KEY_IMPORT */
12429
12430
/* Enecode the private key of the EC key into the buffer as DER.
12431
 *
12432
 * @param [in]      key  EC key to encode.
12433
 * @param [in, out] out  On in, reference to buffer to place DER encoding into.
12434
 *                       On out, reference to buffer after the encoding.
12435
 *                       May be NULL.
12436
 * @return  Length of DER encoding on success.
12437
 * @return  0 on error.
12438
 */
12439
int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *key, unsigned char **out)
12440
{
12441
    int err = 0;
12442
    word32 len = 0;
12443
12444
    WOLFSSL_ENTER("wolfSSL_i2d_ECPrivateKey");
12445
12446
    /* Validate parameters. */
12447
    if (key == NULL) {
12448
        WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments");
12449
        err = 1;
12450
    }
12451
12452
    /* Update the internal EC key if not set. */
12453
    if ((!err) && (!key->inSet) && (SetECKeyInternal((WOLFSSL_EC_KEY*)key) !=
12454
            1)) {
12455
        WOLFSSL_MSG("SetECKeyInternal error");
12456
        err = 1;
12457
    }
12458
12459
    /* Calculate the length of the private key DER encoding using internal EC
12460
     * key. */
12461
    if ((!err) && ((int)(len = (word32)wc_EccKeyDerSize((ecc_key*)key->internal,
12462
           0)) <= 0)) {
12463
        WOLFSSL_MSG("wc_EccKeyDerSize error");
12464
        err = 1;
12465
    }
12466
12467
    /* Only return length when out is NULL. */
12468
    if ((!err) && (out != NULL)) {
12469
        unsigned char* buf = NULL;
12470
12471
        /* Must have a buffer to encode into. */
12472
        if (*out == NULL) {
12473
            /* Allocate a new buffer of appropriate length. */
12474
            buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12475
            if (buf == NULL) {
12476
                /* Error and return 0. */
12477
                err = 1;
12478
                len = 0;
12479
            }
12480
            else {
12481
                /* Return the allocated buffer. */
12482
                *out = buf;
12483
            }
12484
        }
12485
        /* Encode the internal EC key as a private key in DER format. */
12486
        if ((!err) && wc_EccPrivateKeyToDer((ecc_key*)key->internal, *out,
12487
                len) < 0) {
12488
            WOLFSSL_MSG("wc_EccPrivateKeyToDer error");
12489
            err = 1;
12490
        }
12491
        else if (buf != *out) {
12492
            /* Move the reference to byte past encoded private key. */
12493
            *out += len;
12494
        }
12495
12496
        /* Dispose of any allocated buffer on error. */
12497
        if (err && (*out == buf)) {
12498
            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12499
            *out = NULL;
12500
        }
12501
    }
12502
12503
    return (int)len;
12504
}
12505
12506
/* Load private key into EC key from DER encoding.
12507
 *
12508
 * Not an OpenSSL compatibility API.
12509
 *
12510
 * @param [in, out] key     EC key to put private key values into.
12511
 * @param [in]      derBuf  Buffer holding DER encoding.
12512
 * @param [in]      derSz   Size of DER encoding in bytes.
12513
 * @return  1 on success.
12514
 * @return  -1 on error.
12515
 */
12516
int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
12517
                           int derSz)
12518
{
12519
    return wolfSSL_EC_KEY_LoadDer_ex(key, derBuf, derSz,
12520
        WOLFSSL_EC_KEY_LOAD_PRIVATE);
12521
}
12522
12523
/* Load private/public key into EC key from DER encoding.
12524
 *
12525
 * Not an OpenSSL compatibility API.
12526
 *
12527
 * @param [in, out] key     EC key to put private/public key values into.
12528
 * @param [in]      derBuf  Buffer holding DER encoding.
12529
 * @param [in]      derSz   Size of DER encoding in bytes.
12530
 * @param [in]      opt     Key type option. Valid values:
12531
 *                            WOLFSSL_EC_KEY_LOAD_PRIVATE,
12532
 *                            WOLFSSL_EC_KEY_LOAD_PUBLIC.
12533
 * @return  1 on success.
12534
 * @return  -1 on error.
12535
 */
12536
int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
12537
                              int derSz, int opt)
12538
{
12539
    int res = 1;
12540
    int ret;
12541
    word32 idx = 0;
12542
    word32 algId;
12543
12544
    WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
12545
12546
    /* Validate parameters. */
12547
    if ((key == NULL) || (key->internal == NULL) || (derBuf == NULL) ||
12548
            (derSz <= 0)) {
12549
        WOLFSSL_MSG("Bad function arguments");
12550
        res = WOLFSSL_FATAL_ERROR;
12551
    }
12552
    if ((res == 1) && (opt != WOLFSSL_EC_KEY_LOAD_PRIVATE) &&
12553
            (opt != WOLFSSL_EC_KEY_LOAD_PUBLIC)) {
12554
        res = WOLFSSL_FATAL_ERROR;
12555
    }
12556
12557
    if (res == 1) {
12558
        /* Assume no PKCS#8 header. */
12559
        key->pkcs8HeaderSz = 0;
12560
12561
        /* Check if input buffer has PKCS8 header. In the case that it does not
12562
         * have a PKCS8 header then do not error out.
12563
         */
12564
        if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx,
12565
                (word32)derSz, &algId)) > 0) {
12566
            WOLFSSL_MSG("Found PKCS8 header");
12567
            key->pkcs8HeaderSz = (word16)idx;
12568
            res = 1;
12569
        }
12570
        /* Error out on parsing error. */
12571
        else if (ret != WC_NO_ERR_TRACE(ASN_PARSE_E)) {
12572
            WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
12573
            res = WOLFSSL_FATAL_ERROR;
12574
        }
12575
    }
12576
12577
    if (res == 1) {
12578
        /* Load into internal EC key based on key type option. */
12579
        if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
12580
            ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
12581
                (word32)derSz);
12582
        }
12583
        else {
12584
            ret = wc_EccPublicKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
12585
                (word32)derSz);
12586
            if (ret < 0) {
12587
                ecc_key *tmp = (ecc_key*)XMALLOC(sizeof(ecc_key),
12588
                    ((ecc_key*)key->internal)->heap, DYNAMIC_TYPE_ECC);
12589
                if (tmp == NULL) {
12590
                    ret = WOLFSSL_FATAL_ERROR;
12591
                }
12592
                else {
12593
                    /* We now try again as x.963 [point type][x][opt y]. */
12594
                    ret = wc_ecc_init_ex(tmp, ((ecc_key*)key->internal)->heap,
12595
                                         INVALID_DEVID);
12596
                    if (ret == 0) {
12597
                        ret = wc_ecc_import_x963(derBuf, (word32)derSz, tmp);
12598
                        if (ret == 0) {
12599
                            /* Take ownership of new key - set tmp to the old
12600
                             * key which will then be freed below. */
12601
                            ecc_key *old = (ecc_key *)key->internal;
12602
                            key->internal = tmp;
12603
                            tmp = old;
12604
12605
                            idx = (word32)derSz;
12606
                        }
12607
                        wc_ecc_free(tmp);
12608
                    }
12609
                    XFREE(tmp, ((ecc_key*)key->internal)->heap,
12610
                          DYNAMIC_TYPE_ECC);
12611
                }
12612
            }
12613
        }
12614
        if (ret < 0) {
12615
            /* Error returned from wolfSSL. */
12616
            if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
12617
                WOLFSSL_MSG("wc_EccPrivateKeyDecode failed");
12618
            }
12619
            else {
12620
                WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
12621
            }
12622
            res = WOLFSSL_FATAL_ERROR;
12623
        }
12624
12625
        /* Internal key updated - update whether it is a valid key. */
12626
        key->inSet = (res == 1);
12627
    }
12628
12629
    /* Set the external EC key based on value in internal. */
12630
    if ((res == 1) && (SetECKeyExternal(key) != 1)) {
12631
        WOLFSSL_MSG("SetECKeyExternal failed");
12632
        res = WOLFSSL_FATAL_ERROR;
12633
    }
12634
12635
    return res;
12636
}
12637
12638
12639
#ifndef NO_BIO
12640
12641
WOLFSSL_EC_KEY *wolfSSL_d2i_EC_PUBKEY_bio(WOLFSSL_BIO *bio,
12642
        WOLFSSL_EC_KEY **out)
12643
{
12644
    char* data = NULL;
12645
    int dataSz = 0;
12646
    int memAlloced = 0;
12647
    WOLFSSL_EC_KEY* ec = NULL;
12648
    int err = 0;
12649
12650
    WOLFSSL_ENTER("wolfSSL_d2i_EC_PUBKEY_bio");
12651
12652
    if (bio == NULL)
12653
        return NULL;
12654
12655
    if (err == 0 && wolfssl_read_bio(bio, &data, &dataSz, &memAlloced) != 0) {
12656
        WOLFSSL_ERROR_MSG("wolfssl_read_bio failed");
12657
        err = 1;
12658
    }
12659
12660
    if (err == 0 && (ec = wolfSSL_EC_KEY_new()) == NULL) {
12661
        WOLFSSL_ERROR_MSG("wolfSSL_EC_KEY_new failed");
12662
        err = 1;
12663
    }
12664
12665
    /* Load the EC key with the public key from the DER encoding. */
12666
    if (err == 0 && wolfSSL_EC_KEY_LoadDer_ex(ec, (const unsigned char*)data,
12667
            dataSz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1) {
12668
        WOLFSSL_ERROR_MSG("wolfSSL_EC_KEY_LoadDer_ex failed");
12669
        err = 1;
12670
    }
12671
12672
    if (memAlloced)
12673
        XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
12674
    if (err) { /* on error */
12675
        wolfSSL_EC_KEY_free(ec);
12676
        ec = NULL;
12677
    }
12678
    else { /* on success */
12679
        if (out != NULL)
12680
            *out = ec;
12681
    }
12682
12683
    return ec;
12684
}
12685
12686
#endif /* !NO_BIO */
12687
12688
/*
12689
 * EC key PEM APIs
12690
 */
12691
12692
#ifdef HAVE_ECC_KEY_EXPORT
12693
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_FILESYSTEM) || !defined(NO_BIO))
12694
/* Encode the EC public key as DER.
12695
 *
12696
 * @param [in]  key   EC key to encode.
12697
 * @param [out] der   Pointer through which buffer is returned.
12698
 * @param [in]  heap  Heap hint.
12699
 * @return  Size of encoding on success.
12700
 * @return  0 on error.
12701
 */
12702
static int wolfssl_ec_key_to_pubkey_der(WOLFSSL_EC_KEY* key,
12703
    unsigned char** der, void* heap)
12704
{
12705
    int sz;
12706
    unsigned char* buf = NULL;
12707
12708
    (void)heap;
12709
12710
    /* Calculate encoded size to allocate. */
12711
    sz = wc_EccPublicKeyDerSize((ecc_key*)key->internal, 1);
12712
    if (sz <= 0) {
12713
        WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
12714
        sz = 0;
12715
    }
12716
    if (sz > 0) {
12717
        /* Allocate memory to hold encoding. */
12718
        buf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
12719
        if (buf == NULL) {
12720
            WOLFSSL_MSG("malloc failed");
12721
            sz = 0;
12722
        }
12723
    }
12724
    if (sz > 0) {
12725
        /* Encode public key to DER using wolfSSL.  */
12726
        sz = wc_EccPublicKeyToDer((ecc_key*)key->internal, buf, (word32)sz, 1);
12727
        if (sz < 0) {
12728
            WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
12729
            sz = 0;
12730
        }
12731
    }
12732
12733
    /* Return buffer on success. */
12734
    if (sz > 0) {
12735
        *der = buf;
12736
    }
12737
    else {
12738
        /* Dispose of any dynamically allocated data not returned. */
12739
        XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
12740
    }
12741
12742
    return sz;
12743
}
12744
#endif
12745
12746
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_KEY_GEN)
12747
/*
12748
 * Return code compliant with OpenSSL.
12749
 *
12750
 * @param [in] fp   File pointer to write PEM encoding to.
12751
 * @param [in] key  EC key to encode and write.
12752
 * @return  1 on success.
12753
 * @return  0 on error.
12754
 */
12755
int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY* key)
12756
{
12757
    int ret = 1;
12758
    unsigned char* derBuf = NULL;
12759
    int derSz = 0;
12760
12761
    WOLFSSL_ENTER("wolfSSL_PEM_write_EC_PUBKEY");
12762
12763
    /* Validate parameters. */
12764
    if ((fp == XBADFILE) || (key == NULL)) {
12765
        WOLFSSL_MSG("Bad argument.");
12766
        return 0;
12767
    }
12768
12769
    /* Encode public key in EC key as DER. */
12770
    derSz = wolfssl_ec_key_to_pubkey_der(key, &derBuf, key->heap);
12771
    if (derSz == 0) {
12772
        ret = 0;
12773
    }
12774
12775
    /* Write out to file the PEM encoding of the DER. */
12776
    if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
12777
            ECC_PUBLICKEY_TYPE, key->heap) != 1)) {
12778
        ret = 0;
12779
    }
12780
12781
    /* Dispose of any dynamically allocated data. */
12782
    XFREE(derBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
12783
12784
    WOLFSSL_LEAVE("wolfSSL_PEM_write_EC_PUBKEY", ret);
12785
12786
    return ret;
12787
}
12788
#endif
12789
#endif
12790
12791
#ifndef NO_BIO
12792
/* Read a PEM encoded EC public key from a BIO.
12793
 *
12794
 * @param [in]  bio   BIO to read EC public key from.
12795
 * @param [out] out   Pointer to return EC key object through. May be NULL.
12796
 * @param [in]  cb    Password callback when PEM encrypted.
12797
 * @param [in]  pass  NUL terminated string for passphrase when PEM
12798
 *                    encrypted.
12799
 * @return  New EC key object on success.
12800
 * @return  NULL on error.
12801
 */
12802
WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO* bio,
12803
    WOLFSSL_EC_KEY** out, wc_pem_password_cb* cb, void *pass)
12804
{
12805
    int             err = 0;
12806
    WOLFSSL_EC_KEY* ec = NULL;
12807
    DerBuffer*      der = NULL;
12808
    int             keyFormat = 0;
12809
12810
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_EC_PUBKEY");
12811
12812
    /* Validate parameters. */
12813
    if (bio == NULL) {
12814
        err = 1;
12815
    }
12816
12817
    if (!err) {
12818
        /* Create an empty EC key. */
12819
        ec = wolfSSL_EC_KEY_new();
12820
        if (ec == NULL) {
12821
            err = 1;
12822
        }
12823
    }
12824
    /* Read a PEM key in to a new DER buffer. */
12825
    if ((!err) && (pem_read_bio_key(bio, cb, pass, ECC_PUBLICKEY_TYPE,
12826
            &keyFormat, &der) <= 0)) {
12827
        err = 1;
12828
    }
12829
    /* Load the EC key with the public key from the DER encoding. */
12830
    if ((!err) && (wolfSSL_EC_KEY_LoadDer_ex(ec, der->buffer, (int)der->length,
12831
            WOLFSSL_EC_KEY_LOAD_PUBLIC) != 1)) {
12832
        WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_KEY");
12833
        err = 1;
12834
    }
12835
12836
    /* Dispose of dynamically allocated data not needed anymore. */
12837
    FreeDer(&der);
12838
    if (err) {
12839
        wolfSSL_EC_KEY_free(ec);
12840
        ec = NULL;
12841
    }
12842
12843
    /* Return EC key through out if required. */
12844
    if ((out != NULL) && (ec != NULL)) {
12845
        *out = ec;
12846
    }
12847
    return ec;
12848
}
12849
12850
/* Read a PEM encoded EC private key from a BIO.
12851
 *
12852
 * @param [in]  bio   BIO to read EC private key from.
12853
 * @param [out] out   Pointer to return EC key object through. May be NULL.
12854
 * @param [in]  cb    Password callback when PEM encrypted.
12855
 * @param [in]  pass  NUL terminated string for passphrase when PEM
12856
 *                    encrypted.
12857
 * @return  New EC key object on success.
12858
 * @return  NULL on error.
12859
 */
12860
WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio,
12861
   WOLFSSL_EC_KEY** out, wc_pem_password_cb* cb, void *pass)
12862
{
12863
    int             err = 0;
12864
    WOLFSSL_EC_KEY* ec = NULL;
12865
    DerBuffer*      der = NULL;
12866
    int             keyFormat = 0;
12867
12868
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_ECPrivateKey");
12869
12870
    /* Validate parameters. */
12871
    if (bio == NULL) {
12872
        err = 1;
12873
    }
12874
12875
    if (!err) {
12876
        /* Create an empty EC key. */
12877
        ec = wolfSSL_EC_KEY_new();
12878
        if (ec == NULL) {
12879
            err = 1;
12880
        }
12881
    }
12882
    /* Read a PEM key in to a new DER buffer.
12883
     * To check ENC EC PRIVATE KEY, it uses PRIVATEKEY_TYPE to call
12884
     * pem_read_bio_key(), and then check key format if it is EC.
12885
     */
12886
    if ((!err) && (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE,
12887
            &keyFormat, &der) <= 0)) {
12888
        err = 1;
12889
    }
12890
    if (keyFormat != ECDSAk) {
12891
        WOLFSSL_ERROR_MSG("Error not EC key format");
12892
        err = 1;
12893
    }
12894
    /* Load the EC key with the private key from the DER encoding. */
12895
    if ((!err) && (wolfSSL_EC_KEY_LoadDer_ex(ec, der->buffer, (int)der->length,
12896
            WOLFSSL_EC_KEY_LOAD_PRIVATE) != 1)) {
12897
        WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_KEY");
12898
        err = 1;
12899
    }
12900
12901
    /* Dispose of dynamically allocated data not needed anymore. */
12902
    FreeDer(&der);
12903
    if (err) {
12904
        wolfSSL_EC_KEY_free(ec);
12905
        ec = NULL;
12906
    }
12907
12908
    /* Return EC key through out if required. */
12909
    if ((out != NULL) && (ec != NULL)) {
12910
        *out = ec;
12911
    }
12912
    return ec;
12913
}
12914
#endif /* !NO_BIO */
12915
12916
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ECC_KEY_EXPORT)
12917
#ifndef NO_BIO
12918
/* Write out the EC public key as PEM to the BIO.
12919
 *
12920
 * @param [in] bio  BIO to write PEM encoding to.
12921
 * @param [in] ec   EC public key to encode.
12922
 * @return  1 on success.
12923
 * @return  0 on error.
12924
 */
12925
int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec)
12926
{
12927
    int ret = 1;
12928
    unsigned char* derBuf = NULL;
12929
    int derSz = 0;
12930
12931
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_EC_PUBKEY");
12932
12933
    /* Validate parameters. */
12934
    if ((bio == NULL) || (ec == NULL)) {
12935
        WOLFSSL_MSG("Bad Function Arguments");
12936
        return 0;
12937
    }
12938
12939
    /* Encode public key in EC key as DER. */
12940
    derSz = wolfssl_ec_key_to_pubkey_der(ec, &derBuf, ec->heap);
12941
    if (derSz == 0) {
12942
        ret = 0;
12943
    }
12944
12945
    /* Write out to BIO the PEM encoding of the EC public key. */
12946
    if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
12947
            ECC_PUBLICKEY_TYPE) != 1)) {
12948
        ret = 0;
12949
    }
12950
12951
    /* Dispose of any dynamically allocated data. */
12952
    XFREE(derBuf, ec->heap, DYNAMIC_TYPE_TMP_BUFFER);
12953
12954
    return ret;
12955
}
12956
12957
/* Write out the EC private key as PEM to the BIO.
12958
 *
12959
 * Return code compliant with OpenSSL.
12960
 *
12961
 * @param [in] bio       BIO to write PEM encoding to.
12962
 * @param [in] ec        EC private key to encode.
12963
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
12964
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
12965
 * @param [in] passwdSz  Length of password string when PEM encrypted.
12966
 * @param [in] cb        Password callback when PEM encrypted. Unused.
12967
 * @param [in] pass      NUL terminated string for passphrase when PEM
12968
 *                       encrypted. Unused.
12969
 * @return  1 on success.
12970
 * @return  0 on error.
12971
 */
12972
int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec,
12973
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
12974
    wc_pem_password_cb* cb, void* arg)
12975
{
12976
    int ret = 1;
12977
    unsigned char* pem = NULL;
12978
    int pLen = 0;
12979
12980
    (void)cb;
12981
    (void)arg;
12982
12983
    /* Validate parameters. */
12984
    if ((bio == NULL) || (ec == NULL)) {
12985
        ret = 0;
12986
    }
12987
12988
    /* Write EC private key to PEM. */
12989
    if ((ret == 1) && (wolfSSL_PEM_write_mem_ECPrivateKey(ec, cipher, passwd,
12990
            passwdSz, &pem, &pLen) != 1)) {
12991
       ret = 0;
12992
    }
12993
    /* Write PEM to BIO. */
12994
    if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) != pLen)) {
12995
        WOLFSSL_ERROR_MSG("EC private key BIO write failed");
12996
        ret = 0;
12997
    }
12998
12999
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
13000
13001
    return ret;
13002
}
13003
13004
#endif /* !NO_BIO */
13005
13006
/* Encode the EC private key as PEM into buffer.
13007
 *
13008
 * Return code compliant with OpenSSL.
13009
 * Not an OpenSSL API.
13010
 *
13011
 * @param [in]  ec        EC private key to encode.
13012
 * @param [in]  cipher    Cipher to use when PEM encrypted. May be NULL.
13013
 * @param [in]  passwd    Password string when PEM encrypted. May be NULL.
13014
 * @param [in]  passwdSz  Length of password string when PEM encrypted.
13015
 * @param [out] pem       Newly allocated buffer holding PEM encoding.
13016
 * @param [out] pLen      Length of PEM encoding in bytes.
13017
 * @return  1 on success.
13018
 * @return  0 on error.
13019
 */
13020
int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ec,
13021
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
13022
    unsigned char **pem, int *pLen)
13023
{
13024
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
13025
    int ret = 1;
13026
    byte* derBuf = NULL;
13027
    word32 der_max_len = 0;
13028
    int derSz = 0;
13029
13030
    WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey");
13031
13032
    /* Validate parameters. */
13033
    if ((pem == NULL) || (pLen == NULL) || (ec == NULL) ||
13034
            (ec->internal == NULL)) {
13035
        WOLFSSL_MSG("Bad function arguments");
13036
        ret = 0;
13037
    }
13038
13039
    /* Ensure internal EC key is set from external. */
13040
    if ((ret == 1) && (ec->inSet == 0)) {
13041
        WOLFSSL_MSG("No ECC internal set, do it");
13042
13043
        if (SetECKeyInternal(ec) != 1) {
13044
            WOLFSSL_MSG("SetECKeyInternal failed");
13045
            ret = 0;
13046
        }
13047
    }
13048
13049
    if (ret == 1) {
13050
        /* Calculate maximum size of DER encoding.
13051
         * 4 > size of pub, priv + ASN.1 additional information */
13052
        der_max_len = 4 * (word32)wc_ecc_size((ecc_key*)ec->internal) +
13053
                      WC_AES_BLOCK_SIZE;
13054
13055
        /* Allocate buffer big enough to hold encoding. */
13056
        derBuf = (byte*)XMALLOC((size_t)der_max_len, NULL,
13057
            DYNAMIC_TYPE_TMP_BUFFER);
13058
        if (derBuf == NULL) {
13059
            WOLFSSL_MSG("malloc failed");
13060
            ret = 0;
13061
        }
13062
    }
13063
13064
    if (ret == 1) {
13065
        /* Encode EC private key as DER. */
13066
        derSz = wc_EccKeyToDer((ecc_key*)ec->internal, derBuf, der_max_len);
13067
        if (derSz < 0) {
13068
            WOLFSSL_MSG("wc_EccKeyToDer failed");
13069
            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
13070
            ret = 0;
13071
        }
13072
    }
13073
13074
    /* Convert DER to PEM - possibly encrypting. */
13075
    if ((ret == 1) && (der_to_enc_pem_alloc(derBuf, derSz, cipher, passwd,
13076
            passwdSz, ECC_PRIVATEKEY_TYPE, NULL, pem, pLen) != 1)) {
13077
        WOLFSSL_ERROR_MSG("der_to_enc_pem_alloc failed");
13078
        ret = 0;
13079
    }
13080
13081
    return ret;
13082
#else
13083
    (void)ec;
13084
    (void)cipher;
13085
    (void)passwd;
13086
    (void)passwdSz;
13087
    (void)pem;
13088
    (void)pLen;
13089
    return 0;
13090
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
13091
}
13092
13093
#ifndef NO_FILESYSTEM
13094
/* Write out the EC private key as PEM to file.
13095
 *
13096
 * Return code compliant with OpenSSL.
13097
 *
13098
 * @param [in] fp        File pointer to write PEM encoding to.
13099
 * @param [in] ec        EC private key to encode.
13100
 * @param [in] cipher    Cipher to use when PEM encrypted. May be NULL.
13101
 * @param [in] passwd    Password string when PEM encrypted. May be NULL.
13102
 * @param [in] passwdSz  Length of password string when PEM encrypted.
13103
 * @param [in] cb        Password callback when PEM encrypted. Unused.
13104
 * @param [in] pass      NUL terminated string for passphrase when PEM
13105
 *                       encrypted. Unused.
13106
 * @return  1 on success.
13107
 * @return  0 on error.
13108
 */
13109
int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ec,
13110
    const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
13111
    wc_pem_password_cb *cb, void *pass)
13112
{
13113
    int ret = 1;
13114
    byte *pem = NULL;
13115
    int pLen = 0;
13116
13117
    (void)cb;
13118
    (void)pass;
13119
13120
    WOLFSSL_MSG("wolfSSL_PEM_write_ECPrivateKey");
13121
13122
    /* Validate parameters. */
13123
    if ((fp == XBADFILE) || (ec == NULL) || (ec->internal == NULL)) {
13124
        WOLFSSL_MSG("Bad function arguments");
13125
        ret = 0;
13126
    }
13127
13128
    /* Write EC private key to PEM. */
13129
    if ((ret == 1) && (wolfSSL_PEM_write_mem_ECPrivateKey(ec, cipher, passwd,
13130
            passwdSz, &pem, &pLen) != 1)) {
13131
        WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed");
13132
        ret = 0;
13133
    }
13134
13135
    /* Write out to file the PEM encoding of the EC private key. */
13136
    if ((ret == 1) && ((int)XFWRITE(pem, 1, (size_t)pLen, fp) != pLen)) {
13137
        WOLFSSL_MSG("ECC private key file write failed");
13138
        ret = 0;
13139
    }
13140
13141
    /* Dispose of any dynamically allocated data. */
13142
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
13143
13144
    return ret;
13145
}
13146
13147
#endif /* NO_FILESYSTEM */
13148
#endif /* WOLFSSL_KEY_GEN && HAVE_ECC_KEY_EXPORT */
13149
13150
/*
13151
 * EC key print APIs
13152
 */
13153
13154
#ifndef NO_CERTS
13155
13156
#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
13157
    !defined(NO_STDIO_FILESYSTEM)
13158
/* Print the EC key to a file pointer as text.
13159
 *
13160
 * @param [in] fp      File pointer.
13161
 * @param [in] key     EC key to print.
13162
 * @param [in] indent  Number of spaces to place before each line printed.
13163
 * @return  1 on success.
13164
 * @return  0 on failure.
13165
 */
13166
int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent)
13167
{
13168
    int ret = 1;
13169
    int bits = 0;
13170
    int priv = 0;
13171
13172
    WOLFSSL_ENTER("wolfSSL_EC_KEY_print_fp");
13173
13174
    /* Validate parameters. */
13175
    if ((fp == XBADFILE) || (key == NULL) || (key->group == NULL) ||
13176
            (indent < 0)) {
13177
        ret = 0;
13178
    }
13179
13180
    if (ret == 1) {
13181
        /* Get EC groups order size in bits. */
13182
        bits = wolfSSL_EC_GROUP_order_bits(key->group);
13183
        if (bits <= 0) {
13184
            WOLFSSL_MSG("Failed to get group order bits.");
13185
            ret = 0;
13186
        }
13187
    }
13188
    if (ret == 1) {
13189
        const char* keyType;
13190
13191
        /* Determine whether this is a private or public key. */
13192
        if ((key->priv_key != NULL) && (!wolfSSL_BN_is_zero(key->priv_key))) {
13193
            keyType = "Private-Key";
13194
            priv = 1;
13195
        }
13196
        else {
13197
            keyType = "Public-Key";
13198
        }
13199
13200
        /* Print key header. */
13201
        if (XFPRINTF(fp, "%*s%s: (%d bit)\n", indent, "", keyType, bits) < 0) {
13202
            ret = 0;
13203
        }
13204
    }
13205
    if ((ret == 1) && priv) {
13206
        /* Print the private key BN. */
13207
        ret = pk_bn_field_print_fp(fp, indent, "priv", key->priv_key);
13208
    }
13209
    /* Check for public key data in EC key. */
13210
    if ((ret == 1) && (key->pub_key != NULL) && (key->pub_key->exSet)) {
13211
        /* Get the public key point as one BN. */
13212
        WOLFSSL_BIGNUM* pubBn = wolfSSL_EC_POINT_point2bn(key->group,
13213
            key->pub_key, WC_POINT_CONVERSION_UNCOMPRESSED, NULL, NULL);
13214
        if (pubBn == NULL) {
13215
            WOLFSSL_MSG("wolfSSL_EC_POINT_point2bn failed.");
13216
            ret = 0;
13217
        }
13218
        else {
13219
            /* Print the public key in a BN. */
13220
            ret = pk_bn_field_print_fp(fp, indent, "pub", pubBn);
13221
            wolfSSL_BN_free(pubBn);
13222
        }
13223
    }
13224
    if (ret == 1) {
13225
        /* Get the NID of the group. */
13226
        int nid = wolfSSL_EC_GROUP_get_curve_name(key->group);
13227
        if (nid > 0) {
13228
            /* Convert the NID into a long name and NIST name. */
13229
            const char* curve = wolfSSL_OBJ_nid2ln(nid);
13230
            const char* nistName = wolfSSL_EC_curve_nid2nist(nid);
13231
13232
            /* Print OID name if known. */
13233
            if ((curve != NULL) &&
13234
                (XFPRINTF(fp, "%*sASN1 OID: %s\n", indent, "", curve) < 0)) {
13235
                ret = 0;
13236
            }
13237
            /* Print NIST curve name if known. */
13238
            if ((nistName != NULL) &&
13239
                (XFPRINTF(fp, "%*sNIST CURVE: %s\n", indent, "",
13240
                    nistName) < 0)) {
13241
                ret = 0;
13242
            }
13243
        }
13244
    }
13245
13246
13247
    WOLFSSL_LEAVE("wolfSSL_EC_KEY_print_fp", ret);
13248
13249
    return ret;
13250
}
13251
#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
13252
13253
#endif /* !NO_CERTS */
13254
13255
/*
13256
 * EC_KEY get/set/test APIs
13257
 */
13258
13259
/* Set data of internal, wolfCrypt EC key object into EC key.
13260
 *
13261
 * EC_KEY wolfSSL -> OpenSSL
13262
 *
13263
 * @param [in, out] p  EC key to update.
13264
 * @return  1 on success.
13265
 * @return  -1 on failure.
13266
 */
13267
int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
13268
{
13269
    int ret = 1;
13270
13271
    WOLFSSL_ENTER("SetECKeyExternal");
13272
13273
    /* Validate parameter. */
13274
    if ((eckey == NULL) || (eckey->internal == NULL)) {
13275
        WOLFSSL_MSG("ec key NULL error");
13276
        ret = WOLFSSL_FATAL_ERROR;
13277
    }
13278
    else {
13279
        ecc_key* key = (ecc_key*)eckey->internal;
13280
13281
        /* Set group (OID, nid and idx) from wolfCrypt EC key. */
13282
        eckey->group->curve_oid = (int)key->dp->oidSum;
13283
        eckey->group->curve_nid = EccEnumToNID(key->dp->id);
13284
        eckey->group->curve_idx = key->idx;
13285
13286
        if (eckey->pub_key->internal != NULL) {
13287
            /* Copy internal public point from internal key's public point. */
13288
            if (wc_ecc_copy_point(&key->pubkey,
13289
                    (ecc_point*)eckey->pub_key->internal) != MP_OKAY) {
13290
                WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed");
13291
                ret = WOLFSSL_FATAL_ERROR;
13292
            }
13293
13294
            /* Set external public key from internal wolfCrypt, public key. */
13295
            if ((ret == 1) && (ec_point_external_set(eckey->pub_key) != 1)) {
13296
                WOLFSSL_MSG("SetECKeyExternal ec_point_external_set failed");
13297
                ret = WOLFSSL_FATAL_ERROR;
13298
            }
13299
        }
13300
13301
        /* set the external privkey */
13302
        if ((ret == 1) && (key->type == ECC_PRIVATEKEY) &&
13303
                (wolfssl_bn_set_value(&eckey->priv_key,
13304
                wc_ecc_key_get_priv(key)) != 1)) {
13305
            WOLFSSL_MSG("ec priv key error");
13306
            ret = WOLFSSL_FATAL_ERROR;
13307
        }
13308
13309
        /* External values set when operations succeeded. */
13310
        eckey->exSet = (ret == 1);
13311
    }
13312
13313
    return ret;
13314
}
13315
13316
/* Set data of EC key into internal, wolfCrypt EC key object.
13317
 *
13318
 * EC_KEY Openssl -> WolfSSL
13319
 *
13320
 * @param [in, out] p  EC key to update.
13321
 * @return  1 on success.
13322
 * @return  -1 on failure.
13323
 */
13324
int SetECKeyInternal(WOLFSSL_EC_KEY* eckey)
13325
{
13326
    int ret = 1;
13327
13328
    WOLFSSL_ENTER("SetECKeyInternal");
13329
13330
    /* Validate parameter. */
13331
    if ((eckey == NULL) || (eckey->internal == NULL) ||
13332
            (eckey->group == NULL)) {
13333
        WOLFSSL_MSG("ec key NULL error");
13334
        ret = WOLFSSL_FATAL_ERROR;
13335
    }
13336
    else {
13337
        ecc_key* key = (ecc_key*)eckey->internal;
13338
        int pubSet = 0;
13339
13340
        /* Validate group. */
13341
        if ((eckey->group->curve_idx < 0) ||
13342
            (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) {
13343
            WOLFSSL_MSG("invalid curve idx");
13344
            ret = WOLFSSL_FATAL_ERROR;
13345
        }
13346
13347
        if (ret == 1) {
13348
            /* Set group (idx of curve and corresponding domain parameters). */
13349
            key->idx = eckey->group->curve_idx;
13350
            key->dp = &ecc_sets[key->idx];
13351
            pubSet = (eckey->pub_key != NULL);
13352
        }
13353
        /* Set public key (point). */
13354
        if ((ret == 1) && pubSet) {
13355
            if (ec_point_internal_set(eckey->pub_key) != 1) {
13356
                WOLFSSL_MSG("ec key pub error");
13357
                ret = WOLFSSL_FATAL_ERROR;
13358
            }
13359
            /* Copy public point to key. */
13360
            if ((ret == 1) && (wc_ecc_copy_point(
13361
                    (ecc_point*)eckey->pub_key->internal, &key->pubkey) !=
13362
                    MP_OKAY)) {
13363
                WOLFSSL_MSG("wc_ecc_copy_point error");
13364
                ret = WOLFSSL_FATAL_ERROR;
13365
            }
13366
13367
            if (ret == 1) {
13368
                /* Set that the internal key is a public key */
13369
                key->type = ECC_PUBLICKEY;
13370
            }
13371
        }
13372
13373
        /* set privkey */
13374
        if ((ret == 1) && (eckey->priv_key != NULL)) {
13375
            if (wolfssl_bn_get_value(eckey->priv_key,
13376
                    wc_ecc_key_get_priv(key)) != 1) {
13377
                WOLFSSL_MSG("ec key priv error");
13378
                ret = WOLFSSL_FATAL_ERROR;
13379
            }
13380
            /* private key */
13381
            if ((ret == 1) && (!mp_iszero(wc_ecc_key_get_priv(key)))) {
13382
                if (pubSet) {
13383
                    key->type = ECC_PRIVATEKEY;
13384
                }
13385
                else {
13386
                    key->type = ECC_PRIVATEKEY_ONLY;
13387
                }
13388
            }
13389
        }
13390
13391
        /* Internal values set when operations succeeded. */
13392
        eckey->inSet = (ret == 1);
13393
    }
13394
13395
    return ret;
13396
}
13397
13398
/* Get point conversion format of EC key.
13399
 *
13400
 * @param [in] key  EC key.
13401
 * @return  Point conversion format on success.
13402
 * @return  -1 on error.
13403
 */
13404
wc_point_conversion_form_t wolfSSL_EC_KEY_get_conv_form(
13405
    const WOLFSSL_EC_KEY* key)
13406
{
13407
    if (key == NULL)
13408
        return WOLFSSL_FATAL_ERROR;
13409
    return key->form;
13410
}
13411
13412
/* Set point conversion format into EC key.
13413
 *
13414
 * @param [in, out] key   EC key to set format into.
13415
 * @param [in]      form  Point conversion format. Valid values:
13416
 *                          WC_POINT_CONVERSION_UNCOMPRESSED,
13417
 *                          WC_POINT_CONVERSION_COMPRESSED (when HAVE_COMP_KEY)
13418
 */
13419
void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *key, int form)
13420
{
13421
    if (key == NULL) {
13422
        WOLFSSL_MSG("Key passed in NULL");
13423
    }
13424
    else if (form == WC_POINT_CONVERSION_UNCOMPRESSED
13425
#ifdef HAVE_COMP_KEY
13426
          || form == WC_POINT_CONVERSION_COMPRESSED
13427
#endif
13428
             ) {
13429
        key->form = (unsigned char)form;
13430
    }
13431
    else {
13432
        WOLFSSL_MSG("Incorrect form or HAVE_COMP_KEY not compiled in");
13433
    }
13434
}
13435
13436
/* Get the EC group object that is in EC key.
13437
 *
13438
 * @param [in] key  EC key.
13439
 * @return  EC group object on success.
13440
 * @return  NULL when key is NULL.
13441
 */
13442
const WOLFSSL_EC_GROUP *wolfSSL_EC_KEY_get0_group(const WOLFSSL_EC_KEY *key)
13443
{
13444
    WOLFSSL_EC_GROUP* group = NULL;
13445
13446
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_group");
13447
13448
    if (key != NULL) {
13449
        group = key->group;
13450
    }
13451
13452
    return group;
13453
}
13454
13455
/* Set the group in WOLFSSL_EC_KEY
13456
 *
13457
 * @param [in, out] key    EC key to update.
13458
 * @param [in]      group  EC group to copy.
13459
 * @return  1 on success
13460
 * @return  0 on failure.
13461
 */
13462
int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group)
13463
{
13464
    int ret = 1;
13465
13466
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group");
13467
13468
    /* Validate parameters. */
13469
    if ((key == NULL) || (group == NULL)) {
13470
        ret = 0;
13471
    }
13472
13473
    if (ret == 1) {
13474
        /* Dispose of the current group. */
13475
        if (key->group != NULL) {
13476
            wolfSSL_EC_GROUP_free(key->group);
13477
        }
13478
        /* Duplicate the passed in group into EC key. */
13479
        key->group = wolfSSL_EC_GROUP_dup(group);
13480
        if (key->group == NULL) {
13481
            ret = 0;
13482
        }
13483
    }
13484
13485
    return ret;
13486
}
13487
13488
/* Get the BN object that is the private key in the EC key.
13489
 *
13490
 * @param [in] key  EC key.
13491
 * @return  BN object on success.
13492
 * @return  NULL when key is NULL or private key is not set.
13493
 */
13494
WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key)
13495
{
13496
    WOLFSSL_BIGNUM* priv_key = NULL;
13497
13498
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_private_key");
13499
13500
    /* Validate parameter. */
13501
    if (key == NULL) {
13502
        WOLFSSL_MSG("wolfSSL_EC_KEY_get0_private_key Bad arguments");
13503
    }
13504
    /* Only return private key if it is not 0. */
13505
    else if (!wolfSSL_BN_is_zero(key->priv_key)) {
13506
        priv_key = key->priv_key;
13507
    }
13508
13509
    return priv_key;
13510
}
13511
13512
/* Sets the private key value into EC key.
13513
 *
13514
 * Return code compliant with OpenSSL.
13515
 *
13516
 * @param [in, out] key       EC key to set.
13517
 * @param [in]      priv_key  Private key value in a BN.
13518
 * @return  1 on success
13519
 * @return  0 on failure.
13520
 */
13521
int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key,
13522
    const WOLFSSL_BIGNUM *priv_key)
13523
{
13524
    int ret = 1;
13525
13526
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_private_key");
13527
13528
    /* Validate parameters. */
13529
    if ((key == NULL) || (priv_key == NULL)) {
13530
        WOLFSSL_MSG("Bad arguments");
13531
        ret = 0;
13532
    }
13533
13534
    /* Check for obvious invalid values. */
13535
    if (wolfSSL_BN_is_negative(priv_key) || wolfSSL_BN_is_zero(priv_key) ||
13536
            wolfSSL_BN_is_one(priv_key)) {
13537
        WOLFSSL_MSG("Invalid private key value");
13538
        ret = 0;
13539
    }
13540
13541
    if (ret == 1) {
13542
        /* Free key if previously set. */
13543
        if (key->priv_key != NULL) {
13544
            wolfSSL_BN_free(key->priv_key);
13545
        }
13546
13547
        /* Duplicate the BN passed in. */
13548
        key->priv_key = wolfSSL_BN_dup(priv_key);
13549
        if (key->priv_key == NULL) {
13550
            WOLFSSL_MSG("key ecc priv key NULL");
13551
            ret = 0;
13552
        }
13553
    }
13554
    /* Set the external values into internal EC key. */
13555
    if ((ret == 1) && (SetECKeyInternal(key) != 1)) {
13556
        WOLFSSL_MSG("SetECKeyInternal failed");
13557
        /* Dispose of new private key on error. */
13558
        wolfSSL_BN_free(key->priv_key);
13559
        key->priv_key = NULL;
13560
        ret = 0;
13561
    }
13562
13563
    return ret;
13564
}
13565
13566
/* Get the public key EC point object that is in EC key.
13567
 *
13568
 * @param [in] key  EC key.
13569
 * @return  EC point object that is the public key on success.
13570
 * @return  NULL when key is NULL.
13571
 */
13572
WOLFSSL_EC_POINT* wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key)
13573
{
13574
    WOLFSSL_EC_POINT* pub_key = NULL;
13575
13576
    WOLFSSL_ENTER("wolfSSL_EC_KEY_get0_public_key");
13577
13578
    if (key != NULL) {
13579
        pub_key = key->pub_key;
13580
    }
13581
13582
    return pub_key;
13583
}
13584
13585
/*
13586
 * Return code compliant with OpenSSL.
13587
 *
13588
 * @param [in, out] key  EC key.
13589
 * @param [in]      pub  Public key as an EC point.
13590
 * @return  1 on success
13591
 * @return  0 on failure.
13592
 */
13593
int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key,
13594
    const WOLFSSL_EC_POINT *pub)
13595
{
13596
    int ret = 1;
13597
    ecc_point *pub_p = NULL;
13598
    ecc_point *key_p = NULL;
13599
13600
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_public_key");
13601
13602
    /* Validate parameters. */
13603
    if ((key == NULL) || (key->internal == NULL) || (pub == NULL) ||
13604
            (pub->internal == NULL)) {
13605
        WOLFSSL_MSG("wolfSSL_EC_KEY_set_public_key Bad arguments");
13606
        ret = 0;
13607
    }
13608
13609
    /* Ensure the internal EC key is set. */
13610
    if ((ret == 1) && (key->inSet == 0) && (SetECKeyInternal(key) != 1)) {
13611
        WOLFSSL_MSG("SetECKeyInternal failed");
13612
        ret = 0;
13613
    }
13614
13615
    /* Ensure the internal EC point of pub is setup. */
13616
    if ((ret == 1) && (ec_point_setup(pub) != 1)) {
13617
        ret = 0;
13618
    }
13619
13620
    if (ret == 1) {
13621
        /* Get the internal point of pub and the public key in key. */
13622
        pub_p = (ecc_point*)pub->internal;
13623
        key_p = (ecc_point*)key->pub_key->internal;
13624
13625
        /* Create new point if required. */
13626
        if (key_p == NULL) {
13627
            key_p = wc_ecc_new_point();
13628
            key->pub_key->internal = (void*)key_p;
13629
        }
13630
        /* Check point available. */
13631
        if (key_p == NULL) {
13632
            WOLFSSL_MSG("key ecc point NULL");
13633
            ret = 0;
13634
        }
13635
    }
13636
13637
    /* Copy the internal pub point into internal key point. */
13638
    if ((ret == 1) && (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY)) {
13639
        WOLFSSL_MSG("ecc_copy_point failure");
13640
        ret = 0;
13641
    }
13642
13643
    /* Copy the internal point data into external. */
13644
    if ((ret == 1) && (ec_point_external_set(key->pub_key) != 1)) {
13645
        WOLFSSL_MSG("SetECKeyInternal failed");
13646
        ret = 0;
13647
    }
13648
13649
    /* Copy the internal key into external. */
13650
    if ((ret == 1) && (SetECKeyInternal(key) != 1)) {
13651
        WOLFSSL_MSG("SetECKeyInternal failed");
13652
        ret = 0;
13653
    }
13654
13655
    if (ret == 1) {
13656
        /* Dump out the point and the key's public key for debug. */
13657
        wolfSSL_EC_POINT_dump("pub", pub);
13658
        wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key);
13659
    }
13660
13661
    return ret;
13662
}
13663
13664
#ifndef NO_WOLFSSL_STUB
13665
/* Set the ASN.1 encoding flag against the EC key.
13666
 *
13667
 * No implementation as only named curves supported for encoding.
13668
 *
13669
 * @param [in, out] key   EC key.
13670
 * @param [in]      flag  ASN.1 flag to set. Valid values:
13671
 *                        OPENSSL_EC_EXPLICIT_CURVE, OPENSSL_EC_NAMED_CURVE
13672
 */
13673
void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag)
13674
{
13675
    (void)key;
13676
    (void)asn1_flag;
13677
13678
    WOLFSSL_ENTER("wolfSSL_EC_KEY_set_asn1_flag");
13679
    WOLFSSL_STUB("EC_KEY_set_asn1_flag");
13680
}
13681
#endif
13682
13683
/*
13684
 * EC key generate key APIs
13685
 */
13686
13687
/* Generate an EC key.
13688
 *
13689
 * Uses the internal curve index set in the EC key or the default.
13690
 *
13691
 * @param [in, out] key  EC key.
13692
 * @return  1 on success
13693
 * @return  0 on failure.
13694
 */
13695
int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key)
13696
{
13697
    int res = 1;
13698
    int initTmpRng = 0;
13699
    WC_RNG* rng = NULL;
13700
#ifdef WOLFSSL_SMALL_STACK
13701
    WC_RNG* tmpRng = NULL;
13702
#else
13703
    WC_RNG  tmpRng[1];
13704
#endif
13705
13706
    WOLFSSL_ENTER("wolfSSL_EC_KEY_generate_key");
13707
13708
    /* Validate parameters. */
13709
    if ((key == NULL) || (key->internal == NULL) || (key->group == NULL)) {
13710
        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key Bad arguments");
13711
        res = 0;
13712
    }
13713
    if (res == 1) {
13714
        /* Check if we know which internal curve index to use. */
13715
        if (key->group->curve_idx < 0) {
13716
            /* Generate key using the default curve. */
13717
#if FIPS_VERSION3_GE(6,0,0)
13718
            key->group->curve_idx = ECC_SECP256R1; /* FIPS default to 256 */
13719
#else
13720
            key->group->curve_idx = ECC_CURVE_DEF;
13721
#endif
13722
        }
13723
13724
        /* Create a random number generator. */
13725
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
13726
        if (rng == NULL) {
13727
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
13728
            res = 0;
13729
        }
13730
    }
13731
    if (res == 1) {
13732
        /* NIDToEccEnum returns -1 for invalid NID so if key->group->curve_nid
13733
         * is 0 then pass ECC_CURVE_DEF as arg */
13734
        int eccEnum = key->group->curve_nid ?
13735
#if FIPS_VERSION3_GE(6,0,0)
13736
            NIDToEccEnum(key->group->curve_nid) : ECC_SECP256R1;
13737
#else
13738
            NIDToEccEnum(key->group->curve_nid) : ECC_CURVE_DEF;
13739
#endif
13740
        /* Get the internal EC key. */
13741
        ecc_key* ecKey = (ecc_key*)key->internal;
13742
        /* Make the key using internal API. */
13743
        int ret = 0;
13744
13745
#if FIPS_VERSION3_GE(6,0,0)
13746
        /* In the case of FIPS only allow key generation with approved curves */
13747
        if (eccEnum != ECC_SECP256R1 && eccEnum != ECC_SECP224R1 &&
13748
            eccEnum != ECC_SECP384R1 && eccEnum != ECC_SECP521R1) {
13749
            WOLFSSL_MSG("Unsupported curve selected in FIPS mode");
13750
            res = 0;
13751
        }
13752
        if (res == 1) {
13753
#endif
13754
        ret  = wc_ecc_make_key_ex(rng, 0, ecKey, eccEnum);
13755
#if FIPS_VERSION3_GE(6,0,0)
13756
        }
13757
#endif
13758
13759
    #if defined(WOLFSSL_ASYNC_CRYPT)
13760
        /* Wait on asynchronouse operation. */
13761
        ret = wc_AsyncWait(ret, &ecKey->asyncDev, WC_ASYNC_FLAG_NONE);
13762
    #endif
13763
        if (ret != 0) {
13764
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed");
13765
            res = 0;
13766
        }
13767
    }
13768
13769
    /* Dispose of local random number generator if initialized. */
13770
    if (initTmpRng) {
13771
        wc_FreeRng(rng);
13772
    #ifdef WOLFSSL_SMALL_STACK
13773
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
13774
    #endif
13775
    }
13776
13777
    /* Set the external key from new internal key values. */
13778
    if ((res == 1) && (SetECKeyExternal(key) != 1)) {
13779
        WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed");
13780
        res = 0;
13781
    }
13782
13783
    return res;
13784
}
13785
13786
/*
13787
 * EC key check key APIs
13788
 */
13789
13790
/* Check that the EC key is valid.
13791
 *
13792
 * @param [in] key  EC key.
13793
 * @return  1 on valid.
13794
 * @return  0 on invalid or error.
13795
 */
13796
int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key)
13797
{
13798
    int ret = 1;
13799
13800
    WOLFSSL_ENTER("wolfSSL_EC_KEY_check_key");
13801
13802
    /* Validate parameter. */
13803
    if ((key == NULL) || (key->internal == NULL)) {
13804
        WOLFSSL_MSG("Bad parameter");
13805
        ret = 0;
13806
    }
13807
13808
    /* Set the external EC key values into internal if not already. */
13809
    if ((ret == 1) && (key->inSet == 0) && (SetECKeyInternal(
13810
            (WOLFSSL_EC_KEY*)key) != 1)) {
13811
        WOLFSSL_MSG("SetECKeyInternal failed");
13812
        ret = 0;
13813
    }
13814
13815
    if (ret == 1) {
13816
        /* Have internal EC implementation check key. */
13817
        ret = wc_ecc_check_key((ecc_key*)key->internal) == 0;
13818
    }
13819
13820
    return ret;
13821
}
13822
13823
/* End EC_KEY */
13824
13825
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
13826
/* Get the supported, built-in EC curves
13827
 *
13828
 * @param [in, out] curves  Pre-allocated list to put supported curves into.
13829
 * @param [in]      len     Maximum number of items to place in list.
13830
 * @return  Number of built-in EC curves when curves is NULL or len is 0.
13831
 * @return  Number of items placed in list otherwise.
13832
 */
13833
size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *curves,
13834
    size_t len)
13835
{
13836
    size_t i;
13837
    size_t cnt;
13838
#ifdef HAVE_SELFTEST
13839
    /* Defined in ecc.h when available. */
13840
    size_t ecc_sets_count;
13841
13842
    /* Count the pre-defined curves since global not available. */
13843
    for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) {
13844
        /* Do nothing. */
13845
    }
13846
    ecc_sets_count = i;
13847
#endif
13848
13849
    /* Assume we are going to return total count. */
13850
    cnt = ecc_sets_count;
13851
    /* Check we have a list that can hold data. */
13852
    if ((curves != NULL) && (len != 0)) {
13853
        /* Limit count to length of list. */
13854
        if (cnt > len) {
13855
            cnt = len;
13856
        }
13857
13858
        /* Put in built-in EC curve nid and short name. */
13859
        for (i = 0; i < cnt; i++) {
13860
            curves[i].nid = EccEnumToNID(ecc_sets[i].id);
13861
            curves[i].comment = wolfSSL_OBJ_nid2sn(curves[i].nid);
13862
        }
13863
    }
13864
13865
    return cnt;
13866
}
13867
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
13868
13869
/* Start ECDSA_SIG */
13870
13871
/* Allocate a new ECDSA signature object.
13872
 *
13873
 * @return  New, allocated ECDSA signature object on success.
13874
 * @return  NULL on error.
13875
 */
13876
WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_SIG_new(void)
13877
{
13878
    int err = 0;
13879
    WOLFSSL_ECDSA_SIG *sig;
13880
13881
    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_new");
13882
13883
    /* Allocate memory for ECDSA signature object. */
13884
    sig = (WOLFSSL_ECDSA_SIG*)XMALLOC(sizeof(WOLFSSL_ECDSA_SIG), NULL,
13885
        DYNAMIC_TYPE_ECC);
13886
    if (sig == NULL) {
13887
        WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA signature failure");
13888
        err = 1;
13889
    }
13890
13891
    if (!err) {
13892
        /* Set s to NULL in case of error. */
13893
        sig->s = NULL;
13894
        /* Allocate BN into r. */
13895
        sig->r = wolfSSL_BN_new();
13896
        if (sig->r == NULL) {
13897
            WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA r failure");
13898
            err = 1;
13899
        }
13900
    }
13901
    if (!err) {
13902
        /* Allocate BN into s. */
13903
        sig->s = wolfSSL_BN_new();
13904
        if (sig->s == NULL) {
13905
            WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new malloc ECDSA s failure");
13906
            err = 1;
13907
        }
13908
    }
13909
13910
    if (err && (sig != NULL)) {
13911
        /* Dispose of allocated memory. */
13912
        wolfSSL_ECDSA_SIG_free(sig);
13913
        sig = NULL;
13914
    }
13915
    return sig;
13916
}
13917
13918
/* Dispose of ECDSA signature object.
13919
 *
13920
 * Cannot use object after this call.
13921
 *
13922
 * @param [in] sig  ECDSA signature object to free.
13923
 */
13924
void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig)
13925
{
13926
    WOLFSSL_ENTER("wolfSSL_ECDSA_SIG_free");
13927
13928
    if (sig != NULL) {
13929
        /* Dispose of BNs allocated for r and s. */
13930
        wolfSSL_BN_free(sig->r);
13931
        wolfSSL_BN_free(sig->s);
13932
13933
        /* Dispose of memory associated with ECDSA signature object. */
13934
        XFREE(sig, NULL, DYNAMIC_TYPE_ECC);
13935
    }
13936
}
13937
13938
/* Create an ECDSA signature from the DER encoding.
13939
 *
13940
 * @param [in, out] sig  Reference to ECDSA signature object. May be NULL.
13941
 * @param [in, out] pp   On in, reference to buffer containing DER encoding.
13942
 *                       On out, reference to buffer after signature data.
13943
 * @param [in]      len  Length of the data in the buffer. May be more than
13944
 *                       the length of the signature.
13945
 * @return  ECDSA signature object on success.
13946
 * @return  NULL on error.
13947
 */
13948
WOLFSSL_ECDSA_SIG* wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG** sig,
13949
    const unsigned char** pp, long len)
13950
{
13951
    int err = 0;
13952
    /* ECDSA signature object to return. */
13953
    WOLFSSL_ECDSA_SIG *s = NULL;
13954
13955
    /* Validate parameter. */
13956
    if (pp == NULL) {
13957
        err = 1;
13958
    }
13959
    if (!err) {
13960
        if (sig != NULL) {
13961
            /* Use the ECDSA signature object passed in. */
13962
            s = *sig;
13963
        }
13964
        if (s == NULL) {
13965
            /* No ECDSA signature object passed in - create a new one. */
13966
            s = wolfSSL_ECDSA_SIG_new();
13967
            if (s == NULL) {
13968
                err = 1;
13969
            }
13970
        }
13971
    }
13972
    if (!err) {
13973
        /* DecodeECC_DSA_Sig calls mp_init, so free these. */
13974
        mp_free((mp_int*)s->r->internal);
13975
        mp_free((mp_int*)s->s->internal);
13976
13977
        /* Decode the signature into internal r and s fields. */
13978
        if (DecodeECC_DSA_Sig(*pp, (word32)len, (mp_int*)s->r->internal,
13979
                (mp_int*)s->s->internal) != MP_OKAY) {
13980
            err = 1;
13981
        }
13982
    }
13983
13984
    if (!err) {
13985
        /* Move pointer passed signature data successfully decoded. */
13986
        *pp += wolfssl_der_length(*pp, (int)len);
13987
        if (sig != NULL) {
13988
            /* Update reference to ECDSA signature object. */
13989
            *sig = s;
13990
        }
13991
    }
13992
13993
    /* Dispose of newly allocated object on error. */
13994
    if (err) {
13995
        if ((s != NULL) && ((sig == NULL) || (*sig != s))) {
13996
            wolfSSL_ECDSA_SIG_free(s);
13997
        }
13998
        /* Return NULL for object on error. */
13999
        s = NULL;
14000
    }
14001
    return s;
14002
}
14003
14004
/* Encode the ECDSA signature as DER.
14005
 *
14006
 * @param [in]      sig  ECDSA signature object.
14007
 * @param [in, out] pp   On in, reference to buffer in which to place encoding.
14008
 *                       On out, reference to buffer after encoding.
14009
 *                       May be NULL or point to NULL in which case no encoding
14010
 *                       is done.
14011
 * @return  Length of encoding on success.
14012
 * @return  0 on error.
14013
 */
14014
int wolfSSL_i2d_ECDSA_SIG(const WOLFSSL_ECDSA_SIG *sig, unsigned char **pp)
14015
{
14016
    word32 len = 0;
14017
    int    update_p = 1;
14018
14019
    /* Validate parameter. */
14020
    if (sig != NULL) {
14021
        /* ASN.1: SEQ + INT + INT
14022
         *   ASN.1 Integer must be a positive value - prepend zero if number has
14023
         *   top bit set.
14024
         */
14025
        /* Get total length of r including any prepended zero. */
14026
        word32 rLen = (word32)(mp_leading_bit((mp_int*)sig->r->internal) +
14027
               mp_unsigned_bin_size((mp_int*)sig->r->internal));
14028
        /* Get total length of s including any prepended zero. */
14029
        word32 sLen = (word32)(mp_leading_bit((mp_int*)sig->s->internal) +
14030
               mp_unsigned_bin_size((mp_int*)sig->s->internal));
14031
        /* Calculate length of data in sequence. */
14032
        len = (word32)1 + ASN_LEN_SIZE(rLen) + rLen +
14033
              (word32)1 + ASN_LEN_SIZE(sLen) + sLen;
14034
        /* Add in the length of the SEQUENCE. */
14035
        len += (word32)1 + ASN_LEN_SIZE(len);
14036
14037
        #ifdef WOLFSSL_I2D_ECDSA_SIG_ALLOC
14038
        if ((pp != NULL) && (*pp == NULL)) {
14039
            *pp = (unsigned char *)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
14040
            if (*pp != NULL) {
14041
                WOLFSSL_MSG("malloc error");
14042
                return 0;
14043
            }
14044
            update_p = 0;
14045
        }
14046
        #endif
14047
14048
        /* Encode only if there is a buffer to encode into. */
14049
        if ((pp != NULL) && (*pp != NULL)) {
14050
            /* Encode using the internal representations of r and s. */
14051
            if (StoreECC_DSA_Sig(*pp, &len, (mp_int*)sig->r->internal,
14052
                    (mp_int*)sig->s->internal) != MP_OKAY) {
14053
                /* No bytes encoded. */
14054
                len = 0;
14055
            }
14056
            else if (update_p) {
14057
                /* Update pointer to after encoding. */
14058
                *pp += len;
14059
            }
14060
        }
14061
    }
14062
14063
    return (int)len;
14064
}
14065
14066
/* Get the pointer to the fields of the ECDSA signature.
14067
 *
14068
 * r and s untouched when sig is NULL.
14069
 *
14070
 * @param [in]  sig  ECDSA signature object.
14071
 * @param [out] r    R field of ECDSA signature as a BN. May be NULL.
14072
 * @param [out] s    S field of ECDSA signature as a BN. May be NULL.
14073
 */
14074
void wolfSSL_ECDSA_SIG_get0(const WOLFSSL_ECDSA_SIG* sig,
14075
    const WOLFSSL_BIGNUM** r, const WOLFSSL_BIGNUM** s)
14076
{
14077
    /* Validate parameter. */
14078
    if (sig != NULL) {
14079
        /* Return the r BN when pointer to return through. */
14080
        if (r != NULL) {
14081
            *r = sig->r;
14082
        }
14083
        /* Return the s BN when pointer to return through. */
14084
        if (s != NULL) {
14085
            *s = sig->s;
14086
        }
14087
    }
14088
}
14089
14090
/* Set the pointers to the fields of the ECDSA signature.
14091
 *
14092
 * @param [in, out] sig  ECDSA signature object to update.
14093
 * @param [in]      r    R field of ECDSA signature as a BN.
14094
 * @param [in]      s    S field of ECDSA signature as a BN.
14095
 * @return  1 on success.
14096
 * @return  0 on error.
14097
 */
14098
int wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG* sig, WOLFSSL_BIGNUM* r,
14099
    WOLFSSL_BIGNUM* s)
14100
{
14101
    int ret = 1;
14102
14103
    /* Validate parameters. */
14104
    if ((sig == NULL) || (r == NULL) || (s == NULL)) {
14105
        ret = 0;
14106
    }
14107
14108
    if (ret == 1) {
14109
        /* Dispose of old BN objects. */
14110
        wolfSSL_BN_free(sig->r);
14111
        wolfSSL_BN_free(sig->s);
14112
14113
        /* Assign new BN objects. */
14114
        sig->r = r;
14115
        sig->s = s;
14116
    }
14117
14118
    return ret;
14119
}
14120
14121
/* End ECDSA_SIG */
14122
14123
/* Start ECDSA */
14124
14125
/* Calculate maximum size of the DER encoded ECDSA signature for the curve.
14126
 *
14127
 * @param [in] key  EC key.
14128
 * @return  Size of DER encoded signature on success.
14129
 * @return  0 on error.
14130
 */
14131
int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key)
14132
{
14133
    int err = 0;
14134
    int len = 0;
14135
    const WOLFSSL_EC_GROUP *group = NULL;
14136
    int bits = 0;
14137
14138
    /* Validate parameter. */
14139
    if (key == NULL) {
14140
        err = 1;
14141
    }
14142
14143
    /* Get group from key to get order bits. */
14144
    if ((!err) && ((group = wolfSSL_EC_KEY_get0_group(key)) == NULL)) {
14145
        err = 1;
14146
    }
14147
    /* Get order bits of group. */
14148
    if ((!err) && ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0)) {
14149
        /* Group is not set. */
14150
        err = 1;
14151
    }
14152
14153
    if (!err) {
14154
        /* r and s are mod order. */
14155
        int bytes = (bits + 7) / 8;  /* Bytes needed to hold bits. */
14156
        len = SIG_HEADER_SZ + /* 2*ASN_TAG + 2*LEN(ENUM) */
14157
            ECC_MAX_PAD_SZ +  /* possible leading zeroes in r and s */
14158
            bytes + bytes;    /* max r and s in bytes */
14159
    }
14160
14161
    return len;
14162
}
14163
14164
/* Create ECDSA signature by signing digest with key.
14165
 *
14166
 * @param [in] dgst  Digest to sign.
14167
 * @param [in] dLen  Length of digest in bytes.
14168
 * @param [in] key   EC key to sign with.
14169
 * @return  ECDSA signature object on success.
14170
 * @return  NULL on error.
14171
 */
14172
WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *dgst, int dLen,
14173
    WOLFSSL_EC_KEY *key)
14174
{
14175
    int err = 0;
14176
    WOLFSSL_ECDSA_SIG *sig = NULL;
14177
#ifdef WOLFSSL_SMALL_STACK
14178
    byte*   out = NULL;
14179
#else
14180
    byte    out[ECC_BUFSIZE];
14181
#endif
14182
    unsigned int outLen = ECC_BUFSIZE;
14183
14184
    WOLFSSL_ENTER("wolfSSL_ECDSA_do_sign");
14185
14186
    /* Validate parameters. */
14187
    if ((dgst == NULL) || (key == NULL) || (key->internal == NULL)) {
14188
        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign Bad arguments");
14189
        err = 1;
14190
    }
14191
14192
    /* Ensure internal EC key is set from external. */
14193
    if ((!err) && (key->inSet == 0)) {
14194
        WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it");
14195
14196
        if (SetECKeyInternal(key) != 1) {
14197
            WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed");
14198
            err = 1;
14199
        }
14200
    }
14201
14202
#ifdef WOLFSSL_SMALL_STACK
14203
    if (!err) {
14204
        /* Allocate buffer to hold encoded signature. */
14205
        out = (byte*)XMALLOC(outLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14206
        if (out == NULL) {
14207
            err = 1;
14208
        }
14209
    }
14210
#endif
14211
14212
    /* Sign the digest with the key to create encoded ECDSA signature. */
14213
    if ((!err) && (wolfSSL_ECDSA_sign(0, dgst, dLen, out, &outLen, key) != 1)) {
14214
        err = 1;
14215
    }
14216
14217
    if (!err) {
14218
        const byte* p = out;
14219
        /* Decode the ECDSA signature into a new object. */
14220
        sig = wolfSSL_d2i_ECDSA_SIG(NULL, &p, outLen);
14221
    }
14222
14223
#ifdef WOLFSSL_SMALL_STACK
14224
    /* Dispose of any temporary dynamically allocated data. */
14225
    XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14226
#endif
14227
14228
    return sig;
14229
}
14230
14231
/* Verify ECDSA signature in the object using digest and key.
14232
 *
14233
 * Return code compliant with OpenSSL.
14234
 *
14235
 * @param [in] dgst  Digest to verify.
14236
 * @param [in] dLen  Length of the digest in bytes.
14237
 * @param [in] sig   ECDSA signature object.
14238
 * @param [in] key   EC key containing public key.
14239
 * @return  1 when signature is valid.
14240
 * @return  0 when signature is invalid.
14241
 * @return  -1 on error.
14242
 */
14243
int wolfSSL_ECDSA_do_verify(const unsigned char *dgst, int dLen,
14244
    const WOLFSSL_ECDSA_SIG *sig, WOLFSSL_EC_KEY *key)
14245
{
14246
    int ret = 1;
14247
    int verified = 0;
14248
#ifdef WOLF_CRYPTO_CB_ONLY_ECC
14249
    byte signature[ECC_MAX_SIG_SIZE];
14250
    int signatureLen;
14251
    byte* p = signature;
14252
#endif
14253
14254
    WOLFSSL_ENTER("wolfSSL_ECDSA_do_verify");
14255
14256
    /* Validate parameters. */
14257
    if ((dgst == NULL) || (sig == NULL) || (key == NULL) ||
14258
            (key->internal == NULL)) {
14259
        WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments");
14260
        ret = WOLFSSL_FATAL_ERROR;
14261
    }
14262
14263
    /* Ensure internal EC key is set from external. */
14264
    if ((ret == 1) && (key->inSet == 0)) {
14265
        WOLFSSL_MSG("No EC key internal set, do it");
14266
14267
        if (SetECKeyInternal(key) != 1) {
14268
            WOLFSSL_MSG("SetECKeyInternal failed");
14269
            ret = WOLFSSL_FATAL_ERROR;
14270
        }
14271
    }
14272
14273
    if (ret == 1) {
14274
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
14275
        /* Verify hash using digest, r and s as MP ints and internal EC key. */
14276
        if (wc_ecc_verify_hash_ex((mp_int*)sig->r->internal,
14277
                (mp_int*)sig->s->internal, dgst, (word32)dLen, &verified,
14278
                (ecc_key *)key->internal) != MP_OKAY) {
14279
            WOLFSSL_MSG("wc_ecc_verify_hash failed");
14280
            ret = WOLFSSL_FATAL_ERROR;
14281
        }
14282
        else if (verified == 0) {
14283
            WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
14284
            ret = 0;
14285
        }
14286
#else
14287
        signatureLen = i2d_ECDSA_SIG(sig, &p);
14288
        if (signatureLen > 0) {
14289
            /* verify hash. expects to call wc_CryptoCb_EccVerify internally */
14290
            ret = wc_ecc_verify_hash(signature, signatureLen, dgst,
14291
                (word32)dLen, &verified, (ecc_key*)key->internal);
14292
            if (ret != MP_OKAY) {
14293
                WOLFSSL_MSG("wc_ecc_verify_hash failed");
14294
                ret = WOLFSSL_FATAL_ERROR;
14295
            }
14296
            else if (verified == 0) {
14297
                WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected");
14298
                ret = 0;
14299
            }
14300
        }
14301
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
14302
    }
14303
14304
    return ret;
14305
}
14306
14307
/* Sign the digest with the key to produce a DER encode signature.
14308
 *
14309
 * @param [in]      type      Digest algorithm used to create digest. Unused.
14310
 * @param [in]      digest    Digest of the message to sign.
14311
 * @param [in]      digestSz  Size of the digest in bytes.
14312
 * @param [out]     sig       Buffer to hold signature.
14313
 * @param [in, out] sigSz     On in, size of buffer in bytes.
14314
 *                            On out, size of signatre in bytes.
14315
 * @param [in]      key       EC key containing private key.
14316
 * @return  1 on success.
14317
 * @return  0 on error.
14318
 */
14319
int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, int digestSz,
14320
    unsigned char *sig, unsigned int *sigSz, WOLFSSL_EC_KEY *key)
14321
{
14322
    int ret = 1;
14323
    WC_RNG* rng = NULL;
14324
#ifdef WOLFSSL_SMALL_STACK
14325
    WC_RNG* tmpRng = NULL;
14326
#else
14327
    WC_RNG  tmpRng[1];
14328
#endif
14329
    int initTmpRng = 0;
14330
14331
    WOLFSSL_ENTER("wolfSSL_ECDSA_sign");
14332
14333
    /* Digest algorithm not used in DER encoding. */
14334
    (void)type;
14335
14336
    /* Validate parameters. */
14337
    if (key == NULL) {
14338
        ret = 0;
14339
    }
14340
14341
    if (ret == 1) {
14342
        /* Make an RNG - create local or get global. */
14343
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
14344
        if (rng == NULL) {
14345
            ret = 0;
14346
        }
14347
    }
14348
    /* Sign the digest with the key using the RNG and put signature into buffer
14349
     * update sigSz to be actual length.
14350
     */
14351
    if ((ret == 1) && (wc_ecc_sign_hash(digest, (word32)digestSz, sig, sigSz,
14352
            rng, (ecc_key*)key->internal) != 0)) {
14353
        ret = 0;
14354
    }
14355
14356
    if (initTmpRng) {
14357
        wc_FreeRng(rng);
14358
    #ifdef WOLFSSL_SMALL_STACK
14359
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
14360
    #endif
14361
    }
14362
14363
    return ret;
14364
}
14365
14366
/* Verify the signature with the digest and key.
14367
 *
14368
 * @param [in] type      Digest algorithm used to create digest. Unused.
14369
 * @param [in] digest    Digest of the message to verify.
14370
 * @param [in] digestSz  Size of the digest in bytes.
14371
 * @param [in] sig       Buffer holding signature.
14372
 * @param [in] sigSz     Size of signature data in bytes.
14373
 * @param [in] key       EC key containing public key.
14374
 * @return  1 when signature is valid.
14375
 * @return  0 when signature is invalid or error.
14376
 */
14377
int wolfSSL_ECDSA_verify(int type, const unsigned char *digest, int digestSz,
14378
    const unsigned char *sig, int sigSz, WOLFSSL_EC_KEY *key)
14379
{
14380
    int ret = 1;
14381
    int verify = 0;
14382
14383
    WOLFSSL_ENTER("wolfSSL_ECDSA_verify");
14384
14385
    /* Digest algorithm not used in DER encoding. */
14386
    (void)type;
14387
14388
    /* Validate parameters. */
14389
    if (key == NULL) {
14390
        ret = 0;
14391
    }
14392
14393
    /* Verify signature using digest and key. */
14394
    if ((ret == 1) && (wc_ecc_verify_hash(sig, (word32)sigSz, digest,
14395
            (word32)digestSz, &verify, (ecc_key*)key->internal) != 0)) {
14396
        ret = 0;
14397
    }
14398
    /* When no error, verification may still have failed - check now. */
14399
    if ((ret == 1) && (verify != 1)) {
14400
        WOLFSSL_MSG("wolfSSL_ECDSA_verify failed");
14401
        ret = 0;
14402
    }
14403
14404
    return ret;
14405
}
14406
14407
/* End ECDSA */
14408
14409
/* Start ECDH */
14410
14411
#ifndef WOLF_CRYPTO_CB_ONLY_ECC
14412
/* Compute the shared secret (key) using ECDH.
14413
 *
14414
 * KDF not supported.
14415
 *
14416
 * Return code compliant with OpenSSL.
14417
 *
14418
 * @param [out] out      Buffer to hold key.
14419
 * @param [in]  outLen   Length of buffer in bytes.
14420
 * @param [in]  pubKey   Public key as an EC point.
14421
 * @param [in]  privKey  EC key holding a private key.
14422
 * @param [in]  kdf      Key derivation function to apply to secret.
14423
 * @return  Length of computed key on success
14424
 * @return  0 on error.
14425
 */
14426
int wolfSSL_ECDH_compute_key(void *out, size_t outLen,
14427
    const WOLFSSL_EC_POINT *pubKey, WOLFSSL_EC_KEY *privKey,
14428
    void *(*kdf) (const void *in, size_t inlen, void *out, size_t *outLen))
14429
{
14430
    int err = 0;
14431
    word32 len = 0;
14432
    ecc_key* key = NULL;
14433
#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
14434
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
14435
    int setGlobalRNG = 0;
14436
#endif
14437
14438
    /* TODO: support using the KDF. */
14439
    (void)kdf;
14440
14441
    WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
14442
14443
    /* Validate parameters. */
14444
    if ((out == NULL) || (pubKey == NULL) || (pubKey->internal == NULL) ||
14445
        (privKey == NULL) || (privKey->internal == NULL)) {
14446
        WOLFSSL_MSG("Bad function arguments");
14447
        err = 1;
14448
    }
14449
14450
    /* Ensure internal EC key is set from external. */
14451
    if ((!err) && (privKey->inSet == 0)) {
14452
        WOLFSSL_MSG("No EC key internal set, do it");
14453
14454
        if (SetECKeyInternal(privKey) != 1) {
14455
            WOLFSSL_MSG("SetECKeyInternal failed");
14456
            err = 1;
14457
        }
14458
    }
14459
14460
    if (!err) {
14461
        int ret;
14462
14463
        /* Get the internal key. */
14464
        key = (ecc_key*)privKey->internal;
14465
        /* Set length into variable of type suitable for wolfSSL API. */
14466
        len = (word32)outLen;
14467
14468
    #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
14469
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
14470
        /* An RNG is needed. */
14471
        if (key->rng == NULL) {
14472
            key->rng = wolfssl_make_global_rng();
14473
            /* RNG set and needs to be unset. */
14474
            setGlobalRNG = 1;
14475
        }
14476
    #endif
14477
14478
        PRIVATE_KEY_UNLOCK();
14479
        /* Create secret using wolfSSL. */
14480
        ret = wc_ecc_shared_secret_ex(key, (ecc_point*)pubKey->internal,
14481
            (byte *)out, &len);
14482
        PRIVATE_KEY_LOCK();
14483
        if (ret != MP_OKAY) {
14484
            WOLFSSL_MSG("wc_ecc_shared_secret failed");
14485
            err = 1;
14486
        }
14487
    }
14488
14489
#if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \
14490
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0))
14491
    /* Remove global from key. */
14492
    if (setGlobalRNG) {
14493
        key->rng = NULL;
14494
    }
14495
#endif
14496
14497
    if (err) {
14498
        /* Make returned value zero. */
14499
        len = 0;
14500
    }
14501
    return (int)len;
14502
}
14503
#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
14504
14505
/* End ECDH */
14506
14507
#ifndef NO_WOLFSSL_STUB
14508
const WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_OpenSSL(void)
14509
{
14510
    WOLFSSL_STUB("wolfSSL_EC_KEY_OpenSSL");
14511
14512
    return NULL;
14513
}
14514
14515
WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_METHOD_new(
14516
        const WOLFSSL_EC_KEY_METHOD *meth)
14517
{
14518
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_new");
14519
14520
    (void)meth;
14521
14522
    return NULL;
14523
}
14524
14525
void wolfSSL_EC_KEY_METHOD_free(WOLFSSL_EC_KEY_METHOD *meth)
14526
{
14527
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_free");
14528
14529
    (void)meth;
14530
}
14531
14532
void wolfSSL_EC_KEY_METHOD_set_init(WOLFSSL_EC_KEY_METHOD *meth,
14533
        void* a1, void* a2, void* a3, void* a4, void* a5, void* a6)
14534
{
14535
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_set_init");
14536
14537
    (void)meth;
14538
    (void)a1;
14539
    (void)a2;
14540
    (void)a3;
14541
    (void)a4;
14542
    (void)a5;
14543
    (void)a6;
14544
}
14545
14546
void wolfSSL_EC_KEY_METHOD_set_sign(WOLFSSL_EC_KEY_METHOD *meth,
14547
        void* a1, void* a2, void* a3)
14548
{
14549
    WOLFSSL_STUB("wolfSSL_EC_KEY_METHOD_set_sign");
14550
14551
    (void)meth;
14552
    (void)a1;
14553
    (void)a2;
14554
    (void)a3;
14555
}
14556
14557
const WOLFSSL_EC_KEY_METHOD *wolfSSL_EC_KEY_get_method(
14558
        const WOLFSSL_EC_KEY *key)
14559
{
14560
    WOLFSSL_STUB("wolfSSL_EC_KEY_get_method");
14561
14562
    (void)key;
14563
14564
    return NULL;
14565
}
14566
14567
int wolfSSL_EC_KEY_set_method(WOLFSSL_EC_KEY *key,
14568
        const WOLFSSL_EC_KEY_METHOD *meth)
14569
{
14570
    WOLFSSL_STUB("wolfSSL_EC_KEY_set_method");
14571
14572
    (void)key;
14573
    (void)meth;
14574
14575
    return 0;
14576
}
14577
14578
#endif /* !NO_WOLFSSL_STUB */
14579
14580
#endif /* OPENSSL_EXTRA */
14581
14582
#endif /* HAVE_ECC */
14583
14584
/*******************************************************************************
14585
 * END OF EC API
14586
 ******************************************************************************/
14587
14588
/*******************************************************************************
14589
 * START OF EC25519 API
14590
 ******************************************************************************/
14591
14592
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
14593
14594
/* Generate an EC25519 key pair.
14595
 *
14596
 * Output keys are in little endian format.
14597
 *
14598
 * @param [out]     priv    EC25519 private key data.
14599
 * @param [in, out] privSz  On in, the size of priv in bytes.
14600
 *                          On out, the length of the private key data in bytes.
14601
 * @param [out]     pub     EC25519 public key data.
14602
 * @param [in, out] pubSz   On in, the size of pub in bytes.
14603
 *                          On out, the length of the public key data in bytes.
14604
 * @return  1 on success
14605
 * @return  0 on failure.
14606
 */
14607
int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
14608
    unsigned char *pub, unsigned int *pubSz)
14609
{
14610
#ifdef WOLFSSL_KEY_GEN
14611
    int res = 1;
14612
    int initTmpRng = 0;
14613
    WC_RNG *rng = NULL;
14614
#ifdef WOLFSSL_SMALL_STACK
14615
    WC_RNG *tmpRng = NULL;
14616
#else
14617
    WC_RNG tmpRng[1];
14618
#endif
14619
    curve25519_key key;
14620
14621
    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
14622
14623
    /* Validate parameters. */
14624
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE25519_KEYSIZE) ||
14625
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE25519_KEYSIZE)) {
14626
        WOLFSSL_MSG("Bad arguments");
14627
        res = 0;
14628
    }
14629
14630
    if (res) {
14631
        /* Create a random number generator. */
14632
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
14633
        if (rng == NULL) {
14634
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
14635
            res = 0;
14636
        }
14637
    }
14638
14639
    /* Initialize a Curve25519 key. */
14640
    if (res && (wc_curve25519_init(&key) != 0)) {
14641
        WOLFSSL_MSG("wc_curve25519_init failed");
14642
        res = 0;
14643
    }
14644
    if (res) {
14645
        /* Make a Curve25519 key pair. */
14646
        int ret = wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key);
14647
        if (ret != MP_OKAY) {
14648
            WOLFSSL_MSG("wc_curve25519_make_key failed");
14649
            res = 0;
14650
        }
14651
        if (res) {
14652
            /* Export Curve25519 key pair to buffers. */
14653
            ret = wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
14654
                pubSz, EC25519_LITTLE_ENDIAN);
14655
            if (ret != MP_OKAY) {
14656
                WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
14657
                res = 0;
14658
            }
14659
        }
14660
14661
        /* Dispose of key. */
14662
        wc_curve25519_free(&key);
14663
    }
14664
14665
    if (initTmpRng) {
14666
        wc_FreeRng(rng);
14667
    #ifdef WOLFSSL_SMALL_STACK
14668
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
14669
    #endif
14670
    }
14671
14672
    return res;
14673
#else
14674
    WOLFSSL_MSG("No Key Gen built in");
14675
14676
    (void)priv;
14677
    (void)privSz;
14678
    (void)pub;
14679
    (void)pubSz;
14680
14681
    return 0;
14682
#endif /* WOLFSSL_KEY_GEN */
14683
}
14684
14685
/* Compute a shared secret from private and public EC25519 keys.
14686
 *
14687
 * Input and output keys are in little endian format
14688
 *
14689
 * @param [out]     shared    Shared secret buffer.
14690
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
14691
 *                            On out, the length of the secret in bytes.
14692
 * @param [in]      priv      EC25519 private key data.
14693
 * @param [in]      privSz    Length of the private key data in bytes.
14694
 * @param [in]      pub       EC25519 public key data.
14695
 * @param [in]      pubSz     Length of the public key data in bytes.
14696
 * @return  1 on success
14697
 * @return  0 on failure.
14698
 */
14699
int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
14700
    const unsigned char *priv, unsigned int privSz, const unsigned char *pub,
14701
    unsigned int pubSz)
14702
{
14703
#ifdef WOLFSSL_KEY_GEN
14704
    int res = 1;
14705
    curve25519_key privkey;
14706
    curve25519_key pubkey;
14707
14708
    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
14709
14710
    /* Validate parameters. */
14711
    if ((shared == NULL) || (sharedSz == NULL) ||
14712
            (*sharedSz < CURVE25519_KEYSIZE) || (priv == NULL) ||
14713
            (privSz < CURVE25519_KEYSIZE) || (pub == NULL) ||
14714
            (pubSz < CURVE25519_KEYSIZE)) {
14715
        WOLFSSL_MSG("Bad arguments");
14716
        res = 0;
14717
    }
14718
14719
    /* Initialize private key object. */
14720
    if (res && (wc_curve25519_init(&privkey) != 0)) {
14721
        WOLFSSL_MSG("wc_curve25519_init privkey failed");
14722
        res = 0;
14723
    }
14724
    if (res) {
14725
    #ifdef WOLFSSL_CURVE25519_BLINDING
14726
        /* An RNG is needed. */
14727
        if (wc_curve25519_set_rng(&privkey, wolfssl_make_global_rng()) != 0) {
14728
            res = 0;
14729
        }
14730
        else
14731
    #endif
14732
        /* Initialize public key object. */
14733
        if (wc_curve25519_init(&pubkey) != MP_OKAY) {
14734
            WOLFSSL_MSG("wc_curve25519_init pubkey failed");
14735
            res = 0;
14736
        }
14737
        if (res) {
14738
            /* Import our private key. */
14739
            int ret = wc_curve25519_import_private_ex(priv, privSz, &privkey,
14740
                EC25519_LITTLE_ENDIAN);
14741
            if (ret != 0) {
14742
                WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
14743
                res = 0;
14744
            }
14745
14746
            if (res) {
14747
                /* Import peer's public key. */
14748
                ret = wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
14749
                    EC25519_LITTLE_ENDIAN);
14750
                if (ret != 0) {
14751
                    WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
14752
                    res = 0;
14753
                }
14754
            }
14755
            if (res) {
14756
                /* Compute shared secret. */
14757
                ret = wc_curve25519_shared_secret_ex(&privkey, &pubkey, shared,
14758
                    sharedSz, EC25519_LITTLE_ENDIAN);
14759
                if (ret != 0) {
14760
                    WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
14761
                    res = 0;
14762
                }
14763
            }
14764
14765
            wc_curve25519_free(&pubkey);
14766
        }
14767
        wc_curve25519_free(&privkey);
14768
    }
14769
14770
    return res;
14771
#else
14772
    WOLFSSL_MSG("No Key Gen built in");
14773
14774
    (void)shared;
14775
    (void)sharedSz;
14776
    (void)priv;
14777
    (void)privSz;
14778
    (void)pub;
14779
    (void)pubSz;
14780
14781
    return 0;
14782
#endif /* WOLFSSL_KEY_GEN */
14783
}
14784
#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
14785
14786
/*******************************************************************************
14787
 * END OF EC25519 API
14788
 ******************************************************************************/
14789
14790
/*******************************************************************************
14791
 * START OF ED25519 API
14792
 ******************************************************************************/
14793
14794
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
14795
/* Generate an ED25519 key pair.
14796
 *
14797
 * Output keys are in little endian format.
14798
 *
14799
 * @param [out]     priv    ED25519 private key data.
14800
 * @param [in, out] privSz  On in, the size of priv in bytes.
14801
 *                          On out, the length of the private key data in bytes.
14802
 * @param [out]     pub     ED25519 public key data.
14803
 * @param [in, out] pubSz   On in, the size of pub in bytes.
14804
 *                          On out, the length of the public key data in bytes.
14805
 * @return  1 on success
14806
 * @return  0 on failure.
14807
 */
14808
int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
14809
    unsigned char *pub, unsigned int *pubSz)
14810
{
14811
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED25519_KEY_EXPORT)
14812
    int res = 1;
14813
    int initTmpRng = 0;
14814
    WC_RNG *rng = NULL;
14815
#ifdef WOLFSSL_SMALL_STACK
14816
    WC_RNG *tmpRng = NULL;
14817
#else
14818
    WC_RNG tmpRng[1];
14819
#endif
14820
    ed25519_key key;
14821
14822
    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
14823
14824
    /* Validate parameters. */
14825
    if ((priv == NULL) || (privSz == NULL) ||
14826
            (*privSz < ED25519_PRV_KEY_SIZE) || (pub == NULL) ||
14827
            (pubSz == NULL) || (*pubSz < ED25519_PUB_KEY_SIZE)) {
14828
        WOLFSSL_MSG("Bad arguments");
14829
        res = 0;
14830
    }
14831
14832
    if (res) {
14833
        /* Create a random number generator. */
14834
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
14835
        if (rng == NULL) {
14836
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
14837
            res = 0;
14838
        }
14839
    }
14840
14841
    /* Initialize an Ed25519 key. */
14842
    if (res && (wc_ed25519_init(&key) != 0)) {
14843
        WOLFSSL_MSG("wc_ed25519_init failed");
14844
        res = 0;
14845
    }
14846
    if (res) {
14847
        /* Make an Ed25519 key pair. */
14848
        int ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key);
14849
        if (ret != 0) {
14850
            WOLFSSL_MSG("wc_ed25519_make_key failed");
14851
            res = 0;
14852
        }
14853
        if (res) {
14854
            /* Export Curve25519 key pair to buffers. */
14855
            ret = wc_ed25519_export_key(&key, priv, privSz, pub, pubSz);
14856
            if (ret != 0) {
14857
                WOLFSSL_MSG("wc_ed25519_export_key failed");
14858
                res = 0;
14859
            }
14860
        }
14861
14862
        wc_ed25519_free(&key);
14863
    }
14864
14865
    if (initTmpRng) {
14866
        wc_FreeRng(rng);
14867
    #ifdef WOLFSSL_SMALL_STACK
14868
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
14869
    #endif
14870
    }
14871
14872
    return res;
14873
#else
14874
#ifndef WOLFSSL_KEY_GEN
14875
    WOLFSSL_MSG("No Key Gen built in");
14876
#else
14877
    WOLFSSL_MSG("No ED25519 key export built in");
14878
#endif
14879
14880
    (void)priv;
14881
    (void)privSz;
14882
    (void)pub;
14883
    (void)pubSz;
14884
14885
    return 0;
14886
#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
14887
}
14888
14889
/* Sign a message with Ed25519 using the private key.
14890
 *
14891
 * Input and output keys are in little endian format.
14892
 * Priv is a buffer containing private and public part of key.
14893
 *
14894
 * @param [in]      msg     Message to be signed.
14895
 * @param [in]      msgSz   Length of message in bytes.
14896
 * @param [in]      priv    ED25519 private key data.
14897
 * @param [in]      privSz  Length in bytes of private key data.
14898
 * @param [out]     sig     Signature buffer.
14899
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
14900
 *                          On out, the length of the signature in bytes.
14901
 * @return  1 on success
14902
 * @return  0 on failure.
14903
 */
14904
int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
14905
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
14906
    unsigned int *sigSz)
14907
{
14908
#if defined(HAVE_ED25519_SIGN) && defined(WOLFSSL_KEY_GEN) && \
14909
    defined(HAVE_ED25519_KEY_IMPORT)
14910
    ed25519_key key;
14911
    int res = 1;
14912
14913
    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
14914
14915
    /* Validate parameters. */
14916
    if ((priv == NULL) || (privSz != ED25519_PRV_KEY_SIZE) ||
14917
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
14918
            (*sigSz < ED25519_SIG_SIZE)) {
14919
        WOLFSSL_MSG("Bad arguments");
14920
        res = 0;
14921
    }
14922
14923
    /* Initialize Ed25519 key. */
14924
    if (res && (wc_ed25519_init(&key) != 0)) {
14925
        WOLFSSL_MSG("wc_curve25519_init failed");
14926
        res = 0;
14927
    }
14928
    if (res) {
14929
        /* Import private and public key. */
14930
        int ret = wc_ed25519_import_private_key(priv, privSz / 2,
14931
            priv + (privSz / 2), ED25519_PUB_KEY_SIZE, &key);
14932
        if (ret != 0) {
14933
            WOLFSSL_MSG("wc_ed25519_import_private failed");
14934
            res = 0;
14935
        }
14936
14937
        if (res) {
14938
            /* Sign message with Ed25519. */
14939
            ret = wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key);
14940
            if (ret != 0) {
14941
                WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
14942
                res = 0;
14943
            }
14944
        }
14945
14946
        wc_ed25519_free(&key);
14947
    }
14948
14949
    return res;
14950
#else
14951
#if !defined(HAVE_ED25519_SIGN)
14952
    WOLFSSL_MSG("No ED25519 sign built in");
14953
#elif !defined(WOLFSSL_KEY_GEN)
14954
    WOLFSSL_MSG("No Key Gen built in");
14955
#elif !defined(HAVE_ED25519_KEY_IMPORT)
14956
    WOLFSSL_MSG("No ED25519 Key import built in");
14957
#endif
14958
14959
    (void)msg;
14960
    (void)msgSz;
14961
    (void)priv;
14962
    (void)privSz;
14963
    (void)sig;
14964
    (void)sigSz;
14965
14966
    return 0;
14967
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
14968
}
14969
14970
/* Verify a message with Ed25519 using the public key.
14971
 *
14972
 * Input keys are in little endian format.
14973
 *
14974
 * @param [in] msg     Message to be verified.
14975
 * @param [in] msgSz   Length of message in bytes.
14976
 * @param [in] pub     ED25519 public key data.
14977
 * @param [in] privSz  Length in bytes of public key data.
14978
 * @param [in] sig     Signature buffer.
14979
 * @param [in] sigSz   Length of the signature in bytes.
14980
 * @return  1 on success
14981
 * @return  0 on failure.
14982
 */
14983
int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
14984
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
14985
    unsigned int sigSz)
14986
{
14987
#if defined(HAVE_ED25519_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
14988
    defined(HAVE_ED25519_KEY_IMPORT)
14989
    ed25519_key key;
14990
    int res = 1;
14991
14992
    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
14993
14994
    /* Validate parameters. */
14995
    if ((pub == NULL) || (pubSz != ED25519_PUB_KEY_SIZE) || (msg == NULL) ||
14996
            (sig == NULL) || (sigSz != ED25519_SIG_SIZE)) {
14997
        WOLFSSL_MSG("Bad arguments");
14998
        res = 0;
14999
    }
15000
15001
    /* Initialize Ed25519 key. */
15002
    if (res && (wc_ed25519_init(&key) != 0)) {
15003
        WOLFSSL_MSG("wc_curve25519_init failed");
15004
        res = 0;
15005
    }
15006
    if (res) {
15007
        /* Import public key. */
15008
        int ret = wc_ed25519_import_public(pub, pubSz, &key);
15009
        if (ret != 0) {
15010
            WOLFSSL_MSG("wc_ed25519_import_public failed");
15011
            res = 0;
15012
        }
15013
15014
        if (res) {
15015
            int check = 0;
15016
15017
            /* Verify signature with message and public key. */
15018
            ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
15019
                &key);
15020
            /* Check for errors in verification process. */
15021
            if (ret != 0) {
15022
                WOLFSSL_MSG("wc_ed25519_verify_msg failed");
15023
                res = 0;
15024
            }
15025
            /* Check signature is valid. */
15026
            else if (!check) {
15027
                WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
15028
                res = 0;
15029
            }
15030
        }
15031
15032
        wc_ed25519_free(&key);
15033
    }
15034
15035
    return res;
15036
#else
15037
#if !defined(HAVE_ED25519_VERIFY)
15038
    WOLFSSL_MSG("No ED25519 verify built in");
15039
#elif !defined(WOLFSSL_KEY_GEN)
15040
    WOLFSSL_MSG("No Key Gen built in");
15041
#elif !defined(HAVE_ED25519_KEY_IMPORT)
15042
    WOLFSSL_MSG("No ED25519 Key import built in");
15043
#endif
15044
15045
    (void)msg;
15046
    (void)msgSz;
15047
    (void)pub;
15048
    (void)pubSz;
15049
    (void)sig;
15050
    (void)sigSz;
15051
15052
    return 0;
15053
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
15054
}
15055
15056
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
15057
15058
/*******************************************************************************
15059
 * END OF ED25519 API
15060
 ******************************************************************************/
15061
15062
/*******************************************************************************
15063
 * START OF EC448 API
15064
 ******************************************************************************/
15065
15066
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
15067
/* Generate an EC448 key pair.
15068
 *
15069
 * Output keys are in little endian format.
15070
 *
15071
 * @param [out]     priv    EC448 private key data.
15072
 * @param [in, out] privSz  On in, the size of priv in bytes.
15073
 *                          On out, the length of the private key data in bytes.
15074
 * @param [out]     pub     EC448 public key data.
15075
 * @param [in, out] pubSz   On in, the size of pub in bytes.
15076
 *                          On out, the length of the public key data in bytes.
15077
 * @return  1 on success
15078
 * @return  0 on failure.
15079
 */
15080
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
15081
                               unsigned char *pub, unsigned int *pubSz)
15082
{
15083
#ifdef WOLFSSL_KEY_GEN
15084
    int res = 1;
15085
    int initTmpRng = 0;
15086
    WC_RNG *rng = NULL;
15087
#ifdef WOLFSSL_SMALL_STACK
15088
    WC_RNG *tmpRng = NULL;
15089
#else
15090
    WC_RNG tmpRng[1];
15091
#endif
15092
    curve448_key key;
15093
15094
    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
15095
15096
    /* Validate parameters. */
15097
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE448_KEY_SIZE) ||
15098
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE448_KEY_SIZE)) {
15099
        WOLFSSL_MSG("Bad arguments");
15100
        res = 0;
15101
    }
15102
15103
    if (res) {
15104
        /* Create a random number generator. */
15105
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
15106
        if (rng == NULL) {
15107
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
15108
            res = 0;
15109
        }
15110
    }
15111
15112
    /* Initialize a Curve448 key. */
15113
    if (res && (wc_curve448_init(&key) != 0)) {
15114
        WOLFSSL_MSG("wc_curve448_init failed");
15115
        res = 0;
15116
    }
15117
    if (res) {
15118
        /* Make a Curve448 key pair. */
15119
        int ret = wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key);
15120
        if (ret != 0) {
15121
            WOLFSSL_MSG("wc_curve448_make_key failed");
15122
            res = 0;
15123
        }
15124
        if (res) {
15125
            /* Export Curve448 key pair to buffers. */
15126
            ret = wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
15127
                EC448_LITTLE_ENDIAN);
15128
            if (ret != 0) {
15129
                WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
15130
                res = 0;
15131
            }
15132
        }
15133
15134
        /* Dispose of key. */
15135
        wc_curve448_free(&key);
15136
    }
15137
15138
    if (initTmpRng) {
15139
        wc_FreeRng(rng);
15140
    #ifdef WOLFSSL_SMALL_STACK
15141
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
15142
    #endif
15143
    }
15144
15145
    return res;
15146
#else
15147
    WOLFSSL_MSG("No Key Gen built in");
15148
15149
    (void)priv;
15150
    (void)privSz;
15151
    (void)pub;
15152
    (void)pubSz;
15153
15154
    return 0;
15155
#endif /* WOLFSSL_KEY_GEN */
15156
}
15157
15158
/* Compute a shared secret from private and public EC448 keys.
15159
 *
15160
 * Input and output keys are in little endian format
15161
 *
15162
 * @param [out]     shared    Shared secret buffer.
15163
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
15164
 *                            On out, the length of the secret in bytes.
15165
 * @param [in]      priv      EC448 private key data.
15166
 * @param [in]      privSz    Length of the private key data in bytes.
15167
 * @param [in]      pub       EC448 public key data.
15168
 * @param [in]      pubSz     Length of the public key data in bytes.
15169
 * @return  1 on success
15170
 * @return  0 on failure.
15171
 */
15172
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
15173
                             const unsigned char *priv, unsigned int privSz,
15174
                             const unsigned char *pub, unsigned int pubSz)
15175
{
15176
#ifdef WOLFSSL_KEY_GEN
15177
    int res = 1;
15178
    curve448_key privkey;
15179
    curve448_key pubkey;
15180
15181
    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
15182
15183
    /* Validate parameters. */
15184
    if ((shared == NULL) || (sharedSz == NULL) ||
15185
            (*sharedSz < CURVE448_KEY_SIZE) || (priv == NULL) ||
15186
            (privSz < CURVE448_KEY_SIZE) || (pub == NULL) ||
15187
            (pubSz < CURVE448_KEY_SIZE)) {
15188
        WOLFSSL_MSG("Bad arguments");
15189
        res = 0;
15190
    }
15191
15192
    /* Initialize private key object. */
15193
    if (res && (wc_curve448_init(&privkey) != 0)) {
15194
        WOLFSSL_MSG("wc_curve448_init privkey failed");
15195
        res = 0;
15196
    }
15197
    if (res) {
15198
        /* Initialize public key object. */
15199
        if (wc_curve448_init(&pubkey) != MP_OKAY) {
15200
            WOLFSSL_MSG("wc_curve448_init pubkey failed");
15201
            res = 0;
15202
        }
15203
        if (res) {
15204
            /* Import our private key. */
15205
            int ret = wc_curve448_import_private_ex(priv, privSz, &privkey,
15206
                EC448_LITTLE_ENDIAN);
15207
            if (ret != 0) {
15208
                WOLFSSL_MSG("wc_curve448_import_private_ex failed");
15209
                res = 0;
15210
            }
15211
15212
            if (res) {
15213
                /* Import peer's public key. */
15214
                ret = wc_curve448_import_public_ex(pub, pubSz, &pubkey,
15215
                    EC448_LITTLE_ENDIAN);
15216
                if (ret != 0) {
15217
                    WOLFSSL_MSG("wc_curve448_import_public_ex failed");
15218
                    res = 0;
15219
                }
15220
            }
15221
            if (res) {
15222
                /* Compute shared secret. */
15223
                ret = wc_curve448_shared_secret_ex(&privkey, &pubkey, shared,
15224
                    sharedSz, EC448_LITTLE_ENDIAN);
15225
                if (ret != 0) {
15226
                    WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
15227
                    res = 0;
15228
                }
15229
            }
15230
15231
            wc_curve448_free(&pubkey);
15232
        }
15233
        wc_curve448_free(&privkey);
15234
    }
15235
15236
    return res;
15237
#else
15238
    WOLFSSL_MSG("No Key Gen built in");
15239
15240
    (void)shared;
15241
    (void)sharedSz;
15242
    (void)priv;
15243
    (void)privSz;
15244
    (void)pub;
15245
    (void)pubSz;
15246
15247
    return 0;
15248
#endif /* WOLFSSL_KEY_GEN */
15249
}
15250
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
15251
15252
/*******************************************************************************
15253
 * END OF EC448 API
15254
 ******************************************************************************/
15255
15256
/*******************************************************************************
15257
 * START OF ED448 API
15258
 ******************************************************************************/
15259
15260
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
15261
/* Generate an ED448 key pair.
15262
 *
15263
 * Output keys are in little endian format.
15264
 *
15265
 * @param [out]     priv    ED448 private key data.
15266
 * @param [in, out] privSz  On in, the size of priv in bytes.
15267
 *                          On out, the length of the private key data in bytes.
15268
 * @param [out]     pub     ED448 public key data.
15269
 * @param [in, out] pubSz   On in, the size of pub in bytes.
15270
 *                          On out, the length of the public key data in bytes.
15271
 * @return  1 on success
15272
 * @return  0 on failure.
15273
 */
15274
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
15275
    unsigned char *pub, unsigned int *pubSz)
15276
{
15277
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED448_KEY_EXPORT)
15278
    int res = 1;
15279
    int initTmpRng = 0;
15280
    WC_RNG *rng = NULL;
15281
#ifdef WOLFSSL_SMALL_STACK
15282
    WC_RNG *tmpRng = NULL;
15283
#else
15284
    WC_RNG tmpRng[1];
15285
#endif
15286
    ed448_key key;
15287
15288
    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
15289
15290
    /* Validate parameters. */
15291
    if ((priv == NULL) || (privSz == NULL) ||
15292
            (*privSz < ED448_PRV_KEY_SIZE) || (pub == NULL) ||
15293
            (pubSz == NULL) || (*pubSz < ED448_PUB_KEY_SIZE)) {
15294
        WOLFSSL_MSG("Bad arguments");
15295
        res = 0;
15296
    }
15297
15298
    if (res) {
15299
        /* Create a random number generator. */
15300
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
15301
        if (rng == NULL) {
15302
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
15303
            res = 0;
15304
        }
15305
    }
15306
15307
    /* Initialize an Ed448 key. */
15308
    if (res && (wc_ed448_init(&key) != 0)) {
15309
        WOLFSSL_MSG("wc_ed448_init failed");
15310
        res = 0;
15311
    }
15312
    if (res) {
15313
        /* Make an Ed448 key pair. */
15314
        int ret = wc_ed448_make_key(rng, ED448_KEY_SIZE, &key);
15315
        if (ret != 0) {
15316
            WOLFSSL_MSG("wc_ed448_make_key failed");
15317
            res = 0;
15318
        }
15319
        if (res) {
15320
            /* Export Curve448 key pair to buffers. */
15321
            ret = wc_ed448_export_key(&key, priv, privSz, pub, pubSz);
15322
            if (ret != 0) {
15323
                WOLFSSL_MSG("wc_ed448_export_key failed");
15324
                res = 0;
15325
            }
15326
        }
15327
15328
        wc_ed448_free(&key);
15329
    }
15330
15331
    if (initTmpRng) {
15332
        wc_FreeRng(rng);
15333
    #ifdef WOLFSSL_SMALL_STACK
15334
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
15335
    #endif
15336
    }
15337
15338
    return res;
15339
#else
15340
#ifndef WOLFSSL_KEY_GEN
15341
    WOLFSSL_MSG("No Key Gen built in");
15342
#else
15343
    WOLFSSL_MSG("No ED448 key export built in");
15344
#endif
15345
15346
    (void)priv;
15347
    (void)privSz;
15348
    (void)pub;
15349
    (void)pubSz;
15350
15351
    return 0;
15352
#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
15353
}
15354
15355
/* Sign a message with Ed448 using the private key.
15356
 *
15357
 * Input and output keys are in little endian format.
15358
 * Priv is a buffer containing private and public part of key.
15359
 *
15360
 * @param [in]      msg     Message to be signed.
15361
 * @param [in]      msgSz   Length of message in bytes.
15362
 * @param [in]      priv    ED448 private key data.
15363
 * @param [in]      privSz  Length in bytes of private key data.
15364
 * @param [out]     sig     Signature buffer.
15365
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
15366
 *                          On out, the length of the signature in bytes.
15367
 * @return  1 on success
15368
 * @return  0 on failure.
15369
 */
15370
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
15371
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
15372
    unsigned int *sigSz)
15373
{
15374
#if defined(HAVE_ED448_SIGN) && defined(WOLFSSL_KEY_GEN) && \
15375
    defined(HAVE_ED448_KEY_IMPORT)
15376
    ed448_key key;
15377
    int res = 1;
15378
15379
    WOLFSSL_ENTER("wolfSSL_ED448_sign");
15380
15381
    /* Validate parameters. */
15382
    if ((priv == NULL) || (privSz != ED448_PRV_KEY_SIZE) ||
15383
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
15384
            (*sigSz < ED448_SIG_SIZE)) {
15385
        WOLFSSL_MSG("Bad arguments");
15386
        res = 0;
15387
    }
15388
15389
    /* Initialize Ed448 key. */
15390
    if (res && (wc_ed448_init(&key) != 0)) {
15391
        WOLFSSL_MSG("wc_curve448_init failed");
15392
        res = 0;
15393
    }
15394
    if (res) {
15395
        /* Import private and public key. */
15396
        int ret = wc_ed448_import_private_key(priv, privSz / 2,
15397
            priv + (privSz / 2), ED448_PUB_KEY_SIZE, &key);
15398
        if (ret != 0) {
15399
            WOLFSSL_MSG("wc_ed448_import_private failed");
15400
            res = 0;
15401
        }
15402
15403
        if (res) {
15404
            /* Sign message with Ed448 - no context. */
15405
            ret = wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0);
15406
            if (ret != 0) {
15407
                WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
15408
                res = 0;
15409
            }
15410
        }
15411
15412
        wc_ed448_free(&key);
15413
    }
15414
15415
    return res;
15416
#else
15417
#if !defined(HAVE_ED448_SIGN)
15418
    WOLFSSL_MSG("No ED448 sign built in");
15419
#elif !defined(WOLFSSL_KEY_GEN)
15420
    WOLFSSL_MSG("No Key Gen built in");
15421
#elif !defined(HAVE_ED448_KEY_IMPORT)
15422
    WOLFSSL_MSG("No ED448 Key import built in");
15423
#endif
15424
15425
    (void)msg;
15426
    (void)msgSz;
15427
    (void)priv;
15428
    (void)privSz;
15429
    (void)sig;
15430
    (void)sigSz;
15431
15432
    return 0;
15433
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
15434
}
15435
15436
/* Verify a message with Ed448 using the public key.
15437
 *
15438
 * Input keys are in little endian format.
15439
 *
15440
 * @param [in] msg     Message to be verified.
15441
 * @param [in] msgSz   Length of message in bytes.
15442
 * @param [in] pub     ED448 public key data.
15443
 * @param [in] privSz  Length in bytes of public key data.
15444
 * @param [in] sig     Signature buffer.
15445
 * @param [in] sigSz   Length of the signature in bytes.
15446
 * @return  1 on success
15447
 * @return  0 on failure.
15448
 */
15449
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
15450
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
15451
    unsigned int sigSz)
15452
{
15453
#if defined(HAVE_ED448_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
15454
    defined(HAVE_ED448_KEY_IMPORT)
15455
    ed448_key key;
15456
    int res = 1;
15457
15458
    WOLFSSL_ENTER("wolfSSL_ED448_verify");
15459
15460
    /* Validate parameters. */
15461
    if ((pub == NULL) || (pubSz != ED448_PUB_KEY_SIZE) || (msg == NULL) ||
15462
            (sig == NULL) || (sigSz != ED448_SIG_SIZE)) {
15463
        WOLFSSL_MSG("Bad arguments");
15464
        res = 0;
15465
    }
15466
15467
    /* Initialize Ed448 key. */
15468
    if (res && (wc_ed448_init(&key) != 0)) {
15469
        WOLFSSL_MSG("wc_curve448_init failed");
15470
        res = 0;
15471
    }
15472
    if (res) {
15473
        /* Import public key. */
15474
        int ret = wc_ed448_import_public(pub, pubSz, &key);
15475
        if (ret != 0) {
15476
            WOLFSSL_MSG("wc_ed448_import_public failed");
15477
            res = 0;
15478
        }
15479
15480
        if (res) {
15481
            int check = 0;
15482
15483
            /* Verify signature with message and public key - no context. */
15484
            ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
15485
                &key, NULL, 0);
15486
            /* Check for errors in verification process. */
15487
            if (ret != 0) {
15488
                WOLFSSL_MSG("wc_ed448_verify_msg failed");
15489
                res = 0;
15490
            }
15491
            /* Check signature is valid. */
15492
            else if (!check) {
15493
                WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
15494
                res = 0;
15495
            }
15496
        }
15497
15498
        wc_ed448_free(&key);
15499
    }
15500
15501
    return res;
15502
#else
15503
#if !defined(HAVE_ED448_VERIFY)
15504
    WOLFSSL_MSG("No ED448 verify built in");
15505
#elif !defined(WOLFSSL_KEY_GEN)
15506
    WOLFSSL_MSG("No Key Gen built in");
15507
#elif !defined(HAVE_ED448_KEY_IMPORT)
15508
    WOLFSSL_MSG("No ED448 Key import built in");
15509
#endif
15510
15511
    (void)msg;
15512
    (void)msgSz;
15513
    (void)pub;
15514
    (void)pubSz;
15515
    (void)sig;
15516
    (void)sigSz;
15517
15518
    return 0;
15519
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
15520
}
15521
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
15522
15523
/*******************************************************************************
15524
 * END OF ED448 API
15525
 ******************************************************************************/
15526
15527
/*******************************************************************************
15528
 * START OF GENERIC PUBLIC KEY PEM APIs
15529
 ******************************************************************************/
15530
15531
#ifdef OPENSSL_EXTRA
15532
/* Sets default callback password for PEM.
15533
 *
15534
 * @param [out] buf       Buffer to hold password.
15535
 * @param [in]  num       Number of characters in buffer.
15536
 * @param [in]  rwFlag    Read/write flag. Ignored.
15537
 * @param [in]  userData  User data - assumed to be default password.
15538
 * @return  Password size on success.
15539
 * @return  0 on failure.
15540
 */
15541
int wolfSSL_PEM_def_callback(char* buf, int num, int rwFlag, void* userData)
15542
{
15543
    int sz = 0;
15544
15545
    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
15546
15547
    (void)rwFlag;
15548
15549
    /* We assume that the user passes a default password as userdata */
15550
    if ((buf != NULL) && (userData != NULL)) {
15551
        sz = (int)XSTRLEN((const char*)userData);
15552
        sz = (int)min((word32)sz, (word32)num);
15553
        XMEMCPY(buf, userData, (size_t)sz);
15554
    }
15555
    else {
15556
        WOLFSSL_MSG("Error, default password cannot be created.");
15557
    }
15558
15559
    return sz;
15560
}
15561
15562
#ifndef NO_BIO
15563
/* Writes a public key to a WOLFSSL_BIO encoded in PEM format.
15564
 *
15565
 * @param [in] bio  BIO to write to.
15566
 * @param [in] key  Public key to write in PEM format.
15567
 * @return  1 on success.
15568
 * @return  0 on failure.
15569
 */
15570
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
15571
{
15572
    int ret = 0;
15573
15574
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
15575
15576
    if ((bio != NULL) && (key != NULL)) {
15577
        switch (key->type) {
15578
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
15579
            case WC_EVP_PKEY_RSA:
15580
                ret = wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key->rsa);
15581
                break;
15582
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
15583
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
15584
    (defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN))
15585
            case WC_EVP_PKEY_DSA:
15586
                ret = wolfSSL_PEM_write_bio_DSA_PUBKEY(bio, key->dsa);
15587
                break;
15588
#endif /* !NO_DSA && !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
15589
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
15590
    defined(WOLFSSL_KEY_GEN)
15591
            case WC_EVP_PKEY_EC:
15592
                ret = wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key->ecc);
15593
                break;
15594
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
15595
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
15596
            case WC_EVP_PKEY_DH:
15597
                /* DH public key not supported. */
15598
                WOLFSSL_MSG("Writing DH PUBKEY not supported!");
15599
                break;
15600
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
15601
            default:
15602
                /* Key type not supported. */
15603
                WOLFSSL_MSG("Unknown Key type!");
15604
                break;
15605
        }
15606
    }
15607
15608
    return ret;
15609
}
15610
15611
/* Writes a private key to a WOLFSSL_BIO encoded in PEM format.
15612
 *
15613
 * @param [in] bio     BIO to write to.
15614
 * @param [in] key     Public key to write in PEM format.
15615
 * @param [in] cipher  Encryption cipher to use.
15616
 * @param [in] passwd  Password to use when encrypting.
15617
 * @param [in] len     Length of password.
15618
 * @param [in] cb      Password callback.
15619
 * @param [in] arg     Password callback argument.
15620
 * @return  1 on success.
15621
 * @return  0 on failure.
15622
 */
15623
int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
15624
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
15625
    wc_pem_password_cb* cb, void* arg)
15626
{
15627
    int ret = 1;
15628
15629
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
15630
15631
    (void)cipher;
15632
    (void)passwd;
15633
    (void)len;
15634
    (void)cb;
15635
    (void)arg;
15636
15637
    /* Validate parameters. */
15638
    if ((bio == NULL) || (key == NULL)) {
15639
        WOLFSSL_MSG("Bad Function Arguments");
15640
        ret = 0;
15641
    }
15642
15643
    if (ret == 1) {
15644
    #ifdef WOLFSSL_KEY_GEN
15645
        switch (key->type) {
15646
        #ifndef NO_RSA
15647
            case WC_EVP_PKEY_RSA:
15648
                /* Write using RSA specific API. */
15649
                ret = wolfSSL_PEM_write_bio_RSAPrivateKey(bio, key->rsa,
15650
                    cipher, passwd, len, cb, arg);
15651
                break;
15652
        #endif
15653
        #ifndef NO_DSA
15654
            case WC_EVP_PKEY_DSA:
15655
                /* Write using DSA specific API. */
15656
                ret = wolfSSL_PEM_write_bio_DSAPrivateKey(bio, key->dsa,
15657
                    cipher, passwd, len, cb, arg);
15658
                break;
15659
        #endif
15660
        #ifdef HAVE_ECC
15661
            case WC_EVP_PKEY_EC:
15662
            #if defined(HAVE_ECC_KEY_EXPORT)
15663
                /* Write using EC specific API. */
15664
                ret = wolfSSL_PEM_write_bio_ECPrivateKey(bio, key->ecc,
15665
                    cipher, passwd, len, cb, arg);
15666
            #else
15667
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
15668
                    key->pkey_sz, bio, EC_PRIVATEKEY_TYPE);
15669
            #endif
15670
                break;
15671
        #endif
15672
        #ifndef NO_DH
15673
            case WC_EVP_PKEY_DH:
15674
                /* Write using generic API with DH type. */
15675
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
15676
                    key->pkey_sz, bio, DH_PRIVATEKEY_TYPE);
15677
                break;
15678
        #endif
15679
            default:
15680
                WOLFSSL_MSG("Unknown Key type!");
15681
                ret = 0;
15682
                break;
15683
        }
15684
    #else
15685
        int type = 0;
15686
15687
        switch (key->type) {
15688
        #ifndef NO_DSA
15689
            case WC_EVP_PKEY_DSA:
15690
                type = DSA_PRIVATEKEY_TYPE;
15691
                break;
15692
        #endif
15693
        #ifdef HAVE_ECC
15694
            case WC_EVP_PKEY_EC:
15695
                type = ECC_PRIVATEKEY_TYPE;
15696
                break;
15697
        #endif
15698
        #ifndef NO_DH
15699
            case WC_EVP_PKEY_DH:
15700
                type = DH_PRIVATEKEY_TYPE;
15701
                break;
15702
        #endif
15703
        #ifndef NO_RSA
15704
            case WC_EVP_PKEY_RSA:
15705
                type = PRIVATEKEY_TYPE;
15706
                break;
15707
        #endif
15708
            default:
15709
                ret = 0;
15710
                break;
15711
        }
15712
        if (ret == 1) {
15713
            /* Write using generic API with generic type. */
15714
            ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr, key->pkey_sz,
15715
                bio, type);
15716
        }
15717
    #endif
15718
    }
15719
15720
    return ret;
15721
}
15722
#endif /* !NO_BIO */
15723
15724
#ifndef NO_BIO
15725
/* Create a private key object from the data in the BIO.
15726
 *
15727
 * @param [in]      bio   BIO to read from.
15728
 * @param [in, out] key   Public key object. Object used if passed in.
15729
 * @param [in]      cb    Password callback.
15730
 * @param [in]      arg   Password callback argument.
15731
 * @return  A WOLFSSL_EVP_PKEY object on success.
15732
 * @return  NULL on failure.
15733
 */
15734
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
15735
    WOLFSSL_EVP_PKEY **key, wc_pem_password_cb *cb, void *arg)
15736
{
15737
    int err = 0;
15738
    WOLFSSL_EVP_PKEY* pkey = NULL;
15739
    DerBuffer* der = NULL;
15740
15741
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
15742
15743
    if (bio == NULL) {
15744
        err = 1;
15745
    }
15746
15747
    /* Read the PEM public key from the BIO and convert to DER. */
15748
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PUBLICKEY_TYPE, NULL,
15749
            &der) < 0)) {
15750
        err = 1;
15751
    }
15752
15753
    if (!err) {
15754
        const unsigned char* ptr = der->buffer;
15755
15756
        /* Use key passed in if set. */
15757
        if ((key != NULL) && (*key != NULL)) {
15758
            pkey = *key;
15759
        }
15760
15761
        /* Convert DER data to a public key object. */
15762
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
15763
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15764
            pkey = NULL;
15765
            err = 1;
15766
        }
15767
    }
15768
15769
    /* Return the key if possible. */
15770
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15771
        *key = pkey;
15772
    }
15773
    /* Dispose of the DER encoding. */
15774
    FreeDer(&der);
15775
15776
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
15777
15778
    return pkey;
15779
}
15780
15781
/* Create a private key object from the data in the BIO.
15782
 *
15783
 * @param [in]      bio   BIO to read from.
15784
 * @param [in, out] key   Private key object. Object used if passed in.
15785
 * @param [in]      cb    Password callback.
15786
 * @param [in]      arg   Password callback argument.
15787
 * @return  A WOLFSSL_EVP_PKEY object on success.
15788
 * @return  NULL on failure.
15789
 */
15790
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
15791
    WOLFSSL_EVP_PKEY** key, wc_pem_password_cb* cb, void* arg)
15792
{
15793
    int err = 0;
15794
    WOLFSSL_EVP_PKEY* pkey = NULL;
15795
    DerBuffer* der = NULL;
15796
    int keyFormat = 0;
15797
15798
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
15799
15800
    /* Validate parameters. */
15801
    if (bio == NULL) {
15802
        err = 1;
15803
    }
15804
15805
    /* Read the PEM private key from the BIO and convert to DER. */
15806
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
15807
            &der) < 0)) {
15808
        err = 1;
15809
    }
15810
15811
    if (!err) {
15812
        const unsigned char* ptr = der->buffer;
15813
        int type;
15814
15815
        /* Set key type based on format returned. */
15816
        switch (keyFormat) {
15817
            /* No key format set - default to RSA. */
15818
            case 0:
15819
            case RSAk:
15820
                type = WC_EVP_PKEY_RSA;
15821
                break;
15822
            case DSAk:
15823
                type = WC_EVP_PKEY_DSA;
15824
                break;
15825
            case ECDSAk:
15826
                type = WC_EVP_PKEY_EC;
15827
                break;
15828
            case DHk:
15829
                type = WC_EVP_PKEY_DH;
15830
                break;
15831
            default:
15832
                type = WOLFSSL_FATAL_ERROR;
15833
                break;
15834
        }
15835
15836
        /* Use key passed in if set. */
15837
        if ((key != NULL) && (*key != NULL)) {
15838
            pkey = *key;
15839
        }
15840
15841
        /* Convert DER data to a private key object. */
15842
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
15843
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15844
            pkey = NULL;
15845
            err = 1;
15846
        }
15847
    }
15848
15849
    /* Return the key if possible. */
15850
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15851
        *key = pkey;
15852
    }
15853
    /* Dispose of the DER encoding. */
15854
    FreeDer(&der);
15855
15856
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", err);
15857
15858
    return pkey;
15859
}
15860
15861
15862
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(
15863
    WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb,
15864
    void* arg)
15865
{
15866
    return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
15867
}
15868
#endif /* !NO_BIO */
15869
15870
#if !defined(NO_FILESYSTEM)
15871
/* Create a private key object from the data in a file.
15872
 *
15873
 * @param [in]      fp    File pointer.
15874
 * @param [in, out] key   Public key object. Object used if passed in.
15875
 * @param [in]      cb    Password callback.
15876
 * @param [in]      arg   Password callback argument.
15877
 * @return  A WOLFSSL_EVP_PKEY object on success.
15878
 * @return  NULL on failure.
15879
 */
15880
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **key,
15881
    wc_pem_password_cb *cb, void *arg)
15882
{
15883
    int err = 0;
15884
    WOLFSSL_EVP_PKEY* pkey = NULL;
15885
    DerBuffer* der = NULL;
15886
15887
    WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
15888
15889
    /* Validate parameters. */
15890
    if (fp == XBADFILE) {
15891
        err = 1;
15892
    }
15893
15894
    /* Read the PEM public key from the file and convert to DER. */
15895
    if ((!err) && ((pem_read_file_key(fp, cb, arg, PUBLICKEY_TYPE, NULL,
15896
            &der) < 0) || (der == NULL))) {
15897
        err = 1;
15898
    }
15899
    if (!err) {
15900
        const unsigned char* ptr = der->buffer;
15901
15902
        /* Use key passed in if set. */
15903
        if ((key != NULL) && (*key != NULL)) {
15904
            pkey = *key;
15905
        }
15906
15907
        /* Convert DER data to a public key object. */
15908
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
15909
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15910
            pkey = NULL;
15911
            err = 1;
15912
        }
15913
    }
15914
15915
    /* Return the key if possible. */
15916
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15917
        *key = pkey;
15918
    }
15919
    /* Dispose of the DER encoding. */
15920
    FreeDer(&der);
15921
15922
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
15923
15924
    return pkey;
15925
}
15926
15927
#ifndef NO_CERTS
15928
/* Create a private key object from the data in a file.
15929
 *
15930
 * @param [in]      fp    File pointer.
15931
 * @param [in, out] key   Private key object. Object used if passed in.
15932
 * @param [in]      cb    Password callback.
15933
 * @param [in]      arg   Password callback argument.
15934
 * @return  A WOLFSSL_EVP_PKEY object on success.
15935
 * @return  NULL on failure.
15936
 */
15937
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
15938
    wc_pem_password_cb *cb, void *arg)
15939
{
15940
    int err = 0;
15941
    WOLFSSL_EVP_PKEY* pkey = NULL;
15942
    DerBuffer* der = NULL;
15943
    int keyFormat = 0;
15944
15945
    WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
15946
15947
    /* Validate parameters. */
15948
    if (fp == XBADFILE) {
15949
        err = 1;
15950
    }
15951
15952
    /* Read the PEM private key from the file and convert to DER. */
15953
    if ((!err) && (pem_read_file_key(fp, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
15954
            &der)) < 0) {
15955
        err = 1;
15956
    }
15957
15958
    if (!err) {
15959
        const unsigned char* ptr = der->buffer;
15960
        int type;
15961
15962
        /* Set key type based on format returned. */
15963
        switch (keyFormat) {
15964
            /* No key format set - default to RSA. */
15965
            case 0:
15966
            case RSAk:
15967
                type = WC_EVP_PKEY_RSA;
15968
                break;
15969
            case DSAk:
15970
                type = WC_EVP_PKEY_DSA;
15971
                break;
15972
            case ECDSAk:
15973
                type = WC_EVP_PKEY_EC;
15974
                break;
15975
            case DHk:
15976
                type = WC_EVP_PKEY_DH;
15977
                break;
15978
            default:
15979
                type = WOLFSSL_FATAL_ERROR;
15980
                break;
15981
        }
15982
15983
        /* Use key passed in if set. */
15984
        if ((key != NULL) && (*key != NULL)) {
15985
            pkey = *key;
15986
        }
15987
15988
        /* Convert DER data to a private key object. */
15989
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
15990
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
15991
            pkey = NULL;
15992
            err = 1;
15993
        }
15994
    }
15995
15996
    /* Return the key if possible. */
15997
    if ((!err) && (key != NULL) && (pkey != NULL)) {
15998
        *key = pkey;
15999
    }
16000
    /* Dispose of the DER encoding. */
16001
    FreeDer(&der);
16002
16003
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PrivateKey", 0);
16004
16005
    return pkey;
16006
}
16007
#endif /* !NO_CERTS */
16008
#endif /* !NO_FILESYSTEM */
16009
16010
#ifndef NO_CERTS
16011
16012
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
16013
#define PEM_BEGIN              "-----BEGIN "
16014
#define PEM_BEGIN_SZ           11
16015
#define PEM_END                "-----END "
16016
#define PEM_END_SZ             9
16017
#define PEM_HDR_FIN            "-----"
16018
#define PEM_HDR_FIN_SZ         5
16019
#define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
16020
#define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
16021
#define PEM_HDR_FIN_EOL_SZ     6
16022
16023
/* Find strings and return middle offsets.
16024
 *
16025
 * Find first string in pem as a prefix and then locate second string as a
16026
 * postfix.
16027
 * len returning with 0 indicates not found.
16028
 *
16029
 * @param [in]  pem      PEM data.
16030
 * @param [in]  pemLen   Length of PEM data.
16031
 * @param [in]  idx      Current index.
16032
 * @param [in]  prefix   First string to find.
16033
 * @param [in]  postfix  Second string to find after first.
16034
 * @param [out] start    Start index of data between strings.
16035
 * @param [out] len      Length of data between strings.
16036
 */
16037
static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,
16038
    const char* postfix, int* start, int* len)
16039
{
16040
    int prefixLen = (int)XSTRLEN(prefix);
16041
    int postfixLen = (int)XSTRLEN(postfix);
16042
16043
    *start = *len = 0;
16044
    /* Find prefix part. */
16045
    for (; idx < pemLen - prefixLen; idx++) {
16046
        if ((pem[idx] == prefix[0]) &&
16047
                (XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) {
16048
            idx += prefixLen;
16049
            *start = idx;
16050
            break;
16051
        }
16052
    }
16053
    /* Find postfix part. */
16054
    for (; idx < pemLen - postfixLen; idx++) {
16055
        if ((pem[idx] == postfix[0]) &&
16056
                (XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) {
16057
            *len = idx - *start;
16058
            break;
16059
        }
16060
    }
16061
}
16062
16063
/* Parse out content type name, any encryption headers and DER encoding.
16064
 *
16065
 * @param [in]  pem     PEM data.
16066
 * @param [in]  pemLen  Length of PEM data.
16067
 * @param [out] name    Name of content type.
16068
 * @param [out] header  Encryption headers.
16069
 * @param [out] data    DER encoding from PEM.
16070
 * @param [out] len     Length of DER data.
16071
 * @return  0 on success.
16072
 * @return  MEMORY_E when dynamic memory allocation fails.
16073
 * @return  ASN_NO_PEM_HEADER when no header found or different names found.
16074
 */
16075
static int pem_read_data(char* pem, int pemLen, char **name, char **header,
16076
    unsigned char **data, long *len)
16077
{
16078
    int ret = 0;
16079
    int start;
16080
    int nameLen;
16081
    int startHdr = 0;
16082
    int hdrLen = 0;
16083
    int startEnd = 0;
16084
    int endLen;
16085
16086
    *name = NULL;
16087
    *header = NULL;
16088
16089
    /* Find header. */
16090
    pem_find_pattern(pem, pemLen, 0, PEM_BEGIN, PEM_HDR_FIN, &start, &nameLen);
16091
    /* Allocate memory for header name. */
16092
    *name = (char*)XMALLOC((size_t)nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16093
    if (*name == NULL) {
16094
        ret = MEMORY_E;
16095
    }
16096
    if (ret == 0) {
16097
        /* Put in header name. */
16098
        (*name)[nameLen] = '\0';
16099
        if (nameLen == 0) {
16100
            ret = ASN_NO_PEM_HEADER;
16101
        }
16102
        else {
16103
            XMEMCPY(*name, pem + start, (size_t)nameLen);
16104
        }
16105
    }
16106
    if (ret == 0) {
16107
        /* Find encryption headers after header. */
16108
        start += nameLen + PEM_HDR_FIN_SZ;
16109
        pem_find_pattern(pem, pemLen, start, "\n", "\n\n", &startHdr, &hdrLen);
16110
        if (hdrLen > 0) {
16111
            /* Include first of two '\n' characters. */
16112
            hdrLen++;
16113
        }
16114
        /* Allocate memory for encryption header string. */
16115
        *header = (char*)XMALLOC((size_t)hdrLen + 1, NULL,
16116
                                    DYNAMIC_TYPE_TMP_BUFFER);
16117
        if (*header == NULL) {
16118
            ret = MEMORY_E;
16119
        }
16120
    }
16121
    if (ret == 0) {
16122
        /* Put in encryption header string. */
16123
        (*header)[hdrLen] = '\0';
16124
        if (hdrLen > 0) {
16125
            XMEMCPY(*header, pem + startHdr, (size_t)hdrLen);
16126
            start = startHdr + hdrLen + 1;
16127
        }
16128
16129
        /* Find footer. */
16130
        pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
16131
            &endLen);
16132
        /* Validate header name and footer name are the same. */
16133
        if ((endLen != nameLen) ||
16134
                 (XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
16135
            ret = ASN_NO_PEM_HEADER;
16136
        }
16137
    }
16138
    if (ret == 0) {
16139
        unsigned char* der = (unsigned char*)pem;
16140
        word32 derLen;
16141
16142
        /* Convert PEM body to DER. */
16143
        derLen = (word32)(startEnd - PEM_END_SZ - start);
16144
        ret = Base64_Decode(der + start, derLen, der, &derLen);
16145
        if (ret == 0) {
16146
            /* Return the DER data. */
16147
            *data = der;
16148
            *len = derLen;
16149
        }
16150
    }
16151
16152
    return ret;
16153
}
16154
16155
/* Encode the DER data in PEM format into a newly allocated buffer.
16156
 *
16157
 * @param [in]  name       Header/footer name.
16158
 * @param [in]  header     Encryption header.
16159
 * @param [in]  data       DER data.
16160
 * @param [in]  len        Length of DER data.
16161
 * @param [out] pemOut     PEM encoded data.
16162
 * @param [out] pemOutLen  Length of PEM encoded data.
16163
 * @return  0 on success.
16164
 * @return  MEMORY_E when dynamic memory allocation fails.
16165
 */
16166
static int pem_write_data(const char *name, const char *header,
16167
    const unsigned char *data, long len, char** pemOut, word32* pemOutLen)
16168
{
16169
    int ret = 0;
16170
    int nameLen;
16171
    int headerLen;
16172
    char* pem = NULL;
16173
    word32 pemLen;
16174
    word32 derLen = (word32)len;
16175
    byte* p;
16176
16177
    nameLen = (int)XSTRLEN(name);
16178
    headerLen = (int)XSTRLEN(header);
16179
16180
    /* DER encode for PEM. */
16181
    pemLen  = (derLen + 2) / 3 * 4;
16182
    pemLen += (pemLen + 63) / 64;
16183
    /* Header */
16184
    pemLen += (word32)(PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
16185
    if (headerLen > 0) {
16186
        /* Encryption lines plus extra carriage return. */
16187
        pemLen += (word32)headerLen + 1;
16188
    }
16189
    /* Trailer */
16190
    pemLen += (word32)(PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
16191
16192
    pem = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16193
    if (pem == NULL) {
16194
        ret = MEMORY_E;
16195
    }
16196
    p = (byte*)pem;
16197
16198
    if (ret == 0) {
16199
        /* Add header. */
16200
        XMEMCPY(p, PEM_BEGIN, PEM_BEGIN_SZ);
16201
        p += PEM_BEGIN_SZ;
16202
        XMEMCPY(p, name, (size_t)nameLen);
16203
        p += nameLen;
16204
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
16205
        p += PEM_HDR_FIN_EOL_SZ;
16206
16207
        if (headerLen > 0) {
16208
            /* Add encryption header. */
16209
            XMEMCPY(p, header, (size_t)headerLen);
16210
            p += headerLen;
16211
            /* Blank line after a header and before body. */
16212
            *(p++) = '\n';
16213
        }
16214
16215
        /* Add DER data as PEM. */
16216
        pemLen -= (word32)((size_t)p - (size_t)pem);
16217
        ret = Base64_Encode(data, derLen, p, &pemLen);
16218
    }
16219
    if (ret == 0) {
16220
        p += pemLen;
16221
16222
        /* Add trailer. */
16223
        XMEMCPY(p, PEM_END, PEM_END_SZ);
16224
        p += PEM_END_SZ;
16225
        XMEMCPY(p, name, (size_t)nameLen);
16226
        p += nameLen;
16227
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
16228
        p += PEM_HDR_FIN_EOL_SZ;
16229
16230
        /* Return buffer and length of data. */
16231
        *pemOut = pem;
16232
        *pemOutLen = (word32)((size_t)p - (size_t)pem);
16233
    }
16234
    else {
16235
        /* Dispose of any allocated memory. */
16236
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16237
        pem = NULL;
16238
    }
16239
16240
    return ret;
16241
}
16242
#endif /* !NO_BIO || !NO_FILESYSTEM */
16243
16244
#ifndef NO_BIO
16245
/* Read PEM encoded data from a BIO.
16246
 *
16247
 * Reads the entire contents in.
16248
 *
16249
 * @param [in]  bio     BIO to read from.
16250
 * @param [out] name    Name of content type.
16251
 * @param [out] header  Encryption headers.
16252
 * @param [out] data    DER encoding from PEM.
16253
 * @param [out] len     Length of DER data.
16254
 * @return  1 on success.
16255
 * @return  0 on failure.
16256
 */
16257
int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
16258
    unsigned char **data, long *len)
16259
{
16260
    int res = 1;
16261
    char* pem = NULL;
16262
    int pemLen = 0;
16263
    int memAlloced = 1;
16264
16265
    /* Validate parameters. */
16266
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL) ||
16267
            (len == NULL)) {
16268
        res = 0;
16269
    }
16270
16271
    /* Load all the data from the BIO. */
16272
    if ((res == 1) && (wolfssl_read_bio(bio, &pem, &pemLen, &memAlloced) !=
16273
             0)) {
16274
        res = 0;
16275
    }
16276
    if ((res == 1) && (!memAlloced)) {
16277
        /* Need to return allocated memory - make sure it is allocated. */
16278
        char* p = (char*)XMALLOC((size_t)pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16279
        if (p == NULL) {
16280
            res = 0;
16281
        }
16282
        else {
16283
            /* Copy the data into new buffer. */
16284
            XMEMCPY(p, pem, (size_t)pemLen);
16285
            pem = p;
16286
        }
16287
    }
16288
16289
    /* Read the PEM data. */
16290
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
16291
            0)) {
16292
        /* Dispose of any allocated memory. */
16293
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16294
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16295
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16296
        *name = NULL;
16297
        *header = NULL;
16298
        res = 0;
16299
    }
16300
16301
    return res;
16302
}
16303
16304
/* Encode the DER data in PEM format into a BIO.
16305
 *
16306
 * @param [in] bio     BIO to write to.
16307
 * @param [in] name    Header/footer name.
16308
 * @param [in] header  Encryption header.
16309
 * @param [in] data    DER data.
16310
 * @param [in] len     Length of DER data.
16311
 * @return  0 on failure.
16312
 */
16313
int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
16314
    const char *header, const unsigned char *data, long len)
16315
{
16316
    int err = 0;
16317
    char* pem = NULL;
16318
    word32 pemLen = 0;
16319
16320
    /* Validate parameters. */
16321
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL)) {
16322
        err = BAD_FUNC_ARG;
16323
    }
16324
16325
    /* Encode into a buffer. */
16326
    if (!err) {
16327
        err = pem_write_data(name, header, data, len, &pem, &pemLen);
16328
    }
16329
16330
    /* Write PEM into BIO. */
16331
    if ((!err) && (wolfSSL_BIO_write(bio, pem, (int)pemLen) != (int)pemLen)) {
16332
        err = IO_FAILED_E;
16333
    }
16334
16335
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16336
    return (!err) ? (int)pemLen : 0;
16337
}
16338
#endif /* !NO_BIO */
16339
16340
#if !defined(NO_FILESYSTEM)
16341
/* Read PEM encoded data from a file.
16342
 *
16343
 * Reads the entire contents in.
16344
 *
16345
 * @param [in]  bio     BIO to read from.
16346
 * @param [out] name    Name of content type.
16347
 * @param [out] header  Encryption headers.
16348
 * @param [out] data    DER encoding from PEM.
16349
 * @param [out] len     Length of DER data.
16350
 * @return  1 on success.
16351
 * @return  0 on failure.
16352
 */
16353
int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data,
16354
    long *len)
16355
{
16356
    int res = 1;
16357
    char* pem = NULL;
16358
    int pemLen = 0;
16359
16360
    /* Validate parameters. */
16361
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
16362
            (data == NULL) || (len == NULL)) {
16363
        res = 0;
16364
    }
16365
16366
    /* Load all the data from the file. */
16367
    if ((res == 1) && (wolfssl_read_file(fp, &pem, &pemLen) != 0)) {
16368
        res = 0;
16369
    }
16370
16371
    /* Read the PEM data. */
16372
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
16373
            0)) {
16374
        /* Dispose of any allocated memory. */
16375
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16376
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16377
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16378
        *name = NULL;
16379
        *header = NULL;
16380
        res = 0;
16381
    }
16382
16383
    return res;
16384
}
16385
16386
/* Encode the DER data in PEM format into a file.
16387
 *
16388
 * @param [in] fp      File pointer to write to.
16389
 * @param [in] name    Header/footer name.
16390
 * @param [in] header  Encryption header.
16391
 * @param [in] data    DER data.
16392
 * @param [in] len     Length of DER data.
16393
 * @return  0 on success.
16394
 * @return  MEMORY_E when dynamic memory allocation fails.
16395
 */
16396
int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
16397
    const unsigned char *data, long len)
16398
{
16399
    int err = 0;
16400
    char* pem = NULL;
16401
    word32 pemLen = 0;
16402
16403
    /* Validate parameters. */
16404
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
16405
            (data == NULL)) {
16406
        err = 1;
16407
    }
16408
16409
    /* Encode into a buffer. */
16410
    if ((!err) && (pem_write_data(name, header, data, len, &pem, &pemLen) !=
16411
            0)) {
16412
        pemLen = 0;
16413
        err = 1;
16414
    }
16415
16416
    /* Write PEM to a file. */
16417
    if ((!err) && (XFWRITE(pem, 1, pemLen, fp) != pemLen)) {
16418
        pemLen = 0;
16419
    }
16420
16421
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16422
    return (int)pemLen;
16423
}
16424
#endif
16425
16426
/* Get EVP cipher info from encryption header string.
16427
 *
16428
 * @param [in]  header  Encryption header.
16429
 * @param [out] cipher  EVP Cipher info.
16430
 * @return  1 on success.
16431
 * @return  0 on failure.
16432
 */
16433
int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, EncryptedInfo* cipher)
16434
{
16435
    int res = 1;
16436
16437
    /* Validate parameters. */
16438
    if ((header == NULL) || (cipher == NULL)) {
16439
        res = 0;
16440
    }
16441
16442
    if (res == 1) {
16443
        XMEMSET(cipher, 0, sizeof(*cipher));
16444
16445
        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0) {
16446
            res = 0;
16447
        }
16448
    }
16449
16450
    return res;
16451
}
16452
16453
/* Apply cipher to DER data.
16454
 *
16455
 * @param [in]      cipher  EVP cipher info.
16456
 * @param [in, out] data    On in, encrypted DER data.
16457
 *                          On out, unencrypted DER data.
16458
 * @param [in, out] len     On in, length of encrypted DER data.
16459
 *                          On out, length of unencrypted DER data.
16460
 * @param [in]      cb      Password callback.
16461
 * @param [in]      ctx     Context for password callback.
16462
 * @return  1 on success.
16463
 * @return  0 on failure.
16464
 */
16465
int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
16466
    wc_pem_password_cb* cb, void* ctx)
16467
{
16468
    int ret = 1;
16469
    char password[NAME_SZ];
16470
    int passwordSz = 0;
16471
16472
    /* Validate parameters. */
16473
    if ((cipher == NULL) || (data == NULL) || (len == NULL) || (cb == NULL)) {
16474
        ret = 0;
16475
    }
16476
16477
    if (ret == 1) {
16478
        /* Get password and length. */
16479
        passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
16480
        if (passwordSz < 0) {
16481
            ret = 0;
16482
        }
16483
    }
16484
16485
    if (ret == 1) {
16486
        /* Decrypt the data using password and MD5. */
16487
        if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
16488
                passwordSz, WC_MD5) != 0) {
16489
            ret = WOLFSSL_FAILURE;
16490
        }
16491
    }
16492
16493
    if (passwordSz > 0) {
16494
        /* Ensure password is erased from memory. */
16495
        ForceZero(password, (word32)passwordSz);
16496
    }
16497
16498
    return ret;
16499
}
16500
16501
#endif /* !NO_CERTS */
16502
#endif /* OPENSSL_EXTRA */
16503
16504
#ifdef OPENSSL_ALL
16505
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
16506
16507
/* Encrypt the key into a buffer using PKCS$8 and a password.
16508
 *
16509
 * @param [in]      pkey      Private key to encrypt.
16510
 * @param [in]      enc       EVP cipher.
16511
 * @param [in]      passwd    Password to encrypt with.
16512
 * @param [in]      passwdSz  Number of bytes in password.
16513
 * @param [in]      key       Buffer to hold encrypted key.
16514
 * @param [in, out] keySz     On in, size of buffer in bytes.
16515
 *                            On out, size of encrypted key in bytes.
16516
 * @return  0 on success.
16517
 * @return  BAD_FUNC_ARG when EVP cipher not supported.
16518
 */
16519
int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
16520
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
16521
    word32* keySz)
16522
{
16523
    int ret;
16524
    WC_RNG rng;
16525
16526
    /* Initialize a new random number generator. */
16527
    ret = wc_InitRng(&rng);
16528
    if (ret == 0) {
16529
        int encAlgId = 0;
16530
16531
        /* Convert EVP cipher to a support encryption id. */
16532
    #ifndef NO_DES3
16533
        if (enc == EVP_DES_CBC) {
16534
            encAlgId = DESb;
16535
        }
16536
        else if (enc == EVP_DES_EDE3_CBC) {
16537
            encAlgId = DES3b;
16538
        }
16539
        else
16540
    #endif
16541
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
16542
    #ifdef WOLFSSL_AES_128
16543
        if (enc == EVP_AES_128_CBC) {
16544
            encAlgId = AES128CBCb;
16545
        }
16546
        else
16547
     #endif
16548
    #ifdef WOLFSSL_AES_256
16549
        if (enc == EVP_AES_256_CBC) {
16550
            encAlgId = AES256CBCb;
16551
        }
16552
        else
16553
     #endif
16554
#endif
16555
        {
16556
            ret = BAD_FUNC_ARG;
16557
        }
16558
16559
        if (ret == 0) {
16560
            /* Encrypt private into buffer. */
16561
            ret = TraditionalEnc((byte*)pkey->pkey.ptr + pkey->pkcs8HeaderSz,
16562
                (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
16563
                key, keySz, passwd, passwdSz, PKCS5, PBES2, encAlgId,
16564
                NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL);
16565
            if (ret > 0) {
16566
                *keySz = (word32)ret;
16567
            }
16568
        }
16569
        /* Dispose of random number generator. */
16570
        wc_FreeRng(&rng);
16571
    }
16572
16573
    return ret;
16574
}
16575
16576
/* Encode private key in PKCS#8 format.
16577
 *
16578
 * @param [in]      pkey   Private key.
16579
 * @param [out]     key    Buffer to hold encoding.
16580
 * @param [in, out] keySz  On in, size of buffer in bytes.
16581
 * @param                  On out, size of encoded key in bytes.
16582
 * @return  0 on success.
16583
 */
16584
int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
16585
{
16586
    int ret = 0;
16587
    int algId = 0;
16588
    const byte* curveOid = 0;
16589
    word32 oidSz = 0;
16590
16591
    /* Get the details of the private key. */
16592
#ifdef HAVE_ECC
16593
    if (pkey->type == WC_EVP_PKEY_EC) {
16594
        /* ECC private and get curve OID information. */
16595
        algId = ECDSAk;
16596
        ret = wc_ecc_get_oid((word32)pkey->ecc->group->curve_oid, &curveOid,
16597
            &oidSz);
16598
    }
16599
    else
16600
#endif
16601
    if (pkey->type == WC_EVP_PKEY_RSA) {
16602
        /* RSA private has no curve information. */
16603
        algId = RSAk;
16604
        curveOid = NULL;
16605
        oidSz = 0;
16606
    }
16607
    else if (pkey->type == WC_EVP_PKEY_DSA) {
16608
        /* DSA has no curve information. */
16609
        algId = DSAk;
16610
        curveOid = NULL;
16611
        oidSz = 0;
16612
    }
16613
#ifndef NO_DH
16614
    else if (pkey->type == WC_EVP_PKEY_DH) {
16615
        if (pkey->dh == NULL)
16616
            return BAD_FUNC_ARG;
16617
16618
        if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
16619
            /* Special case. DH buffer is always in PKCS8 format */
16620
            if (keySz == NULL)
16621
                return BAD_FUNC_ARG;
16622
16623
            *keySz = (word32)pkey->pkey_sz;
16624
            if (key == NULL)
16625
                return LENGTH_ONLY_E;
16626
16627
            XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
16628
            return pkey->pkey_sz;
16629
        }
16630
16631
        /* DH has no curve information. */
16632
        algId = DHk;
16633
        curveOid = NULL;
16634
        oidSz = 0;
16635
    }
16636
#endif
16637
    else {
16638
        ret = NOT_COMPILED_IN;
16639
    }
16640
16641
    if (ret >= 0) {
16642
        /* Encode private key in PKCS#8 format. */
16643
        ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr +
16644
            pkey->pkcs8HeaderSz, (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
16645
            algId, curveOid, oidSz);
16646
    }
16647
16648
    return ret;
16649
}
16650
16651
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
16652
    !defined(NO_STDIO_FILESYSTEM))
16653
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
16654
 *
16655
 * @param [out] pem       Buffer holding PEM encoding.
16656
 * @param [out] pemSz     Size of data in buffer in bytes.
16657
 * @param [in]  pkey      Private key to write.
16658
 * @param [in]  enc       Encryption information to use. May be NULL.
16659
 * @param [in]  passwd    Password to use when encrypting. May be NULL.
16660
 * @param [in]  passwdSz  Size of password in bytes.
16661
 * @param [in]  cb        Password callback. Used when passwd is NULL. May be
16662
 *                        NULL.
16663
 * @param [in]  ctx       Context for password callback.
16664
 * @return  Length of PEM encoding on success.
16665
 * @return  0 on failure.
16666
 */
16667
static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
16668
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
16669
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
16670
{
16671
    int res = 1;
16672
    int ret = 0;
16673
    char password[NAME_SZ];
16674
    byte* key = NULL;
16675
    word32 keySz = 0;
16676
    int type = PKCS8_PRIVATEKEY_TYPE;
16677
16678
    /* Validate parameters. */
16679
    if (pkey == NULL) {
16680
        res = 0;
16681
    }
16682
16683
    if (res == 1) {
16684
        /* Guestimate key size and PEM size. */
16685
        if (pkcs8_encode(pkey, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
16686
            res = 0;
16687
        }
16688
    }
16689
    if (res == 1) {
16690
        if (enc != NULL) {
16691
            /* Add on enough for extra DER data when encrypting. */
16692
            keySz += 128;
16693
        }
16694
        /* PEM encoding size from DER size. */
16695
        *pemSz  = (int)(keySz + 2) / 3 * 4;
16696
        *pemSz += (*pemSz + 63) / 64;
16697
        /* Header and footer. */
16698
        if (enc != NULL) {
16699
            /* Name is: 'ENCRYPTED PRIVATE KEY'. */
16700
            *pemSz += 74;
16701
        }
16702
        else {
16703
            /* Name is: 'PRIVATE KEY'. */
16704
            *pemSz += 54;
16705
        }
16706
16707
        /* Allocate enough memory to hold PEM encoded encrypted key. */
16708
        *pem = (byte*)XMALLOC((size_t)*pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16709
        if (*pem == NULL) {
16710
            res = 0;
16711
        }
16712
        else {
16713
            /* Use end of PEM buffer for key data. */
16714
            key = *pem + *pemSz - keySz;
16715
        }
16716
    }
16717
16718
    if ((res == 1) && (enc != NULL)) {
16719
        /* Set type for PEM. */
16720
        type = PKCS8_ENC_PRIVATEKEY_TYPE;
16721
16722
        if (passwd == NULL) {
16723
            /* Get the password by using callback. */
16724
            passwdSz = cb(password, sizeof(password), 1, ctx);
16725
            if (passwdSz < 0) {
16726
                res = 0;
16727
            }
16728
            passwd = password;
16729
        }
16730
16731
        if (res == 1) {
16732
            /* Encrypt the private key. */
16733
            ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
16734
            if (ret <= 0) {
16735
                res = 0;
16736
            }
16737
        }
16738
16739
        /* Zeroize the password from memory. */
16740
        if ((password == passwd) && (passwdSz > 0)) {
16741
            ForceZero(password, (word32)passwdSz);
16742
        }
16743
    }
16744
    else if ((res == 1) && (enc == NULL)) {
16745
        /* Set type for PEM. */
16746
        type = PKCS8_PRIVATEKEY_TYPE;
16747
16748
        /* Encode private key in PKCS#8 format. */
16749
        ret = pkcs8_encode(pkey, key, &keySz);
16750
        if (ret < 0) {
16751
            res = 0;
16752
        }
16753
    }
16754
16755
    if (res == 1) {
16756
        /* Encode PKCS#8 formatted key to PEM. */
16757
        ret = wc_DerToPemEx(key, keySz, *pem, (word32)*pemSz, NULL, type);
16758
        if (ret < 0) {
16759
            res = 0;
16760
        }
16761
        else {
16762
            *pemSz = ret;
16763
        }
16764
    }
16765
16766
    /* Return appropriate return code. */
16767
    return (res == 0) ? 0 : ret;
16768
16769
}
16770
#endif /* !NO_BIO || (!NO_FILESYSTEM && !NO_STDIO_FILESYSTEM) */
16771
16772
#ifndef NO_BIO
16773
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
16774
 *
16775
 * TODO: OpenSSL returns 1 and 0 only.
16776
 *
16777
 * @param [in] bio       BIO to write to.
16778
 * @param [in] pkey      Private key to write.
16779
 * @param [in] enc       Encryption information to use. May be NULL.
16780
 * @param [in] passwd    Password to use when encrypting. May be NULL.
16781
 * @param [in] passwdSz  Size of password in bytes.
16782
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
16783
 *                       NULL.
16784
 * @param [in] ctx       Context for password callback.
16785
 * @return  Length of PEM encoding on success.
16786
 * @return  0 on failure.
16787
 */
16788
int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
16789
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
16790
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
16791
{
16792
    byte* pem = NULL;
16793
    int pemSz = 0;
16794
    int res = 1;
16795
16796
    /* Validate parameters. */
16797
    if (bio == NULL) {
16798
        res = 0;
16799
    }
16800
    if (res == 1) {
16801
        /* Write private key to memory. */
16802
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
16803
            passwdSz, cb, ctx);
16804
    }
16805
16806
    /* Write encoded key to BIO. */
16807
    if ((res >= 1) && (wolfSSL_BIO_write(bio, pem, pemSz) != pemSz)) {
16808
        res = 0;
16809
    }
16810
16811
    /* Dispose of dynamically allocated memory (pem and key). */
16812
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16813
    return res;
16814
}
16815
16816
int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
16817
        PKCS8_PRIV_KEY_INFO* keyInfo)
16818
{
16819
    return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
16820
            NULL, NULL);
16821
}
16822
#endif /* !NO_BIO */
16823
16824
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
16825
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
16826
 *
16827
 * TODO: OpenSSL returns 1 and 0 only.
16828
 *
16829
 * @param [in] f         File pointer.
16830
 * @param [in] pkey      Private key to write.
16831
 * @param [in] enc       Encryption information to use. May be NULL.
16832
 * @param [in] passwd    Password to use when encrypting. May be NULL.
16833
 * @param [in] passwdSz  Size of password in bytes.
16834
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
16835
 *                       NULL.
16836
 * @param [in] ctx       Context for password callback.
16837
 * @return  Length of PEM encoding on success.
16838
 * @return  0 on failure.
16839
 */
16840
int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
16841
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
16842
    wc_pem_password_cb* cb, void* ctx)
16843
{
16844
    byte* pem = NULL;
16845
    int pemSz = 0;
16846
    int res = 1;
16847
16848
    /* Validate parameters. */
16849
    if (f == XBADFILE) {
16850
        res = 0;
16851
    }
16852
    if (res == 1) {
16853
        /* Write private key to memory. */
16854
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
16855
            passwdSz, cb, ctx);
16856
    }
16857
16858
    /* Write encoded key to file. */
16859
    if ((res >= 1) && (XFWRITE(pem, 1, (size_t)pemSz, f) != (size_t)pemSz)) {
16860
        res = 0;
16861
    }
16862
16863
    /* Dispose of dynamically allocated memory (pem and key). */
16864
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16865
    return res;
16866
}
16867
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
16868
16869
#endif /* !NO_PWDBASED && HAVE_PKCS8 */
16870
#endif /* OPENSSL_ALL */
16871
16872
/*******************************************************************************
16873
 * END OF GENERIC PUBLIC KEY PEM APIs
16874
 ******************************************************************************/
16875
16876
#endif /* !WOLFSSL_PK_INCLUDED */
16877