Coverage Report

Created: 2026-02-14 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/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
189
{
227
189
    int         ret  = 0;
228
189
    word32      half = (secLen + 1) / 2;
229
189
    const byte* md5_half;
230
189
    const byte* sha_half;
231
189
    byte*      md5_result;
232
189
#ifdef WOLFSSL_SMALL_STACK
233
189
    byte*      sha_result;
234
189
    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
189
    if (half > MAX_PRF_HALF ||
241
189
        labLen + seedLen > MAX_PRF_LABSEED ||
242
189
        digLen > MAX_PRF_DIG)
243
0
    {
244
0
        return BUFFER_E;
245
0
    }
246
247
189
#ifdef WOLFSSL_SMALL_STACK
248
189
    sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
249
189
    labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST);
250
189
    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
189
#endif
256
257
189
    md5_half = secret;
258
189
    sha_half = secret + half - secLen % 2;
259
189
    md5_result = digest;
260
261
189
    XMEMCPY(labelSeed, label, labLen);
262
189
    XMEMCPY(labelSeed + labLen, seed, seedLen);
263
264
189
    if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
265
189
                                labLen + seedLen, md5_mac, heap, devId)) == 0) {
266
189
        if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
267
189
                                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
189
            xorbuf(digest, sha_result, digLen);
274
189
            ForceZero(sha_result, digLen);
275
189
        }
276
189
    }
277
278
#if defined(WOLFSSL_CHECK_MEM_ZERO)
279
    wc_MemZero_Check(sha_result, MAX_PRF_DIG);
280
#endif
281
282
189
    WC_FREE_VAR_EX(sha_result, heap, DYNAMIC_TYPE_DIGEST);
283
189
    WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
284
285
189
    return ret;
286
189
}
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.48k
{
294
3.48k
    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.48k
    if (useAtLeastSha256) {
306
3.29k
        WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, 0);
307
308
3.29k
        if (labLen + seedLen > MAX_PRF_LABSEED) {
309
0
            return BUFFER_E;
310
0
        }
311
312
3.29k
        WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap,
313
3.29k
            DYNAMIC_TYPE_DIGEST, return MEMORY_E);
314
315
3.28k
        XMEMCPY(labelSeed, label, labLen);
316
3.28k
        XMEMCPY(labelSeed + labLen, seed, seedLen);
317
318
        /* If a cipher suite wants an algorithm better than sha256, it
319
         * should use better. */
320
3.28k
        if (hash_type < sha256_mac || hash_type == blake2b_mac) {
321
307
            hash_type = sha256_mac;
322
307
        }
323
        /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
324
3.28k
        ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
325
3.28k
                     labLen + seedLen, hash_type, heap, devId);
326
327
3.28k
        WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
328
3.28k
    }
329
189
    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
189
        ret = BAD_FUNC_ARG;
336
189
#endif
337
189
    }
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.47k
    return ret;
