Coverage Report

Created: 2026-08-12 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/wolfcrypt/src/kdf.c
Line
Count
Source
1
/* kdf.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#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
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,
75
                  int hash_type, void* heap, int devId)
76
0
{
77
0
    word32 len = P_HASH_MAX_SIZE;
78
0
    word32 times;
79
0
    word32 lastLen;
80
0
    word32 lastTime;
81
0
    int    ret = 0;
82
#ifdef WOLFSSL_SMALL_STACK
83
    byte*  current;
84
    Hmac*  hmac;
85
#else
86
0
    byte   current[P_HASH_MAX_SIZE];   /* max size */
87
0
    Hmac   hmac[1];
88
0
#endif
89
90
0
    if ((result == NULL && resLen != 0) || (secret == NULL && secLen != 0) ||
91
0
       (seed == NULL && seedLen != 0))
92
0
        return BAD_FUNC_ARG;
93
94
0
    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
0
    #ifndef NO_SHA256
103
0
        case sha256_mac:
104
0
            hash_type = WC_SHA256;
105
0
            len  = WC_SHA256_DIGEST_SIZE;
106
0
        break;
107
0
    #endif
108
109
0
    #ifdef WOLFSSL_SHA384
110
0
        case sha384_mac:
111
0
            hash_type = WC_SHA384;
112
0
            len  = WC_SHA384_DIGEST_SIZE;
113
0
        break;
114
0
    #endif
115
116
0
    #ifdef WOLFSSL_SHA512
117
0
        case sha512_mac:
118
0
            hash_type = WC_SHA512;
119
0
            len  = WC_SHA512_DIGEST_SIZE;
120
0
        break;
121
0
    #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
0
    #ifndef NO_SHA
131
0
        case sha_mac:
132
0
            hash_type = WC_SHA;
133
0
            len  = WC_SHA_DIGEST_SIZE;
134
0
        break;
135
0
    #endif
136
0
        default:
137
0
            return HASH_TYPE_E;
138
0
    }
139
140
0
    times   = resLen / len;
141
0
    lastLen = resLen % len;
142
143
0
    if (lastLen)
144
0
        times += 1;
145
146
    /* times == 0 if resLen == 0, but times == 0 abides clang static analyzer
147
       while resLen == 0 doesn't */
148
0
    if (times == 0)
149
0
        return BAD_FUNC_ARG;
150
151
0
    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
0
    ret = wc_HmacInit(hmac, heap, devId);
169
0
    if (ret == 0) {
170
0
        ret = wc_HmacSetKey(hmac, hash_type, secret, secLen);
171
0
        if (ret == 0)
172
0
            ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */
173
0
        if (ret == 0)
174
0
            ret = wc_HmacFinal(hmac, current);        /* A1 */
175
0
        if (ret == 0) {
176
0
            word32 i;
177
0
            word32 idx = 0;
178
179
0
            for (i = 0; i < times; i++) {
180
0
                ret = wc_HmacUpdate(hmac, current, len);
181
0
                if (ret != 0)
182
0
                    break;
183
0
                ret = wc_HmacUpdate(hmac, seed, seedLen);
184
0
                if (ret != 0)
185
0
                    break;
186
0
                if ((i != lastTime) || !lastLen) {
187
0
                    ret = wc_HmacFinal(hmac, &result[idx]);
188
0
                    if (ret != 0)
189
0
                        break;
190
0
                    idx += len;
191
192
0
                    ret = wc_HmacUpdate(hmac, current, len);
193
0
                    if (ret != 0)
194
0
                        break;
195
0
                    ret = wc_HmacFinal(hmac, current);
196
0
                    if (ret != 0)
197
0
                        break;
198
0
                }
199
0
                else {
200
0
                    ret = wc_HmacFinal(hmac, current);
201
0
                    if (ret != 0)
202
0
                        break;
203
0
                    XMEMCPY(&result[idx], current,
204
0
                                             min(lastLen, P_HASH_MAX_SIZE));
205
0
                }
206
0
            }
207
0
        }
208
0
        wc_HmacFree(hmac);
209
0
    }
210
211
0
    ForceZero(current, P_HASH_MAX_SIZE);
212
0
    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
0
    WC_FREE_VAR_EX(current, heap, DYNAMIC_TYPE_DIGEST);
220
0
    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
221
222
0
    return ret;
