about summary refs log tree commit diff stats
path: root/gba/source/sha2.c
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-09-10 22:12:47 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-09-10 22:12:47 -0400
commit6ceeb199181d64031f4173cfbffa066f5b9796b8 (patch)
treeabda49c65817f58de5c0cb884e8848aae5723dea /gba/source/sha2.c
parent1d82e3affd42c2336702af4a644baa8eec249ead (diff)
downloadgen3uploader-6ceeb199181d64031f4173cfbffa066f5b9796b8.tar.gz
gen3uploader-6ceeb199181d64031f4173cfbffa066f5b9796b8.tar.bz2
gen3uploader-6ceeb199181d64031f4173cfbffa066f5b9796b8.zip
Added identifying hash to Pokémon data structure
The purpose of this hash is described in detail in pokemon.h. The hash
is computed using an implementation of SHA-224. To allow the GBA
sufficient time to compute this hash, a delay of 5 milliseconds was
introduced on the GC side before reading a Pokémon.
Diffstat (limited to 'gba/source/sha2.c')
-rw-r--r--gba/source/sha2.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/gba/source/sha2.c b/gba/source/sha2.c new file mode 100644 index 0000000..149c043 --- /dev/null +++ b/gba/source/sha2.c
@@ -0,0 +1,471 @@
1/*
2 * FIPS 180-2 SHA-224/256/384/512 implementation
3 * Last update: 02/02/2007
4 * Issue date: 04/30/2005
5 *
6 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#if 0
35#define UNROLL_LOOPS /* Enable loops unrolling */
36#endif
37
38#include <string.h>
39
40#include "sha2.h"
41
42#define SHFR(x, n) (x >> n)
43#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
44#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
45#define CH(x, y, z) ((x & y) ^ (~x & z))
46#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
47
48#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
49#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
50#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
51#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
52
53#define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
54#define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
55#define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7))
56#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6))
57
58#define UNPACK32(x, str) \
59{ \
60 *((str) + 3) = (uint8) ((x) ); \
61 *((str) + 2) = (uint8) ((x) >> 8); \
62 *((str) + 1) = (uint8) ((x) >> 16); \
63 *((str) + 0) = (uint8) ((x) >> 24); \
64}
65
66#define PACK32(str, x) \
67{ \
68 *(x) = ((uint32) *((str) + 3) ) \
69 | ((uint32) *((str) + 2) << 8) \
70 | ((uint32) *((str) + 1) << 16) \
71 | ((uint32) *((str) + 0) << 24); \
72}
73
74#define UNPACK64(x, str) \
75{ \
76 *((str) + 7) = (uint8) ((x) ); \
77 *((str) + 6) = (uint8) ((x) >> 8); \
78 *((str) + 5) = (uint8) ((x) >> 16); \
79 *((str) + 4) = (uint8) ((x) >> 24); \
80 *((str) + 3) = (uint8) ((x) >> 32); \
81 *((str) + 2) = (uint8) ((x) >> 40); \
82 *((str) + 1) = (uint8) ((x) >> 48); \
83 *((str) + 0) = (uint8) ((x) >> 56); \
84}
85
86#define PACK64(str, x) \
87{ \
88 *(x) = ((uint64) *((str) + 7) ) \
89 | ((uint64) *((str) + 6) << 8) \
90 | ((uint64) *((str) + 5) << 16) \
91 | ((uint64) *((str) + 4) << 24) \
92 | ((uint64) *((str) + 3) << 32) \
93 | ((uint64) *((str) + 2) << 40) \
94 | ((uint64) *((str) + 1) << 48) \
95 | ((uint64) *((str) + 0) << 56); \
96}
97
98/* Macros used for loops unrolling */
99
100#define SHA256_SCR(i) \
101{ \
102 w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
103 + SHA256_F3(w[i - 15]) + w[i - 16]; \
104}
105
106#define SHA512_SCR(i) \
107{ \
108 w[i] = SHA512_F4(w[i - 2]) + w[i - 7] \
109 + SHA512_F3(w[i - 15]) + w[i - 16]; \
110}
111
112#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \
113{ \
114 t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
115 + sha256_k[j] + w[j]; \
116 t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
117 wv[d] += t1; \
118 wv[h] = t1 + t2; \
119}
120
121#define SHA512_EXP(a, b, c, d, e, f, g ,h, j) \
122{ \
123 t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
124 + sha512_k[j] + w[j]; \
125 t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
126 wv[d] += t1; \
127 wv[h] = t1 + t2; \
128}
129
130uint32 sha224_h0[8] =
131 {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
132 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
133
134uint32 sha256_h0[8] =
135 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
136 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
137
138uint32 sha256_k[64] =
139 {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
140 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
141 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
142 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
143 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
144 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
145 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
146 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
147 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
148 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
149 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
150 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
151 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
152 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
153 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
154 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
155
156/* SHA-256 functions */
157
158void sha256_transf(sha256_ctx *ctx, const unsigned char *message,
159 unsigned int block_nb)
160{
161 uint32 w[64];
162 uint32 wv[8];
163 uint32 t1, t2;
164 const unsigned char *sub_block;
165 int i;
166
167#ifndef UNROLL_LOOPS
168 int j;
169#endif
170
171 for (i = 0; i < (int) block_nb; i++) {
172 sub_block = message + (i << 6);
173
174#ifndef UNROLL_LOOPS
175 for (j = 0; j < 16; j++) {
176 PACK32(&sub_block[j << 2], &w[j]);
177 }
178
179 for (j = 16; j < 64; j++) {
180 SHA256_SCR(j);
181 }
182
183 for (j = 0; j < 8; j++) {
184 wv[j] = ctx->h[j];
185 }
186
187 for (j = 0; j < 64; j++) {
188 t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
189 + sha256_k[j] + w[j];
190 t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
191 wv[7] = wv[6];
192 wv[6] = wv[5];
193 wv[5] = wv[4];
194 wv[4] = wv[3] + t1;
195 wv[3] = wv[2];
196 wv[2] = wv[1];
197 wv[1] = wv[0];
198 wv[0] = t1 + t2;
199 }
200
201 for (j = 0; j < 8; j++) {
202 ctx->h[j] += wv[j];
203 }
204#else
205 PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]);
206 PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]);
207 PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]);
208 PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]);
209 PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]);
210 PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]);
211 PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]);
212 PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]);
213
214 SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19);
215 SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23);
216 SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27);
217 SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31);
218 SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35);
219 SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39);
220 SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43);
221 SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47);
222 SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51);
223 SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55);
224 SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59);
225 SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63);
226
227 wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
228 wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
229 wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
230 wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
231
232 SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1);
233 SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3);
234 SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5);
235 SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7);
236 SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9);
237 SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11);
238 SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13);
239 SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15);
240 SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17);
241 SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19);
242 SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21);
243 SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23);
244 SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25);
245 SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27);
246 SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29);
247 SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31);
248 SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33);
249 SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35);
250 SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37);
251 SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39);
252 SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41);
253 SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43);
254 SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45);
255 SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47);
256 SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49);
257 SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51);
258 SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53);
259 SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55);
260 SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57);
261 SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59);
262 SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61);
263 SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63);
264
265 ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
266 ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
267 ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
268 ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
269#endif /* !UNROLL_LOOPS */
270 }
271}
272
273void sha256(const unsigned char *message, unsigned int len, unsigned char *digest)
274{
275 sha256_ctx ctx;
276
277 sha256_init(&ctx);
278 sha256_update(&ctx, message, len);
279 sha256_final(&ctx, digest);
280}
281
282void sha256_init(sha256_ctx *ctx)
283{
284#ifndef UNROLL_LOOPS
285 int i;
286 for (i = 0; i < 8; i++) {
287 ctx->h[i] = sha256_h0[i];
288 }
289#else
290 ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1];
291 ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3];
292 ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5];
293 ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7];
294#endif /* !UNROLL_LOOPS */
295
296 ctx->len = 0;
297 ctx->tot_len = 0;
298}
299
300void sha256_update(sha256_ctx *ctx, const unsigned char *message,
301 unsigned int len)
302{
303 unsigned int block_nb;
304 unsigned int new_len, rem_len, tmp_len;
305 const unsigned char *shifted_message;
306
307 tmp_len = SHA256_BLOCK_SIZE - ctx->len;
308 rem_len = len < tmp_len ? len : tmp_len;
309
310 memcpy(&ctx->block[ctx->len], message, rem_len);
311
312 if (ctx->len + len < SHA256_BLOCK_SIZE) {
313 ctx->len += len;
314 return;
315 }
316
317 new_len = len - rem_len;
318 block_nb = new_len / SHA256_BLOCK_SIZE;
319
320 shifted_message = message + rem_len;
321
322 sha256_transf(ctx, ctx->block, 1);
323 sha256_transf(ctx, shifted_message, block_nb);
324
325 rem_len = new_len % SHA256_BLOCK_SIZE;
326
327 memcpy(ctx->block, &shifted_message[block_nb << 6],
328 rem_len);
329
330 ctx->len = rem_len;
331 ctx->tot_len += (block_nb + 1) << 6;
332}
333
334void sha256_final(sha256_ctx *ctx, unsigned char *digest)
335{
336 unsigned int block_nb;
337 unsigned int pm_len;
338 unsigned int len_b;
339
340#ifndef UNROLL_LOOPS
341 int i;
342#endif
343
344 block_nb = (1 + ((SHA256_BLOCK_SIZE - 9)
345 < (ctx->len % SHA256_BLOCK_SIZE)));
346
347 len_b = (ctx->tot_len + ctx->len) << 3;
348 pm_len = block_nb << 6;
349
350 memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
351 ctx->block[ctx->len] = 0x80;
352 UNPACK32(len_b, ctx->block + pm_len - 4);
353
354 sha256_transf(ctx, ctx->block, block_nb);
355
356#ifndef UNROLL_LOOPS
357 for (i = 0 ; i < 8; i++) {
358 UNPACK32(ctx->h[i], &digest[i << 2]);
359 }
360#else
361 UNPACK32(ctx->h[0], &digest[ 0]);
362 UNPACK32(ctx->h[1], &digest[ 4]);
363 UNPACK32(ctx->h[2], &digest[ 8]);
364 UNPACK32(ctx->h[3], &digest[12]);
365 UNPACK32(ctx->h[4], &digest[16]);
366 UNPACK32(ctx->h[5], &digest[20]);
367 UNPACK32(ctx->h[6], &digest[24]);
368 UNPACK32(ctx->h[7], &digest[28]);
369#endif /* !UNROLL_LOOPS */
370}
371
372/* SHA-224 functions */
373
374void sha224(const unsigned char *message, unsigned int len,
375 unsigned char *digest)
376{
377 sha224_ctx ctx;
378
379 sha224_init(&ctx);
380 sha224_update(&ctx, message, len);
381 sha224_final(&ctx, digest);
382}
383
384void sha224_init(sha224_ctx *ctx)
385{
386#ifndef UNROLL_LOOPS
387 int i;
388 for (i = 0; i < 8; i++) {
389 ctx->h[i] = sha224_h0[i];
390 }
391#else
392 ctx->h[0] = sha224_h0[0]; ctx->h[1] = sha224_h0[1];
393 ctx->h[2] = sha224_h0[2]; ctx->h[3] = sha224_h0[3];
394 ctx->h[4] = sha224_h0[4]; ctx->h[5] = sha224_h0[5];
395 ctx->h[6] = sha224_h0[6]; ctx->h[7] = sha224_h0[7];
396#endif /* !UNROLL_LOOPS */
397
398 ctx->len = 0;
399 ctx->tot_len = 0;
400}
401
402void sha224_update(sha224_ctx *ctx, const unsigned char *message,
403 unsigned int len)
404{
405 unsigned int block_nb;
406 unsigned int new_len, rem_len, tmp_len;
407 const unsigned char *shifted_message;
408
409 tmp_len = SHA224_BLOCK_SIZE - ctx->len;
410 rem_len = len < tmp_len ? len : tmp_len;
411
412 memcpy(&ctx->block[ctx->len], message, rem_len);
413
414 if (ctx->len + len < SHA224_BLOCK_SIZE) {
415 ctx->len += len;
416 return;
417 }
418
419 new_len = len - rem_len;
420 block_nb = new_len / SHA224_BLOCK_SIZE;
421
422 shifted_message = message + rem_len;
423
424 sha256_transf(ctx, ctx->block, 1);
425 sha256_transf(ctx, shifted_message, block_nb);
426
427 rem_len = new_len % SHA224_BLOCK_SIZE;
428
429 memcpy(ctx->block, &shifted_message[block_nb << 6],
430 rem_len);
431
432 ctx->len = rem_len;
433 ctx->tot_len += (block_nb + 1) << 6;
434}
435
436void sha224_final(sha224_ctx *ctx, unsigned char *digest)
437{
438 unsigned int block_nb;
439 unsigned int pm_len;
440 unsigned int len_b;
441
442#ifndef UNROLL_LOOPS
443 int i;
444#endif
445
446 block_nb = (1 + ((SHA224_BLOCK_SIZE - 9)
447 < (ctx->len % SHA224_BLOCK_SIZE)));
448
449 len_b = (ctx->tot_len + ctx->len) << 3;
450 pm_len = block_nb << 6;
451
452 memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
453 ctx->block[ctx->len] = 0x80;
454 UNPACK32(len_b, ctx->block + pm_len - 4);
455
456 sha256_transf(ctx, ctx->block, block_nb);
457
458#ifndef UNROLL_LOOPS
459 for (i = 0 ; i < 7; i++) {
460 UNPACK32(ctx->h[i], &digest[i << 2]);
461 }
462#else
463 UNPACK32(ctx->h[0], &digest[ 0]);
464 UNPACK32(ctx->h[1], &digest[ 4]);
465 UNPACK32(ctx->h[2], &digest[ 8]);
466 UNPACK32(ctx->h[3], &digest[12]);
467 UNPACK32(ctx->h[4], &digest[16]);
468 UNPACK32(ctx->h[5], &digest[20]);
469 UNPACK32(ctx->h[6], &digest[24]);
470#endif /* !UNROLL_LOOPS */
471}