346
3.48k
}
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
12.5k
    {
437
12.5k
        int    ret = 0;
438
12.5k
        word32 idx = 0;
439
12.5k
        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
12.5k
        idx = 4 + protocolLen + labelLen + infoLen;
444
12.5k
        if (idx > MAX_TLS13_HKDF_LABEL_SZ) {
445
0
            return BUFFER_E;
446
0
        }
447
448
12.5k
        WC_ALLOC_VAR_EX(data, byte, idx, NULL, DYNAMIC_TYPE_TMP_BUFFER,
449
12.5k
            return MEMORY_E);
450
12.5k
        idx = 0;
451
452
        /* Output length. */
453
12.5k
        data[idx++] = (byte)(okmLen >> 8);
454
12.5k
        data[idx++] = (byte)okmLen;
455
        /* Length of protocol | label. */
456
12.5k
        data[idx++] = (byte)(protocolLen + labelLen);
457
12.5k
        if (protocolLen > 0) {
458
            /* Protocol */
459
12.5k
            XMEMCPY(&data[idx], protocol, protocolLen);
460
12.5k
            idx += protocolLen;
461
12.5k
        }
462
12.5k
        if (labelLen > 0) {
463
            /* Label */
464
12.5k
            XMEMCPY(&data[idx], label, labelLen);
465
12.5k
            idx += labelLen;
466
12.5k
        }
467
        /* Length of hash of messages */
468
12.5k
        data[idx++] = (byte)infoLen;
469
12.5k
        if (infoLen > 0) {
470
            /* Hash of messages */
471
5.73k
            XMEMCPY(&data[idx], info, infoLen);
472
5.73k
            idx += infoLen;
473
5.73k
        }
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.5k
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
488
12.5k
    (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
489
12.5k
        ret = wc_HKDF_Expand_ex(digest, prk, prkLen, data, idx, okm, okmLen,
490
12.5k
            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.5k
        ForceZero(data, idx);
503
504
    #ifdef WOLFSSL_CHECK_MEM_ZERO
505
        wc_MemZero_Check(data, idx);
506
    #endif
507
12.5k
        WC_FREE_VAR_EX(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
508
12.5k
        return ret;
509
12.5k
    }
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[14-15] are counter. */
900
901
    /* When kdrIdx is -1, don't XOR in index. */
902
    if (kdrIdx >= 0) {
903
        /* Get the number of bits to shift index by. */
904
        word32 bits = kdrIdx & 0x7;
905
        /* Reduce index size by number of bytes to remove. */
906
        idxSz -= kdrIdx >> 3;
907
908
        if ((kdrIdx & 0x7) == 0) {
909
            /* Just XOR in as no bit shifting. */
910
            for (i = 0; i < idxSz; i++) {
911
                block[i + WC_SRTP_MAX_SALT - idxSz] ^= idx[i];
912
            }
913
        }
914
        else {
915
            /* XOR in as bit shifted index. */
916
            block[WC_SRTP_MAX_SALT - idxSz] ^= (byte)(idx[0] >> bits);
917
            for (i = 1; i < idxSz; i++) {
918
                block[i + WC_SRTP_MAX_SALT - idxSz] ^=
919
                    (byte)((idx[i-1] << (8 - bits)) |
920
                           (idx[i+0] >>      bits ));
921
            }
922
        }
923
    }
924
}
925
926
/* Derive a key given the first block.
927
 *
928
 * @param [in, out] block    First block to encrypt. Need label XORed in.
929
 * @param [in]      indexSz  Size of index in bytes to calculate where label is
930
 *                           XORed into.
931
 * @param [in]      label    Label byte that differs for each key.
932
 * @param [out]     key      Derived key.
933
 * @param [in]      keySz    Size of key to derive in bytes.
934
 * @param [in]      aes      AES object to encrypt with.
935
 * @return  0 on success.
936
 */
937
static int wc_srtp_kdf_derive_key(byte* block, int idxSz, byte label,
938
        byte* key, word32 keySz, Aes* aes)
939
{
940
    int i;
941
    int ret = 0;
942
    /* Calculate the number of full blocks needed for derived key. */
943
    int blocks = (int)(keySz / WC_AES_BLOCK_SIZE);
944
945
    /* XOR in label. */
946
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
947
    for (i = 0; (ret == 0) && (i < blocks); i++) {
948
        /* Set counter. */
949
        block[14] = (byte)(i >> 8);
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[14] = (byte)(i >> 8);
963
        block[15] = (byte)i;
964
        /* Encrypt block into temporary. */
965
        ret = wc_AesEcbEncrypt(aes, enc, block, WC_AES_BLOCK_SIZE);
966
        if (ret == 0) {
967
            /* Copy into key required amount. */
968
            XMEMCPY(key, enc, keySz);
969
        }
970
    }
971
    /* XOR out label. */
972
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
973
974
    return ret;
975
}
976
977
/* Derive keys using SRTP KDF algorithm.
978
 *
979
 * SP 800-135 (RFC 3711).
980
 *
981
 * @param [in]  key      Key to use with encryption.
982
 * @param [in]  keySz    Size of key in bytes.
983
 * @param [in]  salt     Random non-secret value.
984
 * @param [in]  saltSz   Size of random in bytes.
985
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
986
 *                       kdr = 2^kdrIdx.
987
 * @param [in]  index    Index value to XOR in.
988
 * @param [out] key1     First key. Label value of 0x00.
989
 * @param [in]  key1Sz   Size of first key in bytes.
990
 * @param [out] key2     Second key. Label value of 0x01.
991
 * @param [in]  key2Sz   Size of second key in bytes.
992
 * @param [out] key3     Third key. Label value of 0x02.
993
 * @param [in]  key3Sz   Size of third key in bytes.
994
 * @return  BAD_FUNC_ARG when key or salt is NULL.
995
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
996
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
997
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
998
 * @return  MEMORY_E on dynamic memory allocation failure.
999
 * @return  0 on success.
1000
 */
1001
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1002
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1003
        word32 key2Sz, byte* key3, word32 key3Sz)
1004
{
1005
    int ret = 0;
1006
    byte block[WC_AES_BLOCK_SIZE];
1007
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1008
    int aes_inited = 0;
1009
1010
    /* Validate parameters. */
1011
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1012
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) {
1013
        ret = BAD_FUNC_ARG;
1014
    }
1015
1016
#ifdef WOLFSSL_SMALL_STACK
1017
    if (ret == 0) {
1018
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1019
        if (aes == NULL) {
1020
            ret = MEMORY_E;
1021
        }
1022
    }
1023
#endif
1024
1025
    /* Setup AES object. */
1026
    if (ret == 0) {
1027
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1028
    }
1029
    if (ret == 0) {
1030
        aes_inited = 1;
1031
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1032
    }
1033
1034
    /* Calculate first block that can be used in each derivation. */
1035
    if (ret == 0) {
1036
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1037
            block);
1038
    }
