Coverage Report

Created: 2024-11-21 07:03

/src/SymCrypt/lib/shake.c
Line
Count
Source (jump to first uncovered line)
1
//
2
// Shake.c
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
#include "precomp.h"
8
9
//
10
// See the symcrypt.h file for documentation on what the various functions do.
11
//
12
13
14
15
//
16
//  SHAKE128
17
//
18
#define Alg Shake128
19
#define ALG SHAKE128
20
0
#define SYMCRYPT_SHAKEXXX_INPUT_BLOCK_SIZE      SYMCRYPT_SHAKE128_INPUT_BLOCK_SIZE
21
0
#define SYMCRYPT_SHAKEXXX_RESULT_SIZE           SYMCRYPT_SHAKE128_RESULT_SIZE
22
#include "shake_pattern.c"
23
#undef SYMCRYPT_SHAKEXXX_RESULT_SIZE
24
#undef SYMCRYPT_SHAKEXXX_INPUT_BLOCK_SIZE
25
#undef ALG
26
#undef Alg
27
28
const SYMCRYPT_HASH SymCryptShake128HashAlgorithm_default = {
29
    &SymCryptShake128Init,
30
    &SymCryptShake128Append,
31
    &SymCryptShake128Result,
32
    NULL,                           // AppendBlocks function is not implemented for SHA-3
33
    &SymCryptShake128StateCopy,
34
    sizeof(SYMCRYPT_SHAKE128_STATE),
35
    SYMCRYPT_SHAKE128_RESULT_SIZE,
36
    SYMCRYPT_SHAKE128_INPUT_BLOCK_SIZE,
37
    SYMCRYPT_FIELD_OFFSET(SYMCRYPT_SHAKE128_STATE, ks.state),
38
    SYMCRYPT_FIELD_SIZE(SYMCRYPT_SHAKE128_STATE, ks.state),
39
};
40
41
const PCSYMCRYPT_HASH SymCryptShake128HashAlgorithm = &SymCryptShake128HashAlgorithm_default;
42
43
static const BYTE shake128KATAnswer[SYMCRYPT_SHAKE128_RESULT_SIZE] = {
44
    0x58, 0x81, 0x09, 0x2d, 0xd8, 0x18, 0xbf, 0x5c,
45
    0xf8, 0xa3, 0xdd, 0xb7, 0x93, 0xfb, 0xcb, 0xa7,
46
    0x40, 0x97, 0xd5, 0xc5, 0x26, 0xa6, 0xd3, 0x5f,
47
    0x97, 0xb8, 0x33, 0x51, 0x94, 0x0f, 0x2c ,0xc8
48
};
49
50
VOID
51
SYMCRYPT_CALL
52
SymCryptShake128Selftest(void)
53
0
{
54
0
    BYTE result[SYMCRYPT_SHAKE128_RESULT_SIZE];
55
56
0
    SymCryptShake128(SymCryptTestMsg3, sizeof(SymCryptTestMsg3), result, sizeof(result));
57
58
0
    SymCryptInjectError(result, sizeof(result));
59
60
0
    if (memcmp(result, shake128KATAnswer, sizeof(result)) != 0)
61
0
    {
62
0
        SymCryptFatal('shk1');
63
0
    }
64
0
}
65
66
67
//
68
//  SHAKE256 
69
//
70
#define Alg Shake256
71
#define ALG SHAKE256
72
0
#define SYMCRYPT_SHAKEXXX_INPUT_BLOCK_SIZE      SYMCRYPT_SHAKE256_INPUT_BLOCK_SIZE
73
0
#define SYMCRYPT_SHAKEXXX_RESULT_SIZE           SYMCRYPT_SHAKE256_RESULT_SIZE
74
#include "shake_pattern.c"
75
#undef SYMCRYPT_SHAKEXXX_RESULT_SIZE
76
#undef SYMCRYPT_SHAKEXXX_INPUT_BLOCK_SIZE
77
#undef ALG
78
#undef Alg
79
80
const SYMCRYPT_HASH SymCryptShake256HashAlgorithm_default = {
81
    &SymCryptShake256Init,
82
    &SymCryptShake256Append,
83
    &SymCryptShake256Result,
84
    NULL,                           // AppendBlocks function is not implemented for SHA-3
85
    &SymCryptShake256StateCopy,
86
    sizeof(SYMCRYPT_SHAKE256_STATE),
87
    SYMCRYPT_SHAKE256_RESULT_SIZE,
88
    SYMCRYPT_SHAKE256_INPUT_BLOCK_SIZE,
89
    SYMCRYPT_FIELD_OFFSET(SYMCRYPT_SHAKE256_STATE, ks.state),
90
    SYMCRYPT_FIELD_SIZE(SYMCRYPT_SHAKE256_STATE, ks.state),
91
};
92
93
const PCSYMCRYPT_HASH SymCryptShake256HashAlgorithm = &SymCryptShake256HashAlgorithm_default;
94
95
static const BYTE shake256KATAnswer[SYMCRYPT_SHAKE256_RESULT_SIZE] = {
96
    0x48, 0x33, 0x66, 0x60, 0x13, 0x60, 0xa8, 0x77, 0x1c, 0x68, 0x63, 0x08, 0x0c, 0xc4, 0x11, 0x4d,
97
    0x8d, 0xb4, 0x45, 0x30, 0xf8, 0xf1, 0xe1, 0xee, 0x4f, 0x94, 0xea, 0x37, 0xe7, 0x8b, 0x57, 0x39,
98
    0xd5, 0xa1, 0x5b, 0xef, 0x18, 0x6a, 0x53, 0x86, 0xc7, 0x57, 0x44, 0xc0, 0x52, 0x7e, 0x1f, 0xaa,
99
    0x9f, 0x87, 0x26, 0xe4, 0x62, 0xa1, 0x2a, 0x4f, 0xeb, 0x06, 0xbd, 0x88, 0x01, 0xe7, 0x51, 0xe4
100
};
101
102
VOID
103
SYMCRYPT_CALL
104
SymCryptShake256Selftest(void)
105
0
{
106
0
    BYTE result[SYMCRYPT_SHAKE256_RESULT_SIZE];
107
108
0
    SymCryptShake256(SymCryptTestMsg3, sizeof(SymCryptTestMsg3), result, sizeof(result));
109
110
0
    SymCryptInjectError(result, sizeof(result));
111
112
0
    if (memcmp(result, shake256KATAnswer, sizeof(result)) != 0)
113
0
    {
114
0
        SymCryptFatal('shk2');
115
0
    }
116
0
}
117
118
119
//
120
//  CSHAKE128
121
//
122
#define Alg CShake128
123
#define ALG CSHAKE128
124
0
#define SYMCRYPT_SHAKEXXX_INIT                  SymCryptShake128Init
125
#define SYMCRYPT_SHAKEXXX_STATE                 SYMCRYPT_SHAKE128_STATE
126
#define SYMCRYPT_CSHAKEXXX_INPUT_BLOCK_SIZE     SYMCRYPT_CSHAKE128_INPUT_BLOCK_SIZE
127
0
#define SYMCRYPT_CSHAKEXXX_RESULT_SIZE          SYMCRYPT_CSHAKE128_RESULT_SIZE
128
#include "cshake_pattern.c"
129
#undef SYMCRYPT_CSHAKEXXX_RESULT_SIZE
130
#undef SYMCRYPT_CSHAKEXXX_INPUT_BLOCK_SIZE
131
#undef SYMCRYPT_SHAKEXXX_STATE
132
#undef SYMCRYPT_SHAKEXXX_INIT
133
#undef ALG
134
#undef Alg
135
136
137
static const BYTE cshake128KATAnswer[SYMCRYPT_CSHAKE128_RESULT_SIZE] = {
138
    0x14, 0xe5, 0xdf, 0xf3, 0xae, 0xfd, 0xfe, 0x8e,
139
    0xa6, 0xae, 0xed, 0xfd, 0x99, 0xe6, 0x84, 0x74,
140
    0xbc, 0x61, 0xb9, 0xd6, 0x17, 0x4e, 0x9f, 0x4a,
141
    0xe3, 0xbd, 0x87, 0xdf, 0x0e, 0xf2, 0x16, 0xdb,
142
};
143
144
VOID
145
SYMCRYPT_CALL
146
SymCryptCShake128Selftest(void)
147
0
{
148
0
    BYTE result[SYMCRYPT_CSHAKE128_RESULT_SIZE];
149
0
    static const unsigned char Nstr[] = { 'N' };
150
0
    static const unsigned char Sstr[] = { 'S' };
151
152
0
    SymCryptCShake128(  Nstr, sizeof(Nstr), 
153
0
                        Sstr, sizeof(Sstr), 
154
0
                        SymCryptTestMsg3, sizeof(SymCryptTestMsg3), 
155
0
                        result, sizeof(result));
156
157
0
    SymCryptInjectError(result, sizeof(result));
158
159
0
    if (memcmp(result, cshake128KATAnswer, sizeof(result)) != 0)
160
0
    {
161
0
        SymCryptFatal('cshk');
162
0
    }
163
0
}
164
165
166
//
167
//  CSHAKE256 
168
//
169
#define Alg CShake256
170
#define ALG CSHAKE256
171
0
#define SYMCRYPT_SHAKEXXX_INIT                  SymCryptShake256Init
172
#define SYMCRYPT_SHAKEXXX_STATE                 SYMCRYPT_SHAKE256_STATE
173
#define SYMCRYPT_CSHAKEXXX_INPUT_BLOCK_SIZE     SYMCRYPT_CSHAKE256_INPUT_BLOCK_SIZE
174
0
#define SYMCRYPT_CSHAKEXXX_RESULT_SIZE          SYMCRYPT_CSHAKE256_RESULT_SIZE
175
#include "cshake_pattern.c"
176
#undef SYMCRYPT_CSHAKEXXX_RESULT_SIZE
177
#undef SYMCRYPT_CSHAKEXXX_INPUT_BLOCK_SIZE
178
#undef SYMCRYPT_SHAKEXXX_STATE
179
#undef SYMCRYPT_SHAKEXXX_INIT
180
#undef ALG
181
#undef Alg
182
183
184
static const BYTE cshake256KATAnswer[SYMCRYPT_CSHAKE256_RESULT_SIZE] = {
185
    0x4d, 0xe8, 0x71, 0x6c, 0x4a, 0x16, 0x7e, 0x28, 0x2c, 0x18, 0xc5, 0x1e, 0xed, 0xa6, 0x00, 0xb8,
186
    0x91, 0x92, 0x4f, 0xea, 0x2e, 0x20, 0x7f, 0x71, 0x2c, 0xfd, 0xe2, 0x95, 0xfd, 0x1c, 0x67, 0x32,
187
    0x31, 0x49, 0x98, 0x23, 0xc0, 0x5e, 0x6a, 0xe3, 0x89, 0xad, 0x4d, 0xa2, 0x32, 0x9c, 0xc9, 0x2e,
188
    0x0f, 0xd6, 0x90, 0xb9, 0xee, 0x91, 0x0e, 0x86, 0xf7, 0x1d, 0x03, 0x88, 0xb5, 0x95, 0x61, 0x95
189
};
190
191
VOID
192
SYMCRYPT_CALL
193
SymCryptCShake256Selftest(void)
194
0
{
195
0
    BYTE result[SYMCRYPT_CSHAKE256_RESULT_SIZE];
196
0
    static const unsigned char Nstr[] = { 'N' };
197
0
    static const unsigned char Sstr[] = { 'S' };
198
199
0
    SymCryptCShake256(Nstr, sizeof(Nstr),
200
0
        Sstr, sizeof(Sstr),
201
0
        SymCryptTestMsg3, sizeof(SymCryptTestMsg3),
202
0
        result, sizeof(result));
203
204
0
    SymCryptInjectError(result, sizeof(result));
205
206
0
    if (memcmp(result, cshake256KATAnswer, sizeof(result)) != 0)
207
0
    {
208
0
        SymCryptFatal('cshk');
209
0
    }
210
0
}
211
212
//
213
// CShake helper functions
214
//
215
216
//
217
// SymCryptCShakeEncodeInputStrings
218
//
219
VOID
220
SYMCRYPT_CALL
221
SymCryptCShakeEncodeInputStrings(
222
    _Inout_                             PSYMCRYPT_KECCAK_STATE  pState,
223
    _In_reads_( cbFunctionNameString )  PCBYTE                  pbFunctionNameString,
224
                                        SIZE_T                  cbFunctionNameString,
225
    _In_reads_( cbCustomizationString ) PCBYTE                  pbCustomizationString,
226
                                        SIZE_T                  cbCustomizationString)
