Coverage Report

Created: 2025-04-11 06:45

/src/wolfssl/wolfcrypt/src/kdf.c
Line
Count
Source (jump to first uncovered line)
1
/* kdf.c
2
 *
3
 * Copyright (C) 2006-2023 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 2 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
23
#ifdef HAVE_CONFIG_H
24
    #include <config.h>
25
#endif
26
27
#include <wolfssl/wolfcrypt/wc_port.h>
28
#include <wolfssl/wolfcrypt/error-crypt.h>
29
#include <wolfssl/wolfcrypt/logging.h>
30
31
#ifndef NO_KDF
32
33
#if defined(HAVE_FIPS) && \
34
    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
35
36
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
37
    #define FIPS_NO_WRAPPERS
38
39
    #ifdef USE_WINDOWS_API
40
        #pragma code_seg(".fipsA$m")
41
        #pragma const_seg(".fipsB$m")
42
    #endif
43
#endif
44
45
46
#ifdef NO_INLINE
47
    #include <wolfssl/wolfcrypt/misc.h>
48
#else
49
    #define WOLFSSL_MISC_INCLUDED
50
    #include <wolfcrypt/src/misc.c>
51
#endif
52
53
#include <wolfssl/wolfcrypt/hmac.h>
54
#include <wolfssl/wolfcrypt/kdf.h>
55
#ifdef WC_SRTP_KDF
56
#include <wolfssl/wolfcrypt/aes.h>
57
#endif
58
59
60
#if defined(WOLFSSL_HAVE_PRF) && !defined(NO_HMAC)
61
62
#ifdef WOLFSSL_SHA512
63
0
    #define P_HASH_MAX_SIZE WC_SHA512_DIGEST_SIZE
64
#elif defined(WOLFSSL_SHA384)
65
    #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE
66
#else
67
    #define P_HASH_MAX_SIZE WC_SHA256_DIGEST_SIZE
68
#endif
69
70
/* Pseudo Random Function for MD5, SHA-1, SHA-256, SHA-384, or SHA-512 */
71
int wc_PRF(byte* result, word32 resLen, const byte* secret,
72
                  word32 secLen, const byte* seed, word32 seedLen, int hash,
73
                  void* heap, int devId)