1039
1040
    /* Calculate first key if required. */
1041
    if ((ret == 0) && (key1 != NULL)) {
1042
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1043
            WC_SRTP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1044
    }
1045
    /* Calculate second key if required. */
1046
    if ((ret == 0) && (key2 != NULL)) {
1047
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1048
            WC_SRTP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1049
    }
1050
    /* Calculate third key if required. */
1051
    if ((ret == 0) && (key3 != NULL)) {
1052
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1053
            WC_SRTP_LABEL_SALT, key3, key3Sz, aes);
1054
    }
1055
1056
    if (aes_inited)
1057
        wc_AesFree(aes);
1058
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1059
    return ret;
1060
}
1061
1062
/* Derive keys using SRTCP KDF algorithm.
1063
 *
1064
 * SP 800-135 (RFC 3711).
1065
 *
1066
 * @param [in]  key      Key to use with encryption.
1067
 * @param [in]  keySz    Size of key in bytes.
1068
 * @param [in]  salt     Random non-secret value.
1069
 * @param [in]  saltSz   Size of random in bytes.
1070
 * @param [in]  kdrIdx   Key derivation rate index. kdr = 0 when -1, otherwise
1071
 *                       kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1072
 * @param [in]  index    Index value to XOR in.
1073
 * @param [out] key1     First key. Label value of 0x03.
1074
 * @param [in]  key1Sz   Size of first key in bytes.
1075
 * @param [out] key2     Second key. Label value of 0x04.
1076
 * @param [in]  key2Sz   Size of second key in bytes.
1077
 * @param [out] key3     Third key. Label value of 0x05.
1078
 * @param [in]  key3Sz   Size of third key in bytes.
1079
 * @return  BAD_FUNC_ARG when key or salt is NULL.
1080
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1081
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1082
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1083
 * @return  MEMORY_E on dynamic memory allocation failure.
1084
 * @return  0 on success.
1085
 */
1086
int wc_SRTCP_KDF_ex(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1087
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1088
        word32 key2Sz, byte* key3, word32 key3Sz, int idxLenIndicator)
1089
{
1090
    int ret = 0;
1091
    byte block[WC_AES_BLOCK_SIZE];
1092
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1093
    int aes_inited = 0;
1094
    int idxLen;
1095
1096
    if (idxLenIndicator == WC_SRTCP_32BIT_IDX) {
1097
        idxLen = WC_SRTCP_INDEX_LEN;
1098
    } else if (idxLenIndicator == WC_SRTCP_48BIT_IDX) {
1099
        idxLen = WC_SRTP_INDEX_LEN;
1100
    } else {
1101
        return BAD_FUNC_ARG; /* bad or invalid idxLenIndicator */
1102
    }
1103
1104
    /* Validate parameters. */
1105
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1106
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) {
1107
        ret = BAD_FUNC_ARG;
1108
    }
1109
1110
#ifdef WOLFSSL_SMALL_STACK
1111
    if (ret == 0) {
1112
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1113
        if (aes == NULL) {
1114
            ret = MEMORY_E;
1115
        }
1116
    }
1117
#endif
1118
1119
    /* Setup AES object. */
1120
    if (ret == 0) {
1121
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1122
    }
1123
    if (ret == 0) {
1124
        aes_inited = 1;
1125
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1126
    }
1127
1128
    /* Calculate first block that can be used in each derivation. */
1129
    if (ret == 0) {
1130
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, idxLen, block);
1131
    }
1132
1133
    /* Calculate first key if required. */
1134
    if ((ret == 0) && (key1 != NULL)) {
1135
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1136
            WC_SRTCP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1137
    }
1138
    /* Calculate second key if required. */
1139
    if ((ret == 0) && (key2 != NULL)) {
1140
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1141
            WC_SRTCP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1142
    }
