Coverage Report

Created: 2026-02-14 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/providers/implementations/kdfs/srtpkdf.c
Line
Count
Source
1
/*
2
 * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <stdlib.h>
11
#include <stdarg.h>
12
#include <string.h>
13
#include <openssl/evp.h>
14
#include <openssl/kdf.h>
15
#include <openssl/bn.h>
16
#include <openssl/core_names.h>
17
#include <openssl/proverr.h>
18
#include "internal/cryptlib.h"
19
#include "internal/fips.h"
20
#include "internal/numbers.h"
21
#include "crypto/evp.h"
22
#include "prov/provider_ctx.h"
23
#include "prov/providercommon.h"
24
#include "prov/implementations.h"
25
#include "prov/provider_util.h"
26
#include "providers/implementations/kdfs/srtpkdf.inc"
27
28
2
#define KDF_SRTP_AUTH_KEY_LEN 20
29
2
#define KDF_SRTP_SALT_KEY_LEN 14
30
1
#define KDF_SRTCP_AUTH_KEY_LEN KDF_SRTP_AUTH_KEY_LEN
31
1
#define KDF_SRTCP_SALT_KEY_LEN KDF_SRTP_SALT_KEY_LEN
32
87
#define KDF_SRTP_SALT_LEN 14
33
#define KDF_SRTP_KDR_LEN 6
34
11
#define KDF_SRTP_IDX_LEN 6
35
3
#define KDF_SRTCP_IDX_LEN 4
36
56
#define KDF_SRTP_IV_LEN 16
37
12
#define KDF_SRTP_MAX_KDR 24
38
15
#define KDF_SRTP_MAX_LABEL 7
39
42
#define KDF_SRTP_MAX_SALT_LEN (KDF_SRTP_SALT_LEN + 2)
40
41
/* See RFC 3711, Section 4.3.3 */
42
static OSSL_FUNC_kdf_newctx_fn kdf_srtpkdf_new;
43
static OSSL_FUNC_kdf_dupctx_fn kdf_srtpkdf_dup;
44
static OSSL_FUNC_kdf_freectx_fn kdf_srtpkdf_free;
45
static OSSL_FUNC_kdf_reset_fn kdf_srtpkdf_reset;
46
static OSSL_FUNC_kdf_derive_fn kdf_srtpkdf_derive;
47
static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_srtpkdf_settable_ctx_params;
48
static OSSL_FUNC_kdf_set_ctx_params_fn kdf_srtpkdf_set_ctx_params;
49
static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_srtpkdf_gettable_ctx_params;
50
static OSSL_FUNC_kdf_get_ctx_params_fn kdf_srtpkdf_get_ctx_params;
51
52
static int SRTPKDF(OSSL_LIB_CTX *provctx, const EVP_CIPHER *cipher,
53
    const unsigned char *mkey, const unsigned char *msalt, const unsigned char *index,
54
    const uint32_t kdr, const uint32_t kdr_n,
55
    const uint32_t label, unsigned char *obuffer, const size_t keylen);
56
57
typedef struct {
58
    /* Warning: Any changes to this structure may require you to update kdf_srtpkdf_dup */
59
    void *provctx;
60
    PROV_CIPHER cipher;
61
    unsigned char *key;
62
    size_t key_len;
63
    unsigned char *salt;
64
    size_t salt_len;
65
    unsigned char *index;
66
    size_t index_len;
67
    uint32_t kdr;
68
    uint32_t kdr_n; /* 2 ** kdr_n = kdr */
69
    uint32_t label;
70
} KDF_SRTPKDF;
71
72
static void *kdf_srtpkdf_new(void *provctx)
73
27
{
74
27
    KDF_SRTPKDF *ctx;
75
76
27
    if (!ossl_prov_is_running())
77
0
        return NULL;
78
79
#ifdef FIPS_MODULE
80
    if (!ossl_deferred_self_test(PROV_LIBCTX_OF(provctx),
81
            ST_ID_KDF_SRTPKDF))
82
        return NULL;
83
#endif
84
85
27
    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL)
86
27
        ctx->provctx = provctx;
87
27
    return ctx;
