Skip to content

Commit bc66c79

Browse files
committed
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
1 parent efbfc1f commit bc66c79

37 files changed

+2890
-14
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
# Version 103.0
2+
3+
- Add SRTP-KDF and SSH-KDF implementations
4+
- Add optimized SHA-2 implementations
5+
- Fix integer truncation issue in 32-bit Linux builds
6+
- Refactor CMake files to simplify build steps and increase flexibility
7+
- Fix bug for SymCryptRsakeyGenerate for encrypt-only keys
8+
- Create and test against simple SymCrypt Windows test module (DLL)
9+
- Remove the module export of g_SymCryptFipsSelftestsPerformed and replace it with SymCryptFipsGetSelftestsPerformed
10+
- Enable SymCrypt unit tests to drive a dynamically-linked module
11+
- Removed Linux embedded module, as generic ARM64 module is the same
12+
- Rejig CPUID logic for VAES and AVX
13+
114
# Version 102.0
215

316
- Breaking change to Asymmetric key generation and import handling, sanitizing flags required for FIPS

inc/symcrypt.h

Lines changed: 238 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,9 @@ SIZE_T
760760
SYMCRYPT_CALL
761761
SymCryptHashInputBlockSize( _In_ PCSYMCRYPT_HASH pHash );
762762

763+
SIZE_T
764+
SYMCRYPT_CALL
765+
SymCryptHashStateSize( _In_ PCSYMCRYPT_HASH pHash );
763766
//
764767
// SymCryptHashStateSize
765768
//
@@ -769,19 +772,9 @@ SymCryptHashInputBlockSize( _In_ PCSYMCRYPT_HASH pHash );
769772
// any Symcrypt-implemented hash state, so sizeof( SYMCRYPT_HASH_STATE ) is always
770773
// large enough to contain a hash state.
771774
//
772-
SIZE_T
773-
SYMCRYPT_CALL
774-
SymCryptHashStateSize( _In_ PCSYMCRYPT_HASH pHash );
775775

776776

777777

