Coverage Report

Created: 2024-09-11 06:39

/src/trezor-firmware/crypto/sha3.c
Line
Count
Source (jump to first uncovered line)
1
/* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
2
 * based on the
3
 * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
4
 * by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche
5
 *
6
 * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
7
 *
8
 * Permission is hereby granted,  free of charge,  to any person  obtaining a
9
 * copy of this software and associated documentation files (the "Software"),
10
 * to deal in the Software without restriction,  including without limitation
11
 * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
12
 * and/or sell copies  of  the Software,  and to permit  persons  to whom the
13
 * Software is furnished to do so.
14
 *
15
 * This program  is  distributed  in  the  hope  that it will be useful,  but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17
 * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
18
 */
19
20
#include <assert.h>
21
#include <string.h>
22
23
#include "sha3.h"
24
#include "memzero.h"
25
#include "byte_order.h"
26
27
#define I64(x) x##LL
28
22.3M
#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
29
545k
#define le2me_64(x) (x)
30
31.0k
#define IS_ALIGNED_64(p) (0 == (((uintptr_t)(const void *)(p) & 0x7)))
31
398
# define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
32
33
/* constants */
34
802k
#define NumberOfRounds 24
35
36
/* SHA3 (Keccak) constants for 24 rounds */
37
static uint64_t keccak_round_constants[NumberOfRounds] = {
38
  I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000),
39
  I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009),
40
  I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A),
41
  I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003),
42
  I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A),
43
  I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008)
44
};
45
46
/* Initializing a sha3 context for given number of output bits */
47
static void keccak_Init(SHA3_CTX *ctx, unsigned bits)
48
398
{
49
  /* NB: The Keccak capacity parameter = bits * 2 */
50
398
  unsigned rate = 1600 - bits * 2;
51
52
398
  memzero(ctx, sizeof(SHA3_CTX));
53
398
  ctx->block_size = rate / 8;
54
398
  assert(rate <= 1600 && (rate % 64) == 0);
55
398
}
56
57
/**
58
 * Initialize context before calculating hash.
59
 *
60
 * @param ctx context to initialize
61
 */
62
void sha3_224_Init(SHA3_CTX *ctx)
63
0
{
64
0
  keccak_Init(ctx, 224);
65
0
}
66
67
/**
68
 * Initialize context before calculating hash.
69
 *
70
 * @param ctx context to initialize
71
 */
72
void sha3_256_Init(SHA3_CTX *ctx)
73
398
{
74
398
  keccak_Init(ctx, 256);
75
398
}
76
77
/**
78
 * Initialize context before calculating hash.
79
 *
80
 * @param ctx context to initialize
81
 */
82
void sha3_384_Init(SHA3_CTX *ctx)
83
0
{
84
0
  keccak_Init(ctx, 384);
85
0
}
86
87
/**
88
 * Initialize context before calculating hash.
89
 *
90
 * @param ctx context to initialize
91
 */