223
0
}
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
0
{
231
0
    int         ret  = 0;
232
0
    word32      half = (secLen + 1) / 2;
233
0
    const byte* md5_half;
234
0
    const byte* sha_half;
235
0
    byte*      md5_result;
236
0
    WC_DECLARE_VAR(sha_result, byte, MAX_PRF_DIG, heap); /* digLen is real size */
237
0
    WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
238
239
0
    if ((digest == NULL && digLen  != 0) ||
240
0
        (secret == NULL && secLen  != 0) ||
241
0
        (label  == NULL && labLen  != 0) ||
242
0
        (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
0
    if (half > MAX_PRF_HALF ||
250
0
        labLen > MAX_PRF_LABSEED || seedLen > (MAX_PRF_LABSEED - labLen) ||
251
0
        digLen > MAX_PRF_DIG)
252
0
    {
253
0
        return BUFFER_E;
254
0
    }
255
256
0
    WC_ALLOC_VAR_EX(sha_result, byte, MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST,
257
0
                    return MEMORY_E);
258
0
    WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST,
259
0
                    { WC_FREE_VAR_EX(sha_result, heap, DYNAMIC_TYPE_DIGEST);
260
0
                      return MEMORY_E; });
261
262
0
    md5_half = secret;
263
0
    sha_half = secret + half - secLen % 2;
264
0
    md5_result = digest;
265
266
0
    if (labLen != 0)
267
0
        XMEMCPY(labelSeed, label, labLen);
268
0
    if (seedLen != 0)
269
0
        XMEMCPY(labelSeed + labLen, seed, seedLen);
270
271
0
    if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
272
0
                                labLen + seedLen, md5_mac, heap, devId)) == 0) {
273
0
        if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
274
0
                                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
0
            xorbuf(digest, sha_result, digLen);
281
0
            ForceZero(sha_result, digLen);
282
0
        }
283
0
    }
284
285
#if defined(WOLFSSL_CHECK_MEM_ZERO)
286
    wc_MemZero_Check(sha_result, MAX_PRF_DIG);
287
#endif
288
289
0
    WC_FREE_VAR_EX(sha_result, heap, DYNAMIC_TYPE_DIGEST);
290
0
    WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
291
292
0
    return ret;
293
0
}
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
0
{
301
0
    int ret = 0;
302
303
0
    if ((digest == NULL && digLen  != 0) ||
304
0
        (secret == NULL && secLen  != 0) ||
305
0
        (label  == NULL && labLen  != 0) ||
306
0
        (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
0
    if (useAtLeastSha256) {
320
0
        WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, 0);
321
322
        /* Checked with subtraction to avoid word32 wraparound of
323
         * labLen + seedLen. */
324
0
        if (labLen > MAX_PRF_LABSEED || seedLen > (MAX_PRF_LABSEED - labLen)) {
325
0
            return BUFFER_E;
326
0
        }
327
328
0
        WC_ALLOC_VAR_EX(labelSeed, byte, MAX_PRF_LABSEED, heap,
329
0
            DYNAMIC_TYPE_DIGEST, return MEMORY_E);
330
331
0
        if (labLen != 0)
332
0
            XMEMCPY(labelSeed, label, labLen);
333
0
        if (seedLen != 0)
334
0
            XMEMCPY(labelSeed + labLen, seed, seedLen);
335
336
        /* If a cipher suite wants an algorithm better than sha256, it
337
         * should use better. */
338
0
        if (hash_type < sha256_mac || hash_type == blake2b_mac) {
339
0
            hash_type = sha256_mac;
340
0
        }
341
        /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
342
0
        ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
343
0
                     labLen + seedLen, hash_type, heap, devId);
344
345
0
        WC_FREE_VAR_EX(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
346
0
    }
347
0
    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
0
        ret = BAD_FUNC_ARG;
354
0
#endif
355
0
    }
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
0
    return ret;
364
0
}
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
            #ifdef WOLFSSL_SM3
405
            case WC_SM3:
406
                len = WC_SM3_DIGEST_SIZE;
407
                break;
408
            #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
0
    {
464
0
        int    ret = 0;
465
0
        word32 idx = 0;
466
0
        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
0
        idx = 4 + protocolLen + labelLen + infoLen;
471
0
        if (idx > MAX_TLS13_HKDF_LABEL_SZ) {
472
0
            return BUFFER_E;
473
0
        }
474
475
0
        WC_ALLOC_VAR_EX(data, byte, idx, NULL, DYNAMIC_TYPE_TMP_BUFFER,
476
0
            return MEMORY_E);
477
0
        idx = 0;
478
479
        /* Output length. */
480
0
        data[idx++] = (byte)(okmLen >> 8);
481
0
        data[idx++] = (byte)okmLen;
482
        /* Length of protocol | label. */
483
0
        data[idx++] = (byte)(protocolLen + labelLen);
484
0
        if (protocolLen > 0) {
485
            /* Protocol */
486
0
            XMEMCPY(&data[idx], protocol, protocolLen);
487
0
            idx += protocolLen;
488
0
        }
489
0
        if (labelLen > 0) {
490
            /* Label */
491
0
            XMEMCPY(&data[idx], label, labelLen);
492
0
            idx += labelLen;
493
0
        }
494
        /* Length of hash of messages */
495
0
        data[idx++] = (byte)infoLen;
496
0
        if (infoLen > 0) {
497
            /* Hash of messages */
498
0
            XMEMCPY(&data[idx], info, infoLen);
499
0
            idx += infoLen;
500
0
        }
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
0
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
515
0
    (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
516
0
        ret = wc_HKDF_Expand_ex(digest, prk, prkLen, data, idx, okm, okmLen,
517
0
            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
0
        ForceZero(data, idx);
530
531
    #ifdef WOLFSSL_CHECK_MEM_ZERO
532
        wc_MemZero_Check(data, idx);
533
    #endif
534
0
        WC_FREE_VAR_EX(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
535
0
        return ret;
536
0
    }
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
    }
998
    /* XOR out label. */
999
    block[WC_SRTP_MAX_SALT - idxSz - 1] ^= label;
1000
1001
    return ret;
1002
}
1003
1004
/* Derive keys using SRTP KDF algorithm.
1005
 *
1006
 * SP 800-135 (RFC 3711).
1007
 *
1008
 * @param [in]  key      Key to use with encryption.
1009
 * @param [in]  keySz    Size of key in bytes.
1010
 * @param [in]  salt     Random non-secret value.
1011
 * @param [in]  saltSz   Size of random in bytes.
1012
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
1013
 *                       kdr = 2^kdrIdx.
1014
 * @param [in]  idx      Index value to XOR in.
1015
 * @param [out] key1     First key. Label value of 0x00.
1016
 * @param [in]  key1Sz   Size of first key in bytes.
1017
 * @param [out] key2     Second key. Label value of 0x01.
1018
 * @param [in]  key2Sz   Size of second key in bytes.
1019
 * @param [out] key3     Third key. Label value of 0x02.
1020
 * @param [in]  key3Sz   Size of third key in bytes.
1021
 * @return  BAD_FUNC_ARG when key or salt is NULL.
1022
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1023
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1024
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1025
 * @return  MEMORY_E on dynamic memory allocation failure.
1026
 * @return  0 on success.
1027
 */
1028
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1029
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1030
        word32 key2Sz, byte* key3, word32 key3Sz)
