forked from wolfSSL/wolfssl
Merge pull request #7068 from SparkiDev/srtp_kdf_label
SRTP/SRTCP KDF: add APIs that derives one key from a label
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
\brief This function derives keys using SRTP KDF algorithm.
|
\brief This function derives keys using SRTP KDF algorithm.
|
||||||
|
|
||||||
\return 0 Returned upon successful key derviation.
|
\return 0 Returned upon successful key derivation.
|
||||||
\return BAD_FUNC_ARG Returned when key or salt is NULL
|
\return BAD_FUNC_ARG Returned when key or salt is NULL
|
||||||
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
|
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
|
||||||
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
|
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
|
||||||
@ -44,6 +44,8 @@
|
|||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\sa wc_SRTCP_KDF
|
\sa wc_SRTCP_KDF
|
||||||
|
\sa wc_SRTP_KDF_label
|
||||||
|
\sa wc_SRTCP_KDF_label
|
||||||
\sa wc_SRTP_KDF_kdr_to_idx
|
\sa wc_SRTP_KDF_kdr_to_idx
|
||||||
*/
|
*/
|
||||||
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
||||||
@ -55,7 +57,7 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
|||||||
|
|
||||||
\brief This function derives keys using SRTCP KDF algorithm.
|
\brief This function derives keys using SRTCP KDF algorithm.
|
||||||
|
|
||||||
\return 0 Returned upon successful key derviation.
|
\return 0 Returned upon successful key derivation.
|
||||||
\return BAD_FUNC_ARG Returned when key or salt is NULL
|
\return BAD_FUNC_ARG Returned when key or salt is NULL
|
||||||
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
|
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
|
||||||
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
|
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
|
||||||
@ -95,12 +97,107 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
|||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\sa wc_SRTP_KDF
|
\sa wc_SRTP_KDF
|
||||||
|
\sa wc_SRTP_KDF_label
|
||||||
|
\sa wc_SRTCP_KDF_label
|
||||||
\sa wc_SRTP_KDF_kdr_to_idx
|
\sa wc_SRTP_KDF_kdr_to_idx
|
||||||
*/
|
*/
|
||||||
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
||||||
int kdrIdx, const byte* index, byte* key1, word32 key1Sz, byte* key2,
|
int kdrIdx, const byte* index, byte* key1, word32 key1Sz, byte* key2,
|
||||||
word32 key2Sz, byte* key3, word32 key3Sz);
|
word32 key2Sz, byte* key3, word32 key3Sz);
|
||||||
|
/*!
|
||||||
|
\ingroup SrtpKdf
|
||||||
|
|
||||||
|
\brief This function derives a key with label using SRTP KDF algorithm.
|
||||||
|
|
||||||
|
\return 0 Returned upon successful key derivation.
|
||||||
|
\return BAD_FUNC_ARG Returned when key, salt or outKey is NULL
|
||||||
|
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
|
||||||
|
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
|
||||||
|
\return BAD_FUNC_ARG Returned when kdrIdx is less than -1 or larger than 24.
|
||||||
|
\return MEMORY_E on dynamic memory allocation failure.
|
||||||
|
|
||||||
|
\param [in] key Key to use with encryption.
|
||||||
|
\param [in] keySz Size of key in bytes.
|
||||||
|
\param [in] salt Random non-secret value.
|
||||||
|
\param [in] saltSz Size of random in bytes.
|
||||||
|
\param [in] kdrIdx Key derivation rate. kdr = 0 when -1, otherwise kdr = 2^kdrIdx.
|
||||||
|
\param [in] index Index value to XOR in.
|
||||||
|
\param [in] label Label to use when deriving key.
|
||||||
|
\param [out] outKey Derived key.
|
||||||
|
\param [in] outKeySz Size of derived key in bytes.
|
||||||
|
|
||||||
|
|
||||||
|
_Example_
|
||||||
|
\code
|
||||||
|
unsigned char key[16] = { ... };
|
||||||
|
unsigned char salt[14] = { ... };
|
||||||
|
unsigned char index[6] = { ... };
|
||||||
|
unsigned char keyE[16];
|
||||||
|
int kdrIdx = 0; // Use all of index
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = wc_SRTP_KDF_label(key, sizeof(key), salt, sizeof(salt), kdrIdx, index,
|
||||||
|
WC_SRTP_LABEL_ENCRYPTION, keyE, sizeof(keyE));
|
||||||
|
if (ret != 0) {
|
||||||
|
WOLFSSL_MSG("wc_SRTP_KDF failed");
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\sa wc_SRTP_KDF
|
||||||
|
\sa wc_SRTCP_KDF
|
||||||
|
\sa wc_SRTCP_KDF_label
|
||||||
|
\sa wc_SRTP_KDF_kdr_to_idx
|
||||||
|
*/
|
||||||
|
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||||
|
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
|
||||||
|
word32 outKeySz);
|
||||||
|
/*!
|
||||||
|
\ingroup SrtpKdf
|
||||||
|
|
||||||
|
\brief This function derives key with label using SRTCP KDF algorithm.
|
||||||
|
|
||||||
|
\return 0 Returned upon successful key derivation.
|
||||||
|
\return BAD_FUNC_ARG Returned when key, salt or outKey is NULL
|
||||||
|
\return BAD_FUNC_ARG Returned when key length is not 16, 24 or 32.
|
||||||
|
\return BAD_FUNC_ARG Returned when saltSz is larger than 14.
|
||||||
|
\return BAD_FUNC_ARG Returned when kdrIdx is less than -1 or larger than 24.
|
||||||
|
\return MEMORY_E on dynamic memory allocation failure.
|
||||||
|
|
||||||
|
\param [in] key Key to use with encryption.
|
||||||
|
\param [in] keySz Size of key in bytes.
|
||||||
|
\param [in] salt Random non-secret value.
|
||||||
|
\param [in] saltSz Size of random in bytes.
|
||||||
|
\param [in] kdrIdx Key derivation rate. kdr = 0 when -1, otherwise kdr = 2^kdrIdx.
|
||||||
|
\param [in] index Index value to XOR in.
|
||||||
|
\param [in] label Label to use when deriving key.
|
||||||
|
\param [out] outKey Derived key.
|
||||||
|
\param [in] outKeySz Size of derived key in bytes.
|
||||||
|
|
||||||
|
|
||||||
|
_Example_
|
||||||
|
\code
|
||||||
|
unsigned char key[16] = { ... };
|
||||||
|
unsigned char salt[14] = { ... };
|
||||||
|
unsigned char index[4] = { ... };
|
||||||
|
unsigned char keyE[16];
|
||||||
|
int kdrIdx = 0; // Use all of index
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = wc_SRTCP_KDF_label(key, sizeof(key), salt, sizeof(salt), kdrIdx,
|
||||||
|
index, WC_SRTCP_LABEL_ENCRYPTION, keyE, sizeof(keyE));
|
||||||
|
if (ret != 0) {
|
||||||
|
WOLFSSL_MSG("wc_SRTP_KDF failed");
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\sa wc_SRTP_KDF
|
||||||
|
\sa wc_SRTCP_KDF
|
||||||
|
\sa wc_SRTP_KDF_label
|
||||||
|
\sa wc_SRTP_KDF_kdr_to_idx
|
||||||
|
*/
|
||||||
|
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||||
|
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
|
||||||
|
word32 outKeySz);
|
||||||
/*!
|
/*!
|
||||||
\ingroup SrtpKdf
|
\ingroup SrtpKdf
|
||||||
|
|
||||||
@ -121,6 +218,8 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
|||||||
|
|
||||||
\sa wc_SRTP_KDF
|
\sa wc_SRTP_KDF
|
||||||
\sa wc_SRTCP_KDF
|
\sa wc_SRTCP_KDF
|
||||||
|
\sa wc_SRTP_KDF_label
|
||||||
|
\sa wc_SRTCP_KDF_label
|
||||||
*/
|
*/
|
||||||
int wc_SRTP_KDF_kdr_to_idx(word32 kdr);
|
int wc_SRTP_KDF_kdr_to_idx(word32 kdr);
|
||||||
|
|
||||||
|
@ -890,8 +890,9 @@ static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
|
|||||||
word32 i;
|
word32 i;
|
||||||
|
|
||||||
/* XOR salt into zeroized buffer. */
|
/* XOR salt into zeroized buffer. */
|
||||||
for (i = 0; i < WC_SRTP_MAX_SALT - saltSz; i++)
|
for (i = 0; i < WC_SRTP_MAX_SALT - saltSz; i++) {
|
||||||
block[i] = 0;
|
block[i] = 0;
|
||||||
|
}
|
||||||
XMEMCPY(block + WC_SRTP_MAX_SALT - saltSz, salt, saltSz);
|
XMEMCPY(block + WC_SRTP_MAX_SALT - saltSz, salt, saltSz);
|
||||||
block[WC_SRTP_MAX_SALT] = 0;
|
block[WC_SRTP_MAX_SALT] = 0;
|
||||||
/* block[15] is counter. */
|
/* block[15] is counter. */
|
||||||
@ -905,8 +906,9 @@ static void wc_srtp_kdf_first_block(const byte* salt, word32 saltSz, int kdrIdx,
|
|||||||
|
|
||||||
if ((kdrIdx & 0x7) == 0) {
|
if ((kdrIdx & 0x7) == 0) {
|
||||||
/* Just XOR in as no bit shifting. */
|
/* Just XOR in as no bit shifting. */
|
||||||
for (i = 0; i < indexSz; i++)
|
for (i = 0; i < indexSz; i++) {
|
||||||
block[i + WC_SRTP_MAX_SALT - indexSz] ^= index[i];
|
block[i + WC_SRTP_MAX_SALT - indexSz] ^= index[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* XOR in as bit shifted index. */
|
/* XOR in as bit shifted index. */
|
||||||
@ -1025,26 +1027,33 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup AES object. */
|
/* Setup AES object. */
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||||
if (ret == 0)
|
}
|
||||||
|
if (ret == 0) {
|
||||||
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate first block that can be used in each derivation. */
|
/* Calculate first block that can be used in each derivation. */
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, 6, block);
|
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTP_INDEX_LEN,
|
||||||
|
block);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate first key if required. */
|
/* Calculate first key if required. */
|
||||||
if ((ret == 0) && (key1 != NULL)) {
|
if ((ret == 0) && (key1 != NULL)) {
|
||||||
ret = wc_srtp_kdf_derive_key(block, 6, 0x00, key1, key1Sz, aes);
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
|
||||||
|
WC_SRTP_LABEL_ENCRYPTION, key1, key1Sz, aes);
|
||||||
}
|
}
|
||||||
/* Calculate second key if required. */
|
/* Calculate second key if required. */
|
||||||
if ((ret == 0) && (key2 != NULL)) {
|
if ((ret == 0) && (key2 != NULL)) {
|
||||||
ret = wc_srtp_kdf_derive_key(block, 6, 0x01, key2, key2Sz, aes);
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
|
||||||
|
WC_SRTP_LABEL_MSG_AUTH, key2, key2Sz, aes);
|
||||||
}
|
}
|
||||||
/* Calculate third key if required. */
|
/* Calculate third key if required. */
|
||||||
if ((ret == 0) && (key3 != NULL)) {
|
if ((ret == 0) && (key3 != NULL)) {
|
||||||
ret = wc_srtp_kdf_derive_key(block, 6, 0x02, key3, key3Sz, aes);
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN,
|
||||||
|
WC_SRTP_LABEL_SALT, key3, key3Sz, aes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AES object memset so can always free. */
|
/* AES object memset so can always free. */
|
||||||
@ -1111,26 +1120,33 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup AES object. */
|
/* Setup AES object. */
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||||
if (ret == 0)
|
}
|
||||||
|
if (ret == 0) {
|
||||||
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate first block that can be used in each derivation. */
|
/* Calculate first block that can be used in each derivation. */
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, 4, block);
|
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTCP_INDEX_LEN,
|
||||||
|
block);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate first key if required. */
|
/* Calculate first key if required. */
|
||||||
if ((ret == 0) && (key1 != NULL)) {
|
if ((ret == 0) && (key1 != NULL)) {
|
||||||
ret = wc_srtp_kdf_derive_key(block, 4, 0x03, key1, key1Sz, aes);
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN,
|
||||||
|
WC_SRTCP_LABEL_ENCRYPTION, key1, key1Sz, aes);
|
||||||
}
|
}
|
||||||
/* Calculate second key if required. */
|
/* Calculate second key if required. */
|
||||||
if ((ret == 0) && (key2 != NULL)) {
|
if ((ret == 0) && (key2 != NULL)) {
|
||||||
ret = wc_srtp_kdf_derive_key(block, 4, 0x04, key2, key2Sz, aes);
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN,
|
||||||
|
WC_SRTCP_LABEL_MSG_AUTH, key2, key2Sz, aes);
|
||||||
}
|
}
|
||||||
/* Calculate third key if required. */
|
/* Calculate third key if required. */
|
||||||
if ((ret == 0) && (key3 != NULL)) {
|
if ((ret == 0) && (key3 != NULL)) {
|
||||||
ret = wc_srtp_kdf_derive_key(block, 4, 0x05, key3, key3Sz, aes);
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN,
|
||||||
|
WC_SRTCP_LABEL_SALT, key3, key3Sz, aes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AES object memset so can always free. */
|
/* AES object memset so can always free. */
|
||||||
@ -1141,6 +1157,168 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Derive key with label using SRTP KDF algorithm.
|
||||||
|
*
|
||||||
|
* SP 800-135 (RFC 3711).
|
||||||
|
*
|
||||||
|
* @param [in] key Key to use with encryption.
|
||||||
|
* @param [in] keySz Size of key in bytes.
|
||||||
|
* @param [in] salt Random non-secret value.
|
||||||
|
* @param [in] saltSz Size of random in bytes.
|
||||||
|
* @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise
|
||||||
|
* kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
|
||||||
|
* @param [in] index Index value to XOR in.
|
||||||
|
* @param [in] label Label to use when deriving key.
|
||||||
|
* @param [out] outKey Derived key.
|
||||||
|
* @param [in] outKeySz Size of derived key in bytes.
|
||||||
|
* @return BAD_FUNC_ARG when key, salt or outKey is NULL.
|
||||||
|
* @return BAD_FUNC_ARG when key length is not 16, 24 or 32.
|
||||||
|
* @return BAD_FUNC_ARG when saltSz is larger than 14.
|
||||||
|
* @return BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
|
||||||
|
* @return MEMORY_E on dynamic memory allocation failure.
|
||||||
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
|
int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||||
|
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
|
||||||
|
word32 outKeySz)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
byte block[AES_BLOCK_SIZE];
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
Aes* aes = NULL;
|
||||||
|
#else
|
||||||
|
Aes aes[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Validate parameters. */
|
||||||
|
if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
|
||||||
|
(saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
|
||||||
|
(outKey == NULL)) {
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
if (ret == 0) {
|
||||||
|
aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
|
||||||
|
if (aes == NULL) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aes != NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
XMEMSET(aes, 0, sizeof(Aes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup AES object. */
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate first block that can be used in each derivation. */
|
||||||
|
if (ret == 0) {
|
||||||
|
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTP_INDEX_LEN,
|
||||||
|
block);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
/* Calculate key. */
|
||||||
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTP_INDEX_LEN, label, outKey,
|
||||||
|
outKeySz, aes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AES object memset so can always free. */
|
||||||
|
wc_AesFree(aes);
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Derive key with label using SRTCP KDF algorithm.
|
||||||
|
*
|
||||||
|
* SP 800-135 (RFC 3711).
|
||||||
|
*
|
||||||
|
* @param [in] key Key to use with encryption.
|
||||||
|
* @param [in] keySz Size of key in bytes.
|
||||||
|
* @param [in] salt Random non-secret value.
|
||||||
|
* @param [in] saltSz Size of random in bytes.
|
||||||
|
* @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise
|
||||||
|
* kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx()
|
||||||
|
* @param [in] index Index value to XOR in.
|
||||||
|
* @param [in] label Label to use when deriving key.
|
||||||
|
* @param [out] outKey Derived key.
|
||||||
|
* @param [in] outKeySz Size of derived key in bytes.
|
||||||
|
* @return BAD_FUNC_ARG when key, salt or outKey is NULL.
|
||||||
|
* @return BAD_FUNC_ARG when key length is not 16, 24 or 32.
|
||||||
|
* @return BAD_FUNC_ARG when saltSz is larger than 14.
|
||||||
|
* @return BAD_FUNC_ARG when kdrIdx is less than -1 or larger than 24.
|
||||||
|
* @return MEMORY_E on dynamic memory allocation failure.
|
||||||
|
* @return 0 on success.
|
||||||
|
*/
|
||||||
|
int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt,
|
||||||
|
word32 saltSz, int kdrIdx, const byte* index, byte label, byte* outKey,
|
||||||
|
word32 outKeySz)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
byte block[AES_BLOCK_SIZE];
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
Aes* aes = NULL;
|
||||||
|
#else
|
||||||
|
Aes aes[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Validate parameters. */
|
||||||
|
if ((key == NULL) || (keySz > AES_256_KEY_SIZE) || (salt == NULL) ||
|
||||||
|
(saltSz > WC_SRTP_MAX_SALT) || (kdrIdx < -1) || (kdrIdx > 24) ||
|
||||||
|
(outKey == NULL)) {
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
if (ret == 0) {
|
||||||
|
aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_CIPHER);
|
||||||
|
if (aes == NULL) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aes != NULL)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
XMEMSET(aes, 0, sizeof(Aes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup AES object. */
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_AesInit(aes, NULL, INVALID_DEVID);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate first block that can be used in each derivation. */
|
||||||
|
if (ret == 0) {
|
||||||
|
wc_srtp_kdf_first_block(salt, saltSz, kdrIdx, index, WC_SRTCP_INDEX_LEN,
|
||||||
|
block);
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
/* Calculate key. */
|
||||||
|
ret = wc_srtp_kdf_derive_key(block, WC_SRTCP_INDEX_LEN, label, outKey,
|
||||||
|
outKeySz, aes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AES object memset so can always free. */
|
||||||
|
wc_AesFree(aes);
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(aes, NULL, DYNAMIC_TYPE_CIPHER);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
|
/* Converts a kdr value to an index to use in SRTP/SRTCP KDF API.
|
||||||
*
|
*
|
||||||
* @param [in] kdr Key derivation rate to convert.
|
* @param [in] kdr Key derivation rate to convert.
|
||||||
|
@ -25617,11 +25617,35 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srtpkdf_test(void)
|
|||||||
keyS, tv[i].ksSz);
|
keyS, tv[i].ksSz);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return WC_TEST_RET_ENC_EC(ret);
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
if (XMEMCMP(keyE, tv[i].ke, 16) != 0)
|
if (XMEMCMP(keyE, tv[i].ke, tv[i].keSz) != 0)
|
||||||
return WC_TEST_RET_ENC_NC;
|
return WC_TEST_RET_ENC_NC;
|
||||||
if (XMEMCMP(keyA, tv[i].ka, 20) != 0)
|
if (XMEMCMP(keyA, tv[i].ka, tv[i].kaSz) != 0)
|
||||||
return WC_TEST_RET_ENC_NC;
|
return WC_TEST_RET_ENC_NC;
|
||||||
if (XMEMCMP(keyS, tv[i].ks, 14) != 0)
|
if (XMEMCMP(keyS, tv[i].ks, tv[i].ksSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
ret = wc_SRTP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt,
|
||||||
|
tv[i].saltSz, tv[i].kdfIdx, tv[i].index, WC_SRTP_LABEL_ENCRYPTION,
|
||||||
|
keyE, tv[i].keSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
|
if (XMEMCMP(keyE, tv[i].ke, tv[i].keSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
ret = wc_SRTP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt,
|
||||||
|
tv[i].saltSz, tv[i].kdfIdx, tv[i].index, WC_SRTP_LABEL_MSG_AUTH,
|
||||||
|
keyA, tv[i].kaSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
|
if (XMEMCMP(keyA, tv[i].ka, tv[i].kaSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
ret = wc_SRTP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt,
|
||||||
|
tv[i].saltSz, tv[i].kdfIdx, tv[i].index, WC_SRTP_LABEL_SALT, keyS,
|
||||||
|
tv[i].ksSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
|
if (XMEMCMP(keyS, tv[i].ks, tv[i].ksSz) != 0)
|
||||||
return WC_TEST_RET_ENC_NC;
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
ret = wc_SRTCP_KDF(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz,
|
ret = wc_SRTCP_KDF(tv[i].key, tv[i].keySz, tv[i].salt, tv[i].saltSz,
|
||||||
@ -25629,11 +25653,35 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srtpkdf_test(void)
|
|||||||
keyS, tv[i].ksSz);
|
keyS, tv[i].ksSz);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return WC_TEST_RET_ENC_EC(ret);
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
if (XMEMCMP(keyE, tv[i].ke_c, 16) != 0)
|
if (XMEMCMP(keyE, tv[i].ke_c, tv[i].keSz) != 0)
|
||||||
return WC_TEST_RET_ENC_NC;
|
return WC_TEST_RET_ENC_NC;
|
||||||
if (XMEMCMP(keyA, tv[i].ka_c, 20) != 0)
|
if (XMEMCMP(keyA, tv[i].ka_c, tv[i].kaSz) != 0)
|
||||||
return WC_TEST_RET_ENC_NC;
|
return WC_TEST_RET_ENC_NC;
|
||||||
if (XMEMCMP(keyS, tv[i].ks_c, 14) != 0)
|
if (XMEMCMP(keyS, tv[i].ks_c, tv[i].ksSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
ret = wc_SRTCP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt,
|
||||||
|
tv[i].saltSz, tv[i].kdfIdx, tv[i].index_c,
|
||||||
|
WC_SRTCP_LABEL_ENCRYPTION, keyE, tv[i].keSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
|
if (XMEMCMP(keyE, tv[i].ke_c, tv[i].keSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
ret = wc_SRTCP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt,
|
||||||
|
tv[i].saltSz, tv[i].kdfIdx, tv[i].index_c, WC_SRTCP_LABEL_MSG_AUTH,
|
||||||
|
keyA, tv[i].kaSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
|
if (XMEMCMP(keyA, tv[i].ka_c, tv[i].kaSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
ret = wc_SRTCP_KDF_label(tv[i].key, tv[i].keySz, tv[i].salt,
|
||||||
|
tv[i].saltSz, tv[i].kdfIdx, tv[i].index_c, WC_SRTCP_LABEL_SALT,
|
||||||
|
keyS, tv[i].kaSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(ret);
|
||||||
|
if (XMEMCMP(keyS, tv[i].ks_c, tv[i].ksSz) != 0)
|
||||||
return WC_TEST_RET_ENC_NC;
|
return WC_TEST_RET_ENC_NC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,21 @@ WOLFSSL_API int wc_SSH_KDF(byte hashId, byte keyId,
|
|||||||
#endif /* WOLFSSL_WOLFSSH */
|
#endif /* WOLFSSL_WOLFSSH */
|
||||||
|
|
||||||
#ifdef WC_SRTP_KDF
|
#ifdef WC_SRTP_KDF
|
||||||
|
/* Label values for purpose. */
|
||||||
|
#define WC_SRTP_LABEL_ENCRYPTION 0x00
|
||||||
|
#define WC_SRTP_LABEL_MSG_AUTH 0x01
|
||||||
|
#define WC_SRTP_LABEL_SALT 0x02
|
||||||
|
#define WC_SRTCP_LABEL_ENCRYPTION 0x03
|
||||||
|
#define WC_SRTCP_LABEL_MSG_AUTH 0x04
|
||||||
|
#define WC_SRTCP_LABEL_SALT 0x05
|
||||||
|
#define WC_SRTP_LABEL_HDR_ENCRYPTION 0x06
|
||||||
|
#define WC_SRTP_LABEL_HDR_SALT 0x07
|
||||||
|
|
||||||
|
/* Length of index for SRTP KDF. */
|
||||||
|
#define WC_SRTP_INDEX_LEN 6
|
||||||
|
/* Length of index for SRTCP KDF. */
|
||||||
|
#define WC_SRTCP_INDEX_LEN 4
|
||||||
|
|
||||||
/* Maximum length of salt that can be used with SRTP/SRTCP. */
|
/* Maximum length of salt that can be used with SRTP/SRTCP. */
|
||||||
#define WC_SRTP_MAX_SALT 14
|
#define WC_SRTP_MAX_SALT 14
|
||||||
|
|
||||||
@ -115,6 +130,12 @@ WOLFSSL_API int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt,
|
|||||||
WOLFSSL_API int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt,
|
WOLFSSL_API int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt,
|
||||||
word32 saltSz, int kdrIdx, const byte* index, byte* key1, word32 key1Sz,
|
word32 saltSz, int kdrIdx, const byte* index, byte* key1, word32 key1Sz,
|
||||||
byte* key2, word32 key2Sz, byte* key3, word32 key3Sz);
|
byte* key2, word32 key2Sz, byte* key3, word32 key3Sz);
|
||||||
|
WOLFSSL_API int wc_SRTP_KDF_label(const byte* key, word32 keySz,
|
||||||
|
const byte* salt, word32 saltSz, int kdrIdx, const byte* index, byte label,
|
||||||
|
byte* outKey, word32 outKeySz);
|
||||||
|
WOLFSSL_API int wc_SRTCP_KDF_label(const byte* key, word32 keySz,
|
||||||
|
const byte* salt, word32 saltSz, int kdrIdx, const byte* index, byte label,
|
||||||
|
byte* outKey, word32 outKeySz);
|
||||||
|
|
||||||
WOLFSSL_API int wc_SRTP_KDF_kdr_to_idx(word32 kdr);
|
WOLFSSL_API int wc_SRTP_KDF_kdr_to_idx(word32 kdr);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user