Coverage Report

Created: 2026-01-06 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/src/ssl_crypto.c
Line
Count
Source
1
/* ssl_crypto.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifndef WOLFSSL_SSL_CRYPTO_INCLUDED
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning ssl_crypto.c does not need to be compiled separately from ssl.c
27
    #endif
28
#else
29
30
/*******************************************************************************
31
 * START OF Digest APIs
32
 ******************************************************************************/
33
34
#ifdef OPENSSL_EXTRA
35
#ifndef NO_MD4
36
/* Initialize MD4 hash operation.
37
 *
38
 * @param [in, out] md4  MD4 context object.
39
 */
40
void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
41
178
{
42
    /* Ensure WOLFSSL_MD4_CTX is big enough for wolfCrypt Md4. */
43
178
    WOLFSSL_ASSERT_SIZEOF_GE(md4->buffer, wc_Md4);
44
45
178
    WOLFSSL_ENTER("MD4_Init");
46
47
    /* Initialize wolfCrypt MD4 object. */
48
178
    wc_InitMd4((wc_Md4*)md4);
49
178
}
50
51
/* Update MD4 hash with data.
52
 *
53
 * @param [in, out] md4   MD4 context object.
54
 * @param [in]      data  Data to be hashed.
55
 * @param [in]      len   Length of data in bytes.
56
 */
57
void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
58
    unsigned long len)
59
4.63k
{
60
4.63k
    WOLFSSL_ENTER("MD4_Update");
61
62
    /* Update wolfCrypt MD4 object with data. */
63
4.63k
    wc_Md4Update((wc_Md4*)md4, (const byte*)data, (word32)len);
64
4.63k
}
65
66
/* Finalize MD4 hash and return output.
67
 *
68
 * @param [out]     digest  Hash output.
69
 *                          Must be able to hold MD4_DIGEST_SIZE bytes.
70
 * @param [in, out] md4     MD4 context object.
71
 */
72
void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
73
178
{
74
178
    WOLFSSL_ENTER("MD4_Final");
75
76
    /* Finalize wolfCrypt MD4 hash into digest. */
77
178
    wc_Md4Final((wc_Md4*)md4, digest);
78
178
}
79
80
#endif /* NO_MD4 */
81
#endif /* OPENSSL_EXTRA */
82
83
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
84
#ifndef NO_MD5
85
/* Initialize MD5 hash operation.
86
 *
87
 * @param [in, out] md5  MD5 context object.
88
 * @return  1 on success.
89
 * @return  0 when md5 is NULL.
90
 */
91
int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
92
106
{
93
    /* Ensure WOLFSSL_MD5_CTX is big enough for wolfCrypt wc_Md5. */
94
106
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_MD5_CTX, wc_Md5);
95
96
106
    WOLFSSL_ENTER("MD5_Init");
97
98
    /* Initialize wolfCrypt MD5 object. */
99
106
    return wc_InitMd5((wc_Md5*)md5) == 0;
100
106
}
101
102
/* Update MD5 hash with data.
103
 *
104
 * @param [in, out] md5    MD5 context object.
105
 * @param [in]      input  Data to be hashed.
106
 * @param [in]      sz     Length of data in bytes.
107
 * @return  1 on success.
108
 * @return  0 when md5 is NULL.
109
 */
110
int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
111
    unsigned long sz)
112
3.95k
{
113
3.95k
    WOLFSSL_ENTER("MD5_Update");
114
115
    /* Update wolfCrypt MD5 object with data. */
116
3.95k
    return wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz) == 0;
117
3.95k
}
118
119
/* Finalize MD5 hash and return output.
120
 *
121
 * @param [out]     digest  Hash output.
122
 *                          Must be able to hold MD5_DIGEST_SIZE bytes.
123
 * @param [in, out] md5     MD5 context object.
124
 * @return  1 on success.
125
 * @return  0 when md5 or output is NULL.
126
 */
127
int wolfSSL_MD5_Final(byte* output, WOLFSSL_MD5_CTX* md5)
128
106
{
129
106
    int ret;
130
131
106
    WOLFSSL_ENTER("MD5_Final");
132
133
    /* Finalize wolfCrypt MD5 hash into output. */
134
106
    ret = (wc_Md5Final((wc_Md5*)md5, output) == 0);
135
    /* Free resources here, as OpenSSL API doesn't include MD5_Free(). */
136
106
    wc_Md5Free((wc_Md5*)md5);
137
138
106
    return ret;
139
106
}
140
141
/* Apply MD5 transformation to the data.
142
 *
143
 * 'data' has words reversed in this function when big endian.
144
 *
145
 * @param [in, out] md5   MD5 context object.
146
 * @param [in, out] data  One block of data to be hashed.
147
 * @return  1 on success.
148
 * @return  0 when md5 or data is NULL.
149
 */
150
int wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX* md5, const unsigned char* data)
151
0
{
152
0
    WOLFSSL_ENTER("MD5_Transform");
153
154
#if defined(BIG_ENDIAN_ORDER)
155
    /* Byte reversal done outside transform. */
156
    if ((md5 != NULL) && (data != NULL)) {
157
        ByteReverseWords((word32*)data, (word32*)data, WC_MD5_BLOCK_SIZE);
158
    }
159
#endif
160
    /* Transform block of data with wolfCrypt MD5 object. */
161
0
    return wc_Md5Transform((wc_Md5*)md5, data) == 0;
162
0
}
163
164
/* One shot MD5 hash of data.
165
 *
166
 * When hash is null, a static buffer of MD5_DIGEST_SIZE is used.
167
 * When the static buffer is used this function is not thread safe.
168
 *
169
 * @param [in]  data  Data to be hashed.
170
 * @param [in]  len   Length of data in bytes.
171
 * @param [out] hash  Buffer to hold digest. May be NULL.
172
 *                    Must be able to hold MD5_DIGEST_SIZE bytes.
173
 * @return  Buffer holding hash on success.
174
 * @return  NULL when hashing fails.
175
 */
176
unsigned char* wolfSSL_MD5(const unsigned char* data, size_t len,
177
    unsigned char* hash)
178
0
{
179
    /* Buffer to use when hash is NULL. */
180
0
    static unsigned char dgst[WC_MD5_DIGEST_SIZE];
181
182
0
    WOLFSSL_ENTER("wolfSSL_MD5");
183
184
    /* Ensure buffer available for digest result. */
185
0
    if (hash == NULL) {
186
0
        hash = dgst;
187
0
    }
188
    /* One shot MD5 hash with wolfCrypt. */
189
0
    if (wc_Md5Hash(data, (word32)len, hash) != 0) {
190
0
        WOLFSSL_MSG("wc_Md5Hash error");
191
0
        hash = NULL;
192
0
    }
193
194
0
    return hash;
195
0
}
196
#endif /* !NO_MD5 */
197
198
#ifndef NO_SHA
199
/* Initialize SHA hash operation.
200
 *
201
 * @param [in, out] sha  SHA context object.
202
 * @return  1 on success.
203
 * @return  0 when sha is NULL.
204
 */
205
int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
206
92
{
207
    /* Ensure WOLFSSL_SHA_CTX is big enough for wolfCrypt wc_Sha. */
208
92
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA_CTX, wc_Sha);
209
210
92
    WOLFSSL_ENTER("SHA_Init");
211
212
    /* Initialize wolfCrypt SHA object. */
213
92
    return wc_InitSha((wc_Sha*)sha) == 0;
214
92
}
215
216
/* Update SHA hash with data.
217
 *
218
 * @param [in, out] sha    SHA context object.
219
 * @param [in]      input  Data to be hashed.
220
 * @param [in]      sz     Length of data in bytes.
221
 * @return  1 on success.
222
 * @return  0 when md5 is NULL.
223
 */
224
int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
225
    unsigned long sz)
226
12.5k
{
227
12.5k
    WOLFSSL_ENTER("SHA_Update");
228
229
    /* Update wolfCrypt SHA object with data. */
230
12.5k
    return wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz) == 0;
231
12.5k
}
232
233
/* Finalize SHA hash and return output.
234
 *
235
 * @param [out]     output  Hash output.
236
 *                          Must be able to hold SHA_DIGEST_SIZE bytes.
237
 * @param [in, out] sha     SHA context object.
238
 * @return  1 on success.
239
 * @return  0 when sha or output is NULL.
240
 */
241
int wolfSSL_SHA_Final(byte* output, WOLFSSL_SHA_CTX* sha)
242
92
{
243
92
    int ret;
244
245
92
    WOLFSSL_ENTER("SHA_Final");
246
247
    /* Finalize wolfCrypt SHA hash into output. */
248
92
    ret = (wc_ShaFinal((wc_Sha*)sha, output) == 0);
249
    /* Free resources here, as OpenSSL API doesn't include SHA_Free(). */
250
92
    wc_ShaFree((wc_Sha*)sha);
251
252
92
    return ret;
253
92
}
254
255
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
256
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
257
/* Apply SHA transformation to the data.
258
 *
259
 * 'data' has words reversed in this function when little endian.
260
 *
261
 * @param [in, out] sha   SHA context object.
262
 * @param [in, out] data  One block of data to be hashed.
263
 * @return  1 on success.
264
 * @return  0 when sha or data is NULL.
265
 */
266
int wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX* sha, const unsigned char* data)
267
0
{
268
0
    WOLFSSL_ENTER("SHA_Transform");
269
270
0
#if defined(LITTLE_ENDIAN_ORDER)
271
    /* Byte reversal done outside transform. */
272
0
    if ((sha != NULL) && (data != NULL)) {
273
0
        ByteReverseWords((word32*)data, (word32*)data, WC_SHA_BLOCK_SIZE);
274
0
    }
275
0
#endif
276
    /* Transform block of data with wolfCrypt SHA object. */
277
0
    return wc_ShaTransform((wc_Sha*)sha, data) == 0;
278
0
}
279
#endif
280
281
/* Initialize SHA-1 hash operation.
282
 *
283
 * @param [in, out] sha  SHA context object.
284
 * @return  1 on success.
285
 * @return  0 when sha is NULL.
286
 */
287
int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
288
0
{
289
0
    WOLFSSL_ENTER("SHA1_Init");
290
291
0
    return wolfSSL_SHA_Init(sha);
292
0
}
293
294
295
/* Update SHA-1 hash with data.
296
 *
297
 * @param [in, out] sha    SHA context object.
298
 * @param [in]      input  Data to be hashed.
299
 * @param [in]      sz     Length of data in bytes.
300
 * @return  1 on success.
301
 * @return  0 when sha is NULL.
302
 */
303
int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
304
    unsigned long sz)
305
0
{
306
0
    WOLFSSL_ENTER("SHA1_Update");
307
308
0
    return wolfSSL_SHA_Update(sha, input, sz);
309
0
}
310
311
/* Finalize SHA-1 hash and return output.
312
 *
313
 * @param [out]     output  Hash output.
314
 *                          Must be able to hold SHA_DIGEST_SIZE bytes.
315
 * @param [in, out] sha     SHA context object.
316
 * @return  1 on success.
317
 * @return  0 when sha or output is NULL.
318
 */
319
int wolfSSL_SHA1_Final(byte* output, WOLFSSL_SHA_CTX* sha)
320
0
{
321
0
    WOLFSSL_ENTER("SHA1_Final");
322
323
0
    return wolfSSL_SHA_Final(output, sha);
324
0
}
325
326
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
327
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
328
/* Apply SHA-1 transformation to the data.
329
 *
330
 * 'data' has words reversed in this function when little endian.
331
 *
332
 * @param [in, out] sha   SHA context object.
333
 * @param [in, out] data  One block of data to be hashed.
334
 * @return  1 on success.
335
 * @return  0 when sha or data is NULL.
336
 */
337
int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha, const unsigned char* data)
338
0
{
339
0
   WOLFSSL_ENTER("SHA1_Transform");
340
341
0
   return wolfSSL_SHA_Transform(sha, data);
342
0
}
343
#endif
344
#endif /* !NO_SHA */
345
346
#ifndef NO_SHA256
347
#ifdef WOLFSSL_SHA224
348
/* Initialize SHA-224 hash operation.
349
 *
350
 * @param [in, out] sha224  SHA-224 context object.
351
 * @return  1 on success.
352
 * @return  0 when sha224 is NULL.
353
 */
354
int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha224)
355
85
{
356
    /* Ensure WOLFSSL_SHA224_CTX is big enough for wolfCrypt wc_Sha224. */
357
85
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA224_CTX, wc_Sha224);
358
359
85
    WOLFSSL_ENTER("SHA224_Init");
360
361
    /* Initialize wolfCrypt SHA-224 object. */
362
85
    return wc_InitSha224((wc_Sha224*)sha224) == 0;
363
85
}
364
365
/* Update SHA-224 hash with data.
366
 *
367
 * @param [in, out] sha224  SHA-224 context object.
368
 * @param [in]      input   Data to be hashed.
369
 * @param [in]      sz      Length of data in bytes.
370
 * @return  1 on success.
371
 * @return  0 when sha224 is NULL.
372
 */
373
int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha224, const void* input,
374
    unsigned long sz)
375
497
{
376
497
    WOLFSSL_ENTER("SHA224_Update");
377
378
    /* Update wolfCrypt SHA-224 object with data. */
379
497
    return wc_Sha224Update((wc_Sha224*)sha224, (const byte*)input, (word32)sz)
380
497
        == 0;
381
497
}
382
383
/* Finalize SHA-224 hash and return output.
384
 *
385
 * @param [out]     output  Hash output.
386
 *                          Must be able to hold SHA224_DIGEST_SIZE bytes.
387
 * @param [in, out] sha224  SHA-224 context object.
388
 * @return  1 on success.
389
 * @return  0 when sha224 or output is NULL.
390
 */
391
int wolfSSL_SHA224_Final(byte* output, WOLFSSL_SHA224_CTX* sha224)
392
85
{
393
85
    int ret;
394
395
85
    WOLFSSL_ENTER("SHA224_Final");
396
397
    /* Finalize wolfCrypt SHA-224 hash into output. */
398
85
    ret = (wc_Sha224Final((wc_Sha224*)sha224, output) == 0);
399
    /* Free resources here, as OpenSSL API doesn't include SHA224_Free(). */
400
85
    wc_Sha224Free((wc_Sha224*)sha224);
401
402
85
    return ret;
403
85
}
404
405
#endif /* WOLFSSL_SHA224 */
406
407
/* Initialize SHA-256 hash operation.
408
 *
409
 * @param [in, out] sha256  SHA-256 context object.
410
 * @return  1 on success.
411
 * @return  0 when sha256 is NULL.
412
 */
413
int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
414
139
{
415
    /* Ensure WOLFSSL_SHA256_CTX is big enough for wolfCrypt wc_Sha256. */
416
139
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA256_CTX, wc_Sha256);
417
418
139
    WOLFSSL_ENTER("SHA256_Init");
419
420
    /* Initialize wolfCrypt SHA-256 object. */
421
139
    return wc_InitSha256((wc_Sha256*)sha256) == 0;
422
139
}
423
424
/* Update SHA-256 hash with data.
425
 *
426
 * @param [in, out] sha256  SHA-256 context object.
427
 * @param [in]      input   Data to be hashed.
428
 * @param [in]      sz      Length of data in bytes.
429
 * @return  1 on success.
430
 * @return  0 when sha256 is NULL.
431
 */
432
int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha256, const void* input,
433
    unsigned long sz)
434
2.92k
{
435
2.92k
    WOLFSSL_ENTER("SHA256_Update");
436
437
    /* Update wolfCrypt SHA-256 object with data. */
438
2.92k
    return wc_Sha256Update((wc_Sha256*)sha256, (const byte*)input, (word32)sz)
439
2.92k
        == 0;
440
2.92k
}
441
442
/* Finalize SHA-256 hash and return output.
443
 *
444
 * @param [out]     output  Hash output.
445
 *                          Must be able to hold SHA256_DIGEST_SIZE bytes.
446
 * @param [in, out] sha256  SHA-256 context object.
447
 * @return  1 on success.
448
 * @return  0 when sha256 or output is NULL.
449
 */
450
int wolfSSL_SHA256_Final(byte* output, WOLFSSL_SHA256_CTX* sha256)
451
139
{
452
139
    int ret;
453
454
139
    WOLFSSL_ENTER("SHA256_Final");
455
456
    /* Finalize wolfCrypt SHA-256 hash into output. */
457
139
    ret = (wc_Sha256Final((wc_Sha256*)sha256, output) == 0);
458
    /* Free resources here, as OpenSSL API doesn't include SHA256_Free(). */
459
139
    wc_Sha256Free((wc_Sha256*)sha256);
460
461
139
    return ret;
462
139
}
463
464
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
465
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
466
    !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH) && \
467
    !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */
468
/* Apply SHA-256 transformation to the data.
469
 *
470
 * 'data' has words reversed in this function when little endian.
471
 *
472
 * @param [in, out] sha256  SHA256 context object.
473
 * @param [in, out] data    One block of data to be hashed.
474
 * @return  1 on success.
475
 * @return  0 when sha256 or data is NULL.
476
 */
477
int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256,
478
    const unsigned char* data)
479
0
{
480
0
    WOLFSSL_ENTER("SHA256_Transform");
481
482
0
#if defined(LITTLE_ENDIAN_ORDER)
483
    /* Byte reversal done outside transform. */
484
0
    if ((sha256 != NULL) && (data != NULL)) {
485
0
        ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE);
486
0
    }
487
0
#endif
488
    /* Transform block of data with wolfCrypt SHA-256 object. */
489
0
    return wc_Sha256Transform((wc_Sha256*)sha256, data) == 0;
490
0
}
491
#endif
492
#endif /* !NO_SHA256 */
493
494
#ifdef WOLFSSL_SHA384
495
496
/* Initialize SHA-384 hash operation.
497
 *
498
 * @param [in, out] sha384  SHA-384 context object.
499
 * @return  1 on success.
500
 * @return  0 when sha384 is NULL.
501
 */
502
int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha384)
503
66
{
504
    /* Ensure WOLFSSL_SHA384_CTX is big enough for wolfCrypt wc_Sha384. */
505
66
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA384_CTX, wc_Sha384);
506
507
66
    WOLFSSL_ENTER("SHA384_Init");
508
509
    /* Initialize wolfCrypt SHA-384 object. */
