Coverage Report

Created: 2026-10-16 06:40

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-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#include <wolfssl/internal.h>
25
#ifndef WC_NO_RNG
26
    #include <wolfssl/wolfcrypt/random.h>
27
#endif
28
29
#if !defined(WOLFSSL_PK_INCLUDED)
30
    #ifndef WOLFSSL_IGNORE_FILE_WARN
31
        #warning pk.c does not need to be compiled separately from ssl.c
32
    #endif
33
#else
34
35
#ifndef NO_RSA
36
    #include <wolfssl/wolfcrypt/rsa.h>
37
#endif
38
39
/*******************************************************************************
40
 * COMMON FUNCTIONS
41
 ******************************************************************************/
42
43
/* Calculate the number of bytes require to represent a length value in ASN.
44
 *
45
 * @param [in] l  Length value to use.
46
 * @return  Number of bytes required to represent length value.
47
 */
48
#define ASN_LEN_SIZE(l)             \
49
    (((l) < 128) ? 1 : (((l) < 256) ? 2 : 3))
50
51
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
52
53
#ifndef NO_ASN
54
55
#if (!defined(NO_FILESYSTEM) && (defined(OPENSSL_EXTRA) || \
56
     defined(OPENSSL_ALL))) || (!defined(NO_BIO) && defined(OPENSSL_EXTRA))
57
/* Convert the PEM encoding in the buffer to DER.
58
 *
59
 * @param [in]  pem        Buffer containing PEM encoded data.
60
 * @param [in]  pemSz      Size of data in buffer in bytes.
61
 * @param [in]  cb         Password callback when PEM encrypted.
62
 * @param [in]  pass       NUL terminated string for passphrase when PEM
63
 *                         encrypted.
64
 * @param [in]  keyType    Type of key to match against PEM header/footer.
65
 * @param [out] keyFormat  Format of key.
66
 * @param [out] der        Buffer holding DER encoding.
67
 * @return  Negative on failure.
68
 * @return  Number of bytes consumed on success.
69
 */
70
static int pem_mem_to_der(const char* pem, int pemSz, wc_pem_password_cb* cb,
71
    void* pass, int keyType, int* keyFormat, DerBuffer** der)
72
{
73
    WC_DECLARE_VAR(info, EncryptedInfo, 1, 0);
74
    wc_pem_password_cb* localCb = NULL;
75
    int ret = 0;
76
77
    if (cb != NULL) {
78
        localCb = cb;
79
    }
80
    else if (pass != NULL) {
81
        localCb = wolfSSL_PEM_def_callback;
82
    }
83
84
#ifdef WOLFSSL_SMALL_STACK
85
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
86
        DYNAMIC_TYPE_ENCRYPTEDINFO);
87
    if (info == NULL) {
88
        WOLFSSL_ERROR_MSG("Error getting memory for EncryptedInfo structure");
89
        ret = MEMORY_E;
90
    }
91
#endif /* WOLFSSL_SMALL_STACK */
92
93
    if (ret == 0) {
94
        XMEMSET(info, 0, sizeof(EncryptedInfo));
95
        info->passwd_cb       = localCb;
96
        info->passwd_userdata = pass;
97
98
        /* Do not strip PKCS8 header */
99
        ret = PemToDer((const unsigned char *)pem, pemSz, keyType, der, NULL,
100
            info, keyFormat);
101
        if (ret < 0) {
102
            WOLFSSL_ERROR_MSG("Bad PEM To DER");
103
        }
104
    }
105
    if (ret >= 0) {
106
        ret = (int)info->consumed;
107
    }
108
109
    WC_FREE_VAR_EX(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
110
111
    return ret;
112
}
113
#endif
114
115
#if defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || !defined(WOLFCRYPT_ONLY))
116
#ifndef NO_BIO
117
/* Read PEM data from a BIO and decode to DER in a new buffer.
118
 *
119
 * @param [in, out] bio        BIO object to read with.
120
 * @param [in]      cb         Password callback when PEM encrypted.
121
 * @param [in]      pass       NUL terminated string for passphrase when PEM
122
 *                             encrypted.
123
 * @param [in]      keyType    Type of key to match against PEM header/footer.
124
 * @param [out]     keyFormat  Format of key.
125
 * @param [out]     der        Buffer holding DER encoding.
126
 * @return  Negative on failure.
127
 * @return  Number of bytes consumed on success.
128
 */
129
static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
130
    void* pass, int keyType, int* keyFormat, DerBuffer** der)
131
{
132
    int ret;
133
    char* mem = NULL;
134
    int memSz;
135
    int alloced = 0;
136
137
    ret = wolfssl_read_bio(bio, &mem, &memSz, &alloced);
138
    if (ret == 0) {
139
        ret = pem_mem_to_der(mem, memSz, cb, pass, keyType, keyFormat, der);
140
        /* Write left over data back to BIO if not a file BIO */
141
        if ((ret > 0) && ((memSz - ret) > 0) &&
142
                 (bio->type != WOLFSSL_BIO_FILE)) {
143
            int res;
144
            if (!alloced) {
145
                /* If wolfssl_read_bio() points mem at the buffer internal to
146
                 * bio, we need to dup it before calling wolfSSL_BIO_write(),
147
                 * because the latter may reallocate the bio, invalidating the
148
                 * mem pointer before reading from it.
149
                 */
150
                char *mem_dup = (char *)XMALLOC((size_t)(memSz - ret),
151
                                                NULL, DYNAMIC_TYPE_TMP_BUFFER);
152
                if (mem_dup != NULL) {
153
                    XMEMCPY(mem_dup, mem + ret, (size_t)(memSz - ret));
154
                    res = wolfSSL_BIO_write(bio, mem_dup, memSz - ret);
155
                    mem = mem_dup;
156
                    alloced = 1;
157
                }
158
                else
159
                    res = MEMORY_E;
160
            }
161
            else
162
                res = wolfSSL_BIO_write(bio, mem + ret, memSz - ret);
163
            if (res != memSz - ret) {
164
                WOLFSSL_ERROR_MSG("Unable to write back excess data");
165
                if (res < 0) {
166
                    ret = res;
167
                }
168
                else {
169
                    ret = MEMORY_E;
170
                }
171
            }
172
        }
173
        if (alloced) {
174
            XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
175
        }
176
    }
177
178
    return ret;
179
}
180
#endif /* !NO_BIO */
181
182
#if !defined(NO_FILESYSTEM)
183
/* Read PEM data from a file and decode to DER in a new buffer.
184
 *
185
 * @param [in]  fp         File pointer to read with.
186
 * @param [in]  cb         Password callback when PEM encrypted.
187
 * @param [in]  pass       NUL terminated string for passphrase when PEM
188
 *                         encrypted.
189
 * @param [in]  keyType    Type of key to match against PEM header/footer.
190
 * @param [out] keyFormat  Format of key.
191
 * @param [out] der        Buffer holding DER encoding.
192
 * @return  Negative on failure.
193
 * @return  Number of bytes consumed on success.
194
 */
195
static int pem_read_file_key(XFILE fp, wc_pem_password_cb* cb, void* pass,
196
    int keyType, int* keyFormat, DerBuffer** der)
197
{
198
    int ret;
199
    char* mem = NULL;
200
    int memSz;
201
202
    ret = wolfssl_read_file(fp, &mem, &memSz);
203
    if (ret == 0) {
204
        ret = pem_mem_to_der(mem, memSz, cb, pass, keyType, keyFormat, der);
205
        XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
206
    }
207
208
    return ret;
209
}
210
#endif /* !NO_FILESYSTEM */
211
#endif
212
213
#if defined(OPENSSL_EXTRA) && ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) \
214
    || !defined(WOLFCRYPT_ONLY)) \
215
    && (!defined(NO_BIO) || !defined(NO_FILESYSTEM))
216
/* Convert DER data to PEM in an allocated buffer.
217
 *
218
 * @param [in]  der    Buffer containing DER data.
219
 * @param [in]  derSz  Size of DER data in bytes.
220
 * @param [in]  type   Type of key being encoded.
221
 * @param [in]  heap   Heap hint for dynamic memory allocation.
222
 * @param [out] out    Allocated buffer containing PEM.
223
 * @param [out] outSz  Size of PEM encoding.
224
 * @return  1 on success.
225
 * @return  0 on error.
226
 */
227
static int der_to_pem_alloc(const unsigned char* der, int derSz, int type,
228
    void* heap, byte** out, int* outSz)
229
{
230
    int ret = 1;
231
    int pemSz;
232
    byte* pem = NULL;
233
234
    (void)heap;
235
236
    /* Convert DER to PEM - to get size. */
237
    pemSz = wc_DerToPem(der, (word32)derSz, NULL, 0, type);
238
    if (pemSz < 0) {
239
        ret = 0;
240
    }
241
242
    if (ret == 1) {
243
        /* Allocate memory for PEM to be encoded into. */
244
        pem = (byte*)XMALLOC((size_t)pemSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
245
        if (pem == NULL) {
246
            ret = 0;
247
        }
248
    }
249
250
    /* Convert DER to PEM. */
251
    if ((ret == 1) && (wc_DerToPem(der, (word32)derSz, pem, (word32)pemSz,
252
            type) < 0)) {
253
        ret = 0;
254
        XFREE(pem, heap, DYNAMIC_TYPE_TMP_BUFFER);
255
        pem = NULL;
256
    }
257
258
    *out = pem;
259
    *outSz = pemSz;
260
    return ret;
261
}
262
263
#ifndef NO_BIO
264
/* Write the DER data as PEM into BIO.
265
 *
266
 * @param [in]      der    Buffer containing DER data.
267
 * @param [in]      derSz  Size of DER data in bytes.
268
 * @param [in, out] bio    BIO object to write with.
269
 * @param [in]      type   Type of key being encoded.
270
 * @return  1 on success.
271
 * @return  0 on error.
272
 */
273
static int der_write_to_bio_as_pem(const unsigned char* der, int derSz,
274
    WOLFSSL_BIO* bio, int type)
275
{
276
    int ret;
277
    int pemSz;
278
    byte* pem = NULL;
279
280
    ret = der_to_pem_alloc(der, derSz, type, bio->heap, &pem, &pemSz);
281
    if (ret == 1) {
282
        int len = wolfSSL_BIO_write(bio, pem, pemSz);
283
        if (len != pemSz) {
284
            WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
285
            ret = 0;
286
        }
287
    }
288
289
    XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
290
    return ret;
291
}
292
#endif
293
#endif
294
295
#if !defined(NO_FILESYSTEM) && \
296
    ((defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_ASN)) || \
297
     defined(WOLFSSL_DH_EXTRA))
298
/* Write the DER data as PEM into file pointer.
299
 *
300
 * @param [in] der    Buffer containing DER data.
301
 * @param [in] derSz  Size of DER data in bytes.
302
 * @param [in] fp     File pointer to write with.
303
 * @param [in] type   Type of key being encoded.
304
 * @param [in] heap   Heap hint for dynamic memory allocation.
305
 * @return  1 on success.
306
 * @return  0 on error.
307
 */
308
static int der_write_to_file_as_pem(const unsigned char* der, int derSz,
309
    XFILE fp, int type, void* heap)
310
{
311
    int ret;
312
    int pemSz;
313
    byte* pem = NULL;
314
315
    ret = der_to_pem_alloc(der, derSz, type, heap, &pem, &pemSz);
316
    if (ret == 1) {
317
        int len = (int)XFWRITE(pem, 1, (size_t)pemSz, fp);
318
        if (len != pemSz) {
319
            WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
320
            ret = 0;
321
        }
322
    }
323
324
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
325
    return ret;
326
}
327
#endif /* !NO_FILESYSTEM &&
328
        * ((OPENSSL_EXTRA && !NO_CERTS && !NO_ASN) || WOLFSSL_DH_EXTRA) */
329
330
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
331
    defined(WOLFSSL_PEM_TO_DER)
332
/* Encrypt private key into PEM format.
333
 *
334
 * DER is encrypted in place.
335
 *
336
 * @param [in]  der         DER encoding of private key.
337
 * @param [in]  derSz       Size of DER in bytes.
338
 * @param [in]  cipher      EVP cipher.
339
 * @param [in]  passwd      Password to use with encryption.
340
 * @param [in]  passedSz    Size of password in bytes.
341
 * @param [out] cipherInfo  PEM cipher information lines.
342
 * @param [in]  maxDerSz    Maximum size of DER buffer.
343
 * @param [in]  hashType    Hash algorithm
344
 * @return  1 on success.
345
 * @return  0 on error.
346
 */
347
int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher,
348
    unsigned char* passwd, int passwdSz, byte **cipherInfo, int maxDerSz,
349
    int hashType)
350
{
351
    int ret = 0;
352
    int paddingSz = 0;
353
    word32 idx;
354
    word32 cipherInfoSz = 0;
355
    WC_DECLARE_VAR(info, EncryptedInfo, 1, 0);
356
357
    WOLFSSL_ENTER("EncryptDerKey");
358
359
    /* Validate parameters. */
360
    if ((der == NULL) || (derSz == NULL) || (cipher == NULL) ||
361
            (passwd == NULL) || (cipherInfo == NULL)) {
362
        ret = BAD_FUNC_ARG;
363
    }
364
365
    #ifdef WOLFSSL_SMALL_STACK
366
    if (ret == 0) {
367
        /* Allocate encrypted info. */
368
        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
369
            DYNAMIC_TYPE_ENCRYPTEDINFO);
370
        if (info == NULL) {
371
            WOLFSSL_MSG("malloc failed");
372
            ret = MEMORY_E;
373
        }
374
    }
375
    #endif
376
    if (ret == 0) {
377
        /* Clear the encrypted info and set name. */
378
        XMEMSET(info, 0, sizeof(EncryptedInfo));
379
        XSTRNCPY(info->name, cipher, NAME_SZ - 1);
380
        info->name[NAME_SZ - 1] = '\0'; /* null term */
381
382
        /* Get encrypted info from name. */
383
        ret = wc_EncryptedInfoGet(info, info->name);
384
        if (ret != 0) {
385
            WOLFSSL_MSG("unsupported cipher");
386
        }
387
    }
388
389
    if (ret == 0) {
390
        /* Generate a random salt. */
391
        if (wolfSSL_RAND_bytes(info->iv, (int)info->ivSz) != 1) {
392
            WOLFSSL_MSG("generate iv failed");
393
            ret = WOLFSSL_FATAL_ERROR;
394
        }
395
    }
396
397
    if (ret == 0) {
398
        /* Calculate padding size - always a padding block. */
399
        paddingSz = (int)info->ivSz - ((*derSz) % (int)info->ivSz);
400
        /* Check der is big enough. */
401
        if (maxDerSz < (*derSz) + paddingSz) {
402
            WOLFSSL_MSG("not enough DER buffer allocated");
403
            ret = BAD_FUNC_ARG;
404
        }
405
    }
406
    if (ret == 0) {
407
        /* Set padding bytes to padding length. */
408
        XMEMSET(der + (*derSz), (byte)paddingSz, (size_t)paddingSz);
409
        /* Add padding to DER size. */
410
        (*derSz) += (int)paddingSz;
411
412
        /* Encrypt DER buffer. */
413
        ret = wc_BufferKeyEncrypt(info, der, (word32)*derSz, passwd, passwdSz,
414
            hashType);
415
        if (ret != 0) {
416
            WOLFSSL_MSG("encrypt key failed");
417
        }
418
    }
419
420
    if (ret == 0) {
421
        /* Create cipher info : 'cipher_name,Salt(hex)' */
422
        cipherInfoSz = (word32)(2 * info->ivSz + XSTRLEN(info->name) + 2);
423
        /* Allocate memory for PEM encryption lines. */
424
        *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL, DYNAMIC_TYPE_STRING);
425
        if (*cipherInfo == NULL) {
426
            WOLFSSL_MSG("malloc failed");
427
            ret = MEMORY_E;
428
        }
429
    }
430
    if (ret == 0) {
431
        /* Copy in name and add on comma. */
432
        XSTRLCPY((char*)*cipherInfo, info->name, cipherInfoSz);
433
        XSTRLCAT((char*)*cipherInfo, ",", cipherInfoSz);
434
435
        /* Find end of string. */
436
        idx = (word32)XSTRLEN((char*)*cipherInfo);
437
        /* Calculate remaining bytes. */
438
        cipherInfoSz -= idx;
439
440
        /* Encode IV into PEM encryption lines. */
441
        ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo + idx,
442
            &cipherInfoSz);
443
        if (ret != 0) {
444
            WOLFSSL_MSG("Base16_Encode failed");
445
            XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
446
            *cipherInfo = NULL;
447
        }
448
    }
449
450
    WC_FREE_VAR_EX(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
451
    return ret == 0;
452
}
453
#endif /* OPENSSL_EXTRA && WOLFSSL_KEY_GEN && WOLFSSL_PEM_TO_DER */
454
455
456
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
457
    (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
458
    (!defined(NO_RSA) || defined(HAVE_ECC))
459
/* Encrypt the DER in PEM format.
460
 *
461
 * @param [in]  der       DER encoded private key.
462
 * @param [in]  derSz     Size of DER in bytes.
463
 * @param [in]  cipher    EVP cipher.
464
 * @param [in]  passwd    Password to use in encryption.
465
 * @param [in]  passwdSz  Size of password in bytes.
466
 * @param [in]  type      PEM type of write out.
467
 * @param [in]  heap      Dynamic memory hint.
468
 * @param [out] out       Allocated buffer containing PEM encoding.
469
 *                        heap was NULL and dynamic type is DYNAMIC_TYPE_KEY.
470
 * @param [out] outSz     Size of PEM encoding in bytes.
471
 * @return  1 on success.
472
 * @return  0 on failure.
473
 */
474
static int der_to_enc_pem_alloc(unsigned char* der, int derSz,
475
    const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
476
    int type, void* heap, byte** out, int* outSz)
477
{
478
    int ret = 1;
479
    byte* tmp = NULL;
480
    byte* cipherInfo = NULL;
481
    int pemSz = 0;
482
    int derAllocSz = derSz;
483
    int hashType = WC_HASH_TYPE_NONE;
484
#if !defined(NO_MD5)
485
    hashType = WC_MD5;
486
#elif !defined(NO_SHA)
487
    hashType = WC_SHA;
488
#endif
489
490
    /* Macro doesn't always use it. */
491
    (void)heap;
492
493
    /* Encrypt DER buffer if required. */
494
    if ((ret == 1) && (passwd != NULL) && (passwdSz > 0) && (cipher != NULL)) {
495
        int blockSz = wolfSSL_EVP_CIPHER_block_size(cipher);
496
        byte *tmpBuf;
497
498
        /* Add space for padding. */
499
    #ifdef WOLFSSL_NO_REALLOC
500
        tmpBuf = (byte*)XMALLOC((size_t)(derSz + blockSz), heap,
501
            DYNAMIC_TYPE_TMP_BUFFER);
502
        if (tmpBuf != NULL && der != NULL)
503
        {
504
                XMEMCPY(tmpBuf, der, (size_t)(derSz));
505
                XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
506
                der = NULL;
507
        }
508
    #else
509
        tmpBuf = (byte*)XREALLOC(der, (size_t)(derSz + blockSz), heap,
510
            DYNAMIC_TYPE_TMP_BUFFER);
511
    #endif
512
        if (tmpBuf == NULL) {
513
            WOLFSSL_ERROR_MSG("Extending DER buffer failed");
514
            ret = 0; /* der buffer is free'd at the end of the function */
515
        }
516
        else {
517
            der = tmpBuf;
518
            derAllocSz = derSz + blockSz;
519
520
            /* Encrypt DER inline. */
521
            ret = EncryptDerKey(der, &derSz, cipher, passwd, passwdSz,
522
                &cipherInfo, derSz + blockSz, hashType);
523
            if (ret != 1) {
524
                WOLFSSL_ERROR_MSG("EncryptDerKey failed");
525
            }
526
        }
527
    }
528
529
    if (ret == 1) {
530
        /* Calculate PEM encoding size. */
531
        pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, cipherInfo, type);
532
        if (pemSz <= 0) {
533
            WOLFSSL_ERROR_MSG("wc_DerToPemEx failed");
534
            ret = 0;
535
        }
536
    }
537
    if (ret == 1) {
538
        /* Allocate space for PEM encoding plus a NUL terminator. */
539
        tmp = (byte*)XMALLOC((size_t)(pemSz + 1), NULL, DYNAMIC_TYPE_KEY);
540
        if (tmp == NULL) {
541
            WOLFSSL_ERROR_MSG("malloc failed");
542
            ret = 0;
543
        }
544
    }
545
    if (ret == 1) {
546
        /* DER to PEM */
547
        pemSz = wc_DerToPemEx(der, (word32)derSz, tmp, (word32)pemSz,
548
            cipherInfo, type);
549
        if (pemSz <= 0) {
550
            WOLFSSL_ERROR_MSG("wc_DerToPemEx failed");
551
            ret = 0;
552
        }
553
    }
554
    if (ret == 1) {
555
        /* NUL terminate string - PEM.  */
556
        tmp[pemSz] = 0x00;
557
        /* Return allocated buffer and size. */
558
        *out = tmp;
559
        *outSz = pemSz;
560
        /* Don't free returning buffer. */
561
        tmp = NULL;
562
    }
563
564
    XFREE(tmp, NULL, DYNAMIC_TYPE_KEY);
565
    XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
566
    if (der != NULL) {
567
        ForceZero(der, (word32)derAllocSz);
568
        XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
569
    }
570
571
    return ret;
572
}
573
#endif
574
575
#endif /* !NO_ASN */
576
577
#if !defined(NO_CERTS) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
578
    !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA) || \
579
    defined(HAVE_ECC)) && defined(OPENSSL_EXTRA)
580
/* Print the number bn in hex with name field and indentation indent to file fp.
581
 *
582
 * Used by wolfSSL_DSA_print_fp, wolfSSL_RSA_print_fp and
583
 * wolfSSL_EC_KEY_print_fp to print DSA, RSA and ECC keys and parameters.
584
 *
585
 * @param [in] fp      File pointer to write to.
586
 * @param [in] indent  Number of spaces to prepend to each line.
587
 * @param [in] field   Name of field.
588
 * @param [in] bn      Big number to print.
589
 * @return  1 on success.
590
 * @return  0 on failure.
591
 * @return  BAD_FUNC_ARG when fp is invalid, indent is less than 0, or field or
592
 *          bn or NULL.
593
 */
594
static int pk_bn_field_print_fp(XFILE fp, int indent, const char* field,
595
    const WOLFSSL_BIGNUM* bn)
596
{
597
    static const int HEX_INDENT = 4;
598
    static const int MAX_DIGITS_PER_LINE = 30;
599
600
    int ret = 1;
601
    int i = 0;
602
    char* buf = NULL;
603
604
    /* Internal function - assume parameters are valid. */
605
606
    /* Convert BN to hexadecimal character array (allocates buffer). */
607
    buf = wolfSSL_BN_bn2hex(bn);
608
    if (buf == NULL) {
609
        ret = 0;
610
    }
611
    if (ret == 1) {
612
        /* Print leading spaces, name and spaces before data. */
613
        if (indent > 0) {
614
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
615
                ret = 0;
616
        }
617
    }
618
    if (ret == 1) {
619
        if (XFPRINTF(fp, "%s:\n", field) < 0)
620
            ret = 0;
621
    }
622
    if (ret == 1) {
623
        if (indent > 0) {
624
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
625
                ret = 0;
626
        }
627
    }
628
    if (ret == 1) {
629
        if (XFPRINTF(fp, "%*s", HEX_INDENT, "") < 0)
630
            ret = 0;
631
    }
632
    if (ret == 1) {
633
        /* Print first byte - should always exist. */
634
        if ((buf[i] != '\0') && (buf[i+1] != '\0')) {
635
            if (XFPRINTF(fp, "%c", buf[i++]) < 0)
636
                ret = 0;
637
            else if (XFPRINTF(fp, "%c", buf[i++]) < 0)
638
                    ret = 0;
639
        }
640
    }
641
    if (ret == 1) {
642
        /* Print each hexadecimal character with byte separator. */
643
        while ((buf[i] != '\0') && (buf[i+1] != '\0')) {
644
            /* Byte separator every two nibbles - one byte. */
645
            if (XFPRINTF(fp, ":") < 0) {
646
                ret = 0;
647
                break;
648
            }
649
            /* New line after every 15 bytes - 30 nibbles. */
650
            if (i % MAX_DIGITS_PER_LINE == 0) {
651
                if (XFPRINTF(fp, "\n") < 0) {
652
                    ret = 0;
653
                    break;
654
                }
655
                if (indent > 0) {
656
                    if (XFPRINTF(fp, "%*s", indent, "") < 0) {
657
                        ret = 0;
658
                        break;
659
                    }
660
                }
661
                if (XFPRINTF(fp, "%*s", HEX_INDENT, "") < 0) {
662
                    ret = 0;
663
                    break;
664
                }
665
            }
666
            /* Print two nibbles - one byte. */
667
            if (XFPRINTF(fp, "%c", buf[i++]) < 0) {
668
                ret = 0;
669
                break;
670
            }
671
            if (XFPRINTF(fp, "%c", buf[i++]) < 0) {
672
                ret = 0;
673
                break;
674
            }
675
        }
676
        /* Ensure on new line after data. */
677
        if (XFPRINTF(fp, "\n") < 0) {
678
            ret = 0;
679
        }
680
    }
681
682
    /* Dispose of any allocated character array. */
683
    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
684
685
    return ret;
686
}
687
#endif /* !NO_CERTS && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM &&
688
        * (!NO_DSA || !NO_RSA || HAVE_ECC) */
689
690
#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF) && !defined(NO_BIO) && \
691
    !defined(NO_RSA)
692
/* snprintf() must be available */
693
694
/* Maximum number of extra indent spaces on each line. */
695
#define PRINT_NUM_MAX_INDENT        48
696
/* Maximum size of a line containing a value. */
697
#define PRINT_NUM_MAX_VALUE_LINE    PRINT_NUM_MAX_INDENT
698
/* Number of leading spaces on each line. */
699
#define PRINT_NUM_INDENT_CNT        4
700
/* Indent spaces for number lines. */
701
#define PRINT_NUM_INDENT            "    "
702
/* 4 leading spaces and 15 bytes with colons is a complete line. */
703
#define PRINT_NUM_MAX_DIGIT_LINE   (PRINT_NUM_INDENT_CNT + 3 * 15)
704
705
/* Print indent to BIO.
706
 *
707
 * @param [in] bio      BIO object to write to.
708
 * @param [in] line     Buffer to put characters to before writing to BIO.
709
 * @param [in] lineLen  Length of buffer.
710
 * @return  1 on success.
711
 * @return  0 on failure.
712
 */
713
static int wolfssl_print_indent(WOLFSSL_BIO* bio, char* line, int lineLen,
714
    int indent)
715
{
716
    int ret = 1;
717
718
    if (indent > 0) {
719
        int len_wanted;
720
        /* Cap indent to buffer size to avoid format truncation warning */
721
        if (indent >= lineLen) {
722
            indent = lineLen - 1;
723
        }
724
        /* Print indent spaces. */
725
        len_wanted = XSNPRINTF(line, (size_t)lineLen, "%*s", indent, " ");
726
        if ((len_wanted < 0) || (len_wanted >= lineLen)) {
727
            WOLFSSL_ERROR_MSG("Buffer overflow formatting indentation");
728
            ret = 0;
729
        }
730
        else {
731
            /* Write indents string to BIO */
732
            if (wolfSSL_BIO_write(bio, line, len_wanted) <= 0) {
733
                ret = 0;
734
            }
735
        }
736
    }
737
738
    return ret;
739
}
740
741
/* Print out name, and value in decimal and hex to BIO.
742
 *
743
 * @param [in] bio     BIO object to write to.
744
 * @param [in] value   MP integer to write.
745
 * @param [in] name    Name of value.
746
 * @param [in] indent  Number of leading spaces before line.
747
 * @return  1 on success.
748
 * @return  0 on failure.
749
 */
750
static int wolfssl_print_value(WOLFSSL_BIO* bio, mp_int* value,
751
    const char* name, int indent)
752
{
753
    int ret = 1;
754
    int len;
755
    char line[PRINT_NUM_MAX_VALUE_LINE + 1];
756
757
    /* Get the length of hex encoded value. */
758
    len = mp_unsigned_bin_size(value);
759
    /* Value must no more than 32-bits - 4 bytes. */
760
    if ((len < 0) || (len > 4)) {
761
        WOLFSSL_ERROR_MSG("Error getting exponent size");
762
        ret = 0;
763
    }
764
    if (ret == 1) {
765
        /* Print any indent spaces. */
766
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
767
    }
768
    if (ret == 1) {
769
        /* Get 32-bits of value. */
770
        word32 v = (word32)value->dp[0];
771
        /* Print the line to the string. */
772
        len = (int)XSNPRINTF(line, sizeof(line), "%s %u (0x%x)\n", name, v,
773
            v);
774
        if (len >= (int)sizeof(line)) {
775
            WOLFSSL_ERROR_MSG("Buffer overflow while formatting value");
776
            ret = 0;
777
        } else {
778
            /* Write string to BIO */
779
            if (wolfSSL_BIO_write(bio, line, len) <= 0) {
780
                ret = 0;
781
            }
782
        }
783
    }
784
785
    return ret;
786
}
787
788
/* Print out name and multi-precision number to BIO.
789
 *
790
 * @param [in] bio     BIO object to write to.
791
 * @param [in] num     MP integer to write.
792
 * @param [in] name    Name of value.
793
 * @param [in] indent  Number of leading spaces before each line.
794
 * @return  1 on success.
795
 * @return  0 on failure.
796
 */
797
static int wolfssl_print_number(WOLFSSL_BIO* bio, mp_int* num, const char* name,
798
    int indent)
799
{
800
    int ret = 1;
801
    int rawLen = 0;
802
    byte* rawKey = NULL;
803
    char line[PRINT_NUM_MAX_DIGIT_LINE + 1];
804
    int li = 0; /* Line index. */
805
    int i;
806
807
    /* Allocate a buffer to hold binary encoded data. */
808
    rawLen = mp_unsigned_bin_size(num);
809
    if (rawLen == 0) {
810
        WOLFSSL_ERROR_MSG("Invalid number");
811
        ret = 0;
812
    }
813
    if (ret == 1) {
814
        rawKey = (byte*)XMALLOC((size_t)rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
815
        if (rawKey == NULL) {
816
            WOLFSSL_ERROR_MSG("Memory allocation error");
817
            ret = 0;
818
        }
819
    }
820
    /* Encode number as big-endian byte array. */
821
    if ((ret == 1) && (mp_to_unsigned_bin(num, rawKey) < 0)) {
822
        ret = 0;
823
    }
824
825
    if (ret == 1) {
826
        /* Print any indent spaces. */
827
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
828
    }
829
    if (ret == 1) {
830
        /* Print header string line to string. */
831
        li = XSNPRINTF(line, sizeof(line), "%s\n", name);
832
        if (li >= (int)sizeof(line)) {
833
            WOLFSSL_ERROR_MSG("Buffer overflow formatting name");
834
            ret = 0;
835
        }
836
        else {
837
            if (wolfSSL_BIO_write(bio, line, li) <= 0) {
838
                ret = 0;
839
            }
840
        }
841
    }
842
    if (ret == 1) {
843
        /* Print any indent spaces. */
844
        ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
845
    }
846
    if (ret == 1) {
847
        /* Start first digit line with spaces.
848
         * Writing out zeros ensures number is a positive value. */
849
        li = XSNPRINTF(line, sizeof(line), PRINT_NUM_INDENT "%s",
850
            mp_leading_bit(num) ?  "00:" : "");
851
        if (li >= (int)sizeof(line)) {
852
            WOLFSSL_ERROR_MSG("Buffer overflow formatting spaces");
853
            ret = 0;
854
        }
855
    }
856
857
    /* Put out each line of numbers. */
858
    for (i = 0; (ret == 1) && (i < rawLen); i++) {
859
        /* Encode another byte as 2 hex digits and append colon. */
860
        int len_wanted = XSNPRINTF(line + li, sizeof(line) - (size_t)li,
861
                                   "%02x:", rawKey[i]);
862
        /* Check if there was room -- if not, print the current line, not
863
         * including the newest octet.
864
         */
865
        if (len_wanted >= (int)sizeof(line) - li) {
866
            /* bump current octet to the next line. */
867
            --i;
868
            /* More bytes coming so add a line break. */
869
            line[li++] = '\n';
870
            /* Write out the line. */
871
            if (wolfSSL_BIO_write(bio, line, li) <= 0) {
872
                ret = 0;
873
            }
874
            if (ret == 1) {
875
                /* Print any indent spaces. */
876
                ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
877
            }
878
            /* Put the leading spaces on new line. */
879
            XSTRNCPY(line, PRINT_NUM_INDENT, PRINT_NUM_INDENT_CNT + 1);
880
            li = PRINT_NUM_INDENT_CNT;
881
        }
882
        else {
883
            li += len_wanted;
884
        }
885
    }
886
887
    if (ret == 1) {
888
        /* Put out last line - replace last colon with carriage return. */
889
        line[li-1] = '\n';
890
        if (wolfSSL_BIO_write(bio, line, li) <= 0) {
891
            ret = 0;
892
        }
893
    }
894
895
    /* Dispose of any allocated data. */
896
    XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
897
    return ret;
898
}
899
900
#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_BIO && !NO_RSA */
901
902
#endif /* OPENSSL_EXTRA */
903
904
#if !defined(NO_CERTS) || (defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || \
905
    (!defined(NO_DH) && defined(HAVE_FIPS) && !FIPS_VERSION_GT(2,0)) || \
906
    defined(HAVE_ECC)))
907
908
/* Uses the DER SEQUENCE to determine size of DER data.
909
 *
910
 * Outer SEQUENCE encapsulates all the DER encoding.
911
 * Add the length of the SEQUENCE data to the length of the SEQUENCE header.
912
 *
913
 * @param [in] seq  Buffer holding DER encoded sequence.
914
 * @param [in] len  Length of data in buffer (may be larger than SEQ).
915
 * @return  Size of complete DER encoding on success.
916
 * @return  0 on failure.
917
 */
918
static int wolfssl_der_length(const unsigned char* seq, int len)
919
0
{
920
0
    int ret = 0;
921
0
    word32 i = 0;
922
923
    /* Check it is a SEQUENCE and get the length of the underlying data.
924
     * i is updated to be after SEQUENCE header bytes.
925
     */
926
0
    if (GetSequence_ex(seq, &i, &ret, (word32)len, 0) >= 0) {
927
        /* Add SEQUENCE header length to underlying data length. */
928
0
        ret += (int)i;
929
0
    }
930
931
0
    return ret;
932
0
}
933
934
#endif
935
936
937
#define WOLFSSL_PK_RSA_INCLUDED
938
#include "src/pk_rsa.c"
939
940
941
/*******************************************************************************
942
 * START OF DSA API
943
 ******************************************************************************/
944
945
#ifndef NO_DSA
946
947
#if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
948
    !defined(NO_STDIO_FILESYSTEM)
949
/* return code compliant with OpenSSL :
950
 *   1 if success, 0 if error
951
 */
952
int wolfSSL_DSA_print_fp(XFILE fp, WOLFSSL_DSA* dsa, int indent)
953
{
954
    int ret = 1;
955
956
    WOLFSSL_ENTER("wolfSSL_DSA_print_fp");
957
958
    if (fp == XBADFILE || dsa == NULL) {
959
        ret = 0;
960
    }
961
962
    if (ret == 1 && dsa->p != NULL) {
963
        int pBits = wolfSSL_BN_num_bits(dsa->p);
964
        if (pBits == 0) {
965
            ret = 0;
966
        }
967
        else {
968
            if (XFPRINTF(fp, "%*s", indent, "") < 0)
969
                ret = 0;
970
            else if (XFPRINTF(fp, "Private-Key: (%d bit)\n", pBits) < 0)
971
                ret = 0;
972
        }
973
    }
974
    if (ret == 1 && dsa->priv_key != NULL) {
975
        ret = pk_bn_field_print_fp(fp, indent, "priv", dsa->priv_key);
976
    }
977
    if (ret == 1 && dsa->pub_key != NULL) {
978
        ret = pk_bn_field_print_fp(fp, indent, "pub", dsa->pub_key);
979
    }
980
    if (ret == 1 && dsa->p != NULL) {
981
        ret = pk_bn_field_print_fp(fp, indent, "P", dsa->p);
982
    }
983
    if (ret == 1 && dsa->q != NULL) {
984
        ret = pk_bn_field_print_fp(fp, indent, "Q", dsa->q);
985
    }
986
    if (ret == 1 && dsa->g != NULL) {
987
        ret = pk_bn_field_print_fp(fp, indent, "G", dsa->g);
988
    }
989
990
    WOLFSSL_LEAVE("wolfSSL_DSA_print_fp", ret);
991
992
    return ret;
993
}
994
#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_FILESYSTEM && NO_STDIO_FILESYSTEM */
995
996
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
997
static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
998
{
999
    if (dsa) {
1000
        dsa->p        = NULL;
1001
        dsa->q        = NULL;
1002
        dsa->g        = NULL;
1003
        dsa->pub_key  = NULL;
1004
        dsa->priv_key = NULL;
1005
        dsa->internal = NULL;
1006
        dsa->inSet    = 0;
1007
        dsa->exSet    = 0;
1008
    }
1009
}
1010
1011
1012
WOLFSSL_DSA* wolfSSL_DSA_new(void)
1013
{
1014
    WOLFSSL_DSA* external;
1015
    DsaKey*     key;
1016
1017
    WOLFSSL_MSG("wolfSSL_DSA_new");
1018
1019
    key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
1020
    if (key == NULL) {
1021
        WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
1022
        return NULL;
1023
    }
1024
1025
    external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
1026
                                    DYNAMIC_TYPE_DSA);
