Coverage Report

Created: 2026-11-12 06:38

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