510
66
    return wc_InitSha384((wc_Sha384*)sha384) == 0;
511
66
}
512
513
/* Update SHA-384 hash with data.
514
 *
515
 * @param [in, out] sha384  SHA-384 context object.
516
 * @param [in]      input   Data to be hashed.
517
 * @param [in]      sz      Length of data in bytes.
518
 * @return  1 on success.
519
 * @return  0 when sha384 is NULL.
520
 */
521
int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha384, const void* input,
522
    unsigned long sz)
523
1.49k
{
524
1.49k
    WOLFSSL_ENTER("SHA384_Update");
525
526
    /* Update wolfCrypt SHA-384 object with data. */
527
1.49k
    return wc_Sha384Update((wc_Sha384*)sha384, (const byte*)input, (word32)sz)
528
1.49k
        == 0;
529
1.49k
}
530
531
/* Finalize SHA-384 hash and return output.
532
 *
533
 * @param [out]     output  Hash output.
534
 *                          Must be able to hold SHA384_DIGEST_SIZE bytes.
535
 * @param [in, out] sha384  SHA-384 context object.
536
 * @return  1 on success.
537
 * @return  0 when sha384 or output is NULL.
538
 */
539
int wolfSSL_SHA384_Final(byte* output, WOLFSSL_SHA384_CTX* sha384)
540
66
{
541
66
    int ret;
542
543
66
    WOLFSSL_ENTER("SHA384_Final");
544
545
    /* Finalize wolfCrypt SHA-384 hash into output. */
546
66
    ret = (wc_Sha384Final((wc_Sha384*)sha384, output) == 0);
547
    /* Free resources here, as OpenSSL API doesn't include SHA384_Free(). */
548
66
    wc_Sha384Free((wc_Sha384*)sha384);
549
550
66
    return ret;
551
66
}
552
#endif /* WOLFSSL_SHA384 */
553
554
#ifdef WOLFSSL_SHA512
555
/* Initialize SHA-512 hash operation.
556
 *
557
 * @param [in, out] sha512  SHA-512 context object.
558
 * @return  1 on success.
559
 * @return  0 when sha512 is NULL.
560
 */
561
int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha512)
562
105
{
563
    /* Ensure WOLFSSL_SHA512_CTX is big enough for wolfCrypt wc_Sha512. */
564
105
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA512_CTX, wc_Sha512);
565
566
105
    WOLFSSL_ENTER("SHA512_Init");
567
568
    /* Initialize wolfCrypt SHA-512 object. */
569
105
    return wc_InitSha512((wc_Sha512*)sha512) == 0;
570
105
}
571
572
/* Update SHA-512 hash with data.
573
 *
574
 * @param [in, out] sha512  SHA-512 context object.
575
 * @param [in]      input   Data to be hashed.
576
 * @param [in]      sz      Length of data in bytes.
577
 * @return  1 on success.
578
 * @return  0 when sha512 is NULL.
579
 */
580
int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha512, const void* input,
581
    unsigned long sz)
582
3.62k
{
583
3.62k
    WOLFSSL_ENTER("SHA512_Update");
584
585
    /* Update wolfCrypt SHA-512 object with data. */
586
3.62k
    return wc_Sha512Update((wc_Sha512*)sha512, (const byte*)input, (word32)sz)
587
3.62k
        == 0;
588
3.62k
}
589
590
/* Finalize SHA-512 hash and return output.
591
 *
592
 * @param [out]     output  Hash output.
593
 *                          Must be able to hold SHA512_DIGEST_SIZE bytes.
594
 * @param [in, out] sha512  SHA-512 context object.
595
 * @return  1 on success.
596
 * @return  0 when sha512 or output is NULL.
597
 */
598
int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha512)
599
105
{
600
105
    int ret;
601
602
105
    WOLFSSL_ENTER("SHA512_Final");
603
604
    /* Finalize wolfCrypt SHA-512 hash into output. */
605
105
    ret = (wc_Sha512Final((wc_Sha512*)sha512, output) == 0);
606
    /* Free resources here, as OpenSSL API doesn't include SHA512_Free(). */
607
105
    wc_Sha512Free((wc_Sha512*)sha512);
608
609
105
    return ret;
610
105
}
611
612
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
613
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
614
    !defined(WOLFSSL_KCAPI_HASH) /* doesn't support direct transform */
615
/* Apply SHA-512 transformation to the data.
616
 *
617
 * @param [in, out] sha512  SHA512 context object.
618
 * @param [in]      data    One block of data to be hashed.
619
 * @return  1 on success.
620
 * @return  0 when sha512 or data is NULL.
621
 */
622
int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512,
623
    const unsigned char* data)
624
0
{
625
0
    WOLFSSL_ENTER("SHA512_Transform");
626
627
    /* Transform block of data with wolfCrypt SHA-512 object. */
628
0
    return wc_Sha512Transform((wc_Sha512*)sha512, data) == 0;
629
0
}
630
#endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
631
          (HAVE_FIPS_VERSION > 2)) && !WOLFSSL_KCAPI_HASH */
632
633
#if !defined(WOLFSSL_NOSHA512_224) && \
634
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
635
/* Initialize SHA-512-224 hash operation.
636
 *
637
 * @param [in, out] sha512  SHA-512-224 context object.
638
 * @return  1 on success.
639
 * @return  0 when sha512 is NULL.
640
 */
641
int wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX* sha512)
642
0
{
643
0
    WOLFSSL_ENTER("SHA512_224_Init");
644
645
    /* Initialize wolfCrypt SHA-512-224 object. */
646
0
    return wc_InitSha512_224((wc_Sha512*)sha512) == 0;
647
0
}
648
649
/* Update SHA-512-224 hash with data.
650
 *
651
 * @param [in, out] sha512  SHA-512-224 context object.
652
 * @param [in]      input   Data to be hashed.
653
 * @param [in]      sz      Length of data in bytes.
654
 * @return  1 on success.
655
 * @return  0 when sha512 is NULL.
656
 */
657
int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha512, const void* input,
658
    unsigned long sz)
659
0
{
660
0
    WOLFSSL_ENTER("SHA512_224_Update");
661
662
    /* Update wolfCrypt SHA-512-224 object with data. */
663
0
    return wc_Sha512_224Update((wc_Sha512*)sha512, (const byte*)input,
664
0
        (word32)sz) == 0;
665
0
}
666
667
/* Finalize SHA-512-224 hash and return output.
668
 *
669
 * @param [out]     output  Hash output.
670
 *                          Must be able to hold SHA224_DIGEST_SIZE bytes.
671
 * @param [in, out] sha512  SHA-512-224 context object.
672
 * @return  1 on success.
673
 * @return  0 when sha512 or output is NULL.
674
 */
675
int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha512)
676
0
{
677
0
    int ret;
678
679
0
    WOLFSSL_ENTER("SHA512_224_Final");
680
681
    /* Finalize wolfCrypt SHA-512-224 hash into output. */
682
0
    ret = (wc_Sha512_224Final((wc_Sha512*)sha512, output) == 0);
683
    /* Free resources here, as OpenSSL API doesn't include SHA512_224_Free(). */
684
0
    wc_Sha512_224Free((wc_Sha512*)sha512);
685
686
0
    return ret;
687
0
}
688
689
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
690
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
691
/* Apply SHA-512-224 transformation to the data.
692
 *
693
 * @param [in, out] sha512  SHA512 context object.
694
 * @param [in]      data    One block of data to be hashed.
695
 * @return  1 on success.
696
 * @return  0 when sha512 or data is NULL.
697
 */
698
int wolfSSL_SHA512_224_Transform(WOLFSSL_SHA512_CTX* sha512,
699
    const unsigned char* data)
700
0
{
701
0
    WOLFSSL_ENTER("SHA512_224_Transform");
702
703
    /* Transform block of data with wolfCrypt SHA-512-224 object. */
704
0
    return wc_Sha512_224Transform((wc_Sha512*)sha512, data) == 0;
705
0
}
706
#endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
707
          (HAVE_FIPS_VERSION > 2)) */
708
709
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
710
711
#if !defined(WOLFSSL_NOSHA512_256) && \
712
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
713
/* Initialize SHA-512-256 hash operation.
714
 *
715
 * @param [in, out] sha512  SHA-512-256 context object.
716
 * @return  1 on success.
717
 * @return  0 when sha512 is NULL.
718
 */
719
int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX* sha)
720
0
{
721
0
    WOLFSSL_ENTER("SHA512_256_Init");
722
723
    /* Initialize wolfCrypt SHA-512-256 object. */
724
0
    return wc_InitSha512_256((wc_Sha512*)sha) == 0;
725
0
}
726
727
/* Update SHA-512-256 hash with data.
728
 *
729
 * @param [in, out] sha512  SHA-512-256 context object.
730
 * @param [in]      input   Data to be hashed.
731
 * @param [in]      sz      Length of data in bytes.
732
 * @return  1 on success.
733
 * @return  0 when sha512 is NULL.
734
 */
735
int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha512, const void* input,
736
    unsigned long sz)
737
0
{
738
0
    WOLFSSL_ENTER("SHA512_256_Update");
739
740
    /* Update wolfCrypt SHA-512-256 object with data. */
741
0
    return wc_Sha512_256Update((wc_Sha512*)sha512, (const byte*)input,
742
0
        (word32)sz) == 0;
743
0
}
744
745
/* Finalize SHA-512-256 hash and return output.
746
 *
747
 * @param [out]     output  Hash output.
748
 *                          Must be able to hold SHA256_DIGEST_SIZE bytes.
749
 * @param [in, out] sha512  SHA-512-256 context object.
750
 * @return  1 on success.
751
 * @return  0 when sha512 or output is NULL.
752
 */
753
int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha512)
754
0
{
755
0
    int ret;
756
757
0
    WOLFSSL_ENTER("SHA512_256_Final");
758
759
    /* Finalize wolfCrypt SHA-512-256 hash into output. */
760
0
    ret = (wc_Sha512_256Final((wc_Sha512*)sha512, output) == 0);
761
    /* Free resources here, as OpenSSL API doesn't include SHA512_256_Free(). */
762
0
    wc_Sha512_224Free((wc_Sha512*)sha512);
763
764
0
    return ret;
765
0
}
766
767
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
768
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
769
/* Apply SHA-512-256 transformation to the data.
770
 *
771
 * @param [in, out] sha512  SHA512 context object.
772
 * @param [in]      data    One block of data to be hashed.
773
 * @return  1 on success.
774
 * @return  0 when sha512 or data is NULL.
775
 */
776
int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512,
777
    const unsigned char* data)
778
0
{
779
0
    WOLFSSL_ENTER("SHA512_256_Transform");
780
781
    /* Transform block of data with wolfCrypt SHA-512-256 object. */
782
0
    return wc_Sha512_256Transform((wc_Sha512*)sha512, data) == 0;
783
0
}
784
#endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
785
          (HAVE_FIPS_VERSION > 2)) */
786
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS ... */
787
#endif /* WOLFSSL_SHA512 */
788
789
#ifdef WOLFSSL_SHA3
790
#ifndef WOLFSSL_NOSHA3_224
791
/* Initialize SHA3-224 hash operation.
792
 *
793
 * @param [in, out] sha3_224  SHA3-224 context object.
794
 * @return  1 on success.
795
 * @return  0 when sha3_224 is NULL.
796
 */
797
int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha3_224)
798
0
{
799
    /* Ensure WOLFSSL_SHA3_224_CTX is big enough for wolfCrypt wc_Sha3. */
800
0
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA3_224_CTX, wc_Sha3);
801
802
0
    WOLFSSL_ENTER("SHA3_224_Init");
803
804
    /* Initialize wolfCrypt SHA3-224 object. */
805
0
    return wc_InitSha3_224((wc_Sha3*)sha3_224, NULL, INVALID_DEVID) == 0;
806
0
}
807
808
/* Update SHA3-224 hash with data.
809
 *
810
 * @param [in, out] sha3   SHA3-224 context object.
811
 * @param [in]      input  Data to be hashed.
812
 * @param [in]      sz     Length of data in bytes.
813
 * @return  1 on success.
814
 * @return  0 when sha3 is NULL.
815
 */
816
int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha3, const void* input,
817
    unsigned long sz)
818
0
{
819
0
    WOLFSSL_ENTER("SHA3_224_Update");
820
821
    /* Update wolfCrypt SHA3-224 object with data. */
822
0
    return wc_Sha3_224_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz)
823
0
        == 0;
824
0
}
825
826
/* Finalize SHA3-224 hash and return output.
827
 *
828
 * @param [out]     output  Hash output.
829
 *                          Must be able to hold SHA3_224_DIGEST_SIZE bytes.
830
 * @param [in, out] sha3    SHA3-224 context object.
831
 * @return  1 on success.
832
 * @return  0 when sha3 or output is NULL.
833
 */
834
int wolfSSL_SHA3_224_Final(byte* output, WOLFSSL_SHA3_224_CTX* sha3)
835
0
{
836
0
    int ret;
837
838
0
    WOLFSSL_ENTER("SHA3_224_Final");
839
840
    /* Finalize wolfCrypt SHA3-224 hash into output. */
841
0
    ret = (wc_Sha3_224_Final((wc_Sha3*)sha3, output) == 0);
842
    /* Free resources here, as OpenSSL API doesn't include SHA3_224_Free(). */
843
0
    wc_Sha3_224_Free((wc_Sha3*)sha3);
844
845
0
    return ret;
846
0
}
847
#endif /* WOLFSSL_NOSHA3_224 */
848
849
#ifndef WOLFSSL_NOSHA3_256
850
/* Initialize SHA3-256 hash operation.
851
 *
852
 * @param [in, out] sha3_256  SHA3-256 context object.
853
 * @return  1 on success.
854
 * @return  0 when sha3_256 is NULL.
855
 */
856
int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256)
857
0
{
858
    /* Ensure WOLFSSL_SHA3_256_CTX is big enough for wolfCrypt wc_Sha3. */
859
0
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA3_256_CTX, wc_Sha3);
860
861
0
    WOLFSSL_ENTER("SHA3_256_Init");
862
863
    /* Initialize wolfCrypt SHA3-256 object. */
864
0
    return wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, INVALID_DEVID) == 0;
865
0
}
866
867
/* Update SHA3-256 hash with data.
868
 *
869
 * @param [in, out] sha3   SHA3-256 context object.
870
 * @param [in]      input  Data to be hashed.
871
 * @param [in]      sz     Length of data in bytes.
872
 * @return  1 on success.
873
 * @return  0 when sha3 is NULL.
874
 */
875
int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha3, const void* input,
876
    unsigned long sz)
877
0
{
878
0
    WOLFSSL_ENTER("SHA3_256_Update");
879
880
    /* Update wolfCrypt SHA3-256 object with data. */
881
0
    return wc_Sha3_256_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz)
882
0
        == 0;
883
0
}
884
885
/* Finalize SHA3-256 hash and return output.
886
 *
887
 * @param [out]     output  Hash output.
888
 *                          Must be able to hold SHA3_256_DIGEST_SIZE bytes.
889
 * @param [in, out] sha3    SHA3-256 context object.
890
 * @return  1 on success.
891
 * @return  0 when sha3 or output is NULL.
892
 */
893
int wolfSSL_SHA3_256_Final(byte* output, WOLFSSL_SHA3_256_CTX* sha3)
894
0
{
895
0
    int ret;
896
897
0
    WOLFSSL_ENTER("SHA3_256_Final");
898
899
    /* Finalize wolfCrypt SHA3-256 hash into output. */
900
0
    ret = (wc_Sha3_256_Final((wc_Sha3*)sha3, output) == 0);
901
    /* Free resources here, as OpenSSL API doesn't include SHA3_256_Free(). */
902
0
    wc_Sha3_256_Free((wc_Sha3*)sha3);
903
904
0
    return ret;
905
0
}
906
#endif /* WOLFSSL_NOSHA3_256 */
907
908
#ifndef WOLFSSL_NOSHA3_384
909
/* Initialize SHA3-384 hash operation.
910
 *
911
 * @param [in, out] sha3_384  SHA3-384 context object.
912
 * @return  1 on success.
913
 * @return  0 when sha3_384 is NULL.
914
 */
915
int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha3_384)
916
0
{
917
    /* Ensure WOLFSSL_SHA3_384_CTX is big enough for wolfCrypt wc_Sha3. */
918
0
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA3_384_CTX, wc_Sha3);
919
920
0
    WOLFSSL_ENTER("SHA3_384_Init");
921
922
    /* Initialize wolfCrypt SHA3-384 object. */
923
0
    return wc_InitSha3_384((wc_Sha3*)sha3_384, NULL, INVALID_DEVID) == 0;
924
0
}
925
926
/* Update SHA3-384 hash with data.
927
 *
928
 * @param [in, out] sha3   SHA3-384 context object.
929
 * @param [in]      input  Data to be hashed.
930
 * @param [in]      sz     Length of data in bytes.
931
 * @return  1 on success.
932
 * @return  0 when sha3 is NULL.
933
 */
934
int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha3, const void* input,
935
    unsigned long sz)
936
0
{
937
0
    WOLFSSL_ENTER("SHA3_384_Update");
938
939
    /* Update wolfCrypt SHA3-384 object with data. */
940
0
    return wc_Sha3_384_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz)
941
0
        == 0;
942
0
}
943
944
/* Finalize SHA3-384 hash and return output.
945
 *
946
 * @param [out]     output  Hash output.
947
 *                          Must be able to hold SHA3_384_DIGEST_SIZE bytes.
948
 * @param [in, out] sha3    SHA3-384 context object.
949
 * @return  1 on success.
950
 * @return  0 when sha3 or output is NULL.
951
 */
952
int wolfSSL_SHA3_384_Final(byte* output, WOLFSSL_SHA3_384_CTX* sha3)
953
0
{
954
0
    int ret;
955
956
0
    WOLFSSL_ENTER("SHA3_384_Final");
957
958
    /* Finalize wolfCrypt SHA3-384 hash into output. */
959
0
    ret = (wc_Sha3_384_Final((wc_Sha3*)sha3, output) == 0);
960
    /* Free resources here, as OpenSSL API doesn't include SHA3_384_Free(). */
961
0
    wc_Sha3_384_Free((wc_Sha3*)sha3);
962
963
0
    return ret;
964
0
}
965
#endif /* WOLFSSL_NOSHA3_384 */
966
967
#ifndef WOLFSSL_NOSHA3_512
968
/* Initialize SHA3-512 hash operation.
969
 *
970
 * @param [in, out] sha3_512  SHA3-512 context object.
971
 * @return  1 on success.
972
 * @return  0 when sha3_512 is NULL.
973
 */