227
0
{
228
0
    SYMCRYPT_ASSERT((cbFunctionNameString > 0) || (cbCustomizationString > 0));
229
230
    // left_encode( inputBlockSize ) for byte_pad function
231
    //
232
    // SymCryptKeccakEncodeTimes8 function encodes 8 times the value passed to 
233
    // it. Here, we want the actual value of pState->inputBlockSize to be encoded,
234
    // hence the division by 8.
235
0
    SymCryptKeccakAppendEncodeTimes8(pState, pState->inputBlockSize / 8, TRUE);
236
237
0
    SymCryptKeccakAppendEncodedString(pState, pbFunctionNameString, cbFunctionNameString);
238
0
    SymCryptKeccakAppendEncodedString(pState, pbCustomizationString, cbCustomizationString);
239
    
240
    // Appending of Customization String may have already called the permutation
241
    // if the appended data is aligned to input block size, in which case the zero
242
    // padding has been done.
243
0
    if (pState->stateIndex != 0)
244
0
    {
245
0
        SymCryptKeccakZeroAppendBlock(pState);
246
0
    }
247
0
}
248
249
//
250
// SymCryptKeccakEncodeTimes8
251
//
252
SIZE_T
253
SYMCRYPT_CALL
254
SymCryptKeccakEncodeTimes8(
255
                            UINT64  uInput,
256
    _Out_writes_(cbOutput)  PBYTE   pbOutput,
257
                            SIZE_T  cbOutput,
258
                            BOOLEAN bLeftEncode)
