Coverage Report

Created: 2026-05-16 06:49

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