974
int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha3_512)
975
0
{
976
    /* Ensure WOLFSSL_SHA3_512_CTX is big enough for wolfCrypt wc_Sha3. */
977
0
    WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA3_512_CTX, wc_Sha3);
978
979
0
    WOLFSSL_ENTER("SHA3_512_Init");
980
981
    /* Initialize wolfCrypt SHA3-512 object. */
982
0
    return wc_InitSha3_512((wc_Sha3*)sha3_512, NULL, INVALID_DEVID) == 0;
983
0
}
984
985
/* Update SHA3-512 hash with data.
986
 *
987
 * @param [in, out] sha3   SHA3-512 context object.
988
 * @param [in]      input  Data to be hashed.
989
 * @param [in]      sz     Length of data in bytes.
990
 * @return  1 on success.
991
 * @return  0 when sha3 is NULL.
992
 */
993
int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha3, const void* input,
994
    unsigned long sz)
995
0
{
996
0
    WOLFSSL_ENTER("SHA3_512_Update");
997
998
    /* Update wolfCrypt SHA3-512 object with data. */
999
0
    return wc_Sha3_512_Update((wc_Sha3*)sha3, (const byte*)input, (word32)sz)
1000
0
        == 0;
1001
0
}
1002
1003
/* Finalize SHA3-512 hash and return output.
1004
 *
1005
 * @param [out]     output  Hash output.
1006
 *                          Must be able to hold SHA3_512_DIGEST_SIZE bytes.
1007
 * @param [in, out] sha3    SHA3-512 context object.
1008
 * @return  1 on success.
1009
 * @return  0 when sha3 or output is NULL.
1010
 */
1011
int wolfSSL_SHA3_512_Final(byte* output, WOLFSSL_SHA3_512_CTX* sha3)
1012
0
{
1013
0
    int ret;
1014
1015
0
    WOLFSSL_ENTER("SHA3_512_Final");
1016
1017
    /* Finalize wolfCrypt SHA3-512 hash into output. */
1018
0
    ret = (wc_Sha3_512_Final((wc_Sha3*)sha3, output) == 0);
1019
    /* Free resources here, as OpenSSL API doesn't include SHA3_512_Free(). */
1020
0
    wc_Sha3_512_Free((wc_Sha3*)sha3);
1021
1022
0
    return ret;
1023
0
}
1024
#endif /* WOLFSSL_NOSHA3_512 */
1025
#endif /* WOLFSSL_SHA3 */
1026
#endif /* OPENSSL_EXTRA || HAVE_CURL */
1027
1028
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
1029
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
1030
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
1031
    defined(WOLFSSL_HAPROXY)
1032
1033
#ifndef NO_SHA
1034
/* One shot SHA1 hash of data.
1035
 *
1036
 * When hash is null, a static buffer of SHA_DIGEST_SIZE is used.
1037
 * When the static buffer is used this function is not thread safe.
1038
 *
1039
 * @param [in]  data  Data to hash.
1040
 * @param [in]  len   Size of data in bytes.
1041
 * @param [out] hash  Buffer to hold digest. May be NULL.
1042
 *                    Must be able to hold SHA_DIGEST_SIZE bytes.
1043
 * @return  Buffer holding hash on success.
1044
 * @return  NULL when hashing fails.
1045
 */
1046
unsigned char* wolfSSL_SHA1(const unsigned char* data, size_t len,
1047
    unsigned char* hash)
1048
0
{
1049
    /* Buffer to use when hash is NULL. */
1050
0
    static byte dgst[WC_SHA_DIGEST_SIZE];
1051
0
    WC_DECLARE_VAR(sha, wc_Sha, 1, 0);
1052
0
    int ret = 0;
1053
1054
0
    WOLFSSL_ENTER("wolfSSL_SHA1");
1055
1056
    /* Use static buffer if none passed in. */
1057
0
    if (hash == NULL) {
1058
0
        WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA1 IS NOT "
1059
0
                    "THREAD SAFE WHEN hash == NULL");
1060
0
        hash = dgst;
1061
0
    }
1062
1063
    /* Allocate dynamic memory for a wolfSSL SHA object. */
1064
0
    WC_ALLOC_VAR_EX(sha, wc_Sha, 1, NULL, DYNAMIC_TYPE_DIGEST,
1065
0
        ret=MEMORY_E);
1066
1067
0
    if (ret == 0) {
1068
        /* Initialize wolfCrypt SHA object. */
1069
0
        ret = wc_InitSha_ex(sha, NULL, INVALID_DEVID);
1070
0
        if (ret != 0) {
1071
0
            WOLFSSL_MSG("SHA1 Init failed");
1072
0
            hash = NULL;
1073
0
        }
1074
0
    }
1075
0
    if (ret == 0) {
1076
        /* Update wolfCrypt SHA object with data. */
1077
0
        ret = wc_ShaUpdate(sha, (const byte*)data, (word32)len);
1078
0
        if (ret != 0) {
1079
0
            WOLFSSL_MSG("SHA1 Update failed");
1080
0
            hash = NULL;
1081
0
        }
1082
1083
0
        if (ret == 0) {
1084
            /* Finalize wolfCrypt SHA hash into hash. */
1085
0
            ret = wc_ShaFinal(sha, hash);
1086
0
            if (ret != 0) {
1087
0
                WOLFSSL_MSG("SHA1 Final failed");
1088
0
                hash = NULL;
1089
0
            }
1090
0
        }
1091
        /* Dispose of dynamic memory associated with SHA object. */
1092
0
        wc_ShaFree(sha);
1093
0
    }
1094
1095
0
    WC_FREE_VAR_EX(sha, NULL, DYNAMIC_TYPE_DIGEST);
1096
0
    return hash;
1097
0
}
1098
#endif /* ! NO_SHA */
1099
1100
#ifdef WOLFSSL_SHA224
1101
/* One shot SHA-224 hash of data.
1102
 *
1103
 * When hash is null, a static buffer of SHA224_DIGEST_SIZE is used.
1104
 * When the static buffer is used this function is not thread safe.
1105
 *
1106
 * @param [in]  data  Data to hash.
1107
 * @param [in]  len   Size of data in bytes.
1108
 * @param [out] hash  Buffer to hold digest. May be NULL.
1109
 *                    Must be able to hold SHA224_DIGEST_SIZE bytes.
1110
 * @return  Buffer holding hash on success.
1111
 * @return  NULL when hashing fails.
1112
 */
1113
unsigned char* wolfSSL_SHA224(const unsigned char* data, size_t len,
1114
    unsigned char* hash)
1115
0
{
1116
    /* Buffer to use when hash is NULL. */
1117
0
    static byte dgst[WC_SHA224_DIGEST_SIZE];
1118
0
    WC_DECLARE_VAR(sha224, wc_Sha224, 1, 0);
1119
0
    int ret = 0;
1120
1121
0
    WOLFSSL_ENTER("wolfSSL_SHA224");
1122
1123
    /* Use static buffer if none passed in. */
1124
0
    if (hash == NULL) {
1125
0
        WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA224 IS NOT "
1126
0
                    "THREAD SAFE WHEN hash == NULL");
1127
0
        hash = dgst;
1128
0
    }
1129
1130
    /* Allocate dynamic memory for a wolfSSL SHA-224 object. */
1131
0
    WC_ALLOC_VAR_EX(sha224, wc_Sha224, 1, NULL, DYNAMIC_TYPE_DIGEST,
1132
0
        ret=MEMORY_E);
1133
1134
0
    if (ret == 0) {
1135
        /* Initialize wolfCrypt SHA224 object. */
1136
0
        ret = wc_InitSha224_ex(sha224, NULL, INVALID_DEVID);
1137
0
        if (ret != 0) {
1138
0
            WOLFSSL_MSG("SHA224 Init failed");
1139
0
            hash = NULL;
1140
0
        }
1141
0
    }
1142
0
    if (ret == 0) {
1143
        /* Update wolfCrypt SHA-224 object with data. */
1144
0
        ret = wc_Sha224Update(sha224, (const byte*)data, (word32)len);
1145
0
        if (ret != 0) {
1146
0
            WOLFSSL_MSG("SHA224 Update failed");
1147
0
            hash = NULL;
1148
0
        }
1149
1150
0
        if (ret == 0) {
1151
            /* Finalize wolfCrypt SHA-224 hash into hash. */
1152
0
            ret = wc_Sha224Final(sha224, hash);
1153
0
            if (ret != 0) {
1154
0
                WOLFSSL_MSG("SHA224 Final failed");
1155
0
                hash = NULL;
1156
0
            }
1157
0
        }
1158
        /* Dispose of dynamic memory associated with SHA-224 object. */
1159
0
        wc_Sha224Free(sha224);
1160
0
    }
1161
1162
0
    WC_FREE_VAR_EX(sha224, NULL, DYNAMIC_TYPE_DIGEST);
1163
0
    return hash;
1164
0
}
1165
#endif
1166
1167
#ifndef NO_SHA256
1168
/* One shot SHA-256 hash of data.
1169
 *
1170
 * When hash is null, a static buffer of SHA256_DIGEST_SIZE is used.
1171
 * When the static buffer is used this function is not thread safe.
1172
 *
1173
 * @param [in]  data  Data to hash.
1174
 * @param [in]  len   Size of data in bytes.
1175
 * @param [out] hash  Buffer to hold digest. May be NULL.
1176
 *                    Must be able to hold SHA256_DIGEST_SIZE bytes.
1177
 * @return  Buffer holding hash on success.
1178
 * @return  NULL when hashing fails.
1179
 */
1180
unsigned char* wolfSSL_SHA256(const unsigned char* data, size_t len,
1181
    unsigned char* hash)
1182
52
{
1183
    /* Buffer to use when hash is NULL. */
1184
52
    static byte dgst[WC_SHA256_DIGEST_SIZE];
1185
52
    WC_DECLARE_VAR(sha256, wc_Sha256, 1, 0);
1186
52
    int ret = 0;
1187
1188
52
    WOLFSSL_ENTER("wolfSSL_SHA256");
1189
1190
    /* Use static buffer if none passed in. */
1191
52
    if (hash == NULL) {
1192
0
        WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA256 IS NOT "
1193
0
                    "THREAD SAFE WHEN hash == NULL");
1194
0
        hash = dgst;
1195
0
    }
1196
1197
    /* Allocate dynamic memory for a wolfSSL SHA-256 object. */
1198
52
    WC_ALLOC_VAR_EX(sha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_DIGEST,
1199
52
        ret=MEMORY_E);
1200
1201
52
    if (ret == 0) {
1202
        /* Initialize wolfCrypt SHA256 object. */
1203
52
        ret = wc_InitSha256_ex(sha256, NULL, INVALID_DEVID);
1204
52
        if (ret != 0) {
1205
0
            WOLFSSL_MSG("SHA256 Init failed");
1206
0
            hash = NULL;
1207
0
        }
1208
52
    }
1209
52
    if (ret == 0) {
1210
        /* Update wolfCrypt SHA-256 object with data. */
1211
52
        ret = wc_Sha256Update(sha256, (const byte*)data, (word32)len);
1212
52
        if (ret != 0) {
1213
0
            WOLFSSL_MSG("SHA256 Update failed");
1214
0
            hash = NULL;
1215
0
        }
1216
1217
52
        if (ret == 0) {
1218
            /* Finalize wolfCrypt SHA-256 hash into hash. */
1219
52
            ret = wc_Sha256Final(sha256, hash);
1220
52
            if (ret != 0) {
1221
0
                WOLFSSL_MSG("SHA256 Final failed");
1222
0
                hash = NULL;
1223
0
            }
1224
52
        }
1225
        /* Dispose of dynamic memory associated with SHA-256 object. */
1226
52
        wc_Sha256Free(sha256);
1227
52
    }
1228
1229
52
    WC_FREE_VAR_EX(sha256, NULL, DYNAMIC_TYPE_DIGEST);
1230
52
    return hash;
1231
52
}
1232
#endif /* ! NO_SHA256 */
1233
1234
#ifdef WOLFSSL_SHA384
1235
/* One shot SHA-384 hash of data.
1236
 *
1237
 * When hash is null, a static buffer of SHA384_DIGEST_SIZE is used.
1238
 * When the static buffer is used this function is not thread safe.
1239
 *
1240
 * @param [in]  data  Data to hash.
1241
 * @param [in]  len   Size of data in bytes.
1242
 * @param [out] hash  Buffer to hold digest. May be NULL.
1243
 *                    Must be able to hold SHA384_DIGEST_SIZE bytes.
1244
 * @return  Buffer holding hash on success.
1245
 * @return  NULL when hashing fails.
1246
 */
1247
unsigned char* wolfSSL_SHA384(const unsigned char* data, size_t len,
1248
    unsigned char* hash)
1249
0
{
1250
    /* Buffer to use when hash is NULL. */
1251
0
    static byte dgst[WC_SHA384_DIGEST_SIZE];
1252
0
    WC_DECLARE_VAR(sha384, wc_Sha384, 1, 0);
1253
0
    int ret = 0;
1254
1255
0
    WOLFSSL_ENTER("wolfSSL_SHA384");
1256
1257
    /* Use static buffer if none passed in. */
1258
0
    if (hash == NULL) {
1259
0
        WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA384 IS NOT "
1260
0
                    "THREAD SAFE WHEN hash == NULL");
1261
0
        hash = dgst;
1262
0
    }
1263
1264
    /* Allocate dynamic memory for a wolfSSL SHA-384 object. */
1265
0
    WC_ALLOC_VAR_EX(sha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_DIGEST,
1266
0
        ret=MEMORY_E);
1267
1268
0
    if (ret == 0) {
1269
        /* Initialize wolfCrypt SHA384 object. */
1270
0
        ret = wc_InitSha384_ex(sha384, NULL, INVALID_DEVID);
1271
0
        if (ret != 0) {
1272
0
            WOLFSSL_MSG("SHA384 Init failed");
1273
0
            hash = NULL;
1274
0
        }
1275
0
    }
1276
0
    if (ret == 0) {
1277
        /* Update wolfCrypt SHA-384 object with data. */
1278
0
        ret = wc_Sha384Update(sha384, (const byte*)data, (word32)len);
1279
0
        if (ret != 0) {
1280
0
            WOLFSSL_MSG("SHA384 Update failed");
1281
0
            hash = NULL;
1282
0
        }
1283
1284
0
        if (ret == 0) {
1285
            /* Finalize wolfCrypt SHA-384 hash into hash. */
1286
0
            ret = wc_Sha384Final(sha384, hash);
1287
0
            if (ret != 0) {
1288
0
                WOLFSSL_MSG("SHA384 Final failed");
1289
0
                hash = NULL;
1290
0
            }
1291
0
        }
1292
        /* Dispose of dynamic memory associated with SHA-384 object. */
1293
0
        wc_Sha384Free(sha384);
1294
0
    }
1295
1296
0
    WC_FREE_VAR_EX(sha384, NULL, DYNAMIC_TYPE_DIGEST);
1297
0
    return hash;
1298
0
}
1299
#endif /* WOLFSSL_SHA384  */
1300
1301
#if defined(WOLFSSL_SHA512)
1302
/* One shot SHA-512 hash of data.
1303
 *
1304
 * When hash is null, a static buffer of SHA512_DIGEST_SIZE is used.
1305
 * When the static buffer is used this function is not thread safe.
1306
 *
1307
 * @param [in]  data  Data to hash.
1308
 * @param [in]  len   Size of data in bytes.
1309
 * @param [out] hash  Buffer to hold digest. May be NULL.
1310
 *                    Must be able to hold SHA512_DIGEST_SIZE bytes.
1311
 * @return  Buffer holding hash on success.
1312
 * @return  NULL when hashing fails.
1313
 */
1314
unsigned char* wolfSSL_SHA512(const unsigned char* data, size_t len,
1315
    unsigned char* hash)
1316
0
{
1317
    /* Buffer to use when hash is NULL. */
1318
0
    static byte dgst[WC_SHA512_DIGEST_SIZE];
1319
0
    WC_DECLARE_VAR(sha512, wc_Sha512, 1, 0);
1320
0
    int ret = 0;
1321
1322
0
    WOLFSSL_ENTER("wolfSSL_SHA512");
1323
1324
    /* Use static buffer if none passed in. */
1325
0
    if (hash == NULL) {
1326
0
        WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA512 IS NOT "
1327
0
                    "THREAD SAFE WHEN hash == NULL");
1328
0
        hash = dgst;
1329
0
    }
1330
1331
    /* Allocate dynamic memory for a wolfSSL SHA-512 object. */
1332
0
    WC_ALLOC_VAR_EX(sha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_DIGEST,
1333
0
        ret=MEMORY_E);
1334
1335
0
    if (ret == 0) {
1336
        /* Initialize wolfCrypt SHA512 object. */
1337
0
        ret = wc_InitSha512_ex(sha512, NULL, INVALID_DEVID);
1338
0
        if (ret != 0) {
1339
0
            WOLFSSL_MSG("SHA512 Init failed");
1340
0
            hash = NULL;
1341
0
        }
1342
0
    }
1343
0
    if (ret == 0) {
1344
        /* Update wolfCrypt SHA-512 object with data. */
1345
0
        ret = wc_Sha512Update(sha512, (const byte*)data, (word32)len);
1346
0
        if (ret != 0) {
1347
0
            WOLFSSL_MSG("SHA512 Update failed");
1348
0
            hash = NULL;
1349
0
        }
1350
1351
0
        if (ret == 0) {
1352
            /* Finalize wolfCrypt SHA-512 hash into hash. */
1353
0
            ret = wc_Sha512Final(sha512, hash);
1354
0
            if (ret != 0) {
1355
0
                WOLFSSL_MSG("SHA512 Final failed");
1356
0
                hash = NULL;
1357
0
            }
1358
0
        }
1359
        /* Dispose of dynamic memory associated with SHA-512 object. */
1360
0
        wc_Sha512Free(sha512);
1361
0
    }
1362
1363
0
    WC_FREE_VAR_EX(sha512, NULL, DYNAMIC_TYPE_DIGEST);