88
27
}
89
90
static void *kdf_srtpkdf_dup(void *vsrc)
91
0
{
92
0
    const KDF_SRTPKDF *src = (const KDF_SRTPKDF *)vsrc;
93
0
    KDF_SRTPKDF *dest;
94
95
0
    dest = kdf_srtpkdf_new(src->provctx);
96
0
    if (dest != NULL) {
97
0
        if (!ossl_prov_memdup(src->key, src->key_len,
98
0
                &dest->key, &dest->key_len)
99
0
            || !ossl_prov_memdup(src->salt, src->salt_len,
100
0
                &dest->salt, &dest->salt_len)
101
0
            || !ossl_prov_memdup(src->index, src->index_len,
102
0
                &dest->index, &dest->index_len)
103
0
            || !ossl_prov_cipher_copy(&dest->cipher, &src->cipher))
104
0
            goto err;
105
0
        dest->kdr = src->kdr;
106
0
        dest->kdr_n = src->kdr_n;
107
0
        dest->label = src->label;
108
0
    }
109
0
    return dest;
110
111
0
err:
112
0
    kdf_srtpkdf_free(dest);
113
0
    return NULL;
114
0
}
115
116
static void kdf_srtpkdf_free(void *vctx)
117
27
{
118
27
    KDF_SRTPKDF *ctx = (KDF_SRTPKDF *)vctx;
119
120
27
    if (ctx != NULL) {
121
27
        kdf_srtpkdf_reset(ctx);
122
27
        OPENSSL_free(ctx);
123
27
    }
124
27
}
125
126
static void kdf_srtpkdf_reset(void *vctx)
127
27
{
128
27
    KDF_SRTPKDF *ctx = (KDF_SRTPKDF *)vctx;
129
27
    void *provctx = ctx->provctx;
130
131
27
    ossl_prov_cipher_reset(&ctx->cipher);
132
27
    OPENSSL_clear_free(ctx->key, ctx->key_len);
133
27
    OPENSSL_clear_free(ctx->index, ctx->index_len);
134
27
    OPENSSL_clear_free(ctx->salt, ctx->salt_len);
135
27
    memset(ctx, 0, sizeof(*ctx));
136
27
    ctx->provctx = provctx;
137
27
}
138
139
static int srtpkdf_set_membuf(unsigned char **dst, size_t *dst_len,
140
    const OSSL_PARAM *p)
141
51
{
142
51
    OPENSSL_clear_free(*dst, *dst_len);
143
51
    *dst = NULL;
144
51
    *dst_len = 0;
145
51
    return OSSL_PARAM_get_octet_string(p, (void **)dst, 0, dst_len);
146
51
}
147
148
static int is_power_of_two(uint32_t x, uint32_t *n)
149
13
{
150
    /* Check if we've been given an exact power of two */
151
13
    if (x == 0 || (x & (x - 1)) != 0) {
152
1
        *n = 0;
153
1
        return 0;
154
1
    }
155
    /* Count the number of trailing bits in the passed value */
156
12
#ifdef __GNUC__
157
12
    *n = __builtin_ctz(x);
158
#else
159
    {
160
        uint32_t count = 0;
161
        while ((x & 1) == 0) {
162
            count++;
163
            x >>= 1;
164
        }
165
        *n = count;
166
    }
167
#endif
168
12
    return 1;
169
13
}
170
171
static int kdf_srtpkdf_derive(void *vctx, unsigned char *key, size_t keylen,
172
    const OSSL_PARAM params[])
173
16
{
174
16
    KDF_SRTPKDF *ctx = (KDF_SRTPKDF *)vctx;
175
16
    const EVP_CIPHER *cipher;
176
16
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
177
178
16
    if (!ossl_prov_is_running() || !kdf_srtpkdf_set_ctx_params(ctx, params))
179
0
        return 0;
180
181
16
    cipher = ossl_prov_cipher_cipher(&ctx->cipher);
182
16
    if (cipher == NULL) {
183
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
184
0
        return 0;
185
0
    }
186
16
    if (ctx->key == NULL) {
187
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
188
0
        return 0;
189
0
    }
190
16
    if (ctx->salt == NULL) {
191
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT);
192
0
        return 0;
193
0
    }
