ReactOS 0.4.17-dev-1005-g171e1de
srtp_kdf.c File Reference
#include "precomp.h"
Include dependency graph for srtp_kdf.c:

Go to the source code of this file.

Macros

#define SYMCRYPT_SRTP_KDF_SALT_SIZE   (112 / 8)
 

Functions

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSrtpKdfExpandKey (_Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T 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 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)
 

Macro Definition Documentation

◆ SYMCRYPT_SRTP_KDF_SALT_SIZE

#define SYMCRYPT_SRTP_KDF_SALT_SIZE   (112 / 8)

Definition at line 14 of file srtp_kdf.c.

Function Documentation

◆ SymCryptSrtpKdf()

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 
)

Definition at line 141 of file srtp_kdf.c.

152{
153 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
155
156 scError = SymCryptSrtpKdfExpandKey(&expandedKey, pbKey, cbKey);
157
158 if (scError != SYMCRYPT_NO_ERROR)
159 {
160 goto cleanup;
161 }
162
163 scError = SymCryptSrtpKdfDerive(&expandedKey,
164 pbSalt, cbSalt,
165 uKeyDerivationRate,
166 uIndex, uIndexWidth,
167 label,
168 pbOutput, cbOutput);
169
170cleanup:
171
172 SymCryptWipeKnownSize(&expandedKey, sizeof(expandedKey));
173
174 return scError;
175}
static void cleanup(void)
Definition: main.c:1335
static const WCHAR label[]
Definition: itemdlg.c:1608
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSrtpKdfExpandKey(_Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
Definition: srtp_kdf.c:20
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)
Definition: srtp_kdf.c:31
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
SYMCRYPT_ERROR
Definition: symcrypt.h:227
PCBYTE pbKey
PCBYTE SIZE_T cbKey

◆ SymCryptSrtpKdfDerive()

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 
)

Definition at line 31 of file srtp_kdf.c.

41{
42 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
43 BYTE X[16] = { 0 };
44
45 //
46 // uIndexWidth must be one of 0, 32 or 48. RFC 3711 defines SRTP indices to be
47 // 48-bits. SRTCP indices were first specified as 32-bit values and then updated to
48 // 48-bits by Errata ID 3712. uIndexWidth parameter allows specifying the width of
49 // the uIndex parameter for both SRTP and SRTCP indices. The test vectors use
50 // 32-bit SRTCP index values.
51 //
52 // The default value of 0 is equivalent to setting uIndexWidth to 48.
53 if (uIndexWidth == 0)
54 {
55 uIndexWidth = 48;
56 }
57 else if (uIndexWidth != 32 && uIndexWidth != 48)
58 {
59 scError = SYMCRYPT_INVALID_ARGUMENT;
60 goto cleanup;
61 }
62
63 if (cbSalt != SYMCRYPT_SRTP_KDF_SALT_SIZE)
64 {
65 scError = SYMCRYPT_INVALID_ARGUMENT;
66 goto cleanup;
67 }
68
69 // uKeyDerivationRate must be zero or 2^i for 0 <= i <= 24.
70 // This is verified by checking both it is not greater than 2^24 and it is either zero or a power of two.
71 if( (uKeyDerivationRate > (1 << 24)) || ((uKeyDerivationRate & (uKeyDerivationRate - 1)) != 0) )
72 {
73 scError = SYMCRYPT_INVALID_ARGUMENT;
74 goto cleanup;
75 }
76
77 // Initialize X to Salt || 0
78 memcpy(X, pbSalt, cbSalt);
79
80 // (uIndex DIV uKeyDerivationRate) operation can be performed with a right shift as
81 // uKeyDerivationRate is either zero or a power of 2. When uKeyDerivationRate is zero,
82 // DIV operation should evaluate to zero, which can be performed by shifting uIndex by 48 bits,
83 // i.e., maximum value it may have.
84 UINT32 kdrShift = 48;
85 if (uKeyDerivationRate)
86 {
87 for (UINT32 i = 0; i <= 24; i++)
88 {
89 if (uKeyDerivationRate == (1UL << i))
90 {
91 kdrShift = i;
92 break;
93 }
94 }
95 }
96
97 UINT64 r = uIndex >> kdrShift;
98
99 UINT64 key_id = ((UINT64)label << uIndexWidth) | r;
100
101 // XOR key_id into salt
102 //
103 // X = S0 ... |S6 ... S13| 0 0
104 // | key_id |
105 //
106 PBYTE pbXorPos = &X[SYMCRYPT_SRTP_KDF_SALT_SIZE - sizeof(key_id)];
107 UINT64 uSaltLsb = SYMCRYPT_LOAD_MSBFIRST64(pbXorPos);
108 SYMCRYPT_STORE_MSBFIRST64(pbXorPos, uSaltLsb ^ key_id);
109
110 //
111 // We break the read-once/write once rule here by writing to the pbOutput buffer twice.
112 // The first write wipes the buffer so that we get the raw keystream bytes from AES-CTR encryption.
113 // The second write to pbOutput occurs with the SymCryptAesCtrMsb64() call that produces the keystream bytes.
114 //
115 // Modification of pbOutput between the two calls does not leak any information, it just results in flipping of the
116 // corresponding bits of the correct output.
117 SymCryptWipe(pbOutput, cbOutput);
118 SymCryptAesCtrMsb64(&pExpandedKey->aesExpandedKey, X, pbOutput, pbOutput, cbOutput & ~0xf);
119
120 // SymCryptAesCtrMsb64 only processes full blocks. If cbOutput is not a multiple of 16 we generate the last block of
121 // keystream to local buffer and copy the necessary number of bytes to output.
122 if (cbOutput & 0xf)
123 {
124 BYTE lastBlockBytes[16] = { 0 };
125
126 SymCryptAesCtrMsb64(&pExpandedKey->aesExpandedKey, X, lastBlockBytes, lastBlockBytes, 16);
127
128 memcpy(pbOutput + 16 * (cbOutput / 16), lastBlockBytes, cbOutput & 0xf);
129
130 SymCryptWipeKnownSize(lastBlockBytes, sizeof(lastBlockBytes));
131 }
132
133cleanup:
134
135 return scError;
136}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BYTE * PBYTE
Definition: pedump.c:66
#define SYMCRYPT_SRTP_KDF_SALT_SIZE
Definition: srtp_kdf.c:14
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_LOAD_MSBFIRST64(p)
Definition: symcrypt.h:304
VOID SYMCRYPT_CALL SymCryptAesCtrMsb64(_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey, _Inout_updates_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pbChainingValue, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: aes-default.c:404
#define SYMCRYPT_STORE_MSBFIRST64(p, v)
Definition: symcrypt.h:312
PCVOID pExpandedKey
uint32_t UINT32
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193

Referenced by SymCryptSrtpKdf().

◆ SymCryptSrtpKdfExpandKey()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSrtpKdfExpandKey ( _Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY  pExpandedKey,
_In_reads_(cbKey) PCBYTE  pbKey,
SIZE_T  cbKey 
)

Definition at line 20 of file srtp_kdf.c.

24{
26}
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptAesExpandKeyEncryptOnly(_Out_ PSYMCRYPT_AES_EXPANDED_KEY pExpandedKey, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
Definition: aes-key.c:230

Referenced by SymCryptSrtpKdf().