Coverage Report

Created: 2026-05-16 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/wolfcrypt/src/kdf.c
Line
Count
Source
1
/* kdf.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#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
#ifdef WOLFSSL_SMALL_STACK
83
    byte*  current;
84
    Hmac*  hmac;
85
#else
86
0
    byte   current[P_HASH_MAX_SIZE];   /* max size */
87
0
    Hmac   hmac[1];
88
0
#endif
89
90
0
    switch (hash) {
91
    #ifndef NO_MD5
92
        case md5_mac:
93
            hash = WC_MD5;
94
            len  = WC_MD5_DIGEST_SIZE;
95
        break;
96
    #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
    #ifdef WOLFSSL_SM3
120
        case sm3_mac:
121
            hash = WC_SM3;
122
            len  = WC_SM3_DIGEST_SIZE;
123
        break;
124
    #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
#ifdef WOLFSSL_SMALL_STACK
150
    current = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
151
    hmac    = (Hmac*)XMALLOC(sizeof(Hmac),    heap, DYNAMIC_TYPE_HMAC);
152
    if (current == NULL || hmac == NULL) {
153
        XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
154
        XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
155
        return MEMORY_E;
156
    }
157
#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
0
{
227
0
    int         ret  = 0;
228
0
    word32      half = (secLen + 1) / 2;
229
0
    const byte* md5_half;
230
0
    const byte* sha_half;
231
0
    byte*      md5_result;
232
0
    WC_DECLARE_VAR(sha_result, byte, MAX_PRF_DIG, heap); /* digLen is real size */
233
0
    WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
234
235
0
    if (half > MAX_PRF_HALF ||
236
0
        labLen + seedLen > MAX_PRF_LABSEED ||
237
0
        digLen > MAX_PRF_DIG)
238
0
    {
239
0
        return BUFFER_E;
240
0
    }
241
242
0
    WC_ALLOC_VAR_EX(sha_result, byte, MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST,
243
0
                    return MEMORY_E);
244
0
    WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST,
245
0
                    { WC_FREE_VAR_EX(sha_result, heap, DYNAMIC_TYPE_DIGEST);
246
0
                      return MEMORY_E; });
247
248
0
    md5_half = secret;
249
0
    sha_half = secret + half - secLen % 2;
250
0
    md5_result = digest;
251
252
0
    XMEMCPY(labelSeed, label, labLen);
253
0
    XMEMCPY(labelSeed + labLen, seed, seedLen);
254
255
0
    if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
256
0
                                labLen + seedLen, md5_mac, heap, devId)) == 0) {
257
0
        if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
258
0
                                labLen + seedLen, sha_mac, heap, devId)) == 0) {
259
        #ifdef WOLFSSL_CHECK_MEM_ZERO
260
            wc_MemZero_Add("wc_PRF_TLSv1 sha_result", sha_result, digLen);
261
        #endif
262
            /* calculate XOR for TLSv1 PRF */
263
            /* md5 result is placed directly in digest */
264
0
            xorbuf(digest, sha_result, digLen);
265
0
            ForceZero(sha_result, digLen);
266
0
        }
267
0
    }
268
269
#if defined(WOLFSSL_CHECK_MEM_ZERO)
270
    wc_MemZero_Check(sha_result, MAX_PRF_DIG);
271
#endif
272
273
0
    WC_FREE_VAR_EX(sha_result, heap, DYNAMIC_TYPE_DIGEST);
274
0
    WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
275
276
0
    return ret;
277
0
}
278
279
/* Wrapper for TLS 1.2 and TLSv1 cases to calculate PRF */
280
/* In TLS 1.2 case call straight thru to wc_PRF */
281
int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
282
            const byte* label, word32 labLen, const byte* seed, word32 seedLen,
283
            int useAtLeastSha256, int hash_type, void* heap, int devId)
284
0
{
285
0
    int ret = 0;
286
287
#ifdef WOLFSSL_DEBUG_TLS
288
    WOLFSSL_MSG("  secret");
289
    WOLFSSL_BUFFER(secret, secLen);
290
    WOLFSSL_MSG("  label");
291
    WOLFSSL_BUFFER(label, labLen);
292
    WOLFSSL_MSG("  seed");
293
    WOLFSSL_BUFFER(seed, seedLen);
294
#endif
295
296
0
    if (useAtLeastSha256) {
297
0
        WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, 0);
298
299
0
        if (labLen + seedLen > MAX_PRF_LABSEED) {
300
0
            return BUFFER_E;
301
0
        }
302
303
0
        WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap,
304
0
            DYNAMIC_TYPE_DIGEST, return MEMORY_E);
305
306
0
        XMEMCPY(labelSeed, label, labLen);
307
0
        XMEMCPY(labelSeed + labLen, seed, seedLen);
308
309
        /* If a cipher suite wants an algorithm better than sha256, it
310
         * should use better. */
311
0
        if (hash_type < sha256_mac || hash_type == blake2b_mac) {
312
0
            hash_type = sha256_mac;
313
0
        }
314
        /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
315
0
        ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
316
0
                     labLen + seedLen, hash_type, heap, devId);
317
318
0
        WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
319
0
    }
