Coverage Report

Created: 2026-08-15 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/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
227
{
922
227
    int ret = 0;
923
227
    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
227
    if (GetSequence_ex(seq, &i, &ret, (word32)len, 0) >= 0) {
929
        /* Add SEQUENCE header length to underlying data length. */
930
227
        ret += (int)i;
931
227
    }
932
933
227
    return ret;
934
227
}
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
    int res = 1;
5314
    int initTmpRng = 0;
5315
    WC_RNG *rng = NULL;
5316
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5317
    ed25519_key key;
5318
5319
    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
5320
5321
    /* Validate parameters. */
5322
    if ((priv == NULL) || (privSz == NULL) ||
5323
            (*privSz < ED25519_PRV_KEY_SIZE) || (pub == NULL) ||
5324
            (pubSz == NULL) || (*pubSz < ED25519_PUB_KEY_SIZE)) {
5325
        WOLFSSL_MSG("Bad arguments");
5326
        res = 0;
5327
    }
5328
5329
    if (res) {
5330
        /* Create a random number generator. */
5331
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5332
        if (rng == NULL) {
5333
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5334
            res = 0;
5335
        }
5336
    }
5337
5338
    /* Initialize an Ed25519 key. */
5339
    if (res && (wc_ed25519_init(&key) != 0)) {
5340
        WOLFSSL_MSG("wc_ed25519_init failed");
5341
        res = 0;
5342
    }
5343
    if (res) {
5344
        /* Make an Ed25519 key pair. */
5345
        int ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key);
5346
        if (ret != 0) {
5347
            WOLFSSL_MSG("wc_ed25519_make_key failed");
5348
            res = 0;
5349
        }
5350
        if (res) {
5351
            /* Export Curve25519 key pair to buffers. */
5352
            ret = wc_ed25519_export_key(&key, priv, privSz, pub, pubSz);
5353
            if (ret != 0) {
5354
                WOLFSSL_MSG("wc_ed25519_export_key failed");
5355
                res = 0;
5356
            }
5357
        }
5358
5359
        wc_ed25519_free(&key);
5360
    }
5361
5362
    if (initTmpRng) {
5363
        wc_FreeRng(rng);
5364
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5365
    }
5366
5367
    return res;
5368
#else
5369
#ifndef WOLFSSL_KEY_GEN
5370
    WOLFSSL_MSG("No Key Gen built in");
5371
#else
5372
    WOLFSSL_MSG("No ED25519 key export built in");
5373
#endif
5374
5375
    (void)priv;
5376
    (void)privSz;
5377
    (void)pub;
5378
    (void)pubSz;
5379
5380
    return 0;
5381
#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
5382
}
5383
5384
/* Sign a message with Ed25519 using the private key.
5385
 *
5386
 * Input and output keys are in little endian format.
5387
 * Priv is a buffer containing private and public part of key.
5388
 *
5389
 * @param [in]      msg     Message to be signed.
5390
 * @param [in]      msgSz   Length of message in bytes.
5391
 * @param [in]      priv    ED25519 private key data.
5392
 * @param [in]      privSz  Length in bytes of private key data.
5393
 * @param [out]     sig     Signature buffer.
5394
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
5395
 *                          On out, the length of the signature in bytes.
5396
 * @return  1 on success
5397
 * @return  0 on failure.
5398
 */
5399
int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
5400
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
5401
    unsigned int *sigSz)
5402
{
5403
#if defined(HAVE_ED25519_SIGN) && defined(WOLFSSL_KEY_GEN) && \
5404
    defined(HAVE_ED25519_KEY_IMPORT)
5405
    ed25519_key key;
5406
    int res = 1;
5407
5408
    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
5409
5410
    /* Validate parameters. */
5411
    if ((priv == NULL) || (privSz != ED25519_PRV_KEY_SIZE) ||
5412
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
5413
            (*sigSz < ED25519_SIG_SIZE)) {
5414
        WOLFSSL_MSG("Bad arguments");
5415
        res = 0;
5416
    }
5417
5418
    /* Initialize Ed25519 key. */
5419
    if (res && (wc_ed25519_init(&key) != 0)) {
5420
        WOLFSSL_MSG("wc_curve25519_init failed");
5421
        res = 0;
5422
    }
5423
    if (res) {
5424
        /* Import private and public key. */
5425
        int ret = wc_ed25519_import_private_key(priv, privSz / 2,
5426
            priv + (privSz / 2), ED25519_PUB_KEY_SIZE, &key);
5427
        if (ret != 0) {
5428
            WOLFSSL_MSG("wc_ed25519_import_private failed");
5429
            res = 0;
5430
        }
5431
5432
        if (res) {
5433
            /* Sign message with Ed25519. */
5434
            ret = wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key);
5435
            if (ret != 0) {
5436
                WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
5437
                res = 0;
5438
            }
5439
        }
5440
5441
        wc_ed25519_free(&key);
5442
    }
5443
5444
    return res;
5445
#else
5446
#if !defined(HAVE_ED25519_SIGN)
5447
    WOLFSSL_MSG("No ED25519 sign built in");
5448
#elif !defined(WOLFSSL_KEY_GEN)
5449
    WOLFSSL_MSG("No Key Gen built in");
5450
#elif !defined(HAVE_ED25519_KEY_IMPORT)
5451
    WOLFSSL_MSG("No ED25519 Key import built in");
5452
#endif
5453
5454
    (void)msg;
5455
    (void)msgSz;
5456
    (void)priv;
5457
    (void)privSz;
5458
    (void)sig;
5459
    (void)sigSz;
5460
5461
    return 0;
5462
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
5463
}
5464
5465
/* Verify a message with Ed25519 using the public key.
5466
 *
5467
 * Input keys are in little endian format.
5468
 *
5469
 * @param [in] msg     Message to be verified.
5470
 * @param [in] msgSz   Length of message in bytes.
5471
 * @param [in] pub     ED25519 public key data.
5472
 * @param [in] privSz  Length in bytes of public key data.
5473
 * @param [in] sig     Signature buffer.
5474
 * @param [in] sigSz   Length of the signature in bytes.
5475
 * @return  1 on success
5476
 * @return  0 on failure.
5477
 */
5478
int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
5479
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
5480
    unsigned int sigSz)
5481
{
5482
#if defined(HAVE_ED25519_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
5483
    defined(HAVE_ED25519_KEY_IMPORT)
5484
    ed25519_key key;
5485
    int res = 1;
5486
5487
    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
5488
5489
    /* Validate parameters. */
5490
    if ((pub == NULL) || (pubSz != ED25519_PUB_KEY_SIZE) || (msg == NULL) ||
5491
            (sig == NULL) || (sigSz != ED25519_SIG_SIZE)) {
5492
        WOLFSSL_MSG("Bad arguments");
5493
        res = 0;
5494
    }
5495
5496
    /* Initialize Ed25519 key. */
5497
    if (res && (wc_ed25519_init(&key) != 0)) {
5498
        WOLFSSL_MSG("wc_curve25519_init failed");
5499
        res = 0;
5500
    }
5501
    if (res) {
5502
        /* Import public key. */
5503
        int ret = wc_ed25519_import_public(pub, pubSz, &key);
5504
        if (ret != 0) {
5505
            WOLFSSL_MSG("wc_ed25519_import_public failed");
5506
            res = 0;
5507
        }
5508
5509
        if (res) {
5510
            int check = 0;
5511
5512
            /* Verify signature with message and public key. */
5513
            ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
5514
                &key);
5515
            /* Check for errors in verification process. */
5516
            if (ret != 0) {
5517
                WOLFSSL_MSG("wc_ed25519_verify_msg failed");
5518
                res = 0;
5519
            }
5520
            /* Check signature is valid. */
5521
            else if (!check) {
5522
                WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
5523
                res = 0;
5524
            }
5525
        }
5526
5527
        wc_ed25519_free(&key);
5528
    }
5529
5530
    return res;
5531
#else
5532
#if !defined(HAVE_ED25519_VERIFY)
5533
    WOLFSSL_MSG("No ED25519 verify built in");
5534
#elif !defined(WOLFSSL_KEY_GEN)
5535
    WOLFSSL_MSG("No Key Gen built in");
5536
#elif !defined(HAVE_ED25519_KEY_IMPORT)
5537
    WOLFSSL_MSG("No ED25519 Key import built in");
5538
#endif
5539
5540
    (void)msg;
5541
    (void)msgSz;
5542
    (void)pub;
5543
    (void)pubSz;
5544
    (void)sig;
5545
    (void)sigSz;
5546
5547
    return 0;
5548
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
5549
}
5550
5551
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
5552
5553
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
5554
    defined(HAVE_ED25519)
5555
/* Allocate and initialize a new ed25519_key.
5556
 *
5557
 * @param [in] heap   Heap hint for memory allocation.
5558
 * @param [in] devId  Device identifier for crypto callbacks.
5559
 * @return  Allocated and initialized ed25519_key on success.
5560
 * @return  NULL on failure.
5561
 */
5562
ed25519_key* wolfSSL_ED25519_new(void* heap, int devId)
5563
{
5564
    ed25519_key* key;
5565
5566
    WOLFSSL_ENTER("wolfSSL_ED25519_new");
5567
5568
#ifndef WC_NO_CONSTRUCTORS
5569
    key = wc_ed25519_new(heap, devId, NULL);
5570
#else
5571
    key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
5572
        DYNAMIC_TYPE_ED25519);
5573
    if (key == NULL) {
5574
        WOLFSSL_ERROR_MSG("wolfSSL_ED25519_new malloc failure");
5575
    }
5576
    else if (wc_ed25519_init_ex(key, heap, devId) != 0) {
5577
        WOLFSSL_ERROR_MSG("wolfSSL_ED25519_new init failure");
5578
        XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5579
        key = NULL;
5580
    }
5581
#endif
5582
5583
    return key;
5584
}
5585
5586
/* Free an ed25519_key allocated with wolfSSL_ED25519_new.
5587
 *
5588
 * @param [in] key  ed25519_key to free. May be NULL.
5589
 */
5590
void wolfSSL_ED25519_free(ed25519_key* key)
5591
{
5592
    if (key != NULL) {
5593
        WOLFSSL_ENTER("wolfSSL_ED25519_free");
5594
    #ifndef WC_NO_CONSTRUCTORS
5595
        wc_ed25519_delete(key, NULL);
5596
    #else
5597
        {
5598
            void* heap = key->heap;
5599
            wc_ed25519_free(key);
5600
            XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5601
        }
5602
    #endif
5603
    }
5604
}
5605
#endif /* (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) && HAVE_ED25519 */
5606
5607
/*******************************************************************************
5608
 * END OF ED25519 API
5609
 ******************************************************************************/