1364
0
    return hash;
1365
0
}
1366
#endif /* WOLFSSL_SHA512 */
1367
#endif /* OPENSSL_EXTRA || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
1368
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
1369
1370
/*******************************************************************************
1371
 * END OF Digest APIs
1372
 ******************************************************************************/
1373
1374
/*******************************************************************************
1375
 * START OF HMAC API
1376
 ******************************************************************************/
1377
1378
/* _Internal Hmac object initialization. */
1379
0
#define _HMAC_Init _InitHmac
1380
1381
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
1382
1383
/*
1384
 * Helper Functions
1385
 */
1386
1387
/* Copy a wolfSSL HMAC object.
1388
 *
1389
 * Requires that hash structures have no dynamic parts to them.
1390
 *
1391
 * @param [out] dst  Copy into this object.
1392
 * @param [in]  src  Copy from this object.
1393
 * @return  1 on success.
1394
 * @return  0 on failure.
1395
 */
1396
int wolfSSL_HmacCopy(Hmac* dst, Hmac* src)
1397
336
{
1398
336
    void* heap;
1399
336
    int ret = 1;
1400
1401
336
#ifndef HAVE_FIPS
1402
336
    heap = src->heap;
1403
#else
1404
    heap = NULL;
1405
#endif
1406
1407
    /* Initialize the destination object to reset state. */
1408
336
    if (wc_HmacInit(dst, heap, 0) != 0) {
1409
0
        ret = 0;
1410
0
    }
1411
1412
336
    if (ret == 1) {
1413
336
        int rc;
1414
1415
        /* Copy the digest object based on the MAC type. */
1416
336
        switch (src->macType) {
1417
0
    #ifndef NO_MD5
1418
29
        case WC_MD5:
1419
29
            rc = wc_Md5Copy(&src->hash.md5, &dst->hash.md5);
1420
        #ifdef WOLFSSL_HMAC_COPY_HASH
1421
            if (rc == 0) {
1422
                rc = wc_Md5Copy(&src->i_hash.md5, &dst->i_hash.md5);
1423
            }
1424
            if (rc == 0) {
1425
                rc = wc_Md5Copy(&src->o_hash.md5, &dst->o_hash.md5);
1426
            }
1427
        #endif
1428
29
            break;
1429
0
    #endif /* !NO_MD5 */
1430
1431
0
    #ifndef NO_SHA
1432
47
        case WC_SHA:
1433
47
            rc = wc_ShaCopy(&src->hash.sha, &dst->hash.sha);
1434
        #ifdef WOLFSSL_HMAC_COPY_HASH
1435
            if (rc == 0) {
1436
                rc = wc_ShaCopy(&src->i_hash.sha, &dst->i_hash.sha);
1437
            }
1438
            if (rc == 0) {
1439
                rc = wc_ShaCopy(&src->o_hash.sha, &dst->o_hash.sha);
1440
            }
1441
        #endif
1442
47
            break;
1443
0
    #endif /* !NO_SHA */
1444
1445
0
    #ifdef WOLFSSL_SHA224
1446
51
        case WC_SHA224:
1447
51
            rc = wc_Sha224Copy(&src->hash.sha224, &dst->hash.sha224);
1448
        #ifdef WOLFSSL_HMAC_COPY_HASH
1449
            if (rc == 0) {
1450
                rc = wc_Sha224Copy(&src->i_hash.sha224, &dst->i_hash.sha224);
1451
            }
1452
            if (rc == 0) {
1453
                rc = wc_Sha224Copy(&src->o_hash.sha224, &dst->o_hash.sha224);
1454
            }
1455
        #endif
1456
51
            break;
1457
0
    #endif /* WOLFSSL_SHA224 */
1458
1459
0
    #ifndef NO_SHA256
1460
47
        case WC_SHA256:
1461
47
            rc = wc_Sha256Copy(&src->hash.sha256, &dst->hash.sha256);
1462
        #ifdef WOLFSSL_HMAC_COPY_HASH
1463
            if (rc == 0) {
1464
                rc = wc_Sha256Copy(&src->i_hash.sha256, &dst->i_hash.sha256);
1465
            }
1466
            if (rc == 0) {
1467
                rc = wc_Sha256Copy(&src->o_hash.sha256, &dst->o_hash.sha256);
1468
            }
1469
        #endif
1470
47
            break;
1471
0
    #endif /* !NO_SHA256 */
1472
1473
0
    #ifdef WOLFSSL_SHA384
1474
17
        case WC_SHA384:
1475
17
            rc = wc_Sha384Copy(&src->hash.sha384, &dst->hash.sha384);
1476
        #ifdef WOLFSSL_HMAC_COPY_HASH
1477
            if (rc == 0) {
1478
                rc = wc_Sha384Copy(&src->i_hash.sha384, &dst->i_hash.sha384);
1479
            }
1480
            if (rc == 0) {
1481
                rc = wc_Sha384Copy(&src->o_hash.sha384, &dst->o_hash.sha384);
1482
            }
1483
        #endif
1484
17
            break;
1485
0
    #endif /* WOLFSSL_SHA384 */
1486
0
    #ifdef WOLFSSL_SHA512
1487
145
        case WC_SHA512:
1488
145
            rc = wc_Sha512Copy(&src->hash.sha512, &dst->hash.sha512);
1489
        #ifdef WOLFSSL_HMAC_COPY_HASH
1490
            if (rc == 0) {
1491
                rc = wc_Sha512Copy(&src->i_hash.sha512, &dst->i_hash.sha512);
1492
            }
1493
            if (rc == 0) {
1494
                rc = wc_Sha512Copy(&src->o_hash.sha512, &dst->o_hash.sha512);
1495
            }
1496
        #endif
1497
145
            break;
1498
0
    #endif /* WOLFSSL_SHA512 */
1499
0
#ifdef WOLFSSL_SHA3
1500
0
    #ifndef WOLFSSL_NOSHA3_224
1501
0
        case WC_SHA3_224:
1502
0
            rc = wc_Sha3_224_Copy(&src->hash.sha3, &dst->hash.sha3);
1503
        #ifdef WOLFSSL_HMAC_COPY_HASH
1504
            if (rc == 0) {
1505
                rc = wc_Sha3_224_Copy(&src->i_hash.sha3, &dst->i_hash.sha3);
1506
            }
1507
            if (rc == 0) {
1508
                rc = wc_Sha3_224_Copy(&src->o_hash.sha3, &dst->o_hash.sha3);
1509
            }
1510
        #endif
1511
0
            break;
1512
0
    #endif /* WOLFSSL_NO_SHA3_224 */
1513
0
    #ifndef WOLFSSL_NOSHA3_256
1514
0
        case WC_SHA3_256:
1515
0
            rc = wc_Sha3_256_Copy(&src->hash.sha3, &dst->hash.sha3);
1516
        #ifdef WOLFSSL_HMAC_COPY_HASH
1517
            if (rc == 0) {
1518
                rc = wc_Sha3_256_Copy(&src->i_hash.sha3, &dst->i_hash.sha3);
1519
            }
1520
            if (rc == 0) {
1521
                rc = wc_Sha3_256_Copy(&src->o_hash.sha3, &dst->o_hash.sha3);
1522
            }
1523
        #endif
1524
0
            break;
1525
0
    #endif /* WOLFSSL_NO_SHA3_256 */
1526
0
    #ifndef WOLFSSL_NOSHA3_384
1527
0
        case WC_SHA3_384:
1528
0
            rc = wc_Sha3_384_Copy(&src->hash.sha3, &dst->hash.sha3);
1529
        #ifdef WOLFSSL_HMAC_COPY_HASH
1530
            if (rc == 0) {
1531
                rc = wc_Sha3_384_Copy(&src->i_hash.sha3, &dst->i_hash.sha3);
1532
            }
1533
            if (rc == 0) {
1534
                rc = wc_Sha3_384_Copy(&src->o_hash.sha3, &dst->o_hash.sha3);
1535
            }
1536
        #endif
1537
0
            break;
1538
0
    #endif /* WOLFSSL_NO_SHA3_384 */
1539
0
    #ifndef WOLFSSL_NOSHA3_512
1540
0
        case WC_SHA3_512:
1541
0
            rc = wc_Sha3_512_Copy(&src->hash.sha3, &dst->hash.sha3);
1542
        #ifdef WOLFSSL_HMAC_COPY_HASH
1543
            if (rc == 0) {
1544
                rc = wc_Sha3_512_Copy(&src->i_hash.sha3, &dst->i_hash.sha3);
1545
            }
1546
            if (rc == 0) {
1547
                rc = wc_Sha3_512_Copy(&src->o_hash.sha3, &dst->o_hash.sha3);
1548
            }
1549
        #endif
1550
0
            break;
1551
0
    #endif /* WOLFSSL_NO_SHA3_512 */
1552
0
#endif /* WOLFSSL_SHA3 */
1553
1554
0
    #ifdef WOLFSSL_SM3
1555
0
        case WC_SM3:
1556
0
            rc = wc_Sm3Copy(&src->hash.sm3, &dst->hash.sm3);
1557
        #ifdef WOLFSSL_HMAC_COPY_HASH
1558
            if (rc == 0) {
1559
                rc = wc_Sm3Copy(&src->i_hash.sm3, &dst->i_hash.sm3);
1560
            }
1561
            if (rc == 0) {
1562
                rc = wc_Sm3Copy(&src->o_hash.sm3, &dst->o_hash.sm3);
1563
            }
1564
        #endif
1565
0
            break;
1566
0
    #endif /* WOLFSSL_SM3 */
1567
1568
0
        default:
1569
            /* Digest algorithm not supported. */
1570
0
            rc = BAD_FUNC_ARG;
1571
336
        }
1572
1573
        /* Check result of digest object copy. */
1574
336
        if (rc != 0) {
1575
0
            ret = 0;
1576
0
        }
1577
336
    }
1578
1579
336
    if (ret == 1) {
1580
        /* Copy the pads which are derived from the key. */
1581
336
        XMEMCPY((byte*)dst->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE);
1582
336
        XMEMCPY((byte*)dst->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE);
1583
        /* Copy the inner hash that is the current state. */
1584
336
        XMEMCPY((byte*)dst->innerHash, (byte*)src->innerHash,
1585
336
            WC_MAX_DIGEST_SIZE);
1586
        /* Copy other fields. */
1587
336
    #ifndef HAVE_FIPS
1588
336
        dst->heap    = heap;
1589
336
    #endif
1590
336
        dst->macType = src->macType;
1591
336
        dst->innerHashKeyed = src->innerHashKeyed;
1592
1593
#ifdef WOLFSSL_ASYNC_CRYPT
1594
        XMEMCPY(&dst->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV));
1595
        dst->keyLen = src->keyLen;
1596
    #ifdef HAVE_CAVIUM
1597
        /* Copy the dynamic data. */
1598
        dst->data = (byte*)XMALLOC(src->dataLen, dst->heap, DYNAMIC_TYPE_HMAC);
1599
        if (dst->data == NULL) {
1600
            ret = BUFFER_E;
1601
        }
1602
        else {
1603
            XMEMCPY(dst->data, src->data, src->dataLen);
1604
            dst->dataLen = src->dataLen;
1605
       }
1606
    #endif /* HAVE_CAVIUM */
1607
#endif /* WOLFSSL_ASYNC_CRYPT */
1608
336
    }
1609
1610
336
    return ret;
1611
336
}
1612
1613
1614
/*
1615
 * wolfSSL_HMAC_CTX APIs.
1616
 */
1617
1618
/* Allocate a new HMAC context object and initialize.
1619
 *
1620
 * @return  A cleared HMAC context object on success.
1621
 * @return  NULL on failure.
1622
 */
1623
WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void)
1624
121
{
1625
121
    WOLFSSL_HMAC_CTX* hmac_ctx;
1626
1627
    /* Allocate dynamic memory for HMAC context object. */
1628
121
    hmac_ctx = (WOLFSSL_HMAC_CTX*)XMALLOC(sizeof(WOLFSSL_HMAC_CTX), NULL,
1629
121
        DYNAMIC_TYPE_OPENSSL);
1630
121
    if (hmac_ctx != NULL) {
1631
        /* Initialize HMAC context object. */
1632
121
        wolfSSL_HMAC_CTX_Init(hmac_ctx);
1633
121
    }
1634
1635
121
    return hmac_ctx;
1636
121
}
1637
1638
/* Initialize a HMAC context object.
1639
 *
1640
 * Not an OpenSSL compatibility API.
1641
 *
1642
 * @param [in, out] ctx  HMAC context object.
1643
 * @return  1 indicating success.
1644
 */
1645
int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx)
1646
121
{
1647
121
    WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init");
1648
1649
121
    if (ctx != NULL) {
1650
        /* Clear all fields. */
1651
121
        XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
1652
        /* type field is 0 == WC_HASH_TYPE_NONE. */
1653
        /* TODO: for FIPS and selftest 0 == WC_HASH_TYPE_MD5 instead. */
1654
121
    }
1655
1656
121
    return 1;
1657
121
}
1658
1659
/* Deep copy of information from one HMAC context object to another.
1660
 *
1661
 * @param [out] dst  Copy into this object.
1662
 * @param [in]  src  Copy from this object.
1663
 * @return  1 on success.
1664
 * @return  0 on failure.
1665
 */
1666
int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* dst, WOLFSSL_HMAC_CTX* src)
1667
0
{
1668
0
    int ret = 1;
1669
1670
0
    WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy");
1671
1672
    /* Validate parameters. */
1673
0
    if ((dst == NULL) || (src == NULL)) {
1674
0
        ret = 0;
1675
0
    }
1676
1677
0
    if (ret == 1) {
1678
        /* Copy hash type. */
1679
0
        dst->type = src->type;
1680
        /* Move pads derived from key into save space. */
1681
0
        XMEMCPY((byte *)&dst->save_ipad, (byte *)&src->hmac.ipad,
1682
0
            WC_HMAC_BLOCK_SIZE);
1683
0
        XMEMCPY((byte *)&dst->save_opad, (byte *)&src->hmac.opad,
1684
0
            WC_HMAC_BLOCK_SIZE);
1685
        /* Copy the wolfSSL Hmac ocbject. */
1686
0
        ret = wolfSSL_HmacCopy(&dst->hmac, &src->hmac);
1687
0
    }
1688
1689
0
    return ret;
1690
0
}
1691
1692
/* Cleanup internal state of HMAC context object.
1693
 *
1694
 * Not an OpenSSL compatibility API.
1695
 *
1696
 * @param [in, out] ctx  HMAC context object.
1697
 */
1698
void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx)
1699
121
{
1700
121
    if (ctx != NULL) {
1701
        /* Cleanup HMAC operation data. */
1702
121
        wolfSSL_HMAC_cleanup(ctx);
1703
121
    }
1704
121
}
1705
1706
/* Free HMAC context object.
1707
 *
1708
 * ctx is deallocated and can no longer be used after this call.
1709
 *
1710
 * @param [in] ctx  HMAC context object.
1711
 */
1712
void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx)
1713
121
{
1714
121
    if (ctx != NULL) {
1715
        /* Cleanup HMAC context object, including freeing dynamic data. */
1716
121
        wolfSSL_HMAC_CTX_cleanup(ctx);
1717
        /* Dispose of the memory for the HMAC context object. */
1718
121
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
1719
121
    }
1720
121
}
1721
1722
/* Get the EVP digest of the HMAC context.
1723
 *
1724
 * @param [in] ctx  HMAC context object.
1725
 * @return  EVP digest object.
1726
 * @return  NULL when ctx is NULL or EVP digest not set.
1727
 */
1728
const WOLFSSL_EVP_MD* wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX* ctx)
1729
0
{
1730
0
    const WOLFSSL_EVP_MD* ret = NULL;
1731
1732
0
    if (ctx != NULL) {
1733
        /* Get EVP digest based on digest type. */
1734
0
        ret = wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type);
1735
0
    }
1736
1737
0
    return ret;
1738
0
}
1739
1740
/*
1741
 * wolfSSL_HMAC APIs.
1742
 */
1743
1744
/* Initialize the HMAC operation.
1745
 *
1746
 * @param [in, out] ctx    HMAC context object.
1747
 * @param [in]      key    Array of bytes representing key.
1748
 *                         May be NULL indicating to use the same key as
1749
 *                         previously.
1750
 * @param [in]      keySz  Number of bytes in key.
1751
 *                         0+ in non-FIPS, 14+ in FIPS.
1752
 * @param [in]      type   EVP digest indicate digest type.
1753
 *                         May be NULL if initialized previously.
1754
 * @param [in]      e      wolfSSL engine. Ignored.
1755
 * @return  1 on success.
1756
 * @return  0 on failure.
1757
 */
1758
int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, int keySz,
1759
    const WOLFSSL_EVP_MD* type, WOLFSSL_ENGINE* e)
1760
101
{
1761
101
    WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex");
1762
1763
    /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */
1764
101
    (void)e;
1765
1766
101
    return wolfSSL_HMAC_Init(ctx, key, keySz, type);
1767
101
}
1768
1769
/* Initialize the HMAC operation.
1770
 *
1771
 * @param [in, out] ctx    HMAC context object.
1772
 * @param [in]      key    Array of bytes representing key.
1773
 *                         May be NULL indicating to use the same key as
1774
 *                         previously.
1775
 * @param [in]      keySz  Number of bytes in key.
1776
 *                         0+ in non-FIPS, 14+ in FIPS.
1777
 * @param [in]      type   EVP digest indicate digest type.
1778
 *                         May be NULL if initialized previously.
1779
 * @return  1 on success.
1780
 * @return  0 on failure.
1781
 */
1782
int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
1783
    const WOLFSSL_EVP_MD* type)