1143
    /* Calculate third key if required. */
1144
    if ((ret == 0) && (key3 != NULL)) {
1145
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1146
            WC_SRTCP_LABEL_SALT, key3, key3Sz, aes);
1147
    }
1148
1149
    if (aes_inited)
1150
        wc_AesFree(aes);
1151
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1152
    return ret;
1153
}
1154
1155
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1156
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1157
        word32 key2Sz, byte* key3, word32 key3Sz)
1158
{
1159
    /* The default 32-bit IDX expected by many implementations */
1160
    return wc_SRTCP_KDF_ex(key, keySz, salt, saltSz, kdrIdx, idx,
1161
                           key1, key1Sz, key2, key2Sz, key3, key3Sz,
1162
                           WC_SRTCP_32BIT_IDX);
1163
}
1164
/* Derive key with label using SRTP KDF algorithm.
1165
 *
1166
 * SP 800-135 (RFC 3711).
1167
 *
1168
 * @param [in]  key       Key to use with encryption.
1169
 * @param [in]  keySz     Size of key in bytes.
1170
 * @param [in]  salt      Random non-secret value.
1171
 * @param [in]  saltSz    Size of random in bytes.
1172
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1173
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1174
 * @param [in]  index     Index value to XOR in.
1175
 * @param [in]  label     Label to use when deriving key.
1176
 * @param [out] outKey    Derived key.
1177
 * @param [in]  outKeySz  Size of derived key in bytes.
1178
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1179
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1180
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1181
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1182
 * @return  MEMORY_E on dynamic memory allocation failure.
1183
 * @return  0 on success.
1184
 */
1185
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1186
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1187
        word32 outKeySz)
1188
{
1189
    int ret = 0;
1190
    byte block[WC_AES_BLOCK_SIZE];
1191
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1192
    int aes_inited = 0;
1193
1194
    /* Validate parameters. */
1195
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1196
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1197
            (outKey == NULL)) {
1198
        ret = BAD_FUNC_ARG;
1199
    }
1200
1201
#ifdef WOLFSSL_SMALL_STACK
1202
    if (ret == 0) {
1203
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1204
        if (aes == NULL) {
1205
            ret = MEMORY_E;
1206
        }
1207
    }
1208
#endif
1209
1210
    /* Setup AES object. */
1211
    if (ret == 0) {
1212
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1213
    }
1214
    if (ret == 0) {
1215
        aes_inited = 1;
1216
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1217
    }
1218
1219
    /* Calculate first block that can be used in each derivation. */
1220
    if (ret == 0) {
1221
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1222
            block);
1223
    }
1224
    if (ret == 0) {
1225
        /* Calculate key. */
1226
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN, label, outKey,
1227
            outKeySz, aes);
1228
    }
1229
1230
    if (aes_inited)
1231
        wc_AesFree(aes);
1232
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1233
    return ret;
1234
1235
}
1236
1237
/* Derive key with label using SRTCP KDF algorithm.
1238
 *
1239
 * SP 800-135 (RFC 3711).
1240
 *
1241
 * @param [in]  key       Key to use with encryption.
1242
 * @param [in]  keySz     Size of key in bytes.
1243
 * @param [in]  salt      Random non-secret value.
1244
 * @param [in]  saltSz    Size of random in bytes.
1245
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1246
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1247
 * @param [in]  index     Index value to XOR in.
1248
 * @param [in]  label     Label to use when deriving key.
1249
 * @param [out] outKey    Derived key.
1250
 * @param [in]  outKeySz  Size of derived key in bytes.
1251
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1252
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1253
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1254
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1255
 * @return  MEMORY_E on dynamic memory allocation failure.
1256
 * @return  0 on success.
1257
 */
1258
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1259
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1260
        word32 outKeySz)
1261
{
1262
    int ret = 0;
1263
    byte block[WC_AES_BLOCK_SIZE];
1264
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1265
    int aes_inited = 0;
1266
1267
    /* Validate parameters. */
1268
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1269
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1270
            (outKey == NULL)) {
1271
        ret = BAD_FUNC_ARG;
1272
    }
1273
1274
#ifdef WOLFSSL_SMALL_STACK
1275
    if (ret == 0) {
1276
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1277
        if (aes == NULL) {
1278
            ret = MEMORY_E;
1279
        }
1280
    }
1281
#endif
1282
1283
    /* Setup AES object. */
1284
    if (ret == 0) {
1285
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1286
    }
1287
    if (ret == 0) {
1288
        aes_inited = 1;
1289
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1290
    }
