forked from microsoft/SymCrypt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcshake_pattern.c
149 lines (130 loc) · 4.92 KB
/
cshake_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
//
// cshake_pattern.c
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
//
// This source file implements cSHAKE128 and cSHAKE256
//
// See the symcrypt.h file for documentation on what the various functions do.
//
//
// SymCryptCShake
//
VOID
SYMCRYPT_CALL
SYMCRYPT_Xxx(
_In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,
SIZE_T cbFunctionNameString,
_In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,
SIZE_T cbCustomizationString,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult,
SIZE_T cbResult)
{
SYMCRYPT_XXX_STATE state;
SYMCRYPT_XxxInit(&state,
pbFunctionNameString, cbFunctionNameString,
pbCustomizationString, cbCustomizationString);
SYMCRYPT_XxxAppend(&state, pbData, cbData);
SYMCRYPT_XxxExtract(&state, pbResult, cbResult, TRUE);
}
//
// SymCryptCShakeInit
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxInit(
_Out_ PSYMCRYPT_XXX_STATE pState,
_In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,
SIZE_T cbFunctionNameString,
_In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,
SIZE_T cbCustomizationString)
{
C_ASSERT( sizeof(SYMCRYPT_XXX_STATE) == sizeof(SYMCRYPT_SHAKEXXX_STATE) );
SYMCRYPT_SHAKEXXX_INIT( (SYMCRYPT_SHAKEXXX_STATE*)pState );
// Perform cSHAKE processing of input strings when any of the input strings is non-empty
if (cbFunctionNameString != 0 || cbCustomizationString != 0)
{
// cSHAKE and SHAKE have different paddings. pState->paddingValue
// is set to SYMCRYPT_SHAKE_PADDING_VALUE in the SHAKE initialization above.
// We update the padding value here because at least one of the input strings
// is non-empty and cSHAKE will not default to SHAKE.
pState->ks.paddingValue = SYMCRYPT_CSHAKE_PADDING_VALUE;
SymCryptCShakeEncodeInputStrings(&pState->ks,
pbFunctionNameString, cbFunctionNameString,
pbCustomizationString, cbCustomizationString);
}
SYMCRYPT_SET_MAGIC(pState);
}
//
// SymCryptCShakeAppend
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxAppend(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData )
{
// Fixing of the padding value
//
// SymCryptKeccakAppend will reset the state, switch to absorb mode,
// and append data to the empty state if the state was in squeeze mode
// when Append is called. This behavior is equivalent to initializing
// cSHAKE with empty input strings, which makes cSHAKE a SHAKE instance.
//
// cSHAKE and SHAKE have different paddings, so we have to update the
// padding value in case it was cSHAKE padding before.
if (pState->ks.squeezeMode)
{
pState->ks.paddingValue = SYMCRYPT_SHAKE_PADDING_VALUE;
}
SymCryptKeccakAppend(&pState->ks, pbData, cbData);
}
//
// SymCryptCShakeExtract
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxExtract(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_Out_writes_(cbResult) PBYTE pbResult,
SIZE_T cbResult,
BOOLEAN bWipe)
{
SymCryptKeccakExtract(&pState->ks, pbResult, cbResult, bWipe);
if (bWipe)
{
// If the state was wiped, set the state as if cSHAKE was initialized
// with empty strings, which is equivalent to empty SHAKE state.
// We have no way to store the Function Name string and Customization
// string information to go back to the initial cSHAKE state.
pState->ks.paddingValue = SYMCRYPT_SHAKE_PADDING_VALUE;
}
}
//
// SymCryptCShakeResult
//
VOID
SYMCRYPT_CALL
SYMCRYPT_XxxResult(
_Inout_ PSYMCRYPT_XXX_STATE pState,
_Out_writes_( SYMCRYPT_CSHAKEXXX_RESULT_SIZE ) PBYTE pbResult)
{
SymCryptKeccakExtract(&pState->ks, pbResult, SYMCRYPT_CSHAKEXXX_RESULT_SIZE, TRUE);
// Revert to cSHAKE initialized with empty strings state, i.e., empty SHAKE state
pState->ks.paddingValue = SYMCRYPT_SHAKE_PADDING_VALUE;
}
//
// SymCryptCShakeStateCopy
//
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);
}