Merged PR 7810991: Add SRTP-KDF and SSH-KDF implementations

- Add SRTP-KDF and SSH-KDF implementations
- Update `SYMCRYPT_HASH` structure to contain hash state copying function member

Related work items: #38101963, #38102026
This commit is contained in:
Cagdas Calik 2022-09-19 20:13:04 +00:00
Родитель efbfc1f077
Коммит bc66c79cde
37 изменённых файлов: 2890 добавлений и 14 удалений

Просмотреть файл

@ -1,3 +1,16 @@
# Version 103.0
- Add SRTP-KDF and SSH-KDF implementations
- Add optimized SHA-2 implementations
- Fix integer truncation issue in 32-bit Linux builds
- Refactor CMake files to simplify build steps and increase flexibility
- Fix bug for SymCryptRsakeyGenerate for encrypt-only keys
- Create and test against simple SymCrypt Windows test module (DLL)
- Remove the module export of g_SymCryptFipsSelftestsPerformed and replace it with SymCryptFipsGetSelftestsPerformed
- Enable SymCrypt unit tests to drive a dynamically-linked module
- Removed Linux embedded module, as generic ARM64 module is the same
- Rejig CPUID logic for VAES and AVX
# Version 102.0
- Breaking change to Asymmetric key generation and import handling, sanitizing flags required for FIPS

Просмотреть файл