1291
1292
    /* Calculate first block that can be used in each derivation. */
1293
    if (ret == 0) {
1294
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTCP_INDEX_LEN,
1295
            block);
1296
    }
1297
    if (ret == 0) {
1298
        /* Calculate key. */
1299
        ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN, label, outKey,
1300
            outKeySz, aes);
1301
    }
1302
1303
    if (aes_inited)
1304
        wc_AesFree(aes);
1305
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1306
    return ret;
1307
1308
}
1309
1310
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
1311
 *
1312
 * @param [in] kdr  Key derivation rate to convert.
1313
 * @return  Key derivation rate as an index.
1314
 */
1315
int wc_SRTP_KDF_kdr_to_idx(word32 kdr)
1316
{
1317
    int idx = -1;
1318
1319
    /* Keep shifting value down and incrementing index until top bit is gone. */
1320
    while (kdr != 0) {
1321
        kdr >>= 1;
1322
        idx++;
1323
    }
1324
1325
    /* Index of top bit set. */
1326
    return idx;
1327
}
1328
#endif /* WC_SRTP_KDF */
1329
1330
#ifdef WC_KDF_NIST_SP_800_56C
1331
static int wc_KDA_KDF_iteration(const byte* z, word32 zSz, word32 counter,
1332
    const byte* fixedInfo, word32 fixedInfoSz, enum wc_HashType hashType,
1333
    byte* output)
1334
{
1335
    byte counterBuf[4];
1336
    wc_HashAlg hash;
1337
    int ret;
1338
1339
    ret = wc_HashInit(&hash, hashType);
1340
    if (ret != 0)
1341
        return ret;
1342
    c32toa(counter, counterBuf);
1343
    ret = wc_HashUpdate(&hash, hashType, counterBuf, 4);
1344
    if (ret == 0) {
1345
        ret = wc_HashUpdate(&hash, hashType, z, zSz);
1346
    }
1347
    if (ret == 0 && fixedInfoSz > 0) {
1348
        ret = wc_HashUpdate(&hash, hashType, fixedInfo, fixedInfoSz);
1349
    }
1350
    if (ret == 0) {
1351
        ret = wc_HashFinal(&hash, hashType, output);
1352
    }
1353
    wc_HashFree(&hash, hashType);
1354
    return ret;
1355
}
1356
1357
/**
1358
 * \brief Performs the single-step key derivation function (KDF) as specified in
1359
 * SP800-56C option 1. This implementation uses a 32 bit counter.
1360
 *
1361
 * \param [in] z The input keying material.
1362
 * \param [in] zSz The size of the input keying material.
1363
 * \param [in] fixedInfo The fixed information to be included in the KDF.
1364
 * \param [in] fixedInfoSz The size of the fixed information.
1365
 * \param [in] derivedSecretSz The desired size of the derived secret.
1366
 * \param [in] hashType The hash algorithm to be used in the KDF.
1367
 * \param [out] output The buffer to store the derived secret.
1368
 * \param [in] outputSz The size of the output buffer.
1369
 *
1370
 * \return 0 if the KDF operation is successful.
1371
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1372
 * \return negative error code if the KDF operation fails.
1373
 */
1374
int wc_KDA_KDF_onestep(const byte* z, word32 zSz, const byte* fixedInfo,
1375
    word32 fixedInfoSz, word32 derivedSecretSz, enum wc_HashType hashType,
1376
    byte* output, word32 outputSz)