320
0
    else {
321
#ifndef NO_OLD_TLS
322
        /* compute TLSv1 PRF (pseudo random function using HMAC) */
323
        ret = wc_PRF_TLSv1(digest, digLen, secret, secLen, label, labLen, seed,
324
                          seedLen, heap, devId);
325
#else
326
0
        ret = BAD_FUNC_ARG;
327
0
#endif
328
0
    }
329
330
#ifdef WOLFSSL_DEBUG_TLS
331
    WOLFSSL_MSG("  digest");
332
    WOLFSSL_BUFFER(digest, digLen);
333
    WOLFSSL_MSG_EX("hash_type %d", hash_type);
334
#endif
335
336
0
    return ret;
337
0
}
338
#endif /* WOLFSSL_HAVE_PRF && !NO_HMAC */
339
340
341
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
342
343
    /* Extract data using HMAC, salt and input.
344
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
345
     */
346
    int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, word32 saltLen,
347
        byte* ikm, word32 ikmLen, int digest, void* heap, int devId)
348
0
    {
349
0
        int ret;
350
0
        word32 len = 0;
351
352
0
        switch (digest) {
353
0
            #ifndef NO_SHA256
354
0
            case WC_SHA256:
355
0
                len = WC_SHA256_DIGEST_SIZE;
356
0
                break;
357
0
            #endif
358
359
0
            #ifdef WOLFSSL_SHA384
360
0
            case WC_SHA384:
361
0
                len = WC_SHA384_DIGEST_SIZE;
362
0
                break;
363
0
            #endif
364
365
            #ifdef WOLFSSL_TLS13_SHA512
366
            case WC_SHA512:
367
                len = WC_SHA512_DIGEST_SIZE;
368
                break;
369
            #endif
370
371
            #ifdef WOLFSSL_SM3
372
            case WC_SM3:
373
                len = WC_SM3_DIGEST_SIZE;
374
                break;
375
            #endif
376
377
0
            default:
378
0
                return BAD_FUNC_ARG;
379
0
        }
380
381
        /* When length is 0 then use zeroed data of digest length. */
382
0
        if (ikmLen == 0) {
383
0
            ikmLen = len;
384
0
            XMEMSET(ikm, 0, len);
385
0
        }
386
387
#ifdef WOLFSSL_DEBUG_TLS
388
        WOLFSSL_MSG("  Salt");
389
        WOLFSSL_BUFFER(salt, saltLen);
390
        WOLFSSL_MSG("  IKM");
391
        WOLFSSL_BUFFER(ikm, ikmLen);
392
#endif
393
394
0
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
395
0
    (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
396
0
        ret = wc_HKDF_Extract_ex(digest, salt, saltLen, ikm, ikmLen, prk, heap,
397
0
            devId);
398
#else
399
        ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
400
        (void)heap;
401
        (void)devId;
402
#endif
403
404
#ifdef WOLFSSL_DEBUG_TLS
405
        WOLFSSL_MSG("  PRK");
406
        WOLFSSL_BUFFER(prk, len);
407
#endif
408
409
0
        return ret;
410
0
    }
411
412
    int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen,
413
                                 byte* ikm, word32 ikmLen, int digest)
414
0
    {
415
0
        return wc_Tls13_HKDF_Extract_ex(prk, salt, saltLen, ikm, ikmLen, digest,
416
0
            NULL, INVALID_DEVID);
417
0
    }
418
419
    /* Expand data using HMAC, salt and label and info.
420
     * TLS v1.3 defines this function. */
421
    int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen,
422
                                 const byte* prk, word32 prkLen,
423
                                 const byte* protocol, word32 protocolLen,
424
                                 const byte* label, word32 labelLen,
425
                                 const byte* info, word32 infoLen,
426
                                 int digest, void* heap, int devId)
