Coverage Report

Created: 2026-02-14 07:18

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