1027
    if (external == NULL) {
1028
        WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
1029
        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
1030
        return NULL;
1031
    }
1032
1033
    InitwolfSSL_DSA(external);
1034
    if (wc_InitDsaKey(key) != 0) {
1035
        WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
1036
        XFREE(key, NULL, DYNAMIC_TYPE_DSA);
1037
        wolfSSL_DSA_free(external);
1038
        return NULL;
1039
    }
1040
    external->internal = key;
1041
1042
    return external;
1043
}
1044
1045
1046
void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
1047
{
1048
    WOLFSSL_MSG("wolfSSL_DSA_free");
1049
1050
    if (dsa) {
1051
        if (dsa->internal) {
1052
            FreeDsaKey((DsaKey*)dsa->internal);
1053
            XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
1054
            dsa->internal = NULL;
1055
        }
1056
        wolfSSL_BN_free(dsa->priv_key);
1057
        wolfSSL_BN_free(dsa->pub_key);
1058
        wolfSSL_BN_free(dsa->g);
1059
        wolfSSL_BN_free(dsa->q);
1060
        wolfSSL_BN_free(dsa->p);
1061
        InitwolfSSL_DSA(dsa);  /* set back to NULLs for safety */
1062
1063
        XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
1064
1065
        /* dsa = NULL, don't try to access or double free it */
1066
    }
1067
}
1068
1069
/* wolfSSL -> OpenSSL */
1070
int SetDsaExternal(WOLFSSL_DSA* dsa)
1071
{
1072
    DsaKey* key;
1073
    WOLFSSL_MSG("Entering SetDsaExternal");
1074
1075
    if (dsa == NULL || dsa->internal == NULL) {
1076
        WOLFSSL_MSG("dsa key NULL error");
1077
        return WOLFSSL_FATAL_ERROR;
1078
    }
1079
1080
    key = (DsaKey*)dsa->internal;
1081
1082
    if (wolfssl_bn_set_value(&dsa->p, &key->p) != 1) {
1083
        WOLFSSL_MSG("dsa p key error");
1084
        return WOLFSSL_FATAL_ERROR;
1085
    }
1086
1087
    if (wolfssl_bn_set_value(&dsa->q, &key->q) != 1) {
1088
        WOLFSSL_MSG("dsa q key error");
1089
        return WOLFSSL_FATAL_ERROR;
1090
    }
1091
1092
    if (wolfssl_bn_set_value(&dsa->g, &key->g) != 1) {
1093
        WOLFSSL_MSG("dsa g key error");
1094
        return WOLFSSL_FATAL_ERROR;
1095
    }
1096
1097
    if (wolfssl_bn_set_value(&dsa->pub_key, &key->y) != 1) {
1098
        WOLFSSL_MSG("dsa y key error");
1099
        return WOLFSSL_FATAL_ERROR;
1100
    }
1101
1102
    if (wolfssl_bn_set_value(&dsa->priv_key, &key->x) != 1) {
1103
        WOLFSSL_MSG("dsa x key error");
1104
        return WOLFSSL_FATAL_ERROR;
1105
    }
1106
1107
    dsa->exSet = 1;
1108
1109
    return 1;
1110
}
1111
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1112
1113
#ifdef OPENSSL_EXTRA
1114
/* Openssl -> WolfSSL */
1115
int SetDsaInternal(WOLFSSL_DSA* dsa)
1116
{
1117
    DsaKey* key;
1118
    WOLFSSL_MSG("Entering SetDsaInternal");
1119
1120
    if (dsa == NULL || dsa->internal == NULL) {
1121
        WOLFSSL_MSG("dsa key NULL error");
1122
        return WOLFSSL_FATAL_ERROR;
1123
    }
1124
1125
    key = (DsaKey*)dsa->internal;
1126
1127
    if (dsa->p != NULL &&
1128
        wolfssl_bn_get_value(dsa->p, &key->p) != 1) {
1129
        WOLFSSL_MSG("rsa p key error");
1130
        return WOLFSSL_FATAL_ERROR;
1131
    }
1132
1133
    if (dsa->q != NULL &&
1134
        wolfssl_bn_get_value(dsa->q, &key->q) != 1) {
1135
        WOLFSSL_MSG("rsa q key error");
1136
        return WOLFSSL_FATAL_ERROR;
1137
    }
1138
1139
    if (dsa->g != NULL &&
1140
        wolfssl_bn_get_value(dsa->g, &key->g) != 1) {
1141
        WOLFSSL_MSG("rsa g key error");
1142
        return WOLFSSL_FATAL_ERROR;
1143
    }
1144
1145
    if (dsa->pub_key != NULL) {
1146
        if (wolfssl_bn_get_value(dsa->pub_key, &key->y) != 1) {
1147
            WOLFSSL_MSG("rsa pub_key error");
1148
            return WOLFSSL_FATAL_ERROR;
1149
        }
1150
1151
        /* public key */
1152
        key->type = DSA_PUBLIC;
1153
    }
1154
1155
    if (dsa->priv_key != NULL) {
1156
        if (wolfssl_bn_get_value(dsa->priv_key, &key->x) != 1) {
1157
            WOLFSSL_MSG("rsa priv_key error");
1158
            return WOLFSSL_FATAL_ERROR;
1159
        }
1160
1161
        /* private key */
1162
        key->type = DSA_PRIVATE;
1163
    }
1164
1165
    dsa->inSet = 1;
1166
1167
    return 1;
1168
}
1169
1170
/* return code compliant with OpenSSL :
1171
 *   1 if success, 0 if error
1172
 */
1173
int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
1174
{
1175
    int ret = 0;
1176
1177
    WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
1178
1179
    if (dsa == NULL || dsa->internal == NULL) {
1180
        WOLFSSL_MSG("Bad arguments");
1181
        return 0;
1182
    }
1183
1184
    if (dsa->inSet == 0) {
1185
        WOLFSSL_MSG("No DSA internal set, do it");
1186
1187
        if (SetDsaInternal(dsa) != 1) {
1188
            WOLFSSL_MSG("SetDsaInternal failed");
1189
            return ret;
1190
        }
1191
    }
1192
1193
#ifdef WOLFSSL_KEY_GEN
1194
    {
1195
        int initTmpRng = 0;
1196
        WC_RNG *rng = NULL;
1197
        WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
1198
1199
        WC_ALLOC_VAR_EX(tmpRng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
1200
            return WOLFSSL_FATAL_ERROR);
1201
        if (wc_InitRng(tmpRng) == 0) {
1202
            rng = tmpRng;
1203
            initTmpRng = 1;
1204
        }
1205
        else {
1206
            WOLFSSL_MSG("Bad RNG Init, trying global");
1207
            rng = wolfssl_get_global_rng();
1208
        }
1209
1210
        if (rng) {
1211
            /* These were allocated above by SetDsaInternal(). They should
1212
             * be cleared before wc_MakeDsaKey() which reinitializes
1213
             * x and y. */
1214
            mp_clear(&((DsaKey*)dsa->internal)->x);
1215
            mp_clear(&((DsaKey*)dsa->internal)->y);
1216
1217
            if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
1218
                WOLFSSL_MSG("wc_MakeDsaKey failed");
1219
            else if (SetDsaExternal(dsa) != 1)
1220
                WOLFSSL_MSG("SetDsaExternal failed");
1221
            else
1222
                ret = 1;
1223
        }
1224
1225
        if (initTmpRng)
1226
            wc_FreeRng(tmpRng);
1227
1228
        WC_FREE_VAR_EX(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1229
    }
1230
#else /* WOLFSSL_KEY_GEN */
1231
    WOLFSSL_MSG("No Key Gen built in");
1232
#endif
1233
    return ret;
1234
}
1235
1236
1237
/* Returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
1238
 */
1239
WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed,
1240
        int seedLen, int* counterRet, unsigned long* hRet,
1241
        WOLFSSL_BN_CB cb, void* CBArg)
1242
{
1243
    WOLFSSL_DSA* dsa;
1244
1245
    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters");
1246
1247
    (void)cb;
1248
    (void)CBArg;
1249
    dsa = wolfSSL_DSA_new();
1250
    if (dsa == NULL) {
1251
        return NULL;
1252
    }
1253
1254
    if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen,
1255
                                  counterRet, hRet, NULL) != 1) {
1256
        wolfSSL_DSA_free(dsa);
1257
        return NULL;
1258
    }
1259
1260
    return dsa;
1261
}
1262
1263
1264
/* return code compliant with OpenSSL :
1265
 *   1 if success, 0 if error
1266
 */
1267
int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
1268
                                       unsigned char* seed, int seedLen,
1269
                                       int* counterRet,
1270
                                       unsigned long* hRet, void* cb)
1271
{
1272
    int ret = 0;
1273
1274
    (void)bits;
1275
    (void)seed;
1276
    (void)seedLen;
1277
    (void)counterRet;
1278
    (void)hRet;
1279
    (void)cb;
1280
1281
    WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
1282
1283
    if (dsa == NULL || dsa->internal == NULL) {
1284
        WOLFSSL_MSG("Bad arguments");
1285
        return 0;
1286
    }
1287
1288
#ifdef WOLFSSL_KEY_GEN
1289
    {
1290
        int initTmpRng = 0;
1291
        WC_RNG *rng = NULL;
1292
        WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
1293
1294
        WC_ALLOC_VAR_EX(tmpRng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
1295
            return WOLFSSL_FATAL_ERROR);
1296
        if (wc_InitRng(tmpRng) == 0) {
1297
            rng = tmpRng;
1298
            initTmpRng = 1;
1299
        }
1300
        else {
1301
            WOLFSSL_MSG("Bad RNG Init, trying global");
1302
            rng = wolfssl_get_global_rng();
1303
        }
1304
1305
        if (rng) {
1306
            if (wc_MakeDsaParameters(rng, bits,
1307
                                     (DsaKey*)dsa->internal) != MP_OKAY)
1308
                WOLFSSL_MSG("wc_MakeDsaParameters failed");
1309
            else if (SetDsaExternal(dsa) != 1)
1310
                WOLFSSL_MSG("SetDsaExternal failed");
1311
            else
1312
                ret = 1;
1313
        }
1314
1315
        if (initTmpRng)
1316
            wc_FreeRng(tmpRng);
1317
1318
        WC_FREE_VAR_EX(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1319
    }
1320
#else /* WOLFSSL_KEY_GEN */
1321
    WOLFSSL_MSG("No Key Gen built in");
1322
#endif
1323
1324
    return ret;
1325
}
1326
1327
void wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA *d, const WOLFSSL_BIGNUM **p,
1328
        const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
1329
{
1330
    WOLFSSL_ENTER("wolfSSL_DSA_get0_pqg");
1331
    if (d != NULL) {
1332
        if (p != NULL)
1333
            *p = d->p;
1334
        if (q != NULL)
1335
            *q = d->q;
1336
        if (g != NULL)
1337
            *g = d->g;
1338
    }
1339
}
1340
1341
int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p,
1342
        WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
1343
{
1344
    WOLFSSL_ENTER("wolfSSL_DSA_set0_pqg");
1345
    if (d == NULL || p == NULL || q == NULL || g == NULL) {
1346
        WOLFSSL_MSG("Bad parameter");
1347
        return 0;
1348
    }
1349
    wolfSSL_BN_free(d->p);
1350
    wolfSSL_BN_free(d->q);
1351
    wolfSSL_BN_free(d->g);
1352
    d->p = p;
1353
    d->q = q;
1354
    d->g = g;
1355
    return 1;
1356
}
1357
1358
void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d,
1359
        const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key)
1360
{
1361
    WOLFSSL_ENTER("wolfSSL_DSA_get0_key");
1362
    if (d != NULL) {
1363
        if (pub_key != NULL)
1364
            *pub_key = d->pub_key;
1365
        if (priv_key != NULL)
1366
            *priv_key = d->priv_key;
1367
    }
1368
}
1369
1370
int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key,
1371
        WOLFSSL_BIGNUM *priv_key)
1372
{
1373
    WOLFSSL_ENTER("wolfSSL_DSA_set0_key");
1374
1375
    /* The private key may be NULL */
1376
    if (d->pub_key == NULL && pub_key == NULL) {
1377
        WOLFSSL_MSG("Bad parameter");
1378
        return 0;
1379
    }
1380
1381
    if (pub_key != NULL) {
1382
        wolfSSL_BN_free(d->pub_key);
1383
        d->pub_key = pub_key;
1384
    }
1385
    if (priv_key != NULL) {
1386
        wolfSSL_BN_free(d->priv_key);
1387
        d->priv_key = priv_key;
1388
    }
1389
1390
    return 1;
1391
}
1392
1393
WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void)
1394
{
1395
    WOLFSSL_DSA_SIG* sig;
1396
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_new");
1397
    sig = (WOLFSSL_DSA_SIG*)XMALLOC(sizeof(WOLFSSL_DSA_SIG), NULL,
1398
        DYNAMIC_TYPE_OPENSSL);
1399
    if (sig)
1400
        XMEMSET(sig, 0, sizeof(WOLFSSL_DSA_SIG));
1401
    return sig;
1402
}
1403
1404
void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig)
1405
{
1406
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_free");
1407
    if (sig) {
1408
        if (sig->r) {
1409
            wolfSSL_BN_free(sig->r);
1410
        }
1411
        if (sig->s) {
1412
            wolfSSL_BN_free(sig->s);
1413
        }
1414
        XFREE(sig, NULL, DYNAMIC_TYPE_OPENSSL);
1415
    }
1416
}
1417
1418
void wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG *sig,
1419
        const WOLFSSL_BIGNUM **r, const WOLFSSL_BIGNUM **s)
1420
{
1421
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_get0");
1422
    if (sig != NULL) {
1423
        *r = sig->r;
1424
        *s = sig->s;
1425
    }
1426
}
1427
1428
int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r,
1429
        WOLFSSL_BIGNUM *s)
1430
{
1431
    WOLFSSL_ENTER("wolfSSL_DSA_SIG_set0");
1432
    if (r == NULL || s == NULL) {
1433
        WOLFSSL_MSG("Bad parameter");
1434
        return 0;
1435
    }
1436
1437
    wolfSSL_BN_clear_free(sig->r);
1438
    wolfSSL_BN_clear_free(sig->s);
1439
    sig->r = r;
1440
    sig->s = s;
1441
1442
    return 1;
1443
}
1444
1445
#ifndef HAVE_SELFTEST
1446
/**
1447
 *
1448
 * @param sig The input signature to encode
1449
 * @param out The output buffer. If *out is NULL then a new buffer is
1450
 *            allocated. Otherwise the output is written to the buffer.
1451
 * @return length on success and -1 on error
1452
 */
1453
int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out)
1454
{
1455
    /* Space for sequence + two asn ints */
1456
    byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_MAX_HALF_SIZE)];
1457
    word32 bufLen = sizeof(buf);
1458
1459
    WOLFSSL_ENTER("wolfSSL_i2d_DSA_SIG");
1460
1461
    if (sig == NULL || sig->r == NULL || sig->s == NULL ||
1462
            out == NULL) {
1463
        WOLFSSL_MSG("Bad function arguments");
1464
        return WOLFSSL_FATAL_ERROR;
1465
    }
1466
1467
    if (StoreECC_DSA_Sig(buf, &bufLen,
1468
            (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != 0) {
1469
        WOLFSSL_MSG("StoreECC_DSA_Sig error");
1470
        return WOLFSSL_FATAL_ERROR;
1471
    }
1472
1473
    if (*out == NULL) {
1474
        byte* tmp = (byte*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_ASN1);
1475
        if (tmp == NULL) {
1476
            WOLFSSL_MSG("malloc error");
1477
            return WOLFSSL_FATAL_ERROR;
1478
        }
1479
        *out = tmp;
1480
    }
1481
1482
   XMEMCPY(*out, buf, bufLen);
1483
1484
    return (int)bufLen;
1485
}
1486
1487
/**
1488
 * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums.
1489
 * @return New WOLFSSL_DSA_SIG with r and s created as well
1490
 */
1491
static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void)
1492
{
1493
    WOLFSSL_DSA_SIG* ret;
1494
1495
    if ((ret = wolfSSL_DSA_SIG_new()) == NULL) {
1496
        WOLFSSL_MSG("wolfSSL_DSA_SIG_new error");
1497
        return NULL;
1498
    }
1499
1500
    if ((ret->r = wolfSSL_BN_new()) == NULL) {
1501
        WOLFSSL_MSG("wolfSSL_BN_new error");
1502
        wolfSSL_DSA_SIG_free(ret);
1503
        return NULL;
1504
    }
1505
1506
    if ((ret->s = wolfSSL_BN_new()) == NULL) {
1507
        WOLFSSL_MSG("wolfSSL_BN_new error");
1508
        wolfSSL_DSA_SIG_free(ret);
1509
        return NULL;
1510
    }
1511
1512
    return ret;
1513
}
1514
1515
/**
1516
 * This parses a DER encoded ASN.1 structure. The ASN.1 encoding is:
1517
 * ASN1_SEQUENCE
1518
 *   ASN1_INTEGER (DSA r)
1519
 *   ASN1_INTEGER (DSA s)
1520
 * Alternatively, if the input is DSA_160_SIG_SIZE or DSA_256_SIG_SIZE in
1521
 * length then this API interprets this as two unsigned binary numbers.
1522
 * @param sig    If non-null then free'd first and then newly created
1523
 *               WOLFSSL_DSA_SIG is assigned
1524
 * @param pp     Input buffer that is moved forward on success
1525
 * @param length Length of input buffer
1526
 * @return Newly created WOLFSSL_DSA_SIG on success or NULL on failure
1527
 */
1528
WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig,
1529
        const unsigned char **pp, long length)
1530
{
1531
    WOLFSSL_DSA_SIG* ret;
1532
    mp_int* r;
1533
    mp_int* s;
1534
1535
    WOLFSSL_ENTER("wolfSSL_d2i_DSA_SIG");
1536
1537
    if (pp == NULL || *pp == NULL || length < 0) {
1538
        WOLFSSL_MSG("Bad function arguments");
1539
        return NULL;
1540
    }
1541
1542
    if ((ret = wolfSSL_DSA_SIG_new_bn()) == NULL) {
1543
        WOLFSSL_MSG("wolfSSL_DSA_SIG_new_bn error");
1544
        return NULL;
1545
    }
1546
1547
    r = (mp_int*)ret->r->internal;
1548
    s = (mp_int*)ret->s->internal;
1549
1550
    if (DecodeECC_DSA_Sig(*pp, (word32)length, r, s) != 0) {
1551
        if (length == DSA_160_SIG_SIZE || length == DSA_256_SIG_SIZE) {
1552
            /* Two raw numbers of length/2 size each */
1553
            if (mp_read_unsigned_bin(r, *pp, (word32)length/2) != 0) {
1554
                WOLFSSL_MSG("r mp_read_unsigned_bin error");
1555
                wolfSSL_DSA_SIG_free(ret);
1556
                return NULL;
1557
            }
1558
1559
            if (mp_read_unsigned_bin(s, *pp + (length/2), (word32)length/2) !=
1560
                    0) {
1561
                WOLFSSL_MSG("s mp_read_unsigned_bin error");
1562
                wolfSSL_DSA_SIG_free(ret);
1563
                return NULL;
1564
            }
1565
1566
            *pp += length;
1567
        }
1568
        else {
1569
            WOLFSSL_MSG("DecodeECC_DSA_Sig error");
1570
            wolfSSL_DSA_SIG_free(ret);
1571
            return NULL;
1572
        }
1573
    }
1574
    else {
1575
        /* DecodeECC_DSA_Sig success move pointer forward */
1576
#ifndef NO_STRICT_ECDSA_LEN
1577
        *pp += length;
1578
#else
1579
        {
1580
            /* We need to figure out how much to move by ourselves */
1581
            word32 idx = 0;
1582
            int len = 0;
1583
            if (GetSequence(*pp, &idx, &len, (word32)length) < 0) {
1584
                WOLFSSL_MSG("GetSequence error");
1585
                wolfSSL_DSA_SIG_free(ret);
1586
                return NULL;
1587
            }
1588
            *pp += len;
1589
        }
1590
#endif
1591
    }
1592
1593
    if (sig != NULL) {
1594
        if (*sig != NULL)
1595
            wolfSSL_DSA_SIG_free(*sig);
1596
        *sig = ret;
1597
    }
1598
1599
    return ret;
1600
}
1601
1602
#endif /* !HAVE_SELFTEST */
1603
1604
static int dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet,
1605
        WOLFSSL_DSA* dsa)
1606
{
1607
    int     ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1608
    int     initTmpRng = 0;
1609
    WC_RNG* rng = NULL;
1610
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
1611
1612
    if (d == NULL || sigRet == NULL || dsa == NULL) {
1613
        WOLFSSL_MSG("Bad function arguments");
1614
        return WOLFSSL_FATAL_ERROR;
1615
    }
1616
1617
    if (dsa->inSet == 0) {
1618
        WOLFSSL_MSG("No DSA internal set, do it");
1619
        if (SetDsaInternal(dsa) != 1) {
1620
            WOLFSSL_MSG("SetDsaInternal failed");
1621
            return WOLFSSL_FATAL_ERROR;
1622
        }
1623
    }
1624
1625
    WC_ALLOC_VAR_EX(tmpRng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
1626
        return WOLFSSL_FATAL_ERROR);
1627
1628
    if (wc_InitRng(tmpRng) == 0) {
1629
        rng = tmpRng;
1630
        initTmpRng = 1;
1631
    }
1632
    else {
1633
        WOLFSSL_MSG("Bad RNG Init, trying global");
1634
#ifdef WOLFSSL_SMALL_STACK
1635
        XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1636
        tmpRng = NULL;
1637
#endif
1638
        rng = wolfssl_get_global_rng();
1639
        if (! rng)
1640
            return WOLFSSL_FATAL_ERROR;
1641
    }
1642
1643
    if (rng) {
1644
#ifdef HAVE_SELFTEST
1645
        if (dLen != WC_SHA_DIGEST_SIZE ||
1646
                wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
1647
            WOLFSSL_MSG("wc_DsaSign failed or dLen wrong length");
1648
            ret = WOLFSSL_FATAL_ERROR;
1649
        }
1650
#else
1651
        if (wc_DsaSign_ex(d, dLen, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
1652
            WOLFSSL_MSG("wc_DsaSign_ex failed");
1653
            ret = WOLFSSL_FATAL_ERROR;
1654
        }
1655
#endif
1656
        else
1657
            ret = WOLFSSL_SUCCESS;
1658
    }
1659
1660
    if (initTmpRng)
1661
        wc_FreeRng(tmpRng);
1662
    WC_FREE_VAR_EX(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1663
1664
    return ret;
1665
}
1666
1667
/* return 1 on success, < 0 otherwise */
1668
int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
1669
                       WOLFSSL_DSA* dsa)
1670
{
1671
    WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
1672
1673
    return dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa);
1674
}
1675
1676
#ifndef HAVE_SELFTEST
1677
WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
1678
                                        int inLen, WOLFSSL_DSA* dsa)
1679
{
1680
    byte sigBin[DSA_MAX_SIG_SIZE];
1681
    const byte *tmp = sigBin;
1682
    int sigLen;
1683
1684
    WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
1685
1686
    if (!digest || !dsa) {
1687
        WOLFSSL_MSG("Bad function arguments");
1688
        return NULL;
1689
    }
1690
1691
    if (dsa_do_sign(digest, inLen, sigBin, dsa) != 1) {
1692
        WOLFSSL_MSG("wolfSSL_DSA_do_sign error");
1693
        return NULL;
1694
    }
1695
1696
    if (dsa->internal == NULL) {
1697
        WOLFSSL_MSG("dsa->internal is null");
1698
        return NULL;
1699
    }
1700
1701
    sigLen = mp_unsigned_bin_size(&((DsaKey*)dsa->internal)->q);
1702
    if (sigLen <= 0) {
1703
        WOLFSSL_MSG("mp_unsigned_bin_size error");
1704
        return NULL;
1705
    }
1706
1707
    /* 2 * sigLen for the two points r and s */
1708
    return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen);
1709
}
1710
#endif
1711
1712
static int dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig,
1713
                        WOLFSSL_DSA* dsa, int *dsacheck)
1714
{
1715
    int    ret;
1716
1717
    if (d == NULL || sig == NULL || dsa == NULL) {
1718
        WOLFSSL_MSG("Bad function arguments");
1719
        return WOLFSSL_FATAL_ERROR;
1720
    }
1721
    if (dsa->inSet == 0)
1722
    {
1723
        WOLFSSL_MSG("No DSA internal set, do it");
1724
1725
        if (SetDsaInternal(dsa) != 1) {
1726
            WOLFSSL_MSG("SetDsaInternal failed");
1727
            return WOLFSSL_FATAL_ERROR;
1728
        }
1729
    }
1730
1731
#ifdef HAVE_SELFTEST
1732
    ret = dLen == WC_SHA_DIGEST_SIZE ?
1733
          wc_DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck) : BAD_FUNC_ARG;
1734
#else
1735
    ret = wc_DsaVerify_ex(d, (word32)dLen, sig, (DsaKey*)dsa->internal,
1736
        dsacheck);
1737
#endif
1738
    if (ret != 0) {
1739
        WOLFSSL_MSG("DsaVerify failed");
1740
        return WOLFSSL_FATAL_ERROR;
1741
    }
1742
    if (*dsacheck != 1) {
1743
        WOLFSSL_MSG("DsaVerify sig failed");
1744
        return WOLFSSL_FAILURE;
1745
    }
1746
1747
    return WOLFSSL_SUCCESS;
1748
}
1749
1750
int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
1751
                        WOLFSSL_DSA* dsa, int *dsacheck)
1752
{
1753
    WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
1754
1755
    return dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck);
1756
}
1757
1758
1759
int wolfSSL_DSA_bits(const WOLFSSL_DSA *d)
1760
{
1761
    if (!d)
1762
        return 0;
1763
    if (!d->exSet && SetDsaExternal((WOLFSSL_DSA*)d) != 1)
1764
        return 0;
1765
    return wolfSSL_BN_num_bits(d->p);
1766
}
1767
1768
#ifndef HAVE_SELFTEST
1769
int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
1770
                             WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa)
1771
{
1772
    int dsacheck, sz;
1773
    byte sigBin[DSA_MAX_SIG_SIZE];
1774
    byte* sigBinPtr = sigBin;
1775
    DsaKey* key;
1776
    int qSz;
1777
1778
    WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
1779
1780
    if (!digest || !sig || !dsa) {
1781
        WOLFSSL_MSG("Bad function arguments");
1782
        return 0;
1783
    }
1784
1785
    if (!sig->r || !sig->s) {
1786
        WOLFSSL_MSG("No signature found in DSA_SIG");
1787
        return 0;
1788
    }
1789
1790
    if (dsa->inSet == 0) {
1791
        WOLFSSL_MSG("No DSA internal set, do it");
1792
        if (SetDsaInternal(dsa) != 1) {
1793
            WOLFSSL_MSG("SetDsaInternal failed");
1794
            return 0;
1795
        }
1796
    }
1797
1798
    key = (DsaKey*)dsa->internal;
1799
1800
    if (key == NULL) {
1801
        WOLFSSL_MSG("dsa->internal is null");
1802
        return 0;
1803
    }
1804
1805
    qSz = mp_unsigned_bin_size(&key->q);
1806
    if (qSz < 0 || qSz > DSA_MAX_HALF_SIZE) {
1807
        WOLFSSL_MSG("mp_unsigned_bin_size error");
1808
        return 0;
1809
    }
1810
1811
    /* read r */
1812
    /* front pad with zeros */
1813
    if ((sz = wolfSSL_BN_num_bytes(sig->r)) < 0 || sz > DSA_MAX_HALF_SIZE)
1814
        return 0;
1815
    while (sz++ < qSz)
1816
        *sigBinPtr++ = 0;
1817
    if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == -1)
1818
        return 0;
1819
1820
    /* Move to s */
1821
    sigBinPtr = sigBin + qSz;
1822
1823
    /* read s */
1824
    /* front pad with zeros */
1825
    if ((sz = wolfSSL_BN_num_bytes(sig->s)) < 0 || sz > DSA_MAX_HALF_SIZE)
1826
        return 0;
1827
    while (sz++ < qSz)
1828
        *sigBinPtr++ = 0;
1829
    if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1)
1830
        return 0;
1831
1832
    if ((dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck)
1833
                                         != 1) || dsacheck != 1) {
1834
        return 0;
1835
    }
1836
1837
    return 1;
1838
}
1839
#endif
1840
1841
int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
1842
    unsigned char** out)
1843
{
1844
    int ret = 0;
1845
    word32 derLen = 0;
1846
    int preAllocated = 1;
1847
    DsaKey* key = NULL;
1848
1849
    WOLFSSL_ENTER("wolfSSL_i2d_DSAparams");
1850
1851
    if (dsa == NULL || dsa->internal == NULL || out == NULL) {
1852
        ret = BAD_FUNC_ARG;
1853
    }
1854
1855
    if (ret == 0) {
1856
        key = (DsaKey*)dsa->internal;
1857
        ret = wc_DsaKeyToParamsDer_ex(key, NULL, &derLen);
1858
        if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
1859
            ret = 0;
1860
        }
1861
    }
1862
    if (ret == 0 && *out == NULL) {
1863
        /* If we're allocating out for the caller, we don't increment out just
1864
           past the end of the DER buffer. If out is already allocated, we do.
1865
           (OpenSSL convention) */
1866
        preAllocated = 0;
1867
        *out = (unsigned char*)XMALLOC(derLen, key->heap, DYNAMIC_TYPE_OPENSSL);
1868
        if (*out == NULL) {
1869
            ret = MEMORY_E;
1870
        }
1871
    }
1872
    if (ret == 0) {
1873
        ret = wc_DsaKeyToParamsDer_ex(key, *out, &derLen);
1874
    }
1875
    if (ret >= 0 && preAllocated == 1) {
1876
        *out += derLen;
1877
    }
1878
1879
    if (ret < 0 && preAllocated == 0) {
1880
        XFREE(*out, key ? key->heap : NULL, DYNAMIC_TYPE_OPENSSL);
1881
    }
1882
1883
    WOLFSSL_LEAVE("wolfSSL_i2d_DSAparams", ret);
1884
1885
    return ret;
1886
}
1887
1888
WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa, const unsigned char** der,
1889
    long derLen)
1890
{
1891
    WOLFSSL_DSA* ret = NULL;
1892
    int err = 0;
1893
    word32 idx = 0;
1894
    int asnLen;
1895
    DsaKey* internalKey = NULL;
1896
1897
    WOLFSSL_ENTER("wolfSSL_d2i_DSAparams");
1898
1899
    if (der == NULL || *der == NULL || derLen <= 0) {
1900
        err = 1;
1901
    }
1902
    if (err == 0) {
1903
        ret = wolfSSL_DSA_new();
1904
        err = ret == NULL;
1905
    }
1906
    if (err == 0) {
1907
        err = GetSequence(*der, &idx, &asnLen, (word32)derLen) <= 0;
1908
    }
1909
    if (err == 0) {
1910
        internalKey = (DsaKey*)ret->internal;
1911
        err = GetInt(&internalKey->p, *der, &idx, (word32)derLen) != 0;
1912
    }
1913
    if (err == 0) {
1914
        err = GetInt(&internalKey->q, *der, &idx, (word32)derLen) != 0;
1915
    }
1916
    if (err == 0) {
1917
        err = GetInt(&internalKey->g, *der, &idx, (word32)derLen) != 0;
1918
    }
1919
    if (err == 0) {
1920
        err = wolfssl_bn_set_value(&ret->p, &internalKey->p)
1921
                != 1;
1922
    }
1923
    if (err == 0) {
1924
        err = wolfssl_bn_set_value(&ret->q, &internalKey->q)
1925
                != 1;
1926
    }
1927
    if (err == 0) {
1928
        err = wolfssl_bn_set_value(&ret->g, &internalKey->g)
1929
                != 1;
1930
    }
1931
    if (err == 0 && dsa != NULL) {
1932
        *dsa = ret;
1933
    }
1934
1935
    if (err != 0 && ret != NULL) {
1936
        wolfSSL_DSA_free(ret);
1937
        ret = NULL;
1938
    }
1939
1940
    return ret;
1941
}
1942
1943
#if defined(WOLFSSL_KEY_GEN)
1944
#ifndef NO_BIO
1945
1946
/* Takes a DSA Privatekey and writes it out to a WOLFSSL_BIO
1947
 * Returns 1 or 0
1948
 */
1949
int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
1950
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
1951
    wc_pem_password_cb* cb, void* arg)
1952
{
1953
    int ret = 1;
1954
    byte *pem = NULL;
1955
    int pLen = 0;
1956
1957
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSAPrivateKey");
1958
1959
    (void)cb;
1960
    (void)arg;
1961
1962
    /* Validate parameters. */
1963
    if ((bio == NULL) || (dsa == NULL)) {
1964
        WOLFSSL_MSG("Bad Function Arguments");
1965
        ret = 0;
1966
    }
1967
1968
    if (ret == 1) {
1969
        ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, cipher, passwd, passwdSz,
1970
            &pem, &pLen);
1971
    }
1972
1973
    /* Write PEM to BIO. */
1974
    if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) != pLen)) {
1975
        WOLFSSL_ERROR_MSG("DSA private key BIO write failed");
1976
        ret = 0;
1977
    }
1978
1979
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
1980
    return ret;
1981
}
1982
1983
#ifndef HAVE_SELFTEST
1984
/* Encode the DSA public key as DER.
1985
 *
1986
 * @param [in]  key   DSA key to encode.
1987
 * @param [out] der   Pointer through which buffer is returned.
1988
 * @param [in]  heap  Heap hint.
1989
 * @return  Size of encoding on success.
1990
 * @return  0 on error.
1991
 */
1992
static int wolfssl_dsa_key_to_pubkey_der(WOLFSSL_DSA* key, unsigned char** der,
1993
    void* heap)
1994
{
1995
    int sz;
1996
    unsigned char* buf = NULL;
1997
1998
    /* Use maximum encoded size to allocate. */
1999
    sz = MAX_DSA_PUBKEY_SZ;
2000
    /* Allocate memory to hold encoding. */
2001
    buf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
2002
    if (buf == NULL) {
2003
        WOLFSSL_MSG("malloc failed");
2004
        sz = 0;
2005
    }
2006
    if (sz > 0) {
2007
        /* Encode public key to DER using wolfSSL.  */
2008
        sz = wc_DsaKeyToPublicDer((DsaKey*)key->internal, buf, (word32)sz);
2009
        if (sz < 0) {
2010
            WOLFSSL_MSG("wc_DsaKeyToPublicDer failed");
2011
            sz = 0;
2012
        }
2013
    }
2014
2015
    /* Return buffer on success. */
2016
    if (sz > 0) {
2017
        *der = buf;
2018
    }
2019
    else {
2020
        /* Dispose of any dynamically allocated data not returned. */
2021
        XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
2022
    }
2023
2024
    return sz;
2025
}
2026
2027
/* Takes a DSA public key and writes it out to a WOLFSSL_BIO
2028
 * Returns 1 or 0
2029
 */