92
void sha3_512_Init(SHA3_CTX *ctx)
93
0
{
94
0
  keccak_Init(ctx, 512);
95
0
}
96
97
/* Keccak theta() transformation */
98
static void keccak_theta(uint64_t *A)
99
770k
{
100
770k
  unsigned int x = 0;
101
770k
  uint64_t C[5] = {0}, D[5] = {0};
102
103
4.62M
  for (x = 0; x < 5; x++) {
104
3.85M
    C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
105
3.85M
  }
106
770k
  D[0] = ROTL64(C[1], 1) ^ C[4];
107
770k
  D[1] = ROTL64(C[2], 1) ^ C[0];
108
770k
  D[2] = ROTL64(C[3], 1) ^ C[1];
109
770k
  D[3] = ROTL64(C[4], 1) ^ C[2];
110
770k
  D[4] = ROTL64(C[0], 1) ^ C[3];
111
112
4.62M
  for (x = 0; x < 5; x++) {
113
3.85M
    A[x]      ^= D[x];
114
3.85M
    A[x + 5]  ^= D[x];
115
3.85M
    A[x + 10] ^= D[x];
116
3.85M
    A[x + 15] ^= D[x];
117
3.85M
    A[x + 20] ^= D[x];
118
3.85M
  }
119
770k
}
120
121
/* Keccak pi() transformation */
122
static void keccak_pi(uint64_t *A)
123
770k
{
124
770k
  uint64_t A1 = 0;
125
770k
  A1 = A[1];
126
770k
  A[ 1] = A[ 6];
127
770k
  A[ 6] = A[ 9];
128
770k
  A[ 9] = A[22];
129
770k
  A[22] = A[14];
130
770k
  A[14] = A[20];
131
770k
  A[20] = A[ 2];
132
770k
  A[ 2] = A[12];
133
770k
  A[12] = A[13];
134
770k
  A[13] = A[19];
135
770k
  A[19] = A[23];
136
770k
  A[23] = A[15];
137
770k
  A[15] = A[ 4];
138
770k
  A[ 4] = A[24];
139
770k
  A[24] = A[21];
140
770k
  A[21] = A[ 8];
141
770k
  A[ 8] = A[16];
142
770k
  A[16] = A[ 5];
143
770k
  A[ 5] = A[ 3];
144
770k
  A[ 3] = A[18];
145
770k
  A[18] = A[17];
146
770k
  A[17] = A[11];
147
770k
  A[11] = A[ 7];
148
770k
  A[ 7] = A[10];
149
770k
  A[10] = A1;
150
  /* note: A[ 0] is left as is */
151
770k
}
152
153
/* Keccak chi() transformation */
154
static void keccak_chi(uint64_t *A)
155
770k
{
156
770k
  int i = 0;
157
4.62M
  for (i = 0; i < 25; i += 5) {
158
3.85M
    uint64_t A0 = A[0 + i], A1 = A[1 + i];
159
3.85M
    A[0 + i] ^= ~A1 & A[2 + i];
160
3.85M
    A[1 + i] ^= ~A[2 + i] & A[3 + i];
161
3.85M
    A[2 + i] ^= ~A[3 + i] & A[4 + i];
162
3.85M
    A[3 + i] ^= ~A[4 + i] & A0;
163
3.85M
    A[4 + i] ^= ~A0 & A1;
164
3.85M
  }
165
770k
}
166
167
static void sha3_permutation(uint64_t *state)
168
32.0k
{
169
#if BYTE_ORDER == BIG_ENDIAN
170
  int i;
171
  for (i = 0; i < 25; i++)
172
  {
173
    REVERSE64(state[i], state[i]);
174
  }
175
#endif
176
32.0k
  int round = 0;
177
802k
  for (round = 0; round < NumberOfRounds; round++)
178
770k
  {
179
770k
    keccak_theta(state);
180
181
    /* apply Keccak rho() transformation */
182
770k
    state[ 1] = ROTL64(state[ 1],  1);
183
770k
    state[ 2] = ROTL64(state[ 2], 62);
184
770k
    state[ 3] = ROTL64(state[ 3], 28);
185
770k
    state[ 4] = ROTL64(state[ 4], 27);
186
770k
    state[ 5] = ROTL64(state[ 5], 36);
187
770k
    state[ 6] = ROTL64(state[ 6], 44);
188
770k
    state[ 7] = ROTL64(state[ 7],  6);
189
770k
    state[ 8] = ROTL64(state[ 8], 55);
190
770k
    state[ 9] = ROTL64(state[ 9], 20);
191
770k
    state[10] = ROTL64(state[10],  3);
192
770k
    state[11] = ROTL64(state[11], 10);
193
770k
    state[12] = ROTL64(state[12], 43);
194
770k
    state[13] = ROTL64(state[13], 25);
195
770k
    state[14] = ROTL64(state[14], 39);
196
770k
    state[15] = ROTL64(state[15], 41);
197
770k
    state[16] = ROTL64(state[16], 45);
198
770k
    state[17] = ROTL64(state[17], 15);
199
770k
    state[18] = ROTL64(state[18], 21);
200
770k
    state[19] = ROTL64(state[19],  8);
201
770k
    state[20] = ROTL64(state[20], 18);
202
770k
    state[21] = ROTL64(state[21],  2);
203
770k
    state[22] = ROTL64(state[22], 61);
204
770k
    state[23] = ROTL64(state[23], 56);
205
770k
    state[24] = ROTL64(state[24], 14);
206
207
770k
    keccak_pi(state);
208
770k
    keccak_chi(state);
209
210
    /* apply iota(state, round) */
211
770k
    *state ^= keccak_round_constants[round];
212
770k
  }
213
#if BYTE_ORDER == BIG_ENDIAN
214
  for (i = 0; i < 25; i++)
215
  {
216
    REVERSE64(state[i], state[i]);
217
  }
218
#endif
219
32.0k
}
220
221
/**
222
 * The core transformation. Process the specified block of data.
223
 *
224
 * @param hash the algorithm state
225
 * @param block the message block to process
226
 * @param block_size the size of the processed block in bytes
227
 */
