Coverage Report

Created: 2026-09-20 06:33

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