2030
int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa)
2031
{
2032
    int ret = 1;
2033
    unsigned char* derBuf = NULL;
2034
    int derSz = 0;
2035
2036
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSA_PUBKEY");
2037
2038
    /* Validate parameters. */
2039
    if ((bio == NULL) || (dsa == NULL)) {
2040
        WOLFSSL_MSG("Bad Function Arguments");
2041
        return 0;
2042
    }
2043
2044
    /* Encode public key in EC key as DER. */
2045
    derSz = wolfssl_dsa_key_to_pubkey_der(dsa, &derBuf, bio->heap);
2046
    if (derSz == 0) {
2047
        ret = 0;
2048
    }
2049
2050
    /* Write out to BIO the PEM encoding of the DSA public key. */
2051
    if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
2052
            PUBLICKEY_TYPE) != 1)) {
2053
        ret = 0;
2054
    }
2055
2056
    /* Dispose of any dynamically allocated data. */
2057
    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
2058
2059
    return ret;
2060
}
2061
#endif /* HAVE_SELFTEST */
2062
#endif /* !NO_BIO */
2063
2064
/* return code compliant with OpenSSL :
2065
 *   1 if success, 0 if error
2066
 */
2067
int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
2068
                                        const WOLFSSL_EVP_CIPHER* cipher,
2069
                                        unsigned char* passwd, int passwdSz,
2070
                                        unsigned char **pem, int *pLen)
2071
{
2072
#if (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
2073
    !defined(NO_MD5)
2074
    byte *derBuf, *tmp, *cipherInfo = NULL;
2075
    int  der_max_len = 0, derSz = 0;
2076
    const int type = DSA_PRIVATEKEY_TYPE;
2077
    const char* header = NULL;
2078
    const char* footer = NULL;
2079
2080
    WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
2081
2082
    if (pem == NULL || pLen == NULL || dsa == NULL || dsa->internal == NULL) {
2083
        WOLFSSL_MSG("Bad function arguments");
2084
        return 0;
2085
    }
2086
2087
    if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
2088
        return 0;
2089
2090
    if (dsa->inSet == 0) {
2091
        WOLFSSL_MSG("No DSA internal set, do it");
2092
2093
        if (SetDsaInternal(dsa) != 1) {
2094
            WOLFSSL_MSG("SetDsaInternal failed");
2095
            return 0;
2096
        }
2097
    }
2098
2099
    der_max_len = MAX_DSA_PRIVKEY_SZ;
2100
2101
    derBuf = (byte*)XMALLOC((size_t)der_max_len, NULL, DYNAMIC_TYPE_DER);
2102
    if (derBuf == NULL) {
2103
        WOLFSSL_MSG("malloc failed");
2104
        return 0;
2105
    }
2106
2107
    /* Key to DER */
2108
    derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, (word32)der_max_len);
2109
    if (derSz < 0) {
2110
        WOLFSSL_MSG("wc_DsaKeyToDer failed");
2111
        ForceZero(derBuf, (word32)der_max_len);
2112
        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2113
        return 0;
2114
    }
2115
2116
    /* encrypt DER buffer if required */
2117
    if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
2118
        int ret;
2119
2120
        ret = EncryptDerKey(derBuf, &derSz, cipher, passwd, passwdSz,
2121
            &cipherInfo, der_max_len, WC_MD5);
2122
        if (ret != 1) {
2123
            WOLFSSL_MSG("EncryptDerKey failed");
2124
            ForceZero(derBuf, (word32)der_max_len);
2125
            XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2126
            return ret;
2127
        }
2128
        /* tmp buffer with a max size */
2129
        *pLen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
2130
            (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
2131
    }
2132
    else { /* tmp buffer with a max size */
2133
        *pLen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
2134
            (int)XSTRLEN(footer) + 1;
2135
    }
2136
2137
    tmp = (byte*)XMALLOC((size_t)*pLen, NULL, DYNAMIC_TYPE_PEM);
2138
    if (tmp == NULL) {
2139
        WOLFSSL_MSG("malloc failed");
2140
        ForceZero(derBuf, (word32)der_max_len);
2141
        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2142
        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
2143
        return 0;
2144
    }
2145
2146
    /* DER to PEM */
2147
    *pLen = wc_DerToPemEx(derBuf, (word32)derSz, tmp, (word32)*pLen, cipherInfo,
2148
        type);
2149
    if (*pLen <= 0) {
2150
        WOLFSSL_MSG("wc_DerToPemEx failed");
2151
        ForceZero(derBuf, (word32)der_max_len);
2152
        XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2153
        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2154
        XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
2155
        return 0;
2156
    }
2157
    ForceZero(derBuf, (word32)der_max_len);
2158
    XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2159
    XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
2160
2161
    *pem = (byte*)XMALLOC((size_t)((*pLen)+1), NULL, DYNAMIC_TYPE_KEY);
2162
    if (*pem == NULL) {
2163
        WOLFSSL_MSG("malloc failed");
2164
        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2165
        return 0;
2166
    }
2167
    XMEMSET(*pem, 0, (size_t)((*pLen)+1));
2168
2169
    if (XMEMCPY(*pem, tmp, (size_t)*pLen) == NULL) {
2170
        WOLFSSL_MSG("XMEMCPY failed");
2171
        XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
2172
        XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2173
        return 0;
2174
    }
2175
    XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2176
2177
    return 1;
2178
#else
2179
    (void)dsa;
2180
    (void)cipher;
2181
    (void)passwd;
2182
    (void)passwdSz;
2183
    (void)pem;
2184
    (void)pLen;
2185
    return 0;
2186
#endif /* (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) && !NO_MD5 */
2187
}
2188
2189
#ifndef NO_FILESYSTEM
2190
/* return code compliant with OpenSSL :
2191
 *   1 if success, 0 if error
2192
 */
2193
int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
2194
                                    const WOLFSSL_EVP_CIPHER *enc,
2195
                                    unsigned char *kstr, int klen,
2196
                                    wc_pem_password_cb *cb, void *u)
2197
{
2198
    byte *pem;
2199
    int  pLen, ret;
2200
2201
    (void)cb;
2202
    (void)u;
2203
2204
    WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
2205
2206
    if (fp == XBADFILE || dsa == NULL || dsa->internal == NULL) {
2207
        WOLFSSL_MSG("Bad function arguments");
2208
        return 0;
2209
    }
2210
2211
    ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem,
2212
        &pLen);
2213
    if (ret != 1) {
2214
        WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
2215
        return 0;
2216
    }
2217
2218
    ret = (int)XFWRITE(pem, (size_t)pLen, 1, fp);
2219
    if (ret != 1) {
2220
        WOLFSSL_MSG("DSA private key file write failed");
2221
        return 0;
2222
    }
2223
2224
    XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
2225
    return 1;
2226
}
2227
2228
#endif /* NO_FILESYSTEM */
2229
#endif /* defined(WOLFSSL_KEY_GEN) */
2230
2231
#ifndef NO_FILESYSTEM
2232
/* return code compliant with OpenSSL :
2233
 *   1 if success, 0 if error
2234
 */
2235
#ifndef NO_WOLFSSL_STUB
2236
int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x)
2237
{
2238
    (void)fp;
2239
    (void)x;
2240
    WOLFSSL_STUB("PEM_write_DSA_PUBKEY");
2241
    WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
2242
2243
    return 0;
2244
}
2245
#endif
2246
#endif /* NO_FILESYSTEM */
2247
2248
#ifndef NO_BIO
2249
2250
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && (!defined(NO_CERTS) && \
2251
       !defined(NO_FILESYSTEM) && defined(WOLFSSL_KEY_GEN))
2252
/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
2253
 * the results to be an DSA key.
2254
 *
2255
 * bio  structure to read DSA private key from
2256
 * dsa  if not null is then set to the result
2257
 * cb   password callback for reading PEM
2258
 * pass password string
2259
 *
2260
 * returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
2261
 */
2262
WOLFSSL_DSA* wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO* bio,
2263
                                                WOLFSSL_DSA** dsa,
2264
                                                wc_pem_password_cb* cb,
2265
                                                void* pass)
2266
{
2267
    WOLFSSL_EVP_PKEY* pkey = NULL;
2268
    WOLFSSL_DSA* local;
2269
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAPrivateKey");
2270
2271
2272
    pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
2273
    if (pkey == NULL) {
2274
        WOLFSSL_MSG("Error in PEM_read_bio_PrivateKey");
2275
         return NULL;
2276
     }
2277
     /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
2278
     * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
2279
     * to avoid having it free'd */
2280
    pkey->ownDsa = 0;
2281
    local = pkey->dsa;
2282
    if (dsa != NULL) {
2283
        *dsa = local;
2284
    }
2285
     wolfSSL_EVP_PKEY_free(pkey);
2286
    return local;
2287
}
2288
2289
/* Reads an DSA public key from a WOLFSSL_BIO into a WOLFSSL_DSA.
2290
 * Returns 1 or 0
2291
 */
2292
WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa,
2293
                                             wc_pem_password_cb* cb, void* pass)
2294
{
2295
    WOLFSSL_EVP_PKEY* pkey;
2296
    WOLFSSL_DSA* local;
2297
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSA_PUBKEY");
2298
2299
    pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
2300
    if (pkey == NULL) {
2301
        WOLFSSL_MSG("wolfSSL_PEM_read_bio_PUBKEY failed");
2302
        return NULL;
2303
    }
2304
2305
    /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
2306
     * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
2307
     * to avoid having it free'd */
2308
    pkey->ownDsa = 0;
2309
    local = pkey->dsa;
2310
    if (dsa != NULL) {
2311
        *dsa = local;
2312
    }
2313
2314
    wolfSSL_EVP_PKEY_free(pkey);
2315
    return local;
2316
}
2317
#endif /* (OPENSSL_EXTRA || OPENSSL_ALL) && (!NO_CERTS &&
2318
          !NO_FILESYSTEM && WOLFSSL_KEY_GEN) */
2319
2320
#endif /* NO_BIO */
2321
2322
#endif /* OPENSSL_EXTRA */
2323
2324
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2325
/* return 1 if success, -1 if error */
2326
int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
2327
    int derSz)
2328
{
2329
    word32 idx = 0;
2330
    int    ret;
2331
2332
    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
2333
2334
    if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
2335
        WOLFSSL_MSG("Bad function arguments");
2336
        return WOLFSSL_FATAL_ERROR;
2337
    }
2338
2339
    ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
2340
        (word32)derSz);
2341
    if (ret < 0) {
2342
        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
2343
        return WOLFSSL_FATAL_ERROR;
2344
    }
2345
2346
    if (SetDsaExternal(dsa) != 1) {
2347
        WOLFSSL_MSG("SetDsaExternal failed");
2348
        return WOLFSSL_FATAL_ERROR;
2349
    }
2350
2351
    dsa->inSet = 1;
2352
2353
    return 1;
2354
}
2355
2356
/* Loads DSA key from DER buffer. opt = DSA_LOAD_PRIVATE or DSA_LOAD_PUBLIC.
2357
    returns 1 on success, or 0 on failure.  */
2358
int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
2359
                                                            int derSz, int opt)
2360
{
2361
    word32 idx = 0;
2362
    int    ret;
2363
2364
    WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
2365
2366
    if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
2367
        WOLFSSL_MSG("Bad function arguments");
2368
        return WOLFSSL_FATAL_ERROR;
2369
    }
2370
2371
    if (opt == WOLFSSL_DSA_LOAD_PRIVATE) {
2372
        ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
2373
            (word32)derSz);
2374
    }
2375
    else {
2376
        ret = DsaPublicKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
2377
            (word32)derSz);
2378
    }
2379
2380
    if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PRIVATE) {
2381
        WOLFSSL_ERROR_VERBOSE(ret);
2382
        WOLFSSL_MSG("DsaPrivateKeyDecode failed");
2383
        return WOLFSSL_FATAL_ERROR;
2384
    }
2385
    else if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PUBLIC) {
2386
        WOLFSSL_ERROR_VERBOSE(ret);
2387
        WOLFSSL_MSG("DsaPublicKeyDecode failed");
2388
        return WOLFSSL_FATAL_ERROR;
2389
    }
2390
2391
    if (SetDsaExternal(dsa) != 1) {
2392
        WOLFSSL_MSG("SetDsaExternal failed");
2393
        return WOLFSSL_FATAL_ERROR;
2394
    }
2395
2396
    dsa->inSet = 1;
2397
2398
    return 1;
2399
}
2400
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
2401
2402
#ifdef OPENSSL_EXTRA
2403
#ifndef NO_BIO
2404
WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
2405
        wc_pem_password_cb *cb, void *u)
2406
{
2407
    WOLFSSL_DSA* dsa;
2408
    DsaKey* key;
2409
    int    length;
2410
    unsigned char*  buf;
2411
    word32 bufSz;
2412
    int ret;
2413
    word32 idx = 0;
2414
    DerBuffer* pDer;
2415
2416
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
2417
2418
    ret = wolfSSL_BIO_get_mem_data(bp, &buf);
2419
    if (ret <= 0) {
2420
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
2421
        return NULL;
2422
    }
2423
2424
    bufSz = (word32)ret;
2425
2426
    if (cb != NULL || u != NULL) {
2427
        /*
2428
         * cb is for a call back when encountering encrypted PEM files
2429
         * if cb == NULL and u != NULL then u = null terminated password string
2430
         */
2431
        WOLFSSL_MSG("Not supporting callback or password for encrypted PEM");
2432
    }
2433
2434
    if (PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
2435
                    NULL) < 0 ) {
2436
        WOLFSSL_MSG("Issue converting from PEM to DER");
2437
        return NULL;
2438
    }
2439
2440
    if (GetSequence(pDer->buffer, &idx, &length, pDer->length) < 0) {
2441
        WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
2442
        FreeDer(&pDer);
2443
        return NULL;
2444
    }
2445
2446
    dsa = wolfSSL_DSA_new();
2447
    if (dsa == NULL) {
2448
        FreeDer(&pDer);
2449
        WOLFSSL_MSG("Error creating DSA struct");
2450
        return NULL;
2451
    }
2452
2453
    key = (DsaKey*)dsa->internal;
2454
    if (key == NULL) {
2455
        FreeDer(&pDer);
2456
        wolfSSL_DSA_free(dsa);
2457
        WOLFSSL_MSG("Error finding DSA key struct");
2458
        return NULL;
2459
    }
2460
2461
    if (GetInt(&key->p,  pDer->buffer, &idx, pDer->length) < 0 ||
2462
        GetInt(&key->q,  pDer->buffer, &idx, pDer->length) < 0 ||
2463
        GetInt(&key->g,  pDer->buffer, &idx, pDer->length) < 0 ) {
2464
        WOLFSSL_MSG("dsa key error");
2465
        FreeDer(&pDer);
2466
        wolfSSL_DSA_free(dsa);
2467
        return NULL;
2468
    }
2469
2470
    if (wolfssl_bn_set_value(&dsa->p, &key->p) != 1) {
2471
        WOLFSSL_MSG("dsa p key error");
2472
        FreeDer(&pDer);
2473
        wolfSSL_DSA_free(dsa);
2474
        return NULL;
2475
    }
2476
2477
    if (wolfssl_bn_set_value(&dsa->q, &key->q) != 1) {
2478
        WOLFSSL_MSG("dsa q key error");
2479
        FreeDer(&pDer);
2480
        wolfSSL_DSA_free(dsa);
2481
        return NULL;
2482
    }
2483
2484
    if (wolfssl_bn_set_value(&dsa->g, &key->g) != 1) {
2485
        WOLFSSL_MSG("dsa g key error");
2486
        FreeDer(&pDer);
2487
        wolfSSL_DSA_free(dsa);
2488
        return NULL;
2489
    }
2490
2491
    if (x != NULL) {
2492
        *x = dsa;
2493
    }
2494
2495
    FreeDer(&pDer);
2496
    return dsa;
2497
}
2498
#endif /* !NO_BIO */
2499
2500
#if !defined(NO_DH)
2501
WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
2502
{
2503
    WOLFSSL_DH* dh;
2504
    DhKey*      key;
2505
2506
    WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
2507
2508
    if (dsa == NULL) {
2509
        return NULL;
2510
    }
2511
2512
    dh = wolfSSL_DH_new();
2513
    if (dh == NULL) {
2514
        return NULL;
2515
    }
2516
    key = (DhKey*)dh->internal;
2517
2518
    if (dsa->p != NULL &&
2519
        wolfssl_bn_get_value(((WOLFSSL_DSA*)dsa)->p, &key->p)
2520
                                                           != 1) {
2521
        WOLFSSL_MSG("rsa p key error");
2522
        wolfSSL_DH_free(dh);
2523
        return NULL;
2524
    }
2525
    if (dsa->g != NULL &&
2526
        wolfssl_bn_get_value(((WOLFSSL_DSA*)dsa)->g, &key->g)
2527
                                                           != 1) {
2528
        WOLFSSL_MSG("rsa g key error");
2529
        wolfSSL_DH_free(dh);
2530
        return NULL;
2531
    }
2532
2533
    if (wolfssl_bn_set_value(&dh->p, &key->p) != 1) {
2534
        WOLFSSL_MSG("dsa p key error");
2535
        wolfSSL_DH_free(dh);
2536
        return NULL;
2537
    }
2538
    if (wolfssl_bn_set_value(&dh->g, &key->g) != 1) {
2539
        WOLFSSL_MSG("dsa g key error");
2540
        wolfSSL_DH_free(dh);
2541
        return NULL;
2542
    }
2543
2544
    return dh;
2545
}
2546
#endif /* !NO_DH */
2547
2548
#endif /* OPENSSL_EXTRA */
2549
2550
#endif /* !NO_DSA */
2551
2552
/*******************************************************************************
2553
 * END OF DSA API
2554
 ******************************************************************************/
2555
2556
2557
/*******************************************************************************
2558
 * START OF DH API
2559
 ******************************************************************************/
2560
2561
#ifndef NO_DH
2562
2563
#ifdef OPENSSL_EXTRA
2564
2565
/*
2566
 * DH constructor/deconstructor APIs
2567
 */
2568
2569
/* Allocate and initialize a new DH key.
2570
 *
2571
 * @return  DH key on success.
2572
 * @return  NULL on failure.
2573
 */
2574
WOLFSSL_DH* wolfSSL_DH_new(void)
2575
{
2576
    int err = 0;
2577
    WOLFSSL_DH* dh = NULL;
2578
    DhKey* key = NULL;
2579
2580
    WOLFSSL_ENTER("wolfSSL_DH_new");
2581
2582
    /* Allocate OpenSSL DH key. */
2583
    dh = (WOLFSSL_DH*)XMALLOC(sizeof(WOLFSSL_DH), NULL, DYNAMIC_TYPE_DH);
2584
    if (dh == NULL) {
2585
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
2586
        err = 1;
2587
    }
2588
2589
    if (!err) {
2590
        /* Clear key data. */
2591
        XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
2592
        /* Initialize reference counting. */
2593
        wolfSSL_RefInit(&dh->ref, &err);
2594
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
2595
    }
2596
    if (!err) {
2597
#endif
2598
        /* Allocate wolfSSL DH key. */
2599
        key = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
2600
        if (key == NULL) {
2601
            WOLFSSL_ERROR_MSG("wolfSSL_DH_new malloc DhKey failure");
2602
            err = 1;
2603
        }
2604
    }
2605
    if (!err) {
2606
        /* Set and initialize wolfSSL DH key. */
2607
        dh->internal = key;
2608
        if (wc_InitDhKey(key) != 0) {
2609
            WOLFSSL_ERROR_MSG("wolfSSL_DH_new InitDhKey failure");
2610
            err = 1;
2611
        }
2612
    }
2613
2614
    if (err && (dh != NULL)) {
2615
        /* Dispose of the allocated memory. */
2616
        XFREE(key, NULL, DYNAMIC_TYPE_DH);
2617
        wolfSSL_RefFree(&dh->ref);
2618
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
2619
        dh = NULL;
2620
    }
2621
    return dh;
2622
}
2623
2624
#if defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && FIPS_VERSION_EQ(2,0))
2625
/* Set the DH parameters based on the NID.
2626
 *
2627
 * @param [in, out] dh   DH key to set.
2628
 * @param [in]      nid  Numeric ID of predefined DH parameters.
2629
 * @return  0 on success.
2630
 * @return  1 on failure.
2631
 */
2632
static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
2633
{
2634
    int err = 0;
2635
    const DhParams* params = NULL;
2636
2637
    /* HAVE_PUBLIC_FFDHE not required to expose wc_Dh_ffdhe* functions in
2638
     * FIPS v2 module */
2639
    switch (nid) {
2640
#ifdef HAVE_FFDHE_2048
2641
    case WC_NID_ffdhe2048:
2642
        params = wc_Dh_ffdhe2048_Get();
2643
        break;
2644
#endif /* HAVE_FFDHE_2048 */
2645
#ifdef HAVE_FFDHE_3072
2646
    case WC_NID_ffdhe3072:
2647
        params = wc_Dh_ffdhe3072_Get();
2648
        break;
2649
#endif /* HAVE_FFDHE_3072 */
2650
#ifdef HAVE_FFDHE_4096
2651
    case WC_NID_ffdhe4096:
2652
        params = wc_Dh_ffdhe4096_Get();
2653
        break;
2654
#endif /* HAVE_FFDHE_4096 */
2655
    default:
2656
        break;
2657
    }
2658
    if (params == NULL) {
2659
        WOLFSSL_ERROR_MSG("Unable to find DH params for nid.");
2660
        err = 1;
2661
    }
2662
2663
    if (!err) {
2664
        /* Set prime from data retrieved. */
2665
        dh->p = wolfSSL_BN_bin2bn(params->p, (int)params->p_len, NULL);
2666
        if (dh->p == NULL) {
2667
            WOLFSSL_ERROR_MSG("Error converting p hex to WOLFSSL_BIGNUM.");
2668
            err = 1;
2669
        }
2670
    }
2671
    if (!err) {
2672
        /* Set generator from data retrieved. */
2673
        dh->g = wolfSSL_BN_bin2bn(params->g, (int)params->g_len, NULL);
2674
        if (dh->g == NULL) {
2675
            WOLFSSL_ERROR_MSG("Error converting g hex to WOLFSSL_BIGNUM.");
2676
            err = 1;
2677
        }
2678
    }
2679
#ifdef HAVE_FFDHE_Q
2680
    if (!err) {
2681
        /* Set order from data retrieved. */
2682
        dh->q = wolfSSL_BN_bin2bn(params->q, params->q_len, NULL);
2683
        if (dh->q == NULL) {
2684
            WOLFSSL_ERROR_MSG("Error converting q hex to WOLFSSL_BIGNUM.");
2685
            err = 1;
2686
        }
2687
    }
2688
#endif
2689
2690
    /* Synchronize the external into internal DH key's parameters. */
2691
    if ((!err) && (SetDhInternal(dh) != 1)) {
2692
        WOLFSSL_ERROR_MSG("Failed to set internal DH params.");
2693
        err = 1;
2694
    }
2695
    if (!err) {
2696
        /* External DH key parameters were set. */
2697
        dh->exSet = 1;
2698
    }
2699
2700
    if (err == 1) {
2701
        /* Dispose of any external parameters. */
2702
    #ifdef HAVE_FFDHE_Q
2703
        wolfSSL_BN_free(dh->q);
2704
        dh->q = NULL;
2705
    #endif
2706
        wolfSSL_BN_free(dh->p);
2707
        dh->p = NULL;
2708
        wolfSSL_BN_free(dh->g);
2709
        dh->g = NULL;
2710
    }
2711
2712
    return err;
2713
}
2714
#elif !defined(HAVE_PUBLIC_FFDHE) && (!defined(HAVE_FIPS) || \
2715
      FIPS_VERSION_GT(2,0))
2716
/* Set the DH parameters based on the NID.
2717
 *
2718
 * FIPS v2 and lower doesn't support wc_DhSetNamedKey.
2719
 *
2720
 * @param [in, out] dh   DH key to set.
2721
 * @param [in]      nid  Numeric ID of predefined DH parameters.
2722
 * @return  0 on success.
2723
 * @return  1 on failure.
2724
 */
2725
static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
2726
{
2727
    int err = 0;
2728
    int name = 0;
2729
#ifdef HAVE_FFDHE_Q
2730
    int elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q;
2731
#else
2732
    int elements = ELEMENT_P | ELEMENT_G;
2733
#endif /* HAVE_FFDHE_Q */
2734
2735
    switch (nid) {
2736
#ifdef HAVE_FFDHE_2048
2737
    case WC_NID_ffdhe2048:
2738
        name = WC_FFDHE_2048;
2739
        break;
2740
#endif /* HAVE_FFDHE_2048 */
2741
#ifdef HAVE_FFDHE_3072
2742
    case WC_NID_ffdhe3072:
2743
        name = WC_FFDHE_3072;
2744
        break;
2745
#endif /* HAVE_FFDHE_3072 */
2746
#ifdef HAVE_FFDHE_4096
2747
    case WC_NID_ffdhe4096:
2748
        name = WC_FFDHE_4096;
2749
        break;
2750
#endif /* HAVE_FFDHE_4096 */
2751
    default:
2752
        err = 1;
2753
        WOLFSSL_ERROR_MSG("Unable to find DH params for nid.");
2754
        break;
2755
    }
2756
    /* Set the internal DH key's parameters based on name. */
2757
    if ((!err) && (wc_DhSetNamedKey((DhKey*)dh->internal, name) != 0)) {
2758
        WOLFSSL_ERROR_MSG("wc_DhSetNamedKey failed.");
2759
        err = 1;
2760
    }
2761
    /* Synchronize the internal into external DH key's parameters. */
2762
    if (!err && (SetDhExternal_ex(dh, elements) != 1)) {
2763
        WOLFSSL_ERROR_MSG("Failed to set external DH params.");
2764
        err = 1;
2765
    }
2766
2767
    return err;
2768
}
2769
#else
2770
/* Set the DH parameters based on the NID.
2771
 *
2772
 * Pre-defined DH parameters not available.
2773
 *
2774
 * @param [in, out] dh   DH key to set.
2775
 * @param [in]      nid  Numeric ID of predefined DH parameters.
2776
 * @return  1 for failure.
2777
 */
2778
static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
2779
{
2780
    return 1;
2781
}
2782
#endif
2783
2784
/* Allocate and initialize a new DH key with the parameters based on the NID.
2785
 *
2786
 * @param [in] nid  Numeric ID of DH parameters.
2787
 *
2788
 * @return  DH key on success.
2789
 * @return  NULL on failure.
2790
 */
2791
WOLFSSL_DH* wolfSSL_DH_new_by_nid(int nid)
2792
{
2793
    WOLFSSL_DH* dh = NULL;
2794
    int err = 0;
2795
2796
    WOLFSSL_ENTER("wolfSSL_DH_new_by_nid");
2797
2798
    /* Allocate a new DH key. */
2799
    dh = wolfSSL_DH_new();
2800
    if (dh == NULL) {
2801
        WOLFSSL_ERROR_MSG("Failed to create WOLFSSL_DH.");
2802
        err = 1;
2803
    }
2804
    if (!err) {
2805
        /* Set the parameters based on NID. */
2806
        err = wolfssl_dh_set_nid(dh, nid);
2807
    }
2808
2809
    if (err && (dh != NULL)) {
2810
        /* Dispose of the key on failure to set. */
2811
        wolfSSL_DH_free(dh);
2812
        dh = NULL;
2813
    }
2814
2815
    WOLFSSL_LEAVE("wolfSSL_DH_new_by_nid", err);
2816
2817
    return dh;
2818
}
2819
2820
/* Dispose of DH key and allocated data.
2821
 *
2822
 * Cannot use dh after this call.
2823
 *
2824
 * @param [in] dh  DH key to free.
2825
 */
2826
void wolfSSL_DH_free(WOLFSSL_DH* dh)
2827
{
2828
    int doFree = 0;
2829
2830
    WOLFSSL_ENTER("wolfSSL_DH_free");
2831
2832
    if (dh != NULL) {
2833
        int err;
2834
2835
        /* Only free if all references to it are done */
2836
        wolfSSL_RefDec(&dh->ref, &doFree, &err);
2837
        /* Ignore errors - doFree will be 0 on error. */
2838
        (void)err;
2839
    }
2840
    if (doFree) {
2841
        /* Dispose of allocated reference counting data. */
2842
        wolfSSL_RefFree(&dh->ref);
2843
2844
        /* Dispose of wolfSSL DH key. */
2845
        if (dh->internal) {
2846
            wc_FreeDhKey((DhKey*)dh->internal);
2847
            XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
2848
            dh->internal = NULL;
2849
        }
2850
2851
        /* Dispose of any allocated BNs. */
2852
        wolfSSL_BN_free(dh->priv_key);
2853
        wolfSSL_BN_free(dh->pub_key);
2854
        wolfSSL_BN_free(dh->g);
2855
        wolfSSL_BN_free(dh->p);
2856
        wolfSSL_BN_free(dh->q);
2857
        /* Set back to NULLs for safety. */
2858
        XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
2859
2860
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
2861
    }
2862
}
2863
2864
/* Increments ref count of DH key.
2865
 *
2866
 * @param [in, out] dh  DH key.
2867
 * @return  1 on success
2868
 * @return  0 on error
2869
 */
2870
int wolfSSL_DH_up_ref(WOLFSSL_DH* dh)
2871
{
2872
    int err = 1;
2873
2874
    WOLFSSL_ENTER("wolfSSL_DH_up_ref");
2875
2876
    if (dh != NULL) {
2877
        wolfSSL_RefInc(&dh->ref, &err);
2878
    }
2879
2880
    return !err;
2881
}
2882
2883
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) || \
2884
    defined(OPENSSL_EXTRA)
2885
2886
#ifdef WOLFSSL_DH_EXTRA
2887
/* Duplicate the DH key.
2888
 *
2889
 * Internal DH key in 'dh' is updated if necessary.
2890
 *
2891
 * @param [in, out] dh  DH key to duplicate.
2892
 * @return  NULL on failure.
2893
 * @return  DH key on success.
2894
 */
2895
WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh)
2896
{
2897
    WOLFSSL_DH* ret = NULL;
2898
    int err = 0;
2899
2900
    WOLFSSL_ENTER("wolfSSL_DH_dup");
2901
2902
    /* Validate parameters. */
2903
    if (dh == NULL) {
2904
        WOLFSSL_ERROR_MSG("Bad parameter");
2905
        err = 1;
2906
    }
2907
2908
    /* Ensure internal DH key is set. */
2909
    if ((!err) && (dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
2910
        WOLFSSL_ERROR_MSG("Bad DH set internal");
2911
        err = 1;
2912
    }
2913
2914
    /* Create a new DH key object. */
2915
    if ((!err) && (!(ret = wolfSSL_DH_new()))) {
2916
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new error");
2917
        err = 1;
2918
    }
2919
    /* Copy internal DH key from original to new. */
2920
    if ((!err) && (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) !=
2921
            MP_OKAY)) {
2922
        WOLFSSL_ERROR_MSG("wc_DhKeyCopy error");
2923
        err = 1;
2924
    }
2925
    if (!err) {
2926
        ret->inSet = 1;
2927
2928
         /* Synchronize the internal into external DH key's parameters. */
2929
        if (SetDhExternal(ret) != 1) {
2930
            WOLFSSL_ERROR_MSG("SetDhExternal error");
2931
            err = 1;
2932
        }
2933
    }
2934
2935
    /* Dispose of any allocated DH key on error. */
2936
    if (err && (ret != NULL)) {
2937
        wolfSSL_DH_free(ret);
2938
        ret = NULL;
2939
    }
2940
    return ret;
2941
}
2942
#endif /* WOLFSSL_DH_EXTRA */
2943
2944
#endif
2945
2946
/* Allocate and initialize a new DH key with 2048-bit parameters.
2947
 *
2948
 * See RFC 5114 section 2.3, "2048-bit MODP Group with 256-bit Prime Order
2949
 * Subgroup."
2950
 *
2951
 * @return  NULL on failure.
2952
 * @return  DH Key on success.
2953
 */
