Coverage Report

Created: 2026-02-11 06:19

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