74
0
{
75
0
    word32 len = P_HASH_MAX_SIZE;
76
0
    word32 times;
77
0
    word32 lastLen;
78
0
    word32 lastTime;
79
0
    int    ret = 0;
80
0
#ifdef WOLFSSL_SMALL_STACK
81
0
    byte*  previous;
82
0
    byte*  current;
83
0
    Hmac*  hmac;
84
#else
85
    byte   previous[P_HASH_MAX_SIZE];  /* max size */
86
    byte   current[P_HASH_MAX_SIZE];   /* max size */
87
    Hmac   hmac[1];
88
#endif
89
90
0
    switch (hash) {
91
0
    #ifndef NO_MD5
92
0
        case md5_mac:
93
0
            hash = WC_MD5;
94
0
            len  = WC_MD5_DIGEST_SIZE;
95
0
        break;
96
0
    #endif
97
98
0
    #ifndef NO_SHA256
99
0
        case sha256_mac:
100
0
            hash = WC_SHA256;
101
0
            len  = WC_SHA256_DIGEST_SIZE;
102
0
        break;
103
0
    #endif
104
105
0
    #ifdef WOLFSSL_SHA384
106
0
        case sha384_mac:
107
0
            hash = WC_SHA384;
108
0
            len  = WC_SHA384_DIGEST_SIZE;
109
0
        break;
110
0
    #endif
111
112
0
    #ifdef WOLFSSL_SHA512
113
0
        case sha512_mac:
114
0
            hash = WC_SHA512;
115
0
            len  = WC_SHA512_DIGEST_SIZE;
116
0
        break;
117
0
    #endif
118
119
0
    #ifdef WOLFSSL_SM3
120
0
        case sm3_mac:
121
0
            hash = WC_SM3;
122
0
            len  = WC_SM3_DIGEST_SIZE;
123
0
        break;
124
0
    #endif
125
126
0
    #ifndef NO_SHA
127
0
        case sha_mac:
128
0
            hash = WC_SHA;
129
0
            len  = WC_SHA_DIGEST_SIZE;
130
0
        break;
131
0
    #endif
132
0
        default:
133
0
            return HASH_TYPE_E;
134
0
    }
135
136
0
    times   = resLen / len;
137
0
    lastLen = resLen % len;
138
139
0
    if (lastLen)
140
0
        times += 1;
141
142
    /* times == 0 if resLen == 0, but times == 0 abides clang static analyzer
143
       while resLen == 0 doesn't */
144
0
    if (times == 0)
145
0
        return BAD_FUNC_ARG;
146
147
0
    lastTime = times - 1;
148
149
0
#ifdef WOLFSSL_SMALL_STACK
150
0
    previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
151
0
    current  = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
152
0
    hmac     = (Hmac*)XMALLOC(sizeof(Hmac),    heap, DYNAMIC_TYPE_HMAC);
153
0
    if (previous == NULL || current == NULL || hmac == NULL) {
154
0
        if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
155
0
        if (current)  XFREE(current,  heap, DYNAMIC_TYPE_DIGEST);
156
0
        if (hmac)     XFREE(hmac,     heap, DYNAMIC_TYPE_HMAC);
157
0
        return MEMORY_E;
158
0
    }
159
0
#endif
160
#ifdef WOLFSSL_CHECK_MEM_ZERO
161
    XMEMSET(previous, 0xff, P_HASH_MAX_SIZE);
162
    wc_MemZero_Add("wc_PRF previous", previous, P_HASH_MAX_SIZE);
163
    wc_MemZero_Add("wc_PRF current", current, P_HASH_MAX_SIZE);
164
    wc_MemZero_Add("wc_PRF hmac", hmac, sizeof(Hmac));
165
#endif
166
167
0
    ret = wc_HmacInit(hmac, heap, devId);
168
0
    if (ret == 0) {
169
0
        ret = wc_HmacSetKey(hmac, hash, secret, secLen);
170
0
        if (ret == 0)
171
0
            ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */
172
0
        if (ret == 0)
173
0
            ret = wc_HmacFinal(hmac, previous);       /* A1 */
174
0
        if (ret == 0) {
175
0
            word32 i;
176
0
            word32 idx = 0;
177
178
0
            for (i = 0; i < times; i++) {
179
0
                ret = wc_HmacUpdate(hmac, previous, len);
180
0
                if (ret != 0)
181
0
                    break;
182
0
                ret = wc_HmacUpdate(hmac, seed, seedLen);
183
0
                if (ret != 0)
184
0
                    break;
185
0
                ret = wc_HmacFinal(hmac, current);
186
0
                if (ret != 0)
187
0
                    break;
188
189
0
                if ((i == lastTime) && lastLen)
190
0
                    XMEMCPY(&result[idx], current,
191
0
                                             min(lastLen, P_HASH_MAX_SIZE));
192
0
                else {
193
0
                    XMEMCPY(&result[idx], current, len);
194
0
                    idx += len;
195
0
                    ret = wc_HmacUpdate(hmac, previous, len);
196
0
                    if (ret != 0)
197
0
                        break;
198
0
                    ret = wc_HmacFinal(hmac, previous);
199
0
                    if (ret != 0)
200
0
                        break;
201
0
                }
202
0
            }
203
0
        }
204
0
        wc_HmacFree(hmac);
205
0
    }
206
207
0
    ForceZero(previous,  P_HASH_MAX_SIZE);
208
0
    ForceZero(current,   P_HASH_MAX_SIZE);
209
0
    ForceZero(hmac,      sizeof(Hmac));
210
211
#if defined(WOLFSSL_CHECK_MEM_ZERO)
212
    wc_MemZero_Check(previous, P_HASH_MAX_SIZE);
213
    wc_MemZero_Check(current,  P_HASH_MAX_SIZE);
214
    wc_MemZero_Check(hmac,     sizeof(Hmac));
215
#endif
216
217
0
#ifdef WOLFSSL_SMALL_STACK
218
0
    XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
219
0
    XFREE(current,  heap, DYNAMIC_TYPE_DIGEST);
220
0
    XFREE(hmac,     heap, DYNAMIC_TYPE_HMAC);
221
0
#endif
222
223
0
    return ret;
224
0
}
225
#undef P_HASH_MAX_SIZE
226
227
/* compute PRF (pseudo random function) using SHA1 and MD5 for TLSv1 */
228
int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
229
           word32 secLen, const byte* label, word32 labLen,
230
           const byte* seed, word32 seedLen, void* heap, int devId)
231
0
{
232
0
    int         ret  = 0;
233
0
    word32      half = (secLen + 1) / 2;
234
0
    const byte* md5_half;
235
0
    const byte* sha_half;
236
0
    byte*      md5_result;
237
0
#ifdef WOLFSSL_SMALL_STACK
238
0
    byte*      sha_result;
239
0
    byte*      labelSeed;
240
#else
241
    byte       sha_result[MAX_PRF_DIG];    /* digLen is real size */
242
    byte       labelSeed[MAX_PRF_LABSEED];
243
#endif
244
245
0
    if (half > MAX_PRF_HALF ||
246
0
        labLen + seedLen > MAX_PRF_LABSEED ||
247
0
        digLen > MAX_PRF_DIG)
248
0
    {
249
0
        return BUFFER_E;
250
0
    }
251
252
0
#ifdef WOLFSSL_SMALL_STACK
253
0
    sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
254
0
    labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST);
255
0
    if (sha_result == NULL || labelSeed == NULL) {
256
0
        XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
257
0
        XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
258
0
        return MEMORY_E;
259
0
    }
260
0
#endif
261
262
0
    md5_half = secret;
263
0
    sha_half = secret + half - secLen % 2;
264
0
    md5_result = digest;
265
266
0
    XMEMCPY(labelSeed, label, labLen);
267
0
    XMEMCPY(labelSeed + labLen, seed, seedLen);
268
269
0
    if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
270
0
                                labLen + seedLen, md5_mac, heap, devId)) == 0) {
271
0
        if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
272
0
                                labLen + seedLen, sha_mac, heap, devId)) == 0) {
273
        #ifdef WOLFSSL_CHECK_MEM_ZERO
274
            wc_MemZero_Add("wc_PRF_TLSv1 sha_result", sha_result, digLen);
275
        #endif
276
            /* calculate XOR for TLSv1 PRF */
277
            /* md5 result is placed directly in digest */
278
0
            xorbuf(digest, sha_result, digLen);
279
0
            ForceZero(sha_result, digLen);
280
0
        }
281
0
    }
