Coverage Report

Created: 2025-12-31 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-heapmath/wolfcrypt/src/kdf.c
Line
Count
Source
1
/* kdf.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 NO_KDF
25
26
#if FIPS_VERSION3_GE(5,0,0)
27
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
28
    #define FIPS_NO_WRAPPERS
29
30
    #ifdef USE_WINDOWS_API
31
        #pragma code_seg(".fipsA$h")
32
        #pragma const_seg(".fipsB$h")
33
    #endif
34
#endif
35
36
37
#ifdef NO_INLINE
38
    #include <wolfssl/wolfcrypt/misc.h>
39
#else
40
    #define WOLFSSL_MISC_INCLUDED
41
    #include <wolfcrypt/src/misc.c>
42
#endif
43
44
#include <wolfssl/wolfcrypt/hmac.h>
45
#include <wolfssl/wolfcrypt/kdf.h>
46
#if defined(WC_SRTP_KDF) || defined(HAVE_CMAC_KDF)
47
    #include <wolfssl/wolfcrypt/aes.h>
48
#endif
49
#ifdef WOLF_CRYPTO_CB
50
    #include <wolfssl/wolfcrypt/cryptocb.h>
51
#endif
52
53
#if FIPS_VERSION3_GE(6,0,0)
54
    const unsigned int wolfCrypt_FIPS_kdf_ro_sanity[2] =
55
                                                     { 0x1a2b3c4d, 0x00000009 };
56
    int wolfCrypt_FIPS_KDF_sanity(void)
57
    {
58
        return 0;
59
    }
60
#endif
61
62
#if defined(WOLFSSL_HAVE_PRF) && !defined(NO_HMAC)
63
64
#ifdef WOLFSSL_SHA512
65
0
    #define P_HASH_MAX_SIZE WC_SHA512_DIGEST_SIZE
66
#elif defined(WOLFSSL_SHA384)
67
    #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE
68
#else
69
    #define P_HASH_MAX_SIZE WC_SHA256_DIGEST_SIZE
70
#endif
71
72
/* Pseudo Random Function for MD5, SHA-1, SHA-256, SHA-384, or SHA-512 */
73
int wc_PRF(byte* result, word32 resLen, const byte* secret,
74
                  word32 secLen, const byte* seed, word32 seedLen, int hash,
75
                  void* heap, int devId)
76
0
{
77
0
    word32 len = P_HASH_MAX_SIZE;
78
0
    word32 times;
79
0
    word32 lastLen;
80
0
    word32 lastTime;
81
0
    int    ret = 0;
82
0
#ifdef WOLFSSL_SMALL_STACK
83
0
    byte*  current;
84
0
    Hmac*  hmac;
85
#else
86
    byte   current[P_HASH_MAX_SIZE];   /* max size */
87
    Hmac   hmac[1];
88
#endif
89
90
0
    switch (hash) {
91
0
    #ifndef NO_MD5
92
0
        case md5_mac:
93
0
            hash = WC_MD5;
94
0
            len  = WC_MD5_DIGEST_SIZE;
95
0
        break;
96
0
    #endif
97
98
0
    #ifndef NO_SHA256
99
0
        case sha256_mac:
100
0
            hash = WC_SHA256;
101
0
            len  = WC_SHA256_DIGEST_SIZE;
102
0
        break;
103
0
    #endif
104
105
0
    #ifdef WOLFSSL_SHA384
106
0
        case sha384_mac:
107
0
            hash = WC_SHA384;
108
0
            len  = WC_SHA384_DIGEST_SIZE;
109
0
        break;
110
0
    #endif
111
112
0
    #ifdef WOLFSSL_SHA512
113
0
        case sha512_mac:
114
0
            hash = WC_SHA512;
115
0
            len  = WC_SHA512_DIGEST_SIZE;
116
0
        break;
117
0
    #endif
118
119
0
    #ifdef WOLFSSL_SM3
120
0
        case sm3_mac:
121
0
            hash = WC_SM3;
122
0
            len  = WC_SM3_DIGEST_SIZE;
123
0
        break;
124
0
    #endif
125
126
0
    #ifndef NO_SHA
127
0
        case sha_mac:
128
0
            hash = WC_SHA;
129
0
            len  = WC_SHA_DIGEST_SIZE;
130
0
        break;
131
0
    #endif
132
0
        default:
133
0
            return HASH_TYPE_E;
134
0
    }
135
136
0
    times   = resLen / len;
137
0
    lastLen = resLen % len;
138
139
0
    if (lastLen)
140
0
        times += 1;
141
142
    /* times == 0 if resLen == 0, but times == 0 abides clang static analyzer
143
       while resLen == 0 doesn't */
144
0
    if (times == 0)
145
0
        return BAD_FUNC_ARG;
146
147
0
    lastTime = times - 1;
148
149
0
#ifdef WOLFSSL_SMALL_STACK
150
0
    current = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
151
0
    hmac    = (Hmac*)XMALLOC(sizeof(Hmac),    heap, DYNAMIC_TYPE_HMAC);
152
0
    if (current == NULL || hmac == NULL) {
153
0
        XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
154
0
        XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
155
0
        return MEMORY_E;
156
0
    }
157
0
#endif
158
#ifdef WOLFSSL_CHECK_MEM_ZERO
159
    XMEMSET(current, 0xff, P_HASH_MAX_SIZE);
160
    wc_MemZero_Add("wc_PRF current", current, P_HASH_MAX_SIZE);
161
    wc_MemZero_Add("wc_PRF hmac", hmac, sizeof(Hmac));
162
#endif
163
164
0
    ret = wc_HmacInit(hmac, heap, devId);
165
0
    if (ret == 0) {
166
0
        ret = wc_HmacSetKey(hmac, hash, secret, secLen);
167
0
        if (ret == 0)
168
0
            ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */
169
0
        if (ret == 0)
170
0
            ret = wc_HmacFinal(hmac, current);        /* A1 */
171
0
        if (ret == 0) {
172
0
            word32 i;
173
0
            word32 idx = 0;
174
175
0
            for (i = 0; i < times; i++) {
176
0
                ret = wc_HmacUpdate(hmac, current, len);
177
0
                if (ret != 0)
178
0
                    break;
179
0
                ret = wc_HmacUpdate(hmac, seed, seedLen);
180
0
                if (ret != 0)
181
0
                    break;
182
0
                if ((i != lastTime) || !lastLen) {
183
0
                    ret = wc_HmacFinal(hmac, &result[idx]);
184
0
                    if (ret != 0)
185
0
                        break;
186
0
                    idx += len;
187
188
0
                    ret = wc_HmacUpdate(hmac, current, len);
189
0
                    if (ret != 0)
190
0
                        break;
191
0
                    ret = wc_HmacFinal(hmac, current);
192
0
                    if (ret != 0)
193
0
                        break;
194
0
                }
195
0
                else {
196
0
                    ret = wc_HmacFinal(hmac, current);
197
0
                    if (ret != 0)
198
0
                        break;
199
0
                    XMEMCPY(&result[idx], current,
200
0
                                             min(lastLen, P_HASH_MAX_SIZE));
201
0
                }
202
0
            }
203
0
        }
204
0
        wc_HmacFree(hmac);
205
0
    }
206
207
0
    ForceZero(current, P_HASH_MAX_SIZE);
208
0
    ForceZero(hmac,    sizeof(Hmac));
209
210
#if defined(WOLFSSL_CHECK_MEM_ZERO)
211
    wc_MemZero_Check(current, P_HASH_MAX_SIZE);
212
    wc_MemZero_Check(hmac,    sizeof(Hmac));
213
#endif
214
215
0
    WC_FREE_VAR_EX(current, heap, DYNAMIC_TYPE_DIGEST);
216
0
    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
217
218
0
    return ret;
219
0
}
220
#undef P_HASH_MAX_SIZE
221
222
/* compute PRF (pseudo random function) using SHA1 and MD5 for TLSv1 */
223
int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
224
           word32 secLen, const byte* label, word32 labLen,
