Skip to content

Commit 659a245

Browse files
committed
SRTP/SRTCP KDF: add APIs that derives one key from a label
Added more generic APIs that derive a single key with a label. Added defines for label values and index lengths.
1 parent a66137d commit 659a245

File tree

4 files changed

+368
-22
lines changed

4 files changed

+368
-22
lines changed

doc/dox_comments/header_files/kdf.h

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
\endcode
4545
4646
\sa wc_SRTCP_KDF
47+
\sa wc_SRTP_KDF_label
48+
\sa wc_SRTCP_KDF_label
4749
\sa wc_SRTP_KDF_kdr_to_idx
4850
*/
4951
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
@@ -95,12 +97,107 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
9597
\endcode
9698
9799
\sa wc_SRTP_KDF
100+
\sa wc_SRTP_KDF_label
101+
\sa wc_SRTCP_KDF_label
98102
\sa wc_SRTP_KDF_kdr_to_idx
99103
*/
100104
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
101105
int kdrIdx, const byte* index, byte* key1, word32 key1Sz, byte* key2,
102106
word32 key2Sz, byte* key3, word32 key3Sz);
107+
/*!
108+
\ingroup SrtpKdf
109+
110+
\brief This function derives a key with label using SRTP KDF algorithm.
111+
112+
\return 0 Returned upon successful key derviation.
113+
\return BAD_FUNC_ARG Returned when key, salt or outKey is NULL
114+
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
115+
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
116+
\return BAD_FUNC_ARG Returned when kdrIdx is less than -1 or larger than 24.
117+
\return MEMORY_E on dynamic memory allocation failure.
118+
119+
\param [in] key Key to use with encryption.
120+
\param [in] keySz Size of key in bytes.
121+
\param [in] salt Random non-secret value.
122+
\param [in] saltSz Size of random in bytes.
123+
\param [in] kdrIdx Key derivation rate. kdr = 0 when -1, otherwise kdr = 2^kdrIdx.
124+
\param [in] index Index value to XOR in.
125+
\param [in] label Label to use when deriving key.
126+
\param [out] outKey Derived key.
127+
\param [in] outKeySz Size of derived key in bytes.
128+
129+
130+
_Example_
131+
\code
132+
unsigned char key[16] = { ... };
133+
unsigned char salt[14] = { ... };
134+
unsigned char index[6] = { ... };
135+
unsigned char keyE[16];
136+
int kdrIdx = 0; // Use all of index
137+
int ret;
138+
139+
ret = wc_SRTP_KDF_label(key, sizeof(key), salt, sizeof(salt), kdrIdx, index,
140+
WC_SRTP_LABEL_ENCRYPTION, keyE, sizeof(keyE));
141+
if (ret != 0) {
142+
WOLFSSL_MSG("wc_SRTP_KDF failed");
143+
}
144+
\endcode
103145
146+
\sa wc_SRTP_KDF
147+
\sa wc_SRTCP_KDF
148+
\sa wc_SRTCP_KDF_label
149+
\sa wc_SRTP_KDF_kdr_to_idx
150+
*/
151+
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
152+
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
153+
word32 outKeySz);
154+
/*!
155+
\ingroup SrtpKdf
156+
157+
\brief This function derives key with label using SRTCP KDF algorithm.
158+
159+
\return 0 Returned upon successful key derviation.
160+
\return BAD_FUNC_ARG Returned when key, salt or outKey is NULL
161+
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
162+
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
163+
\return BAD_FUNC_ARG Returned when kdrIdx is less than -1 or larger than 24.
164+
\return MEMORY_E on dynamic memory allocation failure.
165+
166+
\param [in] key Key to use with encryption.
167+
\param [in] keySz Size of key in bytes.
168+
\param [in] salt Random non-secret value.
169+
\param [in] saltSz Size of random in bytes.
170+
\param [in] kdrIdx Key derivation rate. kdr = 0 when -1, otherwise kdr = 2^kdrIdx.
171+
\param [in] index Index value to XOR in.
172+
\param [in] label Label to use when deriving key.
173+
\param [out] outKey Derived key.
174+
\param [in] outKeySz Size of derived key in bytes.
175+
176+
177+
_Example_
178+
\code
179+
unsigned char key[16] = { ... };
180+
unsigned char salt[14] = { ... };
181+
unsigned char index[4] = { ... };
182+
unsigned char keyE[16];
183+
int kdrIdx = 0; // Use all of index
184+
int ret;
185+
186+
ret = wc_SRTCP_KDF_label(key, sizeof(key), salt, sizeof(salt), kdrIdx,
187+
index, WC_SRTCP_LABEL_ENCRYPTION, keyE, sizeof(keyE));
188+
if (ret != 0) {
189+
WOLFSSL_MSG("wc_SRTP_KDF failed");
190+
}
191+
\endcode
192+
193+
\sa wc_SRTP_KDF
194+
\sa wc_SRTCP_KDF
195+
\sa wc_SRTP_KDF_label
196+
\sa wc_SRTP_KDF_kdr_to_idx
197+
*/
198+
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
199+
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
200+
word32 outKeySz);
104201
/*!
105202
\ingroup SrtpKdf
106203
@@ -121,6 +218,8 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
121218
122219
\sa wc_SRTP_KDF
123220
\sa wc_SRTCP_KDF
221+
\sa wc_SRTP_KDF_label
222+
\sa wc_SRTCP_KDF_label
124223
*/
125224
int wc_SRTP_KDF_kdr_to_idx(word32 kdr);
126225

