forked from microsoft/SymCrypt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkmac_pattern.c
215 lines (187 loc) · 6.14 KB
/
kmac_pattern.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//
// kmac_pattern.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
//
// This source file implements KMAC128 and KMAC256
//
// See the symcrypt.h file for documentation on what the various functions do.
//
//
// SymCryptKmac
//
VOID
SYMCRYPT_CALL
SYMCRYPT_Xxx(
_In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,
_In_reads_bytes_( cbInput ) PCBYTE pbInput,
SIZE_T cbInput,
_Out_writes_bytes_( SYMCRYPT_KMACXXX_RESULT_SIZE ) PBYTE pbResult)
{
SYMCRYPT_XXX_STATE state;
SYMCRYPT_XxxInit(&state, pExpandedKey);
SYMCRYPT_XxxAppend(&state, pbInput, cbInput);
SYMCRYPT_XxxResult(&state, pbResult);
}
//
// SymCryptKmacEx
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxEx(
_In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,
_In_reads_bytes_( cbInput ) PCBYTE pbInput,
SIZE_T cbInput,
_Out_writes_bytes_( cbResult ) PBYTE pbResult,
SIZE_T cbResult)
{
SYMCRYPT_XXX_STATE state;
SYMCRYPT_XxxInit(&state, pExpandedKey);
SYMCRYPT_XxxAppend(&state, pbInput, cbInput);
SYMCRYPT_XxxResultEx(&state, pbResult, cbResult);
}
//
// SymCryptKmacExpandKey
//
SYMCRYPT_ERROR
SYMCRYPT_CALL
SYMCRYPT_XxxExpandKey(
_Out_ PSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,
_In_reads_bytes_(cbKey) PCBYTE pbKey,
SIZE_T cbKey)
{
return SYMCRYPT_XxxExpandKeyEx(pExpandedKey, pbKey, cbKey, NULL, 0);
}
//
// SymCryptKmacExpandKeyEx
//
SYMCRYPT_ERROR
SYMCRYPT_CALL
SYMCRYPT_XxxExpandKeyEx(
_Out_ PSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,
_In_reads_bytes_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_bytes_( cbCustomizationString ) PCBYTE pbCustomizationString,
SIZE_T cbCustomizationString)
{
static const BYTE nameString[] = { 0x4b, 0x4d, 0x41, 0x43 }; // "KMAC"
C_ASSERT( sizeof(SYMCRYPT_XXX_EXPANDED_KEY) == sizeof(SYMCRYPT_CSHAKEXXX_STATE) );
SYMCRYPT_CSHAKEXXX_INIT( (SYMCRYPT_CSHAKEXXX_STATE*)pExpandedKey, nameString, sizeof(nameString), pbCustomizationString, cbCustomizationString);
SYMCRYPT_KECCAK_STATE* pks = &pExpandedKey->ks;
// byte_pad( encode_string( K ) )
SymCryptKeccakAppendEncodeTimes8(pks, pks->inputBlockSize / 8, TRUE);
SymCryptKeccakAppendEncodedString(pks, pbKey, cbKey);
if (pks->stateIndex != 0)
{
SymCryptKeccakZeroAppendBlock(pks);
}
return SYMCRYPT_NO_ERROR;
}
//
// SymCryptKmacInit
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxInit(
_Out_ PSYMCRYPT_XXX_STATE pState,
_In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey)
{
C_ASSERT(sizeof(*pState) == sizeof(*pExpandedKey));
SYMCRYPT_CHECK_MAGIC(pExpandedKey);
memcpy(pState, pExpandedKey, sizeof(*pState));
SYMCRYPT_SET_MAGIC(pState);
}
//
// SymCryptKmacAppend
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxAppend(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData )
{
SYMCRYPT_ASSERT(!pState->ks.squeezeMode);
SymCryptKeccakAppend(&pState->ks, pbData, cbData);
}
//
// SymCryptKmacExtract
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxExtract(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_Out_writes_( cbOutput ) PBYTE pbOutput,
SIZE_T cbOutput,
BOOLEAN bWipe)
{
// This function uses KMAC in XOF mode.
//
// If this is the first time Extract is being called, append right_encode(0)
// to indicate that we're in XOF mode. This padding will be applied only once
// as SymCryptKeccakExtract will transition the state to squeeze mode.
if (!pState->ks.squeezeMode)
{
SymCryptKeccakAppendEncodeTimes8(&pState->ks, 0, FALSE);
}
SymCryptKeccakExtract(&pState->ks, pbOutput, cbOutput, bWipe);
}
//
// SymCryptKmacResult
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxResult(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_Out_writes_( SYMCRYPT_KMACXXX_RESULT_SIZE ) PBYTE pbOutput)
{
SYMCRYPT_XxxResultEx(pState, pbOutput, SYMCRYPT_KMACXXX_RESULT_SIZE);
}
//
// SymCryptKmacResultEx
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxResultEx(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_Out_writes_( cbOutput ) PBYTE pbOutput,
SIZE_T cbOutput)
{
// Result and ResultEx functions are used to extract data only once.
// KMAC requires the output length to be encoded and appended to the
// end of the input before the state switches to squeeze mode.
//
// If Result or ResultEx is called after an Extract call with bWipe=FALSE,
// this means KMAC was used in XOF mode and length padding has already been
// applied. In this case, Result and ResultEx functions extract data one last
// time in XOF mode and wipe the state afterwards.
if (!pState->ks.squeezeMode)
{
// Append right_encode(L)
SymCryptKeccakAppendEncodeTimes8(&pState->ks, cbOutput, FALSE);
}
SymCryptKeccakExtract(&pState->ks, pbOutput, cbOutput, TRUE);
}
//
// SymCryptKmacKeyCopy
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxKeyCopy(_In_ PCSYMCRYPT_XXX_EXPANDED_KEY pSrc, _Out_ PSYMCRYPT_XXX_EXPANDED_KEY pDst)
{
SYMCRYPT_CHECK_MAGIC(pSrc);
*pDst = *pSrc;
SYMCRYPT_SET_MAGIC(pDst);
}
//
// SymCryptKmacStateCopy
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxStateCopy(_In_ const SYMCRYPT_XXX_STATE* pSrc, _Out_ SYMCRYPT_XXX_STATE* pDst)
{
SYMCRYPT_CHECK_MAGIC(pSrc);
*pDst = *pSrc;
SYMCRYPT_SET_MAGIC(pDst);
}