@ -760,6 +760,9 @@ SIZE_T
SYMCRYPT_CALL
SymCryptHashInputBlockSize( _In_ PCSYMCRYPT_HASH pHash );
SIZE_T
SYMCRYPT_CALL
SymCryptHashStateSize( _In_ PCSYMCRYPT_HASH pHash );
//
// SymCryptHashStateSize
//
@ -769,19 +772,9 @@ SymCryptHashInputBlockSize( _In_ PCSYMCRYPT_HASH pHash );
// any Symcrypt-implemented hash state, so sizeof( SYMCRYPT_HASH_STATE ) is always
// large enough to contain a hash state.
//
SIZE_T
SYMCRYPT_CALL
SymCryptHashStateSize( _In_ PCSYMCRYPT_HASH pHash );
//
// SymCryptHash
//
// Compute a hash value using any hash function.
// The number of bytes written to the pbResult buffer is
// min( cbResult, SymCryptHashResultSize( pHash ) )
//
VOID
SYMCRYPT_CALL
SymCryptHash(
@ -790,6 +783,14 @@ SymCryptHash(
SIZE_T cbData,
_Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,
SIZE_T cbResult );
//
// SymCryptHash
//
// Compute a hash value using any hash function.
// The number of bytes written to the pbResult buffer is
// min( cbResult, SymCryptHashResultSize( pHash ) )
//
VOID
SYMCRYPT_CALL
@ -805,6 +806,7 @@ SymCryptHashAppend(
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData );
VOID
SYMCRYPT_CALL
SymCryptHashResult(
@ -812,8 +814,23 @@ SymCryptHashResult(
_Inout_updates_bytes_( pHash->stateSize ) PVOID pState,
_Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,
SIZE_T cbResult );
//
// SymCryptHashResult
//
// Finalizes the hash computation by calling the resultFunc member
// of pHash.
// The hash result is produced to an internal buffer and
// the number of bytes written to the pbResult buffer is
// min( cbResult, SymCryptHashResultSize( pHash ) )
VOID
SYMCRYPT_CALL
SymCryptHashStateCopy(
_In_ PCSYMCRYPT_HASH pHash,
_In_reads_(pHash->stateSize) PCVOID pSrc,
_Out_writes_(pHash->stateSize) PVOID pDst);
////////////////////////////////////////////////////////////////////////////
// MD2
//
@ -3912,6 +3929,217 @@ VOID
SYMCRYPT_CALL
SymCryptTlsPrf1_2SelfTest();
////////////////////////////////////////////////////////////////////////////
// SSH-KDF as specified in RFC 4253 Section 7.2.
//
// Labels defined in RFC 4253
#define SYMCRYPT_SSHKDF_IV_CLIENT_TO_SERVER 0x41 // 'A'
#define SYMCRYPT_SSHKDF_IV_SERVER_TO_CLIENT 0x42 // 'B'
#define SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER 0x43 // 'C'
#define SYMCRYPT_SSHKDF_ENCRYPTION_KEY_SERVER_TO_CLIENT 0x44 // 'D'
#define SYMCRYPT_SSHKDF_INTEGRITY_KEY_CLIENT_TO_SERVER 0x45 // 'E'
#define SYMCRYPT_SSHKDF_INTEGRITY_KEY_SERVER_TO_CLIENT 0x46 // 'F'
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSshKdfExpandKey(
_Out_ PSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,
_In_ PCSYMCRYPT_HASH pHashFunc,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey);
//
// Process the key using the specified hash function and store the result in
// SYMCRYPT_SSHKDF_EXPANDED_KEY structure. Once the key is expanded,
// SymCryptSshKdfDerive can be called multiple times to generate keys for
// different uses/labels.
//
// After all the keys are derived from a particular "shared secret" key,
// SYMCRYPT_SSHKDF_EXPANDED_KEY structure must be wiped.
//
// Parameters:
// - pExpandedKey : Pointer to a SYMCRYPT_SSHKDF_EXPANDED_KEY structure that
// will contain the expanded key after the function returns.
// - pHashFunc : Hash function that will be used in the key derivation.
// This function is saved in SYMCRYPT_SSHKDF_EXPANDED_KEY
// so that it is also used by the SymCryptSshKdfDerive function.
// - pbKey, cbKey : Buffer contatining the secret key for the KDF.
//
// Returns SYMCRYPT_NO_ERROR
//
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSshKdfDerive(
_In_ PCSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,
_In_reads_(cbHashValue) PCBYTE pbHashValue,
SIZE_T cbHashValue,
BYTE label,
_In_reads_(cbSessionId) PCBYTE pbSessionId,
SIZE_T cbSessionId,
_Inout_updates_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput);
//
// Derive keys using the expanded key that was initialized with SymCryptSshKdfExpandKey
// along with other inputs. This function can be called consecutively with varying label
// values to generate keys for different purposes as defined in the RFC.
//
// Parameters:
// - pExpandedKey : Pointer to a SYMCRYPT_SSHKDF_EXPANDED_KEY structure that is
// initialized by a prior call to SymCryptSshKdfExpandKey.
// Must be wiped when SymCryptSshKdfDerive is not going to be called
// again with the same expanded key.
// - pbHashValue, cbHashValue : Buffer pointing to "exchange hash" value. cbHashValue must be equal
// to the output size of the hash function passed to SymCryptSshKdfExpandKey.
// - label : Label value used to indicate the type of the derived key.
// - pbSessionId, cbSessionId : Buffer pointing to the session identifier. cbSessionId must be equal
// to the output size of the hash function passed to SymCryptSshKdfExpandKey.
// - pbOutput, cbOutput : Buffer to store the derived key. Exactly cbOutput bytes of output will be generated.
//
// Returns SYMCRYPT_NO_ERROR
//
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSshKdf(
_In_ PCSYMCRYPT_HASH pHashFunc,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_(cbHashValue) PCBYTE pbHashValue,
SIZE_T cbHashValue,
BYTE label,
_In_reads_(cbSessionId) PCBYTE pbSessionId,
SIZE_T cbSessionId,
_Out_writes_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput);
//
// This function is a wrapper for using SymCryptSshKdfExpandKey followed by SymCryptSshKdfDerive
// in order to produce SSH-KDF output.
//
// All of the function arguments are forwarded to SymCryptSshKdfExpandKey and SymCryptSshKdfDerive
// functions, hence the documentation on those functions apply here as well.
//
VOID
SYMCRYPT_CALL
SymCryptSshKdfSha256SelfTest();
VOID
SYMCRYPT_CALL
SymCryptSshKdfSha512SelfTest();
////////////////////////////////////////////////////////////////////////////
// SRTP-KDF as specified in RFC 3711 Section 4.3.1.
//
// Labels defined in RFC 3711
#define SYMCRYPT_SRTP_ENCRYPTION_KEY 0x00
#define SYMCRYPT_SRTP_AUTHENTICATION_KEY 0x01
#define SYMCRYPT_SRTP_SALTING_KEY 0x02
#define SYMCRYPT_SRTCP_ENCRYPTION_KEY 0x03
#define SYMCRYPT_SRTCP_AUTHENTICATION_KEY 0x04
#define SYMCRYPT_SRTCP_SALTING_KEY 0x05
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSrtpKdfExpandKey(
_Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey);
//
// Process the key and store the result in SYMCRYPT_SRTPKDF_EXPANDED_KEY structure.
// Once the key is expanded, SymCryptSrtpKdfDerive can be called multiple times to
// generate keys for different uses/labels.
//
// After all the keys are derived from a particular "shared secret" key,
// SYMCRYPT_SRTPKDF_EXPANDED_KEY structure must be wiped.
//
// Parameters:
// - pExpandedKey : Pointer to a SYMCRYPT_SRTPKDF_EXPANDED_KEY structure that
// will contain the expanded key after the function returns.
// - pbKey, cbKey : Buffer contatining the secret key for the KDF. cbKey must be
// a valid AES key size (16-, 24-, or 32-bytes).
//
// Returns:
// SYMCRYPT_WRONG_KEY_SIZE : If cbKey is not a valid AES key size
// SYMCRYPT_NO_ERROR : On success
//
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSrtpKdfDerive(
_In_ PCSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,
_In_reads_(cbSalt) PCBYTE pbSalt,
SIZE_T cbSalt,
UINT32 uKeyDerivationRate,
UINT64 uIndex,
UINT32 uIndexWidth,
BYTE label,
_Out_writes_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput);
//
// Derive keys using the expanded key that was initialized with SymCryptSrtpKdfExpandKey
// along with other inputs. This function can be called consecutively with varying label
// values to generate keys for different purposes as defined in the RFC.
//
// Parameters:
// - pExpandedKey : Pointer to a SYMCRYPT_SRTPKDF_EXPANDED_KEY structure that is
// initialized by a prior call to SymCryptSrtpKdfExpandKey.
// Must be wiped when SymCryptSrtpKdfDerive is not going to be called
// again with the same expanded key.
// - pbSalt, cbSalt : Buffer pointing to the salt value. cbSalt must always be 14 (112-bits).
// - uKeyDerivationRate : Key derivation rate; must be zero or 2^i for 0 <= i <= 24.
// - uIndex : Denotes an SRTP index value when label is 0x00, 0x01, or 0x02, otherwise
// denotes an SRTCP index value.
// - uIndexWidth : Denotes how wide uIndex value is. Must be one of 0, 32, or 48. By default,
// (when uIndexWidth = 0) uIndex is treated as 48-bits.
// RFC 3711 initially defined SRTCP indices to be 32-bit values. It was updated
// to be 48-bits by Errata ID 3712. SRTP index values are defined to be 48-bits.
// - label : Label value used to indicate the type of the derived key.
// - pbOutput, cbOutput : Buffer to store the derived key. Exactly cbOutput bytes of output will be generated.
//
// Returns:
// SYMCRYPT_INVALID_ARGUMENT : If cbSalt is not 14-bytes, or uKeyDerivationRate in invalid.
// SYMCRYPT_NO_ERROR : On success.
//
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSrtpKdf(
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_(cbSalt) PCBYTE pbSalt,
SIZE_T cbSalt,
UINT32 uKeyDerivationRate,
UINT64 uIndex,
UINT32 uIndexWidth,
BYTE label,
_Out_writes_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput);
//
// This function is a wrapper for using SymCryptSrtpKdfExpandKey followed by SymCryptSrtpKdfDerive
// in order to produce SRTP-KDF output.
//
// All of the function arguments are forwarded to SymCryptSrtpKdfExpandKey and SymCryptSrtpKdfDerive
// functions, hence the documentation on those functions apply here as well.
//
VOID
SYMCRYPT_CALL
SymCryptSrtpKdfSelfTest();
////////////////////////////////////////////////////////////////////////////
// HKDF
//

Просмотреть файл

@ -852,6 +852,7 @@ typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_INIT_FUNC) ( PVOID pSta
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_FUNC) ( PVOID pState, PCBYTE pbData, SIZE_T cbData );
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_RESULT_FUNC) ( PVOID pState, PVOID pbResult );
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC) ( PVOID pChain, PCBYTE pbData, SIZE_T cbData, SIZE_T * pcbRemaining );
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_STATE_COPY_FUNC) ( PCVOID pStateSrc, PVOID pStateDst );
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH
{
@ -859,6 +860,7 @@ typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH
PSYMCRYPT_HASH_APPEND_FUNC appendFunc;
PSYMCRYPT_HASH_RESULT_FUNC resultFunc;
PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC appendBlockFunc;
PSYMCRYPT_HASH_STATE_COPY_FUNC stateCopyFunc;
UINT32 stateSize; // sizeof( hash state )
UINT32 resultSize; // size of hash result
UINT32 inputBlockSize;
@ -1665,6 +1667,23 @@ typedef struct _SYMCRYPT_TLSPRF1_2_EXPANDED_KEY {
} SYMCRYPT_TLSPRF1_2_EXPANDED_KEY, *PSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;
typedef const SYMCRYPT_TLSPRF1_2_EXPANDED_KEY *PCSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;
//
// SSH-KDF
//
typedef struct _SYMCRYPT_SSHKDF_EXPANDED_KEY {
PCSYMCRYPT_HASH pHashFunc;
SYMCRYPT_HASH_STATE hashState;
} SYMCRYPT_SSHKDF_EXPANDED_KEY, *PSYMCRYPT_SSHKDF_EXPANDED_KEY;
typedef const SYMCRYPT_SSHKDF_EXPANDED_KEY *PCSYMCRYPT_SSHKDF_EXPANDED_KEY;
//
// SRTP-KDF
//
typedef struct _SYMCRYPT_SRTPKDF_EXPANDED_KEY {
SYMCRYPT_AES_EXPANDED_KEY aesExpandedKey;
} SYMCRYPT_SRTPKDF_EXPANDED_KEY, *PSYMCRYPT_SRTPKDF_EXPANDED_KEY;
typedef const SYMCRYPT_SRTPKDF_EXPANDED_KEY *PCSYMCRYPT_SRTPKDF_EXPANDED_KEY;
//
// HKDF
//

Просмотреть файл

@ -22,7 +22,7 @@
// The API numbering starts at 100 to avoid number conficts with the old system.
//
#define SYMCRYPT_CODE_VERSION_API 102
#define SYMCRYPT_CODE_VERSION_API 103
#define SYMCRYPT_CODE_VERSION_MINOR 0
#define SYMCRYPT_CODE_VERSION_PATCH 0

Просмотреть файл

@ -96,6 +96,11 @@ set(SOURCES_COMMON
sp800_108_hmacsha256.c
sp800_108_hmacsha512.c
sp800_108.c
srtp_kdf.c
srtp_kdf_selftest.c
ssh_kdf.c
ssh_kdf_sha256.c
ssh_kdf_sha512.c
tlsCbcVerify.c
tlsprf_selftest.c
tlsprf.c

Просмотреть файл

@ -205,4 +205,13 @@ SymCryptHashResult(
SymCryptWipe( buf, pHash->resultSize );
}
VOID
SYMCRYPT_CALL
SymCryptHashStateCopy(
_In_ PCSYMCRYPT_HASH pHash,
_In_reads_( pHash->stateSize ) PCVOID pSrc,
_Out_writes_( pHash->stateSize ) PVOID pDst)
{
(*pHash->stateCopyFunc)( pSrc, pDst );
}

Просмотреть файл

@ -29,6 +29,7 @@ const SYMCRYPT_HASH SymCryptMd2Algorithm_default = {
&SymCryptMd2Append,
&SymCryptMd2Result,
&SymCryptMd2AppendBlocks,
&SymCryptMd2StateCopy,
sizeof( SYMCRYPT_MD2_STATE ),
SYMCRYPT_MD2_RESULT_SIZE,
SYMCRYPT_MD2_INPUT_BLOCK_SIZE,

Просмотреть файл

@ -35,6 +35,7 @@ const SYMCRYPT_HASH SymCryptMd4Algorithm_default = {
&SymCryptMd4Append,
&SymCryptMd4Result,
&SymCryptMd4AppendBlocks,
&SymCryptMd4StateCopy,
sizeof( SYMCRYPT_MD4_STATE ),
SYMCRYPT_MD4_RESULT_SIZE,
SYMCRYPT_MD4_INPUT_BLOCK_SIZE,

Просмотреть файл

@ -32,6 +32,7 @@ const SYMCRYPT_HASH SymCryptMd5Algorithm_default = {
&SymCryptMd5Append,
&SymCryptMd5Result,
&SymCryptMd5AppendBlocks,
&SymCryptMd5StateCopy,
sizeof( SYMCRYPT_MD5_STATE ),
SYMCRYPT_MD5_RESULT_SIZE,
SYMCRYPT_MD5_INPUT_BLOCK_SIZE,

Просмотреть файл

@ -18,6 +18,7 @@ const SYMCRYPT_HASH SymCryptSha1Algorithm_default = {
&SymCryptSha1Append,
&SymCryptSha1Result,
&SymCryptSha1AppendBlocks,
&SymCryptSha1StateCopy,
sizeof( SYMCRYPT_SHA1_STATE ),
SYMCRYPT_SHA1_RESULT_SIZE,
SYMCRYPT_SHA1_INPUT_BLOCK_SIZE,

Просмотреть файл

@ -21,6 +21,7 @@ const SYMCRYPT_HASH SymCryptSha256Algorithm_default = {
&SymCryptSha256Append,
&SymCryptSha256Result,
&SymCryptSha256AppendBlocks,
&SymCryptSha256StateCopy,
sizeof( SYMCRYPT_SHA256_STATE ),
SYMCRYPT_SHA256_RESULT_SIZE,
SYMCRYPT_SHA256_INPUT_BLOCK_SIZE,

Просмотреть файл

@ -97,6 +97,7 @@ const SYMCRYPT_HASH SymCryptSha384Algorithm_default = {
&SymCryptSha384Append,
&SymCryptSha384Result,
&SymCryptSha512AppendBlocks,
&SymCryptSha384StateCopy,
sizeof( SYMCRYPT_SHA384_STATE ),
SYMCRYPT_SHA384_RESULT_SIZE,
SYMCRYPT_SHA384_INPUT_BLOCK_SIZE,
@ -109,6 +110,7 @@ const SYMCRYPT_HASH SymCryptSha512Algorithm_default = {
&SymCryptSha512Append,
&SymCryptSha512Result,
&SymCryptSha512AppendBlocks,
&SymCryptSha512StateCopy,
sizeof( SYMCRYPT_SHA512_STATE ),
SYMCRYPT_SHA512_RESULT_SIZE,
SYMCRYPT_SHA512_INPUT_BLOCK_SIZE,

Просмотреть файл

@ -139,6 +139,11 @@ SOURCES= \
sp800_108_hmacsha1.c \
sp800_108_hmacsha256.c \
sp800_108_hmacsha512.c \
srtp_kdf.c \
srtp_kdf_selftest.c \
ssh_kdf.c \
ssh_kdf_sha256.c \
ssh_kdf_sha512.c \
tlsprf.c \
tlsprf_selftest.c \
hkdf.c \

175
lib/srtp_kdf.c Normal file
Просмотреть файл

@ -0,0 +1,175 @@
//
// srtp_kdf.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
//
// This module implements SRTP-KDF specified in RFC 3711 Section 4.3.1.
//
#include "precomp.h"
#define SYMCRYPT_SRTP_KDF_SALT_SIZE (112 / 8)
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSrtpKdfExpandKey(
_Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey)
{
return SymCryptAesExpandKeyEncryptOnly(&pExpandedKey->aesExpandedKey, pbKey, cbKey);
}
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSrtpKdfDerive(
_In_ PCSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,
_In_reads_(cbSalt) PCBYTE pbSalt,
SIZE_T cbSalt,
UINT32 uKeyDerivationRate,
UINT64 uIndex,
UINT32 uIndexWidth,
BYTE label,
_Out_writes_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput)
{
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
BYTE X[16] = { 0 };
//
// uIndexWidth must be one of 0, 32 or 48. RFC 3711 defines SRTP indices to be
// 48-bits. SRTCP indices were first specified as 32-bit values and then updated to
// 48-bits by Errata ID 3712. uIndexWidth parameter allows specifying the width of
// the uIndex parameter for both SRTP and SRTCP indices. The test vectors use
// 32-bit SRTCP index values.
//
// The default value of 0 is equivalent to setting uIndexWidth to 48.
if (uIndexWidth == 0)
{
uIndexWidth = 48;
}
else if (uIndexWidth != 32 && uIndexWidth != 48)
{
scError = SYMCRYPT_INVALID_ARGUMENT;
goto cleanup;
}
if (cbSalt != SYMCRYPT_SRTP_KDF_SALT_SIZE)
{
scError = SYMCRYPT_INVALID_ARGUMENT;
goto cleanup;
}
// uKeyDerivationRate must be zero or 2^i for 0 <= i <= 24.
// This is verified by checking both it is not greater than 2^24 and it is either zero or a power of two.
if( (uKeyDerivationRate > (1 << 24)) || ((uKeyDerivationRate & (uKeyDerivationRate - 1)) != 0) )
{
scError = SYMCRYPT_INVALID_ARGUMENT;
goto cleanup;
}
// Initialize X to Salt || 0
memcpy(X, pbSalt, cbSalt);
// (uIndex DIV uKeyDerivationRate) operation can be performed with a right shift as
// uKeyDerivationRate is either zero or a power of 2. When uKeyDerivationRate is zero,
// DIV operation should evaluate to zero, which can be performed by shifting uIndex by 48 bits,
// i.e., maximum value it may have.
UINT32 kdrShift = 48;
if (uKeyDerivationRate)
{
for (UINT32 i = 0; i <= 24; i++)
{
if (uKeyDerivationRate == (1UL << i))
{
kdrShift = i;
break;
}
}
}
UINT64 r = uIndex >> kdrShift;
UINT64 key_id = ((UINT64)label << uIndexWidth) | r;
// XOR key_id into salt
//
// X = S0 ... |S6 ... S13| 0 0
// | key_id |
//
PBYTE pbXorPos = &X[SYMCRYPT_SRTP_KDF_SALT_SIZE - sizeof(key_id)];
UINT64 uSaltLsb = SYMCRYPT_LOAD_MSBFIRST64(pbXorPos);
SYMCRYPT_STORE_MSBFIRST64(pbXorPos, uSaltLsb ^ key_id);
//
// We break the read-once/write once rule here by writing to the pbOutput buffer twice.
// The first write wipes the buffer so that we get the raw keystream bytes from AES-CTR encryption.
// The second write to pbOutput occurs with the SymCryptAesCtrMsb64() call that produces the keystream bytes.
//
// Modification of pbOutput between the two calls does not leak any information, it just results in flipping of the
// corresponding bits of the correct output.
SymCryptWipe(pbOutput, cbOutput);
SymCryptAesCtrMsb64(&pExpandedKey->aesExpandedKey, X, pbOutput, pbOutput, cbOutput & ~0xf);
// SymCryptAesCtrMsb64 only processes full blocks. If cbOutput is not a multiple of 16 we generate the last block of
// keystream to local buffer and copy the necessary number of bytes to output.
if (cbOutput & 0xf)
{
BYTE lastBlockBytes[16] = { 0 };
SymCryptAesCtrMsb64(&pExpandedKey->aesExpandedKey, X, lastBlockBytes, lastBlockBytes, 16);
memcpy(pbOutput + 16 * (cbOutput / 16), lastBlockBytes, cbOutput & 0xf);
SymCryptWipeKnownSize(lastBlockBytes, sizeof(lastBlockBytes));
}
cleanup:
return scError;
}
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSrtpKdf(
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_(cbSalt) PCBYTE pbSalt,
SIZE_T cbSalt,
UINT32 uKeyDerivationRate,
UINT64 uIndex,
UINT32 uIndexWidth,
BYTE label,
_Out_writes_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput)
{
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
SYMCRYPT_SRTPKDF_EXPANDED_KEY expandedKey;
scError = SymCryptSrtpKdfExpandKey(&expandedKey, pbKey, cbKey);
if (scError != SYMCRYPT_NO_ERROR)
{
goto cleanup;
}
scError = SymCryptSrtpKdfDerive(&expandedKey,
pbSalt, cbSalt,
uKeyDerivationRate,
uIndex, uIndexWidth,
label,
pbOutput, cbOutput);
cleanup:
SymCryptWipeKnownSize(&expandedKey, sizeof(expandedKey));
return scError;
}

56
lib/srtp_kdf_selftest.c Normal file
Просмотреть файл

@ -0,0 +1,56 @@
//
// srtp_kdf_selftest.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "precomp.h"
static const BYTE pbKey[] =
{
0xc4, 0x80, 0x9f, 0x6d, 0x36, 0x98, 0x88, 0x72, 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90
};
static const BYTE pbSalt[] =
{
0x0e, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6
};
static const UINT64 uIndex = 0x487165649cca;
static const UINT32 uSRTCPIndex = 0x56f3f197;
static const UINT32 uKeyDerivationRate = 0;
static const BYTE label = SYMCRYPT_SRTP_ENCRYPTION_KEY;
static const BYTE pbResultAes128[] =
{
0xdc, 0x38, 0x21, 0x92, 0xab, 0x65, 0x10, 0x8a, 0x86, 0xb2, 0x59, 0xb6, 0x1b, 0x3a, 0xf4, 0x6f
};
VOID
SYMCRYPT_CALL
SymCryptSrtpKdfSelfTest()
{
SYMCRYPT_SRTPKDF_EXPANDED_KEY expandedKey;
SYMCRYPT_ALIGN BYTE rbResultAes128[sizeof(pbResultAes128)];
SymCryptSrtpKdfExpandKey(&expandedKey, pbKey, sizeof(pbKey));
SymCryptSrtpKdfDerive(&expandedKey,
pbSalt, sizeof(pbSalt),
uKeyDerivationRate,
(label < SYMCRYPT_SRTCP_ENCRYPTION_KEY) ? uIndex : uSRTCPIndex,
(label < SYMCRYPT_SRTCP_ENCRYPTION_KEY) ? 48 : 32,
label,
rbResultAes128, sizeof(rbResultAes128));
SymCryptInjectError(rbResultAes128, sizeof(rbResultAes128));
if (memcmp(rbResultAes128, pbResultAes128, sizeof(pbResultAes128)) != 0)
{
SymCryptFatal('srtp');
}
}

122
lib/ssh_kdf.c Normal file
Просмотреть файл

@ -0,0 +1,122 @@
//
// ssh_kdf.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
//
// This module implements SSH-KDF specified in RFC 4253 Section 7.2.
//
#include "precomp.h"
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSshKdfExpandKey(
_Out_ PSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,
_In_ PCSYMCRYPT_HASH pHashFunc,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey)
{
pExpandedKey->pHashFunc = pHashFunc;
SymCryptHashInit(pHashFunc, &pExpandedKey->hashState);
SymCryptHashAppend(pHashFunc, &pExpandedKey->hashState, pbKey, cbKey);
return SYMCRYPT_NO_ERROR;
}
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSshKdfDerive(
_In_ PCSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,
_In_reads_(cbHashValue) PCBYTE pbHashValue,
SIZE_T cbHashValue,
BYTE label,
_In_reads_(cbSessionId) PCBYTE pbSessionId,
SIZE_T cbSessionId,
_Inout_updates_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput)
{
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
SYMCRYPT_HASH_STATE hashState;
PCBYTE pcbOutputSave = pbOutput;
PCSYMCRYPT_HASH pHashFunc = pExpandedKey->pHashFunc;
SIZE_T cbHashResultSize = SymCryptHashResultSize(pHashFunc);
while (cbOutput > 0)
{
SIZE_T cbGeneratedOutput = pbOutput - pcbOutputSave;
SymCryptHashStateCopy(pHashFunc, &pExpandedKey->hashState, &hashState);
SymCryptHashAppend(pHashFunc, &hashState, pbHashValue, cbHashValue); // hashState has (K || H)
// label and session ID are appended only in the first iteration
if (cbGeneratedOutput == 0)
{
SymCryptHashAppend(pHashFunc, &hashState, &label, 1);
SymCryptHashAppend(pHashFunc, &hashState, pbSessionId, cbSessionId);
}
else
{
// We break the read-once write-once rule here by appending data to a
// hash computation from pbOutput that was written by SymCryptHashResult()
// below.
// Modification of data in pbOutput buffer after it's written and before
// used again will have uncontrolled disturbances in the hash output and cannot
// be used to gain knowledge about the secret key.
SymCryptHashAppend(pHashFunc, &hashState, pcbOutputSave, cbGeneratedOutput); // hashState has (K || H || K1 .. Ki)
}
SymCryptHashResult(pHashFunc, &hashState, pbOutput, cbOutput);
SIZE_T bytesCopied = SYMCRYPT_MIN(cbOutput, cbHashResultSize);
pbOutput += bytesCopied;
cbOutput -= bytesCopied;
}
return scError;
}
SYMCRYPT_ERROR
SYMCRYPT_CALL
SymCryptSshKdf(
_In_ PCSYMCRYPT_HASH pHashFunc,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_(cbHashValue) PCBYTE pbHashValue,
SIZE_T cbHashValue,
BYTE label,
_In_reads_(cbSessionId) PCBYTE pbSessionId,
SIZE_T cbSessionId,
_Out_writes_(cbOutput) PBYTE pbOutput,
SIZE_T cbOutput)
{
SYMCRYPT_SSHKDF_EXPANDED_KEY expandedKey;
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
scError = SymCryptSshKdfExpandKey(&expandedKey, pHashFunc, pbKey, cbKey);
if (scError != SYMCRYPT_NO_ERROR)
{
goto cleanup;
}
scError = SymCryptSshKdfDerive(&expandedKey,
pbHashValue, cbHashValue,
label,
pbSessionId, cbSessionId,
pbOutput, cbOutput);
cleanup:
SymCryptWipeKnownSize(&expandedKey, sizeof(expandedKey));
return scError;
}

65
lib/ssh_kdf_sha256.c Normal file
Просмотреть файл

@ -0,0 +1,65 @@
//
// ssh_kdf_sha256.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "precomp.h"
static const BYTE pbKey[] =
{
0x00, 0x00, 0x00, 0x81, 0x00, 0x87, 0x5c, 0x55, 0x1c, 0xef, 0x52, 0x6a, 0x4a, 0x8b, 0xe1, 0xa7,
0xdf, 0x27, 0xe9, 0xed, 0x35, 0x4b, 0xac, 0x9a, 0xfb, 0x71, 0xf5, 0x3d, 0xba, 0xe9, 0x05, 0x67,
0x9d, 0x14, 0xf9, 0xfa, 0xf2, 0x46, 0x9c, 0x53, 0x45, 0x7c, 0xf8, 0x0a, 0x36, 0x6b, 0xe2, 0x78,
0x96, 0x5b, 0xa6, 0x25, 0x52, 0x76, 0xca, 0x2d, 0x9f, 0x4a, 0x97, 0xd2, 0x71, 0xf7, 0x1e, 0x50,
0xd8, 0xa9, 0xec, 0x46, 0x25, 0x3a, 0x6a, 0x90, 0x6a, 0xc2, 0xc5, 0xe4, 0xf4, 0x8b, 0x27, 0xa6,
0x3c, 0xe0, 0x8d, 0x80, 0x39, 0x0a, 0x49, 0x2a, 0xa4, 0x3b, 0xad, 0x9d, 0x88, 0x2c, 0xca, 0xc2,
0x3d, 0xac, 0x88, 0xbc, 0xad, 0xa4, 0xb4, 0xd4, 0x26, 0xa3, 0x62, 0x08, 0x3d, 0xab, 0x65, 0x69,
0xc5, 0x4c, 0x22, 0x4d, 0xd2, 0xd8, 0x76, 0x43, 0xaa, 0x22, 0x76, 0x93, 0xe1, 0x41, 0xad, 0x16,
0x30, 0xce, 0x13, 0x14, 0x4e
};
static const BYTE pbHash[] =
{
0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23, 0xb2, 0x74, 0x5e, 0xbc,
0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7, 0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
};
static const BYTE pbSessionId[] =
{
0x0e, 0x68, 0x3f, 0xc8, 0xa9, 0xed, 0x7c, 0x2f, 0xf0, 0x2d, 0xef, 0x23, 0xb2, 0x74, 0x5e, 0xbc,
0x99, 0xb2, 0x67, 0xda, 0xa8, 0x6a, 0x4a, 0xa7, 0x69, 0x72, 0x39, 0x08, 0x82, 0x53, 0xf6, 0x42
};
static const BYTE label = SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER;
static const BYTE pbResult[] =
{
0x4a, 0x63, 0x14, 0xd2, 0xf7, 0x51, 0x1b, 0xf8, 0x8f, 0xad, 0x39, 0xfb, 0x68, 0x92, 0xf3, 0xf2, 0x18, 0xca, 0xfd, 0x53, 0x0e, 0x72, 0xfe, 0x43
};
VOID
SYMCRYPT_CALL
SymCryptSshKdfSha256SelfTest()
{
SYMCRYPT_SSHKDF_EXPANDED_KEY expandedKey;
SYMCRYPT_ALIGN BYTE rbResult[sizeof(pbResult)];
SymCryptSshKdfExpandKey(&expandedKey, SymCryptSha256Algorithm, pbKey, sizeof(pbKey));
SymCryptSshKdfDerive(&expandedKey,
pbHash, sizeof(pbHash),
label,
pbSessionId, sizeof(pbSessionId),
rbResult, sizeof(rbResult)
);
SymCryptInjectError(rbResult, sizeof(rbResult));
if (memcmp(rbResult, pbResult, sizeof(pbResult)) != 0)
{
SymCryptFatal('sshk');
}
}

70
lib/ssh_kdf_sha512.c Normal file
Просмотреть файл

@ -0,0 +1,70 @@
//
// ssh_kdf_sha512.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "precomp.h"
static const BYTE pbKey[] =
{
0x00, 0x00, 0x00, 0x80, 0x57, 0x53, 0x08, 0xca, 0x39, 0x57, 0x98, 0xbb, 0x21, 0xec, 0x54, 0x38,
0xc4, 0x6a, 0x88, 0xff, 0xa3, 0xf7, 0xf7, 0x67, 0x1c, 0x06, 0xf9, 0x24, 0xab, 0xf7, 0xc3, 0xcf,
0xb4, 0x6c, 0x78, 0xc0, 0x25, 0x59, 0x6e, 0x4a, 0xba, 0x50, 0xc3, 0x27, 0x10, 0x89, 0x18, 0x4a,
0x44, 0x7a, 0x57, 0x1a, 0xbb, 0x7f, 0x4a, 0x1b, 0x1c, 0x41, 0xf5, 0xd5, 0xca, 0x80, 0x62, 0x94,
0x0d, 0x43, 0x69, 0x77, 0x85, 0x89, 0xfd, 0xe8, 0x1a, 0x71, 0xb2, 0x22, 0x8f, 0x01, 0x8c, 0x4c,
0x83, 0x6c, 0xf3, 0x89, 0xf8, 0x54, 0xf8, 0x6d, 0xe7, 0x1a, 0x68, 0xb1, 0x69, 0x3f, 0xe8, 0xff,
0xa1, 0xc5, 0x9c, 0xe7, 0xe9, 0xf9, 0x22, 0x3d, 0xeb, 0xad, 0xa2, 0x56, 0x6d, 0x2b, 0x0e, 0x56,
0x78, 0xa4, 0x8b, 0xfb, 0x53, 0x0e, 0x7b, 0xee, 0x42, 0xbd, 0x2a, 0xc7, 0x30, 0x4a, 0x0a, 0x5a,
0xe3, 0x39, 0xa2, 0xcd
};
static const BYTE pbHash[] =
{
0xa4, 0x12, 0x5a, 0xa9, 0x89, 0x80, 0x92, 0xca, 0x50, 0xc3, 0xc1, 0x63, 0x1c, 0x03, 0xdc, 0xbc,
0x9d, 0xf9, 0x5c, 0xeb, 0xb4, 0x09, 0x88, 0x1e, 0x58, 0x01, 0x08, 0xb6, 0xcc, 0x47, 0x04, 0xb7,
0x6c, 0xc7, 0x7b, 0x87, 0x95, 0xfd, 0x59, 0x40, 0x56, 0x1e, 0x32, 0x24, 0xcc, 0x75, 0x84, 0x85,
0x18, 0x99, 0x2b, 0xd8, 0xd9, 0xb7, 0x0f, 0xe0, 0xfc, 0x97, 0x7a, 0x47, 0x60, 0x63, 0xc8, 0xbf
};
static const BYTE pbSessionId[] =
{
0xa4, 0x12, 0x5a, 0xa9, 0x89, 0x80, 0x92, 0xca, 0x50, 0xc3, 0xc1, 0x63, 0x1c, 0x03, 0xdc, 0xbc,
0x9d, 0xf9, 0x5c, 0xeb, 0xb4, 0x09, 0x88, 0x1e, 0x58, 0x01, 0x08, 0xb6, 0xcc, 0x47, 0x04, 0xb7,
0x6c, 0xc7, 0x7b, 0x87, 0x95, 0xfd, 0x59, 0x40, 0x56, 0x1e, 0x32, 0x24, 0xcc, 0x75, 0x84, 0x85,
0x18, 0x99, 0x2b, 0xd8, 0xd9, 0xb7, 0x0f, 0xe0, 0xfc, 0x97, 0x7a, 0x47, 0x60, 0x63, 0xc8, 0xbf
};
static const BYTE label = SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER;
static const BYTE pbResult[] =
{
0x7e, 0x4a, 0x72, 0x1f, 0xb7, 0x37, 0x9e, 0xbb, 0x42, 0x33, 0x06, 0x46, 0x4d, 0x57, 0xdb, 0x46,
0xaf, 0xa3, 0xcc, 0xa1, 0x0a, 0x1d, 0x7f, 0xeb
};
VOID
SYMCRYPT_CALL
SymCryptSshKdfSha512SelfTest()
{
SYMCRYPT_SSHKDF_EXPANDED_KEY expandedKey;
SYMCRYPT_ALIGN BYTE rbResult[sizeof(pbResult)];
SymCryptSshKdfExpandKey(&expandedKey, SymCryptSha512Algorithm, pbKey, sizeof(pbKey));
SymCryptSshKdfDerive(&expandedKey,
pbHash, sizeof(pbHash),
label,
pbSessionId, sizeof(pbSessionId),
rbResult, sizeof(rbResult)
);
SymCryptInjectError(rbResult, sizeof(rbResult));
if (memcmp(rbResult, pbResult, sizeof(pbResult)) != 0)
{
SymCryptFatal('sshk');
}
}

Просмотреть файл

@ -411,4 +411,13 @@ VERSION_103.0
{
global:
SymCryptFipsGetSelftestsPerformed;
} VERSION_102.0;
SymCryptSrtpKdf;
SymCryptSrtpKdfExpandKey;
SymCryptSrtpKdfDerive;
SymCryptSrtpKdfSelfTest;
SymCryptSshKdf;
SymCryptSshKdfExpandKey;
SymCryptSshKdfDerive;
SymCryptSshKdfSha256SelfTest;
SymCryptSshKdfSha512SelfTest;
} VERSION_102.0;

Просмотреть файл

@ -59,6 +59,11 @@ VOID __attribute__((constructor)) SymCryptModuleMain()
SymCryptPbkdf2_HmacSha1SelfTest();
SymCryptSrtpKdfSelfTest();
SymCryptSshKdfSha256SelfTest();
SymCryptSshKdfSha512SelfTest();
g_SymCryptFipsSelftestsPerformed |= SYMCRYPT_SELFTEST_ALGORITHM_STARTUP;
}
}

Просмотреть файл

@ -384,6 +384,8 @@ typedef enum _KDF_ARGUMENT_TYPE {
KdfArgumentSp800_108 = 3,
KdfArgumentTlsPrf = 4,
KdfArgumentHkdf = 5,
KdfArgumentSshKdf = 6,
KdfArgumentSrtpKdf = 7,
} KDF_ARGUMENT_TYPE;
typedef struct _KDF_GENERIC_ARGUMENTS {
@ -418,6 +420,24 @@ typedef struct _KDF_HKDF_ARGUMENTS {
SIZE_T cbInfo;
} KDF_HKDF_ARGUMENTS;
typedef struct _KDF_SSHKDF_ARGUMENTS {
PCSYMCRYPT_HASH hash;
PCBYTE pbHashValue;
SIZE_T cbHashValue;
PCBYTE pbSessionId;
SIZE_T cbSessionId;
BYTE label;
} KDF_SSHKDF_ARGUMENTS;
typedef struct _KDF_SRTPKDF_ARGUMENTS {
PCBYTE pbSalt;
SIZE_T cbSalt;
UINT32 uKeyDerivationRate;
UINT64 uIndex;
UINT32 uIndexWidth;
BYTE label;
} KDF_SRTPKDF_ARGUMENTS;
typedef struct _KDF_ARGUMENTS {
KDF_ARGUMENT_TYPE argType;
union {
@ -426,6 +446,8 @@ typedef struct _KDF_ARGUMENTS {
KDF_SP800_108_ARGUMENTS uSp800_108;
KDF_TLSPRF_ARGUMENTS uTlsPrf;
KDF_HKDF_ARGUMENTS uHkdf;
KDF_SSHKDF_ARGUMENTS uSshKdf;
KDF_SRTPKDF_ARGUMENTS uSrtpKdf;
};
} KDF_ARGUMENTS, *PKDF_ARGUMENTS;
typedef const KDF_ARGUMENTS *PCKDF_ARGUMENTS;

Просмотреть файл

@ -86,7 +86,7 @@ BString katParseData( KAT_ITEM & item, LPCSTR name );
//
LONGLONG katParseInteger( KAT_ITEM & item, LPCSTR name );
BOOL katIsFieldPresent( KAT_ITEM & item, LPCSTR name );
const KAT_DATA_ITEM * findDataItem( KAT_ITEM & item, LPCSTR name );

Просмотреть файл

@ -265,6 +265,15 @@
#define ScDispatchSymCryptHkdfDerive(...) SCTEST_CALL_DISPATCHFN(SymCryptHkdfDerive, __VA_ARGS__)
#define ScDispatchSymCryptHkdf(...) SCTEST_CALL_DISPATCHFN(SymCryptHkdf, __VA_ARGS__)
#define ScDispatchSymCryptHkdfSelfTest(...) SCTEST_CALL_DISPATCHFN(SymCryptHkdfSelfTest, __VA_ARGS__)
#define ScDispatchSymCryptSshKdf(...) SCTEST_CALL_DISPATCHFN(SymCryptSshKdf, __VA_ARGS__)
#define ScDispatchSymCryptSshKdfExpandKey(...) SCTEST_CALL_DISPATCHFN(SymCryptSshKdfExpandKey, __VA_ARGS__)
#define ScDispatchSymCryptSshKdfDerive(...) SCTEST_CALL_DISPATCHFN(SymCryptSshKdfDerive, __VA_ARGS__)
#define ScDispatchSymCryptSshKdfSha256SelfTest(...) SCTEST_CALL_DISPATCHFN(SymCryptSshKdfSha256SelfTest, __VA_ARGS__)
#define ScDispatchSymCryptSshKdfSha512SelfTest(...) SCTEST_CALL_DISPATCHFN(SymCryptSshKdfSha512SelfTest, __VA_ARGS__)
#define ScDispatchSymCryptSrtpKdf(...) SCTEST_CALL_DISPATCHFN(SymCryptSrtpKdf, __VA_ARGS__)
#define ScDispatchSymCryptSrtpKdfExpandKey(...) SCTEST_CALL_DISPATCHFN(SymCryptSrtpKdfExpandKey, __VA_ARGS__)
#define ScDispatchSymCryptSrtpKdfDerive(...) SCTEST_CALL_DISPATCHFN(SymCryptSrtpKdfDerive, __VA_ARGS__)
#define ScDispatchSymCryptSrtpKdfSelfTest(...) SCTEST_CALL_DISPATCHFN(SymCryptSrtpKdfSelfTest, __VA_ARGS__)
#define ScDispatchSymCryptRngAesInstantiate(...) SCTEST_CALL_DISPATCHFN(SymCryptRngAesInstantiate, __VA_ARGS__)
#define ScDispatchSymCryptRngAesGenerate(...) SCTEST_CALL_DISPATCHFN(SymCryptRngAesGenerate, __VA_ARGS__)
#define ScDispatchSymCryptRngAesReseed(...) SCTEST_CALL_DISPATCHFN(SymCryptRngAesReseed, __VA_ARGS__)

Просмотреть файл

@ -272,6 +272,15 @@
#define ScShimSymCryptHkdfDerive(...) SCTEST_CALL_SCIMPFN(SymCryptHkdfDerive, __VA_ARGS__)
#define ScShimSymCryptHkdf(...) SCTEST_CALL_SCIMPFN(SymCryptHkdf, __VA_ARGS__)
#define ScShimSymCryptHkdfSelfTest(...) SCTEST_CALL_SCIMPFN(SymCryptHkdfSelfTest, __VA_ARGS__)
#define ScShimSymCryptSshKdf(...) SCTEST_CALL_SCIMPFN(SymCryptSshKdf, __VA_ARGS__)
#define ScShimSymCryptSshKdfExpandKey(...) SCTEST_CALL_SCIMPFN(SymCryptSshKdfExpandKey, __VA_ARGS__)
#define ScShimSymCryptSshKdfDerive(...) SCTEST_CALL_SCIMPFN(SymCryptSshKdfDerive, __VA_ARGS__)
#define ScShimSymCryptSshKdfSha256SelfTest(...) SCTEST_CALL_SCIMPFN(SymCryptSshKdfSha256SelfTest, __VA_ARGS__)
#define ScShimSymCryptSshKdfSha512SelfTest(...) SCTEST_CALL_SCIMPFN(SymCryptSshKdfSha512SelfTest, __VA_ARGS__)
#define ScShimSymCryptSrtpKdf(...) SCTEST_CALL_SCIMPFN(SymCryptSrtpKdf, __VA_ARGS__)
#define ScShimSymCryptSrtpKdfExpandKey(...) SCTEST_CALL_SCIMPFN(SymCryptSrtpKdfExpandKey, __VA_ARGS__)
#define ScShimSymCryptSrtpKdfDerive(...) SCTEST_CALL_SCIMPFN(SymCryptSrtpKdfDerive, __VA_ARGS__)
#define ScShimSymCryptSrtpKdfSelfTest(...) SCTEST_CALL_SCIMPFN(SymCryptSrtpKdfSelfTest, __VA_ARGS__)
#define ScShimSymCryptRngAesInstantiate(...) SCTEST_CALL_SCIMPFN(SymCryptRngAesInstantiate, __VA_ARGS__)
#define ScShimSymCryptRngAesGenerate(...) SCTEST_CALL_SCIMPFN(SymCryptRngAesGenerate, __VA_ARGS__)
#define ScShimSymCryptRngAesReseed(...) SCTEST_CALL_SCIMPFN(SymCryptRngAesReseed, __VA_ARGS__)

Просмотреть файл

@ -259,6 +259,18 @@ public:
SYMCRYPT_HKDF_EXPANDED_KEY key;
};
template<class BaseAlg>
class KdfImpState<ImpXxx, AlgSshKdf, BaseAlg> {
public:
SYMCRYPT_SSHKDF_EXPANDED_KEY key;
};
template<class BaseAlg>
class KdfImpState<ImpXxx, AlgSrtpKdf, BaseAlg> {
public:
SYMCRYPT_SRTPKDF_EXPANDED_KEY key;
};
template<>
class XtsImpState<ImpXxx, AlgXtsAes> {
public:

Просмотреть файл

@ -60,6 +60,9 @@ const SELFTEST_INFO g_selfTests[] =
{&SymCryptParallelSha256Selftest, "ParallelSha256" },
{&SymCryptParallelSha384Selftest, "ParallelSha384" },
{&SymCryptParallelSha512Selftest, "ParallelSha512" },
{&SymCryptSrtpKdfSelfTest, "SrtpKdf" },
{&SymCryptSshKdfSha256SelfTest, "SshKdfSha256" },
{&SymCryptSshKdfSha512SelfTest, "SshKdfSha512" },
{NULL, NULL},
};

Просмотреть файл

@ -701,6 +701,16 @@ public:
const static char * name;
};
class AlgSshKdf{
public:
const static char * name;
};
class AlgSrtpKdf{
public:
const static char * name;
};
class AlgHkdf{
public:
const static char * name;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -112,6 +112,10 @@ const char * AlgTlsPrf1_1::name = "TlsPrf1_1";
const char * AlgTlsPrf1_2::name = "TlsPrf1_2";
const char * AlgSshKdf::name = "SshKdf";
const char * AlgSrtpKdf::name = "SrtpKdf";
const char * AlgHkdf::name = "Hkdf";
const char * AlgXtsAes::name = "XtsAes";
@ -505,6 +509,8 @@ const char * g_algorithmNames[] = {
AlgSp800_108::name,
AlgTlsPrf1_1::name,
AlgTlsPrf1_2::name,
AlgSshKdf::name,
AlgSrtpKdf::name,
AlgHkdf::name,
AlgXtsAes::name,
AlgTlsCbcHmacSha1::name,

Просмотреть файл

@ -260,6 +260,8 @@ const ALG_MEASURE_PARAMS g_algMeasureParams[] =
"TlsPrf1_2HmacSha256" , 0, {32}, { 32, 64, 128, 512, 1024 },
"TlsPrf1_2HmacSha384" , 0, {32}, { 32, 64, 128, 512, 1024 },
"TlsPrf1_2HmacSha512" , 0, {32}, { 32, 64, 128, 512, 1024 },
"SrtpKdfAes" , 0, {16, 24, 32}, {16, 24, 32},
"SshKdfSha256" , 0, {128, 256}, {16, 24, 32},
"HkdfHmacSha256" , 0, {32}, { 32, 64, 128, 512, 1024 },
"HkdfHmacSha1" , 0, {32}, { 32, 64, 128, 512, 1024 },
"XtsAes" , 0, {32,48,64}, {512, 1024, 2048, 4096, 8192, 16384, 32768},

Просмотреть файл

@ -357,6 +357,42 @@
#undef ALG_Name
#define ALG_NAME SSHKDF
#define ALG_Name SshKdf
#define ALG_Base Sha1
#include "sc_imp_kdfpattern.cpp"
#include "sc_imp_sshkdfpattern.cpp"
#undef ALG_Base
#define ALG_Base Sha256
#include "sc_imp_kdfpattern.cpp"
#include "sc_imp_sshkdfpattern.cpp"
#undef ALG_Base
#define ALG_Base Sha384
#include "sc_imp_kdfpattern.cpp"
#include "sc_imp_sshkdfpattern.cpp"
#undef ALG_Base
#define ALG_Base Sha512
#include "sc_imp_kdfpattern.cpp"
#include "sc_imp_sshkdfpattern.cpp"
#undef ALG_Base
#undef ALG_NAME
#undef ALG_Name
#define ALG_NAME SRTPKDF
#define ALG_Name SrtpKdf
#define ALG_Base Aes
#include "sc_imp_srtpkdfpattern.cpp"
#undef ALG_Base
#undef ALG_NAME
#undef ALG_Name
//
// There is not enough structure to the CCM & GCM modes to share an implementation
//

Просмотреть файл

@ -0,0 +1,124 @@
//
// Pattern file for the Symcrypt SRTP-KDF implementations.
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
//
// The following (up to // <<<<<<<) is (almost) duplicate code from the sc_imp_kdfpattern.cpp file.
// We add it here due to the uniqueness of the expand key algorithm (It takes as input the salt which
// for the perf function we set it of size equal to keySize).
//
template<> VOID algImpKeyPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize);
template<> VOID algImpCleanPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3);
template<> VOID algImpDataPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize);
//
// Empty constructor.
//
template<>
KdfImp<ImpXxx, AlgXxx, BaseAlgXxx>::KdfImp()
{
m_perfDataFunction = &algImpDataPerfFunction <ImpXxx, AlgXxx, BaseAlgXxx>;
m_perfKeyFunction = &algImpKeyPerfFunction <ImpXxx, AlgXxx, BaseAlgXxx>;
m_perfCleanFunction = &algImpCleanPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>;
}
template<>
KdfImp<ImpXxx, AlgXxx, BaseAlgXxx>::~KdfImp<ImpXxx, AlgXxx, BaseAlgXxx>()
{
}
template<>
VOID
algImpKeyPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize)
{
UNREFERENCED_PARAMETER(buf3);
SYMCRYPT_XxxExpandKey((SYMCRYPT_XXX_EXPANDED_KEY*)buf1, buf2, keySize);
}
template<>
VOID
algImpCleanPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3)
{
UNREFERENCED_PARAMETER(buf2);
UNREFERENCED_PARAMETER(buf3);
SymCryptWipeKnownSize(buf1, sizeof(SYMCRYPT_XXX_EXPANDED_KEY));
}
// <<<<<<<<<<<<<<<<
template<>
VOID
KdfImp<ImpXxx, AlgSrtpKdf, BaseAlgXxx>::derive(
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_ PKDF_ARGUMENTS pArgs,
_Out_writes_(cbDst) PBYTE pbDst,
SIZE_T cbDst)
{
SYMCRYPT_ERROR scError;
SYMCRYPT_SRTPKDF_EXPANDED_KEY expandedKey;
BYTE buffer1[1024];
BYTE buffer2[sizeof(buffer1)];
BYTE expandedKeyChecksum1[SYMCRYPT_MARVIN32_RESULT_SIZE];
BYTE expandedKeyChecksum2[SYMCRYPT_MARVIN32_RESULT_SIZE];
CHECK(cbDst <= sizeof(buffer1), "SRTP-KDF output too large");
switch (pArgs->argType)
{
case KdfArgumentSrtpKdf:
break;
default:
CHECK(FALSE, "Unknown argument type for SRTP-KDF");
return;
}
scError = ScShimSymCryptSrtpKdfExpandKey(&expandedKey, pbKey, cbKey);
CHECK(scError == SYMCRYPT_NO_ERROR, "Error in SymCryptSrtpKdfExpandKey");
ScShimSymCryptMarvin32(ScShimSymCryptMarvin32DefaultSeed, (PCBYTE)&expandedKey, sizeof(expandedKey), expandedKeyChecksum1);
// Note: Test vectors use 32-bit SRTCP index values
scError = ScShimSymCryptSrtpKdfDerive(&expandedKey,
pArgs->uSrtpKdf.pbSalt, pArgs->uSrtpKdf.cbSalt,
pArgs->uSrtpKdf.uKeyDerivationRate,
pArgs->uSrtpKdf.uIndex, pArgs->uSrtpKdf.label < 3 ? 48 : 32,
pArgs->uSrtpKdf.label,
buffer1, cbDst);
CHECK(scError == SYMCRYPT_NO_ERROR, "Error in SymCryptSrtpKdfDerive");
ScShimSymCryptMarvin32(ScShimSymCryptMarvin32DefaultSeed, (PCBYTE)&expandedKey, sizeof(expandedKey), expandedKeyChecksum2);
CHECK(memcmp(expandedKeyChecksum1, expandedKeyChecksum2, SYMCRYPT_MARVIN32_RESULT_SIZE) == 0, "SymCryptSrtpKdfDerive modified expanded key");
scError = ScShimSymCryptSrtpKdf(pbKey, cbKey,
pArgs->uSrtpKdf.pbSalt, pArgs->uSrtpKdf.cbSalt,
pArgs->uSrtpKdf.uKeyDerivationRate,
pArgs->uSrtpKdf.uIndex, pArgs->uSrtpKdf.label < 3 ? 48 : 32,
pArgs->uSrtpKdf.label,
buffer2, cbDst);
CHECK(scError == SYMCRYPT_NO_ERROR, "Error in SymCryptSrtpKdf");
CHECK(memcmp(buffer1, buffer2, cbDst) == 0, "SymCrypt SRTP-KDF calling versions disagree");
memcpy(pbDst, buffer1, cbDst);
}
template<>
VOID
algImpDataPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize)
{
ScShimSymCryptSrtpKdfDerive((PCSYMCRYPT_SRTPKDF_EXPANDED_KEY)buf1,
buf2, // pbSalt
112 / 8, // cbSalt
0, // uKeyDerivationRate
0, // uIndex
48, // uIndexWidth
(BYTE)0, // label
buf3, dataSize);
}

Просмотреть файл

@ -0,0 +1,77 @@
//
// Pattern file for the Symcrypt SSH-KDF implementations.
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
template<>
VOID
KdfImp<ImpXxx, AlgSshKdf, BaseAlgXxx>::derive(
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_ PKDF_ARGUMENTS pArgs,
_Out_writes_(cbDst) PBYTE pbDst,
SIZE_T cbDst)
{
SYMCRYPT_ERROR scError;
SYMCRYPT_SSHKDF_EXPANDED_KEY expandedKey;
BYTE buffer1[1024];
BYTE buffer2[sizeof(buffer1)];
BYTE expandedKeyChecksum1[SYMCRYPT_MARVIN32_RESULT_SIZE];
BYTE expandedKeyChecksum2[SYMCRYPT_MARVIN32_RESULT_SIZE];
CHECK(cbDst <= sizeof(buffer1), "SSH-KDF output too large");
switch (pArgs->argType)
{
case KdfArgumentSshKdf:
break;
default:
CHECK(FALSE, "Unknown argument type for SSH-KDF");
return;
}
scError = ScShimSymCryptSshKdfExpandKey(&expandedKey, pArgs->uSshKdf.hash, pbKey, cbKey);
CHECK(scError == SYMCRYPT_NO_ERROR, "Error in SymCryptSshKdfExpandKey");
ScShimSymCryptMarvin32(ScShimSymCryptMarvin32DefaultSeed, (PCBYTE)&expandedKey, sizeof(expandedKey), expandedKeyChecksum1);
scError = ScShimSymCryptSshKdfDerive(&expandedKey,
pArgs->uSshKdf.pbHashValue, pArgs->uSshKdf.cbHashValue,
pArgs->uSshKdf.label,
pArgs->uSshKdf.pbSessionId, pArgs->uSshKdf.cbSessionId,
buffer1, cbDst);
CHECK(scError == SYMCRYPT_NO_ERROR, "Error in SymCryptSshKdfDerive");
ScShimSymCryptMarvin32(ScShimSymCryptMarvin32DefaultSeed, (PCBYTE)&expandedKey, sizeof(expandedKey), expandedKeyChecksum2);
CHECK(memcmp(expandedKeyChecksum1, expandedKeyChecksum2, SYMCRYPT_MARVIN32_RESULT_SIZE) == 0, "SymCryptSshKdfDerive modified expanded key");
scError = ScShimSymCryptSshKdf(pArgs->uSshKdf.hash,
pbKey, cbKey,
pArgs->uSshKdf.pbHashValue, pArgs->uSshKdf.cbHashValue,
pArgs->uSshKdf.label,
pArgs->uSshKdf.pbSessionId, pArgs->uSshKdf.cbSessionId,
buffer2, cbDst);
CHECK(scError == SYMCRYPT_NO_ERROR, "Error in SymCryptSshKdf");
CHECK(memcmp(buffer1, buffer2, cbDst) == 0, "SymCrypt SSH-KDF calling versions disagree");
memcpy(pbDst, buffer1, cbDst);
}
template<>
VOID
algImpDataPerfFunction<ImpXxx, AlgXxx, BaseAlgXxx>(PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize)
{
PCSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey = (PCSYMCRYPT_SSHKDF_EXPANDED_KEY)buf1;
ScShimSymCryptSshKdfDerive(pExpandedKey,
buf2, pExpandedKey->pHashFunc->resultSize,
(BYTE)SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER,
buf2, pExpandedKey->pHashFunc->resultSize,
buf3, dataSize);
}

Просмотреть файл

@ -257,6 +257,13 @@ addSymCryptImplementationToGlobalList()
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgHkdf, AlgHmacSha256>>();
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgHkdf, AlgHmacSha1>>();
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgSshKdf, AlgSha1>>();
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgSshKdf, AlgSha256>>();
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgSshKdf, AlgSha384>>();
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgSshKdf, AlgSha512>>();
addImplementationToGlobalList<KdfImp<ImpScVariant, AlgSrtpKdf, AlgAes>>();
addImplementationToGlobalList<MacImp<ImpScVariant, AlgPoly1305>>();
addImplementationToGlobalList<StreamCipherImp<ImpScVariant, AlgRc4>>();

Просмотреть файл

@ -63,7 +63,10 @@ const SELFTEST_INFO g_selfTests[] =
{&SymCryptParallelSha256Selftest, "ParallelSha256" },
{&SymCryptParallelSha384Selftest, "ParallelSha384" },
{&SymCryptParallelSha512Selftest, "ParallelSha512" },
{&SymCryptSrtpKdfSelfTest, "SrtpKdf" },
{&SymCryptSshKdfSha256SelfTest, "SshKdfSha256" },
{&SymCryptSshKdfSha512SelfTest, "SshKdfSha512" },
{NULL, NULL},
};

Просмотреть файл

@ -418,6 +418,147 @@ testKdfKats()
continue;
}
if (katIsFieldPresent(katItem, "session_id"))
{
args.argType = KdfArgumentSshKdf;
CHECK3(katItem.dataItems.size() == 14, "Incorrect number of fields in SSH-KDF record in line %lld", line);
BString hashName = katParseData(katItem, "hash");
// The following fields are not used.
// We use the size of the data fields from the test vector..
//SIZE_T cbSharedSecret = katParseInteger(katItem, "shared secret length");
//SIZE_T cbIVLength = katParseInteger(katItem, "iv length");
//SIZE_T cbEncryptionKeyLength = katParseInteger(katItem, "encryption key length");
BString SharedKey = katParseData(katItem, "k");
BString HashValue = katParseData(katItem, "h");
BString SessionId = katParseData(katItem, "session_id");
args.uSshKdf.pbHashValue = HashValue.data();
args.uSshKdf.cbHashValue = HashValue.size();
args.uSshKdf.pbSessionId = SessionId.data();
args.uSshKdf.cbSessionId = SessionId.size();
args.uSshKdf.hash = nullptr;
if (!strcmp((const char*)hashName.c_str(), "SHA-1"))
{
args.uSshKdf.hash = SymCryptSha1Algorithm;
}
else if (!strcmp((const char*)hashName.c_str(), "SHA-256"))
{
args.uSshKdf.hash = SymCryptSha256Algorithm;
}
else if (!strcmp((const char*)hashName.c_str(), "SHA-384"))
{
args.uSshKdf.hash = SymCryptSha384Algorithm;
}
else if (!strcmp((const char*)hashName.c_str(), "SHA-512"))
{
args.uSshKdf.hash = SymCryptSha512Algorithm;
}
CHECK3(args.uSshKdf.hash != nullptr, "Invalid hash function for SSH-KDF record in line %lld", line);
BString katInitialIV_ClientToServer = katParseData(katItem, "initial iv (client to server)");
BString katInitialIV_ServerToClient = katParseData(katItem, "initial iv (server to client)");
BString katEncryptionKey_ClientToServer = katParseData(katItem, "encryption key (client to server)");
BString katEncryptionKey_ServerToClient = katParseData(katItem, "encryption key (server to client)");
BString katIntegrityKey_ClientToServer = katParseData(katItem, "integrity key (client to server)");
BString katIntegrityKey_ServerToClient = katParseData(katItem, "integrity key (server to client)");
args.uSshKdf.label = SYMCRYPT_SSHKDF_IV_CLIENT_TO_SERVER;
katKdfSingle(pKdfMultiImp.get(), SharedKey.data(), SharedKey.size(), &args, katInitialIV_ClientToServer.data(), katInitialIV_ClientToServer.size(), line);
args.uSshKdf.label = SYMCRYPT_SSHKDF_IV_SERVER_TO_CLIENT;
katKdfSingle(pKdfMultiImp.get(), SharedKey.data(), SharedKey.size(), &args, katInitialIV_ServerToClient.data(), katInitialIV_ServerToClient.size(), line);
args.uSshKdf.label = SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER;
katKdfSingle(pKdfMultiImp.get(), SharedKey.data(), SharedKey.size(), &args, katEncryptionKey_ClientToServer.data(), katEncryptionKey_ClientToServer.size(), line);
args.uSshKdf.label = SYMCRYPT_SSHKDF_ENCRYPTION_KEY_SERVER_TO_CLIENT;
katKdfSingle(pKdfMultiImp.get(), SharedKey.data(), SharedKey.size(), &args, katEncryptionKey_ServerToClient.data(), katEncryptionKey_ServerToClient.size(), line);
args.uSshKdf.label = SYMCRYPT_SSHKDF_INTEGRITY_KEY_CLIENT_TO_SERVER;
katKdfSingle(pKdfMultiImp.get(), SharedKey.data(), SharedKey.size(), &args, katIntegrityKey_ClientToServer.data(), katIntegrityKey_ClientToServer.size(), line);
args.uSshKdf.label = SYMCRYPT_SSHKDF_INTEGRITY_KEY_SERVER_TO_CLIENT;
katKdfSingle(pKdfMultiImp.get(), SharedKey.data(), SharedKey.size(), &args, katIntegrityKey_ServerToClient.data(), katIntegrityKey_ServerToClient.size(), line);
continue;
}
if (katIsFieldPresent(katItem, "srtp k_e"))
{
args.argType = KdfArgumentSrtpKdf;
CHECK3(katItem.dataItems.size() == 12, "Incorrect number of fields in SRTP-KDF record in line %lld", line);
BString k_master = katParseData(katItem, "k_master");
BString master_salt = katParseData(katItem, "master_salt");
BString kdr = katParseData(katItem, "kdr");
BString index = katParseData(katItem, "index");
BString indexSRTCP = katParseData(katItem, "index (srtcp)");
args.uSrtpKdf.pbSalt = master_salt.data();
args.uSrtpKdf.cbSalt = master_salt.size();
args.uSrtpKdf.uKeyDerivationRate = 0;
for (auto x : kdr)
{
args.uSrtpKdf.uKeyDerivationRate <<= 8;
args.uSrtpKdf.uKeyDerivationRate |= x;
}
BString katSRTPk_e = katParseData(katItem, "srtp k_e");
BString katSRTPk_a = katParseData(katItem, "srtp k_a");
BString katSRTPk_s = katParseData(katItem, "srtp k_s");
BString katSRTCPk_e = katParseData(katItem, "srtcp k_e");
BString katSRTCPk_a = katParseData(katItem, "srtcp k_a");
BString katSRTCPk_s = katParseData(katItem, "srtcp k_s");
{
args.uSrtpKdf.uIndexWidth = 48;
args.uSrtpKdf.uIndex = 0;
for (auto x : index)
{
args.uSrtpKdf.uIndex <<= 8;
args.uSrtpKdf.uIndex |= x;
}
args.uSrtpKdf.label = SYMCRYPT_SRTP_ENCRYPTION_KEY;
katKdfSingle(pKdfMultiImp.get(), k_master.data(), k_master.size(), &args, katSRTPk_e.data(), katSRTPk_e.size(), line);
args.uSrtpKdf.label = SYMCRYPT_SRTP_AUTHENTICATION_KEY;
katKdfSingle(pKdfMultiImp.get(), k_master.data(), k_master.size(), &args, katSRTPk_a.data(), katSRTPk_a.size(), line);
args.uSrtpKdf.label = SYMCRYPT_SRTP_SALTING_KEY;
katKdfSingle(pKdfMultiImp.get(), k_master.data(), k_master.size(), &args, katSRTPk_s.data(), katSRTPk_s.size(), line);
}
{
args.uSrtpKdf.uIndexWidth = 32;
args.uSrtpKdf.uIndex = 0;
for (auto x : indexSRTCP)
{
args.uSrtpKdf.uIndex <<= 8;
args.uSrtpKdf.uIndex |= x;
}
args.uSrtpKdf.label = SYMCRYPT_SRTCP_ENCRYPTION_KEY;
katKdfSingle(pKdfMultiImp.get(), k_master.data(), k_master.size(), &args, katSRTCPk_e.data(), katSRTCPk_e.size(), line);
args.uSrtpKdf.label = SYMCRYPT_SRTCP_AUTHENTICATION_KEY;
katKdfSingle(pKdfMultiImp.get(), k_master.data(), k_master.size(), &args, katSRTCPk_a.data(), katSRTCPk_a.size(), line);
args.uSrtpKdf.label = SYMCRYPT_SRTCP_SALTING_KEY;
katKdfSingle(pKdfMultiImp.get(), k_master.data(), k_master.size(), &args, katSRTCPk_s.data(), katSRTCPk_s.size(), line);
}
continue;
}
FATAL2( "Unknown data record at line %lld", line );
}

Просмотреть файл

@ -372,6 +372,15 @@ EXPORTS
SymCryptTlsPrf1_2Derive
SymCryptTlsPrf1_2ExpandKey
SymCryptTlsPrf1_2SelfTest
SymCryptSrtpKdf
SymCryptSrtpKdfExpandKey
SymCryptSrtpKdfDerive
SymCryptSrtpKdfSelfTest
SymCryptSshKdf
SymCryptSshKdfExpandKey
SymCryptSshKdfDerive
SymCryptSshKdfSha256SelfTest
SymCryptSshKdfSha512SelfTest
SymCryptUint32Bitsize
SymCryptUint32Bytesize
SymCryptUint64Bitsize