Coverage Report

Created: 2026-09-20 06:33

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