1031
{
1032
    int ret = 0;
1033
    byte block[WC_AES_BLOCK_SIZE];
1034
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1035
    int aes_inited = 0;
1036
1037
    /* Validate parameters. */
1038
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1039
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1040
            ((kdrIdx >= 0) && (idx == NULL))) {
1041
        ret = BAD_FUNC_ARG;
1042
    }
1043
1044
#ifdef WOLFSSL_SMALL_STACK
1045
    if (ret == 0) {
1046
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1047
        if (aes == NULL) {
1048
            ret = MEMORY_E;
1049
        }
1050
    }
1051
#endif
1052
1053
    /* Setup AES object. */
1054
    if (ret == 0) {
1055
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1056
    }
1057
    if (ret == 0) {
1058
        aes_inited = 1;
1059
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1060
    }
1061
1062
    /* Calculate first block that can be used in each derivation. */
1063
    if (ret == 0) {
1064
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1065
            block);
1066
    }
1067
1068
    /* Calculate first key if required. */
1069
    if ((ret == 0) && (key1 != NULL)) {
1070
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1071
            WC_SRTP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1072
    }
1073
    /* Calculate second key if required. */
1074
    if ((ret == 0) && (key2 != NULL)) {
1075
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1076
            WC_SRTP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1077
    }
1078
    /* Calculate third key if required. */
1079
    if ((ret == 0) && (key3 != NULL)) {
1080
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1081
            WC_SRTP_LABEL_SALT, key3, key3Sz, aes);
1082
    }
1083
1084
    if (aes_inited)
1085
        wc_AesFree(aes);
1086
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1087
    return ret;
1088
}
1089
1090
/* Derive keys using SRTCP KDF algorithm.
1091
 *
1092
 * SP 800-135 (RFC 3711).
1093
 *
1094
 * @param [in]  key      Key to use with encryption.
1095
 * @param [in]  keySz    Size of key in bytes.
1096
 * @param [in]  salt     Random non-secret value.
1097
 * @param [in]  saltSz   Size of random in bytes.
1098
 * @param [in]  kdrIdx   Key derivation rate index. kdr = 0 when -1, otherwise
1099
 *                       kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1100
 * @param [in]  idx      Index value to XOR in.
1101
 * @param [out] key1     First key. Label value of 0x03.
1102
 * @param [in]  key1Sz   Size of first key in bytes.
1103
 * @param [out] key2     Second key. Label value of 0x04.
1104
 * @param [in]  key2Sz   Size of second key in bytes.
1105
 * @param [out] key3     Third key. Label value of 0x05.
1106
 * @param [in]  key3Sz   Size of third key in bytes.
1107
 * @return  BAD_FUNC_ARG when key or salt is NULL.
1108
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1109
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1110
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1111
 * @return  MEMORY_E on dynamic memory allocation failure.
1112
 * @return  0 on success.
1113
 */
1114
int wc_SRTCP_KDF_ex(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1115
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1116
        word32 key2Sz, byte* key3, word32 key3Sz, int idxLenIndicator)
1117
{
1118
    int ret = 0;
1119
    byte block[WC_AES_BLOCK_SIZE];
1120
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1121
    int aes_inited = 0;
1122
    int idxLen;
1123
1124
    if (idxLenIndicator == WC_SRTCP_32BIT_IDX) {
1125
        idxLen = WC_SRTCP_INDEX_LEN;
1126
    } else if (idxLenIndicator == WC_SRTCP_48BIT_IDX) {
1127
        idxLen = WC_SRTP_INDEX_LEN;
1128
    } else {
1129
        return BAD_FUNC_ARG; /* bad or invalid idxLenIndicator */
1130
    }
1131
1132
    /* Validate parameters. */
1133
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1134
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1135
            ((kdrIdx >= 0) && (idx == NULL))) {
1136
        ret = BAD_FUNC_ARG;
1137
    }
