Skip to content

Commit d8ea55e

Browse files
committed
Add initial srtp_policy api proposal
Includes a minima implementation and unit tests.
1 parent 959a72a commit d8ea55e

File tree

6 files changed

+457
-1
lines changed

6 files changed

+457
-1
lines changed

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ endif()
143143

144144
set(SOURCES_C
145145
srtp/srtp.c
146+
srtp/srtp_policy.c
146147
)
147148

148149
set(CIPHERS_SOURCES_C
@@ -471,6 +472,17 @@ if(LIBSRTP_TEST_APPS)
471472
endif()
472473
target_link_libraries(test_srtp srtp3)
473474
add_test(test_srtp test_srtp)
475+
476+
add_executable(test_srtp_policy test/test_srtp_policy.c test/util.c)
477+
target_set_warnings(
478+
TARGET
479+
test_srtp_policy
480+
ENABLE
481+
${ENABLE_WARNINGS}
482+
AS_ERRORS
483+
${ENABLE_WARNINGS_AS_ERRORS})
484+
target_link_libraries(test_srtp_policy srtp3)
485+
add_test(test_srtp_policy test_srtp_policy)
474486
endif()
475487

476488
find_program(BASH_PROGRAM bash)

include/srtp.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,7 @@ size_t srtp_profile_get_master_salt_length(srtp_profile_t profile);
10901090
* @warning There must be at least bytes_in_salt + bytes_in_key bytes
10911091
* available at the location pointed to by key.
10921092
*
1093+
*
10931094
*/
10941095
void srtp_append_salt_to_key(uint8_t *key,
10951096
size_t bytes_in_key,
@@ -1492,6 +1493,44 @@ srtp_err_status_t srtp_stream_get_roc(srtp_t session,
14921493
#define SRTCP_E_BYTE_BIT 0x80
14931494
#define SRTCP_INDEX_MASK 0x7fffffff
14941495

1496+
/* WIP new config policy API */
1497+
1498+
typedef struct srtp_policy2_ctx_t_ srtp_policy2_ctx_t;
1499+
typedef srtp_policy2_ctx_t *srtp_policy2_t;
1500+
1501+
srtp_err_status_t srtp_policy2_create(srtp_policy2_t *policy);
1502+
srtp_err_status_t srtp_policy2_set_ssrc(srtp_policy2_t policy,
1503+
srtp_ssrc_t ssrc);
1504+
srtp_err_status_t srtp_policy2_set_profile(srtp_policy2_t policy,
1505+
srtp_profile_t profile);
1506+
srtp_err_status_t srtp_policy2_set_key(srtp_policy2_t policy,
1507+
const uint8_t *key,
1508+
size_t key_len,
1509+
const uint8_t *salt,
1510+
size_t salt_len);
1511+
srtp_err_status_t srtp_policy2_use_mki(srtp_policy2_t policy, size_t mki_len);
1512+
srtp_err_status_t srtp_policy2_add_key(srtp_policy2_t policy,
1513+
const uint8_t *key,
1514+
size_t key_len,
1515+
const uint8_t *salt,
1516+
size_t salt_len,
1517+
const uint8_t *mki,
1518+
size_t mki_len);
1519+
srtp_err_status_t srtp_policy2_set_window_size(srtp_policy2_t policy,
1520+
size_t window_size);
1521+
srtp_err_status_t srtp_policy2_set_allow_repeat_tx(srtp_policy2_t policy,
1522+
bool allow);
1523+
srtp_err_status_t srtp_policy2_use_cryptex(srtp_policy2_t policy);
1524+
srtp_err_status_t srtp_policy2_set_enc_hdr_xtnd_ids(srtp_policy2_t policy,
1525+
const uint8_t *hdr_xtnd_ids,
1526+
size_t num_xtnd_ids);
1527+
srtp_err_status_t srtp_policy2_set_roc(srtp_policy2_t policy, uint32_t roc);
1528+
void srtp_policy2_destroy(srtp_policy2_t policy);
1529+
1530+
srtp_err_status_t srtp_policy2_validate(srtp_policy2_t policy);
1531+
1532+
srtp_err_status_t srtp_create2(srtp_t *session, const srtp_policy2_t policy);
1533+
14951534
#ifdef __cplusplus
14961535
}
14971536
#endif

include/srtp_priv.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ typedef struct srtp_stream_ctx_t_ srtp_stream_ctx_t;
6767
typedef srtp_stream_ctx_t *srtp_stream_t;
6868
typedef struct srtp_stream_list_ctx_t_ *srtp_stream_list_t;
6969

70+
typedef struct srtp_master_key2_t {
71+
uint8_t key[SRTP_MAX_KEY_LEN];
72+
size_t key_len;
73+
uint8_t mki_id[SRTP_MAX_MKI_LEN];
74+
size_t mki_id_len;
75+
} srtp_master2_key_t;
76+
#define SRTP_MAX_NUM_HDR_XTND_IDS 16
77+
typedef struct srtp_policy2_ctx_t_ {
78+
srtp_profile_t profile;
79+
srtp_policy_t legacy;
80+
srtp_master2_key_t master_key_store[SRTP_MAX_NUM_MASTER_KEYS];
81+
srtp_master_key_t master_keys[SRTP_MAX_NUM_MASTER_KEYS];
82+
srtp_master_key_t *keys[SRTP_MAX_NUM_MASTER_KEYS];
83+
uint8_t enc_hdr_xtnd_ids[SRTP_MAX_NUM_HDR_XTND_IDS];
84+
} srtp_policy2_ctx_t_;
85+
86+
srtp_err_status_t srtp_valid_policy(const srtp_policy_t *policy);
87+
7088
/*
7189
* the following declarations are libSRTP internal functions
7290
*/

srtp/srtp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ static srtp_err_status_t srtp_remove_and_dealloc_streams(
554554
return data.status;
555555
}
556556

557-
static srtp_err_status_t srtp_valid_policy(const srtp_policy_t *policy)
557+
srtp_err_status_t srtp_valid_policy(const srtp_policy_t *policy)
558558
{
559559
if (policy == NULL) {
560560
return srtp_err_status_bad_param;

srtp/srtp_policy.c

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/*
2+
* srtp_policy.c
3+
*
4+
* extensible policy API for libSRTP
5+
*/
6+
/*
7+
*
8+
* Copyright (c) 2026
9+
* All rights reserved.
10+
*
11+
* Redistribution and use in source and binary forms, with or without
12+
* modification, are permitted provided that the following conditions
13+
* are met:
14+
*
15+
* Redistributions of source code must retain the above copyright
16+
* notice, this list of conditions and the following disclaimer.
17+
*
18+
* Redistributions in binary form must reproduce the above
19+
* copyright notice, this list of conditions and the following
20+
* disclaimer in the documentation and/or other materials provided
21+
* with the distribution.
22+
*
23+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27+
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34+
* OF THE POSSIBILITY OF SUCH DAMAGE.
35+
*
36+
*/
37+
38+
#include "srtp_priv.h"
39+
40+
#include <string.h>
41+
42+
#include "alloc.h"
43+
44+
srtp_err_status_t srtp_policy2_create(srtp_policy2_t *policy)
45+
{
46+
srtp_policy2_t p;
47+
48+
if (policy == NULL) {
49+
return srtp_err_status_bad_param;
50+
}
51+
52+
p = (srtp_policy2_t)srtp_crypto_alloc(sizeof(*p));
53+
if (p == NULL) {
54+
*policy = NULL;
55+
return srtp_err_status_alloc_fail;
56+
}
57+
58+
memset(p, 0, sizeof(*p));
59+
60+
// set up key store
61+
for (size_t i = 0; i < SRTP_MAX_NUM_MASTER_KEYS; i++) {
62+
p->master_keys[i].key = p->master_key_store[i].key;
63+
p->master_keys[i].mki_id = p->master_key_store[i].mki_id;
64+
p->keys[i] = &p->master_keys[i];
65+
}
66+
p->legacy.keys = p->keys;
67+
68+
// setup hdr xtnd id's
69+
p->legacy.enc_xtn_hdr = p->enc_hdr_xtnd_ids;
70+
71+
*policy = p;
72+
73+
return srtp_err_status_ok;
74+
}
75+
76+
void srtp_policy2_destroy(srtp_policy2_t policy)
77+
{
78+
if (policy == NULL) {
79+
return;
80+
}
81+
82+
octet_string_set_to_zero(policy->keys, sizeof(policy->keys));
83+
srtp_crypto_free(policy);
84+
}
85+
86+
srtp_err_status_t srtp_policy2_validate(srtp_policy2_t policy)
87+
{
88+
if (policy == NULL) {
89+
return srtp_err_status_bad_param;
90+
}
91+
92+
if (policy->legacy.ssrc.type != ssrc_any_inbound &&
93+
policy->legacy.ssrc.type != ssrc_any_outbound &&
94+
policy->legacy.ssrc.type != ssrc_specific) {
95+
return srtp_err_status_bad_param;
96+
}
97+
98+
if (policy->profile == srtp_profile_reserved) {
99+
return srtp_err_status_bad_param;
100+
}
101+
102+
return srtp_valid_policy(&policy->legacy);
103+
}
104+
105+
srtp_err_status_t srtp_policy2_set_ssrc(srtp_policy2_t policy, srtp_ssrc_t ssrc)
106+
{
107+
if (policy == NULL) {
108+
return srtp_err_status_bad_param;
109+
}
110+
111+
if (ssrc.type != ssrc_any_inbound && ssrc.type != ssrc_any_outbound &&
112+
ssrc.type != ssrc_specific) {
113+
return srtp_err_status_bad_param;
114+
}
115+
116+
policy->legacy.ssrc = ssrc;
117+
118+
return srtp_err_status_ok;
119+
}
120+
121+
srtp_err_status_t srtp_policy2_set_profile(srtp_policy2_t policy,
122+
srtp_profile_t profile)
123+
{
124+
if (policy == NULL) {
125+
return srtp_err_status_bad_param;
126+
}
127+
128+
srtp_err_status_t status;
129+
status = srtp_crypto_policy_set_from_profile_for_rtp(&policy->legacy.rtp,
130+
profile);
131+
if (status != srtp_err_status_ok) {
132+
return status;
133+
}
134+
status = srtp_crypto_policy_set_from_profile_for_rtcp(&policy->legacy.rtcp,
135+
profile);
136+
if (status != srtp_err_status_ok) {
137+
return status;
138+
}
139+
140+
policy->profile = profile;
141+
142+
return srtp_err_status_ok;
143+
}
144+
145+
static srtp_err_status_t policy2_add_key(srtp_policy2_t policy,
146+
const uint8_t *key,
147+
size_t key_len,
148+
const uint8_t *salt,
149+
size_t salt_len,
150+
const uint8_t *mki,
151+
size_t mki_len)
152+
{
153+
if (policy->legacy.num_master_keys >= SRTP_MAX_NUM_MASTER_KEYS) {
154+
return srtp_err_status_bad_param;
155+
}
156+
157+
if (key_len + salt_len > SRTP_MAX_KEY_LEN) {
158+
return srtp_err_status_bad_param;
159+
}
160+
161+
size_t key_index = policy->legacy.num_master_keys;
162+
memcpy(policy->master_key_store[key_index].key, key, key_len);
163+
memcpy(policy->master_key_store[key_index].key + key_len, salt, salt_len);
164+
policy->master_key_store[key_index].key_len = key_len + salt_len;
165+
memcpy(policy->master_key_store[key_index].mki_id, mki, mki_len);
166+
policy->master_key_store[key_index].mki_id_len = mki_len;
167+
168+
policy->legacy.num_master_keys++;
169+
170+
return srtp_err_status_ok;
171+
}
172+
173+
srtp_err_status_t srtp_policy2_set_key(srtp_policy2_t policy,
174+
const uint8_t *key,
175+
size_t key_len,
176+
const uint8_t *salt,
177+
size_t salt_len)
178+
{
179+
if (policy == NULL) {
180+
return srtp_err_status_bad_param;
181+
}
182+
183+
if (policy->legacy.num_master_keys != 0) {
184+
return srtp_err_status_bad_param;
185+
}
186+
187+
if (key_len + salt_len > SRTP_MAX_KEY_LEN) {
188+
return srtp_err_status_bad_param;
189+
}
190+
191+
policy->legacy.use_mki = false;
192+
policy->legacy.mki_size = 0;
193+
194+
return policy2_add_key(policy, key, key_len, salt, salt_len, NULL, 0);
195+
}
196+
197+
srtp_err_status_t srtp_policy2_use_mki(srtp_policy2_t policy, size_t mki_len)
198+
{
199+
if (policy == NULL) {
200+
return srtp_err_status_bad_param;
201+
}
202+
203+
if (mki_len > SRTP_MAX_MKI_LEN) {
204+
return srtp_err_status_bad_param;
205+
}
206+
207+
policy->legacy.use_mki = true;
208+
policy->legacy.mki_size = mki_len;
209+
210+
return srtp_err_status_ok;
211+
}
212+
213+
srtp_err_status_t srtp_policy2_add_key(srtp_policy2_t policy,
214+
const uint8_t *key,
215+
size_t key_len,
216+
const uint8_t *salt,
217+
size_t salt_len,
218+
const uint8_t *mki,
219+
size_t mki_len)
220+
{
221+
if (policy == NULL) {
222+
return srtp_err_status_bad_param;
223+
}
224+
225+
if (!policy->legacy.use_mki) {
226+
return srtp_err_status_bad_param;
227+
}
228+
229+
return policy2_add_key(policy, key, key_len, salt, salt_len, mki, mki_len);
230+
}
231+
232+
srtp_err_status_t srtp_create2(srtp_t *session, const srtp_policy2_t policy)
233+
{
234+
return srtp_create(session, policy ? &policy->legacy : NULL);
235+
}

0 commit comments

Comments
 (0)