194
16
    if (ctx->kdr > 0) {
195
13
        uint32_t n = 0;
196
13
        if (!is_power_of_two(ctx->kdr, &n)
197
12
            || n > KDF_SRTP_MAX_KDR) {
198
1
            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KDR);
199
1
            return 0;
200
1
        }
201
12
        ctx->kdr_n = n;
202
12
    }
203
15
    if (ctx->label > KDF_SRTP_MAX_LABEL) {
204
1
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_LABEL);
205
1
        return 0;
206
1
    }
207
208
14
    return SRTPKDF(libctx, cipher, ctx->key, ctx->salt, ctx->index,
209
14
        ctx->kdr, ctx->kdr_n, ctx->label, key, keylen);
210
15
}
211
212
static int kdf_srtpkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
213
43
{
214
43
    struct srtp_set_ctx_params_st p;
215
43
    KDF_SRTPKDF *ctx = vctx;
216
43
    OSSL_LIB_CTX *libctx;
217
43
    const EVP_CIPHER *cipher;
218
43
    int key_len;
219
220
43
    if (params == NULL)
221
16
        return 1;
222
223
27
    if (ctx == NULL || !srtp_set_ctx_params_decoder(params, &p))
224
0
        return 0;
225
226
27
    libctx = PROV_LIBCTX_OF(ctx->provctx);
227
228
27
    if ((p.cipher != NULL)
229
27
        && !ossl_prov_cipher_load(&ctx->cipher, p.cipher, p.propq, libctx))
230
5
        return 0;
231
232
22
    cipher = ossl_prov_cipher_cipher(&ctx->cipher);
233
22
    if (cipher == NULL)
234
0
        return 0;
235
236
22
    if (!EVP_CIPHER_is_a(cipher, "AES-128-CTR") && !EVP_CIPHER_is_a(cipher, "AES-192-CTR")
237
4
        && !EVP_CIPHER_is_a(cipher, "AES-256-CTR"))
238
4
        return 0;
239
240
18
    if (p.key != NULL) {
241
18
        key_len = EVP_CIPHER_get_key_length(cipher);
242
18
        if (!srtpkdf_set_membuf(&ctx->key, &ctx->key_len, p.key))
243
0
            return 0;
244
18
        if (ctx->key_len != (size_t)key_len)
245
1
            return 0;
246
18
    }
247
248
17
    if (p.salt != NULL) {
249
17
        if (!srtpkdf_set_membuf(&ctx->salt, &ctx->salt_len, p.salt))
250
0
            return 0;
251
17
        if (ctx->salt_len < KDF_SRTP_SALT_LEN)
252
1
            return 0;
253
17
    }
254
255
16
    if ((p.index != NULL)
256
16
        && !srtpkdf_set_membuf(&ctx->index, &ctx->index_len, p.index))
257
0
        return 0;
258
259
16
    if (p.kdr != NULL) {
260
16
        if (!OSSL_PARAM_get_uint32(p.kdr, &ctx->kdr))
261
0
            return 0;
262
16
    }
263
264
16
    if (p.label != NULL) {
265
16
        if (!OSSL_PARAM_get_uint32(p.label, &ctx->label))
266
0
            return 0;
267
16
    }
268
269
16
    return 1;
270
16
}
271
272
static const OSSL_PARAM *kdf_srtpkdf_settable_ctx_params(ossl_unused void *ctx,
273
    ossl_unused void *p_ctx)
274
27
{
275
27
    return srtp_set_ctx_params_list;
276
27
}
277
278
static int kdf_srtpkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
279
0
{
280
0
    struct srtp_get_ctx_params_st p;
281
0
    KDF_SRTPKDF *ctx = vctx;
282
283
0
    if (ctx == NULL || !srtp_get_ctx_params_decoder(params, &p))
284
0
        return 0;
285
286
0
    if (p.size != NULL) {
287
0
        size_t sz = EVP_CIPHER_key_length(ossl_prov_cipher_cipher(&ctx->cipher));
288
289
0
        if (!OSSL_PARAM_set_size_t(p.size, sz))
290
0
            return 0;
291
0
    }
292
0
    return 1;
293
0
}
294
295
static const OSSL_PARAM *kdf_srtpkdf_gettable_ctx_params(ossl_unused void *ctx,
296
    ossl_unused void *p_ctx)