5610
5611
/*******************************************************************************
5612
 * START OF EC448 API
5613
 ******************************************************************************/
5614
5615
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
5616
/* Generate an EC448 key pair.
5617
 *
5618
 * Output keys are in little endian format.
5619
 *
5620
 * @param [out]     priv    EC448 private key data.
5621
 * @param [in, out] privSz  On in, the size of priv in bytes.
5622
 *                          On out, the length of the private key data in bytes.
5623
 * @param [out]     pub     EC448 public key data.
5624
 * @param [in, out] pubSz   On in, the size of pub in bytes.
5625
 *                          On out, the length of the public key data in bytes.
5626
 * @return  1 on success
5627
 * @return  0 on failure.
5628
 */
5629
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
5630
                               unsigned char *pub, unsigned int *pubSz)
5631
{
5632
#ifdef WOLFSSL_KEY_GEN
5633
    int res = 1;
5634
    int initTmpRng = 0;
5635
    WC_RNG *rng = NULL;
5636
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5637
    curve448_key key;
5638
5639
    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
5640
5641
    /* Validate parameters. */
5642
    if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE448_KEY_SIZE) ||
5643
            (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE448_KEY_SIZE)) {
5644
        WOLFSSL_MSG("Bad arguments");
5645
        res = 0;
5646
    }
5647
5648
    if (res) {
5649
        /* Create a random number generator. */
5650
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5651
        if (rng == NULL) {
5652
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5653
            res = 0;
5654
        }
5655
    }
5656
5657
    /* Initialize a Curve448 key. */
5658
    if (res && (wc_curve448_init(&key) != 0)) {
5659
        WOLFSSL_MSG("wc_curve448_init failed");
5660
        res = 0;
5661
    }
5662
    if (res) {
5663
        /* Make a Curve448 key pair. */
5664
        int ret = wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key);
5665
        if (ret != 0) {
5666
            WOLFSSL_MSG("wc_curve448_make_key failed");
5667
            res = 0;
5668
        }
5669
        if (res) {
5670
            /* Export Curve448 key pair to buffers. */
5671
            ret = wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
5672
                EC448_LITTLE_ENDIAN);
5673
            if (ret != 0) {
5674
                WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
5675
                res = 0;
5676
            }
5677
        }
5678
5679
        /* Dispose of key. */
5680
        wc_curve448_free(&key);
5681
    }
5682
5683
    if (initTmpRng) {
5684
        wc_FreeRng(rng);
5685
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5686
    }
5687
5688
    return res;
5689
#else
5690
    WOLFSSL_MSG("No Key Gen built in");
5691
5692
    (void)priv;
5693
    (void)privSz;
5694
    (void)pub;
5695
    (void)pubSz;
5696
5697
    return 0;
5698
#endif /* WOLFSSL_KEY_GEN */
5699
}
5700
5701
/* Compute a shared secret from private and public EC448 keys.
5702
 *
5703
 * Input and output keys are in little endian format
5704
 *
5705
 * @param [out]     shared    Shared secret buffer.
5706
 * @param [in, out] sharedSz  On in, the size of shared in bytes.
5707
 *                            On out, the length of the secret in bytes.
5708
 * @param [in]      priv      EC448 private key data.
5709
 * @param [in]      privSz    Length of the private key data in bytes.
5710
 * @param [in]      pub       EC448 public key data.
5711
 * @param [in]      pubSz     Length of the public key data in bytes.
5712
 * @return  1 on success
5713
 * @return  0 on failure.
5714
 */
5715
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
5716
                             const unsigned char *priv, unsigned int privSz,
5717
                             const unsigned char *pub, unsigned int pubSz)
5718
{
5719
#ifdef WOLFSSL_KEY_GEN
5720
    int res = 1;
5721
    curve448_key privkey;
5722
    curve448_key pubkey;
5723
5724
    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
5725
5726
    /* Validate parameters. */
5727
    if ((shared == NULL) || (sharedSz == NULL) ||
5728
            (*sharedSz < CURVE448_KEY_SIZE) || (priv == NULL) ||
5729
            (privSz < CURVE448_KEY_SIZE) || (pub == NULL) ||
5730
            (pubSz < CURVE448_KEY_SIZE)) {
5731
        WOLFSSL_MSG("Bad arguments");
5732
        res = 0;
5733
    }
5734
5735
    /* Initialize private key object. */
5736
    if (res && (wc_curve448_init(&privkey) != 0)) {
5737
        WOLFSSL_MSG("wc_curve448_init privkey failed");
5738
        res = 0;
5739
    }
5740
    if (res) {
5741
        /* Initialize public key object. */
5742
        if (wc_curve448_init(&pubkey) != MP_OKAY) {
5743
            WOLFSSL_MSG("wc_curve448_init pubkey failed");
5744
            res = 0;
5745
        }
5746
        if (res) {
5747
            /* Import our private key. */
5748
            int ret = wc_curve448_import_private_ex(priv, privSz, &privkey,
5749
                EC448_LITTLE_ENDIAN);
5750
            if (ret != 0) {
5751
                WOLFSSL_MSG("wc_curve448_import_private_ex failed");
5752
                res = 0;
5753
            }
5754
5755
            if (res) {
5756
                /* Import peer's public key. */
5757
                ret = wc_curve448_import_public_ex(pub, pubSz, &pubkey,
5758
                    EC448_LITTLE_ENDIAN);
5759
                if (ret != 0) {
5760
                    WOLFSSL_MSG("wc_curve448_import_public_ex failed");
5761
                    res = 0;
5762
                }
5763
            }
5764
            if (res) {
5765
                /* Compute shared secret. */
5766
                ret = wc_curve448_shared_secret_ex(&privkey, &pubkey, shared,
5767
                    sharedSz, EC448_LITTLE_ENDIAN);
5768
                if (ret != 0) {
5769
                    WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
5770
                    res = 0;
5771
                }
5772
            }
5773
5774
            wc_curve448_free(&pubkey);
5775
        }
5776
        wc_curve448_free(&privkey);
5777
    }
5778
5779
    return res;
5780
#else
5781
    WOLFSSL_MSG("No Key Gen built in");
5782
5783
    (void)shared;
5784
    (void)sharedSz;
5785
    (void)priv;
5786
    (void)privSz;
5787
    (void)pub;
5788
    (void)pubSz;
5789
5790
    return 0;
5791
#endif /* WOLFSSL_KEY_GEN */
5792
}
5793
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
5794
5795
/*******************************************************************************
5796
 * END OF EC448 API
5797
 ******************************************************************************/
5798
5799
/*******************************************************************************
5800
 * START OF ED448 API
5801
 ******************************************************************************/
5802
5803
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
5804
/* Generate an ED448 key pair.
5805
 *
5806
 * Output keys are in little endian format.
5807
 *
5808
 * @param [out]     priv    ED448 private key data.
5809
 * @param [in, out] privSz  On in, the size of priv in bytes.
5810
 *                          On out, the length of the private key data in bytes.
5811
 * @param [out]     pub     ED448 public key data.
5812
 * @param [in, out] pubSz   On in, the size of pub in bytes.
5813
 *                          On out, the length of the public key data in bytes.
5814
 * @return  1 on success
5815
 * @return  0 on failure.
5816
 */
5817
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
5818
    unsigned char *pub, unsigned int *pubSz)
5819
{
5820
#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED448_KEY_EXPORT)
5821
    int res = 1;
5822
    int initTmpRng = 0;
5823
    WC_RNG *rng = NULL;
5824
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5825
    ed448_key key;
5826
5827
    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
5828
5829
    /* Validate parameters. */
5830
    if ((priv == NULL) || (privSz == NULL) ||
5831
            (*privSz < ED448_PRV_KEY_SIZE) || (pub == NULL) ||
5832
            (pubSz == NULL) || (*pubSz < ED448_PUB_KEY_SIZE)) {
5833
        WOLFSSL_MSG("Bad arguments");
5834
        res = 0;
5835
    }
5836
5837
    if (res) {
5838
        /* Create a random number generator. */
5839
        rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5840
        if (rng == NULL) {
5841
            WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5842
            res = 0;
5843
        }
5844
    }
5845
5846
    /* Initialize an Ed448 key. */
5847
    if (res && (wc_ed448_init(&key) != 0)) {
5848
        WOLFSSL_MSG("wc_ed448_init failed");
5849
        res = 0;
5850
    }
5851
    if (res) {
5852
        /* Make an Ed448 key pair. */
5853
        int ret = wc_ed448_make_key(rng, ED448_KEY_SIZE, &key);
5854
        if (ret != 0) {
5855
            WOLFSSL_MSG("wc_ed448_make_key failed");
5856
            res = 0;
5857
        }
5858
        if (res) {
5859
            /* Export Curve448 key pair to buffers. */
5860
            ret = wc_ed448_export_key(&key, priv, privSz, pub, pubSz);
5861
            if (ret != 0) {
5862
                WOLFSSL_MSG("wc_ed448_export_key failed");
5863
                res = 0;
5864
            }
5865
        }
5866
5867
        wc_ed448_free(&key);
5868
    }
5869
5870
    if (initTmpRng) {
5871
        wc_FreeRng(rng);
5872
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5873
    }
5874
5875
    return res;
5876
#else
5877
#ifndef WOLFSSL_KEY_GEN
5878
    WOLFSSL_MSG("No Key Gen built in");
5879
#else
5880
    WOLFSSL_MSG("No ED448 key export built in");
5881
#endif
5882
5883
    (void)priv;
5884
    (void)privSz;
5885
    (void)pub;
5886
    (void)pubSz;
5887
5888
    return 0;
5889
#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
5890
}
5891
5892
/* Sign a message with Ed448 using the private key.
5893
 *
5894
 * Input and output keys are in little endian format.
5895
 * Priv is a buffer containing private and public part of key.
5896
 *
5897
 * @param [in]      msg     Message to be signed.
5898
 * @param [in]      msgSz   Length of message in bytes.
5899
 * @param [in]      priv    ED448 private key data.
5900
 * @param [in]      privSz  Length in bytes of private key data.
5901
 * @param [out]     sig     Signature buffer.
5902
 * @param [in, out] sigSz   On in, the length of the signature buffer in bytes.
5903
 *                          On out, the length of the signature in bytes.
5904
 * @return  1 on success
5905
 * @return  0 on failure.
5906
 */
5907
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
5908
    const unsigned char *priv, unsigned int privSz, unsigned char *sig,
5909
    unsigned int *sigSz)