wolfcrypt/src/kdf.c

Lines changed: 194 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -890,8 +890,9 @@ static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
890890
word32 i;
891891

892892
/* XOR salt into zeroized buffer. */
893-
for (i = 0; i < WC_SRTP_MAX_SALT - saltSz; i++)
893+
for (i = 0; i < WC_SRTP_MAX_SALT - saltSz; i++) {
894894
block[i] = 0;
895+
}
895896
XMEMCPY(block + WC_SRTP_MAX_SALT - saltSz, salt, saltSz);
896897
block[WC_SRTP_MAX_SALT] = 0;
897898
/* block[15] is counter. */
@@ -905,8 +906,9 @@ static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
905906

906907
if ((kdrIdx & 0x7) == 0) {
907908
/* Just XOR in as no bit shifting. */
908-
for (i = 0; i < indexSz; i++)
909+
for (i = 0; i < indexSz; i++) {
909910
block[i + WC_SRTP_MAX_SALT - indexSz] ^= index[i];
911+
}
910912
}
911913
else {
912914
/* XOR in as bit shifted index. */
@@ -1025,26 +1027,33 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
10251027
}
10261028

10271029
/* Setup AES object. */
1028-
if (ret == 0)
1030+
if (ret == 0) {
10291031
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1030-
if (ret == 0)
1032+
}
1033+
if (ret == 0) {
10311034
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1035+
}
10321036

10331037
/* 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);
1038+
if (ret == 0) {
1039+
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTP_INDEX_LEN,
1040+
block);
1041+
}
10361042

10371043
/* Calculate first key if required. */
10381044
if ((ret == 0) && (key1 != NULL)) {
1039-
ret = wc_srtp_kdf_derive_key(block, 6, 0x00, key1, key1Sz, aes);
1045+
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1046+
WC_SRTP_LABEL_ENCRYPTION, key1, key1Sz, aes);
10401047
}
10411048
/* Calculate second key if required. */
10421049
if ((ret == 0) && (key2 != NULL)) {
1043-
ret = wc_srtp_kdf_derive_key(block, 6, 0x01, key2, key2Sz, aes);
1050+
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1051+
WC_SRTP_LABEL_MSG_AUTH, key2, key2Sz, aes);
10441052
}
10451053
/* Calculate third key if required. */
10461054
if ((ret == 0) && (key3 != NULL)) {
1047-
ret = wc_srtp_kdf_derive_key(block, 6, 0x02, key3, key3Sz, aes);
1055+
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
1056+
WC_SRTP_LABEL_SALT, key3, key3Sz, aes);
10481057
}
10491058

10501059
/* AES object memset so can always free. */
@@ -1111,26 +1120,113 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
11111120
}
11121121

11131122
/* Setup AES object. */
1114-
if (ret == 0)
1123+
if (ret == 0) {
11151124
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1116-
if (ret == 0)
1125+
}
1126+
if (ret == 0) {
11171127
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1128+
}
11181129