297
0
{
298
0
    return srtp_get_ctx_params_list;
299
0
}
300
301
const OSSL_DISPATCH ossl_kdf_srtpkdf_functions[] = {
302
    { OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_srtpkdf_new },
303
    { OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_srtpkdf_dup },
304
    { OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_srtpkdf_free },
305
    { OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_srtpkdf_reset },
306
    { OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_srtpkdf_derive },
307
    { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
308
        (void (*)(void))kdf_srtpkdf_settable_ctx_params },
309
    { OSSL_FUNC_KDF_SET_CTX_PARAMS,
310
        (void (*)(void))kdf_srtpkdf_set_ctx_params },
311
    { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
312
        (void (*)(void))kdf_srtpkdf_gettable_ctx_params },
313
    { OSSL_FUNC_KDF_GET_CTX_PARAMS,
314
        (void (*)(void))kdf_srtpkdf_get_ctx_params },
315
    { 0, NULL }
316
};
317
318
/*
319
 * SRTPKDF - In compliance with SP800-135 and RFC3711, calculate
320
 *           various keys defined by label using a master key,
321
 *           master salt, kdr(if non-zero) and index.
322
 *
323
 * Denote the cryptographic key (encryption key, cipher salt or
324
 * authentication key(HMAC key), etc) to be derived as K. The
325
 * length of K is denoted by L. Below is a description of the KDF.
326
 *
327
 * master_salt: a random non-salt value.
328
 * kdr: the key derivation rate. kdr is a number from the set
329
 *   factor of 2.
330
 * index: a 48-bit value in RTP or a 32-bit value in RTCP.
331
 *   See Sections 3.2.1 and 4.3.2 of RFC 3711 for details.
332
 * A function, DIV, is defined as followed:
333
 *   a and x are non-negative integers.
334
 *   a DIV x =  a | x (a DIV x) is represented as a bit string whose
335
 *   length (in bits) is the same as a.
336
 * label: an 8-bit value represented by two hexadecimal numbers from
337
 *   the set of {0x00,0x01, 0x02, 0x03, 0x04, 0x05}.
338
 *   https://www.ietf.org/archive/id/draft-ietf-avtcore-srtp-encrypted-header-ext-01.html
339
 *   The values 06 and 07 are used.
340
 * key_id = label || (index DIV kdr)
341
 *
342
 * Input:
343
 *   cipher - AES cipher
344
 *   mkey - pointer to master key
345
 *   msalt - pointer to master salt
346
 *   idx - pointer to index
347
 *   kdr - key derivation rate
348
 *   kdr_n - power of kdr (2**kdr_n = kdr)
349
 *   label - 8-bit label
350
 *   obuffer - buffer for output
351
 *   keylen - length of output buffer
352
 * Output:
353
 *   obuffer - filled with derived key
354
 *   return - 1 on pass, 0 fail
355
 */
356
int SRTPKDF(OSSL_LIB_CTX *provctx, const EVP_CIPHER *cipher,
357
    const unsigned char *mkey, const unsigned char *msalt, const unsigned char *index,
358
    const uint32_t kdr, const uint32_t kdr_n,
359
    const uint32_t label, unsigned char *obuffer, const size_t keylen)