228
static void sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size)
229
32.0k
{
230
  /* expanded loop */
231
32.0k
  hash[ 0] ^= le2me_64(block[ 0]);
232
32.0k
  hash[ 1] ^= le2me_64(block[ 1]);
233
32.0k
  hash[ 2] ^= le2me_64(block[ 2]);
234
32.0k
  hash[ 3] ^= le2me_64(block[ 3]);
235
32.0k
  hash[ 4] ^= le2me_64(block[ 4]);
236
32.0k
  hash[ 5] ^= le2me_64(block[ 5]);
237
32.0k
  hash[ 6] ^= le2me_64(block[ 6]);
238
32.0k
  hash[ 7] ^= le2me_64(block[ 7]);
239
32.0k
  hash[ 8] ^= le2me_64(block[ 8]);
240
  /* if not sha3-512 */
241
32.0k
  if (block_size > 72) {
242
32.0k
    hash[ 9] ^= le2me_64(block[ 9]);
243
32.0k
    hash[10] ^= le2me_64(block[10]);
244
32.0k
    hash[11] ^= le2me_64(block[11]);
245
32.0k
    hash[12] ^= le2me_64(block[12]);
246
    /* if not sha3-384 */
247
32.0k
    if (block_size > 104) {
248
32.0k
      hash[13] ^= le2me_64(block[13]);
249
32.0k
      hash[14] ^= le2me_64(block[14]);
250
32.0k
      hash[15] ^= le2me_64(block[15]);
251
32.0k
      hash[16] ^= le2me_64(block[16]);
252
      /* if not sha3-256 */
253
32.0k
      if (block_size > 136) {
254
0
        hash[17] ^= le2me_64(block[17]);
255
#ifdef FULL_SHA3_FAMILY_SUPPORT
256
        /* if not sha3-224 */
257
        if (block_size > 144) {
258
          hash[18] ^= le2me_64(block[18]);
259
          hash[19] ^= le2me_64(block[19]);
260
          hash[20] ^= le2me_64(block[20]);
261
          hash[21] ^= le2me_64(block[21]);
262
          hash[22] ^= le2me_64(block[22]);
263
          hash[23] ^= le2me_64(block[23]);
264
          hash[24] ^= le2me_64(block[24]);
265
        }
266
#endif
267
0
      }
268
32.0k
    }
269
32.0k
  }
270
  /* make a permutation of the hash */
271
32.0k
  sha3_permutation(hash);
272
32.0k
}
273
274
2.83k
#define SHA3_FINALIZED 0x80000000
275
276
/**
277
 * Calculate message hash.
278
 * Can be called repeatedly with chunks of the message to be hashed.
279
 *
280
 * @param ctx the algorithm context containing current hashing state
281
 * @param msg message chunk
282
 * @param size length of the message chunk
283
 */
284
void sha3_Update(SHA3_CTX *ctx, const unsigned char *msg, size_t size)
285
16.7k
{
286
16.7k
  if (size == 0) return;
287
288
2.03k
  size_t idx = (size_t)ctx->rest;
289
2.03k
  size_t block_size = (size_t)ctx->block_size;
290
291
2.03k
  if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */
292
2.03k
  ctx->rest = (unsigned)((ctx->rest + size) % block_size);
293
294
  /* fill partial block */
295
2.03k
  if (idx) {
296
1.62k
    size_t left = block_size - idx;
297
1.62k
    memcpy((char*)ctx->message + idx, msg, (size < left ? size : left));
298
1.62k
    if (size < left) return;
299
300
    /* process partial block */
301
618
    sha3_process_block(ctx->hash, ctx->message, block_size);
302
618
    msg  += left;
303
618
    size -= left;
304
618
  }
305
32.0k
  while (size >= block_size) {
306
31.0k
    uint64_t *aligned_message_block = NULL;
307
31.0k
    if (IS_ALIGNED_64(msg)) {
308
      /* the most common case is processing of an already aligned message
309
      without copying it */
310
31.0k
      aligned_message_block = (uint64_t*)(void*)msg;
311
31.0k
    } else {
312
0
      memcpy(ctx->message, msg, block_size);
313
0
      aligned_message_block = ctx->message;
314
0
    }
315
316
31.0k
    sha3_process_block(ctx->hash, aligned_message_block, block_size);
317
31.0k
    msg  += block_size;
318
31.0k
    size -= block_size;
319
31.0k
  }
320
1.02k
  if (size) {
321
996
    memcpy(ctx->message, msg, size); /* save leftovers */
322
996
  }
323
1.02k
}
324
325
/**
326
 * Store calculated hash into the given array.
327
 *
328
 * @param ctx the algorithm context containing current hashing state
329
 * @param result calculated hash in binary form
330
 */