225
           const byte* seed, word32 seedLen, void* heap, int devId)
226
251
{
227
251
    int         ret  = 0;
228
251
    word32      half = (secLen + 1) / 2;
229
251
    const byte* md5_half;
230
251
    const byte* sha_half;
231
251
    byte*      md5_result;
232
251
#ifdef WOLFSSL_SMALL_STACK
233
251
    byte*      sha_result;
234
251
    byte*      labelSeed;
235
#else
236
    byte       sha_result[MAX_PRF_DIG];    /* digLen is real size */
237
    byte       labelSeed[MAX_PRF_LABSEED];
238
#endif
239
240
251
    if (half > MAX_PRF_HALF ||
241
251
        labLen + seedLen > MAX_PRF_LABSEED ||
242
251
        digLen > MAX_PRF_DIG)
243
0
    {
244
0
        return BUFFER_E;
245
0
    }
246
247
251
#ifdef WOLFSSL_SMALL_STACK
248
251
    sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
249
251
    labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST);
250
251
    if (sha_result == NULL || labelSeed == NULL) {
251
0
        XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
252
0
        XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
253
0
        return MEMORY_E;
254
0
    }
255
251
#endif
256
257
251
    md5_half = secret;
258
251
    sha_half = secret + half - secLen % 2;
259
251
    md5_result = digest;
260
261
251
    XMEMCPY(labelSeed, label, labLen);
262
251
    XMEMCPY(labelSeed + labLen, seed, seedLen);
263
264
251
    if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
265
251
                                labLen + seedLen, md5_mac, heap, devId)) == 0) {
266
251
        if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
267
251
                                labLen + seedLen, sha_mac, heap, devId)) == 0) {
268
        #ifdef WOLFSSL_CHECK_MEM_ZERO
269
            wc_MemZero_Add("wc_PRF_TLSv1 sha_result", sha_result, digLen);
270
        #endif
271
            /* calculate XOR for TLSv1 PRF */
272
            /* md5 result is placed directly in digest */
273
251
            xorbuf(digest, sha_result, digLen);
274
251
            ForceZero(sha_result, digLen);
275
251
        }
276
251
    }
277
278
#if defined(WOLFSSL_CHECK_MEM_ZERO)
279
    wc_MemZero_Check(sha_result, MAX_PRF_DIG);
280
#endif
281
282
251
    WC_FREE_VAR_EX(sha_result, heap, DYNAMIC_TYPE_DIGEST);
283
251
    WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
284
285
251
    return ret;
286
251
}
287
288
/* Wrapper for TLS 1.2 and TLSv1 cases to calculate PRF */
289
/* In TLS 1.2 case call straight thru to wc_PRF */
290
int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
291
            const byte* label, word32 labLen, const byte* seed, word32 seedLen,
292
            int useAtLeastSha256, int hash_type, void* heap, int devId)
293
3.97k
{
294
3.97k
    int ret = 0;
295
296
#ifdef WOLFSSL_DEBUG_TLS
297
    WOLFSSL_MSG("  secret");
298
    WOLFSSL_BUFFER(secret, secLen);
299
    WOLFSSL_MSG("  label");
300
    WOLFSSL_BUFFER(label, labLen);
301
    WOLFSSL_MSG("  seed");
302
    WOLFSSL_BUFFER(seed, seedLen);
303
#endif
304
305
3.97k
    if (useAtLeastSha256) {
306
3.72k
        WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, 0);
307
308
3.72k
        if (labLen + seedLen > MAX_PRF_LABSEED) {
309
0
            return BUFFER_E;
310
0
        }
311
312
3.72k
        WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap,
313
3.72k
            DYNAMIC_TYPE_DIGEST, return MEMORY_E);
314
315
3.72k
        XMEMCPY(labelSeed, label, labLen);
316
3.72k
        XMEMCPY(labelSeed + labLen, seed, seedLen);
317
318
        /* If a cipher suite wants an algorithm better than sha256, it
319
         * should use better. */
320
3.72k
        if (hash_type < sha256_mac || hash_type == blake2b_mac) {
321
371
            hash_type = sha256_mac;
322
371
        }
323
        /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
324
3.72k
        ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
325
3.72k
                     labLen + seedLen, hash_type, heap, devId);
326
327
3.72k
        WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
328
3.72k
    }
329
251
    else {
330
#ifndef NO_OLD_TLS
331
        /* compute TLSv1 PRF (pseudo random function using HMAC) */
332
        ret = wc_PRF_TLSv1(digest, digLen, secret, secLen, label, labLen, seed,
333
                          seedLen, heap, devId);
334
#else
335
251
        ret = BAD_FUNC_ARG;
336
251
#endif
337
251
    }
338
339
#ifdef WOLFSSL_DEBUG_TLS
340
    WOLFSSL_MSG("  digest");
341
    WOLFSSL_BUFFER(digest, digLen);
342
    WOLFSSL_MSG_EX("hash_type %d", hash_type);
343
#endif
344
345
3.97k
    return ret;
346
3.97k
}
347
#endif /* WOLFSSL_HAVE_PRF && !NO_HMAC */
348
349
350
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
351
352
    /* Extract data using HMAC, salt and input.
353
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
354
     */
355
    int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, word32 saltLen,
356
        byte* ikm, word32 ikmLen, int digest, void* heap, int devId)
357
    {
358
        int ret;
359
        word32 len = 0;
360
361
        switch (digest) {
362
            #ifndef NO_SHA256
363
            case WC_SHA256:
364
                len = WC_SHA256_DIGEST_SIZE;
365
                break;
366
            #endif
367
368
            #ifdef WOLFSSL_SHA384
369
            case WC_SHA384:
370
                len = WC_SHA384_DIGEST_SIZE;
371
                break;
372
            #endif
373
374
            #ifdef WOLFSSL_TLS13_SHA512
375
            case WC_SHA512:
376
                len = WC_SHA512_DIGEST_SIZE;
377
                break;
378
            #endif
379
380
            #ifdef WOLFSSL_SM3
381
            case WC_SM3:
382
                len = WC_SM3_DIGEST_SIZE;
383
                break;
384
            #endif
385
386
            default:
387
                return BAD_FUNC_ARG;
388
        }
389
390
        /* When length is 0 then use zeroed data of digest length. */
391
        if (ikmLen == 0) {
392
            ikmLen = len;
393
            XMEMSET(ikm, 0, len);
394
        }
395
396
#ifdef WOLFSSL_DEBUG_TLS
397
        WOLFSSL_MSG("  Salt");
398
        WOLFSSL_BUFFER(salt, saltLen);
399
        WOLFSSL_MSG("  IKM");
400
        WOLFSSL_BUFFER(ikm, ikmLen);
401
#endif
402
403
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
404
    (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
405
        ret = wc_HKDF_Extract_ex(digest, salt, saltLen, ikm, ikmLen, prk, heap,
406
            devId);
407
#else
408
        ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
409
        (void)heap;
410
        (void)devId;
411
#endif
412
413
#ifdef WOLFSSL_DEBUG_TLS
414
        WOLFSSL_MSG("  PRK");
415
        WOLFSSL_BUFFER(prk, len);
416
#endif
417
418
        return ret;
419
    }
420
421
    int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen,
422
                                 byte* ikm, word32 ikmLen, int digest)
423
0
    {
424
0
        return wc_Tls13_HKDF_Extract_ex(prk, salt, saltLen, ikm, ikmLen, digest,
425
0
            NULL, INVALID_DEVID);
426
0
    }
427
428
    /* Expand data using HMAC, salt and label and info.
429
     * TLS v1.3 defines this function. */
430
    int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen,
431
                                 const byte* prk, word32 prkLen,
432
                                 const byte* protocol, word32 protocolLen,
433
                                 const byte* label, word32 labelLen,
434
                                 const byte* info, word32 infoLen,
435
                                 int digest, void* heap, int devId)