1784
101
{
1785
101
    int ret = 1;
1786
101
    void* heap = NULL;
1787
101
    int rc;
1788
1789
101
    WOLFSSL_MSG("wolfSSL_HMAC_Init");
1790
1791
    /* Validate parameters. */
1792
101
    if (ctx == NULL) {
1793
0
        WOLFSSL_MSG("no ctx on init");
1794
0
        ret = 0;
1795
0
    }
1796
    /* Digest type must have been previously set if not specified. */
1797
101
    if ((ret == 1) && (type == NULL) && (ctx->type == (int)WC_HASH_TYPE_NONE)) {
1798
0
        WOLFSSL_MSG("no hash type");
1799
0
        ret = 0;
1800
0
    }
1801
    /* wolfSSL HMAC object must have been setup with a key if not specified. */
1802
101
    if ((ret == 1) && (key == NULL) &&
1803
9
            (ctx->hmac.macType == (int)WC_HASH_TYPE_NONE)) {
1804
9
        WOLFSSL_MSG("wolfCrypt hash not setup");
1805
9
        ret = 0;
1806
9
    }
1807
1808
101
    if (ret == 1) {
1809
92
    #ifndef HAVE_FIPS
1810
92
        heap = ctx->hmac.heap;
1811
92
    #endif
1812
1813
92
        if (type != NULL) {
1814
92
            WOLFSSL_MSG("init has type");
1815
            /* Get the digest type based on EVP digest. */
1816
92
            if (wolfssl_evp_md_to_hash_type(type, &ctx->type) != 0) {
1817
6
                WOLFSSL_MSG("bad init type");
1818
6
                ret = 0;
1819
6
            }
1820
92
        }
1821
92
    }
1822
1823
101
    if (ret == 1) {
1824
        /* Check if init has been called before */
1825
86
        int inited = (ctx->hmac.macType != WC_HASH_TYPE_NONE);
1826
        /* Free if wolfSSL HMAC object when initialized. */
1827
86
        if (inited) {
1828
0
            wc_HmacFree(&ctx->hmac);
1829
0
        }
1830
        /* Initialize wolfSSL HMAC object for new HMAC operation. */
1831
86
        rc = wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID);
1832
86
        if (rc != 0) {
1833
0
            ret = 0;
1834
0
        }
1835
86
    }
1836
101
    if ((ret == 1) && (key != NULL)) {
1837
        /* Set the key into wolfSSL HMAC object. */
1838
86
        rc = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
1839
86
            (word32)keylen);
1840
86
        if (rc != 0) {
1841
            /* in FIPS mode a key < 14 characters will fail here */
1842
0
            WOLFSSL_MSG("hmac set key error");
1843
0
            WOLFSSL_ERROR(rc);
1844
0
            wc_HmacFree(&ctx->hmac);
1845
0
            ret = 0;
1846
0
        }
1847
86
        if (ret == 1) {
1848
            /* Save the pads which are derived from the key. Used to re-init. */
1849
86
            XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad,
1850
86
                WC_HMAC_BLOCK_SIZE);
1851
86
            XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad,
1852
86
                WC_HMAC_BLOCK_SIZE);
1853
86
        }
1854
86
    }
1855
15
    else if (ret == 1) {
1856
0
        WOLFSSL_MSG("recover hmac");
1857
        /* Set state of wolfSSL HMAC object. */
1858
0
        ctx->hmac.macType = (byte)ctx->type;
1859
0
        ctx->hmac.innerHashKeyed = 0;
1860
        /* Restore key by copying in saved pads. */
1861
0
        XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad,
1862
0
            WC_HMAC_BLOCK_SIZE);
1863
0
        XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad,
1864
0
            WC_HMAC_BLOCK_SIZE);
1865
    #ifdef WOLFSSL_HMAC_COPY_HASH
1866
        rc = _HmacInitIOHashes(&ctx->hmac);
1867
        if (rc != 0) {
1868
            WOLFSSL_MSG("hmac init i_hash/o_hash error");
1869
            WOLFSSL_ERROR(rc);
1870
            ret = 0;
1871
        }
1872
        if (ret == 1)
1873
    #endif
1874
0
        {
1875
            /* Initialize the wolfSSL HMAC object. */
1876
0
            rc = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap);
1877
0
            if (rc != 0) {
1878
0
                WOLFSSL_MSG("hmac init error");
1879
0
                WOLFSSL_ERROR(rc);
1880
0
                ret = 0;
1881
0
            }
1882
0
        }
1883
0
    }
1884
1885
101
    return ret;
1886
101
}
1887
1888
/* Update the HMAC operation with more data.
1889
 *
1890
 * TODO: 'len' should be a signed type.
1891
 *
1892
 * @param [in, out] ctx   HMAC context object.
1893
 * @param [in]      data  Array of byted to MAC. May be NULL.
1894
 * @param [in]      len   Number of bytes to MAC. May be 0.
1895
 * @return  1 on success.
1896
 * @return  0 when ctx is NULL or HMAC update fails.
1897
 */
1898
int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
1899
    int len)
1900
1.83k
{
1901
1.83k
    int ret = 1;
1902
1903
1.83k
    WOLFSSL_MSG("wolfSSL_HMAC_Update");
1904
1905
    /* Validate parameters. */
1906
1.83k
    if (ctx == NULL) {
1907
0
        WOLFSSL_MSG("no ctx");
1908
0
        ret = 0;
1909
0
    }
1910
1911
    /* Update when there is data to add. */
1912
1.83k
    if ((ret == 1) && (data != NULL) && (len > 0)) {
1913
243
        int rc;
1914
1915
243
        WOLFSSL_MSG("updating hmac");
1916
        /* Update wolfSSL HMAC object. */
1917
243
        rc = wc_HmacUpdate(&ctx->hmac, data, (word32)len);
1918
243
        if (rc != 0){
1919
0
            WOLFSSL_MSG("hmac update error");
1920
0
            ret = 0;
1921
0
        }
1922
243
    }
1923
1924
1.83k
    return ret;
1925
1.83k
}
1926
1927
/* Finalize HMAC operation.
1928
 *
1929
 * @param [in, out] ctx   HMAC context object.
1930
 * @param [out]     hash  Buffer to hold HMAC result.
1931
 *                        Must be able to hold bytes equivalent to digest size.
1932
 * @param [out]     len   Length of HMAC result. May be NULL.
1933
 * @return  1 on success.
1934
 * @return  0 when ctx or hash is NULL.
1935
 * @return  0 when HMAC finalization fails.
1936
 */
1937
int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
1938
    unsigned int* len)
1939
86
{
1940
86
    int ret = 1;
1941
86
    int rc;
1942
1943
86
    WOLFSSL_MSG("wolfSSL_HMAC_Final");
1944
1945
    /* Validate parameters. */
1946
86
    if ((ctx == NULL) || (hash == NULL)) {
1947
0
        WOLFSSL_MSG("invalid parameter");
1948
0
        ret = 0;
1949
0
    }
1950
1951
86
    if (ret == 1) {
1952
86
        WOLFSSL_MSG("final hmac");
1953
        /* Finalize wolfSSL HMAC object. */
1954
86
        rc = wc_HmacFinal(&ctx->hmac, hash);
1955
86
        if (rc != 0){
1956
0
            WOLFSSL_MSG("final hmac error");
1957
0
            ret = 0;
1958
0
        }
1959
86
    }
1960
86
    if ((ret == 1) && (len != NULL)) {
1961
86
        WOLFSSL_MSG("setting output len");
1962
        /* Get the length of the output based on digest type. */
1963
86
        *len = wolfssl_mac_len((unsigned char)ctx->type);
1964
86
    }
1965
1966
86
    return ret;
1967
86
}
1968
1969
1970
/* Cleanup the HMAC operation.
1971
 *
1972
 * Not an OpenSSL compatibility API.
1973
 *
1974
 * @param [in, out] ctx  HMAC context object.
1975
 * @return  1 indicating success.
1976
 */
1977
int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
1978
242
{
1979
242
    WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
1980
1981
242
    if (ctx != NULL) {
1982
        /* Free the dynamic data in the wolfSSL HMAC object. */
1983
242
        wc_HmacFree(&ctx->hmac);
1984
242
    }
1985
1986
242
    return 1;
1987
242
}
1988
1989
/* HMAC data using the specified EVP digest.
1990
 *
1991
 * @param [in]  evp_md  EVP digest.
1992
 * @param [in]  key     Array of bytes representing key.
1993
 * @param [in]  keySz   Number of bytes in key.
1994
 *                      0+ in non-FIPS, 14+ in FIPS.
1995
 * @param [in]  data    Data to MAC.
1996
 * @param [in]  len     Length in bytes of data to MAC.
1997
 * @param [out] md      HMAC output.
1998
 * @param [out] md_len  Length of HMAC output in bytes. May be NULL.
1999
 * @return  Buffer holding HMAC output.
2000
 * @return  NULL on failure.
2001
 */
2002
unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
2003
    int key_len, const unsigned char* data, size_t len, unsigned char* md,
2004
    unsigned int* md_len)
2005
0
{
2006
0
    unsigned char* ret = NULL;
2007
0
    int rc = 0;
2008
0
    int type = 0;
2009
0
    int hmacLen = 0;
2010
0
    WC_DECLARE_VAR(hmac, Hmac, 1, 0);
2011
0
    void* heap = NULL;
2012
2013
    /* Validate parameters. */
2014
0
    if ((evp_md == NULL) || (key == NULL) || (md == NULL)) {
2015
0
        rc = BAD_FUNC_ARG;
2016
0
    }
2017
2018
0
    if (rc == 0) {
2019
        /* Get the hash type corresponding to the EVP digest. */
2020
0
        rc = wolfssl_evp_md_to_hash_type(evp_md, &type);
2021
0
    }
2022
0
#ifdef WOLFSSL_SMALL_STACK
2023
0
    if (rc == 0) {
2024
        /* Allocate dynamic memory for a wolfSSL HMAC object. */
2025
0
        hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
2026
0
        if (hmac == NULL) {
2027
0
            rc = MEMORY_E;
2028
0
        }
2029
0
    }
2030
0
#endif
2031
0
    if (rc == 0)  {
2032
        /* Get the HMAC output length. */
2033
0
        hmacLen = (int)wolfssl_mac_len((unsigned char)type);
2034
        /* 0 indicates the digest is not supported. */
2035
0
        if (hmacLen == 0) {
2036
0
            rc = BAD_FUNC_ARG;
2037
0
        }
2038
0
    }
2039
    /* Initialize the wolfSSL HMAC object. */
2040
0
    if ((rc == 0) && (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0)) {
2041
        /* Set the key into the wolfSSL HMAC object. */
2042
0
        rc = wc_HmacSetKey(hmac, type, (const byte*)key, (word32)key_len);
2043
0
        if (rc == 0) {
2044
           /* Update the wolfSSL HMAC object with data. */
2045
0
            rc = wc_HmacUpdate(hmac, data, (word32)len);
2046
0
        }
2047
        /* Finalize the wolfSSL HMAC object. */
2048
0
        if ((rc == 0) && (wc_HmacFinal(hmac, md) == 0)) {
2049
            /* Return the length of the HMAC output if required. */
2050
0
            if (md_len != NULL) {
2051
0
                *md_len = (unsigned int)hmacLen;
2052
0
            }
2053
            /* Set the buffer to return. */
2054
0
            ret = md;
2055
0
        }
2056
        /* Dispose of dynamic memory associated with the wolfSSL HMAC object. */
2057
0
        wc_HmacFree(hmac);
2058
0
    }
2059
2060
0
    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
2061
0
    return ret;
2062
0
}
2063
2064
/* Get the HMAC output size.
2065
 *
2066
 * @param [in] ctx  HMAC context object.
2067
 * @return  Size of HMAC output in bytes.
2068
 * @return  0 when ctx is NULL or no digest algorithm set.
2069
 */
2070
size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX* ctx)
2071
0
{
2072
0
    size_t ret = 0;
2073
2074
0
    if (ctx != NULL) {
2075
        /* Look up digest size with wolfSSL. */
2076
0
        ret = (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType);
2077
0
    }
2078
2079
0
    return ret;
2080
0
}
2081
#endif /* OPENSSL_EXTRA */
2082
2083
/*******************************************************************************
2084
 * END OF HMAC API
2085
 ******************************************************************************/
2086
2087
/*******************************************************************************
2088
 * START OF CMAC API
2089
 ******************************************************************************/
2090
2091
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
2092
#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \
2093
    defined(WOLFSSL_AES_DIRECT)
2094
/* Allocate a new CMAC context object.
2095
 *
2096
 * TODO: make fields static.
2097
 *
2098
 * @return  A CMAC context object on success.
2099
 * @return  NULL on failure.
2100
 */
2101
WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void)
2102
1.00k
{
2103
1.00k
    WOLFSSL_CMAC_CTX* ctx = NULL;
2104
2105
    /* Allocate memory for CMAC context object. */
2106
1.00k
    ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL,
2107
1.00k
        DYNAMIC_TYPE_OPENSSL);
2108
1.00k
    if (ctx != NULL) {
2109
        /* Memory for wolfSSL CMAC object is allocated in
2110
         * wolfSSL_CMAC_Init().
2111
         */
2112
1.00k
        ctx->internal = NULL;
2113
        /* Allocate memory for EVP cipher context object. */
2114
1.00k
        ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new();
2115
1.00k
        if (ctx->cctx == NULL) {
2116
0
            XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
2117
0
            XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
2118
0
            ctx = NULL;
2119
0
        }
2120
1.00k
    }
2121
2122
1.00k
    return ctx;
2123
1.00k
}
2124
2125
/* Free CMAC context object and dynamically allocated fields.
2126
 *
2127
 * ctx is deallocated and can no longer be used after this call.
2128
 *
2129
 * @param [in] ctx  CMAC context object.
2130
 */
2131
void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx)
2132
1.00k
{
2133
1.00k
    if (ctx != NULL) {
2134
        /* Deallocate dynamically allocated fields. */
2135
1.00k
        if (ctx->internal != NULL) {
2136
0
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
2137
0
            wc_CmacFree((Cmac*)ctx->internal);
2138
0
#endif
2139
0
            XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
2140
0
        }
2141
1.00k
        if (ctx->cctx != NULL) {
2142
1.00k
            wolfSSL_EVP_CIPHER_CTX_cleanup(ctx->cctx);
2143
1.00k
            wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx);
2144
1.00k
        }
2145
        /* Deallocate CMAC context object. */
2146
1.00k
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
2147
1.00k
    }
2148
1.00k
}
2149
2150
/* Return a reference to the EVP cipher context.
2151
 *
2152
 * @param [in] ctx  CMAC context object.
2153
 * @return  EVP cipher context.
2154
 * @return  NULL when ctx is NULL.
2155
 */
2156
WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx)
2157
0
{
2158
0
    WOLFSSL_EVP_CIPHER_CTX* cctx = NULL;
2159
2160
0
    if (ctx != NULL) {
2161
        /* Return EVP cipher context object. */
2162
0
        cctx = ctx->cctx;
2163
0
    }
2164
2165
0
    return cctx;
2166
0
}
2167
2168
/* Initialize the CMAC operation.
2169
 *
2170
 * @param [in, out] cmac    CMAC context object.
2171
 * @param [in]      key     Symmetric key to use.
2172
 * @param [in]      keySz   Length of key in bytes.
2173
 * @param [in]      cipher  EVP cipher object describing encryption algorithm
2174
 *                          to use.
2175
 * @param [in]      engine  wolfSSL Engine. Not used.
2176
 * @return  1 on success.
2177
 * @return  0 when ctx or cipher is NULL.
2178
 * @return  0 when cipher is not an AES-CBC algorithm.
2179
 * @return  0 when key length does not match cipher.
2180
 */
2181
int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keySz,
2182
    const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine)
2183
507
{
2184
507
    int ret = 1;
2185
2186
507
    (void)engine;
2187
2188
507
    WOLFSSL_ENTER("wolfSSL_CMAC_Init");
2189
2190
    /* Validate parameters. */
2191
507
    if ((ctx == NULL) || (cipher == NULL)) {
2192
0
        ret = 0;
2193
0
    }
2194
    /* Only AES-CBC ciphers are supported. */
2195
507
    if ((ret == 1)
2196
507
    #ifdef WOLFSSL_AES_128
2197
507
        && (cipher != EVP_AES_128_CBC)
2198
318
    #endif
2199
318
    #ifdef WOLFSSL_AES_192
2200
318
        && (cipher != EVP_AES_192_CBC)
2201
208
    #endif
2202
208
    #ifdef WOLFSSL_AES_256
2203
208
        && (cipher != EVP_AES_256_CBC)
2204
507
    #endif
2205
507
    ) {
2206
147
        WOLFSSL_MSG("wolfSSL_CMAC_Init: requested cipher is unsupported");
2207
147
        ret = 0;
2208
147
    }
2209
    /* Key length must match cipher. */
2210
507
    if ((ret == 1) && ((int)keySz != wolfSSL_EVP_Cipher_key_length(cipher))) {
2211
81
        WOLFSSL_MSG("wolfSSL_CMAC_Init: "
2212
81
                    "supplied key size doesn't match requested cipher");
2213
81
        ret = 0;
2214
81
    }
2215
2216
507
    if ((ret == 1) && (ctx->internal == NULL)) {
2217
        /* Allocate memory for wolfSSL CMAC object. */
2218
279
        ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC);
2219
279
        if (ctx->internal == NULL)
2220
0
            ret = 0;
2221
279
    }
2222
2223
    /* Initialize the wolfCrypt CMAC object. */
2224
507
    if ((ret == 1) && (wc_InitCmac((Cmac*)ctx->internal, (const byte*)key,
2225
279
            (word32)keySz, WC_CMAC_AES, NULL) != 0)) {
2226
0
        WOLFSSL_MSG("wolfSSL_CMAC_Init: wc_InitCmac() failed");
2227
0
        XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
2228
0
        ctx->internal = NULL;
2229
0
        ret = 0;
2230
0
    }
2231
507
    if (ret == 1) {
2232
        /* Initialize the EVP cipher context object for encryption. */
2233
279
        ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL,
2234
279
            1);
2235
279
        if (ret != WOLFSSL_SUCCESS)
2236
0
            WOLFSSL_MSG("wolfSSL_CMAC_Init: wolfSSL_EVP_CipherInit() failed");
2237
279
    }
2238
2239
507
    WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret);
2240
2241
507
    return ret;
2242
507
}
2243
2244
/* Update the CMAC operation with data.
2245
 *
2246
 * @param [in, out] ctx   CMAC context object.
2247
 * @param [in]      data  Data to MAC as a byte array.
2248
 * @param [in]      len   Length of data in bytes.
2249
 * @return  1 on success.
2250
 * @return  0 when ctx is NULL.
2251
 */