282
283
#if defined(WOLFSSL_CHECK_MEM_ZERO)
284
    wc_MemZero_Check(sha_result, MAX_PRF_DIG);
285
#endif
286
287
0
#ifdef WOLFSSL_SMALL_STACK
288
0
    XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
289
0
    XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
290
0
#endif
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 (useAtLeastSha256) {
304
0
    #ifdef WOLFSSL_SMALL_STACK
305
0
        byte* labelSeed;
306
    #else
307
        byte  labelSeed[MAX_PRF_LABSEED];
308
    #endif
309
310
0
        if (labLen + seedLen > MAX_PRF_LABSEED) {
311
0
            return BUFFER_E;
312
0
        }
313
314
0
    #ifdef WOLFSSL_SMALL_STACK
315
0
        labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST);
316
0
        if (labelSeed == NULL) {
317
0
            return MEMORY_E;
318
0
        }
319
0
    #endif
320
321
0
        XMEMCPY(labelSeed, label, labLen);
322
0
        XMEMCPY(labelSeed + labLen, seed, seedLen);
323
324
        /* If a cipher suite wants an algorithm better than sha256, it
325
         * should use better. */
326
0
        if (hash_type < sha256_mac || hash_type == blake2b_mac) {
327
0
            hash_type = sha256_mac;
328
0
        }
329
        /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
330
0
        ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
331
0
                     labLen + seedLen, hash_type, heap, devId);
332
333
0
    #ifdef WOLFSSL_SMALL_STACK
334
0
        XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
335
0
    #endif
336
0
    }
337
0
    else {
338
#ifndef NO_OLD_TLS
339
        /* compute TLSv1 PRF (pseudo random function using HMAC) */
340
        ret = wc_PRF_TLSv1(digest, digLen, secret, secLen, label, labLen, seed,
341
                          seedLen, heap, devId);
342
#else
343
0
        ret = BAD_FUNC_ARG;
344
0
#endif
345
0
    }
346
347
0
    return ret;
348
0
}
349
#endif /* WOLFSSL_HAVE_PRF && !NO_HMAC */
350
351
352
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
353
354
    /* Extract data using HMAC, salt and input.
355
     * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
356
     *
357
     * prk      The generated pseudorandom key.
358
     * salt     The salt.
359
     * saltLen  The length of the salt.
360
     * ikm      The input keying material.
361
     * ikmLen   The length of the input keying material.
362
     * digest   The type of digest to use.
363
     * returns 0 on success, otherwise failure.
364
     */
365
    int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen,
366
                                 byte* ikm, word32 ikmLen, int digest)
367
0
    {
368
0
        int ret;
369
0
        word32 len = 0;
370
371
0
        switch (digest) {
372
0
            #ifndef NO_SHA256
373
0
            case WC_SHA256:
374
0
                len = WC_SHA256_DIGEST_SIZE;
375
0
                break;
376
0
            #endif
377
378
0
            #ifdef WOLFSSL_SHA384
379
0
            case WC_SHA384:
380
0
                len = WC_SHA384_DIGEST_SIZE;
381
0
                break;
382
0
            #endif
383
384
            #ifdef WOLFSSL_TLS13_SHA512
385
            case WC_SHA512:
386
                len = WC_SHA512_DIGEST_SIZE;
387
                break;
388
            #endif
389
390
0
            #ifdef WOLFSSL_SM3
391
0
            case WC_SM3:
392
0
                len = WC_SM3_DIGEST_SIZE;
393
0
                break;
394
0
            #endif
395
396
0
            default:
397
0
                return BAD_FUNC_ARG;
398
0
        }
399
400
        /* When length is 0 then use zeroed data of digest length. */
401
0
        if (ikmLen == 0) {
402
0
            ikmLen = len;
403
0
            XMEMSET(ikm, 0, len);
404
0
        }
405
406
#ifdef WOLFSSL_DEBUG_TLS
407
        WOLFSSL_MSG("  Salt");
408
        WOLFSSL_BUFFER(salt, saltLen);
409
        WOLFSSL_MSG("  IKM");
410
        WOLFSSL_BUFFER(ikm, ikmLen);
411
#endif
412
413
0
        ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
414
415
#ifdef WOLFSSL_DEBUG_TLS
416
        WOLFSSL_MSG("  PRK");
417
        WOLFSSL_BUFFER(prk, len);
418
#endif
419
420
0
        return ret;
421
0
    }
422
423
    /* Expand data using HMAC, salt and label and info.
424
     * TLS v1.3 defines this function.
425
     *
426
     * okm          The generated pseudorandom key - output key material.
427
     * okmLen       The length of generated pseudorandom key -
428
     *              output key material.
429
     * prk          The salt - pseudo-random key.
430
     * prkLen       The length of the salt - pseudo-random key.
431
     * protocol     The TLS protocol label.
432
     * protocolLen  The length of the TLS protocol label.
433
     * info         The information to expand.
434
     * infoLen      The length of the information.
435
     * digest       The type of digest to use.
436
     * returns 0 on success, otherwise failure.
437
     */
438
    int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
439
                                 const byte* prk, word32 prkLen,
440
                                 const byte* protocol, word32 protocolLen,
441
                                 const byte* label, word32 labelLen,
442
                                 const byte* info, word32 infoLen,
443
                                 int digest)