436
13.0k
    {
437
13.0k
        int    ret = 0;
438
13.0k
        word32 idx = 0;
439
13.0k
        WC_DECLARE_VAR(data, byte, MAX_TLS13_HKDF_LABEL_SZ, 0);
440
441
        /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
442
         * labellen + infolen */
443
13.0k
        idx = 4 + protocolLen + labelLen + infoLen;
444
13.0k
        if (idx > MAX_TLS13_HKDF_LABEL_SZ) {
445
0
            return BUFFER_E;
446
0
        }
447
448
13.0k
        WC_ALLOC_VAR_EX(data, byte, idx, NULL, DYNAMIC_TYPE_TMP_BUFFER,
449
13.0k
            return MEMORY_E);
450
12.9k
        idx = 0;
451
452
        /* Output length. */
453
12.9k
        data[idx++] = (byte)(okmLen >> 8);
454
12.9k
        data[idx++] = (byte)okmLen;
455
        /* Length of protocol | label. */
456
12.9k
        data[idx++] = (byte)(protocolLen + labelLen);
457
12.9k
        if (protocolLen > 0) {
458
            /* Protocol */
459
12.9k
            XMEMCPY(&data[idx], protocol, protocolLen);
460
12.9k
            idx += protocolLen;
461
12.9k
        }
462
12.9k
        if (labelLen > 0) {
463
            /* Label */
464
12.9k
            XMEMCPY(&data[idx], label, labelLen);
465
12.9k
            idx += labelLen;
466
12.9k
        }
467
        /* Length of hash of messages */
468
12.9k
        data[idx++] = (byte)infoLen;
469
12.9k
        if (infoLen > 0) {
470
            /* Hash of messages */
471
5.91k
            XMEMCPY(&data[idx], info, infoLen);
472
5.91k
            idx += infoLen;
473
5.91k
        }
474
475
    #ifdef WOLFSSL_CHECK_MEM_ZERO
476
        wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
477
    #endif
478
479
#ifdef WOLFSSL_DEBUG_TLS
480
        WOLFSSL_MSG("  PRK");
481
        WOLFSSL_BUFFER(prk, prkLen);
482
        WOLFSSL_MSG("  Info");
483
        WOLFSSL_BUFFER(data, idx);
484
        WOLFSSL_MSG_EX("  Digest %d", digest);
485
#endif
486
487
12.9k
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
488
12.9k
    (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
489
12.9k
        ret = wc_HKDF_Expand_ex(digest, prk, prkLen, data, idx, okm, okmLen,
490
12.9k
            heap, devId);
491
#else
492
        ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
493
        (void)heap;
494
        (void)devId;
495
#endif
496
497
#ifdef WOLFSSL_DEBUG_TLS
498
        WOLFSSL_MSG("  OKM");
499
        WOLFSSL_BUFFER(okm, okmLen);
500
#endif
501
502
12.9k
        ForceZero(data, idx);
503
504
    #ifdef WOLFSSL_CHECK_MEM_ZERO
505
        wc_MemZero_Check(data, idx);
506
    #endif
507
12.9k
        WC_FREE_VAR_EX(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
508
12.9k
        return ret;
509
13.0k
    }
510
511
    int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
512
                                 const byte* prk, word32 prkLen,
513
                                 const byte* protocol, word32 protocolLen,
514
                                 const byte* label, word32 labelLen,
515
                                 const byte* info, word32 infoLen,
516
                                 int digest)
517
0
    {
518
0
        return wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, protocol,
519
0
            protocolLen, label, labelLen, info, infoLen, digest,
520
0
            NULL, INVALID_DEVID);
521
0
    }
522
523
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                    \
524
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
525
    /* Expand data using HMAC, salt and label and info.
526
     * TLS v1.3 defines this function. */
527
    int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen,
528
        const byte* prk, word32 prkLen, const byte* protocol,
529
        word32 protocolLen, const byte* label, word32 labelLen,
530
        const byte* info, word32 infoLen, int digest, void* heap)
531
    {
532
        int    ret = 0;
533
        word32 idx = 0;
534
        size_t len;
535
        byte   *data;
536
537
        (void)heap;
538
        /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
539
         * labellen + infolen */
540
        len = 4U + protocolLen + labelLen + infoLen;
541
542
        data = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);
543
        if (data == NULL)
544
            return BUFFER_E;
545
546
        /* Output length. */
547
        data[idx++] = (byte)(okmLen >> 8);
548
        data[idx++] = (byte)okmLen;
549
        /* Length of protocol | label. */
550
        data[idx++] = (byte)(protocolLen + labelLen);
551
        /* Protocol */
552
        XMEMCPY(&data[idx], protocol, protocolLen);
553
        idx += protocolLen;
554
        /* Label */
555
        XMEMCPY(&data[idx], label, labelLen);
556
        idx += labelLen;
557
        /* Length of hash of messages */
558
        data[idx++] = (byte)infoLen;
559
        /* Hash of messages */
560
        XMEMCPY(&data[idx], info, infoLen);
561
        idx += infoLen;
562
563
    #ifdef WOLFSSL_CHECK_MEM_ZERO
564
        wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
565
    #endif
566
567
#ifdef WOLFSSL_DEBUG_TLS
568
        WOLFSSL_MSG("  PRK");
569
        WOLFSSL_BUFFER(prk, prkLen);
570
        WOLFSSL_MSG("  Info");
571
        WOLFSSL_BUFFER(data, idx);
572
        WOLFSSL_MSG_EX("  Digest %d", digest);
573
#endif
574
575
        ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
576
577
#ifdef WOLFSSL_DEBUG_TLS
578
        WOLFSSL_MSG("  OKM");
579
        WOLFSSL_BUFFER(okm, okmLen);
580
#endif
581
582
        ForceZero(data, idx);
583
584
    #ifdef WOLFSSL_CHECK_MEM_ZERO
585
        wc_MemZero_Check(data, len);
586
    #endif
587
        XFREE(data, heap, DYNAMIC_TYPE_TMP_BUFFER);
588
        return ret;
589
    }
590
591
#endif
592
/* defined(WOLFSSL_TICKET_NONCE_MALLOC) && (!defined(HAVE_FIPS) ||
593
 *  FIPS_VERSION_GE(5,3)) */
594
595
#endif /* HAVE_HKDF && !NO_HMAC */
596
597
598
#ifdef WOLFSSL_WOLFSSH
599
600
/* hash union */
601
typedef union {
602
#ifndef NO_MD5
603
    wc_Md5 md5;
604
#endif
605
#ifndef NO_SHA
606
    wc_Sha sha;
607
#endif
608
#ifdef WOLFSSL_SHA224
609
    wc_Sha224 sha224;
610
#endif
611
#ifndef NO_SHA256
612
    wc_Sha256 sha256;
613
#endif
614
#ifdef WOLFSSL_SHA384
615
    wc_Sha384 sha384;
616
#endif
617
#ifdef WOLFSSL_SHA512
618
    wc_Sha512 sha512;
619
#endif
620
#ifdef WOLFSSL_SHA3
621
    wc_Sha3 sha3;
622
#endif
623
} _hash;
624
625
static
626
int _HashInit(byte hashId, _hash* hash)
627
{
628
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
629
630
    switch (hashId) {
631
    #ifndef NO_SHA
632
        case WC_SHA:
633
            ret = wc_InitSha(&hash->sha);
634
            break;
635
    #endif /* !NO_SHA */
636
637
    #ifndef NO_SHA256
638
        case WC_SHA256:
639
            ret = wc_InitSha256(&hash->sha256);
640
            break;
641
    #endif /* !NO_SHA256 */
642
643
    #ifdef WOLFSSL_SHA384
644
        case WC_SHA384:
645
            ret = wc_InitSha384(&hash->sha384);
646
            break;
647
    #endif /* WOLFSSL_SHA384 */
648
    #ifdef WOLFSSL_SHA512
649
        case WC_SHA512:
650
            ret = wc_InitSha512(&hash->sha512);
651
            break;
652
    #endif /* WOLFSSL_SHA512 */
653
        default:
654
            ret = BAD_FUNC_ARG;
655
            break;
656
    }
657
658
    return ret;
659
}
660
661
static
662
int _HashUpdate(byte hashId, _hash* hash,
663
        const byte* data, word32 dataSz)