778-
//
779-
// SymCryptHash
780-
//
781-
// Compute a hash value using any hash function.
782-
// The number of bytes written to the pbResult buffer is
783-
// min( cbResult, SymCryptHashResultSize( pHash ) )
784-
//
785778
VOID
786779
SYMCRYPT_CALL
787780
SymCryptHash(
@@ -790,6 +783,14 @@ SymCryptHash(
790783
SIZE_T cbData,
791784
_Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,
792785
SIZE_T cbResult );
786+
//
787+
// SymCryptHash
788+
//
789+
// Compute a hash value using any hash function.
790+
// The number of bytes written to the pbResult buffer is
791+
// min( cbResult, SymCryptHashResultSize( pHash ) )
792+
//
793+
793794

794795
VOID
795796
SYMCRYPT_CALL
@@ -805,15 +806,31 @@ SymCryptHashAppend(
805806
_In_reads_( cbData ) PCBYTE pbData,
806807
SIZE_T cbData );
807808

809+
808810
VOID
809811
SYMCRYPT_CALL
810812
SymCryptHashResult(
811813
_In_ PCSYMCRYPT_HASH pHash,
812814
_Inout_updates_bytes_( pHash->stateSize ) PVOID pState,
813815
_Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,
814816
SIZE_T cbResult );
817+
//
818+
// SymCryptHashResult
819+
//
820+
// Finalizes the hash computation by calling the resultFunc member
821+
// of pHash.
822+
// The hash result is produced to an internal buffer and
823+
// the number of bytes written to the pbResult buffer is
824+
// min( cbResult, SymCryptHashResultSize( pHash ) )
815825

816826

827+
VOID
828+
SYMCRYPT_CALL
829+
SymCryptHashStateCopy(
830+
_In_ PCSYMCRYPT_HASH pHash,
831+
_In_reads_(pHash->stateSize) PCVOID pSrc,
832+
_Out_writes_(pHash->stateSize) PVOID pDst);
833+
817834
////////////////////////////////////////////////////////////////////////////
818835
// MD2
819836
//
@@ -3912,6 +3929,217 @@ VOID
39123929
SYMCRYPT_CALL
39133930
SymCryptTlsPrf1_2SelfTest();
39143931

3932+
3933+
////////////////////////////////////////////////////////////////////////////
3934+
// SSH-KDF as specified in RFC 4253 Section 7.2.
3935+
//
3936+
3937+
3938+
// Labels defined in RFC 4253
3939+
#define SYMCRYPT_SSHKDF_IV_CLIENT_TO_SERVER 0x41 // 'A'
3940+
#define SYMCRYPT_SSHKDF_IV_SERVER_TO_CLIENT 0x42 // 'B'
3941+
#define SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER 0x43 // 'C'
3942+
#define SYMCRYPT_SSHKDF_ENCRYPTION_KEY_SERVER_TO_CLIENT 0x44 // 'D'
3943+
#define SYMCRYPT_SSHKDF_INTEGRITY_KEY_CLIENT_TO_SERVER 0x45 // 'E'
3944+
#define SYMCRYPT_SSHKDF_INTEGRITY_KEY_SERVER_TO_CLIENT 0x46 // 'F'
3945+
3946+
3947+
SYMCRYPT_ERROR
3948+
SYMCRYPT_CALL
3949+
SymCryptSshKdfExpandKey(
3950+
_Out_ PSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,
3951+
_In_ PCSYMCRYPT_HASH pHashFunc,
3952+
_In_reads_(cbKey) PCBYTE pbKey,
3953+
SIZE_T cbKey);
3954+
//
3955+
// Process the key using the specified hash function and store the result in
3956+
// SYMCRYPT_SSHKDF_EXPANDED_KEY structure. Once the key is expanded,
3957+
// SymCryptSshKdfDerive can be called multiple times to generate keys for
3958+
// different uses/labels.
3959+
//
3960+
// After all the keys are derived from a particular "shared secret" key,
3961+
// SYMCRYPT_SSHKDF_EXPANDED_KEY structure must be wiped.
3962+
//
3963+
// Parameters:
3964+
// - pExpandedKey : Pointer to a SYMCRYPT_SSHKDF_EXPANDED_KEY structure that
3965+
// will contain the expanded key after the function returns.
3966+
// - pHashFunc : Hash function that will be used in the key derivation.
3967+
// This function is saved in SYMCRYPT_SSHKDF_EXPANDED_KEY
3968+
// so that it is also used by the SymCryptSshKdfDerive function.
3969+
// - pbKey, cbKey : Buffer contatining the secret key for the KDF.
3970+
//
3971+
// Returns SYMCRYPT_NO_ERROR
3972+
//
3973+
3974+
3975+
SYMCRYPT_ERROR
3976+
SYMCRYPT_CALL
3977+
SymCryptSshKdfDerive(
3978+
_In_ PCSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,
3979+
_In_reads_(cbHashValue) PCBYTE pbHashValue,
3980+
SIZE_T cbHashValue,
3981+
BYTE label,
3982+
_In_reads_(cbSessionId) PCBYTE pbSessionId,
3983+
SIZE_T cbSessionId,
3984+
_Inout_updates_(cbOutput) PBYTE pbOutput,
3985+
SIZE_T cbOutput);
3986+
//
3987+
// Derive keys using the expanded key that was initialized with SymCryptSshKdfExpandKey
3988+
// along with other inputs. This function can be called consecutively with varying label
3989+
// values to generate keys for different purposes as defined in the RFC.
3990+
//
3991+
// Parameters:
3992+
// - pExpandedKey : Pointer to a SYMCRYPT_SSHKDF_EXPANDED_KEY structure that is
3993+
// initialized by a prior call to SymCryptSshKdfExpandKey.
3994+
// Must be wiped when SymCryptSshKdfDerive is not going to be called
3995+
// again with the same expanded key.
3996+
// - pbHashValue, cbHashValue : Buffer pointing to "exchange hash" value. cbHashValue must be equal
3997+
// to the output size of the hash function passed to SymCryptSshKdfExpandKey.
3998+
// - label : Label value used to indicate the type of the derived key.
3999+
// - pbSessionId, cbSessionId : Buffer pointing to the session identifier. cbSessionId must be equal
4000+
// to the output size of the hash function passed to SymCryptSshKdfExpandKey.
4001+
// - pbOutput, cbOutput : Buffer to store the derived key. Exactly cbOutput bytes of output will be generated.
4002+
//
4003+
// Returns SYMCRYPT_NO_ERROR
4004+
//
4005+
4006+
4007+
SYMCRYPT_ERROR
4008+
SYMCRYPT_CALL
4009+
SymCryptSshKdf(
4010+
_In_ PCSYMCRYPT_HASH pHashFunc,
4011+
_In_reads_(cbKey) PCBYTE pbKey,
4012+
SIZE_T cbKey,
4013+
_In_reads_(cbHashValue) PCBYTE pbHashValue,
4014+
SIZE_T cbHashValue,
4015+
BYTE label,
4016+
_In_reads_(cbSessionId) PCBYTE pbSessionId,
4017+
SIZE_T cbSessionId,
4018+
_Out_writes_(cbOutput) PBYTE pbOutput,
4019+
SIZE_T cbOutput);
4020+
//
4021+
// This function is a wrapper for using SymCryptSshKdfExpandKey followed by SymCryptSshKdfDerive
4022+
// in order to produce SSH-KDF output.
4023+
//
4024+
// All of the function arguments are forwarded to SymCryptSshKdfExpandKey and SymCryptSshKdfDerive
4025+
// functions, hence the documentation on those functions apply here as well.
4026+
//
4027+
4028+
4029+
VOID
4030+
SYMCRYPT_CALL
4031+
SymCryptSshKdfSha256SelfTest();
4032+
4033+
VOID
4034+
SYMCRYPT_CALL
4035+
SymCryptSshKdfSha512SelfTest();
4036+
4037+
4038+
////////////////////////////////////////////////////////////////////////////
4039+
// SRTP-KDF as specified in RFC 3711 Section 4.3.1.
4040+
//
4041+
4042+
4043+
// Labels defined in RFC 3711
4044+
#define SYMCRYPT_SRTP_ENCRYPTION_KEY 0x00
4045+
#define SYMCRYPT_SRTP_AUTHENTICATION_KEY 0x01
4046+
#define SYMCRYPT_SRTP_SALTING_KEY 0x02
4047+
#define SYMCRYPT_SRTCP_ENCRYPTION_KEY 0x03
4048+
#define SYMCRYPT_SRTCP_AUTHENTICATION_KEY 0x04
4049+
#define SYMCRYPT_SRTCP_SALTING_KEY 0x05
4050+
4051+
4052+
SYMCRYPT_ERROR
4053+
SYMCRYPT_CALL
4054+
SymCryptSrtpKdfExpandKey(
4055+
_Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,
4056+
_In_reads_(cbKey) PCBYTE pbKey,
4057+
SIZE_T cbKey);
4058+
//
4059+
// Process the key and store the result in SYMCRYPT_SRTPKDF_EXPANDED_KEY structure.
4060+
// Once the key is expanded, SymCryptSrtpKdfDerive can be called multiple times to
4061+
// generate keys for different uses/labels.
4062+
//
4063+
// After all the keys are derived from a particular "shared secret" key,
4064+
// SYMCRYPT_SRTPKDF_EXPANDED_KEY structure must be wiped.
4065+
//
4066+
// Parameters:
4067+
// - pExpandedKey : Pointer to a SYMCRYPT_SRTPKDF_EXPANDED_KEY structure that
4068+
// will contain the expanded key after the function returns.
4069+
// - pbKey, cbKey : Buffer contatining the secret key for the KDF. cbKey must be
4070+
// a valid AES key size (16-, 24-, or 32-bytes).
4071+
//
4072+
// Returns:
4073+
// SYMCRYPT_WRONG_KEY_SIZE : If cbKey is not a valid AES key size
4074+
// SYMCRYPT_NO_ERROR : On success
4075+
//
4076+
4077+
SYMCRYPT_ERROR
4078+
SYMCRYPT_CALL
4079+
SymCryptSrtpKdfDerive(
4080+
_In_ PCSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,
4081+
_In_reads_(cbSalt) PCBYTE pbSalt,
4082+
SIZE_T cbSalt,
4083+
UINT32 uKeyDerivationRate,
4084+
UINT64 uIndex,
4085+
UINT32 uIndexWidth,
4086+
BYTE label,
4087+
_Out_writes_(cbOutput) PBYTE pbOutput,
4088+
SIZE_T cbOutput);
4089+
//
4090+
// Derive keys using the expanded key that was initialized with SymCryptSrtpKdfExpandKey
4091+
// along with other inputs. This function can be called consecutively with varying label
4092+
// values to generate keys for different purposes as defined in the RFC.
4093+
//
4094+
// Parameters:
4095+
// - pExpandedKey : Pointer to a SYMCRYPT_SRTPKDF_EXPANDED_KEY structure that is
4096+
// initialized by a prior call to SymCryptSrtpKdfExpandKey.
4097+
// Must be wiped when SymCryptSrtpKdfDerive is not going to be called
4098+
// again with the same expanded key.
4099+
// - pbSalt, cbSalt : Buffer pointing to the salt value. cbSalt must always be 14 (112-bits).
4100+
// - uKeyDerivationRate : Key derivation rate; must be zero or 2^i for 0 <= i <= 24.
4101+
// - uIndex : Denotes an SRTP index value when label is 0x00, 0x01, or 0x02, otherwise
4102+
// denotes an SRTCP index value.
4103+
// - uIndexWidth : Denotes how wide uIndex value is. Must be one of 0, 32, or 48. By default,
4104+
// (when uIndexWidth = 0) uIndex is treated as 48-bits.
4105+
// RFC 3711 initially defined SRTCP indices to be 32-bit values. It was updated
4106+
// to be 48-bits by Errata ID 3712. SRTP index values are defined to be 48-bits.
4107+
// - label : Label value used to indicate the type of the derived key.
4108+
// - pbOutput, cbOutput : Buffer to store the derived key. Exactly cbOutput bytes of output will be generated.
4109+
//
4110+
// Returns:
4111+
// SYMCRYPT_INVALID_ARGUMENT : If cbSalt is not 14-bytes, or uKeyDerivationRate in invalid.
4112+
// SYMCRYPT_NO_ERROR : On success.
4113+
//
4114+
4115+
4116+
SYMCRYPT_ERROR
4117+
SYMCRYPT_CALL
4118+
SymCryptSrtpKdf(
4119+
_In_reads_(cbKey) PCBYTE pbKey,
4120+
SIZE_T cbKey,
4121+
_In_reads_(cbSalt) PCBYTE pbSalt,
4122+
SIZE_T cbSalt,
4123+
UINT32 uKeyDerivationRate,
4124+
UINT64 uIndex,
4125+
UINT32 uIndexWidth,
4126+
BYTE label,
4127+
_Out_writes_(cbOutput) PBYTE pbOutput,
4128+
SIZE_T cbOutput);
4129+
//
4130+
// This function is a wrapper for using SymCryptSrtpKdfExpandKey followed by SymCryptSrtpKdfDerive
4131+
// in order to produce SRTP-KDF output.
4132+
//
4133+
// All of the function arguments are forwarded to SymCryptSrtpKdfExpandKey and SymCryptSrtpKdfDerive
4134+
// functions, hence the documentation on those functions apply here as well.
4135+
//
4136+
4137+
4138+
VOID
4139+
SYMCRYPT_CALL
4140+
SymCryptSrtpKdfSelfTest();
4141+
4142+
39154143
////////////////////////////////////////////////////////////////////////////
39164144
// HKDF
39174145
//

inc/symcrypt_internal.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,13 +852,15 @@ typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_INIT_FUNC) ( PVOID pSta
852852
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_FUNC) ( PVOID pState, PCBYTE pbData, SIZE_T cbData );
853853
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_RESULT_FUNC) ( PVOID pState, PVOID pbResult );
854854
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC) ( PVOID pChain, PCBYTE pbData, SIZE_T cbData, SIZE_T * pcbRemaining );
855+
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_STATE_COPY_FUNC) ( PCVOID pStateSrc, PVOID pStateDst );
855856