360
14
{
361
14
    EVP_CIPHER_CTX *ctx = NULL;
362
14
    int outl, i, index_len = 0, o_len = 0, salt_len = 0;
363
14
    unsigned char buf[EVP_MAX_KEY_LENGTH];
364
14
    unsigned char iv[KDF_SRTP_IV_LEN];
365
14
    unsigned char local_salt[KDF_SRTP_MAX_SALT_LEN];
366
14
    unsigned char master_salt[KDF_SRTP_MAX_SALT_LEN];
367
14
    BIGNUM *bn_index = NULL, *bn_salt = NULL;
368
14
    int ret, iv_len = KDF_SRTP_IV_LEN, rv = 0;
369
370
14
    salt_len = KDF_SRTP_SALT_LEN;
371
372
    /* get label-specific lengths */
373
14
    switch (label) {
374
5
    case 0:
375
5
        index_len = KDF_SRTP_IDX_LEN;
376
5
        o_len = EVP_CIPHER_key_length(cipher);
377
5
        break;
378
1
    case 1:
379
1
        index_len = KDF_SRTP_IDX_LEN;
380
1
        o_len = KDF_SRTP_AUTH_KEY_LEN;
381
1
        break;
382
1
    case 2:
383
1
        index_len = KDF_SRTP_IDX_LEN;
384
1
        o_len = KDF_SRTP_SALT_KEY_LEN;
385
1
        break;
386
1
    case 3:
387
1
        index_len = KDF_SRTCP_IDX_LEN;
388
1
        o_len = EVP_CIPHER_key_length(cipher);
389
1
        break;
390
1
    case 4:
391
1
        index_len = KDF_SRTCP_IDX_LEN;
392
1
        o_len = KDF_SRTCP_AUTH_KEY_LEN;
393
1
        break;
394
1
    case 5:
395
1
        index_len = KDF_SRTCP_IDX_LEN;
396
1
        o_len = KDF_SRTCP_SALT_KEY_LEN;
397
1
        break;
398
4
    case 6:
399
4
        index_len = KDF_SRTP_IDX_LEN;
400
4
        o_len = EVP_CIPHER_key_length(cipher);
401
4
        break;
402
0
    case 7:
403
0
        index_len = KDF_SRTP_IDX_LEN;
404
0
        o_len = KDF_SRTP_SALT_KEY_LEN;
405
0
        break;
406
0
    default:
407
0
        return rv;
408
14
    }
409
410
14
    if ((obuffer == NULL) || (keylen > INT_MAX) || (o_len > (int)keylen))
411
0
        return rv;
412
413
    /* set up a couple of work areas for the final logic on the salt */
414
14
    memset(iv, 0, KDF_SRTP_IV_LEN);
415
14
    memset(master_salt, 0, KDF_SRTP_MAX_SALT_LEN);
416
14
    memcpy(master_salt, msalt, salt_len);
417
418
    /* gather some bignums for some math */
419
14
    bn_index = BN_new();
420
14
    bn_salt = BN_new();
421
14
    if ((bn_index == NULL) || (bn_salt == NULL)) {
422
0
        BN_free(bn_index);
423
0
        BN_free(bn_salt);
424
0
        return rv;
425
0
    }
426
427
    /* if index is NULL or kdr=0, then index and kdr are not in play */
428
14
    if ((index != NULL) && (kdr > 0)) {
429
12
        if (!BN_bin2bn(index, index_len, bn_index))
430
0
            goto err;
431
432
12
        ret = BN_rshift(bn_salt, bn_index, kdr_n);
433
12
        if (!ret)
434
0
            goto err;
435
12
        iv_len = BN_bn2bin(bn_salt, iv);
436
65
        for (i = 1; i <= iv_len; i++)
437
53
            master_salt[salt_len - i] ^= iv[iv_len - i];
438
12
    }
439
440
    /* take the munged up salt from above and add the label */
441
14
    memset(local_salt, 0, KDF_SRTP_MAX_SALT_LEN);
442
14
    memcpy(local_salt, master_salt, salt_len);
443
14
    local_salt[((KDF_SRTP_SALT_LEN - 1) - index_len)] ^= label;
444
445
    /* perform the AES encryption on the master key and derived salt */
446
14
    memset(buf, 0, o_len);
447
14
    if (!(ctx = EVP_CIPHER_CTX_new())
448
14
        || (EVP_EncryptInit_ex(ctx, cipher, NULL, mkey, local_salt) <= 0)
449
14
        || (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0)
450
14
        || (EVP_EncryptUpdate(ctx, (unsigned char *)obuffer, &outl, buf, o_len) <= 0)
451
14
        || (EVP_EncryptFinal_ex(ctx, (unsigned char *)obuffer, &outl) <= 0))
452
0
        goto err;
453
454
14
    rv = 1;
455
14
err:
456
14
    EVP_CIPHER_CTX_free(ctx);
457
14
    OPENSSL_cleanse(iv, KDF_SRTP_IV_LEN);
458
14
    OPENSSL_cleanse(local_salt, KDF_SRTP_MAX_SALT_LEN);
459
14
    OPENSSL_cleanse(master_salt, KDF_SRTP_IV_LEN);
460
14
    BN_clear_free(bn_index);
461
14
    BN_clear_free(bn_salt);
462
14
    return rv;
463
14
}