331
void sha3_Final(SHA3_CTX *ctx, unsigned char* result)
332
398
{
333
398
  size_t digest_length = 100 - ctx->block_size / 2;
334
398
  const size_t block_size = ctx->block_size;
335
336
398
  if (!(ctx->rest & SHA3_FINALIZED))
337
398
  {
338
    /* clear the rest of the data queue */
339
398
    memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest);
340
398
    ((char*)ctx->message)[ctx->rest] |= 0x06;
341
398
    ((char*)ctx->message)[block_size - 1] |= 0x80;
342
343
    /* process final block */
344
398
    sha3_process_block(ctx->hash, ctx->message, block_size);
345
398
    ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
346
398
  }
347
348
398
  assert(block_size > digest_length);
349
398
  if (result) me64_to_le_str(result, ctx->hash, digest_length);
350
398
  memzero(ctx, sizeof(SHA3_CTX));
351
398
}
352
353
#if USE_KECCAK
354
/**
355
* Store calculated hash into the given array.
356
*
357
* @param ctx the algorithm context containing current hashing state
358
* @param result calculated hash in binary form
359
*/
360
void keccak_Final(SHA3_CTX *ctx, unsigned char* result)
361
0
{
362
0
  size_t digest_length = 100 - ctx->block_size / 2;
363
0
  const size_t block_size = ctx->block_size;
364
365
0
  if (!(ctx->rest & SHA3_FINALIZED))
366
0
  {
367
    /* clear the rest of the data queue */
368
0
    memzero((char*)ctx->message + ctx->rest, block_size - ctx->rest);
369
0
    ((char*)ctx->message)[ctx->rest] |= 0x01;
370
0
    ((char*)ctx->message)[block_size - 1] |= 0x80;
371
372
    /* process final block */
373
0
    sha3_process_block(ctx->hash, ctx->message, block_size);
374
0
    ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
375
0
  }
376
377
0
  assert(block_size > digest_length);
378
0
  if (result) me64_to_le_str(result, ctx->hash, digest_length);
379
0
  memzero(ctx, sizeof(SHA3_CTX));
380
0
}
381
382
void keccak_256(const unsigned char* data, size_t len, unsigned char* digest)
383
0
{
384
0
  SHA3_CTX ctx = {0};
385
0
  keccak_256_Init(&ctx);
386
0
  keccak_Update(&ctx, data, len);
387
0
  keccak_Final(&ctx, digest);
388
0
}
389
390
void keccak_512(const unsigned char* data, size_t len, unsigned char* digest)
391
0
{
392
0
  SHA3_CTX ctx = {0};
393
0
  keccak_512_Init(&ctx);
394
0
  keccak_Update(&ctx, data, len);
395
0
  keccak_Final(&ctx, digest);
396
0
}
397
#endif /* USE_KECCAK */
398
399
void sha3_256(const unsigned char* data, size_t len, unsigned char* digest)
400
0
{
401
0
  SHA3_CTX ctx = {0};
402
0
  sha3_256_Init(&ctx);
403
0
  sha3_Update(&ctx, data, len);
404
0
  sha3_Final(&ctx, digest);
405
0
}
406
407
void sha3_512(const unsigned char* data, size_t len, unsigned char* digest)
408
0
{
409
0
  SHA3_CTX ctx = {0};
410
0
  sha3_512_Init(&ctx);
411
0
  sha3_Update(&ctx, data, len);
412
0
  sha3_Final(&ctx, digest);
413
0
}