856857
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH
857858
{
858859
PSYMCRYPT_HASH_INIT_FUNC initFunc;
859860
PSYMCRYPT_HASH_APPEND_FUNC appendFunc;
860861
PSYMCRYPT_HASH_RESULT_FUNC resultFunc;
861862
PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC appendBlockFunc;
863+
PSYMCRYPT_HASH_STATE_COPY_FUNC stateCopyFunc;
862864
UINT32 stateSize; // sizeof( hash state )
863865
UINT32 resultSize; // size of hash result
864866
UINT32 inputBlockSize;
@@ -1665,6 +1667,23 @@ typedef struct _SYMCRYPT_TLSPRF1_2_EXPANDED_KEY {
16651667
} SYMCRYPT_TLSPRF1_2_EXPANDED_KEY, *PSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;
16661668
typedef const SYMCRYPT_TLSPRF1_2_EXPANDED_KEY *PCSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;
16671669

1670+
//
1671+
// SSH-KDF
1672+
//
1673+
typedef struct _SYMCRYPT_SSHKDF_EXPANDED_KEY {
1674+
PCSYMCRYPT_HASH pHashFunc;
1675+
SYMCRYPT_HASH_STATE hashState;
1676+
} SYMCRYPT_SSHKDF_EXPANDED_KEY, *PSYMCRYPT_SSHKDF_EXPANDED_KEY;
1677+
typedef const SYMCRYPT_SSHKDF_EXPANDED_KEY *PCSYMCRYPT_SSHKDF_EXPANDED_KEY;
1678+
1679+
//
1680+
// SRTP-KDF
1681+
//
1682+
typedef struct _SYMCRYPT_SRTPKDF_EXPANDED_KEY {
1683+
SYMCRYPT_AES_EXPANDED_KEY aesExpandedKey;
1684+
} SYMCRYPT_SRTPKDF_EXPANDED_KEY, *PSYMCRYPT_SRTPKDF_EXPANDED_KEY;
1685+
typedef const SYMCRYPT_SRTPKDF_EXPANDED_KEY *PCSYMCRYPT_SRTPKDF_EXPANDED_KEY;
1686+
16681687
//
16691688
// HKDF
16701689
//

inc/symcrypt_internal_shared.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// The API numbering starts at 100 to avoid number conficts with the old system.
2323
//
2424
25-
#define SYMCRYPT_CODE_VERSION_API 102
25+
#define SYMCRYPT_CODE_VERSION_API 103
2626
#define SYMCRYPT_CODE_VERSION_MINOR 0
2727
#define SYMCRYPT_CODE_VERSION_PATCH 0
2828

lib/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ set(SOURCES_COMMON
9696
sp800_108_hmacsha256.c
9797
sp800_108_hmacsha512.c
9898
sp800_108.c
99+
srtp_kdf.c
100+
srtp_kdf_selftest.c
101+
ssh_kdf.c
102+
ssh_kdf_sha256.c
103+
ssh_kdf_sha512.c
99104
tlsCbcVerify.c
100105
tlsprf_selftest.c
101106
tlsprf.c

lib/hash.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,13 @@ SymCryptHashResult(
205205
SymCryptWipe( buf, pHash->resultSize );
206206
}
207207

208+
VOID
209+
SYMCRYPT_CALL
210+
SymCryptHashStateCopy(
211+
_In_ PCSYMCRYPT_HASH pHash,
212+
_In_reads_( pHash->stateSize ) PCVOID pSrc,
213+
_Out_writes_( pHash->stateSize ) PVOID pDst)
214+
{
215+
(*pHash->stateCopyFunc)( pSrc, pDst );
216+
}
208217

lib/md2.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const SYMCRYPT_HASH SymCryptMd2Algorithm_default = {
2929
&SymCryptMd2Append,
3030
&SymCryptMd2Result,
3131
&SymCryptMd2AppendBlocks,
32+
&SymCryptMd2StateCopy,
3233
sizeof( SYMCRYPT_MD2_STATE ),
3334
SYMCRYPT_MD2_RESULT_SIZE,
3435
SYMCRYPT_MD2_INPUT_BLOCK_SIZE,

0 commit comments

Comments
 (0)