2954
WOLFSSL_DH* wolfSSL_DH_get_2048_256(void)
2955
{
2956
    WOLFSSL_DH* dh;
2957
    int err = 0;
2958
    static const byte pHex[] = {
2959
        0x87, 0xA8, 0xE6, 0x1D, 0xB4, 0xB6, 0x66, 0x3C, 0xFF, 0xBB, 0xD1, 0x9C,
2960
        0x65, 0x19, 0x59, 0x99, 0x8C, 0xEE, 0xF6, 0x08, 0x66, 0x0D, 0xD0, 0xF2,
2961
        0x5D, 0x2C, 0xEE, 0xD4, 0x43, 0x5E, 0x3B, 0x00, 0xE0, 0x0D, 0xF8, 0xF1,
2962
        0xD6, 0x19, 0x57, 0xD4, 0xFA, 0xF7, 0xDF, 0x45, 0x61, 0xB2, 0xAA, 0x30,
2963
        0x16, 0xC3, 0xD9, 0x11, 0x34, 0x09, 0x6F, 0xAA, 0x3B, 0xF4, 0x29, 0x6D,
2964
        0x83, 0x0E, 0x9A, 0x7C, 0x20, 0x9E, 0x0C, 0x64, 0x97, 0x51, 0x7A, 0xBD,
2965
        0x5A, 0x8A, 0x9D, 0x30, 0x6B, 0xCF, 0x67, 0xED, 0x91, 0xF9, 0xE6, 0x72,
2966
        0x5B, 0x47, 0x58, 0xC0, 0x22, 0xE0, 0xB1, 0xEF, 0x42, 0x75, 0xBF, 0x7B,
2967
        0x6C, 0x5B, 0xFC, 0x11, 0xD4, 0x5F, 0x90, 0x88, 0xB9, 0x41, 0xF5, 0x4E,
2968
        0xB1, 0xE5, 0x9B, 0xB8, 0xBC, 0x39, 0xA0, 0xBF, 0x12, 0x30, 0x7F, 0x5C,
2969
        0x4F, 0xDB, 0x70, 0xC5, 0x81, 0xB2, 0x3F, 0x76, 0xB6, 0x3A, 0xCA, 0xE1,
2970
        0xCA, 0xA6, 0xB7, 0x90, 0x2D, 0x52, 0x52, 0x67, 0x35, 0x48, 0x8A, 0x0E,
2971
        0xF1, 0x3C, 0x6D, 0x9A, 0x51, 0xBF, 0xA4, 0xAB, 0x3A, 0xD8, 0x34, 0x77,
2972
        0x96, 0x52, 0x4D, 0x8E, 0xF6, 0xA1, 0x67, 0xB5, 0xA4, 0x18, 0x25, 0xD9,
2973
        0x67, 0xE1, 0x44, 0xE5, 0x14, 0x05, 0x64, 0x25, 0x1C, 0xCA, 0xCB, 0x83,
2974
        0xE6, 0xB4, 0x86, 0xF6, 0xB3, 0xCA, 0x3F, 0x79, 0x71, 0x50, 0x60, 0x26,
2975
        0xC0, 0xB8, 0x57, 0xF6, 0x89, 0x96, 0x28, 0x56, 0xDE, 0xD4, 0x01, 0x0A,
2976
        0xBD, 0x0B, 0xE6, 0x21, 0xC3, 0xA3, 0x96, 0x0A, 0x54, 0xE7, 0x10, 0xC3,
2977
        0x75, 0xF2, 0x63, 0x75, 0xD7, 0x01, 0x41, 0x03, 0xA4, 0xB5, 0x43, 0x30,
2978
        0xC1, 0x98, 0xAF, 0x12, 0x61, 0x16, 0xD2, 0x27, 0x6E, 0x11, 0x71, 0x5F,
2979
        0x69, 0x38, 0x77, 0xFA, 0xD7, 0xEF, 0x09, 0xCA, 0xDB, 0x09, 0x4A, 0xE9,
2980
        0x1E, 0x1A, 0x15, 0x97
2981
    };
2982
    static const byte gHex[] = {
2983
        0x3F, 0xB3, 0x2C, 0x9B, 0x73, 0x13, 0x4D, 0x0B, 0x2E, 0x77, 0x50, 0x66,
2984
        0x60, 0xED, 0xBD, 0x48, 0x4C, 0xA7, 0xB1, 0x8F, 0x21, 0xEF, 0x20, 0x54,
2985
        0x07, 0xF4, 0x79, 0x3A, 0x1A, 0x0B, 0xA1, 0x25, 0x10, 0xDB, 0xC1, 0x50,
2986
        0x77, 0xBE, 0x46, 0x3F, 0xFF, 0x4F, 0xED, 0x4A, 0xAC, 0x0B, 0xB5, 0x55,
2987
        0xBE, 0x3A, 0x6C, 0x1B, 0x0C, 0x6B, 0x47, 0xB1, 0xBC, 0x37, 0x73, 0xBF,
2988
        0x7E, 0x8C, 0x6F, 0x62, 0x90, 0x12, 0x28, 0xF8, 0xC2, 0x8C, 0xBB, 0x18,
2989
        0xA5, 0x5A, 0xE3, 0x13, 0x41, 0x00, 0x0A, 0x65, 0x01, 0x96, 0xF9, 0x31,
2990
        0xC7, 0x7A, 0x57, 0xF2, 0xDD, 0xF4, 0x63, 0xE5, 0xE9, 0xEC, 0x14, 0x4B,
2991
        0x77, 0x7D, 0xE6, 0x2A, 0xAA, 0xB8, 0xA8, 0x62, 0x8A, 0xC3, 0x76, 0xD2,
2992
        0x82, 0xD6, 0xED, 0x38, 0x64, 0xE6, 0x79, 0x82, 0x42, 0x8E, 0xBC, 0x83,
2993
        0x1D, 0x14, 0x34, 0x8F, 0x6F, 0x2F, 0x91, 0x93, 0xB5, 0x04, 0x5A, 0xF2,
2994
        0x76, 0x71, 0x64, 0xE1, 0xDF, 0xC9, 0x67, 0xC1, 0xFB, 0x3F, 0x2E, 0x55,
2995
        0xA4, 0xBD, 0x1B, 0xFF, 0xE8, 0x3B, 0x9C, 0x80, 0xD0, 0x52, 0xB9, 0x85,
2996
        0xD1, 0x82, 0xEA, 0x0A, 0xDB, 0x2A, 0x3B, 0x73, 0x13, 0xD3, 0xFE, 0x14,
2997
        0xC8, 0x48, 0x4B, 0x1E, 0x05, 0x25, 0x88, 0xB9, 0xB7, 0xD2, 0xBB, 0xD2,
2998
        0xDF, 0x01, 0x61, 0x99, 0xEC, 0xD0, 0x6E, 0x15, 0x57, 0xCD, 0x09, 0x15,
2999
        0xB3, 0x35, 0x3B, 0xBB, 0x64, 0xE0, 0xEC, 0x37, 0x7F, 0xD0, 0x28, 0x37,
3000
        0x0D, 0xF9, 0x2B, 0x52, 0xC7, 0x89, 0x14, 0x28, 0xCD, 0xC6, 0x7E, 0xB6,
3001
        0x18, 0x4B, 0x52, 0x3D, 0x1D, 0xB2, 0x46, 0xC3, 0x2F, 0x63, 0x07, 0x84,
3002
        0x90, 0xF0, 0x0E, 0xF8, 0xD6, 0x47, 0xD1, 0x48, 0xD4, 0x79, 0x54, 0x51,
3003
        0x5E, 0x23, 0x27, 0xCF, 0xEF, 0x98, 0xC5, 0x82, 0x66, 0x4B, 0x4C, 0x0F,
3004
        0x6C, 0xC4, 0x16, 0x59
3005
    };
3006
    static const byte qHex[] = {
3007
        0x8C, 0xF8, 0x36, 0x42, 0xA7, 0x09, 0xA0, 0x97, 0xB4, 0x47, 0x99, 0x76,
3008
        0x40, 0x12, 0x9D, 0xA2, 0x99, 0xB1, 0xA4, 0x7D, 0x1E, 0xB3, 0x75, 0x0B,
3009
        0xA3, 0x08, 0xB0, 0xFE, 0x64, 0xF5, 0xFB, 0xD3
3010
    };
3011
3012
    /* Create a new DH key to return. */
3013
    dh = wolfSSL_DH_new();
3014
    if (dh == NULL) {
3015
        err = 1;
3016
    }
3017
    if (!err) {
3018
        /* Set prime. */
3019
        dh->p = wolfSSL_BN_bin2bn(pHex, (int)sizeof(pHex), NULL);
3020
        if (dh->p == NULL) {
3021
            WOLFSSL_ERROR_MSG("Error converting p hex to WOLFSSL_BIGNUM.");
3022
            err = 1;
3023
        }
3024
    }
3025
    if (!err) {
3026
        /* Set generator. */
3027
        dh->g = wolfSSL_BN_bin2bn(gHex, (int)sizeof(gHex), NULL);
3028
        if (dh->g == NULL) {
3029
            WOLFSSL_ERROR_MSG("Error converting g hex to WOLFSSL_BIGNUM.");
3030
            err = 1;
3031
        }
3032
    }
3033
    if (!err) {
3034
        /* Set order. */
3035
        dh->q = wolfSSL_BN_bin2bn(qHex, (int)sizeof(qHex), NULL);
3036
        if (dh->q == NULL) {
3037
            WOLFSSL_ERROR_MSG("Error converting q hex to WOLFSSL_BIGNUM.");
3038
            err = 1;
3039
        }
3040
    }
3041
    /* Set values into wolfSSL DH key. */
3042
    if ((!err) && (SetDhInternal(dh) != 1)) {
3043
        WOLFSSL_ERROR_MSG("Error setting DH parameters.");
3044
        err = 1;
3045
    }
3046
    if (!err) {
3047
        /* External DH key parameters were set. */
3048
        dh->exSet = 1;
3049
    }
3050
3051
    /* Dispose of any allocated DH key on error. */
3052
    if (err && (dh != NULL)) {
3053
        wolfSSL_DH_free(dh);
3054
        dh = NULL;
3055
    }
3056
3057
    return dh;
3058
}
3059
3060
/* TODO: consider changing strings to byte arrays. */
3061
3062
/* Returns a big number with the 768-bit prime from RFC 2409.
3063
 *
3064
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3065
 *                      If NULL then a new BN is created, set and returned.
3066
 *
3067
 * @return  NULL on failure.
3068
 * @return  WOLFSSL_BIGNUM with value set to 768-bit prime on success.
3069
 */
3070
WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn)
3071
{
3072
#if WOLFSSL_MAX_BN_BITS >= 768
3073
    static const char prm[] = {
3074
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3075
        "C4C6628B80DC1CD129024E088A67CC74"
3076
        "020BBEA63B139B22514A08798E3404DD"
3077
        "EF9519B3CD3A431B302B0A6DF25F1437"
3078
        "4FE1356D6D51C245E485B576625E7EC6"
3079
        "F44C42E9A63A3620FFFFFFFFFFFFFFFF"
3080
    };
3081
3082
    WOLFSSL_ENTER("wolfSSL_DH_768_prime");
3083
3084
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3085
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3086
        WOLFSSL_ERROR_MSG("Error converting DH 768 prime to big number");
3087
        bn = NULL;
3088
    }
3089
3090
    return bn;
3091
#else
3092
    (void)bn;
3093
    return NULL;
3094
#endif
3095
}
3096
3097
/* Returns a big number with the 1024-bit prime from RFC 2409.
3098
 *
3099
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3100
 *                      If NULL then a new BN is created, set and returned.
3101
 *
3102
 * @return  NULL on failure.
3103
 * @return  WOLFSSL_BIGNUM with value set to 1024-bit prime on success.
3104
 */
3105
WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn)
3106
{
3107
#if WOLFSSL_MAX_BN_BITS >= 1024
3108
    static const char prm[] = {
3109
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3110
        "C4C6628B80DC1CD129024E088A67CC74"
3111
        "020BBEA63B139B22514A08798E3404DD"
3112
        "EF9519B3CD3A431B302B0A6DF25F1437"
3113
        "4FE1356D6D51C245E485B576625E7EC6"
3114
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3115
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3116
        "49286651ECE65381FFFFFFFFFFFFFFFF"
3117
    };
3118
3119
    WOLFSSL_ENTER("wolfSSL_DH_1024_prime");
3120
3121
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3122
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3123
        WOLFSSL_ERROR_MSG("Error converting DH 1024 prime to big number");
3124
        bn = NULL;
3125
    }
3126
3127
    return bn;
3128
#else
3129
    (void)bn;
3130
    return NULL;
3131
#endif
3132
}
3133
3134
/* Returns a big number with the 1536-bit prime from RFC 3526.
3135
 *
3136
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3137
 *                      If NULL then a new BN is created, set and returned.
3138
 *
3139
 * @return  NULL on failure.
3140
 * @return  WOLFSSL_BIGNUM with value set to 1536-bit prime on success.
3141
 */
3142
WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn)
3143
{
3144
#if WOLFSSL_MAX_BN_BITS >= 1536
3145
    static const char prm[] = {
3146
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3147
        "C4C6628B80DC1CD129024E088A67CC74"
3148
        "020BBEA63B139B22514A08798E3404DD"
3149
        "EF9519B3CD3A431B302B0A6DF25F1437"
3150
        "4FE1356D6D51C245E485B576625E7EC6"
3151
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3152
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3153
        "49286651ECE45B3DC2007CB8A163BF05"
3154
        "98DA48361C55D39A69163FA8FD24CF5F"
3155
        "83655D23DCA3AD961C62F356208552BB"
3156
        "9ED529077096966D670C354E4ABC9804"
3157
        "F1746C08CA237327FFFFFFFFFFFFFFFF"
3158
    };
3159
3160
    WOLFSSL_ENTER("wolfSSL_DH_1536_prime");
3161
3162
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3163
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3164
        WOLFSSL_ERROR_MSG("Error converting DH 1536 prime to big number");
3165
        bn = NULL;
3166
    }
3167
3168
    return bn;
3169
#else
3170
    (void)bn;
3171
    return NULL;
3172
#endif
3173
}
3174
3175
/* Returns a big number with the 2048-bit prime from RFC 3526.
3176
 *
3177
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3178
 *                      If NULL then a new BN is created, set and returned.
3179
 *
3180
 * @return  NULL on failure.
3181
 * @return  WOLFSSL_BIGNUM with value set to 2048-bit prime on success.
3182
 */
3183
WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn)
3184
{
3185
#if WOLFSSL_MAX_BN_BITS >= 2048
3186
    static const char prm[] = {
3187
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3188
        "C4C6628B80DC1CD129024E088A67CC74"
3189
        "020BBEA63B139B22514A08798E3404DD"
3190
        "EF9519B3CD3A431B302B0A6DF25F1437"
3191
        "4FE1356D6D51C245E485B576625E7EC6"
3192
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3193
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3194
        "49286651ECE45B3DC2007CB8A163BF05"
3195
        "98DA48361C55D39A69163FA8FD24CF5F"
3196
        "83655D23DCA3AD961C62F356208552BB"
3197
        "9ED529077096966D670C354E4ABC9804"
3198
        "F1746C08CA18217C32905E462E36CE3B"
3199
        "E39E772C180E86039B2783A2EC07A28F"
3200
        "B5C55DF06F4C52C9DE2BCBF695581718"
3201
        "3995497CEA956AE515D2261898FA0510"
3202
        "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
3203
    };
3204
3205
    WOLFSSL_ENTER("wolfSSL_DH_2048_prime");
3206
3207
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3208
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3209
        WOLFSSL_ERROR_MSG("Error converting DH 2048 prime to big number");
3210
        bn = NULL;
3211
    }
3212
3213
    return bn;
3214
#else
3215
    (void)bn;
3216
    return NULL;
3217
#endif
3218
}
3219
3220
/* Returns a big number with the 3072-bit prime from RFC 3526.
3221
 *
3222
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3223
 *                      If NULL then a new BN is created, set and returned.
3224
 *
3225
 * @return  NULL on failure.
3226
 * @return  WOLFSSL_BIGNUM with value set to 3072-bit prime on success.
3227
 */
3228
WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn)
3229
{
3230
#if WOLFSSL_MAX_BN_BITS >= 3072
3231
    static const char prm[] = {
3232
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3233
        "C4C6628B80DC1CD129024E088A67CC74"
3234
        "020BBEA63B139B22514A08798E3404DD"
3235
        "EF9519B3CD3A431B302B0A6DF25F1437"
3236
        "4FE1356D6D51C245E485B576625E7EC6"
3237
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3238
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3239
        "49286651ECE45B3DC2007CB8A163BF05"
3240
        "98DA48361C55D39A69163FA8FD24CF5F"
3241
        "83655D23DCA3AD961C62F356208552BB"
3242
        "9ED529077096966D670C354E4ABC9804"
3243
        "F1746C08CA18217C32905E462E36CE3B"
3244
        "E39E772C180E86039B2783A2EC07A28F"
3245
        "B5C55DF06F4C52C9DE2BCBF695581718"
3246
        "3995497CEA956AE515D2261898FA0510"
3247
        "15728E5A8AAAC42DAD33170D04507A33"
3248
        "A85521ABDF1CBA64ECFB850458DBEF0A"
3249
        "8AEA71575D060C7DB3970F85A6E1E4C7"
3250
        "ABF5AE8CDB0933D71E8C94E04A25619D"
3251
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
3252
        "D87602733EC86A64521F2B18177B200C"
3253
        "BBE117577A615D6C770988C0BAD946E2"
3254
        "08E24FA074E5AB3143DB5BFCE0FD108E"
3255
        "4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
3256
    };
3257
3258
    WOLFSSL_ENTER("wolfSSL_DH_3072_prime");
3259
3260
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3261
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3262
        WOLFSSL_ERROR_MSG("Error converting DH 3072 prime to big number");
3263
        bn = NULL;
3264
    }
3265
3266
    return bn;
3267
#else
3268
    (void)bn;
3269
    return NULL;
3270
#endif
3271
}
3272
3273
/* Returns a big number with the 4096-bit prime from RFC 3526.
3274
 *
3275
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3276
 *                      If NULL then a new BN is created, set and returned.
3277
 *
3278
 * @return  NULL on failure.
3279
 * @return  WOLFSSL_BIGNUM with value set to 4096-bit prime on success.
3280
 */
3281
WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn)
3282
{
3283
#if WOLFSSL_MAX_BN_BITS >= 4096
3284
    static const char prm[] = {
3285
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3286
        "C4C6628B80DC1CD129024E088A67CC74"
3287
        "020BBEA63B139B22514A08798E3404DD"
3288
        "EF9519B3CD3A431B302B0A6DF25F1437"
3289
        "4FE1356D6D51C245E485B576625E7EC6"
3290
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3291
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3292
        "49286651ECE45B3DC2007CB8A163BF05"
3293
        "98DA48361C55D39A69163FA8FD24CF5F"
3294
        "83655D23DCA3AD961C62F356208552BB"
3295
        "9ED529077096966D670C354E4ABC9804"
3296
        "F1746C08CA18217C32905E462E36CE3B"
3297
        "E39E772C180E86039B2783A2EC07A28F"
3298
        "B5C55DF06F4C52C9DE2BCBF695581718"
3299
        "3995497CEA956AE515D2261898FA0510"
3300
        "15728E5A8AAAC42DAD33170D04507A33"
3301
        "A85521ABDF1CBA64ECFB850458DBEF0A"
3302
        "8AEA71575D060C7DB3970F85A6E1E4C7"
3303
        "ABF5AE8CDB0933D71E8C94E04A25619D"
3304
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
3305
        "D87602733EC86A64521F2B18177B200C"
3306
        "BBE117577A615D6C770988C0BAD946E2"
3307
        "08E24FA074E5AB3143DB5BFCE0FD108E"
3308
        "4B82D120A92108011A723C12A787E6D7"
3309
        "88719A10BDBA5B2699C327186AF4E23C"
3310
        "1A946834B6150BDA2583E9CA2AD44CE8"
3311
        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
3312
        "287C59474E6BC05D99B2964FA090C3A2"
3313
        "233BA186515BE7ED1F612970CEE2D7AF"
3314
        "B81BDD762170481CD0069127D5B05AA9"
3315
        "93B4EA988D8FDDC186FFB7DC90A6C08F"
3316
        "4DF435C934063199FFFFFFFFFFFFFFFF"
3317
    };
3318
3319
    WOLFSSL_ENTER("wolfSSL_DH_4096_prime");
3320
3321
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3322
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3323
        WOLFSSL_ERROR_MSG("Error converting DH 4096 prime to big number");
3324
        bn = NULL;
3325
    }
3326
3327
    return bn;
3328
#else
3329
    (void)bn;
3330
    return NULL;
3331
#endif
3332
}
3333
3334
/* Returns a big number with the 6144-bit prime from RFC 3526.
3335
 *
3336
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3337
 *                      If NULL then a new BN is created, set and returned.
3338
 *
3339
 * @return  NULL on failure.
3340
 * @return  WOLFSSL_BIGNUM with value set to 6144-bit prime on success.
3341
 */
3342
WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn)
3343
{
3344
#if WOLFSSL_MAX_BN_BITS >= 6144
3345
    static const char prm[] = {
3346
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3347
        "C4C6628B80DC1CD129024E088A67CC74"
3348
        "020BBEA63B139B22514A08798E3404DD"
3349
        "EF9519B3CD3A431B302B0A6DF25F1437"
3350
        "4FE1356D6D51C245E485B576625E7EC6"
3351
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3352
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3353
        "49286651ECE45B3DC2007CB8A163BF05"
3354
        "98DA48361C55D39A69163FA8FD24CF5F"
3355
        "83655D23DCA3AD961C62F356208552BB"
3356
        "9ED529077096966D670C354E4ABC9804"
3357
        "F1746C08CA18217C32905E462E36CE3B"
3358
        "E39E772C180E86039B2783A2EC07A28F"
3359
        "B5C55DF06F4C52C9DE2BCBF695581718"
3360
        "3995497CEA956AE515D2261898FA0510"
3361
        "15728E5A8AAAC42DAD33170D04507A33"
3362
        "A85521ABDF1CBA64ECFB850458DBEF0A"
3363
        "8AEA71575D060C7DB3970F85A6E1E4C7"
3364
        "ABF5AE8CDB0933D71E8C94E04A25619D"
3365
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
3366
        "D87602733EC86A64521F2B18177B200C"
3367
        "BBE117577A615D6C770988C0BAD946E2"
3368
        "08E24FA074E5AB3143DB5BFCE0FD108E"
3369
        "4B82D120A92108011A723C12A787E6D7"
3370
        "88719A10BDBA5B2699C327186AF4E23C"
3371
        "1A946834B6150BDA2583E9CA2AD44CE8"
3372
        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
3373
        "287C59474E6BC05D99B2964FA090C3A2"
3374
        "233BA186515BE7ED1F612970CEE2D7AF"
3375
        "B81BDD762170481CD0069127D5B05AA9"
3376
        "93B4EA988D8FDDC186FFB7DC90A6C08F"
3377
        "4DF435C93402849236C3FAB4D27C7026"
3378
        "C1D4DCB2602646DEC9751E763DBA37BD"
3379
        "F8FF9406AD9E530EE5DB382F413001AE"
3380
        "B06A53ED9027D831179727B0865A8918"
3381
        "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
3382
        "DB7F1447E6CC254B332051512BD7AF42"
3383
        "6FB8F401378CD2BF5983CA01C64B92EC"
3384
        "F032EA15D1721D03F482D7CE6E74FEF6"
3385
        "D55E702F46980C82B5A84031900B1C9E"
3386
        "59E7C97FBEC7E8F323A97A7E36CC88BE"
3387
        "0F1D45B7FF585AC54BD407B22B4154AA"
3388
        "CC8F6D7EBF48E1D814CC5ED20F8037E0"
3389
        "A79715EEF29BE32806A1D58BB7C5DA76"
3390
        "F550AA3D8A1FBFF0EB19CCB1A313D55C"
3391
        "DA56C9EC2EF29632387FE8D76E3C0468"
3392
        "043E8F663F4860EE12BF2D5B0B7474D6"
3393
        "E694F91E6DCC4024FFFFFFFFFFFFFFFF"
3394
    };
3395
3396
    WOLFSSL_ENTER("wolfSSL_DH_6144_prime");
3397
3398
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3399
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3400
        WOLFSSL_ERROR_MSG("Error converting DH 6144 prime to big number");
3401
        bn = NULL;
3402
    }
3403
3404
    return bn;
3405
#else
3406
    (void)bn;
3407
    return NULL;
3408
#endif
3409
}
3410
3411
3412
/* Returns a big number with the 8192-bit prime from RFC 3526.
3413
 *
3414
 * @param [in, out] bn  If not NULL then this BN is set and returned.
3415
 *                      If NULL then a new BN is created, set and returned.
3416
 *
3417
 * @return  NULL on failure.
3418
 * @return  WOLFSSL_BIGNUM with value set to 8192-bit prime on success.
3419
 */
3420
WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
3421
{
3422
#if WOLFSSL_MAX_BN_BITS >= 8192
3423
    static const char prm[] = {
3424
        "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3425
        "C4C6628B80DC1CD129024E088A67CC74"
3426
        "020BBEA63B139B22514A08798E3404DD"
3427
        "EF9519B3CD3A431B302B0A6DF25F1437"
3428
        "4FE1356D6D51C245E485B576625E7EC6"
3429
        "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3430
        "EE386BFB5A899FA5AE9F24117C4B1FE6"
3431
        "49286651ECE45B3DC2007CB8A163BF05"
3432
        "98DA48361C55D39A69163FA8FD24CF5F"
3433
        "83655D23DCA3AD961C62F356208552BB"
3434
        "9ED529077096966D670C354E4ABC9804"
3435
        "F1746C08CA18217C32905E462E36CE3B"
3436
        "E39E772C180E86039B2783A2EC07A28F"
3437
        "B5C55DF06F4C52C9DE2BCBF695581718"
3438
        "3995497CEA956AE515D2261898FA0510"
3439
        "15728E5A8AAAC42DAD33170D04507A33"
3440
        "A85521ABDF1CBA64ECFB850458DBEF0A"
3441
        "8AEA71575D060C7DB3970F85A6E1E4C7"
3442
        "ABF5AE8CDB0933D71E8C94E04A25619D"
3443
        "CEE3D2261AD2EE6BF12FFA06D98A0864"
3444
        "D87602733EC86A64521F2B18177B200C"
3445
        "BBE117577A615D6C770988C0BAD946E2"
3446
        "08E24FA074E5AB3143DB5BFCE0FD108E"
3447
        "4B82D120A92108011A723C12A787E6D7"
3448
        "88719A10BDBA5B2699C327186AF4E23C"
3449
        "1A946834B6150BDA2583E9CA2AD44CE8"
3450
        "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
3451
        "287C59474E6BC05D99B2964FA090C3A2"
3452
        "233BA186515BE7ED1F612970CEE2D7AF"
3453
        "B81BDD762170481CD0069127D5B05AA9"
3454
        "93B4EA988D8FDDC186FFB7DC90A6C08F"
3455
        "4DF435C93402849236C3FAB4D27C7026"
3456
        "C1D4DCB2602646DEC9751E763DBA37BD"
3457
        "F8FF9406AD9E530EE5DB382F413001AE"
3458
        "B06A53ED9027D831179727B0865A8918"
3459
        "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
3460
        "DB7F1447E6CC254B332051512BD7AF42"
3461
        "6FB8F401378CD2BF5983CA01C64B92EC"
3462
        "F032EA15D1721D03F482D7CE6E74FEF6"
3463
        "D55E702F46980C82B5A84031900B1C9E"
3464
        "59E7C97FBEC7E8F323A97A7E36CC88BE"
3465
        "0F1D45B7FF585AC54BD407B22B4154AA"
3466
        "CC8F6D7EBF48E1D814CC5ED20F8037E0"
3467
        "A79715EEF29BE32806A1D58BB7C5DA76"
3468
        "F550AA3D8A1FBFF0EB19CCB1A313D55C"
3469
        "DA56C9EC2EF29632387FE8D76E3C0468"
3470
        "043E8F663F4860EE12BF2D5B0B7474D6"
3471
        "E694F91E6DBE115974A3926F12FEE5E4"
3472
        "38777CB6A932DF8CD8BEC4D073B931BA"
3473
        "3BC832B68D9DD300741FA7BF8AFC47ED"
3474
        "2576F6936BA424663AAB639C5AE4F568"
3475
        "3423B4742BF1C978238F16CBE39D652D"
3476
        "E3FDB8BEFC848AD922222E04A4037C07"
3477
        "13EB57A81A23F0C73473FC646CEA306B"
3478
        "4BCBC8862F8385DDFA9D4B7FA2C087E8"
3479
        "79683303ED5BDD3A062B3CF5B3A278A6"
3480
        "6D2A13F83F44F82DDF310EE074AB6A36"
3481
        "4597E899A0255DC164F31CC50846851D"
3482
        "F9AB48195DED7EA1B1D510BD7EE74D73"
3483
        "FAF36BC31ECFA268359046F4EB879F92"
3484
        "4009438B481C6CD7889A002ED5EE382B"
3485
        "C9190DA6FC026E479558E4475677E9AA"
3486
        "9E3050E2765694DFC81F56E880B96E71"
3487
        "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
3488
    };
3489
3490
    WOLFSSL_ENTER("wolfSSL_DH_8192_prime");
3491
3492
    /* Set prime into BN. Creates a new BN when bn is NULL. */
3493
    if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3494
        WOLFSSL_ERROR_MSG("Error converting DH 8192 prime to big number");
3495
        bn = NULL;
3496
    }
3497
3498
    return bn;
3499
#else
3500
    (void)bn;
3501
    return NULL;
3502
#endif
3503
}
3504
3505
/*
3506
 * DH to/from bin APIs
3507
 */
3508
3509
#ifndef NO_CERTS
3510
3511
/* Load the DER encoded DH parameters into DH key.
3512
 *
3513
 * @param [in, out] dh      DH key to load parameters into.
3514
 * @param [in]      der     Buffer holding DER encoded parameters data.
3515
 * @param [in, out] idx     On in, index at which DH key DER data starts.
3516
 *                          On out, index after DH key DER data.
3517
 * @param [in]      derSz   Size of DER buffer in bytes.
3518
 *
3519
 * @return  0 on success.
3520
 * @return  1 when decoding DER or setting the external key fails.
3521
 */
3522
static int wolfssl_dh_load_params(WOLFSSL_DH* dh, const unsigned char* der,
3523
    word32* idx, word32 derSz)
3524
{
3525
    int err = 0;
3526
3527
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
3528
    int ret;
3529
3530
    /* Decode DH parameters/key from DER. */
3531
    ret = wc_DhKeyDecode(der, idx, (DhKey*)dh->internal, derSz);
3532
    if (ret != 0) {
3533
        WOLFSSL_ERROR_MSG("DhKeyDecode() failed");
3534
        err = 1;
3535
    }
3536
    if (!err) {
3537
        /* wolfSSL DH key set. */
3538
        dh->inSet = 1;
3539
3540
        /* Set the external DH key based on wolfSSL DH key. */
3541
        if (SetDhExternal(dh) != 1) {
3542
            WOLFSSL_ERROR_MSG("SetDhExternal failed");
3543
            err = 1;
3544
        }
3545
    }
3546
#else
3547
    byte* p;
3548
    byte* g;
3549
    word32 pSz = MAX_DH_SIZE;
3550
    word32 gSz = MAX_DH_SIZE;
3551
3552
    /* Only DH parameters supported. */
3553
    /* Load external and set internal. */
3554
    p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3555
    g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3556
    if ((p == NULL) || (g == NULL)) {
3557
        err = 1;
3558
    }
3559
    /* Extract the p and g as data from the DER encoded DH parameters. */
3560
    if ((!err) && (wc_DhParamsLoad(der + *idx, derSz - *idx, p, &pSz, g,
3561
            &gSz) < 0)) {
3562
        err = 1;
3563
    }
3564
    if (!err) {
3565
        /* Put p and g in as big numbers - free existing BNs. */
3566
        if (dh->p != NULL) {
3567
            wolfSSL_BN_free(dh->p);
3568
            dh->p = NULL;
3569
        }
3570
        if (dh->g != NULL) {
3571
            wolfSSL_BN_free(dh->g);
3572
            dh->g = NULL;
3573
        }
3574
        dh->p = wolfSSL_BN_bin2bn(p, (int)pSz, NULL);
3575
        dh->g = wolfSSL_BN_bin2bn(g, (int)gSz, NULL);
3576
        if (dh->p == NULL || dh->g == NULL) {
3577
            err = 1;
3578
        }
3579
        else {
3580
            /* External DH key parameters were set. */
3581
            dh->exSet = 1;
3582
        }
3583
    }
3584
3585
    /* Set internal as the outside has been updated. */
3586
    if ((!err) && (SetDhInternal(dh) != 1)) {
3587
        WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
3588
        err = 1;
3589
    }
3590
3591
    if (!err) {
3592
        *idx += wolfssl_der_length(der + *idx, derSz - *idx);
3593
    }
3594
3595
    XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3596
    XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3597
#endif
3598
3599
    return err;
3600
}
3601
3602
#ifdef OPENSSL_ALL
3603
3604
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
3605
/* Convert DER encoded DH parameters to a WOLFSSL_DH structure.
3606
 *
3607
 * @param [out]     dh      DH key to put parameters into. May be NULL.
3608
 * @param [in, out] pp      Pointer to DER encoded DH parameters.
3609
 *                          Value updated to end of data when dh is not NULL.
3610
 * @param [in]      length  Length of data available in bytes.
3611
 *
3612
 * @return  DH key on success.
3613
 * @return  NULL on failure.
3614
 */
3615
WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH** dh, const unsigned char** pp,
3616
    long length)
3617
{
3618
    WOLFSSL_DH *newDh = NULL;
3619
    word32 idx = 0;
3620
    int err = 0;
3621
3622
    WOLFSSL_ENTER("wolfSSL_d2i_DHparams");
3623
3624
    /* Validate parameters. */
3625
    if ((pp == NULL) || (length <= 0)) {
3626
        WOLFSSL_ERROR_MSG("bad argument");
3627
        err = 1;
3628
    }
3629
3630
    /* Create new DH key to return. */
3631
    if ((!err) && ((newDh = wolfSSL_DH_new()) == NULL)) {
3632
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed");
3633
        err = 1;
3634
    }
3635
    if ((!err) && (wolfssl_dh_load_params(newDh, *pp, &idx,
3636
            (word32)length) != 0)) {
3637
        WOLFSSL_ERROR_MSG("Loading DH parameters failed");
3638
        err = 1;
3639
    }
3640
3641
    if ((!err) && (dh != NULL)) {
3642
        /* Return through parameter too. */
3643
        *dh = newDh;
3644
        /* Move buffer on by the used amount. */
3645
        *pp += idx;
3646
    }
3647
3648
    if (err && (newDh != NULL)) {
3649
        /* Dispose of any created DH key. */
3650
        wolfSSL_DH_free(newDh);
3651
        newDh = NULL;
3652
    }
3653
    return newDh;
3654
}
3655
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
3656
3657
/* Converts internal WOLFSSL_DH structure to DER encoded DH parameters.
3658
 *
3659
 * @params [in]      dh   DH key with parameters to encode.
3660
 * @params [in, out] out  Pointer to buffer to encode into.
3661
 *                        When NULL or pointer to NULL, only length returned.
3662
 * @return  0 on error.
3663
 * @return  Size of DER encoding in bytes on success.
3664
 */
3665
int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out)
3666
{
3667
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GT(5,0)) && defined(WOLFSSL_DH_EXTRA)
3668
    /* Set length to an arbitrarily large value for wc_DhParamsToDer(). */
3669
    word32 len = (word32)-1;
3670
    int err = 0;
3671
3672
    /* Validate parameters. */
3673
    if (dh == NULL) {
3674
        WOLFSSL_ERROR_MSG("Bad parameters");
3675
        err = 1;
3676
    }
3677
3678
    /* Push external DH data into internal DH key if not set. */
3679
    if ((!err) && (!dh->inSet) && (SetDhInternal((WOLFSSL_DH*)dh) != 1)) {
3680
        WOLFSSL_ERROR_MSG("Bad DH set internal");
3681
        err = 1;
3682
    }
3683
    if (!err) {
3684
        int ret;
3685
        unsigned char* der = NULL;
3686
3687
        /* Use *out when available otherwise NULL. */
3688
        if (out != NULL) {
3689
            der = *out;
3690
        }
3691
        /* Get length and/or encode. */
3692
        ret = wc_DhParamsToDer((DhKey*)dh->internal, der, &len);
3693
        /* Length of encoded data is returned on success. */
3694
        if (ret > 0) {
3695
            *out += len;
3696
        }
3697
        /* An error occurred unless only length returned. */
3698
        else if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
3699
            err = 1;
3700
        }
3701
    }
3702
3703
    /* Set return to 0 on error. */
3704
    if (err) {
3705
        len = 0;
3706
    }
3707
    return (int)len;
3708
#else
3709
    word32 len;
3710
    int ret = 0;
3711
    int pSz;
3712
    int gSz;
3713
3714
    WOLFSSL_ENTER("wolfSSL_i2d_DHparams");
3715
3716
    /* Validate parameters. */
3717
    if (dh == NULL) {
3718
        WOLFSSL_ERROR_MSG("Bad parameters");
3719
        len = 0;
3720
    }
3721
    else {
3722
        /* SEQ <len>
3723
         *   INT <len> [0x00] <prime>
3724
         *   INT <len> [0x00] <generator>
3725
         * Integers have 0x00 prepended if the top bit of positive number is
3726
         * set.
3727
         */
3728
        /* Get total length of prime including any prepended zeros. */
3729
        pSz = mp_unsigned_bin_size((mp_int*)dh->p->internal) +
3730
              mp_leading_bit((mp_int*)dh->p->internal);
3731
        /* Get total length of generator including any prepended zeros. */
3732
        gSz = mp_unsigned_bin_size((mp_int*)dh->g->internal) +
3733
              mp_leading_bit((mp_int*)dh->g->internal);
3734
        /* Calculate length of data in sequence. */
3735
        len = 1 + ASN_LEN_SIZE(pSz) + pSz +
3736
              1 + ASN_LEN_SIZE(gSz) + gSz;
3737
        /* Add in the length of the SEQUENCE. */
3738
        len += 1 + ASN_LEN_SIZE(len);
3739
3740
        if ((out != NULL) && (*out != NULL)) {
3741
            /* Encode parameters. */
3742
            ret = StoreDHparams(*out, &len, (mp_int*)dh->p->internal,
3743
                (mp_int*)dh->g->internal);
3744
            if (ret != MP_OKAY) {
3745
                WOLFSSL_ERROR_MSG("StoreDHparams error");
3746
                len = 0;
3747
            }
3748
            else {
3749
                /* Move pointer on if encoded. */
3750
                *out += len;
3751
            }
3752
        }
3753
    }
3754
3755
    return (int)len;
3756
#endif
3757
}
3758
3759
#endif /* OPENSSL_ALL */
3760
3761
#endif /* !NO_CERTS */
3762
3763
#endif /* OPENSSL_EXTRA */
3764
3765
#if defined(OPENSSL_EXTRA) ||  \
3766
 ((!defined(NO_BIO) || !defined(NO_FILESYSTEM)) && \
3767
  defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) || \
3768
  defined(WOLFSSL_MYSQL_COMPATIBLE))
3769
3770
/* Load the DER encoded DH parameters into DH key.
3771
 *
3772
 * @param [in, out] dh      DH key to load parameters into.
3773
 * @param [in]      derBuf  Buffer holding DER encoded parameters data.
3774
 * @param [in]      derSz   Size of DER data in buffer in bytes.
3775
 *
3776
 * @return  1 on success.
3777
 * @return  -1 when DH or derBuf is NULL,
3778
 *                  internal DH key in DH is NULL,
3779
 *                  derSz is 0 or less,
3780
 *                  error decoding DER data or
3781
 *                  setting external parameter values fails.
3782
 */
3783
int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
3784
{
3785
    int    ret = 1;
3786
    word32 idx = 0;
3787
3788
    /* Validate parameters. */
3789
    if ((dh == NULL) || (dh->internal == NULL) || (derBuf == NULL) ||
3790
            (derSz <= 0)) {
3791
        WOLFSSL_ERROR_MSG("Bad function arguments");
3792
        ret = WOLFSSL_FATAL_ERROR;
3793
    }
3794
3795
    if ((ret == 1) && (wolfssl_dh_load_params(dh, derBuf, &idx,
3796
            (word32)derSz) != 0)) {
3797
        WOLFSSL_ERROR_MSG("DH key decode failed");
3798
        ret = WOLFSSL_FATAL_ERROR;
3799
    }
3800
3801
    return ret;
3802
}
3803
3804
#endif
3805
3806
/*
3807
 * DH PEM APIs
3808
 */