2252
int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len)
2253
3.16k
{
2254
3.16k
    int ret = 1;
2255
2256
3.16k
    WOLFSSL_ENTER("wolfSSL_CMAC_Update");
2257
2258
    /* Validate parameters. */
2259
3.16k
    if (ctx == NULL) {
2260
0
        ret = 0;
2261
0
    }
2262
2263
    /* Update the wolfCrypto CMAC object with data. */
2264
3.16k
    if ((ret == 1) && (data != NULL) && (wc_CmacUpdate((Cmac*)ctx->internal,
2265
3.02k
            (const byte*)data, (word32)len) != 0)) {
2266
0
        ret = 0;
2267
0
    }
2268
2269
3.16k
    WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret);
2270
2271
3.16k
    return ret;
2272
3.16k
}
2273
2274
/* Finalize the CMAC operation into output buffer.
2275
 *
2276
 * @param [in, out] ctx  CMAC context object.
2277
 * @param [out]     out  Buffer to place CMAC result into.
2278
 *                       Must be able to hold WC_AES_BLOCK_SIZE bytes.
2279
 * @param [out]     len  Length of CMAC result. May be NULL.
2280
 * @return  1 on success.
2281
 * @return  0 when ctx is NULL.
2282
 */
2283
int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, size_t* len)
2284
279
{
2285
279
    int ret = 1;
2286
279
    int blockSize;
2287
279
    word32 len32;
2288
2289
279
    WOLFSSL_ENTER("wolfSSL_CMAC_Final");
2290
2291
    /* Validate parameters. */
2292
279
    if (ctx == NULL) {
2293
0
        ret = 0;
2294
0
    }
2295
2296
279
    if (ret == 1) {
2297
        /* Get the expected output size. */
2298
279
        blockSize = wolfSSL_EVP_CIPHER_CTX_block_size(ctx->cctx);
2299
        /* Check value is valid. */
2300
279
        if (blockSize <= 0) {
2301
0
            ret = 0;
2302
0
        }
2303
279
        else {
2304
            /* wolfCrypt CMAC expects buffer size. */
2305
279
            len32 = (word32)blockSize;
2306
            /* Return size if required. */
2307
279
            if (len != NULL) {
2308
279
                *len = (size_t)blockSize;
2309
279
            }
2310
279
        }
2311
279
    }
2312
279
    if ((ret == 1) && (out != NULL)) {
2313
        /* Calculate MAC result with wolfCrypt CMAC object. */
2314
279
        if (wc_CmacFinal((Cmac*)ctx->internal, out, &len32) != 0) {
2315
0
            ret = 0;
2316
0
        }
2317
        /* TODO: Is this necessary? Length should not change. */
2318
        /* Return actual size if required. */
2319
279
        else if (len != NULL) {
2320
279
            *len = (size_t)len32;
2321
279
        }
2322
2323
279
        XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
2324
279
        ctx->internal = NULL;
2325
279
    }
2326
2327
279
    WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret);
2328
2329
279
    return ret;
2330
279
}
2331
#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */
2332
#endif /* OPENSSL_EXTRA && !WOLFCRYPT_ONLY */
2333
2334
/*******************************************************************************
2335
 * END OF CMAC API
2336
 ******************************************************************************/
2337
2338
/*******************************************************************************
2339
 * START OF DES API
2340
 ******************************************************************************/
2341
2342
#ifdef OPENSSL_EXTRA
2343
#ifndef NO_DES3
2344
/* Set parity of the DES key.
2345
 *
2346
 * @param [in, out] key  DES key.
2347
 */
2348
void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* key)
2349
0
{
2350
0
    int i;
2351
2352
0
    WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity");
2353
2354
0
    for (i = 0; i < DES_KEY_SIZE; i++) {
2355
0
        unsigned char c = (*key)[i];
2356
        /* Set bottom bit to odd parity - XOR of each bit is to be 1.
2357
         * XOR 1 to XOR of each bit.
2358
         * When even parity, the value will be 1 and the bottom bit will be
2359
         * flipped.
2360
         * When odd parity, the value will be 0 and the bottom bit will be
2361
         * unchanged.
2362
         */
2363
0
        c ^= ((c >> 0) ^ (c >> 1) ^ (c >> 2) ^ (c >> 3) ^ (c >> 4) ^ (c >> 5) ^
2364
0
              (c >> 6) ^ (c >> 7) ^ 0x01) & 0x01;
2365
0
        (*key)[i] = c;
2366
0
    }
2367
0
}
2368
2369
/* Check parity of the DES key.
2370
 *
2371
 * @param [in] key  DES key.
2372
 * @return  1 when odd parity on all bytes.
2373
 * @return  0 when even parity on any byte.
2374
 */
2375
int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *key)
2376
0
{
2377
0
    int i;
2378
    /* Assume odd parity. */
2379
0
    unsigned char p = 1;
2380
2381
0
    WOLFSSL_ENTER("wolfSSL_DES_check_key_parity");
2382
2383
0
    for (i = 0; i < DES_KEY_SIZE; i++) {
2384
0
        unsigned char c = (*key)[i];
2385
        /* p will be 0 when parity is even (XOR of bits is 0). */
2386
0
        p &= (c >> 0) ^ (c >> 1) ^ (c >> 2) ^ (c >> 3) ^ (c >> 4) ^ (c >> 5) ^
2387
0
             (c >> 6) ^ (c >> 7);
2388
0
    }
2389
2390
    /* Only care about bottom bit. */
2391
0
    return p & 1;
2392
0
}
2393
2394
/* Check whether key data is the two 32-bit words.
2395
 *
2396
 * return true in fail case (1)
2397
 *
2398
 * @param [in] k1   First part of key.
2399
 * @param [in] k2   Second part of key.
2400
 * @param [in] key  DES key as an array of bytes.
2401
 **/
2402
static int wolfssl_des_check(word32 k1, word32 k2, unsigned char* key)
2403
0
{
2404
    /* Compare the two 32-bit words. */
2405
0
    return (((word32*)key)[0] == k1) && (((word32*)key)[1] == k2);
2406
0
}
2407
2408
/* Check key is not weak.
2409
 *
2410
 * Weak key list from Nist "Recommendation for the Triple Data Encryption
2411
 * Algorithm (TDEA) Block Cipher"
2412
 *
2413
 * @param [in] key  DES key.
2414
 * @return  0 when #key is not a weak key.
2415
 * @return  1 when #key is a weak key.
2416
 */
2417
int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key)
2418
0
{
2419
0
    int ret = 0;
2420
2421
0
    WOLFSSL_ENTER("wolfSSL_DES_is_weak_key");
2422
2423
    /* Validate parameter. */
2424
0
    if (key == NULL) {
2425
0
        WOLFSSL_MSG("NULL key passed in");
2426
0
        ret = 1;
2427
0
    }
2428
2429
    /* Check weak keys - endian doesn't matter. */
2430
0
    if ((ret == 0) && (wolfssl_des_check(0x01010101, 0x01010101, *key) ||
2431
0
                       wolfssl_des_check(0xFEFEFEFE, 0xFEFEFEFE, *key) ||
2432
0
                       wolfssl_des_check(0xE0E0E0E0, 0xF1F1F1F1, *key) ||
2433
0
                       wolfssl_des_check(0x1F1F1F1F, 0x0E0E0E0E, *key))) {
2434
0
        WOLFSSL_MSG("Weak key found");
2435
0
        ret = 1;
2436
0
    }
2437
2438
    /* Check semi-weak keys - endian doesn't matter. */
2439
0
    if ((ret == 0) && (wolfssl_des_check(0x011F011F, 0x010E010E, *key) ||
2440
0
                       wolfssl_des_check(0x1F011F01, 0x0E010E01, *key) ||
2441
0
                       wolfssl_des_check(0x01E001E0, 0x01F101F1, *key) ||
2442
0
                       wolfssl_des_check(0xE001E001, 0xF101F101, *key) ||
2443
0
                       wolfssl_des_check(0x01FE01FE, 0x01FE01FE, *key) ||
2444
0
                       wolfssl_des_check(0xFE01FE01, 0xFE01FE01, *key) ||
2445
0
                       wolfssl_des_check(0x1FE01FE0, 0x0EF10EF1, *key) ||
2446
0
                       wolfssl_des_check(0xE01FE01F, 0xF10EF10E, *key) ||
2447
0
                       wolfssl_des_check(0x1FFE1FFE, 0x0EFE0EFE, *key) ||
2448
0
                       wolfssl_des_check(0xFE1FFE1F, 0xFE0EFE0E, *key) ||
2449
0
                       wolfssl_des_check(0xE0FEE0FE, 0xF1FEF1FE, *key) ||
2450
0
                       wolfssl_des_check(0xFEE0FEE0, 0xFEF1FEF1, *key))) {
2451
0
        WOLFSSL_MSG("Semi-weak key found");
2452
0
        ret = 1;
2453
0
    }
2454
2455
0
    return ret;
2456
0
}
2457
2458
/* Set key into schedule if key parity is odd and key is not weak.
2459
 *
2460
 * @param [in]  key       DES key data.
2461
 * @param [out] schedule  DES key schedule.
2462
 * @return  0 on success.
2463
 * @return  -1 when parity is not odd.
2464
 * @return  -2 when key or schedule is NULL.
2465
 * @return  -2 when key is weak or semi-weak.
2466
 */
2467
int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* key,
2468
    WOLFSSL_DES_key_schedule* schedule)
2469
0
{
2470
0
    int ret = 0;
2471
2472
    /* Validate parameters. */
2473
0
    if ((key == NULL) || (schedule == NULL)) {
2474
0
        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
2475
0
        ret = -2;
2476
0
    }
2477
2478
    /* Check key parity is odd. */
2479
0
    if ((ret == 0) && (!wolfSSL_DES_check_key_parity(key))) {
2480
0
        WOLFSSL_MSG("Odd parity test fail");
2481
0
        ret = WOLFSSL_FATAL_ERROR;
2482
0
    }
2483
    /* Check whether key is weak. */
2484
0
    if ((ret == 0) && wolfSSL_DES_is_weak_key(key)) {
2485
0
        WOLFSSL_MSG("Weak key found");
2486
0
        ret = -2;
2487
0
    }
2488
0
    if (ret == 0) {
2489
        /* Key data passed checks, now copy key into schedule. */
2490
0
        XMEMCPY(schedule, key, DES_KEY_SIZE);
2491
0
    }
2492
2493
0
    return ret;
2494
0
}
2495
2496
/* Set key into schedule - no checks on key data performed.
2497
 *
2498
 * @param [in]  key       DES key data.
2499
 * @param [out] schedule  DES key schedule.
2500
 */
2501
void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* key,
2502
    WOLFSSL_DES_key_schedule* schedule)
2503
0
{
2504
    /* Validate parameters. */
2505
0
    if ((key != NULL) && (schedule != NULL)) {
2506
        /* Copy the key data into the schedule. */
2507
0
        XMEMCPY(schedule, key, DES_KEY_SIZE);
2508
0
    }
2509
0
}
2510
2511
/* Set key into schedule.
2512
 *
2513
 * @param [in]  key       DES key data.
2514
 * @param [out] schedule  DES key schedule.
2515
 * @return  0 on success.
2516
 * @return  -1 when parity is not odd.
2517
 * @return  -2 when key or schedule is NULL.
2518
 * @return  -2 when key is weak or semi-weak.
2519
 */
2520
int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* key,
2521
    WOLFSSL_DES_key_schedule* schedule)
2522
0
{
2523
#ifdef WOLFSSL_CHECK_DESKEY
2524
    return wolfSSL_DES_set_key_checked(key, schedule);
2525
#else
2526
0
    wolfSSL_DES_set_key_unchecked(key, schedule);
2527
0
    return 0;
2528
0
#endif
2529
0
}
2530
2531
/* Set the key schedule from the DES key.
2532
 *
2533
 * TODO: OpenSSL checks parity and weak keys.
2534
 *
2535
 * @param [in]  key       DES key data.
2536
 * @param [out] schedule  DES key schedule.
2537
 * @return  0 on success.
2538
 */
2539
int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
2540
    WOLFSSL_DES_key_schedule* schedule)
2541
0
{
2542
0
    WOLFSSL_ENTER("wolfSSL_DES_key_sched");
2543
2544
    /* Check parameters are usable. */
2545
0
    if ((key == NULL) || (schedule == NULL)) {
2546
0
        WOLFSSL_MSG("Null argument passed in");
2547
0
    }
2548
0
    else {
2549
        /* Copy the key data into the schedule. */
2550
0
        XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock));
2551
0
    }
2552
2553
0
    return 0;
2554
0
}
2555
2556
/* Encrypt with DES-CBC to create a checksum.
2557
 *
2558
 * Intended to behave similar to Kerberos mit_des_cbc_cksum.
2559
 * Returns the last 4 bytes of cipher text.
2560
 *
2561
 * TODO: Encrypt one block at a time instead of allocating a large amount.
2562
 *
2563
 * @param [in]  in      Data to encrypt.
2564
 * @param [out] out     Last encrypted block.
2565
 * @param [in]  length  Length of data to encrypt.
2566
 * @param [in]  sc      Key schedule for encryption.
2567
 * @param [in]  iv      Initialization vector for CBC.
2568
 * @return  Checksum of encryption.
2569
 * @return  0 on error.
2570
 */
2571
WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in,
2572
    WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc,
2573
    WOLFSSL_const_DES_cblock* iv)
2574
0
{
2575
0
    WOLFSSL_DES_LONG ret = 0;
2576
0
    int err = 0;
2577
0
    unsigned char* data = (unsigned char*)in;
2578
0
    unsigned char* tmp = NULL;
2579
0
    long dataSz = length;
2580
2581
0
    WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum");
2582
2583
    /* Validate parameters. */
2584
0
    if ((in == NULL) || (out == NULL) || (sc == NULL) || (iv == NULL)) {
2585
0
        WOLFSSL_MSG("Bad argument passed in");
2586
0
        err = 1;
2587
0
    }
2588
2589
    /* When input length is not a multiple of DES_BLOCK_SIZE pad with 0s. */
2590
0
    if ((!err) && (dataSz % DES_BLOCK_SIZE)) {
2591
        /* Allocate a buffer big enough to hold padded input. */
2592
0
        dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE);
2593
0
        data = (unsigned char*)XMALLOC((size_t)dataSz, NULL,
2594
0
        DYNAMIC_TYPE_TMP_BUFFER);
2595
0
        if (data == NULL) {
2596
0
            WOLFSSL_MSG("Issue creating temporary buffer");
2597
0
            err = 1;
2598
0
        }
2599
0
        else {
2600
            /* Copy input and pad with 0s. */
2601
0
            XMEMCPY(data, in, (size_t)length);
2602
0
            XMEMSET(data + length, 0, (size_t)(dataSz - length));
2603
0
        }
2604
0
    }
2605
2606
0
    if (!err) {
2607
        /* Allocate buffer to hold encrypted data. */
2608
0
        tmp = (unsigned char*)XMALLOC((size_t)dataSz, NULL,
2609
0
        DYNAMIC_TYPE_TMP_BUFFER);
2610
0
        if (tmp == NULL) {
2611
0
            WOLFSSL_MSG("Issue creating temporary buffer");
2612
0
            err = 1;
2613
0
        }
2614
0
    }
2615
2616
0
    if (!err) {
2617
        /* Encrypt data into temporary. */
2618
0
        wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc, (WOLFSSL_DES_cblock*)iv,
2619
0
            WC_DES_ENCRYPT);
2620
        /* Copy out last block. */
2621
0
        XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE),
2622
0
            DES_BLOCK_SIZE);
2623
2624
        /* Use the last half of the encrypted block as the checksum. */
2625
0
        ret = (((*((unsigned char*)out + 4) & 0xFF) << 24) |
2626
0
               ((*((unsigned char*)out + 5) & 0xFF) << 16) |
2627
0
               ((*((unsigned char*)out + 6) & 0xFF) <<  8) |
2628
0
                (*((unsigned char*)out + 7) & 0xFF)      );
2629
0
    }
2630
2631
    /* Dispose of allocated memory. */
2632
0
    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2633
0
    if (data != in) {
2634
0
        XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2635
0
    }
2636
0
    return ret;
2637
0
}
2638
2639
/* Encrypt/decrypt data with DES-CBC.
2640
 *
2641
 * TODO: OpenSSL expects a length that is a multiple of the block size but
2642
 *       we are padding the last block. This is not a padding API.
2643
 * TODO: Validate parameters?
2644
 *
2645
 * @param [in]  input     Data to encipher.
2646
 * @param [out] output    Enciphered data.
2647
 * @param [in]  length    Length of data to encipher.
2648
 * @param [in]  schedule  Key schedule.
2649
 * @param [in]  ivec      IV for CBC operation.
2650
 * @param [in]  enc       Whether to encrypt.
2651
 */
2652
void wolfSSL_DES_cbc_encrypt(const unsigned char* input, unsigned char* output,
2653
    long length, WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
2654
    int enc)