1377
{
1378
    byte hashTempBuf[WC_MAX_DIGEST_SIZE];
1379
    word32 counter, outIdx;
1380
    int hashOutSz;
1381
    int ret;
1382
1383
    if (output == NULL || outputSz < derivedSecretSz)
1384
        return BAD_FUNC_ARG;
1385
    if (z == NULL || zSz == 0 || (fixedInfoSz > 0 && fixedInfo == NULL))
1386
        return BAD_FUNC_ARG;
1387
    if (derivedSecretSz == 0)
1388
        return BAD_FUNC_ARG;
1389
1390
    hashOutSz = wc_HashGetDigestSize(hashType);
1391
    if (hashOutSz <= 0)
1392
        return BAD_FUNC_ARG;
1393
1394
    /* According to SP800_56C, table 1, the max input size (max_H_inputBits)
1395
     * depends on the HASH algo. The smaller value in the table is (2**64-1)/8.
1396
     * This is larger than the possible length using word32 integers. */
1397
1398
    counter = 1; /* init counter to 1, from SP800-56C section 4.1 */
1399
    outIdx = 0;
1400
    ret = 0;
1401
1402
    /* According to SP800_56C the number of iterations shall not be greater than
1403
     * 2**32-1. This is not possible using word32 integers.*/
1404
    while (outIdx + (word32) hashOutSz <= derivedSecretSz) {
1405
        ret = wc_KDA_KDF_iteration(z, zSz, counter, fixedInfo, fixedInfoSz,
1406
            hashType, output + outIdx);
1407
        if (ret != 0)
1408
            break;
1409
        counter++;
1410
        outIdx += (word32) hashOutSz;
1411
    }
1412
1413
    if (ret == 0 && outIdx < derivedSecretSz) {
1414
        ret = wc_KDA_KDF_iteration(z, zSz, counter, fixedInfo, fixedInfoSz,
1415
            hashType, hashTempBuf);
1416
        if (ret == 0) {
1417
            XMEMCPY(output + outIdx, hashTempBuf, derivedSecretSz - outIdx);
1418
        }
1419
        ForceZero(hashTempBuf, (word32) hashOutSz);
1420
    }
1421
1422
    if (ret != 0) {
1423
        ForceZero(output, derivedSecretSz);
1424
    }
1425
1426
    return ret;
1427
}
1428
#endif /* WC_KDF_NIST_SP_800_56C */
1429
1430
#ifdef HAVE_CMAC_KDF
1431
/**
1432
 * \brief Performs the two-step cmac key derivation function (KDF) as
1433
 * specified in SP800-56C, section 5.1, in counter mode.
1434
 *
1435
 *            Z                               fixedInfo
1436
 *        ____|_________________________________|___________
1437
 *       |    |                                 |           |
1438
 *       |    ________________                ___________   |
1439
 * salt--|-> | Randomness     |              | Key       |  |
1440
 *       |   | Extract        | --Key_kdk--> | Expansion | -|-output-->
1441
 *       |    ----------------                -----------   |
1442
 *        --------------------------------------------------
1443
 *
1444
 * \param [in]  salt         The input keying material for cmac.
1445
 * \param [in]  salt_len     The size of the input keying material.
1446
 * \param [in]  z            The input shared secret (message to cmac).
1447
 * \param [in]  zSz          The size of the input shared secret.
1448
 * \param [in]  fixedInfo    The fixed information in the KDF.
1449
 * \param [in]  fixedInfoSz  The size of the fixed information.
1450
 * \param [out] output       The buffer to store the derived secret.
1451
 * \param [in]  outputSz     The desired size of the output secret.
1452
 * \param [in]  heap         The heap hint.
1453
 * \param [in]  devId        The device id.
1454
 *
1455
 * \return 0 if the KDF operation is successful.
1456
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1457
 * \return negative error code if the KDF operation fails.
1458
 */
1459
int wc_KDA_KDF_twostep_cmac(const byte * salt, word32 salt_len,
1460
                            const byte* z, word32 zSz,
1461
                            const byte* fixedInfo, word32 fixedInfoSz,
1462
                            byte* output, word32 outputSz,
1463
                            void * heap, int devId)
1464
{
1465
    byte   Key_kdk[WC_AES_BLOCK_SIZE]; /* key derivation key*/
1466
    word32 kdk_len = sizeof(Key_kdk);
1467
    word32 tag_len = WC_AES_BLOCK_SIZE;
1468
    #ifdef WOLFSSL_SMALL_STACK
1469
    Cmac * cmac = NULL;
1470
    #else
1471
    Cmac   cmac[1];
1472
    #endif /* WOLFSSL_SMALL_STACK */
1473
    int    ret = 0;
1474
1475
    /* screen out bad args. */
1476
    switch (salt_len) {
1477
    case AES_128_KEY_SIZE:
1478
    case AES_192_KEY_SIZE:
1479
    case AES_256_KEY_SIZE:
1480
        break; /* salt ok */
1481
    default:
1482
        WOLFSSL_MSG_EX("KDF twostep cmac: bad salt len: %d", salt_len);
1483
        return BAD_FUNC_ARG;
1484
    }
1485
1486
    if (zSz == 0 || outputSz == 0) {
1487
        return BAD_FUNC_ARG;
1488
    }
1489
1490
    if (fixedInfoSz > 0 && fixedInfo == NULL) {
1491
        return BAD_FUNC_ARG;
1492
    }
1493
1494
    if (salt == NULL || z == NULL || output == NULL) {
1495
        return BAD_FUNC_ARG;
1496
    }
1497
1498
    #ifdef WOLF_CRYPTO_CB
1499
    /* Try crypto callback first for complete operation */
1500
    if (devId != INVALID_DEVID) {
1501
         ret = wc_CryptoCb_Kdf_TwostepCmac(salt, salt_len, z, zSz,
1502
                                           fixedInfo, fixedInfoSz,
1503
                                           output, outputSz, devId);
1504
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
1505
            return ret;
1506
        }
1507
        /* fall-through when unavailable */
1508
    }