3809
3810
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
3811
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
3812
3813
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
3814
/* Create a DH key by reading the PEM encoded data from the BIO.
3815
 *
3816
 * @param [in]      bio         BIO object to read from.
3817
 * @param [in, out] dh          DH key to use. May be NULL.
3818
 * @param [in]      pem         PEM data to decode.
3819
 * @param [in]      pemSz       Size of PEM data in bytes.
3820
 * @param [in]      memAlloced  Indicates that pem was allocated and is to be
3821
 *                              freed after use.
3822
 * @return  DH key on success.
3823
 * @return  NULL on failure.
3824
 */
3825
static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **dh,
3826
    unsigned char* pem, int pemSz, int memAlloced)
3827
{
3828
    WOLFSSL_DH* localDh = NULL;
3829
    DerBuffer *der = NULL;
3830
    int err = 0;
3831
3832
    /* Convert PEM to DER assuming DH Parameter format. */
3833
    if ((!err) && (PemToDer(pem, pemSz, DH_PARAM_TYPE, &der, NULL, NULL,
3834
            NULL) < 0)) {
3835
        /* Convert PEM to DER assuming X9.42 DH Parameter format. */
3836
        if (PemToDer(pem, pemSz, X942_PARAM_TYPE, &der, NULL, NULL, NULL)
3837
                != 0) {
3838
            err = 1;
3839
        }
3840
        /* If Success on X9.42 DH format, clear error from failed DH format */
3841
        else {
3842
            unsigned long error;
3843
            CLEAR_ASN_NO_PEM_HEADER_ERROR(error);
3844
        }
3845
    }
3846
    if (memAlloced) {
3847
        /* PEM data no longer needed.  */
3848
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3849
    }
3850
3851
    if (!err) {
3852
        /* Use the DH key passed in or allocate a new one. */
3853
        if (dh != NULL) {
3854
            localDh = *dh;
3855
        }
3856
        if (localDh == NULL) {
3857
            localDh = wolfSSL_DH_new();
3858
            if (localDh == NULL) {
3859
                err = 1;
3860
            }
3861
        }
3862
    }
3863
    /* Load the DER encoded DH parameters from buffer into a DH key. */
3864
    if ((!err) && (wolfSSL_DH_LoadDer(localDh, der->buffer, (int)der->length)
3865
            != 1)) {
3866
        /* Free an allocated DH key. */
3867
        if ((dh == NULL) || (localDh != *dh)) {
3868
            wolfSSL_DH_free(localDh);
3869
        }
3870
        localDh = NULL;
3871
        err = 1;
3872
    }
3873
    /* Return the DH key on success. */
3874
    if ((!err) && (dh != NULL)) {
3875
        *dh = localDh;
3876
    }
3877
3878
    /* Dispose of DER data. */
3879
    if (der != NULL) {
3880
        FreeDer(&der);
3881
    }
3882
    return localDh;
3883
}
3884
#endif /* !NO_BIO || !NO_FILESYSTEM */
3885
3886
#ifndef NO_BIO
3887
/* Create a DH key by reading the PEM encoded data from the BIO.
3888
 *
3889
 * DH parameters are public data and are not expected to be encrypted.
3890
 *
3891
 * @param [in]      bio   BIO object to read from.
3892
 * @param [in, out] dh    DH key to   When pointer to
3893
 *                        NULL, a new DH key is created.
3894
 * @param [in]      cb    Password callback when PEM encrypted. Not used.
3895
 * @param [in]      pass  NUL terminated string for passphrase when PEM
3896
 *                        encrypted. Not used.
3897
 * @return  DH key on success.
3898
 * @return  NULL on failure.
3899
 */
3900
WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **dh,
3901
    wc_pem_password_cb *cb, void *pass)
3902
{
3903
    WOLFSSL_DH* localDh = NULL;
3904
    int err = 0;
3905
    unsigned char* mem = NULL;
3906
    int size = 0;
3907
    int memAlloced = 0;
3908
3909
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
3910
3911
    (void)cb;
3912
    (void)pass;
3913
3914
    /* Validate parameters. */
3915
    if (bio == NULL) {
3916
        WOLFSSL_ERROR_MSG("Bad Function Argument bio is NULL");
3917
        err = 1;
3918
    }
3919
3920
    /* Get buffer of data from BIO or read data from the BIO into a new buffer.
3921
     */
3922
    if ((!err) && (wolfssl_read_bio(bio, (char**)&mem, &size, &memAlloced)
3923
            != 0)) {
3924
        err = 1;
3925
    }
3926
    if (!err) {
3927
        /* Create a DH key from the PEM - try two different headers. */
3928
        localDh = wolfssl_dhparams_read_pem(dh, mem, size, memAlloced);
3929
    }
3930
3931
    return localDh;
3932
}
3933
3934
#endif /* !NO_BIO */
3935
3936
#ifndef NO_FILESYSTEM
3937
/* Read DH parameters from a file pointer into DH key.
3938
 *
3939
 * DH parameters are public data and are not expected to be encrypted.
3940
 *
3941
 * @param [in]      fp    File pointer to read DH parameter file from.
3942
 * @param [in, out] dh    DH key with parameters if not NULL. When pointer to
3943
 *                        NULL, a new DH key is created.
3944
 * @param [in]      cb    Password callback when PEM encrypted. Not used.
3945
 * @param [in]      pass  NUL terminated string for passphrase when PEM
3946
 *                        encrypted. Not used.
3947
 *
3948
 * @return  NULL on failure.
3949
 * @return  DH key with parameters set on success.
3950
 */
3951
WOLFSSL_DH* wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH** dh,
3952
    wc_pem_password_cb* cb, void* pass)
3953
{
3954
    WOLFSSL_DH* localDh = NULL;
3955
    int err = 0;
3956
    unsigned char* mem = NULL;
3957
    int size = 0;
3958
3959
    (void)cb;
3960
    (void)pass;
3961
3962
    /* Read data from file pointer. */
3963
    if (wolfssl_read_file(fp, (char**)&mem, &size) != 0) {
3964
        err = 1;
3965
    }
3966
    if (!err) {
3967
        localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1);
3968
    }
3969
3970
    return localDh;
3971
}
3972
#endif /* !NO_FILESYSTEM */
3973
3974
#if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
3975
/* Encoded parameter data in DH key as DER.
3976
 *
3977
 * @param [in, out] dh    DH key object to encode.
3978
 * @param [out]     out   Buffer containing DER encoding.
3979
 * @param [in]      heap  Heap hint.
3980
 * @return  <0 on error.
3981
 * @return  Length of DER encoded DH parameters in bytes.
3982
 */
3983
static int wolfssl_dhparams_to_der(WOLFSSL_DH* dh, unsigned char** out,
3984
    void* heap)
3985
{
3986
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
3987
    int err = 0;
3988
    byte* der = NULL;
3989
    word32 derSz = 0;
3990
    DhKey* key = NULL;
3991
3992
    (void)heap;
3993
3994
    /* Set internal parameters based on external parameters. */
3995
    if ((dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
3996
        WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
3997
        err = 1;
3998
    }
3999
    if (!err) {
4000
        /* Use wolfSSL API to get length of DER encode DH parameters. */
4001
        key = (DhKey*)dh->internal;
4002
        ret = wc_DhParamsToDer(key, NULL, &derSz);
4003
        if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
4004
            WOLFSSL_ERROR_MSG("Failed to get size of DH params");
4005
            err = 1;
4006
        }
4007
    }
4008
4009
    if (!err) {
4010
        /* Allocate memory for DER encoding. */
4011
        der = (byte*)XMALLOC(derSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
4012
        if (der == NULL) {
4013
            WOLFSSL_LEAVE("wolfssl_dhparams_to_der", MEMORY_E);
4014
            err = 1;
4015
        }
4016
    }
4017
    if (!err) {
4018
        /* Encode DH parameters into DER buffer. */
4019
        ret = wc_DhParamsToDer(key, der, &derSz);
4020
        if (ret < 0) {
4021
            WOLFSSL_ERROR_MSG("Failed to export DH params");
4022
            err = 1;
4023
        }
4024
    }
4025
4026
    if (!err) {
4027
        *out = der;
4028
        der = NULL;
4029
    }
4030
    XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
4031
4032
    return ret;
4033
}
4034
4035
/* Writes the DH parameters in PEM format from "dh" out to the file pointer
4036
 * passed in.
4037
 *
4038
 * @param [in]  fp  File pointer to write to.
4039
 * @param [in]  dh  DH key to write.
4040
 * @return  1 on success.
4041
 * @return  0 on failure.
4042
 */
4043
int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
4044
{
4045
    int ret = 1;
4046
    int derSz = 0;
4047
    byte* derBuf = NULL;
4048
    void* heap = NULL;
4049
4050
    WOLFSSL_ENTER("wolfSSL_PEM_write_DHparams");
4051
4052
    /* Validate parameters. */
4053
    if ((fp == XBADFILE) || (dh == NULL)) {
4054
        WOLFSSL_ERROR_MSG("Bad Function Arguments");
4055
        ret = 0;
4056
    }
4057
4058
    if (ret == 1) {
4059
        DhKey* key = (DhKey*)dh->internal;
4060
        if (key)
4061
            heap = key->heap;
4062
        if ((derSz = wolfssl_dhparams_to_der(dh, &derBuf, heap)) < 0) {
4063
            WOLFSSL_ERROR_MSG("DER encoding failed");
4064
            ret = 0;
4065
        }
4066
        if (derBuf == NULL) {
4067
            WOLFSSL_ERROR_MSG("DER encoding failed to get buffer");
4068
            ret = 0;
4069
        }
4070
    }
4071
    if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
4072
            DH_PARAM_TYPE, NULL) != 1)) {
4073
        ret = 0;
4074
    }
4075
4076
    /* Dispose of DER buffer. */
4077
    XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
4078
4079
    WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
4080
4081
    return ret;
4082
}
4083
#endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */
4084
4085
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE ||
4086
        * OPENSSL_EXTRA */
4087
4088
/*
4089
 * DH get/set APIs
4090
 */
4091
4092
#ifdef OPENSSL_EXTRA
4093
4094
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) \
4095
    || defined(WOLFSSL_OPENSSH) || defined(OPENSSL_EXTRA)
4096
4097
/* Set the members of DhKey into WOLFSSL_DH
4098
 * Specify elements to set via the 2nd parameter
4099
 *
4100
 * @param [in, out] dh   DH key to synchronize.
4101
 * @param [in]      elm  Elements to synchronize.
4102
 * @return  1 on success.
4103
 * @return  -1 on failure.
4104
 */
4105
int SetDhExternal_ex(WOLFSSL_DH *dh, int elm)
4106
{
4107
    int ret = 1;
4108
    DhKey *key = NULL;
4109
4110
    WOLFSSL_ENTER("SetDhExternal_ex");
4111
4112
    /* Validate parameters. */
4113
    if ((dh == NULL) || (dh->internal == NULL)) {
4114
        WOLFSSL_ERROR_MSG("dh key NULL error");
4115
        ret = WOLFSSL_FATAL_ERROR;
4116
    }
4117
4118
    if (ret == 1) {
4119
        /* Get the wolfSSL DH key. */
4120
        key = (DhKey*)dh->internal;
4121
    }
4122
4123
    if ((ret == 1) && (elm & ELEMENT_P)) {
4124
        /* Set the prime. */
4125
        if (wolfssl_bn_set_value(&dh->p, &key->p) != 1) {
4126
            WOLFSSL_ERROR_MSG("dh param p error");
4127
            ret = WOLFSSL_FATAL_ERROR;
4128
        }
4129
    }
4130
    if ((ret == 1) && (elm & ELEMENT_G)) {
4131
        /* Set the generator. */
4132
        if (wolfssl_bn_set_value(&dh->g, &key->g) != 1) {
4133
            WOLFSSL_ERROR_MSG("dh param g error");
4134
            ret = WOLFSSL_FATAL_ERROR;
4135
        }
4136
    }
4137
    if ((ret == 1) && (elm & ELEMENT_Q)) {
4138
        /* Set the order. */
4139
        if (wolfssl_bn_set_value(&dh->q, &key->q) != 1) {
4140
            WOLFSSL_ERROR_MSG("dh param q error");
4141
            ret = WOLFSSL_FATAL_ERROR;
4142
        }
4143
    }
4144
#ifdef WOLFSSL_DH_EXTRA
4145
    if ((ret == 1) && (elm & ELEMENT_PRV)) {
4146
        /* Set the private key. */
4147
        if (wolfssl_bn_set_value(&dh->priv_key, &key->priv) != 1) {
4148
            WOLFSSL_ERROR_MSG("No DH Private Key");
4149
            ret = WOLFSSL_FATAL_ERROR;
4150
        }
4151
    }
4152
    if ((ret == 1) && (elm & ELEMENT_PUB)) {
4153
        /* Set the public key. */
4154
        if (wolfssl_bn_set_value(&dh->pub_key, &key->pub) != 1) {
4155
            WOLFSSL_ERROR_MSG("No DH Public Key");
4156
            ret = WOLFSSL_FATAL_ERROR;
4157
        }
4158
    }
4159
#endif /* WOLFSSL_DH_EXTRA */
4160
4161
    if (ret == 1) {
4162
        /* On success record that the external values have been set. */
4163
        dh->exSet = 1;
4164
    }
4165
4166
    return ret;
4167
}
4168
/* Set the members of DhKey into WOLFSSL_DH
4169
 * DhKey was populated from wc_DhKeyDecode
4170
 * p, g, pub_key and priv_key are set.
4171
 *
4172
 * @param [in, out] dh   DH key to synchronize.
4173
 * @return  1 on success.
4174
 * @return  -1 on failure.
4175
 */
4176
int SetDhExternal(WOLFSSL_DH *dh)
4177
{
4178
    /* Assuming Q not required when using this API. */
4179
    int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV;
4180
    WOLFSSL_ENTER("SetDhExternal");
4181
    return SetDhExternal_ex(dh, elements);
4182
}
4183
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH || OPENSSL_EXTRA */
4184
4185
/* Set the internal/wolfSSL DH key with data from the external parts.
4186
 *
4187
 * @param [in, out] dh   DH key to synchronize.
4188
 * @return  1 on success.
4189
 * @return  -1 on failure.
4190
 */
4191
int SetDhInternal(WOLFSSL_DH* dh)
4192
{
4193
    int ret = 1;
4194
    DhKey *key = NULL;
4195
4196
    WOLFSSL_ENTER("SetDhInternal");
4197
4198
    /* Validate parameters. */
4199
    if ((dh == NULL) || (dh->p == NULL) || (dh->g == NULL)) {
4200
        WOLFSSL_ERROR_MSG("Bad function arguments");
4201
        ret = WOLFSSL_FATAL_ERROR;
4202
    }
4203
    if (ret == 1) {
4204
        /* Get the wolfSSL DH key. */
4205
        key = (DhKey*)dh->internal;
4206
4207
        /* Clear out key and initialize. */
4208
        wc_FreeDhKey(key);
4209
        if (wc_InitDhKey(key) != 0) {
4210
            ret = WOLFSSL_FATAL_ERROR;
4211
        }
4212
    }
4213
    if (ret == 1) {
4214
        /* Transfer prime. */
4215
        if (wolfssl_bn_get_value(dh->p, &key->p) != 1) {
4216
            ret = WOLFSSL_FATAL_ERROR;
4217
        }
4218
    }
4219
    if (ret == 1) {
4220
        /* Transfer generator. */
4221
        if (wolfssl_bn_get_value(dh->g, &key->g) != 1) {
4222
            ret = WOLFSSL_FATAL_ERROR;
4223
        }
4224
    }
4225
#ifdef HAVE_FFDHE_Q
4226
    /* Transfer order if available. */
4227
    if ((ret == 1) && (dh->q != NULL)) {
4228
        if (wolfssl_bn_get_value(dh->q, &key->q) != 1) {
4229
            ret = WOLFSSL_FATAL_ERROR;
4230
        }
4231
    }
4232
#endif
4233
#ifdef WOLFSSL_DH_EXTRA
4234
    /* Transfer private key if available. */
4235
    if ((ret == 1) && (dh->priv_key != NULL) &&
4236
            (!wolfSSL_BN_is_zero(dh->priv_key))) {
4237
        if (wolfssl_bn_get_value(dh->priv_key, &key->priv) != 1) {
4238
            ret = WOLFSSL_FATAL_ERROR;
4239
        }
4240
    }
4241
    /* Transfer public key if available. */
4242
    if ((ret == 1) && (dh->pub_key != NULL) &&
4243
            (!wolfSSL_BN_is_zero(dh->pub_key))) {
4244
        if (wolfssl_bn_get_value(dh->pub_key, &key->pub) != 1) {
4245
            ret = WOLFSSL_FATAL_ERROR;
4246
        }
4247
    }
4248
#endif /* WOLFSSL_DH_EXTRA */
4249
4250
    if (ret == 1) {
4251
        /* On success record that the internal values have been set. */
4252
        dh->inSet = 1;
4253
    }
4254
4255
    return ret;
4256
}
4257
4258
/* Get the size, in bytes, of the DH key.
4259
 *
4260
 * Return code compliant with OpenSSL.
4261
 *
4262
 * @param [in] dh  DH key.
4263
 * @return  -1 on error.
4264
 * @return  Size of DH key in bytes on success.
4265
 */
4266
int wolfSSL_DH_size(WOLFSSL_DH* dh)
4267
{
4268
    WOLFSSL_ENTER("wolfSSL_DH_size");
4269
4270
    if (dh == NULL)
4271
        return WOLFSSL_FATAL_ERROR;
4272
4273
    /* Validate parameter. */
4274
    /* Size of key is size of prime in bytes. */
4275
    return wolfSSL_BN_num_bytes(dh->p);
4276
}
4277
4278
/**
4279
 * Return parameters p, q and/or g of the DH key.
4280
 *
4281
 * @param [in]  dh  DH key to retrieve parameters from.
4282
 * @param [out] p   Pointer to return prime in. May be NULL.
4283
 * @param [out] q   Pointer to return order in. May be NULL.
4284
 * @param [out] g   Pointer to return generator in. May be NULL.
4285
 */
4286
void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
4287
    const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
4288
{
4289
    WOLFSSL_ENTER("wolfSSL_DH_get0_pqg");
4290
4291
    if (dh != NULL) {
4292
        /* Return prime if required. */
4293
        if (p != NULL) {
4294
            *p = dh->p;
4295
        }
4296
        /* Return order if required. */
4297
        if (q != NULL) {
4298
            *q = dh->q;
4299
        }
4300
        /* Return generator if required. */
4301
        if (g != NULL) {
4302
            *g = dh->g;
4303
        }
4304
    }
4305
}
4306
4307
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
4308
 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
4309
#if defined(OPENSSL_ALL) || \
4310
    defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
4311
/* Sets the parameters p, g and optionally q into the DH key.
4312
 *
4313
 * Ownership of p, q and g get taken over by "dh" on success and should be
4314
 * free'd with a call to wolfSSL_DH_free -- not individually.
4315
 *
4316
 * @param [in, out] dh   DH key to set.
4317
 * @param [in]      p    Prime value to set. May be NULL when value already
4318
 *                       present.
4319
 * @param [in]      q    Order value to set. May be NULL.
4320
 * @param [in]      g    Generator value to set. May be NULL when value already
4321
 *                       present.
4322
 * @return  1 on success.
4323
 * @return  0 on failure.
4324
 */
4325
int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
4326
    WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
4327
{
4328
    int ret = 1;
4329
4330
    WOLFSSL_ENTER("wolfSSL_DH_set0_pqg");
4331
4332
    /* Validate parameters - q is optional. */
4333
    if (dh == NULL) {
4334
        WOLFSSL_ERROR_MSG("Bad function arguments");
4335
        ret = 0;
4336
    }
4337
    /* p can be NULL if we already have one set. */
4338
    if ((ret == 1) && (p == NULL) && (dh->p == NULL)) {
4339
        WOLFSSL_ERROR_MSG("Bad function arguments");
4340
        ret = 0;
4341
    }
4342
    /* g can be NULL if we already have one set. */
4343
    if ((ret == 1) && (g == NULL) && (dh->g == NULL)) {
4344
        WOLFSSL_ERROR_MSG("Bad function arguments");
4345
        ret = 0;
4346
    }
4347
4348
    if (ret == 1) {
4349
        /* Invalidate internal key. */
4350
        dh->inSet = 0;
4351
4352
        /* Free external representation of parameters and set with those passed
4353
         * in. */
4354
        if (p != NULL) {
4355
            wolfSSL_BN_free(dh->p);
4356
            dh->p = p;
4357
        }
4358
        if (q != NULL) {
4359
            wolfSSL_BN_free(dh->q);
4360
            dh->q = q;
4361
        }
4362
        if (g != NULL) {
4363
            wolfSSL_BN_free(dh->g);
4364
            dh->g = g;
4365
        }
4366
        /* External DH key parameters were set. */
4367
        dh->exSet = 1;
4368
4369
        /* Set internal/wolfSSL DH key as well. */
4370
        if (SetDhInternal(dh) != 1) {
4371
            WOLFSSL_ERROR_MSG("Unable to set internal DH key");
4372
            /* Don't keep parameters on failure. */
4373
            dh->p = NULL;
4374
            dh->q = NULL;
4375
            dh->g = NULL;
4376
            /* Internal and external DH key not set. */
4377
            dh->inSet = 0;
4378
            dh->exSet = 0;
4379
            ret = 0;
4380
        }
4381
    }
4382
4383
    return ret;
4384
}
4385
4386
/* Set the length of the DH private key in bits.
4387
 *
4388
 * Length field is checked at generation.
4389
 *
4390
 * @param [in, out] dh   DH key to set.
4391
 * @param [in]      len  Length of DH private key in bytes.
4392
 * @return  0 on failure.
4393
 * @return  1 on success.
4394
 */
4395
int wolfSSL_DH_set_length(WOLFSSL_DH *dh, long len)
4396
{
4397
    int ret = 1;
4398
4399
    WOLFSSL_ENTER("wolfSSL_DH_set_length");
4400
4401
    /* Validate parameter. */
4402
    if (dh == NULL) {
4403
        WOLFSSL_ERROR_MSG("Bad function arguments");
4404
        ret = 0;
4405
    }
4406
    else {
4407
        /* Store length. */
4408
        dh->length = (int)len;
4409
    }
4410
4411
    return ret;
4412
}
4413
#endif /* OPENSSL_ALL || (v1.1.0 or later) */
4414
#endif
4415
4416
/* Get the public and private keys requested.
4417
 *
4418
 * @param [in]  dh         DH key to get keys from.
4419
 * @param [out] pub_key    Pointer to return public key in. May be NULL.
4420
 * @param [out] priv_key   Pointer to return private key in. May be NULL.
4421
 */
4422
void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **pub_key,
4423
    const WOLFSSL_BIGNUM **priv_key)
4424
{
4425
    WOLFSSL_ENTER("wolfSSL_DH_get0_key");
4426
4427
    /* Get only when valid DH passed in. */
4428
    if (dh != NULL) {
4429
        /* Return public key if required and available. */
4430
        if ((pub_key != NULL) && (dh->pub_key != NULL)) {
4431
            *pub_key = dh->pub_key;
4432
        }
4433
        /* Return private key if required and available. */
4434
        if ((priv_key != NULL) && (dh->priv_key != NULL)) {
4435
            *priv_key = dh->priv_key;
4436
        }
4437
    }
4438
}
4439
4440
/* Set the public and/or private key.
4441
 *
4442
 * @param [in, out] dh        DH key to have keys set into.
4443
 * @param [in]      pub_key   Public key to set. May be NULL.
4444
 * @param [in]      priv_key  Private key to set. May be NULL.
4445
 * @return  0 on failure.
4446
 * @return  1 on success.
4447
 */
4448
int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key,
4449
    WOLFSSL_BIGNUM *priv_key)
4450
{
4451
    int ret = 1;
4452
#ifdef WOLFSSL_DH_EXTRA
4453
    DhKey *key = NULL;
4454
#endif
4455
4456
    WOLFSSL_ENTER("wolfSSL_DH_set0_key");
4457
4458
    /* Validate parameters. */
4459
    if (dh == NULL) {
4460
        ret = 0;
4461
    }
4462
#ifdef WOLFSSL_DH_EXTRA
4463
    else {
4464
        key = (DhKey*)dh->internal;
4465
    }
4466
#endif
4467
4468
    /* Replace public key when one passed in. */
4469
    if ((ret == 1) && (pub_key != NULL)) {
4470
        wolfSSL_BN_free(dh->pub_key);
4471
        dh->pub_key = pub_key;
4472
    #ifdef WOLFSSL_DH_EXTRA
4473
        if (wolfssl_bn_get_value(dh->pub_key, &key->pub) != 1) {
4474
            ret = 0;
4475
        }
4476
    #endif
4477
    }
4478
4479
    /* Replace private key when one passed in. */
4480
    if ((ret == 1) && (priv_key != NULL)) {
4481
        wolfSSL_BN_clear_free(dh->priv_key);
4482
        dh->priv_key = priv_key;
4483
    #ifdef WOLFSSL_DH_EXTRA
4484
        if (wolfssl_bn_get_value(dh->priv_key, &key->priv) != 1) {
4485
            ret = 0;
4486
        }
4487
    #endif
4488
    }
4489
4490
    return ret;
4491
}
4492
4493
#endif /* OPENSSL_EXTRA */
4494
4495
/*
4496
 * DH check APIs
4497
 */
4498
4499
#ifdef OPENSSL_EXTRA
4500
4501
#ifndef NO_CERTS
4502
4503
#ifdef OPENSSL_ALL
4504
/* Check whether BN number is a prime.
4505
 *
4506
 * @param [in]  n        Number to check.
4507
 * @param [out] isPrime  MP_YES when prime and MP_NO when not.
4508
 * @return  1 on success.
4509
 * @return  0 on error.
4510
 */
4511
static int wolfssl_dh_check_prime(WOLFSSL_BIGNUM* n, int* isPrime)
4512
{
4513
    int ret = 1;
4514
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4515
    WC_RNG* rng;
4516
    int localRng;
4517
4518
    /* Make an RNG with tmpRng or get global. */
4519
    rng = wolfssl_make_rng(tmpRng, &localRng);
4520
    if (rng == NULL) {
4521
        ret = 0;
4522
    }
4523
    if (ret == 1) {
4524
        mp_int* prime = (mp_int*)n->internal;
4525
4526
        if (mp_prime_is_prime_ex(prime, 8, isPrime, rng) != 0) {
4527
            ret = 0;
4528
        }
4529
        /* Free local random number generator if created. */
4530
        if (localRng) {
4531
            wc_FreeRng(rng);
4532
            WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4533
        }
4534
    }
4535
4536
    return ret;
4537
}
4538
4539
/* Checks the Diffie-Hellman parameters.
4540
 *
4541
 * Checks that the generator and prime are available.
4542
 * Checks that the prime is prime.
4543
 * OpenSSL expects codes to be non-NULL.
4544
 *
4545
 * @param [in]  dh     DH key to check.
4546
 * @param [out] codes  Codes of checks that failed.
4547
 * @return  1 on success.
4548
 * @return  0 when DH is NULL, there were errors or failed to create a random
4549
 *          number generator.
4550
 */
4551
int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
4552
{
4553
    int ret = 1;
4554
    int errors = 0;
4555
4556
    WOLFSSL_ENTER("wolfSSL_DH_check");
4557
4558
    /* Validate parameters. */
4559
    if (dh == NULL) {
4560
        ret = 0;
4561
    }
4562
4563
    /* Check generator available. */
4564
    if ((ret == 1) && ((dh->g == NULL) || (dh->g->internal == NULL))) {
4565
        errors |= DH_NOT_SUITABLE_GENERATOR;
4566
    }
4567
4568
    if (ret == 1) {
4569
        /* Check prime available. */
4570
        if ((dh->p == NULL) || (dh->p->internal == NULL)) {
4571
            errors |= DH_CHECK_P_NOT_PRIME;
4572
        }
4573
        else {
4574
            /* Test if dh->p is prime. */
4575
            int isPrime = MP_NO;
4576
            ret = wolfssl_dh_check_prime(dh->p, &isPrime);
4577
            /* Set error code if parameter p is not prime. */
4578
            if ((ret == 1) && (isPrime != MP_YES)) {
4579
                errors |= DH_CHECK_P_NOT_PRIME;
4580
            }
4581
        }
4582
    }
4583
4584
    /* Return errors when user wants exact issues. */
4585
    if (codes != NULL) {
4586
        *codes = errors;
4587
    }
4588
    else if (errors) {
4589
        ret = 0;
4590
    }
4591
4592
    return ret;
4593
}
4594
4595
#endif /* OPENSSL_ALL */
4596
4597
#endif /* !NO_CERTS */
4598
4599
#endif /* OPENSSL_EXTRA */
4600
4601
/*
4602
 * DH generate APIs
4603
 */
4604
4605
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
4606
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
4607
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
4608
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
4609
4610
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST)
4611
/* Generate DH parameters.
4612
 *
4613
 * @param [in] prime_len  Length of prime in bits.
4614
 * @param [in] generator  Generator value to use.
4615
 * @param [in] callback   Called with progress information. Unused.
4616
 * @param [in] cb_arg     User callback argument. Unused.
4617
 * @return  NULL on failure.
4618
 * @return  DH key on success.
4619
 */
4620
WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
4621
                           void (*callback) (int, int, void *), void *cb_arg)
4622
{
4623
    WOLFSSL_DH* dh = NULL;
4624
4625
    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
4626
    /* Not supported by wolfSSl APIs. */
4627
    (void)callback;
4628
    (void)cb_arg;
4629
4630
    /* Create an empty DH key. */
4631
    if ((dh = wolfSSL_DH_new()) == NULL) {
4632
        WOLFSSL_ERROR_MSG("wolfSSL_DH_new error");
4633
    }
4634
    /* Generate parameters into DH key. */
4635
    else if (wolfSSL_DH_generate_parameters_ex(dh, prime_len, generator, NULL)
4636
            != 1) {
4637
        WOLFSSL_ERROR_MSG("wolfSSL_DH_generate_parameters_ex error");
4638
        wolfSSL_DH_free(dh);
4639
        dh = NULL;
4640
    }
4641
4642
    return dh;
4643
}
4644
4645
/* Generate DH parameters.
4646
 *
4647
 * @param [in] dh         DH key to generate parameters into.
4648
 * @param [in] prime_len  Length of prime in bits.
4649
 * @param [in] generator  Generator value to use.
4650
 * @param [in] callback   Called with progress information. Unused.
4651
 * @param [in] cb_arg     User callback argument. Unused.
4652
 * @return  0 on failure.
4653
 * @return  1 on success.
4654
 */
4655
int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len,
4656
    int generator, void (*callback) (int, int, void *))
4657
{
4658
    int ret = 1;
4659
    DhKey* key = NULL;
4660
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4661
    WC_RNG* rng = NULL;
4662
    int localRng = 0;
4663
4664
    WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
4665
    /* Not supported by wolfSSL APIs. */
4666
    (void)callback;
4667
    (void)generator;
4668
4669
    /* Validate parameters. */
4670
    if (dh == NULL) {
4671
        WOLFSSL_ERROR_MSG("Bad parameter");
4672
        ret = 0;
4673
    }
4674
4675
    if (ret == 1) {
4676
        /* Make an RNG with tmpRng or get global. */
4677
        rng = wolfssl_make_rng(tmpRng, &localRng);
4678
        if (rng == NULL) {
4679
            WOLFSSL_ERROR_MSG("No RNG to use");
4680
            ret = 0;
4681
        }
4682
    }
4683
4684
    if (ret == 1) {
4685
        /* Get internal/wolfSSL DH key. */
4686
        key = (DhKey*)dh->internal;
4687
4688
        /* Clear out data from internal DH key. */
4689
        wc_FreeDhKey(key);
4690
        /* Re-initialize internal DH key. */
4691
        if (wc_InitDhKey(key) != 0) {
4692
            ret = 0;
4693
        }
4694
    }
4695
    if (ret == 1) {
4696
    #ifndef WOLFSSL_NO_DH_GEN_PARAMS
4697
        /* Generate parameters into internal DH key. */
4698
        if (wc_DhGenerateParams(rng, prime_len, key) != 0) {
4699
            WOLFSSL_ERROR_MSG("wc_DhGenerateParams error");
4700
            ret = 0;
4701
        }
4702
    #else
4703
        WOLFSSL_ERROR_MSG("DH parameter generation disabled in this build");
4704
        (void)prime_len;
4705
        ret = 0;
4706
    #endif
4707
    }
4708
4709
    /* Free local random number generator if created. */
4710
    if (localRng) {
4711
        wc_FreeRng(rng);
4712
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4713
    }
4714
4715
    if (ret == 1) {
4716
        /* Internal parameters set by generation. */
4717
        dh->inSet = 1;
4718
4719
        WOLFSSL_MSG("wolfSSL does not support using a custom generator.");
4720
4721
        /* Synchronize the external to the internal parameters. */
4722
        if (SetDhExternal(dh) != 1) {
4723
            WOLFSSL_ERROR_MSG("SetDhExternal error");
4724
            ret = 0;
4725
        }
4726
    }
4727
4728
    return ret;
4729
}
4730
#endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST */
4731
4732
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
4733
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
4734
        * HAVE_SBLIM_SFCB)) */
4735
4736
#ifdef OPENSSL_EXTRA
4737
4738
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
4739
 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
4740
/* Generate a public/private key pair base on parameters.
4741
 *
4742
 * @param [in, out] dh  DH key to generate keys into.
4743
 * @return  1 on success.
4744
 * @return  0 on error.
4745
 */
4746
int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
4747
{
4748
    int     ret    = 1;
4749
    word32  pubSz  = 0;
4750
    word32  privSz = 0;
4751
    word32  privAllocSz = 0;
4752
    int     localRng = 0;
4753
    WC_RNG* rng    = NULL;
4754
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4755
    unsigned char* pub    = NULL;
4756
    unsigned char* priv   = NULL;
4757
4758
    WOLFSSL_ENTER("wolfSSL_DH_generate_key");
4759
4760
    /* Validate parameters. */
4761
    if ((dh == NULL) || (dh->p == NULL) || (dh->g == NULL)) {
4762
        WOLFSSL_ERROR_MSG("Bad function arguments");
4763
        ret = 0;
4764
    }
4765
4766
    /* Synchronize the external and internal parameters. */
4767
    if ((ret == 1) && (dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
4768
        WOLFSSL_ERROR_MSG("Bad DH set internal");
4769
        ret = 0;
4770
    }
4771
4772
    if (ret == 1) {
4773
        /* Make a new RNG or use global. */
4774
        rng = wolfssl_make_rng(tmpRng, &localRng);
4775
        /* Check we have a random number generator. */
4776
        if (rng == NULL) {
4777
            ret = 0;
4778
        }
4779
    }
4780
4781
    if (ret == 1) {
4782
        /* Get the size of the prime in bytes. */
4783
        pubSz = (word32)wolfSSL_BN_num_bytes(dh->p);
4784
        if (pubSz == 0) {
4785
            WOLFSSL_ERROR_MSG("Prime parameter invalid");
4786
            ret = 0;
4787
        }
4788
    }
4789
    if (ret == 1) {
4790
        /* Private key size can be as much as the size of the prime. */
4791
        if (dh->length) {
4792
            privSz = (word32)(dh->length / 8); /* to bytes */
4793
            /* Special case where priv key is larger than dh->length / 8
4794
             * See GeneratePrivateDh */
4795
            if (dh->length == 128)
4796
                privSz = 21;
4797
        }
4798
        else {
4799
            privSz = pubSz;
4800
        }
4801
        /* Allocate public and private key arrays. Preserve the allocation
4802
         * size because wc_DhGenerateKeyPair updates privSz in-place. */
4803
        privAllocSz = privSz;
4804
        pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
4805
        priv = (unsigned char*)XMALLOC(privAllocSz, NULL,
4806
            DYNAMIC_TYPE_PRIVATE_KEY);
4807
        if (pub == NULL || priv == NULL) {
4808
            WOLFSSL_ERROR_MSG("Unable to malloc memory");
4809
            ret = 0;
4810
        }
4811
    }
4812
    if (ret == 1) {
4813
        /* Dispose of old public and private keys. */
4814
        wolfSSL_BN_free(dh->pub_key);
4815
        wolfSSL_BN_free(dh->priv_key);
4816
4817
        /* Allocate new public and private keys. */
4818
        dh->pub_key = wolfSSL_BN_new();
4819
        dh->priv_key = wolfSSL_BN_new();
4820
        if (dh->pub_key == NULL) {
4821
            WOLFSSL_ERROR_MSG("Bad DH new pub");
4822
            ret = 0;
4823
        }
4824
        if (dh->priv_key == NULL) {
4825
            WOLFSSL_ERROR_MSG("Bad DH new priv");
4826
            ret = 0;
4827
        }
4828
    }
4829
4830
    PRIVATE_KEY_UNLOCK();
4831
    /* Generate public and private keys into arrays. */
4832
    if ((ret == 1) && (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv,
4833
            &privSz, pub, &pubSz) < 0)) {
4834
        WOLFSSL_ERROR_MSG("Bad wc_DhGenerateKeyPair");
4835
        ret = 0;
4836
    }
4837
    /* Set public key from array. */
4838
    if ((ret == 1) && (wolfSSL_BN_bin2bn(pub, (int)pubSz, dh->pub_key) ==
4839
            NULL)) {
4840
        WOLFSSL_ERROR_MSG("Bad DH bn2bin error pub");
4841
        ret = 0;
4842
    }
4843
    /* Set private key from array. */
4844
    if ((ret == 1) && (wolfSSL_BN_bin2bn(priv, (int)privSz, dh->priv_key) ==
4845
            NULL)) {
4846
        WOLFSSL_ERROR_MSG("Bad DH bn2bin error priv");
4847
        ret = 0;
4848
    }
4849
    PRIVATE_KEY_LOCK();
4850
4851
    if (localRng) {
4852
        /* Free an initialized local random number generator. */
4853
        wc_FreeRng(rng);
4854
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
4855
    }
4856
    /* Dispose of allocated data. */
4857
    XFREE(pub,  NULL, DYNAMIC_TYPE_PUBLIC_KEY);
4858
    if (priv != NULL) {
4859
        ForceZero(priv, privAllocSz);
4860
        XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
4861
    }
4862
4863
    return ret;
4864
}
4865
4866
4867
static int _DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
4868
    WOLFSSL_DH* dh, int ct)
