/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 | } |