Coverage Report

Created: 2026-11-12 06:38

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