2655
0
{
2656
0
    WC_DECLARE_VAR(des, Des, 1, 0);
2657
0
    byte lastBlock[DES_BLOCK_SIZE];
2658
2659
0
    WOLFSSL_ENTER("wolfSSL_DES_cbc_encrypt");
2660
2661
0
#ifdef WOLFSSL_SMALL_STACK
2662
0
    des = (Des*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_CIPHER);
2663
0
    if (des == NULL) {
2664
0
        WOLFSSL_MSG("Failed to allocate memory for Des object");
2665
0
    }
2666
0
    else
2667
0
#endif
2668
    /* OpenSSL compat, no ret */
2669
0
    if (wc_Des_SetKey(des, (const byte*)schedule, (const byte*)ivec,
2670
0
            !enc) != 0) {
2671
0
        WOLFSSL_MSG("wc_Des_SetKey return error.");
2672
0
    }
2673
0
    else {
2674
        /* Last incomplete block size. 0 means none over. */
2675
0
        int    lb_sz = length % DES_BLOCK_SIZE;
2676
        /* Length of data that is a multiple of a block. */
2677
0
        word32 len   = (word32)(length - lb_sz);
2678
2679
0
        if (enc == WC_DES_ENCRYPT) {
2680
            /* Encrypt full blocks into output. */
2681
0
            wc_Des_CbcEncrypt(des, output, input, len);
2682
0
            if (lb_sz != 0) {
2683
                /* Create a 0 padded block from remaining bytes. */
2684
0
                XMEMSET(lastBlock, 0, DES_BLOCK_SIZE);
2685
0
                XMEMCPY(lastBlock, input + len, (size_t)lb_sz);
2686
                /* Encrypt last block into output. */
2687
0
                wc_Des_CbcEncrypt(des, output + len, lastBlock,
2688
0
                    (word32)DES_BLOCK_SIZE);
2689
0
            }
2690
0
        }
2691
0
        else {
2692
            /* Decrypt full blocks into output. */
2693
0
            wc_Des_CbcDecrypt(des, output, input, len);
2694
0
            if (lb_sz != 0) {
2695
                /* Decrypt the last block that is not going to be full size. */
2696
0
                wc_Des_CbcDecrypt(des, lastBlock, input + len,
2697
0
                    (word32)DES_BLOCK_SIZE);
2698
                /* Copy out the required amount of the decrypted block. */
2699
0
                XMEMCPY(output + len, lastBlock, (size_t)lb_sz);
2700
0
            }
2701
0
        }
2702
0
    }
2703
2704
0
    WC_FREE_VAR_EX(des, NULL, DYNAMIC_TYPE_CIPHER);
2705
0
}
2706
2707
/* Encrypt/decrypt data with DES-CBC. Sets the IV for following operation.
2708
 *
2709
 * TODO: OpenSSL expects a length that is a multiple of the block size but
2710
 *       we are padding the last block. This is not a padding API.
2711
 * TODO: Validate parameters?
2712
 *
2713
 * @param [in]      input     Data to encipher.
2714
 * @param [out]     output    Enciphered data.
2715
 * @param [in]      length    Length of data to encipher.
2716
 * @param [in]      schedule  Key schedule.
2717
 * @param [in, out] ivec      IV for CBC operation.
2718
 * @param [in]      enc       Whether to encrypt.
2719
 */
2720
void wolfSSL_DES_ncbc_encrypt(const unsigned char* input, unsigned char* output,
2721
    long length, WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
2722
    int enc)
2723
0
{
2724
0
    unsigned char tmp[DES_IV_SIZE];
2725
    /* Calculate length to a multiple of block size. */
2726
0
    size_t offset = (size_t)length;
2727
2728
0
    WOLFSSL_ENTER("wolfSSL_DES_ncbc_encrypt");
2729
2730
0
    offset = (offset + DES_BLOCK_SIZE - 1) / DES_BLOCK_SIZE;
2731
0
    offset *= DES_BLOCK_SIZE;
2732
0
    offset -= DES_BLOCK_SIZE;
2733
0
    if (enc == WC_DES_ENCRYPT) {
2734
        /* Encrypt data. */
2735
0
        wolfSSL_DES_cbc_encrypt(input, output, length, schedule, ivec, enc);
2736
        /* Use last encrypted block as new IV. */
2737
0
        XMEMCPY(ivec, output + offset, DES_IV_SIZE);
2738
0
    }
2739
0
    else {
2740
        /* Get last encrypted block for new IV. */
2741
0
        XMEMCPY(tmp, input + offset, DES_IV_SIZE);
2742
        /* Decrypt data. */
2743
0
        wolfSSL_DES_cbc_encrypt(input, output, length, schedule, ivec, enc);
2744
        /* Use last encrypted block as new IV. */
2745
0
        XMEMCPY(ivec, tmp, DES_IV_SIZE);
2746
0
    }
2747
0
}
2748
2749
/* Encrypt/decrypt data with DES-CBC.
2750
 *
2751
 * WOLFSSL_DES_key_schedule is an unsigned char array of size 8.
2752
 *
2753
 * TODO: OpenSSL expects a length that is a multiple of the block size but
2754
 *       we are padding the last block. This is not a padding API.
2755
 * TODO: Validate parameters?
2756
 *
2757
 * @param [in]      input     Data to encipher.
2758
 * @param [out]     output    Enciphered data.
2759
 * @param [in]      length    Length of data to encipher.
2760
 * @param [in]      schedule  Key schedule.
2761
 * @param [in, out] ivec      IV for CBC operation.
2762
 * @param [in]      enc       Whether to encrypt.
2763
 */
2764
void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
2765
    unsigned char* output, long sz, WOLFSSL_DES_key_schedule* ks1,
2766
    WOLFSSL_DES_key_schedule* ks2, WOLFSSL_DES_key_schedule* ks3,
2767
    WOLFSSL_DES_cblock* ivec, int enc)
2768
0
{
2769
0
    WC_DECLARE_VAR(des3, Des3, 1, 0);
2770
2771
0
    WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
2772
2773
0
#ifdef WOLFSSL_SMALL_STACK
2774
0
    des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_CIPHER);
2775
0
    if (des3 == NULL) {
2776
0
        WOLFSSL_MSG("Failed to allocate memory for Des3 object");
2777
0
        sz = 0;
2778
0
    }
2779
0
#endif
2780
2781
0
    if (sz > 0) {
2782
0
        int    ret;
2783
0
        byte   key[DES3_KEY_SIZE];
2784
0
        byte   lastBlock[DES_BLOCK_SIZE];
2785
0
        int    lb_sz;
2786
0
        word32 len;
2787
2788
        /* Copy the three keys into the buffer for wolfCrypt DES. */
2789
0
        XMEMCPY(key + 0 * DES_BLOCK_SIZE, *ks1, DES_BLOCK_SIZE);
2790
0
        XMEMCPY(key + 1 * DES_BLOCK_SIZE, *ks2, DES_BLOCK_SIZE);
2791
0
        XMEMCPY(key + 2 * DES_BLOCK_SIZE, *ks3, DES_BLOCK_SIZE);
2792
2793
        /* Last incomplete block size. 0 means none over. */
2794
0
        lb_sz = sz % DES_BLOCK_SIZE;
2795
        /* Length of data that is a multiple of a block. */
2796
0
        len   = (word32)(sz - lb_sz);
2797
2798
        /* Initialize wolfCrypt DES3 object. */
2799
0
        XMEMSET(des3, 0, sizeof(Des3));
2800
0
        ret = wc_Des3Init(des3, NULL, INVALID_DEVID);
2801
0
        (void)ret;
2802
2803
0
        if (enc == WC_DES_ENCRYPT) {
2804
            /* Initialize wolfCrypt DES3 object. */
2805
0
            if (wc_Des3_SetKey(des3, key, (const byte*)ivec, DES_ENCRYPTION)
2806
0
                    == 0) {
2807
                /* Encrypt full blocks into output. */
2808
0
                ret = wc_Des3_CbcEncrypt(des3, output, input, len);
2809
0
                (void)ret;
2810
            #if defined(WOLFSSL_ASYNC_CRYPT)
2811
                ret = wc_AsyncWait(ret, &des3->asyncDev, WC_ASYNC_FLAG_NONE);
2812
                (void)ret;
2813
            #endif
2814
0
                if (lb_sz != 0) {
2815
                    /* Create a 0 padded block from remaining bytes. */
2816
0
                    XMEMSET(lastBlock, 0, DES_BLOCK_SIZE);
2817
0
                    XMEMCPY(lastBlock, input + len, (size_t)lb_sz);
2818
                    /* Encrypt last block into output. */
2819
0
                    ret = wc_Des3_CbcEncrypt(des3, output + len, lastBlock,
2820
0
                        (word32)DES_BLOCK_SIZE);
2821
0
                    (void)ret;
2822
                #if defined(WOLFSSL_ASYNC_CRYPT)
2823
                    ret = wc_AsyncWait(ret, &des3->asyncDev,
2824
                        WC_ASYNC_FLAG_NONE);
2825
                    (void)ret;
2826
                #endif
2827
                    /* Copy the last encrypted block as IV for next decrypt. */
2828
0
                    XMEMCPY(ivec, output + len, DES_BLOCK_SIZE);
2829
0
                }
2830
0
                else {
2831
                    /* Copy the last encrypted block as IV for next decrypt. */
2832
0
                    XMEMCPY(ivec, output + len - DES_BLOCK_SIZE,
2833
0
                        DES_BLOCK_SIZE);
2834
0
                }
2835
0
            }
2836
0
        }
2837
0
        else {
2838
            /* Initialize wolfCrypt DES3 object. */
2839
0
            if (wc_Des3_SetKey(des3, key, (const byte*)ivec, DES_DECRYPTION)
2840
0
                    == 0) {
2841
                /* Copy the last encrypted block as IV for next decrypt. */
2842
0
                if (lb_sz != 0) {
2843
0
                    XMEMCPY(ivec, input + len, DES_BLOCK_SIZE);
2844
0
                }
2845
0
                else {
2846
0
                    XMEMCPY(ivec, input + len - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
2847
0
                }
2848
                /* Decrypt full blocks into output. */
2849
0
                ret = wc_Des3_CbcDecrypt(des3, output, input, len);
2850
0
                (void)ret;
2851
            #if defined(WOLFSSL_ASYNC_CRYPT)
2852
                ret = wc_AsyncWait(ret, &des3->asyncDev, WC_ASYNC_FLAG_NONE);
2853
                (void)ret;
2854
            #endif
2855
0
                if (lb_sz != 0) {
2856
                   /* Decrypt the last block that is not going to be full size.
2857
                    */
2858
0
                    ret = wc_Des3_CbcDecrypt(des3, lastBlock, input + len,
2859
0
                        (word32)DES_BLOCK_SIZE);
2860
0
                    (void)ret;
2861
                #if defined(WOLFSSL_ASYNC_CRYPT)
2862
                    ret = wc_AsyncWait(ret, &des3->asyncDev,
2863
                        WC_ASYNC_FLAG_NONE);
2864
                    (void)ret;
2865
                #endif
2866
                    /* Copy out the required amount of the decrypted block. */
2867
0
                    XMEMCPY(output + len, lastBlock, (size_t)lb_sz);
2868
0
                }
2869
0
            }
2870
0
        }
2871
0
        wc_Des3Free(des3);
2872
0
    }
2873
2874
0
    WC_FREE_VAR_EX(des3, NULL, DYNAMIC_TYPE_CIPHER);
2875
0
}
2876
2877
#ifdef WOLFSSL_DES_ECB
2878
/* Encrypt or decrypt input message desa with key and get output in desb.
2879
 *
2880
 * @param [in]  in   Block to encipher with DES-ECB.
2881
 * @param [out] out  Enciphered block.
2882
 * @param [in]  key  DES key schedule.
2883
 * @param [in]  enc  Whether to encrypt.
2884
 */
2885
void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* in, WOLFSSL_DES_cblock* out,
2886
    WOLFSSL_DES_key_schedule* key, int enc)
2887
0
{
2888
0
    WC_DECLARE_VAR(des, Des, 1, 0);
2889
2890
0
    WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
2891
2892
    /* Validate parameters. */
2893
0
    if ((in == NULL) || (out == NULL) || (key == NULL) ||
2894
0
           ((enc != WC_DES_ENCRYPT) && (enc != WC_DES_DECRYPT))) {
2895
0
        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
2896
0
    }
2897
0
#ifdef WOLFSSL_SMALL_STACK
2898
0
    else if ((des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_CIPHER))
2899
0
             == NULL)
2900
0
    {
2901
0
        WOLFSSL_MSG("Failed to allocate memory for Des object");
2902
0
    }
2903
0
#endif
2904
    /* Set key in wolfCrypt DES object for encryption or decryption.
2905
     * WC_DES_ENCRYPT = 1, wolfSSL DES_ENCRYPTION = 0.
2906
     * WC_DES_DECRYPT = 0, wolfSSL DES_DECRYPTION = 1.
2907
     */
2908
0
    else if (wc_Des_SetKey(des, (const byte*)key, NULL, !enc) != 0) {
2909
0
        WOLFSSL_MSG("wc_Des_SetKey return error.");
2910
0
    }
2911
0
    else if (enc == WC_DES_ENCRYPT) {
2912
        /* Encrypt a block with wolfCrypt DES object. */
2913
0
        if (wc_Des_EcbEncrypt(des, (byte*)out, (const byte*)in, DES_KEY_SIZE)
2914
0
                != 0) {
2915
0
            WOLFSSL_MSG("wc_Des_EcbEncrypt return error.");
2916
0
        }
2917
0
    }
2918
0
    else {
2919
        /* Decrypt a block with wolfCrypt DES object. */
2920
0
        if (wc_Des_EcbDecrypt(des, (byte*)out, (const byte*)in, DES_KEY_SIZE)
2921
0
                != 0) {
2922
0
            WOLFSSL_MSG("wc_Des_EcbDecrpyt return error.");
2923
0
        }
2924
0
    }
2925
2926
0
    WC_FREE_VAR_EX(des, NULL, DYNAMIC_TYPE_CIPHER);
2927
0
}
2928
#endif
2929
#endif /* NO_DES3 */
2930
#endif /* OPENSSL_EXTRA */
2931
2932
/*******************************************************************************
2933
 * END OF DES API
2934
 ******************************************************************************/
2935
2936
/*******************************************************************************
2937
 * START OF AES API
2938
 ******************************************************************************/
2939
2940
#ifdef OPENSSL_EXTRA
2941
2942
#if !defined(NO_AES) && !defined(WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API)
2943
2944
/* Sets the key into the AES key object for encryption or decryption.
2945
 *
2946
 * TODO: check bits value?
2947
 *
2948
 * @param [in]  key   Key data.
2949
 * @param [in]  bits  Number of bits in key.
2950
 * @param [out] aes   AES key object.
2951
 * @param [in]  enc   Whether to encrypt. AES_ENCRYPTION or AES_DECRYPTION.
2952
 * @return  0 on success.
2953
 * @return  -1 when key or aes is NULL.
2954
 * @return  -1 when setting key with wolfCrypt fails.
2955
 */
2956
static int wolfssl_aes_set_key(const unsigned char *key, const int bits,
2957
    WOLFSSL_AES_KEY *aes, int enc)
2958
{
2959
    wc_static_assert(sizeof(WOLFSSL_AES_KEY) >= sizeof(Aes));
2960
2961
    /* Validate parameters. */
2962
    if ((key == NULL) || (aes == NULL)) {
2963
        WOLFSSL_MSG("Null argument passed in");
2964
        return WOLFSSL_FATAL_ERROR;
2965
    }
2966
2967
    XMEMSET(aes, 0, sizeof(WOLFSSL_AES_KEY));
2968
2969
    if (wc_AesInit((Aes*)aes, NULL, INVALID_DEVID) != 0) {
2970
        WOLFSSL_MSG("Error in initting AES key");
2971
        return WOLFSSL_FATAL_ERROR;
2972
    }
2973
2974
    if (wc_AesSetKey((Aes*)aes, key, (word32)((bits)/8), NULL, enc) != 0) {
2975
        WOLFSSL_MSG("Error in setting AES key");
2976
        return WOLFSSL_FATAL_ERROR;
2977
    }
2978
    return 0;
2979
}
2980
2981
/* Sets the key into the AES key object for encryption.
2982
 *
2983
 * @param [in]  key   Key data.
2984
 * @param [in]  bits  Number of bits in key.
2985
 * @param [out] aes   AES key object.
2986
 * @return  0 on success.
2987
 * @return  -1 when key or aes is NULL.
2988
 * @return  -1 when setting key with wolfCrypt fails.
2989
 */
2990
int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits,
2991
    WOLFSSL_AES_KEY *aes)
2992
{
2993
    WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key");
2994
2995
    return wolfssl_aes_set_key(key, bits, aes, AES_ENCRYPTION);
2996
}
2997
2998
/* Sets the key into the AES key object for decryption.
2999
 *
3000
 * @param [in]  key   Key data.
3001
 * @param [in]  bits  Number of bits in key.
3002
 * @param [out] aes   AES key object.
3003
 * @return  0 on success.
3004
 * @return  -1 when key or aes is NULL.
3005
 * @return  -1 when setting key with wolfCrypt fails.
3006
 */
3007
int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits,
3008
    WOLFSSL_AES_KEY *aes)
3009
{
3010
    WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key");
3011
3012
    return wolfssl_aes_set_key(key, bits, aes, AES_DECRYPTION);
3013
}
3014
3015
#ifdef WOLFSSL_AES_DIRECT
3016
/* Encrypt a 16-byte block of data using AES-ECB.
3017
 *
3018
 * wolfSSL_AES_set_encrypt_key() must have been called.
3019
 *
3020
 * #input must contain WC_AES_BLOCK_SIZE bytes of data.
3021
 * #output must be a buffer at least WC_AES_BLOCK_SIZE bytes in length.
3022
 *
3023
 * @param [in]  input   Data to encrypt.
3024
 * @param [out] output  Encrypted data.
3025
 * @param [in]  key     AES key to use for encryption.
3026
 */
3027
void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
3028
    WOLFSSL_AES_KEY *key)
3029
{
3030
    WOLFSSL_ENTER("wolfSSL_AES_encrypt");
3031
3032
    /* Validate parameters. */
3033
    if ((input == NULL) || (output == NULL) || (key == NULL)) {
3034
        WOLFSSL_MSG("Null argument passed in");
3035
    }
3036
    else
3037
#if !defined(HAVE_SELFTEST) && \
3038
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) \
3039
    || defined(WOLFSSL_KERNEL_MODE))
3040
    /* Encrypt a block with wolfCrypt AES. */
3041
    if (wc_AesEncryptDirect((Aes*)key, output, input) != 0) {
3042
        WOLFSSL_MSG("wc_AesEncryptDirect failed");
3043
    }
3044
#else
3045
    {
3046
        /* Encrypt a block with wolfCrypt AES. */
3047
        wc_AesEncryptDirect((Aes*)key, output, input);
3048
    }
3049
#endif
3050
}
3051
3052
3053
/* Decrypt a 16-byte block of data using AES-ECB.
3054
 *
3055
 * wolfSSL_AES_set_decrypt_key() must have been called.
3056
 *
3057
 * #input must contain WC_AES_BLOCK_SIZE bytes of data.
3058
 * #output must be a buffer at least WC_AES_BLOCK_SIZE bytes in length.
3059
 *
3060
 * @param [in]  input   Data to decrypt.
3061
 * @param [out] output  Decrypted data.
3062
 * @param [in]  key     AES key to use for encryption.
3063
 */
3064
void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
3065
    WOLFSSL_AES_KEY *key)