664
{
665
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
666
667
    switch (hashId) {
668
    #ifndef NO_SHA
669
        case WC_SHA:
670
            ret = wc_ShaUpdate(&hash->sha, data, dataSz);
671
            break;
672
    #endif /* !NO_SHA */
673
674
    #ifndef NO_SHA256
675
        case WC_SHA256:
676
            ret = wc_Sha256Update(&hash->sha256, data, dataSz);
677
            break;
678
    #endif /* !NO_SHA256 */
679
680
    #ifdef WOLFSSL_SHA384
681
        case WC_SHA384:
682
            ret = wc_Sha384Update(&hash->sha384, data, dataSz);
683
            break;
684
    #endif /* WOLFSSL_SHA384 */
685
    #ifdef WOLFSSL_SHA512
686
        case WC_SHA512:
687
            ret = wc_Sha512Update(&hash->sha512, data, dataSz);
688
            break;
689
    #endif /* WOLFSSL_SHA512 */
690
        default:
691
            ret = BAD_FUNC_ARG;
692
            break;
693
    }
694
695
    return ret;
696
}
697
698
static
699
int _HashFinal(byte hashId, _hash* hash, byte* digest)
700
{
701
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
702
703
    switch (hashId) {
704
    #ifndef NO_SHA
705
        case WC_SHA:
706
            ret = wc_ShaFinal(&hash->sha, digest);
707
            break;
708
    #endif /* !NO_SHA */
709
710
    #ifndef NO_SHA256
711
        case WC_SHA256:
712
            ret = wc_Sha256Final(&hash->sha256, digest);
713
            break;
714
    #endif /* !NO_SHA256 */
715
716
    #ifdef WOLFSSL_SHA384
717
        case WC_SHA384:
718
            ret = wc_Sha384Final(&hash->sha384, digest);
719
            break;
720
    #endif /* WOLFSSL_SHA384 */
721
    #ifdef WOLFSSL_SHA512
722
        case WC_SHA512:
723
            ret = wc_Sha512Final(&hash->sha512, digest);
724
            break;
725
    #endif /* WOLFSSL_SHA512 */
726
        default:
727
            ret = BAD_FUNC_ARG;
728
            break;
729
    }
730
731
    return ret;
732
}
733
734
static
735
void _HashFree(byte hashId, _hash* hash)
736
{
737
    switch (hashId) {
738
    #ifndef NO_SHA
739
        case WC_SHA:
740
            wc_ShaFree(&hash->sha);
741
            break;
742
    #endif /* !NO_SHA */
743
744
    #ifndef NO_SHA256
745
        case WC_SHA256:
746
            wc_Sha256Free(&hash->sha256);
747
            break;
748
    #endif /* !NO_SHA256 */
749
750
    #ifdef WOLFSSL_SHA384
751
        case WC_SHA384:
752
            wc_Sha384Free(&hash->sha384);
753
            break;
754
    #endif /* WOLFSSL_SHA384 */
755
    #ifdef WOLFSSL_SHA512
756
        case WC_SHA512:
757
            wc_Sha512Free(&hash->sha512);
758
            break;
759
    #endif /* WOLFSSL_SHA512 */
760
    }
761
}
762
763
764
#define LENGTH_SZ 4
765
766
int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz,
767
        const byte* k, word32 kSz, const byte* h, word32 hSz,
768
        const byte* sessionId, word32 sessionIdSz)
769
{
770
    word32 blocks, remainder;
771
    _hash hash;
772
    enum wc_HashType enmhashId = (enum wc_HashType)hashId;
773
    byte kPad = 0;
774
    byte pad = 0;
775
    byte kSzFlat[LENGTH_SZ];
776
    word32 digestSz;
777
    int ret;
778
779
    if (key == NULL || keySz == 0 ||
780
        k == NULL || kSz == 0 ||
781
        h == NULL || hSz == 0 ||
782
        sessionId == NULL || sessionIdSz == 0) {
783
784
        return BAD_FUNC_ARG;
785
    }
786
787
    ret = wc_HmacSizeByType((int)enmhashId);
788
    if (ret <= 0) {
789
        return BAD_FUNC_ARG;
790
    }
791
    digestSz = (word32)ret;
792
793
    if (k[0] & 0x80) kPad = 1;
794
    c32toa(kSz + kPad, kSzFlat);
795
796
    blocks = keySz / digestSz;
797
    remainder = keySz % digestSz;
798
799
    ret = _HashInit(enmhashId, &hash);
800
    if (ret != 0)
801
        return ret;
802
803
    ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
804
    if (ret == 0 && kPad)
805
        ret = _HashUpdate(enmhashId, &hash, &pad, 1);
806
    if (ret == 0)
807
        ret = _HashUpdate(enmhashId, &hash, k, kSz);
808
    if (ret == 0)
809
        ret = _HashUpdate(enmhashId, &hash, h, hSz);
810
    if (ret == 0)
811
        ret = _HashUpdate(enmhashId, &hash, &keyId, sizeof(keyId));
812
    if (ret == 0)
813
        ret = _HashUpdate(enmhashId, &hash, sessionId, sessionIdSz);
814
815
    if (ret == 0) {
816
        if (blocks == 0) {
817
            if (remainder > 0) {
818
                byte lastBlock[WC_MAX_DIGEST_SIZE];
819
                ret = _HashFinal(enmhashId, &hash, lastBlock);
820
                if (ret == 0)
821
                    XMEMCPY(key, lastBlock, remainder);
822
            }
823
        }
824
        else {
825
            word32 runningKeySz, curBlock;
826
827
            runningKeySz = digestSz;
828
            ret = _HashFinal(enmhashId, &hash, key);
829
830
            for (curBlock = 1; curBlock < blocks; curBlock++) {
831
                ret = _HashInit(enmhashId, &hash);
832
                if (ret != 0) break;
833
                ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
834
                if (ret != 0) break;
835
                if (kPad)
836
                    ret = _HashUpdate(enmhashId, &hash, &pad, 1);
837
                if (ret != 0) break;
838
                ret = _HashUpdate(enmhashId, &hash, k, kSz);
839
                if (ret != 0) break;
840
                ret = _HashUpdate(enmhashId, &hash, h, hSz);
841
                if (ret != 0) break;
842
                ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
843
                if (ret != 0) break;
844
                ret = _HashFinal(enmhashId, &hash, key + runningKeySz);
845
                if (ret != 0) break;
846
                runningKeySz += digestSz;
847
            }
848
849
            if (remainder > 0) {
850
                byte lastBlock[WC_MAX_DIGEST_SIZE];
851
                if (ret == 0)
852
                    ret = _HashInit(enmhashId, &hash);
853
                if (ret == 0)
854
                    ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
855
                if (ret == 0 && kPad)
856
                    ret = _HashUpdate(enmhashId, &hash, &pad, 1);
857
                if (ret == 0)
858
                    ret = _HashUpdate(enmhashId, &hash, k, kSz);
859
                if (ret == 0)
860
                    ret = _HashUpdate(enmhashId, &hash, h, hSz);
861
                if (ret == 0)
862
                    ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
863
                if (ret == 0)
864
                    ret = _HashFinal(enmhashId, &hash, lastBlock);
865
                if (ret == 0)
866
                    XMEMCPY(key + runningKeySz, lastBlock, remainder);
867
            }
868
        }
869
    }
870
871
    _HashFree(enmhashId, &hash);
872
873
    return ret;
874
}
875
876
#endif /* WOLFSSL_WOLFSSH */
877
878
#ifdef WC_SRTP_KDF
879
/* Calculate first block to encrypt.
880
 *
881
 * @param [in]  salt     Random value to XOR in.
882
 * @param [in]  saltSz   Size of random value in bytes.
883
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
884
 *                       kdr = 2^kdrIdx.
885
 * @param [in]  idx      Index value to XOR in.
886
 * @param [in]  idxSz    Size of index value in bytes.
887
 * @param [out] block    First block to encrypt.
888
 */