4869
{
4870
    int            ret    = 0;
4871
    word32         keySz  = 0;
4872
    int            pubSz  = MAX_DHKEY_SZ;
4873
    int            privSz = MAX_DHKEY_SZ;
4874
    int            sz     = 0;
4875
#ifdef WOLFSSL_SMALL_STACK
4876
    unsigned char* pub    = NULL;
4877
    unsigned char* priv   = NULL;
4878
#else
4879
    unsigned char  pub [MAX_DHKEY_SZ];
4880
    unsigned char  priv[MAX_DHKEY_SZ];
4881
#endif
4882
4883
    WOLFSSL_ENTER("wolfSSL_DH_compute_key");
4884
4885
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
4886
    /* Baseline-zero and register the whole stack array before it is filled so
4887
     * the bn2bin fill and every path to the ForceZero are covered. The written
4888
     * length is not known here, so the full array is registered and the XMEMSET
4889
     * keeps the unwritten tail zero. (Small-stack sibling is heap; skipped.) */
4890
    XMEMSET(priv, 0, sizeof(priv));
4891
    wc_MemZero_Add("_DH_compute_key priv", priv, sizeof(priv));
4892
#endif
4893
4894
    /* Validate parameters. */
4895
    if ((dh == NULL) || (dh->priv_key == NULL) || (otherPub == NULL)) {
4896
        WOLFSSL_ERROR_MSG("Bad function arguments");
4897
        ret = WOLFSSL_FATAL_ERROR;
4898
    }
4899
    /* Get the maximum size of computed DH key. */
4900
    if ((ret == 0) && ((keySz = (word32)wolfSSL_DH_size(dh)) == 0)) {
4901
        WOLFSSL_ERROR_MSG("Bad DH_size");
4902
        ret = WOLFSSL_FATAL_ERROR;
4903
    }
4904
    if (ret == 0) {
4905
        /* Validate the size of the private key. */
4906
        sz = wolfSSL_BN_num_bytes(dh->priv_key);
4907
        if (sz > privSz) {
4908
            WOLFSSL_ERROR_MSG("Bad priv internal size");
4909
            ret = WOLFSSL_FATAL_ERROR;
4910
        }
4911
    }
4912
    if (ret == 0) {
4913
    #ifdef WOLFSSL_SMALL_STACK
4914
        /* Keep real private key size to minimize amount allocated. */
4915
        privSz = sz;
4916
    #endif
4917
4918
        /* Validate the size of the public key. */
4919
        sz = wolfSSL_BN_num_bytes(otherPub);
4920
        if (sz > pubSz) {
4921
            WOLFSSL_ERROR_MSG("Bad otherPub size");
4922
            ret = WOLFSSL_FATAL_ERROR;
4923
        }
4924
    }
4925
4926
    if (ret == 0) {
4927
    #ifdef WOLFSSL_SMALL_STACK
4928
        /* Allocate memory for the public key array. */
4929
        pub = (unsigned char*)XMALLOC((size_t)sz, NULL,
4930
            DYNAMIC_TYPE_PUBLIC_KEY);
4931
        if (pub == NULL)
4932
            ret = WOLFSSL_FATAL_ERROR;
4933
    }
4934
    if (ret == 0) {
4935
        /* Allocate memory for the private key array. */
4936
        priv = (unsigned char*)XMALLOC((size_t)privSz, NULL,
4937
            DYNAMIC_TYPE_PRIVATE_KEY);
4938
        if (priv == NULL) {
4939
            ret = WOLFSSL_FATAL_ERROR;
4940
        }
4941
    }
4942
    if (ret == 0) {
4943
    #endif
4944
        /* Get the private key into the array. */
4945
        privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
4946
        if (privSz <= 0) {
4947
            ret = WOLFSSL_FATAL_ERROR;
4948
        }
4949
    }
4950
    if (ret == 0) {
4951
        /* Get the public key into the array. */
4952
        pubSz  = wolfSSL_BN_bn2bin(otherPub, pub);
4953
        if (pubSz <= 0) {
4954
            ret = WOLFSSL_FATAL_ERROR;
4955
        }
4956
    }
4957
    /* Synchronize the external into the internal parameters. */
4958
    if ((ret == 0) && ((dh->inSet == 0) && (SetDhInternal(dh) != 1))) {
4959
        WOLFSSL_ERROR_MSG("Bad DH set internal");
4960
        ret = WOLFSSL_FATAL_ERROR;
4961
    }
4962
4963
    PRIVATE_KEY_UNLOCK();
4964
    /* Calculate shared secret from private and public keys. */
4965
    if (ret == 0) {
4966
        word32 padded_keySz = keySz;
4967
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) && !defined(HAVE_SELFTEST)
4968
        if (ct) {
4969
            if (wc_DhAgree_ct((DhKey*)dh->internal, key, &keySz, priv,
4970
                           (word32)privSz, pub, (word32)pubSz) < 0) {
4971
                WOLFSSL_ERROR_MSG("wc_DhAgree_ct failed");
4972
                ret = WOLFSSL_FATAL_ERROR;
4973
            }
4974
        }
4975
        else
4976
#endif /* (!HAVE_FIPS || FIPS_VERSION_GE(7,0)) && !HAVE_SELFTEST */
4977
        {
4978
            if (wc_DhAgree((DhKey*)dh->internal, key, &keySz, priv,
4979
                           (word32)privSz, pub, (word32)pubSz) < 0) {
4980
                WOLFSSL_ERROR_MSG("wc_DhAgree failed");
4981
                ret = WOLFSSL_FATAL_ERROR;
4982
            }
4983
        }
4984
4985
        if ((ret == 0) && ct) {
4986
            /* Arrange for correct fixed-length, right-justified key, even if
4987
             * the crypto back end doesn't support it.  With some crypto back
4988
             * ends this forgoes formal constant-timeness on the key agreement,
4989
             * but assured that wolfSSL_DH_compute_key_padded() functions
4990
             * correctly.
4991
             */
4992
            if (keySz < padded_keySz) {
4993
                XMEMMOVE(key + (padded_keySz - keySz), key, keySz);
4994
                XMEMSET(key, 0, padded_keySz - keySz);
4995
                keySz = padded_keySz;
4996
            }
4997
        }
4998
    }
4999
    if (ret == 0) {
5000
        /* Return actual length. */
5001
        ret = (int)keySz;
5002
    }
5003
    PRIVATE_KEY_LOCK();
5004
5005
    if (privSz > 0) {
5006
#ifdef WOLFSSL_SMALL_STACK
5007
        if (priv != NULL)
5008
#endif
5009
        {
5010
            /* Zeroize sensitive data. */
5011
            ForceZero(priv, (word32)privSz);
5012
        }
5013
    }
5014
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
5015
    /* Whole array is zero here on every path (baseline + ForceZero), so the
5016
     * check always passes and the up-front registration is always retired. */
5017
    wc_MemZero_Check(priv, sizeof(priv));
5018
#endif
5019
    WC_FREE_VAR_EX(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
5020
    WC_FREE_VAR_EX(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
5021
5022
    WOLFSSL_LEAVE("wolfSSL_DH_compute_key", ret);
5023
5024
    return ret;
5025
}
5026
5027
/* Compute the shared key from the private key and peer's public key.
5028
 *
5029
 * Return code compliant with OpenSSL.
5030
 * OpenSSL returns 0 when number of bits in p are smaller than minimum
5031
 * supported.
5032
 *
5033
 * @param [out] key       Buffer to place shared key.
5034
 * @param [in]  otherPub  Peer's public key.
5035
 * @param [in]  dh        DH key containing private key.
5036
 * @return  -1 on error.
5037
 * @return  Size of shared secret in bytes on success.
5038
 */
5039
int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
5040
    WOLFSSL_DH* dh)
5041
{
5042
    return _DH_compute_key(key, otherPub, dh, 0);
5043
}
5044
5045
/* Compute the shared key from the private key and peer's public key as in
5046
 * wolfSSL_DH_compute_key, but using constant time processing, with an output
5047
 * key length fixed at the nominal DH key size.  Leading zeros are retained.
5048
 *
5049
 * Return code compliant with OpenSSL.
5050
 * OpenSSL returns 0 when number of bits in p are smaller than minimum
5051
 * supported.
5052
 *
5053
 * @param [out] key       Buffer to place shared key.
5054
 * @param [in]  otherPub  Peer's public key.
5055
 * @param [in]  dh        DH key containing private key.
5056
 * @return  -1 on error.
5057
 * @return  Size of shared secret in bytes on success.
5058
 */
5059
int wolfSSL_DH_compute_key_padded(unsigned char* key,
5060
    const WOLFSSL_BIGNUM* otherPub, WOLFSSL_DH* dh)
5061
{
5062
    return _DH_compute_key(key, otherPub, dh, 1);
5063
}
5064
5065
#endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) ||
5066
        * HAVE_FIPS_VERSION > 2 */
5067
5068
#endif /* OPENSSL_EXTRA */
5069
5070
#endif /* NO_DH */
5071
5072
/*******************************************************************************
5073
 * END OF DH API
5074
 ******************************************************************************/
5075
5076
5077
#define WOLFSSL_PK_EC_INCLUDED
5078
#include "src/pk_ec.c"
5079
5080
5081
/*******************************************************************************
5082
 * START OF EC25519 API
5083
 ******************************************************************************/
5084
5085
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
5086
5087
/* Generate an EC25519 key pair.
5088
 *
5089
 * Output keys are in little endian format.
5090
 *
5091
 * @param [out]     priv    EC25519 private key data.
5092
 * @param [in, out] privSz  On in, the size of priv in bytes.
5093
 *                          On out, the length of the private key data in bytes.
5094
 * @param [out]     pub     EC25519 public key data.
5095
 * @param [in, out] pubSz   On in, the size of pub in bytes.
5096
 *                          On out, the length of the public key data in bytes.
5097
 * @return  1 on success
5098
 * @return  0 on failure.
5099
 */
5100
int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
5101
    unsigned char *pub, unsigned int *pubSz)
5102
{
5103
#ifdef WOLFSSL_KEY_GEN
5104
    int res = 1;
5105
    int initTmpRng = 0;
5106
    WC_RNG *rng = NULL;
5107
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5108
    curve25519_key key;
5109
5110
    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
5111
5112
    /* Validate parameters. */
5113
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE25519_KEYSIZE) ||
5114
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE25519_KEYSIZE)) {
5115
        WOLFSSL_MSG("Bad arguments");
5116
        res = 0;
5117
    }
5118
5119
    if (res) {
5120
        /* Create a random number generator. */
5121
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5122
        if (rng == NULL) {
5123
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5124
            res = 0;
5125
        }
5126
    }
5127
5128
    /* Initialize a Curve25519 key. */
5129
    if (res && (wc_curve25519_init(&key) != 0)) {
5130
        WOLFSSL_MSG("wc_curve25519_init failed");
5131
        res = 0;
5132
    }
5133
    if (res) {
5134
        /* Make a Curve25519 key pair. */
5135
        int ret = wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key);
5136
        if (ret != MP_OKAY) {
5137
            WOLFSSL_MSG("wc_curve25519_make_key failed");
5138
            res = 0;
5139
        }
5140
        if (res) {
5141
            /* Export Curve25519 key pair to buffers. */
5142
            ret = wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
5143
                pubSz, EC25519_LITTLE_ENDIAN);
5144
            if (ret != MP_OKAY) {
5145
                WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
5146
                res = 0;
5147
            }
5148
        }
5149
5150
        /* Dispose of key. */
5151
        wc_curve25519_free(&key);
5152
    }
5153
5154
    if (initTmpRng) {
5155
        wc_FreeRng(rng);
5156
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5157
    }
5158
5159
    return res;
5160
#else
5161
    WOLFSSL_MSG("No Key Gen built in");
5162
5163
    (void)priv;
5164
    (void)privSz;
5165
    (void)pub;
5166
    (void)pubSz;
5167
5168
    return 0;
5169
#endif /* WOLFSSL_KEY_GEN */
5170
}
5171
5172
/* Compute a shared secret from private and public EC25519 keys.
5173
 *
5174
 * Input and output keys are in little endian format
5175
 *
5176
 * @param [out]     shared    Shared secret buffer.
5177
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
5178
 *                            On out, the length of the secret in bytes.
5179
 * @param [in]      priv      EC25519 private key data.
5180
 * @param [in]      privSz    Length of the private key data in bytes.
5181
 * @param [in]      pub       EC25519 public key data.
5182
 * @param [in]      pubSz     Length of the public key data in bytes.
5183
 * @return  1 on success
5184
 * @return  0 on failure.
5185
 */
5186
int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
5187
    const unsigned char *priv, unsigned int privSz, const unsigned char *pub,
5188
    unsigned int pubSz)
5189
{
5190
#ifdef WOLFSSL_KEY_GEN
5191
    int res = 1;
5192
    curve25519_key privkey;
5193
    curve25519_key pubkey;
5194
#ifdef WOLFSSL_CURVE25519_BLINDING
5195
    WC_RNG* rng = NULL;
5196
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5197
    int initTmpRng = 0;
5198
#endif
5199
5200
    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
5201
5202
    /* Validate parameters. */
5203
    if ((shared == NULL) || (sharedSz == NULL) ||
5204
            (*sharedSz < CURVE25519_KEYSIZE) || (priv == NULL) ||
5205
            (privSz < CURVE25519_KEYSIZE) || (pub == NULL) ||
5206
            (pubSz < CURVE25519_KEYSIZE)) {
5207
        WOLFSSL_MSG("Bad arguments");
5208
        res = 0;
5209
    }
5210
5211
    /* Initialize private key object. */
5212
    if (res && (wc_curve25519_init(&privkey) != 0)) {
5213
        WOLFSSL_MSG("wc_curve25519_init privkey failed");
5214
        res = 0;
5215
    }
5216
    if (res) {
5217
    #ifdef WOLFSSL_CURVE25519_BLINDING
5218
        /* An RNG is needed for blinding - create local or get global. */
5219
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5220
        if (rng == NULL) {
5221
            WOLFSSL_MSG("wolfSSL_EC25519_shared_key failed to make RNG");
5222
            res = 0;
5223
        }
5224
        else if (wc_curve25519_set_rng(&privkey, rng) != 0) {
5225
            res = 0;
5226
        }
5227
        else
5228
    #endif
5229
        /* Initialize public key object. */
5230
        if (wc_curve25519_init(&pubkey) != MP_OKAY) {
5231
            WOLFSSL_MSG("wc_curve25519_init pubkey failed");
5232
            res = 0;
5233
        }
5234
        if (res) {
5235
            /* Import our private key. */
5236
            int ret = wc_curve25519_import_private_ex(priv, privSz, &privkey,
5237
                EC25519_LITTLE_ENDIAN);
5238
            if (ret != 0) {
5239
                WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
5240
                res = 0;
5241
            }
5242
5243
            if (res) {
5244
                /* Import peer's public key. */
5245
                ret = wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
5246
                    EC25519_LITTLE_ENDIAN);
5247
                if (ret != 0) {
5248
                    WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
5249
                    res = 0;
5250
                }
5251
            }
5252
            if (res) {
5253
                /* Compute shared secret. */
5254
                ret = wc_curve25519_shared_secret_ex(&privkey, &pubkey, shared,
5255
                    sharedSz, EC25519_LITTLE_ENDIAN);
5256
                if (ret != 0) {
5257
                    WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
5258
                    res = 0;
5259
                }
5260
            }
5261
5262
            wc_curve25519_free(&pubkey);
5263
        }
5264
        wc_curve25519_free(&privkey);
5265
    }
5266
5267
#ifdef WOLFSSL_CURVE25519_BLINDING
5268
    /* Disposed of after privkey, which references it for blinding. */
5269
    if (initTmpRng) {
5270
        wc_FreeRng(rng);
5271
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5272
    }
5273
#endif
5274
5275
    return res;
5276
#else
5277
    WOLFSSL_MSG("No Key Gen built in");
5278
5279
    (void)shared;
5280
    (void)sharedSz;
5281
    (void)priv;
5282
    (void)privSz;
5283
    (void)pub;
5284
    (void)pubSz;
5285
5286
    return 0;
5287
#endif /* WOLFSSL_KEY_GEN */
5288
}
5289
#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
5290
5291
/*******************************************************************************
5292
 * END OF EC25519 API
5293
 ******************************************************************************/
5294
5295
/*******************************************************************************
5296
 * START OF ED25519 API
5297
 ******************************************************************************/
5298
5299
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
5300
/* Generate an ED25519 key pair.
5301
 *
5302
 * Output keys are in little endian format.
5303
 *
5304
 * @param [out]     priv    ED25519 private key data.
5305
 * @param [in, out] privSz  On in, the size of priv in bytes.
5306
 *                          On out, the length of the private key data in bytes.
5307
 * @param [out]     pub     ED25519 public key data.
5308
 * @param [in, out] pubSz   On in, the size of pub in bytes.
5309
 *                          On out, the length of the public key data in bytes.
5310
 * @return  1 on success
5311
 * @return  0 on failure.
5312
 */
5313
int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
5314
    unsigned char *pub, unsigned int *pubSz)
5315
{
5316
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED25519_KEY_EXPORT) && \
5317
    defined(HAVE_ED25519_MAKE_KEY)
5318
    int res = 1;
5319
    int initTmpRng = 0;
5320
    WC_RNG *rng = NULL;
5321
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5322
    ed25519_key key;
5323
5324
    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
5325
5326
    /* Validate parameters. */
5327
    if ((priv == NULL) || (privSz == NULL) ||
5328
            (*privSz < ED25519_PRV_KEY_SIZE) || (pub == NULL) ||
5329
            (pubSz == NULL) || (*pubSz < ED25519_PUB_KEY_SIZE)) {
5330
        WOLFSSL_MSG("Bad arguments");
5331
        res = 0;
5332
    }
5333
5334
    if (res) {
5335
        /* Create a random number generator. */
5336
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5337
        if (rng == NULL) {
5338
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5339
            res = 0;
5340
        }
5341
    }
5342
5343
    /* Initialize an Ed25519 key. */
5344
    if (res && (wc_ed25519_init(&key) != 0)) {
5345
        WOLFSSL_MSG("wc_ed25519_init failed");
5346
        res = 0;
5347
    }
5348
    if (res) {
5349
        /* Make an Ed25519 key pair. */
5350
        int ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key);
5351
        if (ret != 0) {
5352
            WOLFSSL_MSG("wc_ed25519_make_key failed");
5353
            res = 0;
5354
        }
5355
        if (res) {
5356
            /* Export Curve25519 key pair to buffers. */
5357
            ret = wc_ed25519_export_key(&key, priv, privSz, pub, pubSz);
5358
            if (ret != 0) {
5359
                WOLFSSL_MSG("wc_ed25519_export_key failed");
5360
                res = 0;
5361
            }
5362
        }
5363
5364
        wc_ed25519_free(&key);
5365
    }
5366
5367
    if (initTmpRng) {
5368
        wc_FreeRng(rng);
5369
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5370
    }
5371
5372
    return res;
5373
#else
5374
#ifndef HAVE_ED25519_MAKE_KEY
5375
    WOLFSSL_MSG("No ED25519 make key built in");
5376
#elif !defined(WOLFSSL_KEY_GEN)
5377
    WOLFSSL_MSG("No Key Gen built in");
5378
#else
5379
    WOLFSSL_MSG("No ED25519 key export built in");
5380
#endif
5381
5382
    (void)priv;
5383
    (void)privSz;
5384
    (void)pub;
5385
    (void)pubSz;
5386
5387
    return 0;
5388
#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_MAKE_KEY */
5389
}
5390
5391
/* Sign a message with Ed25519 using the private key.
5392
 *
5393
 * Input and output keys are in little endian format.
5394
 * Priv is a buffer containing private and public part of key.
5395
 *
5396
 * @param [in]      msg     Message to be signed.
5397
 * @param [in]      msgSz   Length of message in bytes.
5398
 * @param [in]      priv    ED25519 private key data.
5399
 * @param [in]      privSz  Length in bytes of private key data.
5400
 * @param [out]     sig     Signature buffer.
5401
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
5402
 *                          On out, the length of the signature in bytes.
5403
 * @return  1 on success
5404
 * @return  0 on failure.
5405
 */
5406
int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
5407
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
5408
    unsigned int *sigSz)
5409
{
5410
#if defined(HAVE_ED25519_SIGN) && defined(WOLFSSL_KEY_GEN) && \
5411
    defined(HAVE_ED25519_KEY_IMPORT)
5412
    ed25519_key key;
5413
    int res = 1;
5414
5415
    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
5416
5417
    /* Validate parameters. */
5418
    if ((priv == NULL) || (privSz != ED25519_PRV_KEY_SIZE) ||
5419
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
5420
            (*sigSz < ED25519_SIG_SIZE)) {
5421
        WOLFSSL_MSG("Bad arguments");
5422
        res = 0;
5423
    }
5424
5425
    /* Initialize Ed25519 key. */
5426
    if (res && (wc_ed25519_init(&key) != 0)) {
5427
        WOLFSSL_MSG("wc_curve25519_init failed");
5428
        res = 0;
5429
    }
5430
    if (res) {
5431
        /* Import private and public key. */
5432
        int ret = wc_ed25519_import_private_key(priv, privSz / 2,
5433
            priv + (privSz / 2), ED25519_PUB_KEY_SIZE, &key);
5434
        if (ret != 0) {
5435
            WOLFSSL_MSG("wc_ed25519_import_private failed");
5436
            res = 0;
5437
        }
5438
5439
        if (res) {
5440
            /* Sign message with Ed25519. */
5441
            ret = wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key);
5442
            if (ret != 0) {
5443
                WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
5444
                res = 0;
5445
            }
5446
        }
5447
5448
        wc_ed25519_free(&key);
5449
    }
5450
5451
    return res;
5452
#else
5453
#if !defined(HAVE_ED25519_SIGN)
5454
    WOLFSSL_MSG("No ED25519 sign built in");
5455
#elif !defined(WOLFSSL_KEY_GEN)
5456
    WOLFSSL_MSG("No Key Gen built in");
5457
#elif !defined(HAVE_ED25519_KEY_IMPORT)
5458
    WOLFSSL_MSG("No ED25519 Key import built in");
5459
#endif
5460
5461
    (void)msg;
5462
    (void)msgSz;
5463
    (void)priv;
5464
    (void)privSz;
5465
    (void)sig;
5466
    (void)sigSz;
5467
5468
    return 0;
5469
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
5470
}
5471
5472
/* Verify a message with Ed25519 using the public key.
5473
 *
5474
 * Input keys are in little endian format.
5475
 *
5476
 * @param [in] msg     Message to be verified.
5477
 * @param [in] msgSz   Length of message in bytes.
5478
 * @param [in] pub     ED25519 public key data.
5479
 * @param [in] privSz  Length in bytes of public key data.
5480
 * @param [in] sig     Signature buffer.
5481
 * @param [in] sigSz   Length of the signature in bytes.
5482
 * @return  1 on success
5483
 * @return  0 on failure.
5484
 */
5485
int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
5486
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
5487
    unsigned int sigSz)
5488
{
5489
#if defined(HAVE_ED25519_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
5490
    defined(HAVE_ED25519_KEY_IMPORT)
5491
    ed25519_key key;
5492
    int res = 1;
5493
5494
    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
5495
5496
    /* Validate parameters. */
5497
    if ((pub == NULL) || (pubSz != ED25519_PUB_KEY_SIZE) || (msg == NULL) ||
5498
            (sig == NULL) || (sigSz != ED25519_SIG_SIZE)) {
5499
        WOLFSSL_MSG("Bad arguments");
5500
        res = 0;
5501
    }
5502
5503
    /* Initialize Ed25519 key. */
5504
    if (res && (wc_ed25519_init(&key) != 0)) {
5505
        WOLFSSL_MSG("wc_curve25519_init failed");
5506
        res = 0;
5507
    }
5508
    if (res) {
5509
        /* Import public key. */
5510
        int ret = wc_ed25519_import_public(pub, pubSz, &key);
5511
        if (ret != 0) {
5512
            WOLFSSL_MSG("wc_ed25519_import_public failed");
5513
            res = 0;
5514
        }
5515
5516
        if (res) {
5517
            int check = 0;
5518
5519
            /* Verify signature with message and public key. */
5520
            ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
5521
                &key);
5522
            /* Check for errors in verification process. */
5523
            if (ret != 0) {
5524
                WOLFSSL_MSG("wc_ed25519_verify_msg failed");
5525
                res = 0;
5526
            }
5527
            /* Check signature is valid. */
5528
            else if (!check) {
5529
                WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
5530
                res = 0;
5531
            }
5532
        }
5533
5534
        wc_ed25519_free(&key);
5535
    }
5536
5537
    return res;
5538
#else
5539
#if !defined(HAVE_ED25519_VERIFY)
5540
    WOLFSSL_MSG("No ED25519 verify built in");
5541
#elif !defined(WOLFSSL_KEY_GEN)
5542
    WOLFSSL_MSG("No Key Gen built in");
5543
#elif !defined(HAVE_ED25519_KEY_IMPORT)
5544
    WOLFSSL_MSG("No ED25519 Key import built in");
5545
#endif
5546
5547
    (void)msg;
5548
    (void)msgSz;
5549
    (void)pub;
5550
    (void)pubSz;
5551
    (void)sig;
5552
    (void)sigSz;
5553
5554
    return 0;
5555
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
5556
}
5557
5558
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
5559
5560
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
5561
    defined(OPENSSL_EXTRA_X509_SMALL)) && defined(HAVE_ED25519)
5562
/* Allocate and initialize a new ed25519_key.
5563
 *
5564
 * @param [in] heap   Heap hint for memory allocation.
5565
 * @param [in] devId  Device identifier for crypto callbacks.
5566
 * @return  Allocated and initialized ed25519_key on success.
5567
 * @return  NULL on failure.
5568
 */
5569
ed25519_key* wolfSSL_ED25519_new(void* heap, int devId)
5570
{
5571
    ed25519_key* key;
5572
5573
    WOLFSSL_ENTER("wolfSSL_ED25519_new");
5574
5575
#ifndef WC_NO_CONSTRUCTORS
5576
    key = wc_ed25519_new(heap, devId, NULL);
5577
#else
5578
    key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
5579
        DYNAMIC_TYPE_ED25519);
5580
    if (key == NULL) {
5581
        WOLFSSL_ERROR_MSG("wolfSSL_ED25519_new malloc failure");
5582
    }
5583
    else if (wc_ed25519_init_ex(key, heap, devId) != 0) {
5584
        WOLFSSL_ERROR_MSG("wolfSSL_ED25519_new init failure");
5585
        XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5586
        key = NULL;
5587
    }
5588
#endif
5589
5590
    return key;
5591
}
5592
5593
/* Free an ed25519_key allocated with wolfSSL_ED25519_new.
5594
 *
5595
 * @param [in] key  ed25519_key to free. May be NULL.
5596
 */
5597
void wolfSSL_ED25519_free(ed25519_key* key)
5598
{
5599
    if (key != NULL) {
5600
        WOLFSSL_ENTER("wolfSSL_ED25519_free");
5601
    #ifndef WC_NO_CONSTRUCTORS
5602
        wc_ed25519_delete(key, NULL);
5603
    #else
5604
        {
5605
            void* heap = key->heap;
5606
            wc_ed25519_free(key);
5607
            XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5608
        }
5609
    #endif
5610
    }
5611
}
5612
#endif /* (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || OPENSSL_EXTRA_X509_SMALL) &&
5613
        * HAVE_ED25519 */
5614
5615
/*******************************************************************************
5616
 * END OF ED25519 API
5617
 ******************************************************************************/
5618
5619
/*******************************************************************************
5620
 * START OF EC448 API
5621
 ******************************************************************************/
5622
5623
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
5624
/* Generate an EC448 key pair.
5625
 *
5626
 * Output keys are in little endian format.
5627
 *
5628
 * @param [out]     priv    EC448 private key data.
5629
 * @param [in, out] privSz  On in, the size of priv in bytes.
5630
 *                          On out, the length of the private key data in bytes.
5631
 * @param [out]     pub     EC448 public key data.
5632
 * @param [in, out] pubSz   On in, the size of pub in bytes.
5633
 *                          On out, the length of the public key data in bytes.
5634
 * @return  1 on success
5635
 * @return  0 on failure.
5636
 */
5637
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
5638
                               unsigned char *pub, unsigned int *pubSz)
5639
{
5640
#ifdef WOLFSSL_KEY_GEN
5641
    int res = 1;
5642
    int initTmpRng = 0;
5643
    WC_RNG *rng = NULL;
5644
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5645
    curve448_key key;
5646
5647
    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
5648
5649
    /* Validate parameters. */
5650
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE448_KEY_SIZE) ||
5651
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE448_KEY_SIZE)) {
5652
        WOLFSSL_MSG("Bad arguments");
5653
        res = 0;
5654
    }
5655
5656
    if (res) {
5657
        /* Create a random number generator. */
5658
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5659
        if (rng == NULL) {
5660
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5661
            res = 0;
5662
        }
5663
    }
5664
5665
    /* Initialize a Curve448 key. */
5666
    if (res && (wc_curve448_init(&key) != 0)) {
5667
        WOLFSSL_MSG("wc_curve448_init failed");
5668
        res = 0;
5669
    }
5670
    if (res) {
5671
        /* Make a Curve448 key pair. */
5672
        int ret = wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key);
5673
        if (ret != 0) {
5674
            WOLFSSL_MSG("wc_curve448_make_key failed");
5675
            res = 0;
5676
        }
5677
        if (res) {
5678
            /* Export Curve448 key pair to buffers. */
5679
            ret = wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
5680
                EC448_LITTLE_ENDIAN);
5681
            if (ret != 0) {
5682
                WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
5683
                res = 0;
5684
            }
5685
        }
5686
5687
        /* Dispose of key. */
5688
        wc_curve448_free(&key);
5689
    }
5690
5691
    if (initTmpRng) {
5692
        wc_FreeRng(rng);
5693
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5694
    }
5695
5696
    return res;
5697
#else
5698
    WOLFSSL_MSG("No Key Gen built in");
5699
5700
    (void)priv;
5701
    (void)privSz;
5702
    (void)pub;
5703
    (void)pubSz;
5704
5705
    return 0;
5706
#endif /* WOLFSSL_KEY_GEN */
5707
}
5708
5709
/* Compute a shared secret from private and public EC448 keys.
5710
 *
5711
 * Input and output keys are in little endian format
5712
 *
5713
 * @param [out]     shared    Shared secret buffer.
5714
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
5715
 *                            On out, the length of the secret in bytes.
5716
 * @param [in]      priv      EC448 private key data.
5717
 * @param [in]      privSz    Length of the private key data in bytes.
5718
 * @param [in]      pub       EC448 public key data.
5719
 * @param [in]      pubSz     Length of the public key data in bytes.
5720
 * @return  1 on success
5721
 * @return  0 on failure.
5722
 */
5723
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
5724
                             const unsigned char *priv, unsigned int privSz,
5725
                             const unsigned char *pub, unsigned int pubSz)
5726
{
5727
#ifdef WOLFSSL_KEY_GEN
5728
    int res = 1;
5729
    curve448_key privkey;
5730
    curve448_key pubkey;
5731
5732
    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
5733
5734
    /* Validate parameters. */
5735
    if ((shared == NULL) || (sharedSz == NULL) ||
5736
            (*sharedSz < CURVE448_KEY_SIZE) || (priv == NULL) ||
5737
            (privSz < CURVE448_KEY_SIZE) || (pub == NULL) ||
5738
            (pubSz < CURVE448_KEY_SIZE)) {
5739
        WOLFSSL_MSG("Bad arguments");
5740
        res = 0;
5741
    }
5742
5743
    /* Initialize private key object. */
5744
    if (res && (wc_curve448_init(&privkey) != 0)) {
5745
        WOLFSSL_MSG("wc_curve448_init privkey failed");
5746
        res = 0;
5747
    }
5748
    if (res) {
5749
        /* Initialize public key object. */
5750
        if (wc_curve448_init(&pubkey) != MP_OKAY) {
5751
            WOLFSSL_MSG("wc_curve448_init pubkey failed");
5752
            res = 0;
5753
        }
5754
        if (res) {
5755
            /* Import our private key. */
5756
            int ret = wc_curve448_import_private_ex(priv, privSz, &privkey,
5757
                EC448_LITTLE_ENDIAN);
5758
            if (ret != 0) {
5759
                WOLFSSL_MSG("wc_curve448_import_private_ex failed");
5760
                res = 0;
5761
            }
5762
5763
            if (res) {
5764
                /* Import peer's public key. */
5765
                ret = wc_curve448_import_public_ex(pub, pubSz, &pubkey,
5766
                    EC448_LITTLE_ENDIAN);
5767
                if (ret != 0) {
5768
                    WOLFSSL_MSG("wc_curve448_import_public_ex failed");
5769
                    res = 0;
5770
                }
5771
            }
5772
            if (res) {
5773
                /* Compute shared secret. */
5774
                ret = wc_curve448_shared_secret_ex(&privkey, &pubkey, shared,
5775
                    sharedSz, EC448_LITTLE_ENDIAN);
5776
                if (ret != 0) {
5777
                    WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
5778
                    res = 0;
5779
                }
5780
            }
5781
5782
            wc_curve448_free(&pubkey);
5783
        }
5784
        wc_curve448_free(&privkey);
5785
    }
5786
5787
    return res;
5788
#else
5789
    WOLFSSL_MSG("No Key Gen built in");
5790
5791
    (void)shared;
5792
    (void)sharedSz;
5793
    (void)priv;
5794
    (void)privSz;
5795
    (void)pub;
5796
    (void)pubSz;
5797
5798
    return 0;
5799
#endif /* WOLFSSL_KEY_GEN */
5800
}
5801
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
5802
5803
/*******************************************************************************
5804
 * END OF EC448 API
5805
 ******************************************************************************/
5806
5807
/*******************************************************************************
5808
 * START OF ED448 API
5809
 ******************************************************************************/
5810
5811
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
5812
/* Generate an ED448 key pair.
5813
 *
5814
 * Output keys are in little endian format.
5815
 *
5816
 * @param [out]     priv    ED448 private key data.
5817
 * @param [in, out] privSz  On in, the size of priv in bytes.
5818
 *                          On out, the length of the private key data in bytes.
5819
 * @param [out]     pub     ED448 public key data.
5820
 * @param [in, out] pubSz   On in, the size of pub in bytes.
5821
 *                          On out, the length of the public key data in bytes.
5822
 * @return  1 on success
5823
 * @return  0 on failure.
5824
 */
5825
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
5826
    unsigned char *pub, unsigned int *pubSz)