444
0
    {
445
0
        int    ret = 0;
446
0
        word32 idx = 0;
447
0
    #ifdef WOLFSSL_SMALL_STACK
448
0
        byte*  data;
449
    #else
450
        byte   data[MAX_TLS13_HKDF_LABEL_SZ];
451
    #endif
452
453
        /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
454
         * labellen + infolen */
455
0
        idx = 4 + protocolLen + labelLen + infoLen;
456
0
        if (idx > MAX_TLS13_HKDF_LABEL_SZ) {
457
0
            return BUFFER_E;
458
0
        }
459
460
0
    #ifdef WOLFSSL_SMALL_STACK
461
0
        data = (byte*)XMALLOC(idx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
462
0
        if (data == NULL) {
463
0
            return MEMORY_E;
464
0
        }
465
0
    #endif
466
0
        idx = 0;
467
468
        /* Output length. */
469
0
        data[idx++] = (byte)(okmLen >> 8);
470
0
        data[idx++] = (byte)okmLen;
471
        /* Length of protocol | label. */
472
0
        data[idx++] = (byte)(protocolLen + labelLen);
473
        /* Protocol */
474
0
        XMEMCPY(&data[idx], protocol, protocolLen);
475
0
        idx += protocolLen;
476
        /* Label */
477
0
        XMEMCPY(&data[idx], label, labelLen);
478
0
        idx += labelLen;
479
        /* Length of hash of messages */
480
0
        data[idx++] = (byte)infoLen;
481
        /* Hash of messages */
482
0
        XMEMCPY(&data[idx], info, infoLen);
483
0
        idx += infoLen;
484
485
    #ifdef WOLFSSL_CHECK_MEM_ZERO
486
        wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
487
    #endif
488
489
#ifdef WOLFSSL_DEBUG_TLS
490
        WOLFSSL_MSG("  PRK");
491
        WOLFSSL_BUFFER(prk, prkLen);
492
        WOLFSSL_MSG("  Info");
493
        WOLFSSL_BUFFER(data, idx);
494
        WOLFSSL_MSG_EX("  Digest %d", digest);
495
#endif
496
497
0
        ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
498
499
#ifdef WOLFSSL_DEBUG_TLS
500
        WOLFSSL_MSG("  OKM");
501
        WOLFSSL_BUFFER(okm, okmLen);
502
#endif
503
504
0
        ForceZero(data, idx);
505
506
    #ifdef WOLFSSL_CHECK_MEM_ZERO
507
        wc_MemZero_Check(data, idx);
508
    #endif
509
0
    #ifdef WOLFSSL_SMALL_STACK
510
0
        XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
511
0
    #endif
512
0
        return ret;
513
0
    }
514
515
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                    \
516
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
517
    /* Expand data using HMAC, salt and label and info.
518
     * TLS v1.3 defines this function.
519
     *
520
     * okm          The generated pseudorandom key - output key material.
521
     * okmLen       The length of generated pseudorandom key -
522
     *              output key material.
523
     * prk          The salt - pseudo-random key.
524
     * prkLen       The length of the salt - pseudo-random key.
525
     * protocol     The TLS protocol label.
526
     * protocolLen  The length of the TLS protocol label.
527
     * info         The information to expand.
528
     * infoLen      The length of the information.
529
     * digest       The type of digest to use.
530
     *
531
     * This functions is very similar to wc_Tls13_HKDF_Expand_Label() but it
532
     * allocate memory if the stack space usually used isn't enough.
533
     *
534
     * returns 0 on success, otherwise failure.
535
     */
536
    int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen,
537
        const byte* prk, word32 prkLen, const byte* protocol,
538
        word32 protocolLen, const byte* label, word32 labelLen,
539
        const byte* info, word32 infoLen, int digest, void* heap)
540
    {
541
        int    ret = 0;
542
        int    idx = 0;
543
        int    len;
544
        byte   *data;
545
546
        (void)heap;
547
        /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
548
         * labellen + infolen */
549
        len = 4 + protocolLen + labelLen + infoLen;
550
551
        data = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);
552
        if (data == NULL)
553
            return BUFFER_E;
554
555
        /* Output length. */
556
        data[idx++] = (byte)(okmLen >> 8);
557
        data[idx++] = (byte)okmLen;
558
        /* Length of protocol | label. */
559
        data[idx++] = (byte)(protocolLen + labelLen);
560
        /* Protocol */
561
        XMEMCPY(&data[idx], protocol, protocolLen);
562
        idx += protocolLen;
563
        /* Label */
564
        XMEMCPY(&data[idx], label, labelLen);
565
        idx += labelLen;
566
        /* Length of hash of messages */
567
        data[idx++] = (byte)infoLen;
568
        /* Hash of messages */
569
        XMEMCPY(&data[idx], info, infoLen);
570
        idx += infoLen;
571
572
    #ifdef WOLFSSL_CHECK_MEM_ZERO
573
        wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
574
    #endif
575
576
#ifdef WOLFSSL_DEBUG_TLS
577
        WOLFSSL_MSG("  PRK");
578
        WOLFSSL_BUFFER(prk, prkLen);
579
        WOLFSSL_MSG("  Info");
580
        WOLFSSL_BUFFER(data, idx);
581
        WOLFSSL_MSG_EX("  Digest %d", digest);
582
#endif
583
584
        ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
585
586
#ifdef WOLFSSL_DEBUG_TLS
587
        WOLFSSL_MSG("  OKM");
588
        WOLFSSL_BUFFER(okm, okmLen);
589
#endif
590
591
        ForceZero(data, idx);
592
593
    #ifdef WOLFSSL_CHECK_MEM_ZERO