427
0
    {
428
0
        int    ret = 0;
429
0
        word32 idx = 0;
430
0
        WC_DECLARE_VAR(data, byte, MAX_TLS13_HKDF_LABEL_SZ, 0);
431
432
        /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
433
         * labellen + infolen */
434
0
        idx = 4 + protocolLen + labelLen + infoLen;
435
0
        if (idx > MAX_TLS13_HKDF_LABEL_SZ) {
436
0
            return BUFFER_E;
437
0
        }
438
439
0
        WC_ALLOC_VAR_EX(data, byte, idx, NULL, DYNAMIC_TYPE_TMP_BUFFER,
440
0
            return MEMORY_E);
441
0
        idx = 0;
442
443
        /* Output length. */
444
0
        data[idx++] = (byte)(okmLen >> 8);
445
0
        data[idx++] = (byte)okmLen;
446
        /* Length of protocol | label. */
447
0
        data[idx++] = (byte)(protocolLen + labelLen);
448
0
        if (protocolLen > 0) {
449
            /* Protocol */
450
0
            XMEMCPY(&data[idx], protocol, protocolLen);
451
0
            idx += protocolLen;
452
0
        }
453
0
        if (labelLen > 0) {
454
            /* Label */
455
0
            XMEMCPY(&data[idx], label, labelLen);
456
0
            idx += labelLen;
457
0
        }
458
        /* Length of hash of messages */
459
0
        data[idx++] = (byte)infoLen;
460
0
        if (infoLen > 0) {
461
            /* Hash of messages */
462
0
            XMEMCPY(&data[idx], info, infoLen);
463
0
            idx += infoLen;
464
0
        }
465
466
    #ifdef WOLFSSL_CHECK_MEM_ZERO
467
        wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
468
    #endif
469
470
#ifdef WOLFSSL_DEBUG_TLS
471
        WOLFSSL_MSG("  PRK");
472
        WOLFSSL_BUFFER(prk, prkLen);
473
        WOLFSSL_MSG("  Info");
474
        WOLFSSL_BUFFER(data, idx);
475
        WOLFSSL_MSG_EX("  Digest %d", digest);
476
#endif
477
478
0
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
479
0
    (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
480
0
        ret = wc_HKDF_Expand_ex(digest, prk, prkLen, data, idx, okm, okmLen,
481
0
            heap, devId);
482
#else
483
        ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
484
        (void)heap;
485
        (void)devId;
486
#endif
487
488
#ifdef WOLFSSL_DEBUG_TLS
489
        WOLFSSL_MSG("  OKM");
490
        WOLFSSL_BUFFER(okm, okmLen);
491
#endif
492
493
0
        ForceZero(data, idx);
494
495
    #ifdef WOLFSSL_CHECK_MEM_ZERO
496
        wc_MemZero_Check(data, idx);
497
    #endif
498
0
        WC_FREE_VAR_EX(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
499
0
        return ret;
500
0
    }
501
502
    int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
503
                                 const byte* prk, word32 prkLen,
504
                                 const byte* protocol, word32 protocolLen,
505
                                 const byte* label, word32 labelLen,
506
                                 const byte* info, word32 infoLen,
507
                                 int digest)
508
0
    {
509
0
        return wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, protocol,
510
0
            protocolLen, label, labelLen, info, infoLen, digest,
511
0
            NULL, INVALID_DEVID);
512
0
    }
513
514
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                    \
515
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
516
    /* Expand data using HMAC, salt and label and info.
517
     * TLS v1.3 defines this function. */
518
    int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen,
519
        const byte* prk, word32 prkLen, const byte* protocol,
520
        word32 protocolLen, const byte* label, word32 labelLen,
521
        const byte* info, word32 infoLen, int digest, void* heap)
522
    {
523
        int    ret = 0;
524
        word32 idx = 0;
525
        size_t len;
526
        byte   *data;
527
528
        (void)heap;
529
        /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
530
         * labellen + infolen */
531
        len = 4U + protocolLen + labelLen + infoLen;
532
533
        data = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);
534
        if (data == NULL)
535
            return BUFFER_E;
536
537
        /* Output length. */
538
        data[idx++] = (byte)(okmLen >> 8);
539
        data[idx++] = (byte)okmLen;
540
        /* Length of protocol | label. */
541
        data[idx++] = (byte)(protocolLen + labelLen);
542
        /* Protocol */
543
        XMEMCPY(&data[idx], protocol, protocolLen);
544
        idx += protocolLen;
545
        /* Label */
546
        XMEMCPY(&data[idx], label, labelLen);
547
        idx += labelLen;
548
        /* Length of hash of messages */
549
        data[idx++] = (byte)infoLen;
550
        /* Hash of messages */
551
        XMEMCPY(&data[idx], info, infoLen);
552
        idx += infoLen;
553
554
    #ifdef WOLFSSL_CHECK_MEM_ZERO
555
        wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
556
    #endif
557
558
#ifdef WOLFSSL_DEBUG_TLS
559
        WOLFSSL_MSG("  PRK");
560
        WOLFSSL_BUFFER(prk, prkLen);
561
        WOLFSSL_MSG("  Info");
562
        WOLFSSL_BUFFER(data, idx);
563
        WOLFSSL_MSG_EX("  Digest %d", digest);
564
#endif
565
566
        ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
567
568
#ifdef WOLFSSL_DEBUG_TLS
569
        WOLFSSL_MSG("  OKM");
570
        WOLFSSL_BUFFER(okm, okmLen);
571
#endif
572
573
        ForceZero(data, idx);
574
575
    #ifdef WOLFSSL_CHECK_MEM_ZERO
576
        wc_MemZero_Check(data, len);
577
    #endif
578
        XFREE(data, heap, DYNAMIC_TYPE_TMP_BUFFER);
579
        return ret;
580
    }
581
582
#endif
583
/* defined(WOLFSSL_TICKET_NONCE_MALLOC) && (!defined(HAVE_FIPS) ||
584
 *  FIPS_VERSION_GE(5,3)) */