5910
{
5911
#if defined(HAVE_ED448_SIGN) && defined(WOLFSSL_KEY_GEN) && \
5912
    defined(HAVE_ED448_KEY_IMPORT)
5913
    ed448_key key;
5914
    int res = 1;
5915
5916
    WOLFSSL_ENTER("wolfSSL_ED448_sign");
5917
5918
    /* Validate parameters. */
5919
    if ((priv == NULL) || (privSz != ED448_PRV_KEY_SIZE) ||
5920
            (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
5921
            (*sigSz < ED448_SIG_SIZE)) {
5922
        WOLFSSL_MSG("Bad arguments");
5923
        res = 0;
5924
    }
5925
5926
    /* Initialize Ed448 key. */
5927
    if (res && (wc_ed448_init(&key) != 0)) {
5928
        WOLFSSL_MSG("wc_curve448_init failed");
5929
        res = 0;
5930
    }
5931
    if (res) {
5932
        /* Import private and public key. */
5933
        int ret = wc_ed448_import_private_key(priv, privSz / 2,
5934
            priv + (privSz / 2), ED448_PUB_KEY_SIZE, &key);
5935
        if (ret != 0) {
5936
            WOLFSSL_MSG("wc_ed448_import_private failed");
5937
            res = 0;
5938
        }
5939
5940
        if (res) {
5941
            /* Sign message with Ed448 - no context. */
5942
            ret = wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0);
5943
            if (ret != 0) {
5944
                WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
5945
                res = 0;
5946
            }
5947
        }
5948
5949
        wc_ed448_free(&key);
5950
    }
5951
5952
    return res;
5953
#else
5954
#if !defined(HAVE_ED448_SIGN)
5955
    WOLFSSL_MSG("No ED448 sign built in");
5956
#elif !defined(WOLFSSL_KEY_GEN)
5957
    WOLFSSL_MSG("No Key Gen built in");
5958
#elif !defined(HAVE_ED448_KEY_IMPORT)
5959
    WOLFSSL_MSG("No ED448 Key import built in");
5960
#endif
5961
5962
    (void)msg;
5963
    (void)msgSz;
5964
    (void)priv;
5965
    (void)privSz;
5966
    (void)sig;
5967
    (void)sigSz;
5968
5969
    return 0;
5970
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
5971
}
5972
5973
/* Verify a message with Ed448 using the public key.
5974
 *
5975
 * Input keys are in little endian format.
5976
 *
5977
 * @param [in] msg     Message to be verified.
5978
 * @param [in] msgSz   Length of message in bytes.
5979
 * @param [in] pub     ED448 public key data.
5980
 * @param [in] privSz  Length in bytes of public key data.
5981
 * @param [in] sig     Signature buffer.
5982
 * @param [in] sigSz   Length of the signature in bytes.
5983
 * @return  1 on success
5984
 * @return  0 on failure.
5985
 */
5986
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
5987
    const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
5988
    unsigned int sigSz)
5989
{
5990
#if defined(HAVE_ED448_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
5991
    defined(HAVE_ED448_KEY_IMPORT)
5992
    ed448_key key;
5993
    int res = 1;
5994
5995
    WOLFSSL_ENTER("wolfSSL_ED448_verify");
5996
5997
    /* Validate parameters. */
5998
    if ((pub == NULL) || (pubSz != ED448_PUB_KEY_SIZE) || (msg == NULL) ||
5999
            (sig == NULL) || (sigSz != ED448_SIG_SIZE)) {
6000
        WOLFSSL_MSG("Bad arguments");
6001
        res = 0;
6002
    }
6003
6004
    /* Initialize Ed448 key. */
6005
    if (res && (wc_ed448_init(&key) != 0)) {
6006
        WOLFSSL_MSG("wc_curve448_init failed");
6007
        res = 0;
6008
    }
6009
    if (res) {
6010
        /* Import public key. */
6011
        int ret = wc_ed448_import_public(pub, pubSz, &key);
6012
        if (ret != 0) {
6013
            WOLFSSL_MSG("wc_ed448_import_public failed");
6014
            res = 0;
6015
        }
6016
6017
        if (res) {
6018
            int check = 0;
6019
6020
            /* Verify signature with message and public key - no context. */
6021
            ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
6022
                &key, NULL, 0);
6023
            /* Check for errors in verification process. */
6024
            if (ret != 0) {
6025
                WOLFSSL_MSG("wc_ed448_verify_msg failed");
6026
                res = 0;
6027
            }
6028
            /* Check signature is valid. */
6029
            else if (!check) {
6030
                WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
6031
                res = 0;
6032
            }
6033
        }
6034
6035
        wc_ed448_free(&key);
6036
    }
6037
6038
    return res;
6039
#else
6040
#if !defined(HAVE_ED448_VERIFY)
6041
    WOLFSSL_MSG("No ED448 verify built in");
6042
#elif !defined(WOLFSSL_KEY_GEN)
6043
    WOLFSSL_MSG("No Key Gen built in");
6044
#elif !defined(HAVE_ED448_KEY_IMPORT)
6045
    WOLFSSL_MSG("No ED448 Key import built in");
6046
#endif
6047
6048
    (void)msg;
6049
    (void)msgSz;
6050
    (void)pub;
6051
    (void)pubSz;
6052
    (void)sig;
6053
    (void)sigSz;
6054
6055
    return 0;
6056
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
6057
}
6058
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
6059
6060
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
6061
    defined(HAVE_ED448)
6062
/* Allocate and initialize a new ed448_key.
6063
 *
6064
 * @param [in] heap   Heap hint for memory allocation.
6065
 * @param [in] devId  Device identifier for crypto callbacks.
6066
 * @return  Allocated and initialized ed448_key on success.
6067
 * @return  NULL on failure.
6068
 */
6069
ed448_key* wolfSSL_ED448_new(void* heap, int devId)
6070
{
6071
    ed448_key* key;
6072
6073
    WOLFSSL_ENTER("wolfSSL_ED448_new");
6074
6075
#if !defined(WC_NO_CONSTRUCTORS) && \
6076
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7, 0))
6077
    key = wc_ed448_new(heap, devId, NULL);
6078
#else
6079
    key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
6080
    if (key == NULL) {
6081
        WOLFSSL_ERROR_MSG("wolfSSL_ED448_new malloc failure");
6082
    }
6083
    else if (wc_ed448_init_ex(key, heap, devId) != 0) {
6084
        WOLFSSL_ERROR_MSG("wolfSSL_ED448_new init failure");
6085
        XFREE(key, heap, DYNAMIC_TYPE_ED448);
6086
        key = NULL;
6087
    }
6088
#endif
6089
6090
    return key;
6091
}
6092
6093
/* Free an ed448_key allocated with wolfSSL_ED448_new.
6094
 *
6095
 * @param [in] key  ed448_key to free. May be NULL.
6096
 */
6097
void wolfSSL_ED448_free(ed448_key* key)
6098
{
6099
    if (key != NULL) {
6100
        WOLFSSL_ENTER("wolfSSL_ED448_free");
6101
    #if !defined(WC_NO_CONSTRUCTORS) && \
6102
        (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7, 0))
6103
        wc_ed448_delete(key, NULL);
6104
    #else
6105
        {
6106
            void* heap = key->heap;
6107
            wc_ed448_free(key);
6108
            XFREE(key, heap, DYNAMIC_TYPE_ED448);
6109
        }
6110
    #endif
6111
    }
6112
}
6113
#endif /* (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) && HAVE_ED448 */
6114
6115
/*******************************************************************************
6116
 * END OF ED448 API
6117
 ******************************************************************************/
6118
6119
/*******************************************************************************
6120
 * START OF GENERIC PUBLIC KEY PEM APIs
6121
 ******************************************************************************/
6122
6123
#ifdef OPENSSL_EXTRA
6124
/* Sets default callback password for PEM.
6125
 *
6126
 * @param [out] buf       Buffer to hold password.
6127
 * @param [in]  num       Number of characters in buffer.
6128
 * @param [in]  rwFlag    Read/write flag. Ignored.
6129
 * @param [in]  userData  User data - assumed to be default password.
6130
 * @return  Password size on success.
6131
 * @return  0 on failure.
6132
 */
6133
int wolfSSL_PEM_def_callback(char* buf, int num, int rwFlag, void* userData)
6134
{
6135
    int sz = 0;
6136
6137
    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
6138
6139
    (void)rwFlag;
6140
6141
    /* We assume that the user passes a default password as userdata */
6142
    if ((buf != NULL) && (userData != NULL)) {
6143
        sz = (int)XSTRLEN((const char*)userData);
6144
        sz = (int)min((word32)sz, (word32)num);
6145
        XMEMCPY(buf, userData, (size_t)sz);
6146
    }
6147
    else {
6148
        WOLFSSL_MSG("Error, default password cannot be created.");
6149
    }
6150
6151
    return sz;
6152
}
6153
6154
#ifndef NO_BIO
6155
/* Writes a public key to a WOLFSSL_BIO encoded in PEM format.
6156
 *
6157
 * @param [in] bio  BIO to write to.
6158
 * @param [in] key  Public key to write in PEM format.
6159
 * @return  1 on success.
6160
 * @return  0 on failure.
6161
 */
6162
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
6163
{
6164
    int ret = 0;
6165
6166
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
6167
6168
    if ((bio != NULL) && (key != NULL)) {
6169
        switch (key->type) {
6170
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
6171
            case WC_EVP_PKEY_RSA:
6172
                ret = wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key->rsa);
6173
                break;
6174
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
6175
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
6176
    defined(WOLFSSL_KEY_GEN)
6177
            case WC_EVP_PKEY_DSA:
6178
                ret = wolfSSL_PEM_write_bio_DSA_PUBKEY(bio, key->dsa);
6179
                break;
6180
#endif /* !NO_DSA && !HAVE_SELFTEST && defined(WOLFSSL_KEY_GEN) */
6181
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
6182
    defined(WOLFSSL_KEY_GEN)
6183
            case WC_EVP_PKEY_EC:
6184
                ret = wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key->ecc);
6185
                break;
6186
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
6187
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
6188
            case WC_EVP_PKEY_DH:
6189
                /* DH public key not supported. */
6190
                WOLFSSL_MSG("Writing DH PUBKEY not supported!");
6191
                break;
6192
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
6193
            default:
6194
                /* Key type not supported. */
6195
                WOLFSSL_MSG("Unknown Key type!");
6196
                break;
6197
        }
6198
    }
6199
6200
    return ret;
6201
}
6202
6203
/* Writes a private key to a WOLFSSL_BIO encoded in PEM format.
6204
 *
6205
 * @param [in] bio     BIO to write to.
6206
 * @param [in] key     Public key to write in PEM format.
6207
 * @param [in] cipher  Encryption cipher to use.
6208
 * @param [in] passwd  Password to use when encrypting.
6209
 * @param [in] len     Length of password.
6210
 * @param [in] cb      Password callback.
6211
 * @param [in] arg     Password callback argument.
6212
 * @return  1 on success.
6213
 * @return  0 on failure.
6214
 */