594
        wc_MemZero_Check(data, len);
595
    #endif
596
        XFREE(data, heap, DYNAMIC_TYPE_TMP_BUFFER);
597
        return ret;
598
    }
599
600
#endif
601
/* defined(WOLFSSL_TICKET_NONCE_MALLOC) && (!defined(HAVE_FIPS) ||
602
 *  FIPS_VERSION_GE(5,3)) */
603
604
#endif /* HAVE_HKDF && !NO_HMAC */
605
606
607
#ifdef WOLFSSL_WOLFSSH
608
609
/* hash union */
610
typedef union {
611
#ifndef NO_MD5
612
    wc_Md5 md5;
613
#endif
614
#ifndef NO_SHA
615
    wc_Sha sha;
616
#endif
617
#ifdef WOLFSSL_SHA224
618
    wc_Sha224 sha224;
619
#endif
620
#ifndef NO_SHA256
621
    wc_Sha256 sha256;
622
#endif
623
#ifdef WOLFSSL_SHA384
624
    wc_Sha384 sha384;
625
#endif
626
#ifdef WOLFSSL_SHA512
627
    wc_Sha512 sha512;
628
#endif
629
#ifdef WOLFSSL_SHA3
630
    wc_Sha3 sha3;
631
#endif
632
} _hash;
633
634
static
635
int _HashInit(byte hashId, _hash* hash)
636
{
637
    int ret = BAD_FUNC_ARG;
638
639
    switch (hashId) {
640
    #ifndef NO_SHA
641
        case WC_SHA:
642
            ret = wc_InitSha(&hash->sha);
643
            break;
644
    #endif /* !NO_SHA */
645
646
    #ifndef NO_SHA256
647
        case WC_SHA256:
648
            ret = wc_InitSha256(&hash->sha256);
649
            break;
650
    #endif /* !NO_SHA256 */
651
652
    #ifdef WOLFSSL_SHA384
653
        case WC_SHA384:
654
            ret = wc_InitSha384(&hash->sha384);
655
            break;
656
    #endif /* WOLFSSL_SHA384 */
657
    #ifdef WOLFSSL_SHA512
658
        case WC_SHA512:
659
            ret = wc_InitSha512(&hash->sha512);
660
            break;
661
    #endif /* WOLFSSL_SHA512 */
662
    }
663
664
    return ret;
665
}
666
667
static
668
int _HashUpdate(byte hashId, _hash* hash,
669
        const byte* data, word32 dataSz)
670
{
671
    int ret = BAD_FUNC_ARG;
672
673
    switch (hashId) {
674
    #ifndef NO_SHA
675
        case WC_SHA:
676
            ret = wc_ShaUpdate(&hash->sha, data, dataSz);
677
            break;
678
    #endif /* !NO_SHA */
679
680
    #ifndef NO_SHA256
681
        case WC_SHA256:
682
            ret = wc_Sha256Update(&hash->sha256, data, dataSz);
683
            break;
684
    #endif /* !NO_SHA256 */
685
686
    #ifdef WOLFSSL_SHA384
687
        case WC_SHA384:
688
            ret = wc_Sha384Update(&hash->sha384, data, dataSz);
689
            break;
690
    #endif /* WOLFSSL_SHA384 */
691
    #ifdef WOLFSSL_SHA512
692
        case WC_SHA512:
693
            ret = wc_Sha512Update(&hash->sha512, data, dataSz);
694
            break;
695
    #endif /* WOLFSSL_SHA512 */
696
    }
697
698
    return ret;
699
}
700
701
static
702
int _HashFinal(byte hashId, _hash* hash, byte* digest)
703
{
704
    int ret = BAD_FUNC_ARG;
705
706
    switch (hashId) {
707
    #ifndef NO_SHA
708
        case WC_SHA:
709
            ret = wc_ShaFinal(&hash->sha, digest);
710
            break;
711
    #endif /* !NO_SHA */
712
713
    #ifndef NO_SHA256
714
        case WC_SHA256:
715
            ret = wc_Sha256Final(&hash->sha256, digest);
716
            break;
717
    #endif /* !NO_SHA256 */
718
719
    #ifdef WOLFSSL_SHA384
720
        case WC_SHA384:
721
            ret = wc_Sha384Final(&hash->sha384, digest);
722
            break;
723
    #endif /* WOLFSSL_SHA384 */
724
    #ifdef WOLFSSL_SHA512
725
        case WC_SHA512:
726
            ret = wc_Sha512Final(&hash->sha512, digest);
727
            break;
728
    #endif /* WOLFSSL_SHA512 */
729
    }
730
731
    return ret;
732
}
733
734
static
735
void _HashFree(byte hashId, _hash* hash)
736
{
737
    switch (hashId) {
738
    #ifndef NO_SHA
739
        case WC_SHA:
740
            wc_ShaFree(&hash->sha);
741
            break;
742
    #endif /* !NO_SHA */
743
744
    #ifndef NO_SHA256
745
        case WC_SHA256:
746
            wc_Sha256Free(&hash->sha256);
747
            break;
748
    #endif /* !NO_SHA256 */
749
750
    #ifdef WOLFSSL_SHA384
751
        case WC_SHA384:
752
            wc_Sha384Free(&hash->sha384);
753
            break;
754
    #endif /* WOLFSSL_SHA384 */
755
    #ifdef WOLFSSL_SHA512
756
        case WC_SHA512:
757
            wc_Sha512Free(&hash->sha512);
758
            break;
759
    #endif /* WOLFSSL_SHA512 */
760
    }
761
}
762
763
764
#define LENGTH_SZ 4
765
766
int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz,
767
        const byte* k, word32 kSz, const byte* h, word32 hSz,