585
586
#endif /* HAVE_HKDF && !NO_HMAC */
587
588
589
#ifdef WOLFSSL_WOLFSSH
590
591
/* hash union */
592
typedef union {
593
#ifndef NO_MD5
594
    wc_Md5 md5;
595
#endif
596
#ifndef NO_SHA
597
    wc_Sha sha;
598
#endif
599
#ifdef WOLFSSL_SHA224
600
    wc_Sha224 sha224;
601
#endif
602
#ifndef NO_SHA256
603
    wc_Sha256 sha256;
604
#endif
605
#ifdef WOLFSSL_SHA384
606
    wc_Sha384 sha384;
607
#endif
608
#ifdef WOLFSSL_SHA512
609
    wc_Sha512 sha512;
610
#endif
611
#ifdef WOLFSSL_SHA3
612
    wc_Sha3 sha3;
613
#endif
614
} _hash;
615
616
static
617
int _HashInit(byte hashId, _hash* hash)
618
{
619
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
620
621
    switch (hashId) {
622
    #ifndef NO_SHA
623
        case WC_SHA:
624
            ret = wc_InitSha(&hash->sha);
625
            break;
626
    #endif /* !NO_SHA */
627
628
    #ifndef NO_SHA256
629
        case WC_SHA256:
630
            ret = wc_InitSha256(&hash->sha256);
631
            break;
632
    #endif /* !NO_SHA256 */
633
634
    #ifdef WOLFSSL_SHA384
635
        case WC_SHA384:
636
            ret = wc_InitSha384(&hash->sha384);
637
            break;
638
    #endif /* WOLFSSL_SHA384 */
639
    #ifdef WOLFSSL_SHA512
640
        case WC_SHA512:
641
            ret = wc_InitSha512(&hash->sha512);
642
            break;
643
    #endif /* WOLFSSL_SHA512 */
644
        default:
645
            ret = BAD_FUNC_ARG;
646
            break;
647
    }
648
649
    return ret;
650
}
651
652
static
653
int _HashUpdate(byte hashId, _hash* hash,
654
        const byte* data, word32 dataSz)
655
{
656
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
657
658
    switch (hashId) {
659
    #ifndef NO_SHA
660
        case WC_SHA:
661
            ret = wc_ShaUpdate(&hash->sha, data, dataSz);
662
            break;
663
    #endif /* !NO_SHA */
664
665
    #ifndef NO_SHA256
666
        case WC_SHA256:
667
            ret = wc_Sha256Update(&hash->sha256, data, dataSz);
668
            break;
669
    #endif /* !NO_SHA256 */
670
671
    #ifdef WOLFSSL_SHA384
672
        case WC_SHA384:
673
            ret = wc_Sha384Update(&hash->sha384, data, dataSz);
674
            break;
675
    #endif /* WOLFSSL_SHA384 */
676
    #ifdef WOLFSSL_SHA512
677
        case WC_SHA512:
678
            ret = wc_Sha512Update(&hash->sha512, data, dataSz);
679
            break;
680
    #endif /* WOLFSSL_SHA512 */
681
        default:
682
            ret = BAD_FUNC_ARG;
683
            break;
684
    }
685
686
    return ret;
687
}
688
689
static
690
int _HashFinal(byte hashId, _hash* hash, byte* digest)
691
{
692
    int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
693
694
    switch (hashId) {
695
    #ifndef NO_SHA
696
        case WC_SHA:
697
            ret = wc_ShaFinal(&hash->sha, digest);
698
            break;
699
    #endif /* !NO_SHA */
700
701
    #ifndef NO_SHA256
702
        case WC_SHA256:
703
            ret = wc_Sha256Final(&hash->sha256, digest);
704
            break;
705
    #endif /* !NO_SHA256 */
706
707
    #ifdef WOLFSSL_SHA384
708
        case WC_SHA384:
709
            ret = wc_Sha384Final(&hash->sha384, digest);
710
            break;
711
    #endif /* WOLFSSL_SHA384 */
712
    #ifdef WOLFSSL_SHA512
713
        case WC_SHA512:
714
            ret = wc_Sha512Final(&hash->sha512, digest);
715
            break;
716
    #endif /* WOLFSSL_SHA512 */
717
        default:
718
            ret = BAD_FUNC_ARG;
719
            break;
720
    }
721
722
    return ret;
723
}
724
725
static
726
void _HashFree(byte hashId, _hash* hash)
727
{
728
    switch (hashId) {
729
    #ifndef NO_SHA
730
        case WC_SHA:
731
            wc_ShaFree(&hash->sha);
732
            break;
733
    #endif /* !NO_SHA */
734
735
    #ifndef NO_SHA256
736
        case WC_SHA256:
737
            wc_Sha256Free(&hash->sha256);
738
            break;
739
    #endif /* !NO_SHA256 */
740
741
    #ifdef WOLFSSL_SHA384
742
        case WC_SHA384:
743
            wc_Sha384Free(&hash->sha384);
744
            break;
745
    #endif /* WOLFSSL_SHA384 */
746
    #ifdef WOLFSSL_SHA512
747
        case WC_SHA512:
748
            wc_Sha512Free(&hash->sha512);
749
            break;
750
    #endif /* WOLFSSL_SHA512 */
751
    }
752
}
753
754
755
#define LENGTH_SZ 4
756
757
int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz,
758
        const byte* k, word32 kSz, const byte* h, word32 hSz,
759
        const byte* sessionId, word32 sessionIdSz)