6215
int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
6216
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
6217
    wc_pem_password_cb* cb, void* arg)
6218
{
6219
    int ret = 1;
6220
6221
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
6222
6223
    (void)cipher;
6224
    (void)passwd;
6225
    (void)len;
6226
    (void)cb;
6227
    (void)arg;
6228
6229
    /* Validate parameters. */
6230
    if ((bio == NULL) || (key == NULL)) {
6231
        WOLFSSL_MSG("Bad Function Arguments");
6232
        ret = 0;
6233
    }
6234
6235
    if (ret == 1) {
6236
    #ifdef WOLFSSL_KEY_GEN
6237
        switch (key->type) {
6238
        #ifndef NO_RSA
6239
            case WC_EVP_PKEY_RSA:
6240
                /* Write using RSA specific API. */
6241
                ret = wolfSSL_PEM_write_bio_RSAPrivateKey(bio, key->rsa,
6242
                    cipher, passwd, len, cb, arg);
6243
                break;
6244
        #endif
6245
        #ifndef NO_DSA
6246
            case WC_EVP_PKEY_DSA:
6247
                /* Write using DSA specific API. */
6248
                ret = wolfSSL_PEM_write_bio_DSAPrivateKey(bio, key->dsa,
6249
                    cipher, passwd, len, cb, arg);
6250
                break;
6251
        #endif
6252
        #ifdef HAVE_ECC
6253
            case WC_EVP_PKEY_EC:
6254
            #if defined(HAVE_ECC_KEY_EXPORT)
6255
                /* Write using EC specific API. */
6256
                ret = wolfSSL_PEM_write_bio_ECPrivateKey(bio, key->ecc,
6257
                    cipher, passwd, len, cb, arg);
6258
            #else
6259
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
6260
                    key->pkey_sz, bio, EC_PRIVATEKEY_TYPE);
6261
            #endif
6262
                break;
6263
        #endif
6264
        #ifndef NO_DH
6265
            case WC_EVP_PKEY_DH:
6266
                /* Write using generic API with DH type. */
6267
                ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
6268
                    key->pkey_sz, bio, DH_PRIVATEKEY_TYPE);
6269
                break;
6270
        #endif
6271
            default:
6272
                WOLFSSL_MSG("Unknown Key type!");
6273
                ret = 0;
6274
                break;
6275
        }
6276
    #else
6277
        int type = 0;
6278
6279
        switch (key->type) {
6280
        #ifndef NO_DSA
6281
            case WC_EVP_PKEY_DSA:
6282
                type = DSA_PRIVATEKEY_TYPE;
6283
                break;
6284
        #endif
6285
        #ifdef HAVE_ECC
6286
            case WC_EVP_PKEY_EC:
6287
                type = ECC_PRIVATEKEY_TYPE;
6288
                break;
6289
        #endif
6290
        #ifndef NO_DH
6291
            case WC_EVP_PKEY_DH:
6292
                type = DH_PRIVATEKEY_TYPE;
6293
                break;
6294
        #endif
6295
        #ifndef NO_RSA
6296
            case WC_EVP_PKEY_RSA:
6297
                type = PRIVATEKEY_TYPE;
6298
                break;
6299
        #endif
6300
            default:
6301
                ret = 0;
6302
                break;
6303
        }
6304
        if (ret == 1) {
6305
            /* Write using generic API with generic type. */
6306
            ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr, key->pkey_sz,
6307
                bio, type);
6308
        }
6309
    #endif
6310
    }
6311
6312
    return ret;
6313
}
6314
#endif /* !NO_BIO */
6315
6316
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \
6317
    !defined(NO_ASN) && !defined(NO_PWDBASED)
6318
/* Writes a public key to a file pointer encoded in PEM format.
6319
 *
6320
 * @param [in] fp   File pointer to write to.
6321
 * @param [in] key  Public key to write in PEM format.
6322
 * @return  1 on success.
6323
 * @return  0 on failure.
6324
 */
6325
int wolfSSL_PEM_write_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY* key)
6326
{
6327
    int err = 0;
6328
    unsigned char* derBuf = NULL;
6329
    int derSz = 0;
6330
6331
    WOLFSSL_ENTER("wolfSSL_PEM_write_PUBKEY");
6332
6333
    if ((fp == XBADFILE) || (key == NULL)) {
6334
        WOLFSSL_MSG("Bad Function Arguments");
6335
        err = 1;
6336
    }
6337
6338
    if (!err) {
6339
        derSz = wolfSSL_i2d_PUBKEY(key, NULL);
6340
        if (derSz <= 0) {
6341
            WOLFSSL_MSG("Failed to get DER size for key");
6342
            err = 1;
6343
        }
6344
    }
6345
6346
    if (!err) {
6347
        unsigned char* tmp;
6348
        derBuf = (unsigned char*)XMALLOC((size_t)derSz, NULL,
6349
            DYNAMIC_TYPE_TMP_BUFFER);
6350
        if (derBuf == NULL) {
6351
            WOLFSSL_MSG("Failed to allocate DER buffer");
6352
            err = 1;
6353
        }
6354
        else {
6355
            tmp = derBuf;
6356
            if (wolfSSL_i2d_PUBKEY(key, &tmp) <= 0) {
6357
                WOLFSSL_MSG("Failed to convert key to DER");
6358
                err = 1;
6359
            }
6360
        }
6361
    }
6362
6363
    /* Write DER buffer to file as PEM. */
6364
    if ((!err) && (der_write_to_file_as_pem(derBuf, derSz, fp,
6365
            PUBLICKEY_TYPE, NULL) != 1)) {
6366
        WOLFSSL_MSG("Failed to write DER to file as PEM");
6367
        err = 1;
6368
    }
6369
6370
    /* Dispose of the DER encoding. */
6371
    XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6372
6373
    WOLFSSL_LEAVE("wolfSSL_PEM_write_PUBKEY", err);
6374
    return !err;
6375
}
6376
6377
/* Writes a private key to a file pointer encoded in PEM format.
6378
 *
6379
 * @param [in] fp      File pointer to write to.
6380
 * @param [in] key     Private key to write in PEM format.
6381
 * @param [in] cipher  Encryption cipher to use. May be NULL.
6382
 * @param [in] passwd  Password to use when encrypting. May be NULL.
6383
 * @param [in] len     Length of password.
6384
 * @param [in] cb      Password callback.
6385
 * @param [in] arg     Password callback argument.
6386
 * @return  1 on success.
6387
 * @return  0 on failure.
6388
 */
6389
int wolfSSL_PEM_write_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY* key,
6390
    const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
6391
    wc_pem_password_cb* cb, void* arg)
6392
{
6393
    int err = 0;
6394
    int type = 0;
6395
    unsigned char* derBuf = NULL;
6396
    int derSz = 0;
6397
6398
    (void)cipher;
6399
    (void)passwd;
6400
    (void)len;
6401
    (void)cb;
6402
    (void)arg;
6403
6404
    WOLFSSL_ENTER("wolfSSL_PEM_write_PrivateKey");
6405
6406
    /* Validate parameters. */
6407
    if ((fp == XBADFILE) || (key == NULL)) {
6408
        WOLFSSL_MSG("Bad Function Arguments");
6409
        err = 1;
6410
    }
6411
6412
    /* Determine PEM type from key type, mirroring wolfSSL_PEM_read_PrivateKey's
6413
     * keyFormat switch. */
6414
    if (!err) {
6415
        switch (key->type) {
6416
            case WC_EVP_PKEY_RSA:
6417
                type = PRIVATEKEY_TYPE;
6418
                break;
6419
            case WC_EVP_PKEY_DSA:
6420
                type = DSA_PRIVATEKEY_TYPE;
6421
                break;
6422
            case WC_EVP_PKEY_EC:
6423
                type = ECC_PRIVATEKEY_TYPE;
6424
                break;
6425
            case WC_EVP_PKEY_DH:
6426
                type = DH_PRIVATEKEY_TYPE;
6427
                break;
6428
            default:
6429
                WOLFSSL_MSG("Unknown key type");
6430
                err = 1;
6431
                break;
6432
        }
6433
    }
6434
6435
    if (!err) {
6436
        derSz = wolfSSL_i2d_PrivateKey(key, NULL);
6437
        if (derSz <= 0) {
6438
            WOLFSSL_MSG("Failed to get DER size for private key");
6439
            err = 1;
6440
        }
6441
    }
6442
6443
    if (!err) {
6444
        unsigned char* tmp;
6445
        derBuf = (unsigned char*)XMALLOC((size_t)derSz, NULL,
6446
            DYNAMIC_TYPE_TMP_BUFFER);
6447
        if (derBuf == NULL) {
6448
            WOLFSSL_MSG("Failed to allocate DER buffer");
6449
            err = 1;
6450
        }
6451
        else {
6452
            tmp = derBuf;
6453
            if (wolfSSL_i2d_PrivateKey(key, &tmp) <= 0) {
6454
                WOLFSSL_MSG("Error encoding private key as DER");
6455
                err = 1;
6456
            }
6457
        }
6458
    }
6459
6460
    /* Write DER buffer to file as PEM. */
6461
    if ((!err) && (der_write_to_file_as_pem(derBuf, derSz, fp, type,
6462
            NULL) != 1)) {
6463
        WOLFSSL_MSG("Error writing DER to file as PEM");
6464
        err = 1;
6465
    }
6466
6467
    /* Dispose of the DER encoding. */
6468
    XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6469
6470
    WOLFSSL_LEAVE("wolfSSL_PEM_write_PrivateKey", err);
6471
    return !err;
6472
}
6473
#endif /* !NO_FILESYSTEM && !NO_CERTS && OPENSSL_EXTRA && !NO_ASN &&
6474
        * !NO_PWDBASED */
6475
6476
#ifndef NO_BIO
6477
/* Create a private key object from the data in the BIO.
6478
 *
6479
 * @param [in]      bio   BIO to read from.
6480
 * @param [in, out] key   Public key object. Object used if passed in.
6481
 * @param [in]      cb    Password callback.
6482
 * @param [in]      arg   Password callback argument.
6483
 * @return  A WOLFSSL_EVP_PKEY object on success.
6484
 * @return  NULL on failure.
6485
 */
6486
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
6487
    WOLFSSL_EVP_PKEY **key, wc_pem_password_cb *cb, void *arg)