1138
1139
#ifdef WOLFSSL_SMALL_STACK
1140
    if (ret == 0) {
1141
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1142
        if (aes == NULL) {
1143
            ret = MEMORY_E;
1144
        }
1145
    }
1146
#endif
1147
1148
    /* Setup AES object. */
1149
    if (ret == 0) {
1150
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1151
    }
1152
    if (ret == 0) {
1153
        aes_inited = 1;
1154
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1155
    }
1156
1157
    /* Calculate first block that can be used in each derivation. */
1158
    if (ret == 0) {
1159
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, idxLen, block);
1160
    }
1161
1162
    /* Calculate first key if required. */
1163
    if ((ret == 0) && (key1 != NULL)) {
1164
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1165
            WC_SRTCP_LABEL_ENCRYPTION, key1, key1Sz, aes);
1166
    }
1167
    /* Calculate second key if required. */
1168
    if ((ret == 0) && (key2 != NULL)) {
1169
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1170
            WC_SRTCP_LABEL_MSG_AUTH, key2, key2Sz, aes);
1171
    }
1172
    /* Calculate third key if required. */
1173
    if ((ret == 0) && (key3 != NULL)) {
1174
        ret = wc_srtp_kdf_derive_key(block, idxLen,
1175
            WC_SRTCP_LABEL_SALT, key3, key3Sz, aes);
1176
    }
1177
1178
    if (aes_inited)
1179
        wc_AesFree(aes);
1180
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1181
    return ret;
1182
}
1183
1184
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1185
        int kdrIdx, const byte* idx, byte* key1, word32 key1Sz, byte* key2,
1186
        word32 key2Sz, byte* key3, word32 key3Sz)
1187
{
1188
    /* The default 32-bit IDX expected by many implementations */
1189
    return wc_SRTCP_KDF_ex(key, keySz, salt, saltSz, kdrIdx, idx,
1190
                           key1, key1Sz, key2, key2Sz, key3, key3Sz,
1191
                           WC_SRTCP_32BIT_IDX);
1192
}
1193
/* Derive key with label using SRTP KDF algorithm.
1194
 *
1195
 * SP 800-135 (RFC 3711).
1196
 *
1197
 * @param [in]  key       Key to use with encryption.
1198
 * @param [in]  keySz     Size of key in bytes.
1199
 * @param [in]  salt      Random non-secret value.
1200
 * @param [in]  saltSz    Size of random in bytes.
1201
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1202
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1203
 * @param [in]  idx       Index value to XOR in.
1204
 * @param [in]  label     Label to use when deriving key.
1205
 * @param [out] outKey    Derived key.
1206
 * @param [in]  outKeySz  Size of derived key in bytes.
1207
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1208
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1209
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1210
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1211
 * @return  MEMORY_E on dynamic memory allocation failure.
1212
 * @return  0 on success.
1213
 */
1214
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1215
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1216
        word32 outKeySz)
1217
{
1218
    int ret = 0;
1219
    byte block[WC_AES_BLOCK_SIZE];
1220
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1221
    int aes_inited = 0;
1222
1223
    /* Validate parameters. */
1224
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1225
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1226
            (outKey == NULL) || ((kdrIdx >= 0) && (idx == NULL))) {
1227
        ret = BAD_FUNC_ARG;
1228
    }
1229
1230
#ifdef WOLFSSL_SMALL_STACK
1231
    if (ret == 0) {
1232
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1233
        if (aes == NULL) {
1234
            ret = MEMORY_E;
1235
        }
1236
    }
1237
#endif
1238
1239
    /* Setup AES object. */
1240
    if (ret == 0) {
1241
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1242
    }
1243
    if (ret == 0) {
1244
        aes_inited = 1;
1245
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1246
    }
1247
1248
    /* Calculate first block that can be used in each derivation. */
1249
    if (ret == 0) {
1250
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTP_INDEX_LEN,
1251
            block);
1252
    }
1253
    if (ret == 0) {
1254
        /* Calculate key. */
1255
        ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN, label, outKey,
1256
            outKeySz, aes);
1257
    }
1258
1259
    if (aes_inited)
1260
        wc_AesFree(aes);
1261
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1262
    return ret;
1263
1264
}
1265
1266
/* Derive key with label using SRTCP KDF algorithm.
1267
 *
1268
 * SP 800-135 (RFC 3711).
1269
 *
1270
 * @param [in]  key       Key to use with encryption.
1271
 * @param [in]  keySz     Size of key in bytes.
1272
 * @param [in]  salt      Random non-secret value.
1273
 * @param [in]  saltSz    Size of random in bytes.
1274
 * @param [in]  kdrIdx    Key derivation rate index. kdr = 0 when -1, otherwise
1275
 *                        kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1276
 * @param [in]  idx       Index value to XOR in.
1277
 * @param [in]  label     Label to use when deriving key.
1278
 * @param [out] outKey    Derived key.
1279
 * @param [in]  outKeySz  Size of derived key in bytes.
1280
 * @return  BAD_FUNC_ARG when key, salt or outKey is NULL.
1281
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1282
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1283
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1284
 * @return  MEMORY_E on dynamic memory allocation failure.
1285
 * @return  0 on success.
1286
 */
1287
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1288
        word32 saltSz, int kdrIdx, const byte* idx, byte label, byte* outKey,