760
{
761
    word32 blocks, remainder;
762
    _hash hash;
763
    enum wc_HashType enmhashId = (enum wc_HashType)hashId;
764
    byte kPad = 0;
765
    byte pad = 0;
766
    byte kSzFlat[LENGTH_SZ];
767
    word32 digestSz;
768
    int ret;
769
770
    if (key == NULL || keySz == 0 ||
771
        k == NULL || kSz == 0 ||
772
        h == NULL || hSz == 0 ||
773
        sessionId == NULL || sessionIdSz == 0) {
774
775
        return BAD_FUNC_ARG;
776
    }
777
778
    ret = wc_HmacSizeByType((int)enmhashId);
779
    if (ret <= 0) {
780
        return BAD_FUNC_ARG;
781
    }
782
    digestSz = (word32)ret;
783
784
    if (k[0] & 0x80) kPad = 1;
785
    c32toa(kSz + kPad, kSzFlat);
786
787
    blocks = keySz / digestSz;
788
    remainder = keySz % digestSz;
789
790
    ret = _HashInit(enmhashId, &hash);
791
    if (ret != 0)
792
        return ret;
793
794
    ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
795
    if (ret == 0 && kPad)
796
        ret = _HashUpdate(enmhashId, &hash, &pad, 1);
797
    if (ret == 0)
798
        ret = _HashUpdate(enmhashId, &hash, k, kSz);
799
    if (ret == 0)
800
        ret = _HashUpdate(enmhashId, &hash, h, hSz);
801
    if (ret == 0)
802
        ret = _HashUpdate(enmhashId, &hash, &keyId, sizeof(keyId));
803
    if (ret == 0)
804
        ret = _HashUpdate(enmhashId, &hash, sessionId, sessionIdSz);
805
806
    if (ret == 0) {
807
        if (blocks == 0) {
808
            if (remainder > 0) {
809
                byte lastBlock[WC_MAX_DIGEST_SIZE];
810
                ret = _HashFinal(enmhashId, &hash, lastBlock);
811
                if (ret == 0)
812
                    XMEMCPY(key, lastBlock, remainder);
813
            }
814
        }
815
        else {
816
            word32 runningKeySz, curBlock;
817
818
            runningKeySz = digestSz;
819
            ret = _HashFinal(enmhashId, &hash, key);
820
821
            for (curBlock = 1; curBlock < blocks; curBlock++) {
822
                ret = _HashInit(enmhashId, &hash);
823
                if (ret != 0) break;
824
                ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
825
                if (ret != 0) break;
826
                if (kPad)
827
                    ret = _HashUpdate(enmhashId, &hash, &pad, 1);
828
                if (ret != 0) break;
829
                ret = _HashUpdate(enmhashId, &hash, k, kSz);
830
                if (ret != 0) break;
831
                ret = _HashUpdate(enmhashId, &hash, h, hSz);
832
                if (ret != 0) break;
833
                ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
834
                if (ret != 0) break;
835
                ret = _HashFinal(enmhashId, &hash, key + runningKeySz);
836
                if (ret != 0) break;
837
                runningKeySz += digestSz;
838
            }
839
840
            if (remainder > 0) {
841
                byte lastBlock[WC_MAX_DIGEST_SIZE];
842
                if (ret == 0)
843
                    ret = _HashInit(enmhashId, &hash);
844
                if (ret == 0)
845
                    ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
846
                if (ret == 0 && kPad)
847
                    ret = _HashUpdate(enmhashId, &hash, &pad, 1);
848
                if (ret == 0)
849
                    ret = _HashUpdate(enmhashId, &hash, k, kSz);
850
                if (ret == 0)
851
                    ret = _HashUpdate(enmhashId, &hash, h, hSz);
852
                if (ret == 0)
853
                    ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
854
                if (ret == 0)
855
                    ret = _HashFinal(enmhashId, &hash, lastBlock);
856
                if (ret == 0)
857
                    XMEMCPY(key + runningKeySz, lastBlock, remainder);
858
            }
859
        }
860
    }
861
862
    _HashFree(enmhashId, &hash);
863
864
    return ret;
865
}
866
867
#endif /* WOLFSSL_WOLFSSH */
868
869
#ifdef WC_SRTP_KDF
870
/* Calculate first block to encrypt.
871
 *
872
 * @param [in]  salt     Random value to XOR in.
873
 * @param [in]  saltSz   Size of random value in bytes.
874
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
875
 *                       kdr = 2^kdrIdx.
876
 * @param [in]  idx      Index value to XOR in.
877
 * @param [in]  idxSz    Size of index value in bytes.
878
 * @param [out] block    First block to encrypt.
879
 */
880
static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
881
        const byte* idx, int idxSz, unsigned char* block)