6488
{
6489
    int err = 0;
6490
    WOLFSSL_EVP_PKEY* pkey = NULL;
6491
    DerBuffer* der = NULL;
6492
6493
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
6494
6495
    if (bio == NULL) {
6496
        err = 1;
6497
    }
6498
6499
    /* Read the PEM public key from the BIO and convert to DER. */
6500
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PUBLICKEY_TYPE, NULL,
6501
            &der) < 0)) {
6502
        err = 1;
6503
    }
6504
6505
    if (!err) {
6506
        const unsigned char* ptr = der->buffer;
6507
6508
        /* Use key passed in if set. */
6509
        if ((key != NULL) && (*key != NULL)) {
6510
            pkey = *key;
6511
        }
6512
6513
        /* Convert DER data to a public key object. */
6514
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
6515
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6516
            pkey = NULL;
6517
            err = 1;
6518
        }
6519
    }
6520
6521
    /* Return the key if possible. */
6522
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6523
        *key = pkey;
6524
    }
6525
    /* Dispose of the DER encoding. */
6526
    FreeDer(&der);
6527
6528
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
6529
6530
    return pkey;
6531
}
6532
6533
/* Create a private key object from the data in the BIO.
6534
 *
6535
 * @param [in]      bio   BIO to read from.
6536
 * @param [in, out] key   Private key object. Object used if passed in.
6537
 * @param [in]      cb    Password callback.
6538
 * @param [in]      arg   Password callback argument.
6539
 * @return  A WOLFSSL_EVP_PKEY object on success.
6540
 * @return  NULL on failure.
6541
 */
6542
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
6543
    WOLFSSL_EVP_PKEY** key, wc_pem_password_cb* cb, void* arg)
6544
{
6545
    int err = 0;
6546
    WOLFSSL_EVP_PKEY* pkey = NULL;
6547
    DerBuffer* der = NULL;
6548
    int keyFormat = 0;
6549
6550
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
6551
6552
    /* Validate parameters. */
6553
    if (bio == NULL) {
6554
        err = 1;
6555
    }
6556
6557
    /* Read the PEM private key from the BIO and convert to DER. */
6558
    if ((!err) && (pem_read_bio_key(bio, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
6559
            &der) < 0)) {
6560
        err = 1;
6561
    }
6562
6563
    if (!err) {
6564
        const unsigned char* ptr = der->buffer;
6565
        int type;
6566
6567
        /* Set key type based on format returned. */
6568
        switch (keyFormat) {
6569
            /* No key format set - default to RSA. */
6570
            case 0:
6571
            case RSAk:
6572
                type = WC_EVP_PKEY_RSA;
6573
                break;
6574
            case DSAk:
6575
                type = WC_EVP_PKEY_DSA;
6576
                break;
6577
            case ECDSAk:
6578
                type = WC_EVP_PKEY_EC;
6579
                break;
6580
            case DHk:
6581
                type = WC_EVP_PKEY_DH;
6582
                break;
6583
        #ifdef HAVE_ED25519
6584
            case ED25519k:
6585
                type = WC_EVP_PKEY_ED25519;
6586
                break;
6587
        #endif
6588
        #ifdef HAVE_ED448
6589
            case ED448k:
6590
                type = WC_EVP_PKEY_ED448;
6591
                break;
6592
        #endif
6593
        #ifdef WOLFSSL_HAVE_MLDSA
6594
            case ML_DSA_44k:
6595
            case ML_DSA_65k:
6596
            case ML_DSA_87k:
6597
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
6598
            case DILITHIUM_LEVEL2k:
6599
            case DILITHIUM_LEVEL3k:
6600
            case DILITHIUM_LEVEL5k:
6601
            #endif
6602
                type = WC_EVP_PKEY_DILITHIUM;
6603
                break;
6604
        #endif
6605
            default:
6606
                type = WOLFSSL_FATAL_ERROR;
6607
                break;
6608
        }
6609
6610
        /* Use key passed in if set. */
6611
        if ((key != NULL) && (*key != NULL)) {
6612
            pkey = *key;
6613
        }
6614
6615
        /* Convert DER data to a private key object. */
6616
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
6617
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6618
            pkey = NULL;
6619
            err = 1;
6620
        }
6621
    }
6622
6623
    /* Return the key if possible. */
6624
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6625
        *key = pkey;
6626
    }
6627
    /* Dispose of the DER encoding. */
6628
    FreeDer(&der);
6629
6630
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", err);
6631
6632
    return pkey;
6633
}
6634
6635
6636
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(
6637
    WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb,
6638
    void* arg)
6639
{
6640
    return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
6641
}
6642
#endif /* !NO_BIO */
6643
6644
#if !defined(NO_FILESYSTEM)
6645
/* Create a private key object from the data in a file.
6646
 *
6647
 * @param [in]      fp    File pointer.
6648
 * @param [in, out] key   Public key object. Object used if passed in.
6649
 * @param [in]      cb    Password callback.
6650
 * @param [in]      arg   Password callback argument.
6651
 * @return  A WOLFSSL_EVP_PKEY object on success.
6652
 * @return  NULL on failure.
6653
 */
6654
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **key,
6655
    wc_pem_password_cb *cb, void *arg)
6656
{
6657
    int err = 0;
6658
    WOLFSSL_EVP_PKEY* pkey = NULL;
6659
    DerBuffer* der = NULL;
6660
6661
    WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
6662
6663
    /* Validate parameters. */
6664
    if (fp == XBADFILE) {
6665
        err = 1;
6666
    }
6667
6668
    /* Read the PEM public key from the file and convert to DER. */
6669
    if ((!err) && ((pem_read_file_key(fp, cb, arg, PUBLICKEY_TYPE, NULL,
6670
            &der) < 0) || (der == NULL))) {
6671
        err = 1;
6672
    }
6673
    if (!err) {
6674
        const unsigned char* ptr = der->buffer;
6675
6676
        /* Use key passed in if set. */
6677
        if ((key != NULL) && (*key != NULL)) {
6678
            pkey = *key;
6679
        }
6680
6681
        /* Convert DER data to a public key object. */
6682
        if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
6683
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6684
            pkey = NULL;
6685
            err = 1;
6686
        }
6687
    }
6688
6689
    /* Return the key if possible. */
6690
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6691
        *key = pkey;
6692
    }
6693
    /* Dispose of the DER encoding. */
6694
    FreeDer(&der);
6695
6696
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
6697
6698
    return pkey;
6699
}
6700
6701
#ifndef NO_CERTS
6702
/* Create a private key object from the data in a file.
6703
 *
6704
 * @param [in]      fp    File pointer.
6705
 * @param [in, out] key   Private key object. Object used if passed in.
6706
 * @param [in]      cb    Password callback.
6707
 * @param [in]      arg   Password callback argument.
6708
 * @return  A WOLFSSL_EVP_PKEY object on success.
6709
 * @return  NULL on failure.
6710
 */
6711
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
6712
    wc_pem_password_cb *cb, void *arg)
6713
{
6714
    int err = 0;
6715
    WOLFSSL_EVP_PKEY* pkey = NULL;
6716
    DerBuffer* der = NULL;
6717
    int keyFormat = 0;
6718
6719
    WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
6720
6721
    /* Validate parameters. */
6722
    if (fp == XBADFILE) {
6723
        err = 1;
6724
    }
6725
6726
    /* Read the PEM private key from the file and convert to DER. */
6727
    if ((!err) && (pem_read_file_key(fp, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
6728
            &der)) < 0) {
6729
        err = 1;
6730
    }
6731
6732
    if (!err) {
6733
        const unsigned char* ptr = der->buffer;
6734
        int type;
6735
6736
        /* Set key type based on format returned. */
6737
        switch (keyFormat) {
6738
            /* No key format set - default to RSA. */
6739
            case 0:
6740
            case RSAk:
6741
                type = WC_EVP_PKEY_RSA;
6742
                break;
6743
            case DSAk:
6744
                type = WC_EVP_PKEY_DSA;
6745
                break;
6746
            case ECDSAk:
6747
                type = WC_EVP_PKEY_EC;
6748
                break;
6749
            case DHk:
6750
                type = WC_EVP_PKEY_DH;
6751
                break;
6752
        #ifdef HAVE_ED25519
6753
            case ED25519k:
6754
                type = WC_EVP_PKEY_ED25519;
6755
                break;
6756
        #endif
6757
        #ifdef HAVE_ED448
6758
            case ED448k:
6759
                type = WC_EVP_PKEY_ED448;
6760
                break;
6761
        #endif
6762
        #ifdef WOLFSSL_HAVE_MLDSA
6763
            case ML_DSA_44k:
6764
            case ML_DSA_65k:
6765
            case ML_DSA_87k:
6766
            #ifdef WOLFSSL_MLDSA_FIPS204_DRAFT
6767
            case DILITHIUM_LEVEL2k:
6768
            case DILITHIUM_LEVEL3k:
6769
            case DILITHIUM_LEVEL5k:
6770
            #endif
6771
                type = WC_EVP_PKEY_DILITHIUM;
6772
                break;
6773
        #endif
6774
            default:
6775
                type = WOLFSSL_FATAL_ERROR;
6776
                break;
6777
        }
6778
6779
        /* Use key passed in if set. */
6780
        if ((key != NULL) && (*key != NULL)) {
6781
            pkey = *key;
6782
        }
6783
6784
        /* Convert DER data to a private key object. */
6785
        if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
6786
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6787
            pkey = NULL;
6788
            err = 1;
6789
        }
6790
    }
6791
6792
    /* Return the key if possible. */
6793
    if ((!err) && (key != NULL) && (pkey != NULL)) {
6794
        *key = pkey;
6795
    }
6796
    /* Dispose of the DER encoding. */
6797
    FreeDer(&der);
6798
6799
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PrivateKey", 0);
6800
6801
    return pkey;
6802
}
6803
#endif /* !NO_CERTS */
6804
#endif /* !NO_FILESYSTEM */
6805
6806
#ifndef NO_CERTS
6807
6808
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
6809
#define PEM_BEGIN              "-----BEGIN "
6810
#define PEM_BEGIN_SZ           11
6811
#define PEM_END                "-----END "
6812
#define PEM_END_SZ             9
6813
#define PEM_HDR_FIN            "-----"
6814
#define PEM_HDR_FIN_SZ         5
6815
#define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
6816
#define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
6817
#define PEM_HDR_FIN_EOL_SZ     6
6818
6819
/* Find strings and return middle offsets.
6820
 *
6821
 * Find first string in pem as a prefix and then locate second string as a
6822
 * postfix.
6823
 * len returning with 0 indicates not found.
6824
 *
6825
 * @param [in]  pem      PEM data.
6826
 * @param [in]  pemLen   Length of PEM data.
6827
 * @param [in]  idx      Current index.
6828
 * @param [in]  prefix   First string to find.
6829
 * @param [in]  postfix  Second string to find after first.
6830
 * @param [out] start    Start index of data between strings.
6831
 * @param [out] len      Length of data between strings.
6832
 */