768
        const byte* sessionId, word32 sessionIdSz)
769
{
770
    word32 blocks, remainder;
771
    _hash hash;
772
    enum wc_HashType enmhashId = (enum wc_HashType)hashId;
773
    byte kPad = 0;
774
    byte pad = 0;
775
    byte kSzFlat[LENGTH_SZ];
776
    word32 digestSz;
777
    int ret;
778
779
    if (key == NULL || keySz == 0 ||
780
        k == NULL || kSz == 0 ||
781
        h == NULL || hSz == 0 ||
782
        sessionId == NULL || sessionIdSz == 0) {
783
784
        return BAD_FUNC_ARG;
785
    }
786
787
    ret = wc_HmacSizeByType(enmhashId);
788
    if (ret <= 0) {
789
        return BAD_FUNC_ARG;
790
    }
791
    digestSz = (word32)ret;
792
793
    if (k[0] & 0x80) kPad = 1;
794
    c32toa(kSz + kPad, kSzFlat);
795
796
    blocks = keySz / digestSz;
797
    remainder = keySz % digestSz;
798
799
    ret = _HashInit(enmhashId, &hash);
800
    if (ret == 0)
801
        ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
802
    if (ret == 0 && kPad)
803
        ret = _HashUpdate(enmhashId, &hash, &pad, 1);
804
    if (ret == 0)
805
        ret = _HashUpdate(enmhashId, &hash, k, kSz);
806
    if (ret == 0)
807
        ret = _HashUpdate(enmhashId, &hash, h, hSz);
808
    if (ret == 0)
809
        ret = _HashUpdate(enmhashId, &hash, &keyId, sizeof(keyId));
810
    if (ret == 0)
811
        ret = _HashUpdate(enmhashId, &hash, sessionId, sessionIdSz);
812
813
    if (ret == 0) {
814
        if (blocks == 0) {
815
            if (remainder > 0) {
816
                byte lastBlock[WC_MAX_DIGEST_SIZE];
817
                ret = _HashFinal(enmhashId, &hash, lastBlock);
818
                if (ret == 0)
819
                    XMEMCPY(key, lastBlock, remainder);
820
            }
821
        }
822
        else {
823
            word32 runningKeySz, curBlock;
824
825
            runningKeySz = digestSz;
826
            ret = _HashFinal(enmhashId, &hash, key);
827
828
            for (curBlock = 1; curBlock < blocks; curBlock++) {
829
                ret = _HashInit(enmhashId, &hash);
830
                if (ret != 0) break;
831
                ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
832
                if (ret != 0) break;
833
                if (kPad)
834
                    ret = _HashUpdate(enmhashId, &hash, &pad, 1);
835
                if (ret != 0) break;
836
                ret = _HashUpdate(enmhashId, &hash, k, kSz);
837
                if (ret != 0) break;
838
                ret = _HashUpdate(enmhashId, &hash, h, hSz);
839
                if (ret != 0) break;
840
                ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
841
                if (ret != 0) break;
842
                ret = _HashFinal(enmhashId, &hash, key + runningKeySz);
843
                if (ret != 0) break;
844
                runningKeySz += digestSz;
845
            }
846
847
            if (remainder > 0) {
848
                byte lastBlock[WC_MAX_DIGEST_SIZE];
849
                if (ret == 0)
850
                    ret = _HashInit(enmhashId, &hash);
851
                if (ret == 0)
852
                    ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
853
                if (ret == 0 && kPad)
854
                    ret = _HashUpdate(enmhashId, &hash, &pad, 1);
855
                if (ret == 0)
856
                    ret = _HashUpdate(enmhashId, &hash, k, kSz);
857
                if (ret == 0)
858
                    ret = _HashUpdate(enmhashId, &hash, h, hSz);
859
                if (ret == 0)
860
                    ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
861
                if (ret == 0)
862
                    ret = _HashFinal(enmhashId, &hash, lastBlock);
863
                if (ret == 0)
864
                    XMEMCPY(key + runningKeySz, lastBlock, remainder);
865
            }
866
        }
867
    }
868
869
    _HashFree(enmhashId, &hash);
870
871
    return ret;
872
}
873
874
#endif /* WOLFSSL_WOLFSSH */
875
876
#ifdef WC_SRTP_KDF
877
/* Calculate first block to encrypt.
878
 *
879
 * @param [in]  salt     Random value to XOR in.
880
 * @param [in]  saltSz   Size of random value in bytes.
881
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
882
 *                       kdr = 2^kdrIdx.
883
 * @param [in]  index    Index value to XOR in.
884
 * @param [in]  indexSz  Size of index value in bytes.
885
 * @param [out] block    First block to encrypt.
886
 */
887
static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
888
        const byte* index, byte indexSz, unsigned char* block)