882
{
883
    int i;
884
885
    /* XOR salt into zeroized buffer. */
886
    for (i = 0; i < WC_SRTP_MAX_SALT - (int)saltSz; i++) {
887
        block[i] = 0;
888
    }
889
    XMEMCPY(block + WC_SRTP_MAX_SALT - saltSz, salt, saltSz);
890
    /* block[14-15] are counter. */
891
892
    /* When kdrIdx is -1, don't XOR in index. */
893
    if (kdrIdx >= 0) {
894
        /* Get the number of bits to shift index by. */
895
        word32 bits = kdrIdx & 0x7;
896
        /* Reduce index size by number of bytes to remove. */
897
        idxSz -= kdrIdx >> 3;
898
899
        if ((kdrIdx & 0x7) == 0) {
900
            /* Just XOR in as no bit shifting. */
901
            for (i = 0; i < idxSz; i++) {
902
                block[i + WC_SRTP_MAX_SALT - idxSz] ^= idx[i];
903
            }
904
        }
905
        else {
906
            /* XOR in as bit shifted index. */
907
            block[WC_SRTP_MAX_SALT - idxSz] ^= (byte)(idx[0] >> bits);
908
            for (i = 1; i < idxSz; i++) {
909
                block[i + WC_SRTP_MAX_SALT - idxSz] ^=
910
                    (byte)((idx[i-1] << (8 - bits)) |
911
                           (idx[i+0] >>      bits ));
912
            }
913
        }
914
    }
915
}
916
917
/* Derive a key given the first block.
918
 *
919
 * @param [in, out] block    First block to encrypt. Need label XORed in.
920
 * @param [in]      indexSz  Size of index in bytes to calculate where label is
921
 *                           XORed into.
922
 * @param [in]      label    Label byte that differs for each key.
923
 * @param [out]     key      Derived key.
924
 * @param [in]      keySz    Size of key to derive in bytes.
925
 * @param [in]      aes      AES object to encrypt with.
926
 * @return  0 on success.
927
 */
928
static int wc_srtp_kdf_derive_key(byte* block, int idxSz, byte label,
929
        byte* key, word32 keySz, Aes* aes)
930
{
931
    int i;
932
    int ret = 0;
933
    /* Calculate the number of full blocks needed for derived key. */
934
    int blocks = (int)(keySz / WC_AES_BLOCK_SIZE);
935
936
    /* XOR in label. */
937
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
938
    for (i = 0; (ret == 0) && (i < blocks); i++) {
939
        /* Set counter. */
940
        block[14] = (byte)(i >> 8);
941
        block[15] = (byte)i;
942
        /* Encrypt block into key buffer. */
943
        ret = wc_AesEcbEncrypt(aes, key, block, WC_AES_BLOCK_SIZE);
944
        /* Reposition for more derived key. */
945
        key += WC_AES_BLOCK_SIZE;
946
        /* Reduce the count of key bytes required. */
947
        keySz -= WC_AES_BLOCK_SIZE;
948
    }
949
    /* Do any partial blocks. */
950
    if ((ret == 0) && (keySz > 0)) {
951
        byte enc[WC_AES_BLOCK_SIZE];
952
        /* Set counter. */
953
        block[14] = (byte)(i >> 8);
954
        block[15] = (byte)i;
955
        /* Encrypt block into temporary. */
956
        ret = wc_AesEcbEncrypt(aes, enc, block, WC_AES_BLOCK_SIZE);
957
        if (ret == 0) {
958
            /* Copy into key required amount. */
959
            XMEMCPY(key, enc, keySz);
960
        }
961
    }
962
    /* XOR out label. */
963
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
964
965
    return ret;
966
}
967
968
/* Derive keys using SRTP KDF algorithm.
969
 *
970
 * SP 800-135 (RFC 3711).
971
 *
972
 * @param [in]  key      Key to use with encryption.
973
 * @param [in]  keySz    Size of key in bytes.
974
 * @param [in]  salt     Random non-secret value.
975
 * @param [in]  saltSz   Size of random in bytes.
976
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
977
 *                       kdr = 2^kdrIdx.
978
 * @param [in]  idx      Index value to XOR in.
979
 * @param [out] key1     First key. Label value of 0x00.
980
 * @param [in]  key1Sz   Size of first key in bytes.
981
 * @param [out] key2     Second key. Label value of 0x01.
982
 * @param [in]  key2Sz   Size of second key in bytes.
983
 * @param [out] key3     Third key. Label value of 0x02.
984
 * @param [in]  key3Sz   Size of third key in bytes.
985
 * @return  BAD_FUNC_ARG when key or salt is NULL.
986
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
987
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
988
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
989
 * @return  MEMORY_E on dynamic memory allocation failure.
990
 * @return  0 on success.
991
 */
992
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
993
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
994
        word32 key2Sz, byte* key3, word32 key3Sz)
995
{
996
    int ret = 0;
997
    byte block[WC_AES_BLOCK_SIZE];
998
    WC_DECLARE_VAR(aes, Aes, 1, 0);
999
    int aes_inited = 0;
1000
1001
    /* Validate parameters. */
1002
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1003
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1004
            ((kdrIdx >= 0) && (idx == NULL))) {
1005
        ret = BAD_FUNC_ARG;
1006
    }
1007
1008
#ifdef WOLFSSL_SMALL_STACK
1009
    if (ret == 0) {
1010
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1011
        if (aes == NULL) {
1012
            ret = MEMORY_E;
1013
        }
1014
    }
1015
#endif
1016
1017
    /* Setup AES object. */
1018
    if (ret == 0) {
1019
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1020
    }
1021
    if (ret == 0) {
1022
        aes_inited = 1;
1023
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1024
    }
1025
1026
    /* Calculate first block that can be used in each derivation. */
1027
    if (ret == 0) {
1028
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1029
            block);
1030
    }
1031
1032
    /* Calculate first key if required. */
1033
    if ((ret == 0) && (key1 != NULL)) {
1034
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1035
            WC_SRTP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1036
    }
1037
    /* Calculate second key if required. */
1038
    if ((ret == 0) && (key2 != NULL)) {
1039
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1040
            WC_SRTP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1041
    }
1042
    /* Calculate third key if required. */