6833
static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,
6834
    const char* postfix, int* start, int* len)
6835
{
6836
    int prefixLen = (int)XSTRLEN(prefix);
6837
    int postfixLen = (int)XSTRLEN(postfix);
6838
6839
    *start = *len = 0;
6840
    /* Find prefix part. */
6841
    for (; idx < pemLen - prefixLen; idx++) {
6842
        if ((pem[idx] == prefix[0]) &&
6843
                (XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) {
6844
            idx += prefixLen;
6845
            *start = idx;
6846
            break;
6847
        }
6848
    }
6849
    /* Find postfix part. */
6850
    for (; idx < pemLen - postfixLen; idx++) {
6851
        if ((pem[idx] == postfix[0]) &&
6852
                (XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) {
6853
            *len = idx - *start;
6854
            break;
6855
        }
6856
    }
6857
}
6858
6859
/* Parse out content type name, any encryption headers and DER encoding.
6860
 *
6861
 * @param [in]  pem     PEM data.
6862
 * @param [in]  pemLen  Length of PEM data.
6863
 * @param [out] name    Name of content type.
6864
 * @param [out] header  Encryption headers.
6865
 * @param [out] data    DER encoding from PEM.
6866
 * @param [out] len     Length of DER data.
6867
 * @return  0 on success.
6868
 * @return  MEMORY_E when dynamic memory allocation fails.
6869
 * @return  ASN_NO_PEM_HEADER when no header found or different names found.
6870
 */
6871
static int pem_read_data(char* pem, int pemLen, char **name, char **header,
6872
    unsigned char **data, long *len)
6873
{
6874
    int ret = 0;
6875
    int start;
6876
    int nameLen;
6877
    int startHdr = 0;
6878
    int hdrLen = 0;
6879
    int startEnd = 0;
6880
    int endLen;
6881
6882
    *name = NULL;
6883
    *header = NULL;
6884
6885
    /* Find header. */
6886
    pem_find_pattern(pem, pemLen, 0, PEM_BEGIN, PEM_HDR_FIN, &start, &nameLen);
6887
    /* Allocate memory for header name. */
6888
    *name = (char*)XMALLOC((size_t)nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6889
    if (*name == NULL) {
6890
        ret = MEMORY_E;
6891
    }
6892
    if (ret == 0) {
6893
        /* Put in header name. */
6894
        (*name)[nameLen] = '\0';
6895
        if (nameLen == 0) {
6896
            ret = ASN_NO_PEM_HEADER;
6897
        }
6898
        else {
6899
            XMEMCPY(*name, pem + start, (size_t)nameLen);
6900
        }
6901
    }
6902
    if (ret == 0) {
6903
        /* Find encryption headers after header. */
6904
        start += nameLen + PEM_HDR_FIN_SZ;
6905
        pem_find_pattern(pem, pemLen, start, "\n", "\n\n", &startHdr, &hdrLen);
6906
        if (hdrLen > 0) {
6907
            /* Include first of two '\n' characters. */
6908
            hdrLen++;
6909
        }
6910
        /* Allocate memory for encryption header string. */
6911
        *header = (char*)XMALLOC((size_t)hdrLen + 1, NULL,
6912
                                    DYNAMIC_TYPE_TMP_BUFFER);
6913
        if (*header == NULL) {
6914
            ret = MEMORY_E;
6915
        }
6916
    }
6917
    if (ret == 0) {
6918
        /* Put in encryption header string. */
6919
        (*header)[hdrLen] = '\0';
6920
        if (hdrLen > 0) {
6921
            XMEMCPY(*header, pem + startHdr, (size_t)hdrLen);
6922
            start = startHdr + hdrLen + 1;
6923
        }
6924
6925
        /* Find footer. */
6926
        pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
6927
            &endLen);
6928
        /* Validate header name and footer name are the same. */
6929
        if ((endLen != nameLen) ||
6930
                 (XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
6931
            ret = ASN_NO_PEM_HEADER;
6932
        }
6933
    }
6934
    if (ret == 0) {
6935
        unsigned char* der = (unsigned char*)pem;
6936
        word32 derLen;
6937
6938
        /* Convert PEM body to DER. */
6939
        derLen = (word32)(startEnd - PEM_END_SZ - start);
6940
        ret = Base64_Decode(der + start, derLen, der, &derLen);
6941
        if (ret == 0) {
6942
            /* Return the DER data. */
6943
            *data = der;
6944
            *len = derLen;
6945
        }
6946
    }
6947
6948
    return ret;
6949
}
6950
6951
/* Encode the DER data in PEM format into a newly allocated buffer.
6952
 *
6953
 * @param [in]  name       Header/footer name.
6954
 * @param [in]  header     Encryption header.
6955
 * @param [in]  data       DER data.
6956
 * @param [in]  len        Length of DER data.
6957
 * @param [out] pemOut     PEM encoded data.
6958
 * @param [out] pemOutLen  Length of PEM encoded data.
6959
 * @return  0 on success.
6960
 * @return  MEMORY_E when dynamic memory allocation fails.
6961
 */
6962
static int pem_write_data(const char *name, const char *header,
6963
    const unsigned char *data, long len, char** pemOut, word32* pemOutLen)
6964
{
6965
    int ret = 0;
6966
    int nameLen;
6967
    int headerLen;
6968
    char* pem = NULL;
6969
    word32 pemLen;
6970
    word32 derLen;
6971
    byte* p;
6972
6973
    /* Reject lengths that would wrap the PEM size calculation below. */
6974
    if ((len < 0) || ((word32)len >= (WOLFSSL_MAX_32BIT / 4))) {
6975
        return BAD_FUNC_ARG;
6976
    }
6977
    derLen = (word32)len;
6978
6979
    nameLen = (int)XSTRLEN(name);
6980
    headerLen = (int)XSTRLEN(header);
6981
6982
    /* DER encode for PEM. */
6983
    pemLen  = (derLen + 2) / 3 * 4;
6984
    pemLen += (pemLen + 63) / 64;
6985
    /* Header */
6986
    pemLen += (word32)(PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
6987
    if (headerLen > 0) {
6988
        /* Encryption lines plus extra carriage return. */
6989
        pemLen += (word32)headerLen + 1;
6990
    }
6991
    /* Trailer */
6992
    pemLen += (word32)(PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
6993
6994
    pem = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6995
    if (pem == NULL) {
6996
        ret = MEMORY_E;
6997
    }
6998
    p = (byte*)pem;
6999
7000
    if (ret == 0) {
7001
        /* Add header. */
7002
        XMEMCPY(p, PEM_BEGIN, PEM_BEGIN_SZ);
7003
        p += PEM_BEGIN_SZ;
7004
        XMEMCPY(p, name, (size_t)nameLen);
7005
        p += nameLen;
7006
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
7007
        p += PEM_HDR_FIN_EOL_SZ;
7008
7009
        if (headerLen > 0) {
7010
            /* Add encryption header. */
7011
            XMEMCPY(p, header, (size_t)headerLen);
7012
            p += headerLen;
7013
            /* Blank line after a header and before body. */
7014
            *(p++) = '\n';
7015
        }
7016
7017
        /* Add DER data as PEM. */
7018
        pemLen -= (word32)((size_t)p - (size_t)pem);
7019
        ret = Base64_Encode(data, derLen, p, &pemLen);
7020
    }
7021
    if (ret == 0) {
7022
        p += pemLen;
7023
7024
        /* Add trailer. */
7025
        XMEMCPY(p, PEM_END, PEM_END_SZ);
7026
        p += PEM_END_SZ;
7027
        XMEMCPY(p, name, (size_t)nameLen);
7028
        p += nameLen;
7029
        XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
7030
        p += PEM_HDR_FIN_EOL_SZ;
7031
7032
        /* Return buffer and length of data. */
7033
        *pemOut = pem;
7034
        *pemOutLen = (word32)((size_t)p - (size_t)pem);
7035
    }
7036
    else {
7037
        /* Dispose of any allocated memory. */
7038
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7039
        pem = NULL;
7040
    }
7041
7042
    return ret;
7043
}
7044
#endif /* !NO_BIO || !NO_FILESYSTEM */
7045
7046
#ifndef NO_BIO
7047
/* Read PEM encoded data from a BIO.
7048
 *
7049
 * Reads the entire contents in.
7050
 *
7051
 * @param [in]  bio     BIO to read from.
7052
 * @param [out] name    Name of content type.
7053
 * @param [out] header  Encryption headers.
7054
 * @param [out] data    DER encoding from PEM.
7055
 * @param [out] len     Length of DER data.
7056
 * @return  1 on success.
7057
 * @return  0 on failure.
7058
 */
7059
int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
7060
    unsigned char **data, long *len)
7061
{
7062
    int res = 1;
7063
    char* pem = NULL;
7064
    int pemLen = 0;
7065
    int memAlloced = 1;
7066
7067
    /* Validate parameters. */
7068
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL) ||
7069
            (len == NULL)) {
7070
        res = 0;
7071
    }
7072
7073
    /* Load all the data from the BIO. */
7074
    if ((res == 1) && (wolfssl_read_bio(bio, &pem, &pemLen, &memAlloced) !=
7075
             0)) {
7076
        res = 0;
7077
    }
7078
    if ((res == 1) && (!memAlloced)) {
7079
        /* Need to return allocated memory - make sure it is allocated. */
7080
        char* p = (char*)XMALLOC((size_t)pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7081
        if (p == NULL) {
7082
            res = 0;
7083
        }
7084
        else {
7085
            /* Copy the data into new buffer. */
7086
            XMEMCPY(p, pem, (size_t)pemLen);
7087
            pem = p;
7088
        }
7089
    }
7090
7091
    /* Read the PEM data. */
7092
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
7093
            0)) {
7094
        /* Dispose of any allocated memory. */
7095
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7096
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7097
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7098
        *name = NULL;
7099
        *header = NULL;
7100
        res = 0;
7101
    }
7102
7103
    return res;
7104
}
7105
7106
/* Encode the DER data in PEM format into a BIO.
7107
 *
7108
 * @param [in] bio     BIO to write to.
7109
 * @param [in] name    Header/footer name.
7110
 * @param [in] header  Encryption header.
7111
 * @param [in] data    DER data.
7112
 * @param [in] len     Length of DER data.
7113
 * @return  0 on failure.
7114
 */
7115
int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
7116
    const char *header, const unsigned char *data, long len)
7117
{
7118
    int err = 0;
7119
    char* pem = NULL;
7120
    word32 pemLen = 0;
7121
7122
    /* Validate parameters. */
7123
    if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL)) {
7124
        err = BAD_FUNC_ARG;
7125
    }