1509
    #endif
1510
1511
    XMEMSET(Key_kdk, 0, kdk_len);
1512
1513
    #ifdef WOLFSSL_SMALL_STACK
1514
    cmac = (Cmac*)XMALLOC(sizeof(Cmac), heap, DYNAMIC_TYPE_CMAC);
1515
    if (cmac == NULL) {
1516
        return MEMORY_E;
1517
    }
1518
    #endif
1519
1520
    /* step 1: cmac extract */
1521
    ret = wc_AesCmacGenerate_ex(cmac, Key_kdk, &tag_len, z, zSz, salt, salt_len,
1522
                                heap, devId);
1523
1524
    if (ret == 0) {
1525
        if (tag_len != WC_AES_BLOCK_SIZE) {
1526
            WOLFSSL_MSG_EX("KDF twostep cmac: got %d, expected %d\n",
1527
                           tag_len, WC_AES_BLOCK_SIZE);
1528
            ret = BUFFER_E;
1529
        }
1530
    }
1531
1532
    #ifdef WOLFSSL_SMALL_STACK
1533
    if (cmac) {
1534
        XFREE(cmac, heap, DYNAMIC_TYPE_CMAC);
1535
        cmac = NULL;
1536
    }
1537
    #endif /* WOLFSSL_SMALL_STACK */
1538
1539
    /* step 2: cmac expand with SP 800-108 PRF.
1540
     * If AES-128-CMAC, AES-192-CMAC, or AES-256-CMAC is used in the
1541
     * randomness extraction step, then only AES-128-CMAC is used in the
1542
     * key-expansion step.*/
1543
    if (ret == 0) {
1544
        ret = wc_KDA_KDF_PRF_cmac(Key_kdk, kdk_len, fixedInfo, fixedInfoSz,
1545
                                  output, outputSz, WC_CMAC_AES,
1546
                                  heap, devId);
1547
    }
1548
1549
    /* always force zero the intermediate key derivation key. */
1550
    ForceZero(Key_kdk, sizeof(Key_kdk));
1551
1552
    return ret;
1553
}
1554
1555
/**
1556
 * \brief Performs the KDF PRF as specified in SP800-108r1.
1557
 * At the moment, only AES-CMAC counter mode (section 4.1) is
1558
 * implemented. This implementation uses a 32 bit counter.
1559
 *
1560
 * \param [in]  Kin       The input keying material.
1561
 * \param [in]  KinSz     The size of the input keying material.
1562
 * \param [in]  fixedInfo The fixed information to be included in the KDF.
1563
 * \param [in]  fixedInfo Sz The size of the fixed information.
1564
 * \param [out] Kout      The output keying material.
1565
 * \param [in]  KoutSz    The desired size of the output key.
1566
 * \param [in]  type      The type of cmac.
1567
 * \param [in]  heap      The heap hint.
1568
 * \param [in]  devId     The device id.
1569
 *
1570
 * \return 0 if the KDF operation is successful.
1571
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1572
 * \return negative error code if the KDF operation fails.
1573
 */
1574
int wc_KDA_KDF_PRF_cmac(const byte* Kin, word32 KinSz,
1575
                        const byte* fixedInfo, word32 fixedInfoSz,
1576
                        byte* Kout, word32 KoutSz, CmacType type,
1577
                        void * heap, int devId)