1043
    if ((ret == 0) && (key3 != NULL)) {
1044
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1045
            WC_SRTP_LABEL_SALT, key3, key3Sz, aes);
1046
    }
1047
1048
    if (aes_inited)
1049
        wc_AesFree(aes);
1050
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1051
    return ret;
1052
}
1053
1054
/* Derive keys using SRTCP KDF algorithm.
1055
 *
1056
 * SP 800-135 (RFC 3711).
1057
 *
1058
 * @param [in]  key      Key to use with encryption.
1059
 * @param [in]  keySz    Size of key in bytes.
1060
 * @param [in]  salt     Random non-secret value.
1061
 * @param [in]  saltSz   Size of random in bytes.
1062
 * @param [in]  kdrIdx   Key derivation rate index. kdr = 0 when -1, otherwise
1063
 *                       kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1064
 * @param [in]  idx      Index value to XOR in.
1065
 * @param [out] key1     First key. Label value of 0x03.
1066
 * @param [in]  key1Sz   Size of first key in bytes.
1067
 * @param [out] key2     Second key. Label value of 0x04.
1068
 * @param [in]  key2Sz   Size of second key in bytes.
1069
 * @param [out] key3     Third key. Label value of 0x05.
1070
 * @param [in]  key3Sz   Size of third key in bytes.
1071
 * @return  BAD_FUNC_ARG when key or salt is NULL.
1072
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1073
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1074
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1075
 * @return  MEMORY_E on dynamic memory allocation failure.
1076
 * @return  0 on success.
1077
 */
1078
int wc_SRTCP_KDF_ex(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1079
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1080
        word32 key2Sz, byte* key3, word32 key3Sz, int idxLenIndicator)
1081
{
1082
    int ret = 0;
1083
    byte block[WC_AES_BLOCK_SIZE];
1084
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1085
    int aes_inited = 0;
1086
    int idxLen;
1087
1088
    if (idxLenIndicator == WC_SRTCP_32BIT_IDX) {
1089
        idxLen = WC_SRTCP_INDEX_LEN;
1090
    } else if (idxLenIndicator == WC_SRTCP_48BIT_IDX) {
1091
        idxLen = WC_SRTP_INDEX_LEN;
1092
    } else {
1093
        return BAD_FUNC_ARG; /* bad or invalid idxLenIndicator */
1094
    }
1095
1096
    /* Validate parameters. */
1097
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1098
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1099
            ((kdrIdx >= 0) && (idx == NULL))) {
1100
        ret = BAD_FUNC_ARG;
1101
    }
1102
1103
#ifdef WOLFSSL_SMALL_STACK
1104
    if (ret == 0) {
1105
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1106
        if (aes == NULL) {
1107
            ret = MEMORY_E;
1108
        }
1109
    }
1110
#endif
1111
1112
    /* Setup AES object. */
1113
    if (ret == 0) {
1114
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1115
    }
1116
    if (ret == 0) {
1117
        aes_inited = 1;
1118
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1119
    }
1120
1121
    /* Calculate first block that can be used in each derivation. */
1122
    if (ret == 0) {
1123
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, idxLen, block);
1124
    }
1125
1126
    /* Calculate first key if required. */
1127
    if ((ret == 0) && (key1 != NULL)) {
1128
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1129
            WC_SRTCP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1130
    }
1131
    /* Calculate second key if required. */
1132
    if ((ret == 0) && (key2 != NULL)) {
1133
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1134
            WC_SRTCP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1135
    }
1136
    /* Calculate third key if required. */
1137
    if ((ret == 0) && (key3 != NULL)) {
1138
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1139
            WC_SRTCP_LABEL_SALT, key3, key3Sz, aes);
1140
    }
1141
1142
    if (aes_inited)
1143
        wc_AesFree(aes);
1144
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1145
    return ret;
1146
}
1147
1148
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1149
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1150
        word32 key2Sz, byte* key3, word32 key3Sz)
1151
{
1152
    /* The default 32-bit IDX expected by many implementations */
1153
    return wc_SRTCP_KDF_ex(key, keySz, salt, saltSz, kdrIdx, idx,
1154
                           key1, key1Sz, key2, key2Sz, key3, key3Sz,
1155
                           WC_SRTCP_32BIT_IDX);
1156
}
1157
/* Derive key with label using SRTP KDF algorithm.
1158
 *
1159
 * SP 800-135 (RFC 3711).
1160
 *
1161
 * @param [in]  key       Key to use with encryption.
1162
 * @param [in]  keySz     Size of key in bytes.
1163
 * @param [in]  salt      Random non-secret value.
1164
 * @param [in]  saltSz    Size of random in bytes.
1165
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1166
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1167
 * @param [in]  idx       Index value to XOR in.
1168
 * @param [in]  label     Label to use when deriving key.
1169
 * @param [out] outKey    Derived key.
1170
 * @param [in]  outKeySz  Size of derived key in bytes.
1171
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1172
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1173
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1174
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1175
 * @return  MEMORY_E on dynamic memory allocation failure.
1176
 * @return  0 on success.
1177
 */
1178
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1179
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1180
        word32 outKeySz)