5827
{
5828
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED448_KEY_EXPORT)
5829
    int res = 1;
5830
    int initTmpRng = 0;
5831
    WC_RNG *rng = NULL;
5832
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5833
    ed448_key key;
5834
5835
    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
5836
5837
    /* Validate parameters. */
5838
    if ((priv == NULL) || (privSz == NULL) ||
5839
            (*privSz < ED448_PRV_KEY_SIZE) || (pub == NULL) ||
5840
            (pubSz == NULL) || (*pubSz < ED448_PUB_KEY_SIZE)) {
5841
        WOLFSSL_MSG("Bad arguments");
5842
        res = 0;
5843
    }
5844
5845
    if (res) {
5846
        /* Create a random number generator. */
5847
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5848
        if (rng == NULL) {
5849
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5850
            res = 0;
5851
        }
5852
    }
5853
5854
    /* Initialize an Ed448 key. */
5855
    if (res && (wc_ed448_init(&key) != 0)) {
5856
        WOLFSSL_MSG("wc_ed448_init failed");
5857
        res = 0;
5858
    }
5859
    if (res) {
5860
        /* Make an Ed448 key pair. */
5861
        int ret = wc_ed448_make_key(rng, ED448_KEY_SIZE, &key);
5862
        if (ret != 0) {
5863
            WOLFSSL_MSG("wc_ed448_make_key failed");
5864
            res = 0;
5865
        }
5866
        if (res) {
5867
            /* Export Curve448 key pair to buffers. */
5868
            ret = wc_ed448_export_key(&key, priv, privSz, pub, pubSz);
5869
            if (ret != 0) {
5870
                WOLFSSL_MSG("wc_ed448_export_key failed");
5871
                res = 0;
5872
            }
5873
        }
5874
5875
        wc_ed448_free(&key);
5876
    }
5877
5878
    if (initTmpRng) {
5879
        wc_FreeRng(rng);
5880
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5881
    }
5882
5883
    return res;
5884
#else
5885
#ifndef WOLFSSL_KEY_GEN
5886
    WOLFSSL_MSG("No Key Gen built in");
5887
#else
5888
    WOLFSSL_MSG("No ED448 key export built in");
5889
#endif
5890
5891
    (void)priv;
5892
    (void)privSz;
5893
    (void)pub;
5894
    (void)pubSz;
5895
5896
    return 0;
5897
#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
5898
}
5899
5900
/* Sign a message with Ed448 using the private key.
5901
 *
5902
 * Input and output keys are in little endian format.
5903
 * Priv is a buffer containing private and public part of key.
5904
 *
5905
 * @param [in]      msg     Message to be signed.
5906
 * @param [in]      msgSz   Length of message in bytes.
5907
 * @param [in]      priv    ED448 private key data.
5908
 * @param [in]      privSz  Length in bytes of private key data.
5909
 * @param [out]     sig     Signature buffer.
5910
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
5911
 *                          On out, the length of the signature in bytes.
5912
 * @return  1 on success
5913
 * @return  0 on failure.
5914
 */
5915
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
5916
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
5917
    unsigned int *sigSz)
5918
{
5919
#if defined(HAVE_ED448_SIGN) && defined(WOLFSSL_KEY_GEN) && \
5920
    defined(HAVE_ED448_KEY_IMPORT)
5921
    ed448_key key;
5922
    int res = 1;
5923
5924
    WOLFSSL_ENTER("wolfSSL_ED448_sign");
5925
5926
    /* Validate parameters. */
5927
    if ((priv == NULL) || (privSz != ED448_PRV_KEY_SIZE) ||
5928
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
5929
            (*sigSz < ED448_SIG_SIZE)) {
5930
        WOLFSSL_MSG("Bad arguments");
5931
        res = 0;
5932
    }
5933
5934
    /* Initialize Ed448 key. */
5935
    if (res && (wc_ed448_init(&key) != 0)) {
5936
        WOLFSSL_MSG("wc_curve448_init failed");
5937
        res = 0;
5938
    }
5939
    if (res) {
5940
        /* Import private and public key. */
5941
        int ret = wc_ed448_import_private_key(priv, privSz / 2,
5942
            priv + (privSz / 2), ED448_PUB_KEY_SIZE, &key);
5943
        if (ret != 0) {
5944
            WOLFSSL_MSG("wc_ed448_import_private failed");
5945
            res = 0;
5946
        }
5947
5948
        if (res) {
5949
            /* Sign message with Ed448 - no context. */
5950
            ret = wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0);
5951
            if (ret != 0) {
5952
                WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
5953
                res = 0;
5954
            }
5955
        }
5956
5957
        wc_ed448_free(&key);
5958
    }
5959
5960
    return res;
5961
#else
5962
#if !defined(HAVE_ED448_SIGN)
5963
    WOLFSSL_MSG("No ED448 sign built in");
5964
#elif !defined(WOLFSSL_KEY_GEN)
5965
    WOLFSSL_MSG("No Key Gen built in");
5966
#elif !defined(HAVE_ED448_KEY_IMPORT)
5967
    WOLFSSL_MSG("No ED448 Key import built in");
5968
#endif
5969
5970
    (void)msg;
5971
    (void)msgSz;
5972
    (void)priv;
5973
    (void)privSz;
5974
    (void)sig;
5975
    (void)sigSz;
5976
5977
    return 0;
5978
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
5979
}
5980
5981
/* Verify a message with Ed448 using the public key.
5982
 *
5983
 * Input keys are in little endian format.
5984
 *
5985
 * @param [in] msg     Message to be verified.
5986
 * @param [in] msgSz   Length of message in bytes.
5987
 * @param [in] pub     ED448 public key data.
5988
 * @param [in] privSz  Length in bytes of public key data.
5989
 * @param [in] sig     Signature buffer.
5990
 * @param [in] sigSz   Length of the signature in bytes.
5991
 * @return  1 on success
5992
 * @return  0 on failure.
5993
 */
5994
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
5995
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
5996
    unsigned int sigSz)
5997
{
5998
#if defined(HAVE_ED448_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
5999
    defined(HAVE_ED448_KEY_IMPORT)
6000
    ed448_key key;
6001
    int res = 1;
6002
6003
    WOLFSSL_ENTER("wolfSSL_ED448_verify");
6004
6005
    /* Validate parameters. */
6006
    if ((pub == NULL) || (pubSz != ED448_PUB_KEY_SIZE) || (msg == NULL) ||
6007
            (sig == NULL) || (sigSz != ED448_SIG_SIZE)) {
6008
        WOLFSSL_MSG("Bad arguments");
6009
        res = 0;
6010
    }
6011
6012
    /* Initialize Ed448 key. */
6013
    if (res && (wc_ed448_init(&key) != 0)) {
6014
        WOLFSSL_MSG("wc_curve448_init failed");
6015
        res = 0;
6016
    }
6017
    if (res) {
6018
        /* Import public key. */
6019
        int ret = wc_ed448_import_public(pub, pubSz, &key);
6020
        if (ret != 0) {
6021
            WOLFSSL_MSG("wc_ed448_import_public failed");
6022
            res = 0;
6023
        }
6024
6025
        if (res) {
6026
            int check = 0;
6027
6028
            /* Verify signature with message and public key - no context. */
6029
            ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
6030
                &key, NULL, 0);
6031
            /* Check for errors in verification process. */
6032
            if (ret != 0) {
6033
                WOLFSSL_MSG("wc_ed448_verify_msg failed");
6034
                res = 0;
6035
            }
6036
            /* Check signature is valid. */
6037
            else if (!check) {
6038
                WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
6039
                res = 0;
6040
            }
6041
        }
6042
6043
        wc_ed448_free(&key);
6044
    }
6045
6046
    return res;
6047
#else
6048
#if !defined(HAVE_ED448_VERIFY)
6049
    WOLFSSL_MSG("No ED448 verify built in");
6050
#elif !defined(WOLFSSL_KEY_GEN)
6051
    WOLFSSL_MSG("No Key Gen built in");
6052
#elif !defined(HAVE_ED448_KEY_IMPORT)
6053
    WOLFSSL_MSG("No ED448 Key import built in");
6054
#endif
6055
6056
    (void)msg;
6057
    (void)msgSz;
6058
    (void)pub;
6059
    (void)pubSz;
6060
    (void)sig;
6061
    (void)sigSz;
6062
6063
    return 0;
6064
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
6065
}
6066
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
6067
6068
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
6069
    defined(HAVE_ED448)
6070
/* Allocate and initialize a new ed448_key.
6071
 *
6072
 * @param [in] heap   Heap hint for memory allocation.
6073
 * @param [in] devId  Device identifier for crypto callbacks.
6074
 * @return  Allocated and initialized ed448_key on success.
6075
 * @return  NULL on failure.
6076
 */
6077
ed448_key* wolfSSL_ED448_new(void* heap, int devId)
6078
{
6079
    ed448_key* key;
6080
6081
    WOLFSSL_ENTER("wolfSSL_ED448_new");
6082
6083
#if !defined(WC_NO_CONSTRUCTORS) && \
6084
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7, 0))
6085
    key = wc_ed448_new(heap, devId, NULL);
6086
#else
6087
    key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
6088
    if (key == NULL) {
6089
        WOLFSSL_ERROR_MSG("wolfSSL_ED448_new malloc failure");
6090
    }
6091
    else if (wc_ed448_init_ex(key, heap, devId) != 0) {
6092
        WOLFSSL_ERROR_MSG("wolfSSL_ED448_new init failure");
6093
        XFREE(key, heap, DYNAMIC_TYPE_ED448);
6094
        key = NULL;
6095
    }
6096
#endif
6097
6098
    return key;
6099
}
6100
6101
/* Free an ed448_key allocated with wolfSSL_ED448_new.
6102
 *
6103
 * @param [in] key  ed448_key to free. May be NULL.
6104
 */
6105
void wolfSSL_ED448_free(ed448_key* key)
6106
{
6107
    if (key != NULL) {
6108
        WOLFSSL_ENTER("wolfSSL_ED448_free");
6109
    #if !defined(WC_NO_CONSTRUCTORS) && \
6110
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7, 0))
6111
        wc_ed448_delete(key, NULL);
6112
    #else
6113
        {
6114
            void* heap = key->heap;
6115
            wc_ed448_free(key);
6116
            XFREE(key, heap, DYNAMIC_TYPE_ED448);
6117
        }
6118
    #endif
6119
    }
6120
}
6121
#endif /* (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) && HAVE_ED448 */
6122
6123
/*******************************************************************************
6124
 * END OF ED448 API
6125
 ******************************************************************************/
6126
6127
/*******************************************************************************
6128
 * START OF GENERIC PUBLIC KEY PEM APIs
6129
 ******************************************************************************/
6130
6131
#ifdef OPENSSL_EXTRA
6132
/* Sets default callback password for PEM.
6133
 *
6134
 * @param [out] buf       Buffer to hold password.
6135
 * @param [in]  num       Number of characters in buffer.
6136
 * @param [in]  rwFlag    Read/write flag. Ignored.
6137
 * @param [in]  userData  User data - assumed to be default password.
6138
 * @return  Password size on success.
6139
 * @return  0 on failure.
6140
 */
6141
int wolfSSL_PEM_def_callback(char* buf, int num, int rwFlag, void* userData)
6142
{
6143
    int sz = 0;
6144
6145
    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
6146
6147
    (void)rwFlag;
6148
6149
    /* We assume that the user passes a default password as userdata */
6150
    if ((buf != NULL) && (userData != NULL)) {
6151
        sz = (int)XSTRLEN((const char*)userData);
6152
        sz = (int)min((word32)sz, (word32)num);
6153
        XMEMCPY(buf, userData, (size_t)sz);
6154
    }
6155
    else {
6156
        WOLFSSL_MSG("Error, default password cannot be created.");
6157
    }
6158
6159
    return sz;
6160
}
6161
6162
#ifndef NO_BIO
6163
/* Writes a public key to a WOLFSSL_BIO encoded in PEM format.
6164
 *
6165
 * @param [in] bio  BIO to write to.
6166
 * @param [in] key  Public key to write in PEM format.
6167
 * @return  1 on success.
6168
 * @return  0 on failure.
6169
 */
6170
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
6171
{
6172
    int ret = 0;
6173
#if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
6174
    !defined(WOLFSSL_MLDSA_NO_ASN1) && defined(WC_ENABLE_ASYM_KEY_EXPORT) && \
6175
    !defined(NO_ASN)
6176
    unsigned char* derBuf = NULL;
6177
    int derSz = 0;
6178
#endif
6179
6180
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
6181
6182
    if ((bio != NULL) && (key != NULL)) {
6183
        switch (key->type) {
6184
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
6185
            case WC_EVP_PKEY_RSA:
6186
                ret = wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key->rsa);
6187
                break;
6188
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
6189
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
6190
    defined(WOLFSSL_KEY_GEN)
6191
            case WC_EVP_PKEY_DSA:
6192
                ret = wolfSSL_PEM_write_bio_DSA_PUBKEY(bio, key->dsa);
6193
                break;
6194
#endif /* !NO_DSA && !HAVE_SELFTEST && defined(WOLFSSL_KEY_GEN) */
6195
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
6196
    defined(WOLFSSL_KEY_GEN)
6197
            case WC_EVP_PKEY_EC:
6198
                ret = wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key->ecc);
6199
                break;
6200
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
6201
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
6202
            case WC_EVP_PKEY_DH:
6203
                /* DH public key not supported. */
6204
                WOLFSSL_MSG("Writing DH PUBKEY not supported!");
6205
                break;
6206
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
6207
#if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PUBLIC_KEY) && \
6208
    !defined(WOLFSSL_MLDSA_NO_ASN1) && defined(WC_ENABLE_ASYM_KEY_EXPORT) && \
6209
    !defined(NO_ASN)
6210
            case WC_EVP_PKEY_DILITHIUM:
6211
                /* Encode as SPKI and write as PUBLIC KEY PEM. */
6212
                derSz = wolfSSL_i2d_PUBKEY(key, &derBuf);
6213
                if (derSz > 0) {
6214
                    ret = der_write_to_bio_as_pem(derBuf, derSz, bio,
6215
                        PUBLICKEY_TYPE);
6216
                }
6217
                XFREE(derBuf, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
6218
                break;
6219
#endif /* WOLFSSL_HAVE_MLDSA && WOLFSSL_MLDSA_PUBLIC_KEY &&
6220
        * !WOLFSSL_MLDSA_NO_ASN1 && WC_ENABLE_ASYM_KEY_EXPORT && !NO_ASN */
6221
            default:
6222
                /* Key type not supported. */
6223
                WOLFSSL_MSG("Unknown Key type!");
6224
                break;
6225
        }
6226
    }
6227
6228
    return ret;
6229
}
6230
6231
/* Writes a private key to a WOLFSSL_BIO encoded in PEM format.
6232
 *
6233
 * @param [in] bio     BIO to write to.
6234
 * @param [in] key     Public key to write in PEM format.
6235
 * @param [in] cipher  Encryption cipher to use.
6236
 * @param [in] passwd  Password to use when encrypting.
6237
 * @param [in] len     Length of password.
6238
 * @param [in] cb      Password callback.
6239
 * @param [in] arg     Password callback argument.
6240
 * @return  1 on success.
6241
 * @return  0 on failure.
6242
 */
6243
int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
6244
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
6245
    wc_pem_password_cb* cb, void* arg)
6246
{
6247
    int ret = 1;
6248
6249
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
6250
6251
    (void)cipher;
6252
    (void)passwd;
6253
    (void)len;
6254
    (void)cb;
6255
    (void)arg;
6256
6257
    /* Validate parameters. */
6258
    if ((bio == NULL) || (key == NULL)) {
6259
        WOLFSSL_MSG("Bad Function Arguments");
6260
        ret = 0;
6261
    }
6262
6263
    if (ret == 1) {
6264
    #ifdef WOLFSSL_KEY_GEN
6265
        switch (key->type) {
6266
        #ifndef NO_RSA
6267
            case WC_EVP_PKEY_RSA:
6268
                /* Write using RSA specific API. */
6269
                ret = wolfSSL_PEM_write_bio_RSAPrivateKey(bio, key->rsa,
6270
                    cipher, passwd, len, cb, arg);
6271
                break;
6272
        #endif
6273
        #ifndef NO_DSA
6274
            case WC_EVP_PKEY_DSA:
6275
                /* Write using DSA specific API. */
6276
                ret = wolfSSL_PEM_write_bio_DSAPrivateKey(bio, key->dsa,
6277
                    cipher, passwd, len, cb, arg);
6278
                break;
6279
        #endif
6280
        #ifdef HAVE_ECC
6281
            case WC_EVP_PKEY_EC:
6282
            #if defined(HAVE_ECC_KEY_EXPORT)
6283
                /* Write using EC specific API. */
6284
                ret = wolfSSL_PEM_write_bio_ECPrivateKey(bio, key->ecc,
6285
                    cipher, passwd, len, cb, arg);
6286
            #else
6287
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
6288
                    key->pkey_sz, bio, EC_PRIVATEKEY_TYPE);
6289
            #endif
6290
                break;
6291
        #endif
6292
        #ifndef NO_DH
6293
            case WC_EVP_PKEY_DH:
6294
                /* Write using generic API with DH type. */
6295
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
6296
                    key->pkey_sz, bio, DH_PRIVATEKEY_TYPE);
6297
                break;
6298
        #endif
6299
            default:
6300
                WOLFSSL_MSG("Unknown Key type!");
6301
                ret = 0;
6302
                break;
6303
        }
6304
    #else
6305
        int type = 0;
6306
6307
        switch (key->type) {
6308
        #ifndef NO_DSA
6309
            case WC_EVP_PKEY_DSA:
6310
                type = DSA_PRIVATEKEY_TYPE;
6311
                break;
6312
        #endif
6313
        #ifdef HAVE_ECC
6314
            case WC_EVP_PKEY_EC:
6315
                type = ECC_PRIVATEKEY_TYPE;
6316
                break;
6317
        #endif
6318
        #ifndef NO_DH
6319
            case WC_EVP_PKEY_DH:
6320
                type = DH_PRIVATEKEY_TYPE;
6321
                break;
6322
        #endif
6323
        #ifndef NO_RSA
6324
            case WC_EVP_PKEY_RSA:
6325
                type = PRIVATEKEY_TYPE;
6326
                break;
6327
        #endif
6328
            default:
6329
                ret = 0;
6330
                break;
6331
        }
6332
        if (ret == 1) {
6333
            /* Write using generic API with generic type. */
6334
            ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr, key->pkey_sz,
6335
                bio, type);
6336
        }
6337
    #endif
6338
    }
6339
6340
    return ret;
6341
}
6342
#endif /* !NO_BIO */
6343
6344
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \
6345
    !defined(NO_ASN)
6346
/* Writes a public key to a file pointer encoded in PEM format.
6347
 *
6348
 * @param [in] fp   File pointer to write to.
6349
 * @param [in] key  Public key to write in PEM format.
6350
 * @return  1 on success.
6351
 * @return  0 on failure.
6352
 */
6353
int wolfSSL_PEM_write_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY* key)
6354
{
6355
    int err = 0;
6356
    unsigned char* derBuf = NULL;
6357
    int derSz = 0;
6358
6359
    WOLFSSL_ENTER("wolfSSL_PEM_write_PUBKEY");
6360
6361
    if ((fp == XBADFILE) || (key == NULL)) {
6362
        WOLFSSL_MSG("Bad Function Arguments");
6363
        err = 1;
6364
    }
6365
6366
    if (!err) {
6367
        derSz = wolfSSL_i2d_PUBKEY(key, NULL);
6368
        if (derSz <= 0) {
6369
            WOLFSSL_MSG("Failed to get DER size for key");
6370
            err = 1;
6371
        }
6372
    }
6373
6374
    if (!err) {
6375
        unsigned char* tmp;
6376
        derBuf = (unsigned char*)XMALLOC((size_t)derSz, NULL,
6377
            DYNAMIC_TYPE_TMP_BUFFER);
6378
        if (derBuf == NULL) {
6379
            WOLFSSL_MSG("Failed to allocate DER buffer");
6380
            err = 1;
6381
        }
6382
        else {
6383
            tmp = derBuf;
6384
            if (wolfSSL_i2d_PUBKEY(key, &tmp) <= 0) {
6385
                WOLFSSL_MSG("Failed to convert key to DER");
6386
                err = 1;
6387
            }
6388
        }
6389
    }
6390
6391
    /* Write DER buffer to file as PEM. */
6392
    if ((!err) && (der_write_to_file_as_pem(derBuf, derSz, fp,
6393
            PUBLICKEY_TYPE, NULL) != 1)) {
6394
        WOLFSSL_MSG("Failed to write DER to file as PEM");
6395
        err = 1;
6396
    }
6397
6398
    /* Dispose of the DER encoding. */
6399
    XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6400
6401
    WOLFSSL_LEAVE("wolfSSL_PEM_write_PUBKEY", err);
6402
    return !err;
6403
}
6404
6405
/* Writes a private key to a file pointer encoded in PEM format.
6406
 *
6407
 * @param [in] fp      File pointer to write to.
6408
 * @param [in] key     Private key to write in PEM format.
6409
 * @param [in] cipher  Encryption cipher to use. May be NULL.
6410
 * @param [in] passwd  Password to use when encrypting. May be NULL.
6411
 * @param [in] len     Length of password.
6412
 * @param [in] cb      Password callback.
6413
 * @param [in] arg     Password callback argument.
6414
 * @return  1 on success.
6415
 * @return  0 on failure.
6416
 */
6417
int wolfSSL_PEM_write_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY* key,
6418
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
6419
    wc_pem_password_cb* cb, void* arg)
6420
{
6421
    int err = 0;
6422
    int type = 0;
6423
    unsigned char* derBuf = NULL;
6424
    int derSz = 0;
6425
6426
    (void)cipher;
6427
    (void)passwd;
6428
    (void)len;
6429
    (void)cb;
6430
    (void)arg;
6431
6432
    WOLFSSL_ENTER("wolfSSL_PEM_write_PrivateKey");
6433
6434
    /* Validate parameters. */
6435
    if ((fp == XBADFILE) || (key == NULL)) {
6436
        WOLFSSL_MSG("Bad Function Arguments");
6437
        err = 1;
6438
    }
6439
6440
    /* Determine PEM type from key type, mirroring wolfSSL_PEM_read_PrivateKey's
6441
     * keyFormat switch. */
6442
    if (!err) {
6443
        switch (key->type) {
6444
            case WC_EVP_PKEY_RSA:
6445
                type = PRIVATEKEY_TYPE;
6446
                break;
6447
            case WC_EVP_PKEY_DSA:
6448
                type = DSA_PRIVATEKEY_TYPE;
6449
                break;
6450
            case WC_EVP_PKEY_EC:
6451
                type = ECC_PRIVATEKEY_TYPE;
6452
                break;
6453
            case WC_EVP_PKEY_DH:
6454
                type = DH_PRIVATEKEY_TYPE;
6455
                break;
6456
            default:
6457
                WOLFSSL_MSG("Unknown key type");
6458
                err = 1;
6459
                break;
6460
        }
6461
    }
6462
6463
    if (!err) {
6464
        derSz = wolfSSL_i2d_PrivateKey(key, NULL);
6465
        if (derSz <= 0) {
6466
            WOLFSSL_MSG("Failed to get DER size for private key");
6467
            err = 1;
6468
        }
6469
    }
6470
6471
    if (!err) {
6472
        unsigned char* tmp;
6473
        derBuf = (unsigned char*)XMALLOC((size_t)derSz, NULL,
6474
            DYNAMIC_TYPE_TMP_BUFFER);
6475
        if (derBuf == NULL) {
6476
            WOLFSSL_MSG("Failed to allocate DER buffer");
6477
            err = 1;
6478
        }
6479
        else {
6480
            tmp = derBuf;
6481
            if (wolfSSL_i2d_PrivateKey(key, &tmp) <= 0) {
6482
                WOLFSSL_MSG("Error encoding private key as DER");
6483
                err = 1;
6484
            }
6485
        }
6486
    }
6487
6488
    /* Write DER buffer to file as PEM. */
6489
    if ((!err) && (der_write_to_file_as_pem(derBuf, derSz, fp, type,
6490
            NULL) != 1)) {
6491
        WOLFSSL_MSG("Error writing DER to file as PEM");
6492
        err = 1;
6493
    }
6494
6495
    /* Dispose of the DER encoding. */
6496
    XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6497
6498
    WOLFSSL_LEAVE("wolfSSL_PEM_write_PrivateKey", err);
6499
    return !err;
6500
}
6501
#endif /* !NO_FILESYSTEM && !NO_CERTS && OPENSSL_EXTRA && !NO_ASN */
6502
6503
#ifndef NO_BIO
6504
/* Create a private key object from the data in the BIO.
6505
 *
6506
 * @param [in]      bio   BIO to read from.
6507
 * @param [in, out] key   Public key object. Object used if passed in.
6508
 * @param [in]      cb    Password callback.
6509
 * @param [in]      arg   Password callback argument.
6510
 * @return  A WOLFSSL_EVP_PKEY object on success.
6511
 * @return  NULL on failure.
6512
 */
6513
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
6514
    WOLFSSL_EVP_PKEY **key, wc_pem_password_cb *cb, void *arg)
6515
{
6516
    int err = 0;
6517
    WOLFSSL_EVP_PKEY* pkey = NULL;
6518
    DerBuffer* der = NULL;
6519
6520
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
6521
6522
    if (bio == NULL) {
6523
        err = 1;
6524
    }
6525
6526
    /* Read the PEM public key from the BIO and convert to DER. */
6527
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PUBLICKEY_TYPE, NULL,
6528
            &der) < 0)) {
6529
        err = 1;
6530
    }
6531
6532
    if (!err) {
6533
        const unsigned char* ptr = der->buffer;
6534
6535
        /* Use key passed in if set. */
6536
        if ((key != NULL) && (*key != NULL)) {
6537
            pkey = *key;
6538
        }
6539
6540
        /* Convert DER data to a public key object. */
6541
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
6542
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6543
            pkey = NULL;
6544
            err = 1;
6545
        }
6546
    }
6547
6548
    /* Return the key if possible. */
6549
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6550
        *key = pkey;
6551
    }
6552
    /* Dispose of the DER encoding. */
6553
    FreeDer(&der);
6554
6555
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
6556
6557
    return pkey;
6558
}
6559
6560
/* Create a private key object from the data in the BIO.
6561
 *
6562
 * @param [in]      bio   BIO to read from.
6563
 * @param [in, out] key   Private key object. Object used if passed in.
6564
 * @param [in]      cb    Password callback.
6565
 * @param [in]      arg   Password callback argument.
6566
 * @return  A WOLFSSL_EVP_PKEY object on success.
6567
 * @return  NULL on failure.
6568
 */
6569
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
6570
    WOLFSSL_EVP_PKEY** key, wc_pem_password_cb* cb, void* arg)
6571
{
6572
    int err = 0;
6573
    WOLFSSL_EVP_PKEY* pkey = NULL;
6574
    DerBuffer* der = NULL;
6575
    int keyFormat = 0;
6576
6577
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
6578
6579
    /* Validate parameters. */
6580
    if (bio == NULL) {
6581
        err = 1;
6582
    }
6583
6584
    /* Read the PEM private key from the BIO and convert to DER. */
6585
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
6586
            &der) < 0)) {
6587
        err = 1;
6588
    }
6589
6590
    if (!err) {
6591
        const unsigned char* ptr = der->buffer;
6592
        int type;
6593
6594
        /* Set key type based on format returned. */
6595
        switch (keyFormat) {
6596
            /* No key format set - default to RSA. */
6597
            case 0:
6598
            case RSAk:
6599
                type = WC_EVP_PKEY_RSA;
6600
                break;
6601
            case DSAk:
6602
                type = WC_EVP_PKEY_DSA;
6603
                break;
6604
            case ECDSAk:
6605
                type = WC_EVP_PKEY_EC;
6606
                break;
6607
            case DHk:
6608
                type = WC_EVP_PKEY_DH;
6609
                break;
6610
        #ifdef HAVE_ED25519
6611
            case ED25519k:
6612
                type = WC_EVP_PKEY_ED25519;
6613
                break;
6614
        #endif
6615
        #ifdef HAVE_ED448
6616
            case ED448k:
6617
                type = WC_EVP_PKEY_ED448;
6618
                break;
6619
        #endif
6620
        #ifdef WOLFSSL_HAVE_MLDSA
6621
            case ML_DSA_44k:
6622
            case ML_DSA_65k:
6623
            case ML_DSA_87k:
6624
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
6625
            case DILITHIUM_LEVEL2k:
6626
            case DILITHIUM_LEVEL3k:
6627
            case DILITHIUM_LEVEL5k:
6628
            #endif
6629
                type = WC_EVP_PKEY_DILITHIUM;
6630
                break;
6631
        #endif
6632
            default:
6633
                type = WOLFSSL_FATAL_ERROR;
6634
                break;
6635
        }
6636
6637
        /* Use key passed in if set. */
6638
        if ((key != NULL) && (*key != NULL)) {
6639
            pkey = *key;
6640
        }
6641
6642
        /* Convert DER data to a private key object. */
6643
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
6644
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6645
            pkey = NULL;
6646
            err = 1;
6647
        }
6648
    }
6649
6650
    /* Return the key if possible. */
6651
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6652
        *key = pkey;
6653
    }
6654
    /* Dispose of the DER encoding. */
6655
    FreeDer(&der);
6656
6657
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", err);
6658
6659
    return pkey;
6660
}
6661
6662
6663
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(
6664
    WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb,
6665
    void* arg)
6666
{
6667
    return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
6668
}
6669
#endif /* !NO_BIO */
6670
6671
#if !defined(NO_FILESYSTEM)
6672
/* Create a private key object from the data in a file.
6673
 *
6674
 * @param [in]      fp    File pointer.
6675
 * @param [in, out] key   Public key object. Object used if passed in.
6676
 * @param [in]      cb    Password callback.
6677
 * @param [in]      arg   Password callback argument.
6678
 * @return  A WOLFSSL_EVP_PKEY object on success.
6679
 * @return  NULL on failure.
6680
 */
6681
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **key,
6682
    wc_pem_password_cb *cb, void *arg)
6683
{
6684
    int err = 0;
6685
    WOLFSSL_EVP_PKEY* pkey = NULL;
6686
    DerBuffer* der = NULL;
6687
6688
    WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
6689
6690
    /* Validate parameters. */
6691
    if (fp == XBADFILE) {
6692
        err = 1;
6693
    }
6694
6695
    /* Read the PEM public key from the file and convert to DER. */
6696
    if ((!err) && ((pem_read_file_key(fp, cb, arg, PUBLICKEY_TYPE, NULL,
6697
            &der) < 0) || (der == NULL))) {
6698
        err = 1;
6699
    }
6700
    if (!err) {
6701
        const unsigned char* ptr = der->buffer;
6702
6703
        /* Use key passed in if set. */
6704
        if ((key != NULL) && (*key != NULL)) {
6705
            pkey = *key;
6706
        }
6707
6708
        /* Convert DER data to a public key object. */
6709
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
6710
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6711
            pkey = NULL;
6712
            err = 1;
6713
        }
6714
    }
6715
6716
    /* Return the key if possible. */
6717
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6718
        *key = pkey;
6719
    }
6720
    /* Dispose of the DER encoding. */
6721
    FreeDer(&der);
6722
6723
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
6724
6725
    return pkey;
6726
}
6727
6728
#ifndef NO_CERTS
6729
/* Create a private key object from the data in a file.
6730
 *
6731
 * @param [in]      fp    File pointer.
6732
 * @param [in, out] key   Private key object. Object used if passed in.
6733
 * @param [in]      cb    Password callback.
6734
 * @param [in]      arg   Password callback argument.
6735
 * @return  A WOLFSSL_EVP_PKEY object on success.
6736
 * @return  NULL on failure.
6737
 */
6738
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
6739
    wc_pem_password_cb *cb, void *arg)
6740
{
6741
    int err = 0;
6742
    WOLFSSL_EVP_PKEY* pkey = NULL;
6743
    DerBuffer* der = NULL;
6744
    int keyFormat = 0;
6745
6746
    WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
6747
6748
    /* Validate parameters. */
6749
    if (fp == XBADFILE) {
6750
        err = 1;
6751
    }
6752
6753
    /* Read the PEM private key from the file and convert to DER. */
6754
    if ((!err) && (pem_read_file_key(fp, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
6755
            &der)) < 0) {
6756
        err = 1;
6757
    }
6758
6759
    if (!err) {
6760
        const unsigned char* ptr = der->buffer;
6761
        int type;
6762
6763
        /* Set key type based on format returned. */
6764
        switch (keyFormat) {
6765
            /* No key format set - default to RSA. */
6766
            case 0:
6767
            case RSAk:
6768
                type = WC_EVP_PKEY_RSA;
6769
                break;
6770
            case DSAk:
6771
                type = WC_EVP_PKEY_DSA;
6772
                break;
6773
            case ECDSAk:
6774
                type = WC_EVP_PKEY_EC;
6775
                break;
6776
            case DHk:
6777
                type = WC_EVP_PKEY_DH;
6778
                break;
6779
        #ifdef HAVE_ED25519
6780
            case ED25519k:
6781
                type = WC_EVP_PKEY_ED25519;
6782
                break;
6783
        #endif
6784
        #ifdef HAVE_ED448
6785
            case ED448k:
6786
                type = WC_EVP_PKEY_ED448;
6787
                break;
6788
        #endif
6789
        #ifdef WOLFSSL_HAVE_MLDSA
6790
            case ML_DSA_44k:
6791
            case ML_DSA_65k:
6792
            case ML_DSA_87k:
6793
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
6794
            case DILITHIUM_LEVEL2k:
6795
            case DILITHIUM_LEVEL3k:
6796
            case DILITHIUM_LEVEL5k:
6797
            #endif
6798
                type = WC_EVP_PKEY_DILITHIUM;
6799
                break;
6800
        #endif
6801
            default:
6802
                type = WOLFSSL_FATAL_ERROR;
6803
                break;
6804
        }
6805
6806
        /* Use key passed in if set. */
6807
        if ((key != NULL) && (*key != NULL)) {
6808
            pkey = *key;
6809
        }
6810
6811
        /* Convert DER data to a private key object. */
6812
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
6813
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6814
            pkey = NULL;
6815
            err = 1;
6816
        }
6817
    }
6818
6819
    /* Return the key if possible. */
6820
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6821
        *key = pkey;
6822
    }
6823
    /* Dispose of the DER encoding. */
6824
    FreeDer(&der);
6825
6826
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PrivateKey", 0);
6827
6828
    return pkey;
6829
}
6830
#endif /* !NO_CERTS */
6831
#endif /* !NO_FILESYSTEM */
6832
6833
#ifndef NO_CERTS
6834
6835
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
6836
#define PEM_BEGIN              "-----BEGIN "
6837
#define PEM_BEGIN_SZ           11
6838
#define PEM_END                "-----END "
6839
#define PEM_END_SZ             9
6840
#define PEM_HDR_FIN            "-----"
6841
#define PEM_HDR_FIN_SZ         5
6842
#define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
6843
#define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
6844
#define PEM_HDR_FIN_EOL_SZ     6
6845
6846
/* Find strings and return middle offsets.
6847
 *
6848
 * Find first string in pem as a prefix and then locate second string as a
6849
 * postfix.
6850
 * len returning with 0 indicates not found.
6851
 *
6852
 * @param [in]  pem      PEM data.
6853
 * @param [in]  pemLen   Length of PEM data.
6854
 * @param [in]  idx      Current index.
6855
 * @param [in]  prefix   First string to find.
6856
 * @param [in]  postfix  Second string to find after first.
6857
 * @param [out] start    Start index of data between strings.
6858
 * @param [out] len      Length of data between strings.
6859
 */
6860
static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,
6861
    const char* postfix, int* start, int* len)