889
static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
890
        const byte* idx, int idxSz, unsigned char* block)
891
{
892
    int i;
893
894
    /* XOR salt into zeroized buffer. */
895
    for (i = 0; i < WC_SRTP_MAX_SALT - (int)saltSz; i++) {
896
        block[i] = 0;
897
    }
898
    XMEMCPY(block + WC_SRTP_MAX_SALT - saltSz, salt, saltSz);
899
    block[WC_SRTP_MAX_SALT] = 0;
900
    /* block[15] is counter. */
901
902
    /* When kdrIdx is -1, don't XOR in index. */
903
    if (kdrIdx >= 0) {
904
        /* Get the number of bits to shift index by. */
905
        word32 bits = kdrIdx & 0x7;
906
        /* Reduce index size by number of bytes to remove. */
907
        idxSz -= kdrIdx >> 3;
908
909
        if ((kdrIdx & 0x7) == 0) {
910
            /* Just XOR in as no bit shifting. */
911
            for (i = 0; i < idxSz; i++) {
912
                block[i + WC_SRTP_MAX_SALT - idxSz] ^= idx[i];
913
            }
914
        }
915
        else {
916
            /* XOR in as bit shifted index. */
917
            block[WC_SRTP_MAX_SALT - idxSz] ^= (byte)(idx[0] >> bits);
918
            for (i = 1; i < idxSz; i++) {
919
                block[i + WC_SRTP_MAX_SALT - idxSz] ^=
920
                    (byte)((idx[i-1] << (8 - bits)) |
921
                           (idx[i+0] >>      bits ));
922
            }
923
        }
924
    }
925
}
926
927
/* Derive a key given the first block.
928
 *
929
 * @param [in, out] block    First block to encrypt. Need label XORed in.
930
 * @param [in]      indexSz  Size of index in bytes to calculate where label is
931
 *                           XORed into.
932
 * @param [in]      label    Label byte that differs for each key.
933
 * @param [out]     key      Derived key.
934
 * @param [in]      keySz    Size of key to derive in bytes.
935
 * @param [in]      aes      AES object to encrypt with.
936
 * @return  0 on success.
937
 */
938
static int wc_srtp_kdf_derive_key(byte* block, int idxSz, byte label,
939
        byte* key, word32 keySz, Aes* aes)
940
{
941
    int i;
942
    int ret = 0;
943
    /* Calculate the number of full blocks needed for derived key. */
944
    int blocks = (int)(keySz / WC_AES_BLOCK_SIZE);
945
946
    /* XOR in label. */
947
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
948
    for (i = 0; (ret == 0) && (i < blocks); i++) {
949
        /* Set counter. */
950
        block[15] = (byte)i;
951
        /* Encrypt block into key buffer. */
952
        ret = wc_AesEcbEncrypt(aes, key, block, WC_AES_BLOCK_SIZE);
953
        /* Reposition for more derived key. */
954
        key += WC_AES_BLOCK_SIZE;
955
        /* Reduce the count of key bytes required. */
956
        keySz -= WC_AES_BLOCK_SIZE;
957
    }
958
    /* Do any partial blocks. */
959
    if ((ret == 0) && (keySz > 0)) {
960
        byte enc[WC_AES_BLOCK_SIZE];
961
        /* Set counter. */
962
        block[15] = (byte)i;
963
        /* Encrypt block into temporary. */
964
        ret = wc_AesEcbEncrypt(aes, enc, block, WC_AES_BLOCK_SIZE);
965
        if (ret == 0) {
966
            /* Copy into key required amount. */
967
            XMEMCPY(key, enc, keySz);
968
        }
969
    }
970
    /* XOR out label. */
971
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
972
973
    return ret;
974
}
975
976
/* Derive keys using SRTP KDF algorithm.
977
 *
978
 * SP 800-135 (RFC 3711).
979
 *
980
 * @param [in]  key      Key to use with encryption.
981
 * @param [in]  keySz    Size of key in bytes.
982
 * @param [in]  salt     Random non-secret value.
983
 * @param [in]  saltSz   Size of random in bytes.
984
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
985
 *                       kdr = 2^kdrIdx.
986
 * @param [in]  index    Index value to XOR in.
987
 * @param [out] key1     First key. Label value of 0x00.
988
 * @param [in]  key1Sz   Size of first key in bytes.
989
 * @param [out] key2     Second key. Label value of 0x01.
990
 * @param [in]  key2Sz   Size of second key in bytes.
991
 * @param [out] key3     Third key. Label value of 0x02.
992
 * @param [in]  key3Sz   Size of third key in bytes.
993
 * @return  BAD_FUNC_ARG when key or salt is NULL.
994
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
995
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
996
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
997
 * @return  MEMORY_E on dynamic memory allocation failure.
998
 * @return  0 on success.
999
 */
1000
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1001
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1002
        word32 key2Sz, byte* key3, word32 key3Sz)
1003
{
1004
    int ret = 0;
1005
    byte block[WC_AES_BLOCK_SIZE];
1006
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1007
    int aes_inited = 0;
1008
1009
    /* Validate parameters. */
1010
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1011
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) {
1012
        ret = BAD_FUNC_ARG;
1013
    }
1014
1015
#ifdef WOLFSSL_SMALL_STACK
1016
    if (ret == 0) {
1017
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1018
        if (aes == NULL) {
1019
            ret = MEMORY_E;
1020
        }
1021
    }
1022
#endif
1023
1024
    /* Setup AES object. */
1025
    if (ret == 0) {
1026
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1027
    }
1028
    if (ret == 0) {
1029
        aes_inited = 1;
1030
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1031
    }
1032
1033
    /* Calculate first block that can be used in each derivation. */
1034
    if (ret == 0) {
1035
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1036
            block);
1037
    }
1038
1039
    /* Calculate first key if required. */
1040
    if ((ret == 0) && (key1 != NULL)) {
1041
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1042
            WC_SRTP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1043
    }
1044
    /* Calculate second key if required. */
1045
    if ((ret == 0) && (key2 != NULL)) {
1046
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1047
            WC_SRTP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1048
    }
1049
    /* Calculate third key if required. */
1050
    if ((ret == 0) && (key3 != NULL)) {
1051
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1052
            WC_SRTP_LABEL_SALT, key3, key3Sz, aes);
1053
    }
1054
1055
    if (aes_inited)
1056
        wc_AesFree(aes);
1057
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1058
    return ret;
1059
}
1060
1061
/* Derive keys using SRTCP KDF algorithm.
1062
 *
1063
 * SP 800-135 (RFC 3711).
1064
 *
1065
 * @param [in]  key      Key to use with encryption.
1066
 * @param [in]  keySz    Size of key in bytes.
1067
 * @param [in]  salt     Random non-secret value.
1068
 * @param [in]  saltSz   Size of random in bytes.
1069
 * @param [in]  kdrIdx   Key derivation rate index. kdr = 0 when -1, otherwise
1070
 *                       kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1071
 * @param [in]  index    Index value to XOR in.
1072
 * @param [out] key1     First key. Label value of 0x03.
1073
 * @param [in]  key1Sz   Size of first key in bytes.
1074
 * @param [out] key2     Second key. Label value of 0x04.
1075
 * @param [in]  key2Sz   Size of second key in bytes.
1076
 * @param [out] key3     Third key. Label value of 0x05.
1077
 * @param [in]  key3Sz   Size of third key in bytes.
1078
 * @return  BAD_FUNC_ARG when key or salt is NULL.
1079
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1080
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1081
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1082
 * @return  MEMORY_E on dynamic memory allocation failure.
1083
 * @return  0 on success.
1084
 */
1085
int wc_SRTCP_KDF_ex(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1086
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1087
        word32 key2Sz, byte* key3, word32 key3Sz, int idxLenIndicator)