889
{
890
    word32 i;
891
892
    /* XOR salt into zeroized buffer. */
893
    for (i = 0; i < WC_SRTP_MAX_SALT - saltSz; i++)
894
        block[i] = 0;
895
    XMEMCPY(block + WC_SRTP_MAX_SALT - saltSz, salt, saltSz);
896
    block[WC_SRTP_MAX_SALT] = 0;
897
    /* block[15] is counter. */
898
899
    /* When kdrIdx is -1, don't XOR in index. */
900
    if (kdrIdx >= 0) {
901
        /* Get the number of bits to shift index by. */
902
        word32 bits = kdrIdx & 0x7;
903
        /* Reduce index size by number of bytes to remove. */
904
        indexSz -= kdrIdx >> 3;
905
906
        if ((kdrIdx & 0x7) == 0) {
907
            /* Just XOR in as no bit shifting. */
908
            for (i = 0; i < indexSz; i++)
909
                block[i + WC_SRTP_MAX_SALT - indexSz] ^= index[i];
910
        }
911
        else {
912
            /* XOR in as bit shifted index. */
913
            block[WC_SRTP_MAX_SALT - indexSz] ^= index[0] >> bits;
914
            for (i = 1; i < indexSz; i++) {
915
                block[i + WC_SRTP_MAX_SALT - indexSz] ^=
916
                    (index[i-1] << (8 - bits)) |
917
                    (index[i+0] >>      bits );
918
            }
919
        }
920
    }
921
}
922
923
/* Derive a key given the first block.
924
 *
925
 * @param [in, out] block    First block to encrypt. Need label XORed in.
926
 * @param [in]      indexSz  Size of index in bytes to calculate where label is
927
 *                           XORed into.
928
 * @param [in]      label    Label byte that differs for each key.
929
 * @param [out]     key      Derived key.
930
 * @param [in]      keySz    Size of key to derive in bytes.
931
 * @param [in]      aes      AES object to encrypt with.
932
 * @return  0 on success.
933
 */
934
static int wc_srtp_kdf_derive_key(byte* block, byte indexSz, byte label,
935
        byte* key, word32 keySz, Aes* aes)
936
{
937
    int i;
938
    int ret = 0;
939
    /* Calculate the number of full blocks needed for derived key. */
940
    int blocks = keySz / AES_BLOCK_SIZE;
941
942
    /* XOR in label. */
943
    block[WC_SRTP_MAX_SALT - indexSz - 1] ^= label;
944
    for (i = 0; (ret == 0) && (i < blocks); i++) {
945
        /* Set counter. */
946
        block[15] = i;
947
        /* Encrypt block into key buffer. */
948
        ret = wc_AesEcbEncrypt(aes, key, block, AES_BLOCK_SIZE);
949
        /* Reposition for more derived key. */
950
        key += AES_BLOCK_SIZE;
951
        /* Reduce the count of key bytes required. */
952
        keySz -= AES_BLOCK_SIZE;
953
    }
954
    /* Do any partial blocks. */
955
    if ((ret == 0) && (keySz > 0)) {
956
        byte enc[AES_BLOCK_SIZE];
957
        /* Set counter. */
958
        block[15] = i;
959
        /* Encrypt block into temporary. */
960
        ret = wc_AesEcbEncrypt(aes, enc, block, AES_BLOCK_SIZE);
961
        if (ret == 0) {
962
            /* Copy into key required amount. */
963
            XMEMCPY(key, enc, keySz);
964
        }
965
    }
966
    /* XOR out label. */
967
    block[WC_SRTP_MAX_SALT - indexSz - 1] ^= label;
968
969
    return ret;
970
}
971
972
/* Derive keys using SRTP KDF algorithm.
973
 *
974
 * SP 800-135 (RFC 3711).
975
 *
976
 * @param [in]  key      Key to use with encryption.
977
 * @param [in]  keySz    Size of key in bytes.
978
 * @param [in]  salt     Random non-secret value.
979
 * @param [in]  saltSz   Size of random in bytes.
980
 * @param [in]  kdrIdx   Key derivation rate. kdr = 0 when -1, otherwise
981
 *                       kdr = 2^kdrIdx.
982
 * @param [in]  index    Index value to XOR in.
983
 * @param [out] key1     First key. Label value of 0x00.
984
 * @param [in]  key1Sz   Size of first key in bytes.
985
 * @param [out] key2     Second key. Label value of 0x01.
986
 * @param [in]  key2Sz   Size of second key in bytes.
987
 * @param [out] key3     Third key. Label value of 0x02.
988
 * @param [in]  key3Sz   Size of third key in bytes.
989
 * @return  BAD_FUNC_ARG when key or salt is NULL.
990
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
991
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
992
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
993
 * @return  MEMORY_E on dynamic memory allocation failure.
994
 * @return  0 on success.
995
 */
996
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
997
        int kdrIdx, const byte* index, byte* key1, word32 key1Sz, byte* key2,
998
        word32 key2Sz, byte* key3, word32 key3Sz)
999
{
1000
    int ret = 0;
1001
    byte block[AES_BLOCK_SIZE];
1002
#ifdef WOLFSSL_SMALL_STACK
1003
    Aes* aes = NULL;
1004
#else
1005
    Aes aes[1];
1006
#endif
1007
1008
    /* Validate parameters. */
1009
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1010
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) {
1011
        ret = BAD_FUNC_ARG;
1012
    }
1013
1014
#ifdef WOLFSSL_SMALL_STACK
1015
    if (ret == 0) {
1016
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1017
        if (aes == NULL) {
1018
            ret = MEMORY_E;
1019
        }
1020
    }
1021
    if (aes != NULL)
1022
#endif
1023
    {
1024
        XMEMSET(aes, 0, sizeof(Aes));
1025
    }
1026
1027
    /* Setup AES object. */