1289
        word32 outKeySz)
1290
{
1291
    int ret = 0;
1292
    byte block[WC_AES_BLOCK_SIZE];
1293
    WC_DECLARE_VAR(aes, Aes, 1, 0);
1294
    int aes_inited = 0;
1295
1296
    /* Validate parameters. */
1297
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1298
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1299
            (outKey == NULL) || ((kdrIdx >= 0) && (idx == NULL))) {
1300
        ret = BAD_FUNC_ARG;
1301
    }
1302
1303
#ifdef WOLFSSL_SMALL_STACK
1304
    if (ret == 0) {
1305
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1306
        if (aes == NULL) {
1307
            ret = MEMORY_E;
1308
        }
1309
    }
1310
#endif
1311
1312
    /* Setup AES object. */
1313
    if (ret == 0) {
1314
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1315
    }
1316
    if (ret == 0) {
1317
        aes_inited = 1;
1318
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1319
    }
1320
1321
    /* Calculate first block that can be used in each derivation. */
1322
    if (ret == 0) {
1323
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, idx, WC_SRTCP_INDEX_LEN,
1324
            block);
1325
    }
1326
    if (ret == 0) {
1327
        /* Calculate key. */
1328
        ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN, label, outKey,
1329
            outKeySz, aes);
1330
    }
1331
1332
    if (aes_inited)
1333
        wc_AesFree(aes);
1334
    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_CIPHER);
1335
    return ret;
1336
1337
}
1338
1339
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
1340
 *
1341
 * @param [in] kdr  Key derivation rate to convert.
1342
 * @return  Key derivation rate as an index.
1343
 */
1344
int wc_SRTP_KDF_kdr_to_idx(word32 kdr)
1345
{
1346
    int idx = -1;
1347
1348
    /* Keep shifting value down and incrementing index until top bit is gone. */
1349
    while (kdr != 0) {
1350
        kdr >>= 1;
1351
        idx++;
1352
    }
1353
1354
    /* Index of top bit set. */
1355
    return idx;
1356
}
1357
#endif /* WC_SRTP_KDF */
1358
1359
#ifdef WC_KDF_NIST_SP_800_56C
1360
static int wc_KDA_KDF_iteration(const byte* z, word32 zSz, word32 counter,
1361
    const byte* fixedInfo, word32 fixedInfoSz, enum wc_HashType hashType,
1362
    byte* output)
1363
{
1364
    byte counterBuf[4];
1365
    WC_DECLARE_VAR(hash, wc_HashAlg, 1, NULL);
1366
    int ret;
1367
1368
    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
1369
                    return MEMORY_E);
1370
1371
    ret = wc_HashInit(hash, hashType);
1372
    if (ret != 0) {
1373
        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
1374
        return ret;
1375
    }
1376
    c32toa(counter, counterBuf);
1377
    ret = wc_HashUpdate(hash, hashType, counterBuf, 4);
1378
    if (ret == 0) {
1379
        ret = wc_HashUpdate(hash, hashType, z, zSz);
1380
    }
1381
    if (ret == 0 && fixedInfoSz > 0) {
1382
        ret = wc_HashUpdate(hash, hashType, fixedInfo, fixedInfoSz);
1383
    }
1384
    if (ret == 0) {
1385
        ret = wc_HashFinal(hash, hashType, output);
1386
    }
1387
    wc_HashFree(hash, hashType);
1388
    WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
1389
    return ret;
1390
}
1391
1392
/**
1393
 * \brief Performs the single-step key derivation function (KDF) as specified in
1394
 * SP800-56C option 1. This implementation uses a 32 bit counter.
1395
 *
1396
 * \param [in] z The input keying material.
1397
 * \param [in] zSz The size of the input keying material.
1398
 * \param [in] fixedInfo The fixed information to be included in the KDF.
1399
 * \param [in] fixedInfoSz The size of the fixed information.
1400
 * \param [in] derivedSecretSz The desired size of the derived secret.
1401
 * \param [in] hashType The hash algorithm to be used in the KDF.
1402
 * \param [out] output The buffer to store the derived secret.
1403
 * \param [in] outputSz The size of the output buffer.
1404
 *
1405
 * \return 0 if the KDF operation is successful.
1406
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1407
 * \return negative error code if the KDF operation fails.
1408
 */
1409
int wc_KDA_KDF_onestep(const byte* z, word32 zSz, const byte* fixedInfo,
1410
    word32 fixedInfoSz, word32 derivedSecretSz, enum wc_HashType hashType,
1411
    byte* output, word32 outputSz)