1088
{
1089
    int ret = 0;
1090
    byte block[WC_AES_BLOCK_SIZE];
1091
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1092
    int aes_inited = 0;
1093
    int idxLen;
1094
1095
    if (idxLenIndicator == WC_SRTCP_32BIT_IDX) {
1096
        idxLen = WC_SRTCP_INDEX_LEN;
1097
    } else if (idxLenIndicator == WC_SRTCP_48BIT_IDX) {
1098
        idxLen = WC_SRTP_INDEX_LEN;
1099
    } else {
1100
        return BAD_FUNC_ARG; /* bad or invalid idxLenIndicator */
1101
    }
1102
1103
    /* Validate parameters. */
1104
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1105
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) {
1106
        ret = BAD_FUNC_ARG;
1107
    }
1108
1109
#ifdef WOLFSSL_SMALL_STACK
1110
    if (ret == 0) {
1111
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1112
        if (aes == NULL) {
1113
            ret = MEMORY_E;
1114
        }
1115
    }
1116
#endif
1117
1118
    /* Setup AES object. */
1119
    if (ret == 0) {
1120
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1121
    }
1122
    if (ret == 0) {
1123
        aes_inited = 1;
1124
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1125
    }
1126
1127
    /* Calculate first block that can be used in each derivation. */
1128
    if (ret == 0) {
1129
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, idxLen, block);
1130
    }
1131
1132
    /* Calculate first key if required. */
1133
    if ((ret == 0) && (key1 != NULL)) {
1134
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1135
            WC_SRTCP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1136
    }
1137
    /* Calculate second key if required. */
1138
    if ((ret == 0) && (key2 != NULL)) {
1139
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1140
            WC_SRTCP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1141
    }
1142
    /* Calculate third key if required. */
1143
    if ((ret == 0) && (key3 != NULL)) {
1144
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1145
            WC_SRTCP_LABEL_SALT, key3, key3Sz, aes);
1146
    }
1147
1148
    if (aes_inited)
1149
        wc_AesFree(aes);
1150
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1151
    return ret;
1152
}
1153
1154
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1155
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1156
        word32 key2Sz, byte* key3, word32 key3Sz)
1157
{
1158
    /* The default 32-bit IDX expected by many implementations */
1159
    return wc_SRTCP_KDF_ex(key, keySz, salt, saltSz, kdrIdx, idx,
1160
                           key1, key1Sz, key2, key2Sz, key3, key3Sz,
1161
                           WC_SRTCP_32BIT_IDX);
1162
}
1163
/* Derive key with label using SRTP KDF algorithm.
1164
 *
1165
 * SP 800-135 (RFC 3711).
1166
 *
1167
 * @param [in]  key       Key to use with encryption.
1168
 * @param [in]  keySz     Size of key in bytes.
1169
 * @param [in]  salt      Random non-secret value.
1170
 * @param [in]  saltSz    Size of random in bytes.
1171
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1172
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1173
 * @param [in]  index     Index value to XOR in.
1174
 * @param [in]  label     Label to use when deriving key.
1175
 * @param [out] outKey    Derived key.
1176
 * @param [in]  outKeySz  Size of derived key in bytes.
1177
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1178
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1179
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1180
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1181
 * @return  MEMORY_E on dynamic memory allocation failure.
1182
 * @return  0 on success.
1183
 */
1184
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1185
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1186
        word32 outKeySz)
1187
{
1188
    int ret = 0;
1189
    byte block[WC_AES_BLOCK_SIZE];
1190
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1191
    int aes_inited = 0;
1192
1193
    /* Validate parameters. */
1194
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1195
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1196
            (outKey == NULL)) {
1197
        ret = BAD_FUNC_ARG;
1198
    }
1199
1200
#ifdef WOLFSSL_SMALL_STACK
1201
    if (ret == 0) {
1202
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1203
        if (aes == NULL) {
1204
            ret = MEMORY_E;
1205
        }
1206
    }
1207
#endif
1208
1209
    /* Setup AES object. */
1210
    if (ret == 0) {
1211
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1212
    }
1213
    if (ret == 0) {
1214
        aes_inited = 1;
1215
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1216
    }
1217
1218
    /* Calculate first block that can be used in each derivation. */
1219
    if (ret == 0) {
1220
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1221
            block);
1222
    }
1223
    if (ret == 0) {
1224
        /* Calculate key. */
1225
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN, label, outKey,
1226
            outKeySz, aes);
1227
    }
1228
1229
    if (aes_inited)
1230
        wc_AesFree(aes);
1231
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1232
    return ret;
1233
1234
}
1235
1236
/* Derive key with label using SRTCP KDF algorithm.
1237
 *
1238
 * SP 800-135 (RFC 3711).
1239
 *
1240
 * @param [in]  key       Key to use with encryption.
1241
 * @param [in]  keySz     Size of key in bytes.
1242
 * @param [in]  salt      Random non-secret value.
1243
 * @param [in]  saltSz    Size of random in bytes.
1244
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1245
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1246
 * @param [in]  index     Index value to XOR in.
1247
 * @param [in]  label     Label to use when deriving key.
1248
 * @param [out] outKey    Derived key.
1249
 * @param [in]  outKeySz  Size of derived key in bytes.
1250
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1251
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1252
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1253
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1254
 * @return  MEMORY_E on dynamic memory allocation failure.
1255
 * @return  0 on success.
1256
 */
1257
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1258
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1259
        word32 outKeySz)
1260
{
1261
    int ret = 0;
1262
    byte block[WC_AES_BLOCK_SIZE];
1263
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1264
    int aes_inited = 0;
1265
1266
    /* Validate parameters. */
1267
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1268
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1269
            (outKey == NULL)) {
1270
        ret = BAD_FUNC_ARG;
1271
    }
1272
1273
#ifdef WOLFSSL_SMALL_STACK
1274
    if (ret == 0) {
1275
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1276
        if (aes == NULL) {
1277
            ret = MEMORY_E;
1278
        }
1279
    }
1280
#endif
1281
1282
    /* Setup AES object. */
1283
    if (ret == 0) {
1284
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1285
    }
1286
    if (ret == 0) {
1287
        aes_inited = 1;
1288
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1289
    }
1290
1291
    /* Calculate first block that can be used in each derivation. */
1292
    if (ret == 0) {
1293
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTCP_INDEX_LEN,
1294
            block);
1295
    }
1296
    if (ret == 0) {
1297
        /* Calculate key. */
1298
        ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN, label, outKey,
1299
            outKeySz, aes);
1300
    }
1301
1302
    if (aes_inited)
1303
        wc_AesFree(aes);
1304
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1305
    return ret;
1306
1307
}
1308
1309
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
1310
 *
1311
 * @param [in] kdr  Key derivation rate to convert.
1312
 * @return  Key derivation rate as an index.
1313
 */
1314
int wc_SRTP_KDF_kdr_to_idx(word32 kdr)
1315
{
1316
    int idx = -1;
1317
1318
    /* Keep shifting value down and incrementing index until top bit is gone. */
1319
    while (kdr != 0) {
1320
        kdr >>= 1;
1321
        idx++;
1322
    }
1323
1324
    /* Index of top bit set. */
1325
    return idx;
1326
}
1327
#endif /* WC_SRTP_KDF */
1328
1329
#ifdef WC_KDF_NIST_SP_800_56C
1330
static int wc_KDA_KDF_iteration(const byte* z, word32 zSz, word32 counter,
1331
    const byte* fixedInfo, word32 fixedInfoSz, enum wc_HashType hashType,
1332
    byte* output)