1028
    if (ret == 0)
1029
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1030
    if (ret == 0)
1031
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1032
1033
    /* Calculate first block that can be used in each derivation. */
1034
    if (ret == 0)
1035
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, 6, block);
1036
1037
    /* Calculate first key if required. */
1038
    if ((ret == 0) && (key1 != NULL)) {
1039
        ret = wc_srtp_kdf_derive_key(block, 6, 0x00, key1, key1Sz, aes);
1040
    }
1041
    /* Calculate second key if required. */
1042
    if ((ret == 0) && (key2 != NULL)) {
1043
        ret = wc_srtp_kdf_derive_key(block, 6, 0x01, key2, key2Sz, aes);
1044
    }
1045
    /* Calculate third key if required. */
1046
    if ((ret == 0) && (key3 != NULL)) {
1047
        ret = wc_srtp_kdf_derive_key(block, 6, 0x02, key3, key3Sz, aes);
1048
    }
1049
1050
    /* AES object memset so can always free. */
1051
    wc_AesFree(aes);
1052
#ifdef WOLFSSL_SMALL_STACK
1053
    XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
1054
#endif
1055
    return ret;
1056
}
1057
1058
/* Derive keys using SRTCP KDF algorithm.
1059
 *
1060
 * SP 800-135 (RFC 3711).
1061
 *
1062
 * @param [in]  key      Key to use with encryption.
1063
 * @param [in]  keySz    Size of key in bytes.
1064
 * @param [in]  salt     Random non-secret value.
1065
 * @param [in]  saltSz   Size of random in bytes.
1066
 * @param [in]  kdrIdx   Key derivation rate index. kdr = 0 when -1, otherwise
1067
 *                       kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1068
 * @param [in]  index    Index value to XOR in.
1069
 * @param [out] key1     First key. Label value of 0x03.
1070
 * @param [in]  key1Sz   Size of first key in bytes.
1071
 * @param [out] key2     Second key. Label value of 0x04.
1072
 * @param [in]  key2Sz   Size of second key in bytes.
1073
 * @param [out] key3     Third key. Label value of 0x05.
1074
 * @param [in]  key3Sz   Size of third key in bytes.
1075
 * @return  BAD_FUNC_ARG when key or salt is NULL.
1076
 * @return  BAD_FUNC_ARG when key length is not 16, 24 or 32.
1077
 * @return  BAD_FUNC_ARG when saltSz is larger than 14.
1078
 * @return  BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1079
 * @return  MEMORY_E on dynamic memory allocation failure.
1080
 * @return  0 on success.
1081
 */
1082
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
1083
        int kdrIdx, const byte* index, byte* key1, word32 key1Sz, byte* key2,
1084
        word32 key2Sz, byte* key3, word32 key3Sz)
1085
{
1086
    int ret = 0;
1087
    byte block[AES_BLOCK_SIZE];
1088
#ifdef WOLFSSL_SMALL_STACK
1089
    Aes* aes = NULL;
1090
#else
1091
    Aes aes[1];
1092
#endif
1093
1094
    /* Validate parameters. */
1095
    if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1096
            (saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24)) {
1097
        ret = BAD_FUNC_ARG;
1098
    }
1099
1100
#ifdef WOLFSSL_SMALL_STACK
1101
    if (ret == 0) {
1102
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1103
        if (aes == NULL) {
1104
            ret = MEMORY_E;
1105
        }
1106
    }
1107
    if (aes != NULL)
1108
#endif
1109
    {
1110
        XMEMSET(aes, 0, sizeof(Aes));
1111
    }
1112
1113
    /* Setup AES object. */
1114
    if (ret == 0)
1115
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1116
    if (ret == 0)
1117
        ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1118
1119
    /* Calculate first block that can be used in each derivation. */
1120
    if (ret == 0)
1121
        wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, 4, block);
1122
1123
    /* Calculate first key if required. */
1124
    if ((ret == 0) && (key1 != NULL)) {
1125
        ret = wc_srtp_kdf_derive_key(block, 4, 0x03, key1, key1Sz, aes);
1126
    }
1127
    /* Calculate second key if required. */
1128
    if ((ret == 0) && (key2 != NULL)) {
1129
        ret = wc_srtp_kdf_derive_key(block, 4, 0x04, key2, key2Sz, aes);
1130
    }
1131
    /* Calculate third key if required. */
1132
    if ((ret == 0) && (key3 != NULL)) {
1133
        ret = wc_srtp_kdf_derive_key(block, 4, 0x05, key3, key3Sz, aes);
1134
    }
1135
1136
    /* AES object memset so can always free. */
1137
    wc_AesFree(aes);
1138
#ifdef WOLFSSL_SMALL_STACK
1139
    XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
1140
#endif
1141
    return ret;
1142
}
1143
1144
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
1145
 *
1146
 * @param [in] kdr  Key derivation rate to convert.
1147
 * @return  Key derivation rate as an index.
1148
 */
1149
int wc_SRTP_KDF_kdr_to_idx(word32 kdr)
1150
{
1151
    int idx = -1;
1152
1153
    /* Keep shifting value down and incrementing index until top bit is gone. */
1154
    while (kdr != 0) {
1155
        kdr >>= 1;
1156
        idx++;
1157
    }
1158
1159
    /* Index of top bit set. */
1160
    return idx;
1161
}
1162
#endif /* WC_SRTP_KDF */
1163
1164
#endif /* NO_KDF */