3066
{
3067
    WOLFSSL_ENTER("wolfSSL_AES_decrypt");
3068
3069
    /* Validate parameters. */
3070
    if ((input == NULL) || (output == NULL) || (key == NULL)) {
3071
        WOLFSSL_MSG("Null argument passed in");
3072
    }
3073
    else
3074
#if !defined(HAVE_SELFTEST) && \
3075
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION3_GE(5,3,0)))
3076
    /* Decrypt a block with wolfCrypt AES. */
3077
    if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) {
3078
        WOLFSSL_MSG("wc_AesDecryptDirect failed");
3079
    }
3080
#else
3081
    {
3082
        /* Decrypt a block with wolfCrypt AES. */
3083
        wc_AesDecryptDirect((Aes*)key, output, input);
3084
    }
3085
#endif
3086
}
3087
#endif /* WOLFSSL_AES_DIRECT */
3088
3089
3090
3091
#ifdef HAVE_AES_ECB
3092
/* Encrypt/decrypt a 16-byte block of data using AES-ECB.
3093
 *
3094
 * wolfSSL_AES_set_encrypt_key() or wolfSSL_AES_set_decrypt_key ()must have been
3095
 * called.
3096
 *
3097
 * #input must contain WC_AES_BLOCK_SIZE bytes of data.
3098
 * #output must be a buffer at least WC_AES_BLOCK_SIZE bytes in length.
3099
 *
3100
 * @param [in]  in   Data to encipher.
3101
 * @param [out] out  Enciphered data.
3102
 * @param [in]  key  AES key to use for encryption/decryption.
3103
 * @param [in]  enc  Whether to encrypt.
3104
 *                   AES_ENCRPT for encryption, AES_DECRYPTION for decryption.
3105
 */
3106
void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out,
3107
    WOLFSSL_AES_KEY *key, const int enc)
3108
{
3109
    WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt");
3110
3111
    /* Validate parameters. */
3112
    if ((key == NULL) || (in == NULL) || (out == NULL)) {
3113
        WOLFSSL_MSG("Error, Null argument passed in");
3114
    }
3115
    else if (enc == AES_ENCRYPTION) {
3116
        /* Encrypt block. */
3117
        if (wc_AesEcbEncrypt((Aes*)key, out, in, WC_AES_BLOCK_SIZE) != 0) {
3118
            WOLFSSL_MSG("Error with AES CBC encrypt");
3119
        }
3120
    }
3121
    else {
3122
    #ifdef HAVE_AES_DECRYPT
3123
        /* Decrypt block. */
3124
        if (wc_AesEcbDecrypt((Aes*)key, out, in, WC_AES_BLOCK_SIZE) != 0) {
3125
            WOLFSSL_MSG("Error with AES CBC decrypt");
3126
        }
3127
    #else
3128
        WOLFSSL_MSG("AES decryption not compiled in");
3129
    #endif
3130
    }
3131
}
3132
#endif /* HAVE_AES_ECB */
3133
3134
#ifdef HAVE_AES_CBC
3135
/* Encrypt/decrypt data with IV using AES-CBC.
3136
 *
3137
 * wolfSSL_AES_set_encrypt_key() or wolfSSL_AES_set_decrypt_key() must have been
3138
 * called.
3139
 *
3140
 * @param [in]       in   Data to encipher.
3141
 * @param [out]      out  Enciphered data.
3142
 * @param [in]       len  Length of data to encipher.
3143
 * @param [in]       key  AES key to use for encryption/decryption.
3144
 * @param [in, out]  iv   Initialization Vector (IV) of CBC mode.
3145
 *                        On in, used with first block.
3146
 *                        On out, IV for further operations.
3147
 * @param [in]       enc  Whether to encrypt.
3148
 *                   AES_ENCRPT for encryption, AES_DECRYPTION for decryption.
3149
 */
3150
void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
3151
    size_t len, WOLFSSL_AES_KEY *key, unsigned char* iv, const int enc)
3152
{
3153
    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
3154
3155
    /* Validate parameters. */
3156
    if ((key == NULL) || (in == NULL) || (out == NULL) || (iv == NULL) ||
3157
            (len == 0)) {
3158
        WOLFSSL_MSG("Error, Null argument passed in");
3159
    }
3160
    /* Set IV for operation. */
3161
    else {
3162
        int ret;
3163
        Aes* aes = (Aes*)key;
3164
3165
        if ((ret = wc_AesSetIV(aes, (const byte*)iv)) != 0) {
3166
            WOLFSSL_MSG("Error with setting iv");
3167
        }
3168
        else if (enc == AES_ENCRYPTION) {
3169
            /* Encrypt with wolfCrypt AES object. */
3170
            if ((ret = wc_AesCbcEncrypt(aes, out, in, (word32)len)) != 0) {
3171
                WOLFSSL_MSG("Error with AES CBC encrypt");
3172
            }
3173
        }
3174
        else {
3175
            /* Decrypt with wolfCrypt AES object. */
3176
            if ((ret = wc_AesCbcDecrypt(aes, out, in, (word32)len)) != 0) {
3177
                WOLFSSL_MSG("Error with AES CBC decrypt");
3178
            }
3179
        }
3180
3181
        if (ret == 0) {
3182
            /* Get IV for next operation. */
3183
            XMEMCPY(iv, (byte*)(aes->reg), WC_AES_BLOCK_SIZE);
3184
        }
3185
    }
3186
}
3187
#endif /* HAVE_AES_CBC */
3188
3189
3190
/* Encrypt/decrypt data with IV using AES-CFB.
3191
 *
3192
 * wolfSSL_AES_set_encrypt_key() must have been called.
3193
 *
3194
 * @param [in]       in   Data to encipher.
3195
 * @param [out]      out  Enciphered data.
3196
 * @param [in]       len  Length of data to encipher.
3197
 * @param [in]       key  AES key to use for encryption/decryption.
3198
 * @param [in, out]  iv   Initialization Vector (IV) of CFB mode.
3199
 *                        On in, used with first block.
3200
 *                        On out, IV for further operations.
3201
 * @param [out]      num  Number of bytes used from last incomplete block.
3202
 * @param [in]       enc  Whether to encrypt.
3203
 *                   AES_ENCRPT for encryption, AES_DECRYPTION for decryption.
3204
 */
3205
void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
3206
    size_t len, WOLFSSL_AES_KEY *key, unsigned char* iv, int* num, const int enc)
3207
{
3208
#ifndef WOLFSSL_AES_CFB
3209
    WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
3210
3211
    (void)in;
3212
    (void)out;
3213
    (void)len;
3214
    (void)key;
3215
    (void)iv;
3216
    (void)num;
3217
    (void)enc;
3218
#else
3219
    WOLFSSL_ENTER("wolfSSL_AES_cfb_encrypt");
3220
3221
    /* Validate parameters. */
3222
    if ((key == NULL) || (in == NULL) || (out == NULL) || (iv == NULL)) {
3223
        WOLFSSL_MSG("Error, Null argument passed in");
3224
    }
3225
    else {
3226
        int ret;
3227
        Aes* aes = (Aes*)key;
3228
3229
        /* Copy the IV directly into reg here because wc_AesSetIV clears
3230
         * leftover bytes field "left", and this function relies on the leftover
3231
         * bytes being preserved between calls.
3232
         */
3233
        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
3234
3235
        if (enc == AES_ENCRYPTION) {
3236
            /* Encrypt data with AES-CFB. */
3237
            if ((ret = wc_AesCfbEncrypt(aes, out, in, (word32)len)) != 0) {
3238
                WOLFSSL_MSG("Error with AES CBC encrypt");
3239
            }
3240
        }
3241
        else {
3242
            /* Decrypt data with AES-CFB. */
3243
            if ((ret = wc_AesCfbDecrypt(aes, out, in, (word32)len)) != 0) {
3244
                WOLFSSL_MSG("Error with AES CBC decrypt");
3245
            }
3246
        }
3247
3248
        if (ret == 0) {
3249
            /* Copy IV out after operation. */
3250
            XMEMCPY(iv, (byte*)(aes->reg), WC_AES_BLOCK_SIZE);
3251
3252
            /* Store number of left over bytes to num. */
3253
            if (num != NULL) {
3254
                *num = (WC_AES_BLOCK_SIZE - aes->left) % WC_AES_BLOCK_SIZE;
3255
            }
3256
        }
3257
    }
3258
#endif /* WOLFSSL_AES_CFB */
3259
}
3260
3261
/* wc_AesKey*Wrap_ex API not available in FIPS and SELFTEST */
3262
#if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
3263
/* Wrap (encrypt) a key using RFC3394 AES key wrap.
3264
 *
3265
 * @param [in, out] key   AES key.
3266
 * @param [in]      iv    Initialization vector used by encryption mode.
3267
 * @param [out]     out   Wrapped key.
3268
 * @param [in]      in    Key data to wrap.
3269
 * @param [in]      inSz  Length of key to wrap in bytes.
3270
 * @return  Length of encrypted key in bytes.
3271
 * @return  0 when key, iv, out or in is NULL.
3272
 * @return  0 when key length is not valid.
3273
 */
3274
int wolfSSL_AES_wrap_key(WOLFSSL_AES_KEY *key, const unsigned char *iv,
3275
    unsigned char *out, const unsigned char *in, unsigned int inSz)
3276
{
3277
    int ret = 0;
3278
    int len = 0;
3279
3280
    WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
3281
3282
    /* Validate parameters. */
3283
    if ((out == NULL) || (in == NULL)) {
3284
        WOLFSSL_MSG("Error, Null argument passed in");
3285
        ret = BAD_FUNC_ARG;
3286
    }
3287
3288
    /* Wrap key. */
3289
    if ((ret == 0) && ((ret = wc_AesKeyWrap_ex((Aes*)key, in, inSz, out,
3290
            inSz + KEYWRAP_BLOCK_SIZE, iv)) > 0)) {
3291
        /* Get the length of the wrapped key. */
3292
        len = ret;
3293
    }
3294
3295
    return len;
3296
}
3297
3298
/* Unwrap (decrypt) a key using RFC3394 AES key wrap.
3299
 *
3300
 * @param [in, out] key   AES key.
3301
 * @param [in]      iv    Initialization vector used by decryption mode.
3302
 * @param [out]     out   Unwrapped key.
3303
 * @param [in]      in    Wrapped key data.
3304
 * @param [in]      inSz  Length of wrapped key data in bytes.
3305
 * @return  Length of decrypted key in bytes.
3306
 * @return  0 when key, iv, out or in is NULL.
3307
 * @return  0 when wrapped key data length is not valid.
3308
 */
3309
int wolfSSL_AES_unwrap_key(WOLFSSL_AES_KEY *key, const unsigned char *iv,
3310
    unsigned char *out, const unsigned char *in, unsigned int inSz)
3311
{
3312
    int ret = 0;
3313
    int len = 0;
3314
3315
    WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
3316
3317
    /* Validate parameters. */
3318
    if ((out == NULL) || (in == NULL)) {
3319
        WOLFSSL_MSG("Error, Null argument passed in");
3320
        ret = BAD_FUNC_ARG;
3321
    }
3322
3323
    /* Unwrap key. */
3324
    if ((ret == 0) && ((ret = wc_AesKeyUnWrap_ex((Aes*)key, in, inSz, out,
3325
            inSz + KEYWRAP_BLOCK_SIZE, iv)) > 0)) {
3326
        /* Get the length of the unwrapped key. */
3327
        len = ret;
3328
    }
3329
3330
    return len;
3331
}
3332
#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */
3333
3334
#ifdef HAVE_CTS
3335
/* Ciphertext stealing encryption compatible with RFC2040 and RFC3962.
3336
 *
3337
 * @param [in]  in   Data to encrypt.
3338
 * @param [out] out  Encrypted data.
3339
 * @param [in]  len  Length of data to encrypt.
3340
 * @param [in]  key  Symmetric key.
3341
 * @param [in]  iv   Initialization Vector for encryption mode.
3342
 * @param [in]  cbc  CBC mode encryption function.
3343
 * @return  Length of encrypted data in bytes on success.
3344
 * @return  0 when in, out, cbc, key or iv are NULL.
3345
 * @return  0 when len is less than or equal to 16 bytes.
3346
 */
3347
size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in,
3348
    unsigned char *out, size_t len, const void *key, unsigned char *iv,
3349
    WOLFSSL_CBC128_CB cbc)
3350
{
3351
    byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
3352
    int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
3353
3354
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt");
3355
3356
    /* Validate parameters. */
3357
    if ((in == NULL) || (out == NULL) || (len <= WOLFSSL_CTS128_BLOCK_SZ) ||
3358
            (cbc == NULL) || (key == NULL) || (iv == NULL)) {
3359
        WOLFSSL_MSG("Bad parameter");
3360
        len = 0;
3361
    }
3362
3363
    if (len > 0) {
3364
        /* Must have a last block. */
3365
        if (lastBlkLen == 0) {
3366
            lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
3367
        }
3368
3369
        /* Encrypt data up to last block */
3370
        (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPTION);
3371
3372
        /* Move to last block */
3373
        in += len - lastBlkLen;
3374
        out += len - lastBlkLen;
3375
3376
        /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */
3377
        XMEMCPY(lastBlk, in, lastBlkLen);
3378
        XMEMSET(lastBlk + lastBlkLen, 0, WOLFSSL_CTS128_BLOCK_SZ - lastBlkLen);
3379
        /* RFC2040: Select the first Ln bytes of En-1 to create Cn */
3380
        XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
3381
        /* Encrypt last block. */
3382
        (*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ,
3383
                key, iv, AES_ENCRYPTION);
3384
    }
3385
3386
    return len;
3387
}
3388
3389
/* Ciphertext stealing decryption compatible with RFC2040 and RFC3962.
3390
 *
3391
 * @param [in]  in   Data to decrypt.
3392
 * @param [out] out  Decrypted data.
3393
 * @param [in]  len  Length of data to decrypt.
3394
 * @param [in]  key  Symmetric key.
3395
 * @param [in]  iv   Initialization Vector for decryption mode.
3396
 * @param [in]  cbc  CBC mode encryption function.
3397
 * @return  Length of decrypted data in bytes on success.
3398
 * @return  0 when in, out, cbc, key or iv are NULL.
3399
 * @return  0 when len is less than or equal to 16 bytes.
3400
 */
3401
size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
3402
    unsigned char *out, size_t len, const void *key, unsigned char *iv,
3403
    WOLFSSL_CBC128_CB cbc)
3404
{
3405
    byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
3406
    byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ];
3407
    int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
3408
3409
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt");
3410
3411
    /* Validate parameters. */
3412
    if ((in == NULL) || (out == NULL) || (len <= WOLFSSL_CTS128_BLOCK_SZ) ||
3413
            (cbc == NULL) || (key == NULL) || (iv == NULL)) {
3414
        WOLFSSL_MSG("Bad parameter");
3415
        len = 0;
3416
    }
3417
3418
    if (len > 0) {
3419
        /* Must have a last block. */
3420
        if (lastBlkLen == 0) {
3421
            lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
3422
        }
3423
3424
        if (len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ != 0) {
3425
            /* Decrypt up to last two blocks */
3426
            (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv,
3427
                    AES_DECRYPTION);
3428
3429
            /* Move to last two blocks */
3430
            in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
3431
            out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
3432
        }
3433
3434
        /* RFC2040: Decrypt Cn-1 to create Dn.
3435
         * Use 0 buffer as IV to do straight decryption.
3436
         * This places the Cn-1 block at lastBlk */
3437
        XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ);
3438
        (*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, AES_DECRYPTION);
3439
        /* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn
3440
         *          to create En. */
3441
        XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
3442
        /* Cn and Cn-1 can now be decrypted */
3443
        (*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPTION);
3444
        (*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPTION);
3445
        XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen);
3446
    }
3447
3448
    return len;
3449
}
3450
#endif /* HAVE_CTS */
3451
#endif /* !NO_AES && !WOLFSSL_NO_OPENSSL_AES_LOW_LEVEL_API */
3452
#endif /* OPENSSL_EXTRA */
3453
3454
/*******************************************************************************
3455
 * END OF AES API
3456
 ******************************************************************************/
3457
3458
/*******************************************************************************
3459
 * START OF RC4 API
3460
 ******************************************************************************/
3461
3462
#ifdef OPENSSL_EXTRA
3463
3464
#ifndef NO_RC4
3465
/* Set the key state for Arc4 key.
3466
 *
3467
 * @param [out] key   Arc4 key.
3468
 * @param [in]  len   Length of key in buffer.
3469
 * @param [in]  data  Key data buffer.
3470
 */
3471
void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len,
3472
    const unsigned char* data)
3473
0
{
3474
0
    wc_static_assert(sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4));
3475
3476
0
    WOLFSSL_ENTER("wolfSSL_RC4_set_key");
3477
3478
    /* Validate parameters. */
3479
0
    if ((key == NULL) || (len < 0) || (data == NULL)) {
3480
0
        WOLFSSL_MSG("bad argument passed in");
3481
0
    }
3482
0
    else {
3483
        /* Reset wolfCrypt Arc4 object. */
3484
0
        XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY));
3485
        /* Set key into wolfCrypt Arc4 object. */
3486
0
        wc_Arc4SetKey((Arc4*)key, data, (word32)len);
3487
0
    }
3488
0
}
3489
3490
3491
/* Encrypt/decrypt with Arc4 key.
3492
 *
3493
 * @param [in]  len  Length of data to encrypt/decrypt.
3494
 * @param [in]  in   Data to encrypt/decrypt.
3495
 * @param [out] out  Enciphered data.
3496
 */
3497
void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len, const unsigned char* in,
3498
    unsigned char* out)
3499
0
{
3500
0
    WOLFSSL_ENTER("wolfSSL_RC4");
3501
3502
    /* Validate parameters. */
3503
0
    if ((key == NULL) || (in == NULL) || (out == NULL)) {
3504
0
        WOLFSSL_MSG("Bad argument passed in");
3505
0
    }
3506
0
    else {
3507
        /* Encrypt/decrypt data. */
3508
0
        wc_Arc4Process((Arc4*)key, out, in, (word32)len);
3509
0
    }
3510
0
}
3511
#endif /* NO_RC4 */
3512
3513
#endif /* OPENSSL_EXTRA */
3514
3515
/*******************************************************************************
3516
 * END OF RC4 API
3517
 ******************************************************************************/
3518
3519
#endif /* WOLFSSL_SSL_CRYPTO_INCLUDED */
3520