@@ -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