1578
{
1579
    word32 len_rem = KoutSz;
1580
    word32 tag_len = WC_AES_BLOCK_SIZE;
1581
    word32 counter = 1; /* init counter to 1, from SP800-108r1 section 4.1 */
1582
    #ifdef WOLFSSL_SMALL_STACK
1583
    Cmac * cmac = NULL;
1584
    #else
1585
    Cmac   cmac[1];
1586
    #endif /* WOLFSSL_SMALL_STACK */
1587
    byte   counterBuf[4];
1588
    int    ret = 0;
1589
1590
    /* screen out bad args. */
1591
    if (Kin == NULL || Kout == NULL) {
1592
        return BAD_FUNC_ARG;
1593
    }
1594
1595
    if (fixedInfoSz > 0 && fixedInfo == NULL) {
1596
        return BAD_FUNC_ARG;
1597
    }
1598
1599
    if (KoutSz == 0) {
1600
        return BAD_FUNC_ARG;
1601
    }
1602
1603
    /* Only AES-CMAC PRF supported at this time. */
1604
    if (type != WC_CMAC_AES) {
1605
        return BAD_FUNC_ARG;
1606
    }
1607
1608
    #ifdef WOLFSSL_SMALL_STACK
1609
    cmac = (Cmac*)XMALLOC(sizeof(Cmac), heap, DYNAMIC_TYPE_CMAC);
1610
    if (cmac == NULL) {
1611
        return MEMORY_E;
1612
    }
1613
    #endif
1614
1615
    while (ret == 0 && len_rem >= WC_AES_BLOCK_SIZE) {
1616
        /* cmac in place in block size increments */
1617
        c32toa(counter, counterBuf);
1618
        #ifdef WOLFSSL_DEBUG_KDF
1619
        WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: in place: "
1620
                       "len_rem = %d, i = %d", len_rem, counter);
1621
        #endif /* WOLFSSL_DEBUG_KDF */
1622
1623
        ret = wc_InitCmac_ex(cmac, Kin, KinSz, WC_CMAC_AES, NULL, heap, devId);
1624
1625
        if (ret == 0) {
1626
            ret = wc_CmacUpdate(cmac, counterBuf, sizeof(counterBuf));
1627
        }
1628
1629
        if (ret == 0 && fixedInfoSz > 0) {
1630
            ret = wc_CmacUpdate(cmac, fixedInfo, fixedInfoSz);
1631
        }
1632
1633
        if (ret == 0) {
1634
            ret = wc_CmacFinalNoFree(cmac, &Kout[KoutSz - len_rem], &tag_len);
1635
1636
            if (tag_len != WC_AES_BLOCK_SIZE) {
1637
                WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: got %d, expected %d\n",
1638
                               tag_len, WC_AES_BLOCK_SIZE);
1639
                ret = BUFFER_E;
1640
            }
1641
        }
1642
1643
        (void)wc_CmacFree(cmac);
1644
1645
        if (ret != 0) { break; }
1646
1647
        len_rem -= WC_AES_BLOCK_SIZE;
1648
        ++counter;
1649
    }
1650
1651
    if (ret == 0 && len_rem) {
1652
        /* cmac the last little bit that wouldn't fit in a block size. */
1653
        byte rem[WC_AES_BLOCK_SIZE];
1654
        XMEMSET(rem, 0, sizeof(rem));
1655
        c32toa(counter, counterBuf);
1656
1657
        #ifdef WOLFSSL_DEBUG_KDF
1658
        WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: last little bit: "
1659
                       "len_rem = %d, i = %d", len_rem, counter);
1660
        #endif /* WOLFSSL_DEBUG_KDF */
1661
1662
        ret = wc_InitCmac_ex(cmac, Kin, KinSz, WC_CMAC_AES, NULL, heap, devId);
1663
1664
        if (ret == 0) {
1665
            ret = wc_CmacUpdate(cmac, counterBuf, sizeof(counterBuf));
1666
        }
1667
1668
        if (ret == 0 && fixedInfoSz > 0) {
1669
            ret = wc_CmacUpdate(cmac, fixedInfo, fixedInfoSz);
1670
        }
1671
1672
        if (ret == 0) {
1673
            ret = wc_CmacFinalNoFree(cmac, rem, &tag_len);
1674
1675
            if (tag_len != WC_AES_BLOCK_SIZE) {
1676
                WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: got %d, expected %d\n",
1677
                               tag_len, WC_AES_BLOCK_SIZE);
1678
                ret = BUFFER_E;
1679
            }
1680
        }
1681
1682
        if (ret == 0) {
1683
            XMEMCPY(&Kout[KoutSz - len_rem], rem, len_rem);
1684
        }
1685
1686
        ForceZero(rem, sizeof(rem));
1687
        (void)wc_CmacFree(cmac);
1688
    }
1689
1690
    #ifdef WOLFSSL_SMALL_STACK
1691
    if (cmac) {
1692
        XFREE(cmac, heap, DYNAMIC_TYPE_CMAC);
1693
        cmac = NULL;
1694
    }
1695
    #endif /* WOLFSSL_SMALL_STACK */
1696
1697
    if (ret != 0) {
1698
        ForceZero(Kout, KoutSz);
1699
    }
1700
1701
    return ret;
1702
}
1703
#endif /* HAVE_CMAC_KDF */
1704
1705
#endif /* NO_KDF */