7126
7127
    /* Encode into a buffer. */
7128
    if (!err) {
7129
        err = pem_write_data(name, header, data, len, &pem, &pemLen);
7130
    }
7131
7132
    /* Write PEM into BIO. */
7133
    if ((!err) && (wolfSSL_BIO_write(bio, pem, (int)pemLen) != (int)pemLen)) {
7134
        err = IO_FAILED_E;
7135
    }
7136
7137
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7138
    return (!err) ? (int)pemLen : 0;
7139
}
7140
#endif /* !NO_BIO */
7141
7142
#if !defined(NO_FILESYSTEM)
7143
/* Read PEM encoded data from a file.
7144
 *
7145
 * Reads the entire contents in.
7146
 *
7147
 * @param [in]  bio     BIO to read from.
7148
 * @param [out] name    Name of content type.
7149
 * @param [out] header  Encryption headers.
7150
 * @param [out] data    DER encoding from PEM.
7151
 * @param [out] len     Length of DER data.
7152
 * @return  1 on success.
7153
 * @return  0 on failure.
7154
 */
7155
int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data,
7156
    long *len)
7157
{
7158
    int res = 1;
7159
    char* pem = NULL;
7160
    int pemLen = 0;
7161
7162
    /* Validate parameters. */
7163
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
7164
            (data == NULL) || (len == NULL)) {
7165
        res = 0;
7166
    }
7167
7168
    /* Load all the data from the file. */
7169
    if ((res == 1) && (wolfssl_read_file(fp, &pem, &pemLen) != 0)) {
7170
        res = 0;
7171
    }
7172
7173
    /* Read the PEM data. */
7174
    if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
7175
            0)) {
7176
        /* Dispose of any allocated memory. */
7177
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7178
        XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7179
        XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7180
        *name = NULL;
7181
        *header = NULL;
7182
        res = 0;
7183
    }
7184
7185
    return res;
7186
}
7187
7188
/* Encode the DER data in PEM format into a file.
7189
 *
7190
 * @param [in] fp      File pointer to write to.
7191
 * @param [in] name    Header/footer name.
7192
 * @param [in] header  Encryption header.
7193
 * @param [in] data    DER data.
7194
 * @param [in] len     Length of DER data.
7195
 * @return  0 on success.
7196
 * @return  MEMORY_E when dynamic memory allocation fails.
7197
 */
7198
int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
7199
    const unsigned char *data, long len)
7200
{
7201
    int err = 0;
7202
    char* pem = NULL;
7203
    word32 pemLen = 0;
7204
7205
    /* Validate parameters. */
7206
    if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
7207
            (data == NULL)) {
7208
        err = 1;
7209
    }
7210
7211
    /* Encode into a buffer. */
7212
    if ((!err) && (pem_write_data(name, header, data, len, &pem, &pemLen) !=
7213
            0)) {
7214
        pemLen = 0;
7215
        err = 1;
7216
    }
7217
7218
    /* Write PEM to a file. */
7219
    if ((!err) && (XFWRITE(pem, 1, pemLen, fp) != pemLen)) {
7220
        pemLen = 0;
7221
    }
7222
7223
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7224
    return (int)pemLen;
7225
}
7226
#endif
7227
7228
/* Get EVP cipher info from encryption header string.
7229
 *
7230
 * @param [in]  header  Encryption header.
7231
 * @param [out] cipher  EVP Cipher info.
7232
 * @return  1 on success.
7233
 * @return  0 on failure.
7234
 */
7235
int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, EncryptedInfo* cipher)
7236
{
7237
    int res = 1;
7238
7239
    /* Validate parameters. */
7240
    if ((header == NULL) || (cipher == NULL)) {
7241
        res = 0;
7242
    }
7243
7244
    if (res == 1) {
7245
        XMEMSET(cipher, 0, sizeof(*cipher));
7246
7247
        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0) {
7248
            res = 0;
7249
        }
7250
    }
7251
7252
    return res;
7253
}
7254
7255
/* Apply cipher to DER data.
7256
 *
7257
 * @param [in]      cipher  EVP cipher info.
7258
 * @param [in, out] data    On in, encrypted DER data.
7259
 *                          On out, unencrypted DER data.
7260
 * @param [in, out] len     On in, length of encrypted DER data.
7261
 *                          On out, length of unencrypted DER data.
7262
 * @param [in]      cb      Password callback.
7263
 * @param [in]      ctx     Context for password callback.
7264
 * @return  1 on success.
7265
 * @return  0 on failure.
7266
 */
7267
int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
7268
    wc_pem_password_cb* cb, void* ctx)
7269
{
7270
    int ret = 1;
7271
    char password[NAME_SZ];
7272
    int passwordSz = 0;
7273
7274
#ifdef WOLFSSL_CHECK_MEM_ZERO
7275
    /* Baseline-zero and register the whole buffer up front so the cb() fill and
7276
     * every path to the ForceZero are covered. The written length is not known
7277
     * here, so the full buffer is registered; the XMEMSET keeps the unwritten
7278
     * tail defined-zero so the full-window check never false-fails. */
7279
    XMEMSET(password, 0, sizeof(password));
7280
    wc_MemZero_Add("wolfSSL_PEM_do_header password", password,
7281
        sizeof(password));
7282
#endif
7283
7284
    /* Validate parameters. */
7285
    if ((cipher == NULL) || (data == NULL) || (len == NULL) || (cb == NULL)) {
7286
        ret = 0;
7287
    }
7288
7289
    if (ret == 1) {
7290
        /* Get password and length. */
7291
        passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
7292
        if (passwordSz < 0) {
7293
            ret = 0;
7294
        }
7295
    }
7296
7297
    if (ret == 1) {
7298
        /* Decrypt the data using password and MD5. */
7299
        if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
7300
                passwordSz, WC_MD5) != 0) {
7301
            ret = WOLFSSL_FAILURE;
7302
        }
7303
    }
7304
7305
    if (passwordSz > 0) {
7306
        /* Ensure password is erased from memory. */
7307
        ForceZero(password, (word32)passwordSz);
7308
    }
7309
7310
#ifdef WOLFSSL_CHECK_MEM_ZERO
7311
    /* Whole buffer is zero here on every path (baseline + ForceZero), so the
7312
     * check always passes and the up-front registration is always retired. */
7313
    wc_MemZero_Check(password, sizeof(password));
7314
#endif
7315
    return ret;
7316
}
7317
7318
#endif /* !NO_CERTS */
7319
#endif /* OPENSSL_EXTRA */
7320
7321
#ifdef OPENSSL_ALL
7322
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
7323
7324
/* Encrypt the key into a buffer using PKCS$8 and a password.
7325
 *
7326
 * @param [in]      pkey      Private key to encrypt.
7327
 * @param [in]      enc       EVP cipher.
7328
 * @param [in]      passwd    Password to encrypt with.
7329
 * @param [in]      passwdSz  Number of bytes in password.
7330
 * @param [in]      key       Buffer to hold encrypted key.
7331
 * @param [in, out] keySz     On in, size of buffer in bytes.
7332
 *                            On out, size of encrypted key in bytes.
7333
 * @return  0 on success.
7334
 * @return  BAD_FUNC_ARG when EVP cipher not supported.
7335
 */
7336
int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
7337
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
7338
    word32* keySz)
7339
{
7340
    int ret;
7341
    WC_RNG rng;
7342
7343
    /* Initialize a new random number generator. */
7344
    ret = wc_InitRng(&rng);
7345
    if (ret == 0) {
7346
        int encAlgId = 0;
7347
7348
        /* Convert EVP cipher to a support encryption id. */
7349
    #ifndef NO_DES3
7350
        if (enc == EVP_DES_CBC) {
7351
            encAlgId = DESb;
7352
        }
7353
        else if (enc == EVP_DES_EDE3_CBC) {
7354
            encAlgId = DES3b;
7355
        }
7356
        else
7357
    #endif
7358
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
7359
    #ifdef WOLFSSL_AES_128
7360
        if (enc == EVP_AES_128_CBC) {
7361
            encAlgId = AES128CBCb;
7362
        }
7363
        else
7364
     #endif
7365
    #ifdef WOLFSSL_AES_256
7366
        if (enc == EVP_AES_256_CBC) {
7367
            encAlgId = AES256CBCb;
7368
        }
7369
        else
7370
     #endif
7371
#endif
7372
        {
7373
            ret = BAD_FUNC_ARG;
7374
        }
7375
7376
        if (ret == 0) {
7377
            /* Encrypt private into buffer. */
7378
            ret = TraditionalEnc((byte*)pkey->pkey.ptr + pkey->pkcs8HeaderSz,
7379
                (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
7380
                key, keySz, passwd, passwdSz, PKCS5, PBES2, encAlgId,
7381
                NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL);
7382
            if (ret > 0) {
7383
                *keySz = (word32)ret;
7384
            }
7385
        }
7386
        /* Dispose of random number generator. */
7387
        wc_FreeRng(&rng);
7388
    }
7389
7390
    return ret;
7391
}
7392
7393
/* Encode private key in PKCS#8 format.
7394
 *
7395
 * @param [in]      pkey   Private key.
7396
 * @param [out]     key    Buffer to hold encoding.
7397
 * @param [in, out] keySz  On in, size of buffer in bytes.
7398
 * @param                  On out, size of encoded key in bytes.
7399
 * @return  0 on success.
7400
 */
7401
int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
7402
{
7403
    int ret = 0;
7404
    int algId = 0;
7405
    const byte* curveOid = 0;
7406
    word32 oidSz = 0;
7407
7408
    /* Get the details of the private key. */
7409
#ifdef HAVE_ECC
7410
    if (pkey->type == WC_EVP_PKEY_EC) {
7411
        /* ECC private and get curve OID information. */
7412
        algId = ECDSAk;
7413
        ret = wc_ecc_get_oid((word32)pkey->ecc->group->curve_oid, &curveOid,
7414
            &oidSz);
7415
    }
7416
    else
7417
#endif
7418
    if (pkey->type == WC_EVP_PKEY_RSA) {
7419
        /* RSA private has no curve information. */
7420
        algId = RSAk;
7421
        curveOid = NULL;
7422
        oidSz = 0;
7423
    }
7424
    else if (pkey->type == WC_EVP_PKEY_DSA) {
7425
        /* DSA has no curve information. */
7426
        algId = DSAk;
7427
        curveOid = NULL;
7428
        oidSz = 0;
7429
    }
7430
#ifndef NO_DH
7431
    else if (pkey->type == WC_EVP_PKEY_DH) {
7432
        if (pkey->dh == NULL)
7433
            return BAD_FUNC_ARG;
7434
7435
        if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
7436
            /* Special case. DH buffer is always in PKCS8 format */
7437
            if (keySz == NULL)
7438
                return BAD_FUNC_ARG;
7439
7440
            *keySz = (word32)pkey->pkey_sz;
7441
            if (key == NULL)
7442
                return LENGTH_ONLY_E;
7443
7444
            XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
7445
            return pkey->pkey_sz;
7446
        }
7447
7448
        /* DH has no curve information. */
7449
        algId = DHk;
7450
        curveOid = NULL;
7451
        oidSz = 0;
7452
    }
7453
#endif
7454
    else {
7455
        ret = NOT_COMPILED_IN;
7456
    }
7457
7458
    if (ret >= 0) {
7459
        /* Encode private key in PKCS#8 format. */
7460
        ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr +
7461
            pkey->pkcs8HeaderSz, (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
7462
            algId, curveOid, oidSz);
7463
    }
7464
7465
    return ret;
7466
}
7467
7468
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
7469
    !defined(NO_STDIO_FILESYSTEM))