1333
{
1334
    byte counterBuf[4];
1335
    wc_HashAlg hash;
1336
    int ret;
1337
1338
    ret = wc_HashInit(&hash, hashType);
1339
    if (ret != 0)
1340
        return ret;
1341
    c32toa(counter, counterBuf);
1342
    ret = wc_HashUpdate(&hash, hashType, counterBuf, 4);
1343
    if (ret == 0) {
1344
        ret = wc_HashUpdate(&hash, hashType, z, zSz);
1345
    }
1346
    if (ret == 0 && fixedInfoSz > 0) {
1347
        ret = wc_HashUpdate(&hash, hashType, fixedInfo, fixedInfoSz);
1348
    }
1349
    if (ret == 0) {
1350
        ret = wc_HashFinal(&hash, hashType, output);
1351
    }
1352
    wc_HashFree(&hash, hashType);
1353
    return ret;
1354
}
1355
1356
/**
1357
 * \brief Performs the single-step key derivation function (KDF) as specified in
1358
 * SP800-56C option 1. This implementation uses a 32 bit counter.
1359
 *
1360
 * \param [in] z The input keying material.
1361
 * \param [in] zSz The size of the input keying material.
1362
 * \param [in] fixedInfo The fixed information to be included in the KDF.
1363
 * \param [in] fixedInfoSz The size of the fixed information.
1364
 * \param [in] derivedSecretSz The desired size of the derived secret.
1365
 * \param [in] hashType The hash algorithm to be used in the KDF.
1366
 * \param [out] output The buffer to store the derived secret.
1367
 * \param [in] outputSz The size of the output buffer.
1368
 *
1369
 * \return 0 if the KDF operation is successful.
1370
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1371
 * \return negative error code if the KDF operation fails.
1372
 */
1373
int wc_KDA_KDF_onestep(const byte* z, word32 zSz, const byte* fixedInfo,
1374
    word32 fixedInfoSz, word32 derivedSecretSz, enum wc_HashType hashType,
1375
    byte* output, word32 outputSz)
1376
{
1377
    byte hashTempBuf[WC_MAX_DIGEST_SIZE];
1378
    word32 counter, outIdx;
1379
    int hashOutSz;
1380
    int ret;
1381
1382
    if (output == NULL || outputSz < derivedSecretSz)
1383
        return BAD_FUNC_ARG;
1384
    if (z == NULL || zSz == 0 || (fixedInfoSz > 0 && fixedInfo == NULL))
1385
        return BAD_FUNC_ARG;
1386
    if (derivedSecretSz == 0)
1387
        return BAD_FUNC_ARG;
1388
1389
    hashOutSz = wc_HashGetDigestSize(hashType);
1390
    if (hashOutSz <= 0)
1391
        return BAD_FUNC_ARG;
1392
1393
    /* According to SP800_56C, table 1, the max input size (max_H_inputBits)
1394
     * depends on the HASH algo. The smaller value in the table is (2**64-1)/8.
1395
     * This is larger than the possible length using word32 integers. */
1396
1397
    counter = 1; /* init counter to 1, from SP800-56C section 4.1 */
1398
    outIdx = 0;
1399
    ret = 0;
1400
1401
    /* According to SP800_56C the number of iterations shall not be greater than
1402
     * 2**32-1. This is not possible using word32 integers.*/
1403
    while (outIdx + (word32) hashOutSz <= derivedSecretSz) {
1404
        ret = wc_KDA_KDF_iteration(z, zSz, counter, fixedInfo, fixedInfoSz,
1405
            hashType, output + outIdx);
1406
        if (ret != 0)
1407
            break;
1408
        counter++;
1409
        outIdx += (word32) hashOutSz;
1410
    }
1411
1412
    if (ret == 0 && outIdx < derivedSecretSz) {
1413
        ret = wc_KDA_KDF_iteration(z, zSz, counter, fixedInfo, fixedInfoSz,
1414
            hashType, hashTempBuf);
1415
        if (ret == 0) {
1416
            XMEMCPY(output + outIdx, hashTempBuf, derivedSecretSz - outIdx);
1417
        }
1418
        ForceZero(hashTempBuf, (word32) hashOutSz);
1419
    }
1420
1421
    if (ret != 0) {
1422
        ForceZero(output, derivedSecretSz);
1423
    }
1424
1425
    return ret;
1426
}
1427
#endif /* WC_KDF_NIST_SP_800_56C */
1428
1429
#ifdef HAVE_CMAC_KDF
1430
/**
1431
 * \brief Performs the two-step cmac key derivation function (KDF) as
1432
 * specified in SP800-56C, section 5.1, in counter mode.
1433
 *
1434
 *            Z                               fixedInfo
1435
 *        ____|_________________________________|___________
1436
 *       |    |                                 |           |
1437
 *       |    ________________                ___________   |
1438
 * salt--|-> | Randomness     |              | Key       |  |
1439
 *       |   | Extract        | --Key_kdk--> | Expansion | -|-output-->
1440
 *       |    ----------------                -----------   |
1441
 *        --------------------------------------------------
1442
 *
1443
 * \param [in]  salt         The input keying material for cmac.
1444
 * \param [in]  salt_len     The size of the input keying material.
1445
 * \param [in]  z            The input shared secret (message to cmac).
1446
 * \param [in]  zSz          The size of the input shared secret.
1447
 * \param [in]  fixedInfo    The fixed information in the KDF.
1448
 * \param [in]  fixedInfoSz  The size of the fixed information.
1449
 * \param [out] output       The buffer to store the derived secret.
1450
 * \param [in]  outputSz     The desired size of the output secret.
1451
 * \param [in]  heap         The heap hint.
1452
 * \param [in]  devId        The device id.
1453
 *
1454
 * \return 0 if the KDF operation is successful.
1455
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1456
 * \return negative error code if the KDF operation fails.
1457
 */
1458
int wc_KDA_KDF_twostep_cmac(const byte * salt, word32 salt_len,
1459
                            const byte* z, word32 zSz,
1460
                            const byte* fixedInfo, word32 fixedInfoSz,
1461
                            byte* output, word32 outputSz,
1462
                            void * heap, int devId)
1463
{
1464
    byte   Key_kdk[WC_AES_BLOCK_SIZE]; /* key derivation key*/
1465
    word32 kdk_len = sizeof(Key_kdk);
1466
    word32 tag_len = WC_AES_BLOCK_SIZE;
1467
    #ifdef WOLFSSL_SMALL_STACK
1468
    Cmac * cmac = NULL;
1469
    #else
1470
    Cmac   cmac[1];
1471
    #endif /* WOLFSSL_SMALL_STACK */
1472
    int    ret = 0;
1473
1474
    /* screen out bad args. */
1475
    switch (salt_len) {
1476
    case AES_128_KEY_SIZE:
1477
    case AES_192_KEY_SIZE:
1478
    case AES_256_KEY_SIZE:
1479
        break; /* salt ok */
1480
    default:
1481
        WOLFSSL_MSG_EX("KDF twostep cmac: bad salt len: %d", salt_len);
1482
        return BAD_FUNC_ARG;
1483
    }
1484
1485
    if (zSz == 0 || outputSz == 0) {
1486
        return BAD_FUNC_ARG;
1487
    }
1488
1489
    if (fixedInfoSz > 0 && fixedInfo == NULL) {
1490
        return BAD_FUNC_ARG;
1491
    }
1492
1493
    if (salt == NULL || z == NULL || output == NULL) {
1494
        return BAD_FUNC_ARG;
1495
    }
1496
1497
    #ifdef WOLF_CRYPTO_CB
1498
    /* Try crypto callback first for complete operation */
1499
    if (devId != INVALID_DEVID) {
1500
         ret = wc_CryptoCb_Kdf_TwostepCmac(salt, salt_len, z, zSz,
1501
                                           fixedInfo, fixedInfoSz,
1502
                                           output, outputSz, devId);
1503
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
1504
            return ret;
1505
        }
1506
        /* fall-through when unavailable */
1507
    }
1508
    #endif
1509
1510
    XMEMSET(Key_kdk, 0, kdk_len);
1511
1512
    #ifdef WOLFSSL_SMALL_STACK
1513
    cmac = (Cmac*)XMALLOC(sizeof(Cmac), heap, DYNAMIC_TYPE_CMAC);
1514
    if (cmac == NULL) {
1515
        return MEMORY_E;
1516
    }
1517
    #endif
1518
1519
    /* step 1: cmac extract */
1520
    ret = wc_AesCmacGenerate_ex(cmac, Key_kdk, &tag_len, z, zSz, salt, salt_len,
1521
                                heap, devId);