11191130
/* 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);
1131+
if (ret == 0) {
1132+
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTCP_INDEX_LEN,
1133+
block);
1134+
}
11221135

11231136
/* Calculate first key if required. */
11241137
if ((ret == 0) && (key1 != NULL)) {
1125-
ret = wc_srtp_kdf_derive_key(block, 4, 0x03, key1, key1Sz, aes);
1138+
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN,
1139+
WC_SRTCP_LABEL_ENCRYPTION, key1, key1Sz, aes);
11261140
}
11271141
/* Calculate second key if required. */
11281142
if ((ret == 0) && (key2 != NULL)) {
1129-
ret = wc_srtp_kdf_derive_key(block, 4, 0x04, key2, key2Sz, aes);
1143+
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN,
1144+
WC_SRTCP_LABEL_MSG_AUTH, key2, key2Sz, aes);
11301145
}
11311146
/* Calculate third key if required. */
11321147
if ((ret == 0) && (key3 != NULL)) {
1133-
ret = wc_srtp_kdf_derive_key(block, 4, 0x05, key3, key3Sz, aes);
1148+
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN,
1149+
WC_SRTCP_LABEL_SALT, key3, key3Sz, aes);
1150+
}
1151+
1152+
/* AES object memset so can always free. */
1153+
wc_AesFree(aes);
1154+
#ifdef WOLFSSL_SMALL_STACK
1155+
XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
1156+
#endif
1157+
return ret;
1158+
}
1159+
1160+
/* Derive key with label using SRTP KDF algorithm.
1161+
*
1162+
* SP 800-135 (RFC 3711).
1163+
*
1164+
* @param [in] key Key to use with encryption.
1165+
* @param [in] keySz Size of key in bytes.
1166+
* @param [in] salt Random non-secret value.
1167+
* @param [in] saltSz Size of random in bytes.
1168+
* @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise
1169+
* kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1170+
* @param [in] index Index value to XOR in.
1171+
* @param [in] label Label to use when deriving key.
1172+
* @param [out] outKey Derived key.
1173+
* @param [in] outKeySz Size of derived key in bytes.
1174+
* @return BAD_FUNC_ARG when key, salt or outKey is NULL.
1175+
* @return BAD_FUNC_ARG when key length is not 16, 24 or 32.
1176+
* @return BAD_FUNC_ARG when saltSz is larger than 14.
1177+
* @return BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1178+
* @return MEMORY_E on dynamic memory allocation failure.
1179+
* @return 0 on success.
1180+
*/
1181+
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1182+
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
1183+
word32 outKeySz)
1184+
{
1185+
int ret = 0;
1186+
byte block[AES_BLOCK_SIZE];
1187+
#ifdef WOLFSSL_SMALL_STACK
1188+
Aes* aes = NULL;
1189+
#else
1190+
Aes aes[1];
1191+
#endif
1192+
1193+
/* Validate parameters. */
1194+
if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1195+
(saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1196+
(outKey == NULL)) {
1197+
ret = BAD_FUNC_ARG;
1198+
}
1199+
1200+
#ifdef WOLFSSL_SMALL_STACK
1201+
if (ret == 0) {
1202+
aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1203+
if (aes == NULL) {
1204+
ret = MEMORY_E;
1205+
}
1206+
}
1207+
if (aes != NULL)
1208+
#endif
1209+
{
1210+
XMEMSET(aes, 0, sizeof(Aes));
1211+
}
1212+
1213+
/* Setup AES object. */
1214+
if (ret == 0) {
1215+
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1216+
}
1217+
if (ret == 0) {
1218+
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1219+
}
1220+
1221+
/* Calculate first block that can be used in each derivation. */
1222+
if (ret == 0) {
1223+
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTP_INDEX_LEN,
1224+
block);
1225+
}
1226+
if (ret == 0) {
1227+
/* Calculate key. */
1228+
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN, label, outKey,
1229+
outKeySz, aes);
11341230
}
11351231

11361232
/* AES object memset so can always free. */
@@ -1139,6 +1235,88 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
11391235
XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
11401236
#endif
11411237
return ret;
1238+
1239+
}
1240+
1241+
/* Derive key with label using SRTCP KDF algorithm.
1242+
*
1243+
* SP 800-135 (RFC 3711).
1244+
*
1245+
* @param [in] key Key to use with encryption.
1246+
* @param [in] keySz Size of key in bytes.
1247+
* @param [in] salt Random non-secret value.
1248+
* @param [in] saltSz Size of random in bytes.
1249+
* @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise
1250+
* kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
1251+
* @param [in] index Index value to XOR in.
1252+
* @param [in] label Label to use when deriving key.
1253+
* @param [out] outKey Derived key.
1254+
* @param [in] outKeySz Size of derived key in bytes.
1255+
* @return BAD_FUNC_ARG when key, salt or outKey is NULL.
1256+
* @return BAD_FUNC_ARG when key length is not 16, 24 or 32.
1257+
* @return BAD_FUNC_ARG when saltSz is larger than 14.
1258+
* @return BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
1259+
* @return MEMORY_E on dynamic memory allocation failure.
1260+
* @return 0 on success.
1261+
*/
1262+
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
1263+
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
1264+
word32 outKeySz)
1265+
{
1266+
int ret = 0;
1267+
byte block[AES_BLOCK_SIZE];
1268+
#ifdef WOLFSSL_SMALL_STACK
1269+
Aes* aes = NULL;
1270+
#else
1271+
Aes aes[1];
1272+
#endif
1273+
1274+
/* Validate parameters. */
1275+
if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
1276+
(saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
1277+
(outKey == NULL)) {
1278+
ret = BAD_FUNC_ARG;
1279+
}
1280+
1281+
#ifdef WOLFSSL_SMALL_STACK
1282+
if (ret == 0) {
1283+
aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
1284+
if (aes == NULL) {
1285+
ret = MEMORY_E;
1286+
}
1287+
}
1288+
if (aes != NULL)
1289+
#endif
1290+
{
1291+
XMEMSET(aes, 0, sizeof(Aes));
1292+
}
1293+
1294+
/* Setup AES object. */
1295+
if (ret == 0) {
1296+
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
1297+
}
1298+
if (ret == 0) {
1299+
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
1300+
}
1301+
1302+
/* Calculate first block that can be used in each derivation. */
1303+
if (ret == 0) {
1304+
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTCP_INDEX_LEN,
1305+
block);
1306+
}
1307+
if (ret == 0) {
1308+
/* Calculate key. */
1309+
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN, label, outKey,
1310+
outKeySz, aes);
1311+
}
1312+
1313+
/* AES object memset so can always free. */
1314+
wc_AesFree(aes);
1315+
#ifdef WOLFSSL_SMALL_STACK
1316+
XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
1317+
#endif
1318+
return ret;
1319+
11421320
}
11431321

11441322
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.

0 commit comments

Comments
 (0)