7470
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7471
 *
7472
 * @param [out] pem       Buffer holding PEM encoding.
7473
 * @param [out] pemSz     Size of data in buffer in bytes.
7474
 * @param [in]  pkey      Private key to write.
7475
 * @param [in]  enc       Encryption information to use. May be NULL.
7476
 * @param [in]  passwd    Password to use when encrypting. May be NULL.
7477
 * @param [in]  passwdSz  Size of password in bytes.
7478
 * @param [in]  cb        Password callback. Used when passwd is NULL. May be
7479
 *                        NULL.
7480
 * @param [in]  ctx       Context for password callback.
7481
 * @return  Length of PEM encoding on success.
7482
 * @return  0 on failure.
7483
 */
7484
static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
7485
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
7486
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
7487
{
7488
    int res = 1;
7489
    int ret = 0;
7490
    char password[NAME_SZ];
7491
    byte* key = NULL;
7492
    word32 keySz = 0;
7493
    word32 allocSz = 0;
7494
    int type = PKCS8_PRIVATEKEY_TYPE;
7495
7496
    /* Validate parameters. */
7497
    if (pkey == NULL) {
7498
        res = 0;
7499
    }
7500
7501
    if (res == 1) {
7502
        /* Guestimate key size and PEM size. */
7503
        if (pkcs8_encode(pkey, NULL, &keySz) !=
7504
                WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
7505
            res = 0;
7506
        }
7507
    }
7508
    if (res == 1) {
7509
        if (enc != NULL) {
7510
            /* Add on enough for extra DER data when encrypting. */
7511
            keySz += 128;
7512
        }
7513
        /* PEM encoding size from DER size. */
7514
        *pemSz  = (int)(keySz + 2) / 3 * 4;
7515
        *pemSz += (*pemSz + 63) / 64;
7516
        /* Header and footer. */
7517
        if (enc != NULL) {
7518
            /* Name is: 'ENCRYPTED PRIVATE KEY'. */
7519
            *pemSz += 74;
7520
        }
7521
        else {
7522
            /* Name is: 'PRIVATE KEY'. */
7523
            *pemSz += 54;
7524
        }
7525
7526
        allocSz = (word32)*pemSz;
7527
        /* Allocate enough memory to hold PEM encoded encrypted key. */
7528
        *pem = (byte*)XMALLOC((size_t)allocSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7529
        if (*pem == NULL) {
7530
            allocSz = 0;
7531
            res = 0;
7532
        }
7533
        else {
7534
            /* Use end of PEM buffer for key data. */
7535
            key = *pem + *pemSz - keySz;
7536
        }
7537
    }
7538
7539
    if ((res == 1) && (enc != NULL)) {
7540
        /* Set type for PEM. */
7541
        type = PKCS8_ENC_PRIVATEKEY_TYPE;
7542
7543
        if (passwd == NULL) {
7544
        #ifdef WOLFSSL_CHECK_MEM_ZERO
7545
            /* Baseline-zero and register the whole buffer before the cb() fill
7546
             * so the fill and every path to the ForceZero are covered. The
7547
             * written length is not known here, so the full buffer is
7548
             * registered and the XMEMSET keeps the unwritten tail zero. */
7549
            XMEMSET(password, 0, sizeof(password));
7550
            wc_MemZero_Add("pem_write_mem_pkcs8privatekey password", password,
7551
                sizeof(password));
7552
        #endif
7553
            /* Get the password by using callback. */
7554
            passwdSz = cb(password, sizeof(password), 1, ctx);
7555
            if (passwdSz < 0) {
7556
                res = 0;
7557
            }
7558
            passwd = password;
7559
        }
7560
7561
        if (res == 1) {
7562
            /* Encrypt the private key. */
7563
            ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
7564
            if (ret <= 0) {
7565
                res = 0;
7566
            }
7567
        }
7568
7569
        /* Zeroize the password from memory. */
7570
        if ((password == passwd) && (passwdSz > 0)) {
7571
            ForceZero(password, (word32)passwdSz);
7572
        }
7573
    #ifdef WOLFSSL_CHECK_MEM_ZERO
7574
        /* Retire the up-front registration on every path that made it: the
7575
         * local buffer was used iff passwd now aliases it. Buffer is zero here
7576
         * (baseline + ForceZero), so the full-window check always passes. */
7577
        if (password == passwd) {
7578
            wc_MemZero_Check(password, sizeof(password));
7579
        }
7580
    #endif
7581
    }
7582
    else if ((res == 1) && (enc == NULL)) {
7583
        /* Set type for PEM. */
7584
        type = PKCS8_PRIVATEKEY_TYPE;
7585
7586
        /* Encode private key in PKCS#8 format. */
7587
        ret = pkcs8_encode(pkey, key, &keySz);
7588
        if (ret < 0) {
7589
            res = 0;
7590
        }
7591
    }
7592
7593
    if (res == 1) {
7594
        /* Encode PKCS#8 formatted key to PEM. */
7595
        ret = wc_DerToPemEx(key, keySz, *pem, (word32)*pemSz, NULL, type);
7596
        if (ret < 0) {
7597
            res = 0;
7598
        }
7599
        else {
7600
            *pemSz = ret;
7601
        }
7602
    }
7603
7604
    /* Zero any remnants of the DER staging area that persist after PEM
7605
     * conversion so plaintext private key material is not left in freed heap
7606
     * memory. On success, only the bytes past the actual PEM output need
7607
     * clearing; on failure, the whole buffer is zeroed since its state is
7608
     * indeterminate. */
7609
    if (*pem != NULL) {
7610
        if (res == 1 && (word32)*pemSz < allocSz) {
7611
            ForceZero(*pem + *pemSz, allocSz - (word32)*pemSz);
7612
        }
7613
        else if (res != 1) {
7614
            ForceZero(*pem, allocSz);
7615
        }
7616
    }
7617
7618
    /* Return appropriate return code. */
7619
    return (res == 0) ? 0 : ret;
7620
7621
}
7622
#endif /* !NO_BIO || (!NO_FILESYSTEM && !NO_STDIO_FILESYSTEM) */
7623
7624
#ifndef NO_BIO
7625
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7626
 *
7627
 * TODO: OpenSSL returns 1 and 0 only.
7628
 *
7629
 * @param [in] bio       BIO to write to.
7630
 * @param [in] pkey      Private key to write.
7631
 * @param [in] enc       Encryption information to use. May be NULL.
7632
 * @param [in] passwd    Password to use when encrypting. May be NULL.
7633
 * @param [in] passwdSz  Size of password in bytes.
7634
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
7635
 *                       NULL.
7636
 * @param [in] ctx       Context for password callback.
7637
 * @return  Length of PEM encoding on success.
7638
 * @return  0 on failure.
7639
 */
7640
int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
7641
    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
7642
    int passwdSz, wc_pem_password_cb* cb, void* ctx)
7643
{
7644
    byte* pem = NULL;
7645
    int pemSz = 0;
7646
    int res = 1;
7647
7648
    /* Validate parameters. */
7649
    if (bio == NULL) {
7650
        res = 0;
7651
    }
7652
    if (res == 1) {
7653
        /* Write private key to memory. */
7654
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
7655
            passwdSz, cb, ctx);
7656
    }
7657
7658
    /* Write encoded key to BIO. */
7659
    if ((res >= 1) && (wolfSSL_BIO_write(bio, pem, pemSz) != pemSz)) {
7660
        res = 0;
7661
    }
7662
7663
    /* Dispose of dynamically allocated memory (pem and key). */
7664
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7665
    return res;
7666
}
7667
7668
int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
7669
        PKCS8_PRIV_KEY_INFO* keyInfo)
7670
{
7671
    return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
7672
            NULL, NULL);
7673
}
7674
#endif /* !NO_BIO */
7675
7676
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
7677
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7678
 *
7679
 * TODO: OpenSSL returns 1 and 0 only.
7680
 *
7681
 * @param [in] f         File pointer.
7682
 * @param [in] pkey      Private key to write.
7683
 * @param [in] enc       Encryption information to use. May be NULL.
7684
 * @param [in] passwd    Password to use when encrypting. May be NULL.
7685
 * @param [in] passwdSz  Size of password in bytes.
7686
 * @param [in] cb        Password callback. Used when passwd is NULL. May be
7687
 *                       NULL.
7688
 * @param [in] ctx       Context for password callback.
7689
 * @return  Length of PEM encoding on success.
7690
 * @return  0 on failure.
7691
 */
7692
int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
7693
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
7694
    wc_pem_password_cb* cb, void* ctx)
7695
{
7696
    byte* pem = NULL;
7697
    int pemSz = 0;
7698
    int res = 1;
7699
7700
    /* Validate parameters. */
7701
    if (f == XBADFILE) {
7702
        res = 0;
7703
    }
7704
    if (res == 1) {
7705
        /* Write private key to memory. */
7706
        res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
7707
            passwdSz, cb, ctx);
7708
    }
7709
7710
    /* Write encoded key to file. */
7711
    if ((res >= 1) && (XFWRITE(pem, 1, (size_t)pemSz, f) != (size_t)pemSz)) {
7712
        res = 0;
7713
    }
7714
7715
    /* Dispose of dynamically allocated memory (pem and key). */
7716
    XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7717
    return res;
7718
}
7719
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
7720
7721
#endif /* !NO_PWDBASED && HAVE_PKCS8 */
7722
#endif /* OPENSSL_ALL */
7723
7724
/*******************************************************************************
7725
 * END OF GENERIC PUBLIC KEY PEM APIs
7726
 ******************************************************************************/
7727
7728
#endif /* !WOLFSSL_PK_INCLUDED */