1412
{
1413
    byte hashTempBuf[WC_MAX_DIGEST_SIZE];
1414
    word32 counter, outIdx;
1415
    int hashOutSz;
1416
    int ret;
1417
1418
    if (output == NULL || outputSz < derivedSecretSz)
1419
        return BAD_FUNC_ARG;
1420
    if (z == NULL || zSz == 0 || (fixedInfoSz > 0 && fixedInfo == NULL))
1421
        return BAD_FUNC_ARG;
1422
    if (derivedSecretSz == 0)
1423
        return BAD_FUNC_ARG;
1424
1425
    hashOutSz = wc_HashGetDigestSize(hashType);
1426
    if (hashOutSz <= 0)
1427
        return BAD_FUNC_ARG;
1428
1429
    /* According to SP800_56C, table 1, the max input size (max_H_inputBits)
1430
     * depends on the HASH algo. The smaller value in the table is (2**64-1)/8.
1431
     * This is larger than the possible length using word32 integers. */
1432
1433
    counter = 1; /* init counter to 1, from SP800-56C section 4.1 */
1434
    outIdx = 0;
1435
    ret = 0;
1436
1437
    /* According to SP800_56C the number of iterations shall not be greater than
1438
     * 2**32-1. This is not possible using word32 integers.*/
1439
    while (outIdx + (word32) hashOutSz <= derivedSecretSz) {
1440
        ret = wc_KDA_KDF_iteration(z, zSz, counter, fixedInfo, fixedInfoSz,
1441
            hashType, output + outIdx);
1442
        if (ret != 0)
1443
            break;
1444
        counter++;
1445
        outIdx += (word32) hashOutSz;
1446
    }
1447
1448
    if (ret == 0 && outIdx < derivedSecretSz) {
1449
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1450
        /* poison so a missed ForceZero on any path is caught by the check */
1451
        XMEMSET(hashTempBuf, 0xff, (word32) hashOutSz);
1452
        wc_MemZero_Add("wc_KDA_KDF_onestep hashTempBuf", hashTempBuf,
1453
            (word32) hashOutSz);
1454
    #endif
1455
        ret = wc_KDA_KDF_iteration(z, zSz, counter, fixedInfo, fixedInfoSz,
1456
            hashType, hashTempBuf);
1457
        if (ret == 0) {
1458
            XMEMCPY(output + outIdx, hashTempBuf, derivedSecretSz - outIdx);
1459
        }
1460
        ForceZero(hashTempBuf, (word32) hashOutSz);
1461
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1462
        wc_MemZero_Check(hashTempBuf, (word32) hashOutSz);
1463
    #endif
1464
    }
1465
1466
    if (ret != 0) {
1467
        ForceZero(output, derivedSecretSz);
1468
    }
1469
1470
    return ret;
1471
}
1472
#endif /* WC_KDF_NIST_SP_800_56C */
1473
1474
#ifdef HAVE_CMAC_KDF
1475
/**
1476
 * \brief Performs the two-step cmac key derivation function (KDF) as
1477
 * specified in SP800-56C, section 5.1, in counter mode.
1478
 *
1479
 *            Z                               fixedInfo
1480
 *        ____|_________________________________|___________
1481
 *       |    |                                 |           |
1482
 *       |    ________________                ___________   |
1483
 * salt--|-> | Randomness     |              | Key       |  |
1484
 *       |   | Extract        | --Key_kdk--> | Expansion | -|-output-->
1485
 *       |    ----------------                -----------   |
1486
 *        --------------------------------------------------
1487
 *
1488
 * \param [in]  salt         The input keying material for cmac.
1489
 * \param [in]  salt_len     The size of the input keying material.
1490
 * \param [in]  z            The input shared secret (message to cmac).
1491
 * \param [in]  zSz          The size of the input shared secret.
1492
 * \param [in]  fixedInfo    The fixed information in the KDF.
1493
 * \param [in]  fixedInfoSz  The size of the fixed information.
1494
 * \param [out] output       The buffer to store the derived secret.
1495
 * \param [in]  outputSz     The desired size of the output secret.
1496
 * \param [in]  heap         The heap hint.
1497
 * \param [in]  devId        The device id.
1498
 *
1499
 * \return 0 if the KDF operation is successful.
1500
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1501
 * \return negative error code if the KDF operation fails.
1502
 */
1503
int wc_KDA_KDF_twostep_cmac(const byte * salt, word32 salt_len,
1504
                            const byte* z, word32 zSz,
1505
                            const byte* fixedInfo, word32 fixedInfoSz,
1506
                            byte* output, word32 outputSz,
1507
                            void * heap, int devId)
1508
{
1509
    byte   Key_kdk[WC_AES_BLOCK_SIZE]; /* key derivation key*/
1510
    word32 kdk_len = sizeof(Key_kdk);
1511
    word32 tag_len = WC_AES_BLOCK_SIZE;
1512
    #ifdef WOLFSSL_SMALL_STACK
1513
    Cmac * cmac = NULL;
1514
    #else
1515
    Cmac   cmac[1];
1516
    #endif /* WOLFSSL_SMALL_STACK */
1517
    int    ret = 0;
1518
1519
    /* screen out bad args. */
1520
    switch (salt_len) {
1521
    case AES_128_KEY_SIZE:
1522
    case AES_192_KEY_SIZE:
1523
    case AES_256_KEY_SIZE:
1524
        break; /* salt ok */
1525
    default:
1526
        WOLFSSL_MSG_EX("KDF twostep cmac: bad salt len: %d", salt_len);
1527
        return BAD_FUNC_ARG;
1528
    }
1529
1530
    if (zSz == 0 || outputSz == 0) {
1531
        return BAD_FUNC_ARG;
1532
    }
1533
1534
    if (fixedInfoSz > 0 && fixedInfo == NULL) {
1535
        return BAD_FUNC_ARG;
1536
    }
1537
1538
    if (salt == NULL || z == NULL || output == NULL) {
1539
        return BAD_FUNC_ARG;
1540
    }
1541
1542
    #ifdef WOLF_CRYPTO_CB
1543
    /* Try crypto callback first for complete operation */
1544
    if (devId != INVALID_DEVID) {
1545
         ret = wc_CryptoCb_Kdf_TwostepCmac(salt, salt_len, z, zSz,
1546
                                           fixedInfo, fixedInfoSz,
1547
                                           output, outputSz, devId);
1548
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
1549
            return ret;
1550
        }
1551
        /* fall-through when unavailable */
1552
    }
