blob: f09b54df8126e6b8d02b73aa726430ae84ccc6ba [file] [log] [blame]
Pascal Brandc639ac82015-07-02 08:53:34 +02001/*
2 * Copyright (c) 2014, STMicroelectronics International N.V.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * FIPS 180-2 SHA-224/256/384/512 implementation
30 * Last update: 02/02/2007
31 * Issue date: 04/30/2005
32 *
33 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
Etienne Carriere102092e2019-03-28 15:24:22 +010060#include <stddef.h>
61#include <stdint.h>
62#include <tee_api.h>
63
Pascal Brandc639ac82015-07-02 08:53:34 +020064#include "sha2_impl.h"
65
66#define SHFR(x, n) (x >> n)
67#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
68#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
69#define CH(x, y, z) ((x & y) ^ (~x & z))
70#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
71
72#define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
73#define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
74#define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
75#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
76
77#define UNPACK32(x, str) \
78 { \
79 *((str) + 3) = (uint8_t) ((x)); \
80 *((str) + 2) = (uint8_t) ((x) >> 8); \
81 *((str) + 1) = (uint8_t) ((x) >> 16); \
82 *((str) + 0) = (uint8_t) ((x) >> 24); \
83 }
84
85#define PACK32(str, x) \
86 { \
87 *(x) = ((uint32_t) *((str) + 3)) \
88 | ((uint32_t) *((str) + 2) << 8) \
89 | ((uint32_t) *((str) + 1) << 16) \
90 | ((uint32_t) *((str) + 0) << 24); \
91 }
92
93/* Macros used for loops unrolling */
94#define SHA256_SCR(i) \
95{ \
96 w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
97 + SHA256_F3(w[i - 15]) + w[i - 16]; \
98}
99
100#define SHA256_EXP(a, b, c, d, e, f, g, h, j) \
101{ \
102 t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
103 + sha256_k[j] + w[j]; \
104 t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \
105 wv[d] += t1; \
106 wv[h] = t1 + t2; \
107}
108
109uint32_t sha224_h0[8] = {
110 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
111 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
112};
113
114uint32_t sha256_h0[8] = {
115 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
116 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
117};
118
119uint32_t sha256_k[64] = {
120 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
121 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
122 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
123 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
124 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
125 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
126 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
127 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
128 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
129 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
130 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
131 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
132 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
133 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
134 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
135 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
136};
137
138/* SHA-256 functions */
139void sha256_transf(struct sha256_ctx *ctx, const unsigned char *message,
140 unsigned int block_nb)
141{
Etienne Carriere102092e2019-03-28 15:24:22 +0100142 uint32_t w[64] = { };
143 uint32_t wv[8] = { };
144 uint32_t t1 = 0;
145 uint32_t t2 = 0;
146 const unsigned char *sub_block = NULL;
147 int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200148#ifndef UNROLL_LOOPS
Etienne Carriere102092e2019-03-28 15:24:22 +0100149 int j = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200150#endif
151
152 for (i = 0; i < (int)block_nb; i++) {
153 sub_block = message + (i << 6);
154
155#ifndef UNROLL_LOOPS
156 for (j = 0; j < 16; j++)
157 PACK32(&sub_block[j << 2], &w[j]);
158
159 for (j = 16; j < 64; j++)
160 SHA256_SCR(j);
161
162 for (j = 0; j < 8; j++)
163 wv[j] = ctx->h[j];
164
165 for (j = 0; j < 64; j++) {
166 t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
167 + sha256_k[j] + w[j];
168 t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
169 wv[7] = wv[6];
170 wv[6] = wv[5];
171 wv[5] = wv[4];
172 wv[4] = wv[3] + t1;
173 wv[3] = wv[2];
174 wv[2] = wv[1];
175 wv[1] = wv[0];
176 wv[0] = t1 + t2;
177 }
178
179 for (j = 0; j < 8; j++)
180 ctx->h[j] += wv[j];
181#else
182 PACK32(&sub_block[0], &w[0]);
183 PACK32(&sub_block[4], &w[1]);
184 PACK32(&sub_block[8], &w[2]);
185 PACK32(&sub_block[12], &w[3]);
186 PACK32(&sub_block[16], &w[4]);
187 PACK32(&sub_block[20], &w[5]);
188 PACK32(&sub_block[24], &w[6]);
189 PACK32(&sub_block[28], &w[7]);
190 PACK32(&sub_block[32], &w[8]);
191 PACK32(&sub_block[36], &w[9]);
192 PACK32(&sub_block[40], &w[10]);
193 PACK32(&sub_block[44], &w[11]);
194 PACK32(&sub_block[48], &w[12]);
195 PACK32(&sub_block[52], &w[13]);
196 PACK32(&sub_block[56], &w[14]);
197 PACK32(&sub_block[60], &w[15]);
198
199 SHA256_SCR(16);
200 SHA256_SCR(17);
201 SHA256_SCR(18);
202 SHA256_SCR(19);
203 SHA256_SCR(20);
204 SHA256_SCR(21);
205 SHA256_SCR(22);
206 SHA256_SCR(23);
207 SHA256_SCR(24);
208 SHA256_SCR(25);
209 SHA256_SCR(26);
210 SHA256_SCR(27);
211 SHA256_SCR(28);
212 SHA256_SCR(29);
213 SHA256_SCR(30);
214 SHA256_SCR(31);
215 SHA256_SCR(32);
216 SHA256_SCR(33);
217 SHA256_SCR(34);
218 SHA256_SCR(35);
219 SHA256_SCR(36);
220 SHA256_SCR(37);
221 SHA256_SCR(38);
222 SHA256_SCR(39);
223 SHA256_SCR(40);
224 SHA256_SCR(41);
225 SHA256_SCR(42);
226 SHA256_SCR(43);
227 SHA256_SCR(44);
228 SHA256_SCR(45);
229 SHA256_SCR(46);
230 SHA256_SCR(47);
231 SHA256_SCR(48);
232 SHA256_SCR(49);
233 SHA256_SCR(50);
234 SHA256_SCR(51);
235 SHA256_SCR(52);
236 SHA256_SCR(53);
237 SHA256_SCR(54);
238 SHA256_SCR(55);
239 SHA256_SCR(56);
240 SHA256_SCR(57);
241 SHA256_SCR(58);
242 SHA256_SCR(59);
243 SHA256_SCR(60);
244 SHA256_SCR(61);
245 SHA256_SCR(62);
246 SHA256_SCR(63);
247
248 wv[0] = ctx->h[0];
249 wv[1] = ctx->h[1];
250 wv[2] = ctx->h[2];
251 wv[3] = ctx->h[3];
252 wv[4] = ctx->h[4];
253 wv[5] = ctx->h[5];
254 wv[6] = ctx->h[6];
255 wv[7] = ctx->h[7];
256
257 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 0);
258 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 1);
259 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 2);
260 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 3);
261 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 4);
262 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 5);
263 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 6);
264 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 7);
265 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 8);
266 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 9);
267 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 10);
268 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 11);
269 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 12);
270 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 13);
271 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 14);
272 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 15);
273 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 16);
274 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 17);
275 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 18);
276 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 19);
277 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 20);
278 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 21);
279 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 22);
280 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 23);
281 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 24);
282 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 25);
283 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 26);
284 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 27);
285 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 28);
286 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 29);
287 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 30);
288 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 31);
289 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 32);
290 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 33);
291 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 34);
292 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 35);
293 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 36);
294 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 37);
295 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 38);
296 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 39);
297 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 40);
298 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 41);
299 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 42);
300 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 43);
301 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 44);
302 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 45);
303 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 46);
304 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 47);
305 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 48);
306 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 49);
307 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 50);
308 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 51);
309 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 52);
310 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 53);
311 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 54);
312 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 55);
313 SHA256_EXP(0, 1, 2, 3, 4, 5, 6, 7, 56);
314 SHA256_EXP(7, 0, 1, 2, 3, 4, 5, 6, 57);
315 SHA256_EXP(6, 7, 0, 1, 2, 3, 4, 5, 58);
316 SHA256_EXP(5, 6, 7, 0, 1, 2, 3, 4, 59);
317 SHA256_EXP(4, 5, 6, 7, 0, 1, 2, 3, 60);
318 SHA256_EXP(3, 4, 5, 6, 7, 0, 1, 2, 61);
319 SHA256_EXP(2, 3, 4, 5, 6, 7, 0, 1, 62);
320 SHA256_EXP(1, 2, 3, 4, 5, 6, 7, 0, 63);
321
322 ctx->h[0] += wv[0];
323 ctx->h[1] += wv[1];
324 ctx->h[2] += wv[2];
325 ctx->h[3] += wv[3];
326 ctx->h[4] += wv[4];
327 ctx->h[5] += wv[5];
328 ctx->h[6] += wv[6];
329 ctx->h[7] += wv[7];
330#endif
331 }
332}
333
334void sha256(const unsigned char *message,
335 unsigned int len, unsigned char *digest)
336{
Etienne Carriere102092e2019-03-28 15:24:22 +0100337 struct sha256_ctx ctx = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200338
339 sha256_init(&ctx);
340 sha256_update(&ctx, message, len);
341 sha256_final(&ctx, digest);
342}
343
344void sha256_init(struct sha256_ctx *ctx)
345{
346#ifndef UNROLL_LOOPS
Etienne Carriere102092e2019-03-28 15:24:22 +0100347 int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200348
349 for (i = 0; i < 8; i++)
350 ctx->h[i] = sha256_h0[i];
351#else
352 ctx->h[0] = sha256_h0[0];
353 ctx->h[1] = sha256_h0[1];
354 ctx->h[2] = sha256_h0[2];
355 ctx->h[3] = sha256_h0[3];
356 ctx->h[4] = sha256_h0[4];
357 ctx->h[5] = sha256_h0[5];
358 ctx->h[6] = sha256_h0[6];
359 ctx->h[7] = sha256_h0[7];
360#endif
361
362 ctx->len = 0;
363 ctx->tot_len = 0;
364}
365
366void sha256_update(struct sha256_ctx *ctx, const unsigned char *message,
367 unsigned int len)
368{
Etienne Carriere102092e2019-03-28 15:24:22 +0100369 unsigned int block_nb = 0;
370 unsigned int new_len = 0;
371 unsigned int rem_len = 0;
372 unsigned int tmp_len = 0;
373 const unsigned char *shifted_message = NULL;
374 unsigned long int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200375
376 tmp_len = SHA256_BLOCK_SIZE - ctx->len;
377 rem_len = len < tmp_len ? len : tmp_len;
378
379 for (i = 0; i < rem_len; i++)
380 ctx->block[ctx->len + i] = message[i];
381
382 if (ctx->len + len < SHA256_BLOCK_SIZE) {
383 ctx->len += len;
384 return;
385 }
386
387 new_len = len - rem_len;
388 block_nb = new_len / SHA256_BLOCK_SIZE;
389
390 shifted_message = message + rem_len;
391
392 sha256_transf(ctx, ctx->block, 1);
393 sha256_transf(ctx, shifted_message, block_nb);
394
395 rem_len = new_len % SHA256_BLOCK_SIZE;
396
397 for (i = 0; i < rem_len; i++)
398 ctx->block[i] = shifted_message[(block_nb << 6) + i];
399
400 ctx->len = rem_len;
401 ctx->tot_len += (block_nb + 1) << 6;
402}
403
404void sha256_final(struct sha256_ctx *ctx, unsigned char *digest)
405{
Etienne Carriere102092e2019-03-28 15:24:22 +0100406 unsigned int block_nb = 0;
407 unsigned int pm_len = 0;
408 unsigned int len_b = 0;
409 unsigned long int i_m = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200410#ifndef UNROLL_LOOPS
Etienne Carriere102092e2019-03-28 15:24:22 +0100411 int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200412#endif
413
Etienne Carriere102092e2019-03-28 15:24:22 +0100414 block_nb = 1;
415 if ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE))
416 block_nb++;
Pascal Brandc639ac82015-07-02 08:53:34 +0200417
418 len_b = (ctx->tot_len + ctx->len) << 3;
419 pm_len = block_nb << 6;
420
421 for (i_m = 0; i_m < pm_len - ctx->len; i_m++)
422 ctx->block[ctx->len + i_m] = 0;
423
424 ctx->block[ctx->len] = 0x80;
425 UNPACK32(len_b, ctx->block + pm_len - 4);
426
427 sha256_transf(ctx, ctx->block, block_nb);
428
429#ifndef UNROLL_LOOPS
430 for (i = 0; i < 8; i++)
431 UNPACK32(ctx->h[i], &digest[i << 2]);
432#else
433 UNPACK32(ctx->h[0], &digest[0]);
434 UNPACK32(ctx->h[1], &digest[4]);
435 UNPACK32(ctx->h[2], &digest[8]);
436 UNPACK32(ctx->h[3], &digest[12]);
437 UNPACK32(ctx->h[4], &digest[16]);
438 UNPACK32(ctx->h[5], &digest[20]);
439 UNPACK32(ctx->h[6], &digest[24]);
440 UNPACK32(ctx->h[7], &digest[28]);
441#endif
442}
443
444/* SHA-224 functions */
445void sha224(const unsigned char *message, unsigned int len,
446 unsigned char *digest)
447{
Etienne Carriere102092e2019-03-28 15:24:22 +0100448 struct sha224_ctx ctx = { };
Pascal Brandc639ac82015-07-02 08:53:34 +0200449
450 sha224_init(&ctx);
451 sha224_update(&ctx, message, len);
452 sha224_final(&ctx, digest);
453}
454
455void sha224_init(struct sha224_ctx *ctx)
456{
457#ifndef UNROLL_LOOPS
Etienne Carriere102092e2019-03-28 15:24:22 +0100458 int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200459
460 for (i = 0; i < 8; i++)
461 ctx->h[i] = sha224_h0[i];
462#else
463 ctx->h[0] = sha224_h0[0];
464 ctx->h[1] = sha224_h0[1];
465 ctx->h[2] = sha224_h0[2];
466 ctx->h[3] = sha224_h0[3];
467 ctx->h[4] = sha224_h0[4];
468 ctx->h[5] = sha224_h0[5];
469 ctx->h[6] = sha224_h0[6];
470 ctx->h[7] = sha224_h0[7];
471#endif
472
473 ctx->len = 0;
474 ctx->tot_len = 0;
475}
476
477void sha224_update(struct sha224_ctx *ctx, const unsigned char *message,
478 unsigned int len)
479{
Etienne Carriere102092e2019-03-28 15:24:22 +0100480 unsigned int block_nb = 0;
481 unsigned int new_len = 0;
482 unsigned int rem_len = 0;
483 unsigned int tmp_len = 0;
484 const unsigned char *shifted_message = NULL;
485 unsigned long int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200486
487 tmp_len = SHA224_BLOCK_SIZE - ctx->len;
488 rem_len = len < tmp_len ? len : tmp_len;
489
490 for (i = 0; i < rem_len; i++)
491 ctx->block[ctx->len + i] = message[i];
492
493 if (ctx->len + len < SHA224_BLOCK_SIZE) {
494 ctx->len += len;
495 return;
496 }
497
498 new_len = len - rem_len;
499 block_nb = new_len / SHA224_BLOCK_SIZE;
500
501 shifted_message = message + rem_len;
502
503 sha256_transf((struct sha256_ctx *)ctx, ctx->block, 1);
504 sha256_transf((struct sha256_ctx *)ctx, shifted_message, block_nb);
505
506 rem_len = new_len % SHA224_BLOCK_SIZE;
507
508 for (i = 0; i < rem_len; i++)
509 ctx->block[i] = shifted_message[(block_nb << 6) + i];
510
511 ctx->len = rem_len;
512 ctx->tot_len += (block_nb + 1) << 6;
513}
514
515void sha224_final(struct sha224_ctx *ctx, unsigned char *digest)
516{
Etienne Carriere102092e2019-03-28 15:24:22 +0100517 unsigned int block_nb = 0;
518 unsigned int pm_len = 0;
519 unsigned int len_b = 0;
520 unsigned long int i_m = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200521#ifndef UNROLL_LOOPS
Etienne Carriere102092e2019-03-28 15:24:22 +0100522 int i = 0;
Pascal Brandc639ac82015-07-02 08:53:34 +0200523#endif
524
Etienne Carriere102092e2019-03-28 15:24:22 +0100525 block_nb = 1;
526 if ((SHA224_BLOCK_SIZE - 9) < (ctx->len % SHA224_BLOCK_SIZE))
527 block_nb++;
Pascal Brandc639ac82015-07-02 08:53:34 +0200528
529 len_b = (ctx->tot_len + ctx->len) << 3;
530 pm_len = block_nb << 6;
531
532 for (i_m = 0; i_m < pm_len - ctx->len; i_m++)
533 ctx->block[ctx->len + i_m] = 0;
534
535 ctx->block[ctx->len] = 0x80;
536 UNPACK32(len_b, ctx->block + pm_len - 4);
537
538 sha256_transf((struct sha256_ctx *)ctx, ctx->block, block_nb);
539
540#ifndef UNROLL_LOOPS
541 for (i = 0; i < 7; i++)
542 UNPACK32(ctx->h[i], &digest[i << 2]);
543#else
544 UNPACK32(ctx->h[0], &digest[0]);
545 UNPACK32(ctx->h[1], &digest[4]);
546 UNPACK32(ctx->h[2], &digest[8]);
547 UNPACK32(ctx->h[3], &digest[12]);
548 UNPACK32(ctx->h[4], &digest[16]);
549 UNPACK32(ctx->h[5], &digest[20]);
550 UNPACK32(ctx->h[6], &digest[24]);
551#endif
552}