@@ -1389,4 +1389,104 @@ int wc_SRTP_KDF_kdr_to_idx(word32 kdr)
13891389}
13901390#endif /* WC_SRTP_KDF */
13911391
1392+ #ifdef WC_KDF_NIST_SP_800_56C
1393+ static int wc_KDA_KDF_iteration (const byte * z , word32 zSz , word32 counter ,
1394+ const byte * fixedInfo , word32 fixedInfoSz , enum wc_HashType hashType ,
1395+ byte * output )
1396+ {
1397+ byte counterBuf [4 ];
1398+ wc_HashAlg hash ;
1399+ int ret ;
1400+
1401+ ret = wc_HashInit (& hash , hashType );
1402+ if (ret != 0 )
1403+ return ret ;
1404+ c32toa (counter , counterBuf );
1405+ ret = wc_HashUpdate (& hash , hashType , counterBuf , 4 );
1406+ if (ret == 0 ) {
1407+ ret = wc_HashUpdate (& hash , hashType , z , zSz );
1408+ }
1409+ if (ret == 0 && fixedInfoSz > 0 ) {
1410+ ret = wc_HashUpdate (& hash , hashType , fixedInfo , fixedInfoSz );
1411+ }
1412+ if (ret == 0 ) {
1413+ ret = wc_HashFinal (& hash , hashType , output );
1414+ }
1415+ wc_HashFree (& hash , hashType );
1416+ return ret ;
1417+ }
1418+
1419+ /**
1420+ * \brief Performs the single-step key derivation function (KDF) as specified in
1421+ * SP800-56C option 1.
1422+ *
1423+ * \param [in] z The input keying material.
1424+ * \param [in] zSz The size of the input keying material.
1425+ * \param [in] fixedInfo The fixed information to be included in the KDF.
1426+ * \param [in] fixedInfoSz The size of the fixed information.
1427+ * \param [in] derivedSecretSz The desired size of the derived secret.
1428+ * \param [in] hashType The hash algorithm to be used in the KDF.
1429+ * \param [out] output The buffer to store the derived secret.
1430+ * \param [in] outputSz The size of the output buffer.
1431+ *
1432+ * \return 0 if the KDF operation is successful.
1433+ * \return BAD_FUNC_ARG if the input parameters are invalid.
1434+ * \return negative error code if the KDF operation fails.
1435+ */
1436+ int wc_KDA_KDF_onestep (const byte * z , word32 zSz , const byte * fixedInfo ,
1437+ word32 fixedInfoSz , word32 derivedSecretSz , enum wc_HashType hashType ,
1438+ byte * output , word32 outputSz )
1439+ {
1440+ byte hashTempBuf [WC_MAX_DIGEST_SIZE ];
1441+ word32 counter , outIdx ;
1442+ int hashOutSz ;
1443+ int ret ;
1444+
1445+ if (output == NULL || outputSz < derivedSecretSz )
1446+ return BAD_FUNC_ARG ;
1447+ if (z == NULL || zSz == 0 || (fixedInfoSz > 0 && fixedInfo == NULL ))
1448+ return BAD_FUNC_ARG ;
1449+ if (derivedSecretSz == 0 )
1450+ return BAD_FUNC_ARG ;
1451+
1452+ hashOutSz = wc_HashGetDigestSize (hashType );
1453+ if (hashOutSz == HASH_TYPE_E )
1454+ return BAD_FUNC_ARG ;
1455+
1456+ /* According to SP800_56C, table 1, the max input size (max_H_inputBits)
1457+ * depends on the HASH algo. The smaller value in the table is (2**64-1)/8.
1458+ * This is larger than the possible length using word32 integers. */
1459+
1460+ counter = 1 ;
1461+ outIdx = 0 ;
1462+ ret = 0 ;
1463+
1464+ /* According to SP800_56C the number of iterations shall not be greater than
1465+ * 2**32-1. This is not possible using word32 integers.*/
1466+ while (outIdx + hashOutSz <= derivedSecretSz ) {
1467+ ret = wc_KDA_KDF_iteration (z , zSz , counter , fixedInfo , fixedInfoSz ,
1468+ hashType , output + outIdx );
1469+ if (ret != 0 )
1470+ break ;
1471+ counter ++ ;
1472+ outIdx += hashOutSz ;
1473+ }
1474+
1475+ if (ret == 0 && outIdx < derivedSecretSz ) {
1476+ ret = wc_KDA_KDF_iteration (z , zSz , counter , fixedInfo , fixedInfoSz ,
1477+ hashType , hashTempBuf );
1478+ if (ret == 0 ) {
1479+ XMEMCPY (output + outIdx , hashTempBuf , derivedSecretSz - outIdx );
1480+ }
1481+ ForceZero (hashTempBuf , hashOutSz );
1482+ }
1483+
1484+ if (ret != 0 ) {
1485+ ForceZero (output , derivedSecretSz );
1486+ }
1487+
1488+ return ret ;
1489+ }
1490+ #endif /* WC_KDF_NIST_SP_800_56C */
1491+
13921492#endif /* NO_KDF */
0 commit comments