1522
1523
    if (ret == 0) {
1524
        if (tag_len != WC_AES_BLOCK_SIZE) {
1525
            WOLFSSL_MSG_EX("KDF twostep cmac: got %d, expected %d\n",
1526
                           tag_len, WC_AES_BLOCK_SIZE);
1527
            ret = BUFFER_E;
1528
        }
1529
    }
1530
1531
    #ifdef WOLFSSL_SMALL_STACK
1532
    if (cmac) {
1533
        XFREE(cmac, heap, DYNAMIC_TYPE_CMAC);
1534
        cmac = NULL;
1535
    }
1536
    #endif /* WOLFSSL_SMALL_STACK */
1537
1538
    /* step 2: cmac expand with SP 800-108 PRF.
1539
     * If AES-128-CMAC, AES-192-CMAC, or AES-256-CMAC is used in the
1540
     * randomness extraction step, then only AES-128-CMAC is used in the
1541
     * key-expansion step.*/
1542
    if (ret == 0) {
1543
        ret = wc_KDA_KDF_PRF_cmac(Key_kdk, kdk_len, fixedInfo, fixedInfoSz,
1544
                                  output, outputSz, WC_CMAC_AES,
1545
                                  heap, devId);
1546
    }
1547
1548
    /* always force zero the intermediate key derivation key. */
1549
    ForceZero(Key_kdk, sizeof(Key_kdk));
1550
1551
    return ret;
1552
}
1553
1554
/**
1555
 * \brief Performs the KDF PRF as specified in SP800-108r1.
1556
 * At the moment, only AES-CMAC counter mode (section 4.1) is
1557
 * implemented. This implementation uses a 32 bit counter.
1558
 *
1559
 * \param [in]  Kin       The input keying material.
1560
 * \param [in]  KinSz     The size of the input keying material.
1561
 * \param [in]  fixedInfo The fixed information to be included in the KDF.
1562
 * \param [in]  fixedInfo Sz The size of the fixed information.
1563
 * \param [out] Kout      The output keying material.
1564
 * \param [in]  KoutSz    The desired size of the output key.
1565
 * \param [in]  type      The type of cmac.
1566
 * \param [in]  heap      The heap hint.
1567
 * \param [in]  devId     The device id.
1568
 *
1569
 * \return 0 if the KDF operation is successful.
1570
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1571
 * \return negative error code if the KDF operation fails.
1572
 */
1573
int wc_KDA_KDF_PRF_cmac(const byte* Kin, word32 KinSz,
1574
                        const byte* fixedInfo, word32 fixedInfoSz,
1575
                        byte* Kout, word32 KoutSz, CmacType type,
1576
                        void * heap, int devId)
1577
{
1578
    word32 len_rem = KoutSz;
1579
    word32 tag_len = WC_AES_BLOCK_SIZE;
1580
    word32 counter = 1; /* init counter to 1, from SP800-108r1 section 4.1 */
1581
    #ifdef WOLFSSL_SMALL_STACK
1582
    Cmac * cmac = NULL;
1583
    #else
1584
    Cmac   cmac[1];
1585
    #endif /* WOLFSSL_SMALL_STACK */
1586
    byte   counterBuf[4];
1587
    int    ret = 0;
1588
1589
    /* screen out bad args. */
1590
    if (Kin == NULL || Kout == NULL) {
1591
        return BAD_FUNC_ARG;
1592
    }
1593
1594
    if (fixedInfoSz > 0 && fixedInfo == NULL) {
1595
        return BAD_FUNC_ARG;
1596
    }
1597
1598
    if (KoutSz == 0) {
1599
        return BAD_FUNC_ARG;
1600
    }
1601
1602
    /* Only AES-CMAC PRF supported at this time. */
1603
    if (type != WC_CMAC_AES) {
1604
        return BAD_FUNC_ARG;
1605
    }
1606
1607
    #ifdef WOLFSSL_SMALL_STACK
1608
    cmac = (Cmac*)XMALLOC(sizeof(Cmac), heap, DYNAMIC_TYPE_CMAC);
1609
    if (cmac == NULL) {
1610
        return MEMORY_E;
1611
    }
1612
    #endif
1613
1614
    while (ret == 0 && len_rem >= WC_AES_BLOCK_SIZE) {
1615
        /* cmac in place in block size increments */
1616
        c32toa(counter, counterBuf);
1617
        #ifdef WOLFSSL_DEBUG_KDF
1618
        WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: in place: "
1619
                       "len_rem = %d, i = %d", len_rem, counter);
1620
        #endif /* WOLFSSL_DEBUG_KDF */
1621
1622
        ret = wc_InitCmac_ex(cmac, Kin, KinSz, WC_CMAC_AES, NULL, heap, devId);
1623
1624
        if (ret == 0) {
1625
            ret = wc_CmacUpdate(cmac, counterBuf, sizeof(counterBuf));
1626
        }
1627
1628
        if (ret == 0 && fixedInfoSz > 0) {
1629
            ret = wc_CmacUpdate(cmac, fixedInfo, fixedInfoSz);
1630
        }
1631
1632
        if (ret == 0) {
1633
            ret = wc_CmacFinalNoFree(cmac, &Kout[KoutSz - len_rem], &tag_len);
1634
1635
            if (tag_len != WC_AES_BLOCK_SIZE) {
1636
                WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: got %d, expected %d\n",
1637
                               tag_len, WC_AES_BLOCK_SIZE);
1638
                ret = BUFFER_E;
1639
            }
1640
        }
1641
1642
        (void)wc_CmacFree(cmac);
1643
1644
        if (ret != 0) { break; }
1645
1646
        len_rem -= WC_AES_BLOCK_SIZE;
1647
        ++counter;
1648
    }
1649
1650
    if (ret == 0 && len_rem) {
1651
        /* cmac the last little bit that wouldn't fit in a block size. */
1652
        byte rem[WC_AES_BLOCK_SIZE];
1653
        XMEMSET(rem, 0, sizeof(rem));
1654
        c32toa(counter, counterBuf);
1655
1656
        #ifdef WOLFSSL_DEBUG_KDF
1657
        WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: last little bit: "
1658
                       "len_rem = %d, i = %d", len_rem, counter);
1659
        #endif /* WOLFSSL_DEBUG_KDF */
1660
1661
        ret = wc_InitCmac_ex(cmac, Kin, KinSz, WC_CMAC_AES, NULL, heap, devId);
1662
1663
        if (ret == 0) {
1664
            ret = wc_CmacUpdate(cmac, counterBuf, sizeof(counterBuf));
1665
        }
1666
1667
        if (ret == 0 && fixedInfoSz > 0) {
1668
            ret = wc_CmacUpdate(cmac, fixedInfo, fixedInfoSz);
1669
        }
1670
1671
        if (ret == 0) {
1672
            ret = wc_CmacFinalNoFree(cmac, rem, &tag_len);
1673
1674
            if (tag_len != WC_AES_BLOCK_SIZE) {
1675
                WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: got %d, expected %d\n",
1676
                               tag_len, WC_AES_BLOCK_SIZE);
1677
                ret = BUFFER_E;
1678
            }
1679
        }
1680
1681
        if (ret == 0) {
1682
            XMEMCPY(&Kout[KoutSz - len_rem], rem, len_rem);
1683
        }
1684
1685
        ForceZero(rem, sizeof(rem));
1686
        (void)wc_CmacFree(cmac);
1687
    }
1688
1689
    #ifdef WOLFSSL_SMALL_STACK
1690
    if (cmac) {
1691
        XFREE(cmac, heap, DYNAMIC_TYPE_CMAC);
1692
        cmac = NULL;
1693
    }
1694
    #endif /* WOLFSSL_SMALL_STACK */
1695
1696
    if (ret != 0) {
1697
        ForceZero(Kout, KoutSz);
1698
    }
1699
1700
    return ret;
1701
}
1702
#endif /* HAVE_CMAC_KDF */
1703
1704
#endif /* NO_KDF */