259
0
{
260
0
    BYTE encoding[1 + sizeof(UINT64)];
261
0
    SIZE_T ret = 0;
262
    
263
    // longest encoding is 1 byte for length + 9 bytes for uInput * 8
264
0
    SYMCRYPT_ASSERT(cbOutput >= (1 + sizeof(encoding)));
265
0
    UNREFERENCED_PARAMETER(cbOutput);
266
267
    //
268
    // encoding[0] .. encoding[8] will contain (uInput * 8) in big endian form
269
0
    encoding[0] = (BYTE)(uInput >> 61);
270
0
    SYMCRYPT_STORE_MSBFIRST64(&encoding[1], uInput * 8);
271
272
0
    SIZE_T length = 1;                              // number of bytes required to encode uInput
273
0
    PCBYTE pbMsb = &encoding[sizeof(encoding) - 1]; // pointer to the most significant byte
274
275
    // Locate the most significant non-zero byte
276
0
    for (int i = 0; i < sizeof(encoding); i++)
277
0
    {
278
        // Do not early terminate on the most significant byte
279
0
        if (encoding[i] != 0 && length == 1)
280
0
        {
281
0
            length = sizeof(encoding) - i;
282
0
            pbMsb = &encoding[i];
283
0
        }
284
0
    }
285
286
0
    ret = 1 + length;
287
288
0
    if (bLeftEncode)
289
0
    {
290
        // length for left_encode
291
0
        *pbOutput++ = (BYTE)length;
292
0
    }
293
294
0
    memcpy(pbOutput, pbMsb, length);
295
296
0
    if(!bLeftEncode)
297
0
    {
298
        // length for right_encode
299
0
        pbOutput[length] = (BYTE)length;
300
0
    }
301
302
0
    return ret; // total number of bytes written to pbOutput
303
0
}
304
305
//
306
// SymCryptKeccakAppendEncodeTimes8
307
//
308
VOID
309
SYMCRYPT_CALL
310
SymCryptKeccakAppendEncodeTimes8(
311
    _Inout_ SYMCRYPT_KECCAK_STATE *pState,
312
            UINT64  uValue,
313
            BOOLEAN bLeftEncode)
314
315
0
{
316
0
    BYTE encoding[1 + (1 + sizeof(UINT64))];
317
0
    SIZE_T ret;
318
319
0
    ret = SymCryptKeccakEncodeTimes8(uValue, encoding, sizeof(encoding), bLeftEncode);
320
321
0
    SymCryptKeccakAppend(pState, encoding, ret);
322
0
}
323
324
325
//
326
// SymCryptKeccakAppendEncodedString
327
//
328
VOID
329
SYMCRYPT_CALL
330
SymCryptKeccakAppendEncodedString(
331
    _Inout_                 PSYMCRYPT_KECCAK_STATE  pState,
332
    _In_reads_(cbString)    PCBYTE                  pbString,
333
                            SIZE_T                  cbString)
334
0
{
335
0
    SymCryptKeccakAppendEncodeTimes8(pState, cbString, TRUE);
336
0
    SymCryptKeccakAppend(pState, pbString, cbString);
337
0
}
338