6862
{
6863
    int prefixLen = (int)XSTRLEN(prefix);
6864
    int postfixLen = (int)XSTRLEN(postfix);
6865
6866
    *start = *len = 0;
6867
    /* Find prefix part. */
6868
    for (; idx <= pemLen - prefixLen; idx++) {
6869
        if ((pem[idx] == prefix[0]) &&
6870
                (XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) {
6871
            idx += prefixLen;
6872
            *start = idx;
6873
            break;
6874
        }
6875
    }
6876
    /* Find postfix part. */
6877
    for (; idx <= pemLen - postfixLen; idx++) {
6878
        if ((pem[idx] == postfix[0]) &&
6879
                (XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) {
6880
            *len = idx - *start;
6881
            break;
6882
        }
6883
    }
6884
}
6885
6886
/* Parse out content type name, any encryption headers and DER encoding.
6887
 *
6888
 * @param [in]  pem     PEM data.
6889
 * @param [in]  pemLen  Length of PEM data.
6890
 * @param [out] name    Name of content type.
6891
 * @param [out] header  Encryption headers.
6892
 * @param [out] data    DER encoding from PEM.
6893
 * @param [out] len     Length of DER data.
6894
 * @return  0 on success.
6895
 * @return  MEMORY_E when dynamic memory allocation fails.
6896
 * @return  ASN_NO_PEM_HEADER when no header found or different names found.
6897
 */
6898
static int pem_read_data(char* pem, int pemLen, char **name, char **header,
6899
    unsigned char **data, long *len)
6900
{
6901
    int ret = 0;
6902
    int start;
6903
    int nameLen;
6904
    int startHdr = 0;
6905
    int hdrLen = 0;
6906
    int startEnd = 0;
6907
    int endLen;
6908
6909
    *name = NULL;
6910
    *header = NULL;
6911
6912
    /* Find header. */
6913
    pem_find_pattern(pem, pemLen, 0, PEM_BEGIN, PEM_HDR_FIN, &start, &nameLen);
6914
    /* Allocate memory for header name. */
6915
    *name = (char*)XMALLOC((size_t)nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6916
    if (*name == NULL) {
6917
        ret = MEMORY_E;
6918
    }
6919
    if (ret == 0) {
6920
        /* Put in header name. */
6921
        (*name)[nameLen] = '\0';
6922
        if (nameLen == 0) {
6923
            ret = ASN_NO_PEM_HEADER;
6924
        }
6925
        else {
6926
            XMEMCPY(*name, pem + start, (size_t)nameLen);
6927
        }
6928
    }
6929
    if (ret == 0) {
6930
        /* Find footer. */
6931
        start += nameLen + PEM_HDR_FIN_SZ;
6932
        pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
6933
            &endLen);
6934
        /* Validate header name and footer name are the same. */
6935
        if ((endLen != nameLen) ||
6936
                 (XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
6937
            ret = ASN_NO_PEM_HEADER;
6938
        }
6939
    }
6940
    if (ret == 0) {
6941
        /* Find encryption headers - bounded by the footer so that a blank line
6942
         * after it isn't matched. */
6943
        pem_find_pattern(pem, startEnd - PEM_END_SZ, start, "\n", "\n\n",
6944
            &startHdr, &hdrLen);
6945
        if (hdrLen > 0) {
6946
            /* Include first of two '\n' characters. */
6947
            hdrLen++;
6948
        }
6949
        /* Allocate memory for encryption header string. */
6950
        *header = (char*)XMALLOC((size_t)hdrLen + 1, NULL,
6951
                                    DYNAMIC_TYPE_TMP_BUFFER);
6952
        if (*header == NULL) {
6953
            ret = MEMORY_E;
6954
        }
6955
    }
6956
    if (ret == 0) {
6957
        /* Put in encryption header string. */
6958
        (*header)[hdrLen] = '\0';
6959
        if (hdrLen > 0) {
6960
            XMEMCPY(*header, pem + startHdr, (size_t)hdrLen);
6961
            start = startHdr + hdrLen + 1;
6962
        }
6963
    }
6964
    if (ret == 0) {
6965
        unsigned char* der = (unsigned char*)pem;
6966
        word32 derLen;
6967
6968
        /* Convert PEM body to DER. */
6969
        derLen = (word32)(startEnd - PEM_END_SZ - start);
6970
        ret = Base64_Decode(der + start, derLen, der, &derLen);
6971
        if (ret == 0) {
6972
            /* Return the DER data. */
6973
            *data = der;
6974
            *len = derLen;
6975
        }
6976
    }
6977
6978
    return ret;
6979
}
6980
6981
/* Encode the DER data in PEM format into a newly allocated buffer.
6982
 *
6983
 * @param [in]  name       Header/footer name.
6984
 * @param [in]  header     Encryption header.
6985
 * @param [in]  data       DER data.
6986
 * @param [in]  len        Length of DER data.
6987
 * @param [out] pemOut     PEM encoded data.
6988
 * @param [out] pemOutLen  Length of PEM encoded data.
6989
 * @return  0 on success.
6990
 * @return  MEMORY_E when dynamic memory allocation fails.
6991
 */
6992
static int pem_write_data(const char *name, const char *header,
6993
    const unsigned char *data, long len, char** pemOut, word32* pemOutLen)
6994
{
6995
    int ret = 0;
6996
    int nameLen;
6997
    int headerLen;
6998
    char* pem = NULL;
6999
    word32 pemLen;
7000
    word32 derLen;
7001
    byte* p;
7002
7003
    /* Reject lengths that would wrap the PEM size calculation below. */
7004
    if ((len < 0) || ((word32)len >= (WOLFSSL_MAX_32BIT / 4))) {
7005
        return BAD_FUNC_ARG;
7006
    }
7007
    derLen = (word32)len;
7008
7009
    nameLen = (int)XSTRLEN(name);
7010
    headerLen = (int)XSTRLEN(header);
7011
7012
    /* DER encode for PEM. */
7013
    pemLen  = (derLen + 2) / 3 * 4;
7014
    pemLen += (pemLen + 63) / 64;
7015
    /* Header */
7016
    pemLen += (word32)(PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
7017
    if (headerLen > 0) {
7018
        /* Encryption lines plus extra carriage return. */
7019
        pemLen += (word32)headerLen + 1;
7020
    }
7021
    /* Trailer */
7022
    pemLen += (word32)(PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
7023
7024
    pem = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7025
    if (pem == NULL) {
7026
        ret = MEMORY_E;
7027
    }
7028
    p = (byte*)pem;
7029
7030
    if (ret == 0) {
7031
        /* Add header. */
7032
        XMEMCPY(p, PEM_BEGIN, PEM_BEGIN_SZ);
7033
        p += PEM_BEGIN_SZ;
7034
        XMEMCPY(p, name, (size_t)nameLen);
7035
        p += nameLen;
7036
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
7037
        p += PEM_HDR_FIN_EOL_SZ;
7038
7039
        if (headerLen > 0) {
7040
            /* Add encryption header. */
7041
            XMEMCPY(p, header, (size_t)headerLen);
7042
            p += headerLen;
7043
            /* Blank line after a header and before body. */
7044
            *(p++) = '\n';
7045
        }
7046
7047
        /* Add DER data as PEM. */
7048
        pemLen -= (word32)((size_t)p - (size_t)pem);
7049
        ret = Base64_Encode(data, derLen, p, &pemLen);
7050
    }
7051
    if (ret == 0) {
7052
        p += pemLen;
7053
7054
        /* Add trailer. */
7055
        XMEMCPY(p, PEM_END, PEM_END_SZ);
7056
        p += PEM_END_SZ;
7057
        XMEMCPY(p, name, (size_t)nameLen);
7058
        p += nameLen;
7059
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
7060
        p += PEM_HDR_FIN_EOL_SZ;
7061
7062
        /* Return buffer and length of data. */
7063
        *pemOut = pem;
7064
        *pemOutLen = (word32)((size_t)p - (size_t)pem);
7065
    }
7066
    else {
7067
        /* Dispose of any allocated memory. */
7068
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7069
        pem = NULL;
7070
    }
7071
7072
    return ret;
7073
}
7074
#endif /* !NO_BIO || !NO_FILESYSTEM */
7075
7076
#ifndef NO_BIO
7077
/* Read PEM encoded data from a BIO.
7078
 *
7079
 * Reads the entire contents in.
7080
 *
7081
 * @param [in]  bio     BIO to read from.
7082
 * @param [out] name    Name of content type.
7083
 * @param [out] header  Encryption headers.
7084
 * @param [out] data    DER encoding from PEM.
7085
 * @param [out] len     Length of DER data.
7086
 * @return  1 on success.
7087
 * @return  0 on failure.
7088
 */
7089
int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
7090
    unsigned char **data, long *len)
7091
{
7092
    int res = 1;
7093
    char* pem = NULL;
7094
    int pemLen = 0;
7095
    int memAlloced = 1;
7096
7097
    /* Validate parameters. */
7098
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL) ||
7099
            (len == NULL)) {
7100
        res = 0;
7101
    }
7102
7103
    /* Load all the data from the BIO. */
7104
    if ((res == 1) && (wolfssl_read_bio(bio, &pem, &pemLen, &memAlloced) !=
7105
             0)) {
7106
        res = 0;
7107
    }
7108
    if ((res == 1) && (!memAlloced)) {
7109
        /* Need to return allocated memory - make sure it is allocated. */
7110
        char* p = (char*)XMALLOC((size_t)pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7111
        if (p == NULL) {
7112
            res = 0;
7113
        }
7114
        else {
7115
            /* Copy the data into new buffer. */
7116
            XMEMCPY(p, pem, (size_t)pemLen);
7117
            pem = p;
7118
        }
7119
    }
7120
7121
    /* Read the PEM data. */
7122
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
7123
            0)) {
7124
        /* Dispose of any allocated memory. */
7125
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7126
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7127
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7128
        *name = NULL;
7129
        *header = NULL;
7130
        res = 0;
7131
    }
7132
7133
    return res;
7134
}
7135
7136
/* Encode the DER data in PEM format into a BIO.
7137
 *
7138
 * @param [in] bio     BIO to write to.
7139
 * @param [in] name    Header/footer name.
7140
 * @param [in] header  Encryption header.
7141
 * @param [in] data    DER data.
7142
 * @param [in] len     Length of DER data.
7143
 * @return  0 on failure.
7144
 */
7145
int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
7146
    const char *header, const unsigned char *data, long len)
7147
{
7148
    int err = 0;
7149
    char* pem = NULL;
7150
    word32 pemLen = 0;
7151
7152
    /* Validate parameters. */
7153
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL)) {
7154
        err = BAD_FUNC_ARG;
7155
    }
7156
7157
    /* Encode into a buffer. */
7158
    if (!err) {
7159
        err = pem_write_data(name, header, data, len, &pem, &pemLen);
7160
    }
7161
7162
    /* Write PEM into BIO. */
7163
    if ((!err) && (wolfSSL_BIO_write(bio, pem, (int)pemLen) != (int)pemLen)) {
7164
        err = IO_FAILED_E;
7165
    }
7166
7167
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7168
    return (!err) ? (int)pemLen : 0;
7169
}
7170
#endif /* !NO_BIO */
7171
7172
#if !defined(NO_FILESYSTEM)
7173
/* Read PEM encoded data from a file.
7174
 *
7175
 * Reads the entire contents in.
7176
 *
7177
 * @param [in]  bio     BIO to read from.
7178
 * @param [out] name    Name of content type.
7179
 * @param [out] header  Encryption headers.
7180
 * @param [out] data    DER encoding from PEM.
7181
 * @param [out] len     Length of DER data.
7182
 * @return  1 on success.
7183
 * @return  0 on failure.
7184
 */
7185
int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data,
7186
    long *len)
7187
{
7188
    int res = 1;
7189
    char* pem = NULL;
7190
    int pemLen = 0;
7191
7192
    /* Validate parameters. */
7193
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
7194
            (data == NULL) || (len == NULL)) {
7195
        res = 0;
7196
    }
7197
7198
    /* Load all the data from the file. */
7199
    if ((res == 1) && (wolfssl_read_file(fp, &pem, &pemLen) != 0)) {
7200
        res = 0;
7201
    }
7202
7203
    /* Read the PEM data. */
7204
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
7205
            0)) {
7206
        /* Dispose of any allocated memory. */
7207
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7208
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7209
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7210
        *name = NULL;
7211
        *header = NULL;
7212
        res = 0;
7213
    }
7214
7215
    return res;
7216
}
7217
7218
/* Encode the DER data in PEM format into a file.
7219
 *
7220
 * @param [in] fp      File pointer to write to.
7221
 * @param [in] name    Header/footer name.
7222
 * @param [in] header  Encryption header.
7223
 * @param [in] data    DER data.
7224
 * @param [in] len     Length of DER data.
7225
 * @return  0 on success.
7226
 * @return  MEMORY_E when dynamic memory allocation fails.
7227
 */
7228
int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
7229
    const unsigned char *data, long len)
7230
{
7231
    int err = 0;
7232
    char* pem = NULL;
7233
    word32 pemLen = 0;
7234
7235
    /* Validate parameters. */
7236
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
7237
            (data == NULL)) {
7238
        err = 1;
7239
    }
7240
7241
    /* Encode into a buffer. */
7242
    if ((!err) && (pem_write_data(name, header, data, len, &pem, &pemLen) !=
7243
            0)) {
7244
        pemLen = 0;
7245
        err = 1;
7246
    }
7247
7248
    /* Write PEM to a file. */
7249
    if ((!err) && (XFWRITE(pem, 1, pemLen, fp) != pemLen)) {
7250
        pemLen = 0;
7251
    }
7252
7253
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7254
    return (int)pemLen;
7255
}
7256
#endif
7257
7258
/* Get EVP cipher info from encryption header string.
7259
 *
7260
 * @param [in]  header  Encryption header.
7261
 * @param [out] cipher  EVP Cipher info.
7262
 * @return  1 on success.
7263
 * @return  0 on failure.
7264
 */
7265
int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, EncryptedInfo* cipher)
7266
{
7267
    int res = 1;
7268
7269
    /* Validate parameters. */
7270
    if ((header == NULL) || (cipher == NULL)) {
7271
        res = 0;
7272
    }
7273
7274
    if (res == 1) {
7275
        XMEMSET(cipher, 0, sizeof(*cipher));
7276
7277
        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0) {
7278
            res = 0;
7279
        }
7280
    }
7281
7282
    return res;
7283
}
7284
7285
/* Apply cipher to DER data.
7286
 *
7287
 * @param [in]      cipher  EVP cipher info.
7288
 * @param [in, out] data    On in, encrypted DER data.
7289
 *                          On out, unencrypted DER data.
7290
 * @param [in, out] len     On in, length of encrypted DER data.
7291
 *                          On out, length of unencrypted DER data.
7292
 * @param [in]      cb      Password callback.
7293
 * @param [in]      ctx     Context for password callback.
7294
 * @return  1 on success.
7295
 * @return  0 on failure.
7296
 */
7297
int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
7298
    wc_pem_password_cb* cb, void* ctx)
7299
{
7300
    int ret = 1;
7301
    char password[NAME_SZ];
7302
    int passwordSz = 0;
7303
7304
#ifdef WOLFSSL_CHECK_MEM_ZERO
7305
    /* Baseline-zero and register the whole buffer up front so the cb() fill and
7306
     * every path to the ForceZero are covered. The written length is not known
7307
     * here, so the full buffer is registered; the XMEMSET keeps the unwritten
7308
     * tail defined-zero so the full-window check never false-fails. */
7309
    XMEMSET(password, 0, sizeof(password));
7310
    wc_MemZero_Add("wolfSSL_PEM_do_header password", password,
7311
        sizeof(password));
7312
#endif
7313
7314
    /* Validate parameters. */
7315
    if ((cipher == NULL) || (data == NULL) || (len == NULL) || (cb == NULL)) {
7316
        ret = 0;
7317
    }
7318
7319
    if (ret == 1) {
7320
        /* Get password and length. */
7321
        passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
7322
        if (passwordSz < 0) {
7323
            ret = 0;
7324
        }
7325
    }
7326
7327
    if (ret == 1) {
7328
        /* Decrypt the data using password and MD5. */
7329
        if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
7330
                passwordSz, WC_MD5) != 0) {
7331
            ret = WOLFSSL_FAILURE;
7332
        }
7333
    }
7334
7335
    if (passwordSz > 0) {
7336
        /* Ensure password is erased from memory. */
7337
        ForceZero(password, (word32)passwordSz);
7338
    }
7339
7340
#ifdef WOLFSSL_CHECK_MEM_ZERO
7341
    /* Whole buffer is zero here on every path (baseline + ForceZero), so the
7342
     * check always passes and the up-front registration is always retired. */
7343
    wc_MemZero_Check(password, sizeof(password));
7344
#endif
7345
    return ret;
7346
}
7347
7348
#endif /* !NO_CERTS */
7349
#endif /* OPENSSL_EXTRA */
7350
7351
#ifdef OPENSSL_ALL
7352
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
7353
7354
/* Encrypt the key into a buffer using PKCS#8 and a password.
7355
 *
7356
 * @param [in]      pkey      Private key to encrypt.
7357
 * @param [in]      enc       EVP cipher.
7358
 * @param [in]      passwd    Password to encrypt with.
7359
 * @param [in]      passwdSz  Number of bytes in password.
7360
 * @param [in]      key       Buffer to hold encrypted key.
7361
 * @param [in, out] keySz     On in, size of buffer in bytes.
7362
 *                            On out, size of encrypted key in bytes.
7363
 * @return  0 on success.
7364
 * @return  BAD_FUNC_ARG when EVP cipher not supported.
7365
 */
7366
int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
7367
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
7368
    word32* keySz)
7369
{
7370
    int ret;
7371
    WC_RNG rng;
7372
7373
    /* Initialize a new random number generator. */
7374
    ret = wc_InitRng(&rng);
7375
    if (ret == 0) {
7376
        int encAlgId = 0;
7377
7378
        /* Convert EVP cipher to a support encryption id. */
7379
    #ifndef NO_DES3
7380
        if (enc == EVP_DES_CBC) {
7381
            encAlgId = DESb;
7382
        }
7383
        else if (enc == EVP_DES_EDE3_CBC) {
7384
            encAlgId = DES3b;
7385
        }
7386
        else
7387
    #endif
7388
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
7389
    #ifdef WOLFSSL_AES_128
7390
        if (enc == EVP_AES_128_CBC) {
7391
            encAlgId = AES128CBCb;
7392
        }
7393
        else
7394
     #endif
7395
    #ifdef WOLFSSL_AES_256
7396
        if (enc == EVP_AES_256_CBC) {
7397
            encAlgId = AES256CBCb;
7398
        }
7399
        else
7400
     #endif
7401
#endif
7402
        {
7403
            ret = BAD_FUNC_ARG;
7404
        }
7405
7406
        if (ret == 0) {
7407
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
7408
            if (pkey->type == WC_EVP_PKEY_ED25519) {
7409
                /* The cached pkey.ptr is a full PKCS#8 blob and TraditionalEnc
7410
                 * requires a *traditional* (unwrapped) key.  Build the PKCS#8
7411
                 * from the key object via pkcs8_encode() and encrypt it with
7412
                 * wc_EncryptPKCS8Key(), which expects PKCS#8 input. */
7413
                byte*  edDer = NULL;
7414
                word32 edDerSz = 0;
7415
7416
                if (pkcs8_encode(pkey, NULL, &edDerSz) !=
7417
                        WC_NO_ERR_TRACE(LENGTH_ONLY_E) || edDerSz == 0) {
7418
                    ret = BAD_FUNC_ARG;
7419
                }
7420
                else {
7421
                    edDer = (byte*)XMALLOC(edDerSz, pkey->heap,
7422
                        DYNAMIC_TYPE_TMP_BUFFER);
7423
                    if (edDer == NULL)
7424
                        ret = MEMORY_E;
7425
                    else
7426
                        ret = pkcs8_encode(pkey, edDer, &edDerSz);
7427
                }
7428
                if (ret > 0) {
7429
                    edDerSz = (word32)ret;
7430
                    ret = wc_EncryptPKCS8Key(edDer, edDerSz, key, keySz,
7431
                        passwd, passwdSz, PKCS5, PBES2, encAlgId,
7432
                        NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL);
7433
                    if (ret > 0) {
7434
                        *keySz = (word32)ret;
7435
                    }
7436
                }
7437
                if (edDer != NULL) {
7438
                    ForceZero(edDer, edDerSz);
7439
                    XFREE(edDer, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
7440
                }
7441
            }
7442
            else
7443
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_EXPORT */
7444
#ifdef WOLFSSL_HAVE_MLDSA
7445
            if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
7446
                word32 idx = 0;
7447
                word32 keyOid = 0;
7448
7449
                /* TraditionalEnc() would wrap the key again, so encrypt
7450
                 * the stored encoding directly. */
7451
                if ((pkey->pkey.ptr == NULL) || (pkey->pkey_sz <= 0)) {
7452
                    ret = BAD_FUNC_ARG;
7453
                }
7454
                else if (ToTraditionalInline_ex((const byte*)pkey->pkey.ptr,
7455
                        &idx, (word32)pkey->pkey_sz, &keyOid) < 0) {
7456
                    ret = ASN_PARSE_E;
7457
                }
7458
                else {
7459
                    ret = wc_EncryptPKCS8Key((byte*)pkey->pkey.ptr,
7460
                        (word32)pkey->pkey_sz, key, keySz, passwd, passwdSz,
7461
                        PKCS5, PBES2, encAlgId, NULL, 0, WC_PKCS12_ITT_DEFAULT,
7462
                        &rng, NULL);
7463
                    if (ret > 0) {
7464
                        *keySz = (word32)ret;
7465
                    }
7466
                }
7467
            }
7468
            else
7469
#endif /* WOLFSSL_HAVE_MLDSA */
7470
            {
7471
                /* Encrypt private into buffer. */
7472
                ret = TraditionalEnc(
7473
                    (byte*)pkey->pkey.ptr + pkey->pkcs8HeaderSz,
7474
                    (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
7475
                    key, keySz, passwd, passwdSz, PKCS5, PBES2, encAlgId,
7476
                    NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL);
7477
                if (ret > 0) {
7478
                    *keySz = (word32)ret;
7479
                }
7480
            }
7481
        }
7482
        /* Dispose of random number generator. */
7483
        wc_FreeRng(&rng);
7484
    }
7485
7486
    return ret;
7487
}
7488
#endif /* !NO_PWDBASED && HAVE_PKCS8 */
7489
7490
#ifdef HAVE_PKCS8
7491
/* Encode private key in PKCS#8 format.
7492
 *
7493
 * @param [in]      pkey   Private key.
7494
 * @param [out]     key    Buffer to hold encoding.
7495
 * @param [in, out] keySz  On in, size of buffer in bytes.
7496
 * @param                  On out, size of encoded key in bytes.
7497
 * @return  0 on success.
7498
 */
7499
int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
7500
{
7501
    int ret = 0;
7502
    int algId = 0;
7503
    const byte* curveOid = 0;
7504
    word32 oidSz = 0;
7505
7506
    /* Get the details of the private key. */
7507
#ifdef HAVE_ECC
7508
    if (pkey->type == WC_EVP_PKEY_EC) {
7509
        /* ECC private and get curve OID information. */
7510
        algId = ECDSAk;
7511
        ret = wc_ecc_get_oid((word32)pkey->ecc->group->curve_oid, &curveOid,
7512
            &oidSz);
7513
    }
7514
    else
7515
#endif
7516
    if (pkey->type == WC_EVP_PKEY_RSA) {
7517
        /* RSA private has no curve information. */
7518
        algId = RSAk;
7519
        curveOid = NULL;
7520
        oidSz = 0;
7521
    }
7522
    else if (pkey->type == WC_EVP_PKEY_DSA) {
7523
        /* DSA has no curve information. */
7524
        algId = DSAk;
7525
        curveOid = NULL;
7526
        oidSz = 0;
7527
    }
7528
#ifndef NO_DH
7529
    else if (pkey->type == WC_EVP_PKEY_DH) {
7530
        if (pkey->dh == NULL)
7531
            return BAD_FUNC_ARG;
7532
7533
        if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
7534
            /* Special case. DH buffer is always in PKCS8 format */
7535
            if (keySz == NULL)
7536
                return BAD_FUNC_ARG;
7537
7538
            if (key == NULL) {
7539
                *keySz = (word32)pkey->pkey_sz;
7540
                return LENGTH_ONLY_E;
7541
            }
7542
            if (*keySz < (word32)pkey->pkey_sz)
7543
                return BUFFER_E;
7544
7545
            XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
7546
            *keySz = (word32)pkey->pkey_sz;
7547
            return pkey->pkey_sz;
7548
        }
7549
7550
        /* DH has no curve information. */
7551
        algId = DHk;
7552
        curveOid = NULL;
7553
        oidSz = 0;
7554
    }
7555
#endif
7556
#if defined(HAVE_ED25519)
7557
    else if (pkey->type == WC_EVP_PKEY_ED25519) {
7558
    #if defined(HAVE_ED25519_KEY_EXPORT)
7559
        /* Build the PKCS#8 PrivateKeyInfo from the key object. A public-only
7560
         * key (e.g. from wolfSSL_X509_get_pubkey()) has no private half to
7561
         * encode (privKeySet == 0) and is rejected. */
7562
        if (keySz == NULL || pkey->ed25519 == NULL ||
7563
                !pkey->ed25519->privKeySet)
7564
            return BAD_FUNC_ARG;
7565
7566
        ret = wc_Ed25519PrivateKeyToDer(pkey->ed25519, NULL, 0);
7567
        if (ret <= 0)
7568
            return (ret < 0) ? ret : BAD_FUNC_ARG;
7569
7570
        if (key == NULL) {          /* length query */
7571
            *keySz = (word32)ret;
7572
            return LENGTH_ONLY_E;
7573
        }
7574
        if (*keySz < (word32)ret)   /* honour the caller's buffer size */
7575
            return BUFFER_E;
7576
7577
        ret = wc_Ed25519PrivateKeyToDer(pkey->ed25519, key, *keySz);
7578
        if (ret > 0)
7579
            *keySz = (word32)ret;   /* only set on success */
7580
        return ret;
7581
    #else
7582
        return NOT_COMPILED_IN;
7583
    #endif /* HAVE_ED25519_KEY_EXPORT */
7584
    }
7585
#endif /* HAVE_ED25519 */
7586
#ifdef WOLFSSL_HAVE_MLDSA
7587
    else if (pkey->type == WC_EVP_PKEY_DILITHIUM) {
7588
        word32 idx = 0;
7589
        word32 keyOid = 0;
7590
7591
        /* ML-DSA buffer is expected to be in PKCS8 format */
7592
        if ((keySz == NULL) || (pkey->pkey.ptr == NULL) ||
7593
                (pkey->pkey_sz <= 0)) {
7594
            return BAD_FUNC_ARG;
7595
        }
7596
        if (ToTraditionalInline_ex((const byte*)pkey->pkey.ptr, &idx,
7597
                (word32)pkey->pkey_sz, &keyOid) < 0) {
7598
            return ASN_PARSE_E;
7599
        }
7600
7601
        if (key == NULL) {
7602
            *keySz = (word32)pkey->pkey_sz;
7603
            return LENGTH_ONLY_E;
7604
        }
7605
        if (*keySz < (word32)pkey->pkey_sz)
7606
            return BUFFER_E;
7607
7608
        XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
7609
        *keySz = (word32)pkey->pkey_sz;
7610
        return pkey->pkey_sz;
7611
    }
7612
#endif /* WOLFSSL_HAVE_MLDSA */
7613
    else {
7614
        ret = NOT_COMPILED_IN;
7615
    }
7616
7617
    if (ret >= 0) {
7618
        /* Encode private key in PKCS#8 format. */
7619
        ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr +
7620
            pkey->pkcs8HeaderSz, (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
7621
            algId, curveOid, oidSz);
7622
    }
7623
7624
    return ret;
7625
}
7626
#endif /* HAVE_PKCS8 */
7627
7628
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
7629
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
7630
    !defined(NO_STDIO_FILESYSTEM))
7631
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7632
 *
7633
 * @param [out] pem       Buffer holding PEM encoding.
7634
 * @param [out] pemSz     Size of data in buffer in bytes.
7635
 * @param [in]  pkey      Private key to write.
7636
 * @param [in]  enc       Encryption information to use. May be NULL.
7637
 * @param [in]  passwd    Password to use when encrypting. May be NULL.
7638
 * @param [in]  passwdSz  Size of password in bytes.
7639
 * @param [in]  cb        Password callback. Used when passwd is NULL. May be
7640
 *                        NULL.
7641
 * @param [in]  ctx       Context for password callback.
7642
 * @return  Length of PEM encoding on success.
7643
 * @return  0 on failure.
7644
 */
7645
static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
7646
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
7647
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
7648
{
7649
    int res = 1;
7650
    int ret = 0;
7651
    char password[NAME_SZ];
7652
    byte* key = NULL;
7653
    word32 keySz = 0;
7654
    word32 allocSz = 0;
7655
    int type = PKCS8_PRIVATEKEY_TYPE;
7656
7657
    /* Validate parameters. */
7658
    if (pkey == NULL) {
7659
        res = 0;
7660
    }
7661
7662
    if (res == 1) {
7663
        /* Guestimate key size and PEM size. */
7664
        if (pkcs8_encode(pkey, NULL, &keySz) !=
7665
                WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
7666
            res = 0;
7667
        }
7668
    }
7669
    if (res == 1) {
7670
        if (enc != NULL) {
7671
            /* Add on enough for extra DER data when encrypting. */
7672
            keySz += 128;
7673
        }
7674
        /* PEM encoding size from DER size. */
7675
        *pemSz  = (int)(keySz + 2) / 3 * 4;
7676
        *pemSz += (*pemSz + 63) / 64;
7677
        /* Header and footer. */
7678
        if (enc != NULL) {
7679
            /* Name is: 'ENCRYPTED PRIVATE KEY'. */
7680
            *pemSz += 74;
7681
        }
7682
        else {
7683
            /* Name is: 'PRIVATE KEY'. */
7684
            *pemSz += 54;
7685
        }
7686
7687
        allocSz = (word32)*pemSz;
7688
        /* Allocate enough memory to hold PEM encoded encrypted key. */
7689
        *pem = (byte*)XMALLOC((size_t)allocSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7690
        if (*pem == NULL) {
7691
            allocSz = 0;
7692
            res = 0;
7693
        }
7694
        else {
7695
            /* Use end of PEM buffer for key data. */
7696
            key = *pem + *pemSz - keySz;
7697
        }
7698
    }
7699
7700
    if ((res == 1) && (enc != NULL)) {
7701
        /* Set type for PEM. */
7702
        type = PKCS8_ENC_PRIVATEKEY_TYPE;
7703
7704
        if (passwd == NULL) {
7705
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7706
            /* Baseline-zero and register the whole buffer before the cb() fill
7707
             * so the fill and every path to the ForceZero are covered. The
7708
             * written length is not known here, so the full buffer is
7709
             * registered and the XMEMSET keeps the unwritten tail zero. */
7710
            XMEMSET(password, 0, sizeof(password));
7711
            wc_MemZero_Add("pem_write_mem_pkcs8privatekey password", password,
7712
                sizeof(password));
7713
        #endif
7714
            /* Get the password by using callback. */
7715
            passwdSz = cb(password, sizeof(password), 1, ctx);
7716
            if (passwdSz < 0) {
7717
                res = 0;
7718
            }
7719
            passwd = password;
7720
        }
7721
7722
        if (res == 1) {
7723
            /* Encrypt the private key. */
7724
            ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
7725
            if (ret <= 0) {
7726
                res = 0;
7727
            }
7728
        }
7729
7730
        /* Zeroize the password from memory. */
7731
        if ((password == passwd) && (passwdSz > 0)) {
7732
            ForceZero(password, (word32)passwdSz);
7733
        }
7734
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7735
        /* Retire the up-front registration on every path that made it: the
7736
         * local buffer was used iff passwd now aliases it. Buffer is zero here
7737
         * (baseline + ForceZero), so the full-window check always passes. */
7738
        if (password == passwd) {
7739
            wc_MemZero_Check(password, sizeof(password));
7740
        }
7741
    #endif
7742
    }
7743
    else if ((res == 1) && (enc == NULL)) {
7744
        /* Set type for PEM. */
7745
        type = PKCS8_PRIVATEKEY_TYPE;
7746
7747
        /* Encode private key in PKCS#8 format. */
7748
        ret = pkcs8_encode(pkey, key, &keySz);
7749
        if (ret < 0) {
7750
            res = 0;
7751
        }
7752
    }
7753
7754
    if (res == 1) {
7755
        /* Encode PKCS#8 formatted key to PEM. */
7756
        ret = wc_DerToPemEx(key, keySz, *pem, (word32)*pemSz, NULL, type);
7757
        if (ret < 0) {
7758
            res = 0;
7759
        }
7760
        else {
7761
            *pemSz = ret;
7762
        }
7763
    }
7764
7765
    /* Zero any remnants of the DER staging area that persist after PEM
7766
     * conversion so plaintext private key material is not left in freed heap
7767
     * memory. On success, only the bytes past the actual PEM output need
7768
     * clearing; on failure, the whole buffer is zeroed since its state is
7769
     * indeterminate. */
7770
    if (*pem != NULL) {
7771
        if (res == 1 && (word32)*pemSz < allocSz) {
7772
            ForceZero(*pem + *pemSz, allocSz - (word32)*pemSz);
7773
        }
7774
        else if (res != 1) {
7775
            ForceZero(*pem, allocSz);
7776
        }
7777
    }
7778
7779
    /* Return appropriate return code. */
7780
    return (res == 0) ? 0 : ret;
7781
7782
}
7783
#endif /* !NO_BIO || (!NO_FILESYSTEM && !NO_STDIO_FILESYSTEM) */
7784
7785
#ifndef NO_BIO
7786
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7787
 *
7788
 * TODO: OpenSSL returns 1 and 0 only.
7789
 *
7790
 * @param [in] bio       BIO to write to.
7791
 * @param [in] pkey      Private key to write.
7792
 * @param [in] enc       Encryption information to use. May be NULL.
7793
 * @param [in] passwd    Password to use when encrypting. May be NULL.
7794
 * @param [in] passwdSz  Size of password in bytes.
7795
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
7796
 *                       NULL.
7797
 * @param [in] ctx       Context for password callback.
7798
 * @return  Length of PEM encoding on success.
7799
 * @return  0 on failure.
7800
 */
7801
int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
7802
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
7803
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
7804
{
7805
    byte* pem = NULL;
7806
    int pemSz = 0;
7807
    int res = 1;
7808
7809
    /* Validate parameters. */
7810
    if (bio == NULL) {
7811
        res = 0;
7812
    }
7813
    if (res == 1) {
7814
        /* Write private key to memory. */
7815
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
7816
            passwdSz, cb, ctx);
7817
    }
7818
7819
    /* Write encoded key to BIO. */
7820
    if ((res >= 1) && (wolfSSL_BIO_write(bio, pem, pemSz) != pemSz)) {
7821
        res = 0;
7822
    }
7823
7824
    /* Dispose of dynamically allocated memory (pem and key). */
7825
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7826
    return res;
7827
}
7828
7829
int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
7830
        PKCS8_PRIV_KEY_INFO* keyInfo)
7831
{
7832
    return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
7833
            NULL, NULL);
7834
}
7835
#endif /* !NO_BIO */
7836
7837
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
7838
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7839
 *
7840
 * TODO: OpenSSL returns 1 and 0 only.
7841
 *
7842
 * @param [in] f         File pointer.
7843
 * @param [in] pkey      Private key to write.
7844
 * @param [in] enc       Encryption information to use. May be NULL.
7845
 * @param [in] passwd    Password to use when encrypting. May be NULL.
7846
 * @param [in] passwdSz  Size of password in bytes.
7847
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
7848
 *                       NULL.
7849
 * @param [in] ctx       Context for password callback.
7850
 * @return  Length of PEM encoding on success.
7851
 * @return  0 on failure.
7852
 */
7853
int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
7854
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
7855
    wc_pem_password_cb* cb, void* ctx)
7856
{
7857
    byte* pem = NULL;
7858
    int pemSz = 0;
7859
    int res = 1;
7860
7861
    /* Validate parameters. */
7862
    if (f == XBADFILE) {
7863
        res = 0;
7864
    }
7865
    if (res == 1) {
7866
        /* Write private key to memory. */
7867
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
7868
            passwdSz, cb, ctx);
7869
    }
7870
7871
    /* Write encoded key to file. */
7872
    if ((res >= 1) && (XFWRITE(pem, 1, (size_t)pemSz, f) != (size_t)pemSz)) {
7873
        res = 0;
7874
    }
7875
7876
    /* Dispose of dynamically allocated memory (pem and key). */
7877
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7878
    return res;
7879
}
7880
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
7881
7882
#endif /* !NO_PWDBASED && HAVE_PKCS8 */
7883
#endif /* OPENSSL_ALL */
7884
7885
/*******************************************************************************
7886
 * END OF GENERIC PUBLIC KEY PEM APIs
7887
 ******************************************************************************/
7888
7889
#endif /* !WOLFSSL_PK_INCLUDED */