1181
{
1182
    int ret = 0;
1183
    byte block[WC_AES_BLOCK_SIZE];
1184
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1185
    int aes_inited = 0;
1186
1187
    /* Validate parameters. */
1188
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1189
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1190
            (outKey == NULL) || ((kdrIdx >= 0) && (idx == NULL))) {
1191
        ret = BAD_FUNC_ARG;
1192
    }
1193
1194
#ifdef WOLFSSL_SMALL_STACK
1195
    if (ret == 0) {
1196
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1197
        if (aes == NULL) {
1198
            ret = MEMORY_E;
1199
        }
1200
    }
1201
#endif
1202
1203
    /* Setup AES object. */
1204
    if (ret == 0) {
1205
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1206
    }
1207
    if (ret == 0) {
1208
        aes_inited = 1;
1209
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1210
    }
1211
1212
    /* Calculate first block that can be used in each derivation. */
1213
    if (ret == 0) {
1214
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1215
            block);
1216
    }
1217
    if (ret == 0) {
1218
        /* Calculate key. */
1219
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN, label, outKey,
1220
            outKeySz, aes);
1221
    }
1222
1223
    if (aes_inited)
1224
        wc_AesFree(aes);
1225
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1226
    return ret;
1227
1228
}
1229
1230
/* Derive key with label using SRTCP KDF algorithm.
1231
 *
1232
 * SP 800-135 (RFC 3711).
1233
 *
1234
 * @param [in]  key       Key to use with encryption.
1235
 * @param [in]  keySz     Size of key in bytes.
1236
 * @param [in]  salt      Random non-secret value.
1237
 * @param [in]  saltSz    Size of random in bytes.
1238
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1239
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1240
 * @param [in]  idx       Index value to XOR in.
1241
 * @param [in]  label     Label to use when deriving key.
1242
 * @param [out] outKey    Derived key.
1243
 * @param [in]  outKeySz  Size of derived key in bytes.
1244
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1245
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1246
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1247
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1248
 * @return  MEMORY_E on dynamic memory allocation failure.
1249
 * @return  0 on success.
1250
 */
1251
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1252
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1253
        word32 outKeySz)
1254
{
1255
    int ret = 0;
1256
    byte block[WC_AES_BLOCK_SIZE];
1257
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1258
    int aes_inited = 0;
1259
1260
    /* Validate parameters. */
1261
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1262
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1263
            (outKey == NULL) || ((kdrIdx >= 0) && (idx == NULL))) {
1264
        ret = BAD_FUNC_ARG;
1265
    }
1266
1267
#ifdef WOLFSSL_SMALL_STACK
1268
    if (ret == 0) {
1269
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1270
        if (aes == NULL) {
1271
            ret = MEMORY_E;
1272
        }
1273
    }
1274
#endif
1275
1276
    /* Setup AES object. */
1277
    if (ret == 0) {
1278
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1279
    }
1280
    if (ret == 0) {
1281
        aes_inited = 1;
1282
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1283
    }
1284
1285
    /* Calculate first block that can be used in each derivation. */
1286
    if (ret == 0) {
1287
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTCP_INDEX_LEN,
1288
            block);
1289
    }
1290
    if (ret == 0) {
1291
        /* Calculate key. */
1292
        ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN, label, outKey,
1293
            outKeySz, aes);
1294
    }
1295
1296
    if (aes_inited)
1297
        wc_AesFree(aes);
1298
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1299
    return ret;
1300
1301
}
1302
1303
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
1304
 *
1305
 * @param [in] kdr  Key derivation rate to convert.
1306
 * @return  Key derivation rate as an index.
1307
 */
1308
int wc_SRTP_KDF_kdr_to_idx(word32 kdr)
1309
{
1310
    int idx = -1;
1311
1312
    /* Keep shifting value down and incrementing index until top bit is gone. */
1313
    while (kdr != 0) {
1314
        kdr >>= 1;
1315
        idx++;
1316
    }
1317
1318
    /* Index of top bit set. */
1319
    return idx;
1320
}
1321
#endif /* WC_SRTP_KDF */
1322
1323
#ifdef WC_KDF_NIST_SP_800_56C
1324
static int wc_KDA_KDF_iteration(const byte* z, word32 zSz, word32 counter,
1325
    const byte* fixedInfo, word32 fixedInfoSz, enum wc_HashType hashType,
1326
    byte* output)
1327
{
1328
    byte counterBuf[4];
1329
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, NULL);
1330
    int ret;
1331
1332
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
1333
                    return MEMORY_E);
1334
1335
    ret = wc_HashInit(hash, hashType);
1336
    if (ret != 0) {
1337
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
1338
        return ret;
1339
    }
1340
    c32toa(counter, counterBuf);
1341
    ret = wc_HashUpdate(hash, hashType, counterBuf, 4);
1342
    if (ret == 0) {
1343
        ret = wc_HashUpdate(hash, hashType, z, zSz);
1344
    }
1345
    if (ret == 0 && fixedInfoSz > 0) {
1346
        ret = wc_HashUpdate(hash, hashType, fixedInfo, fixedInfoSz);
1347
    }
1348
    if (ret == 0) {
1349
        ret = wc_HashFinal(hash, hashType, output);
1350
    }
1351
    wc_HashFree(hash, hashType);
1352
    WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
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 */