1553
    #endif
1554
1555
    XMEMSET(Key_kdk, 0, kdk_len);
1556
#ifdef WOLFSSL_CHECK_MEM_ZERO
1557
    /* register at the 0 baseline; every exit below checks it */
1558
    wc_MemZero_Add("wc_KDA_KDF_twostep_cmac Key_kdk", Key_kdk,
1559
        sizeof(Key_kdk));
1560
#endif
1561
1562
    #ifdef WOLFSSL_SMALL_STACK
1563
    cmac = (Cmac*)XMALLOC(sizeof(Cmac), heap, DYNAMIC_TYPE_CMAC);
1564
    if (cmac == NULL) {
1565
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1566
        wc_MemZero_Check(Key_kdk, sizeof(Key_kdk));
1567
    #endif
1568
        return MEMORY_E;
1569
    }
1570
    #endif
1571
1572
    /* step 1: cmac extract */
1573
    ret = wc_AesCmacGenerate_ex(cmac, Key_kdk, &tag_len, z, zSz, salt, salt_len,
1574
                                heap, devId);
1575
1576
    if (ret == 0) {
1577
        if (tag_len != WC_AES_BLOCK_SIZE) {
1578
            WOLFSSL_MSG_EX("KDF twostep cmac: got %d, expected %d\n",
1579
                           tag_len, WC_AES_BLOCK_SIZE);
1580
            ret = BUFFER_E;
1581
        }
1582
    }
1583
1584
    #ifdef WOLFSSL_SMALL_STACK
1585
    if (cmac) {
1586
        XFREE(cmac, heap, DYNAMIC_TYPE_CMAC);
1587
        cmac = NULL;
1588
    }
1589
    #endif /* WOLFSSL_SMALL_STACK */
1590
1591
    /* step 2: cmac expand with SP 800-108 PRF.
1592
     * If AES-128-CMAC, AES-192-CMAC, or AES-256-CMAC is used in the
1593
     * randomness extraction step, then only AES-128-CMAC is used in the
1594
     * key-expansion step.*/
1595
    if (ret == 0) {
1596
        ret = wc_KDA_KDF_PRF_cmac(Key_kdk, kdk_len, fixedInfo, fixedInfoSz,
1597
                                  output, outputSz, WC_CMAC_AES,
1598
                                  heap, devId);
1599
    }
1600
1601
    /* always force zero the intermediate key derivation key. */
1602
    ForceZero(Key_kdk, sizeof(Key_kdk));
1603
#ifdef WOLFSSL_CHECK_MEM_ZERO
1604
    wc_MemZero_Check(Key_kdk, sizeof(Key_kdk));
1605
#endif
1606
1607
    return ret;
1608
}
1609
1610
/**
1611
 * \brief Performs the KDF PRF as specified in SP800-108r1.
1612
 * At the moment, only AES-CMAC counter mode (section 4.1) is
1613
 * implemented. This implementation uses a 32 bit counter.
1614
 *
1615
 * \param [in]  Kin       The input keying material.
1616
 * \param [in]  KinSz     The size of the input keying material.
1617
 * \param [in]  fixedInfo The fixed information to be included in the KDF.
1618
 * \param [in]  fixedInfo Sz The size of the fixed information.
1619
 * \param [out] Kout      The output keying material.
1620
 * \param [in]  KoutSz    The desired size of the output key.
1621
 * \param [in]  type      The type of cmac.
1622
 * \param [in]  heap      The heap hint.
1623
 * \param [in]  devId     The device id.
1624
 *
1625
 * \return 0 if the KDF operation is successful.
1626
 * \return BAD_FUNC_ARG if the input parameters are invalid.
1627
 * \return negative error code if the KDF operation fails.
1628
 */
1629
int wc_KDA_KDF_PRF_cmac(const byte* Kin, word32 KinSz,
1630
                        const byte* fixedInfo, word32 fixedInfoSz,
1631
                        byte* Kout, word32 KoutSz, CmacType type,
1632
                        void * heap, int devId)
1633
{
1634
    word32 len_rem = KoutSz;
1635
    word32 tag_len = WC_AES_BLOCK_SIZE;
1636
    word32 counter = 1; /* init counter to 1, from SP800-108r1 section 4.1 */
1637
    #ifdef WOLFSSL_SMALL_STACK
1638
    Cmac * cmac = NULL;
1639
    #else
1640
    Cmac   cmac[1];
1641
    #endif /* WOLFSSL_SMALL_STACK */
1642
    byte   counterBuf[4];
1643
    int    ret = 0;
1644
1645
    /* screen out bad args. */
1646
    if (Kin == NULL || Kout == NULL) {
1647
        return BAD_FUNC_ARG;
1648
    }
1649
1650
    if (fixedInfoSz > 0 && fixedInfo == NULL) {
1651
        return BAD_FUNC_ARG;
1652
    }
1653
1654
    if (KoutSz == 0) {
1655
        return BAD_FUNC_ARG;
1656
    }
1657
1658
    /* Only AES-CMAC PRF supported at this time. */
1659
    if (type != WC_CMAC_AES) {
1660
        return BAD_FUNC_ARG;
1661
    }
1662
1663
    #ifdef WOLFSSL_SMALL_STACK
1664
    cmac = (Cmac*)XMALLOC(sizeof(Cmac), heap, DYNAMIC_TYPE_CMAC);
1665
    if (cmac == NULL) {
1666
        return MEMORY_E;
1667
    }
1668
    #endif
1669
1670
    while (len_rem >= WC_AES_BLOCK_SIZE) {
1671
        int cmac_inited = 0;
1672
        /* cmac in place in block size increments */
1673
        c32toa(counter, counterBuf);
1674
        #ifdef WOLFSSL_DEBUG_KDF
1675
        WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: in place: "
1676
                       "len_rem = %d, i = %d", len_rem, counter);
1677
        #endif /* WOLFSSL_DEBUG_KDF */
1678
1679
        ret = wc_InitCmac_ex(cmac, Kin, KinSz, WC_CMAC_AES, NULL, heap, devId);
1680
1681
        if (ret == 0) {
1682
            cmac_inited = 1;
1683
            ret = wc_CmacUpdate(cmac, counterBuf, sizeof(counterBuf));
1684
        }
1685
1686
        if (ret == 0 && fixedInfoSz > 0) {
1687
            ret = wc_CmacUpdate(cmac, fixedInfo, fixedInfoSz);
1688
        }
1689
1690
        if (ret == 0) {
1691
            ret = wc_CmacFinalNoFree(cmac, &Kout[KoutSz - len_rem], &tag_len);
1692
1693
            if (tag_len != WC_AES_BLOCK_SIZE) {
1694
                WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: got %d, expected %d\n",
1695
                               tag_len, WC_AES_BLOCK_SIZE);
1696
                ret = BUFFER_E;
1697
            }
1698
        }
1699
1700
        if (cmac_inited)
1701
            (void)wc_CmacFree(cmac);
1702
1703
        if (ret != 0) { break; }
1704
1705
        len_rem -= WC_AES_BLOCK_SIZE;
1706
        ++counter;
1707
    }
1708
1709
    if (ret == 0 && len_rem) {
1710
        /* cmac the last little bit that wouldn't fit in a block size. */
1711
        byte rem[WC_AES_BLOCK_SIZE];
1712
        int cmac_inited = 0;
1713
        XMEMSET(rem, 0, sizeof(rem));
1714
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1715
        wc_MemZero_Add("wc_KDA_KDF_PRF_cmac rem", rem, sizeof(rem));
1716
    #endif
1717
        c32toa(counter, counterBuf);
1718
1719
        #ifdef WOLFSSL_DEBUG_KDF
1720
        WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: last little bit: "
1721
                       "len_rem = %d, i = %d", len_rem, counter);
1722
        #endif /* WOLFSSL_DEBUG_KDF */
1723
1724
        ret = wc_InitCmac_ex(cmac, Kin, KinSz, WC_CMAC_AES, NULL, heap, devId);
1725
1726
        if (ret == 0) {
1727
            cmac_inited = 1;
1728
            ret = wc_CmacUpdate(cmac, counterBuf, sizeof(counterBuf));
1729
        }
1730
1731
        if (ret == 0 && fixedInfoSz > 0) {
1732
            ret = wc_CmacUpdate(cmac, fixedInfo, fixedInfoSz);
1733
        }
1734
1735
        if (ret == 0) {
1736
            ret = wc_CmacFinalNoFree(cmac, rem, &tag_len);
1737
1738
            if (tag_len != WC_AES_BLOCK_SIZE) {
1739
                WOLFSSL_MSG_EX("wc_KDA_KDF_PRF_cmac: got %d, expected %d\n",
1740
                               tag_len, WC_AES_BLOCK_SIZE);
1741
                ret = BUFFER_E;
1742
            }
1743
        }
1744
1745
        if (ret == 0) {
1746
            XMEMCPY(&Kout[KoutSz - len_rem], rem, len_rem);
1747
        }
1748
1749
        ForceZero(rem, sizeof(rem));
1750
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1751
        wc_MemZero_Check(rem, sizeof(rem));
1752
    #endif
1753
        if (cmac_inited)
1754
            (void)wc_CmacFree(cmac);
1755
    }
1756
1757
    #ifdef WOLFSSL_SMALL_STACK
1758
    if (cmac) {
1759
        XFREE(cmac, heap, DYNAMIC_TYPE_CMAC);
1760
        cmac = NULL;
1761
    }
1762
    #endif /* WOLFSSL_SMALL_STACK */
1763
1764
    if (ret != 0) {
1765
        ForceZero(Kout, KoutSz);
1766
    }
1767
1768
    return ret;
1769
}
1770
#endif /* HAVE_CMAC_KDF */
1771
1772
#endif /* NO_KDF */