Unmap pages mapped during a failed fill_vmr()
[akaros.git] / kern / lib / crypto / 2sha512.c
1 /* SHA-256 and SHA-512 implementation based on code by Oliver Gay
2  * <olivier.gay@a3.epfl.ch> under a BSD-style license. See below.
3  */
4
5 /*
6  * FIPS 180-2 SHA-224/256/384/512 implementation
7  * Last update: 02/02/2007
8  * Issue date:  04/30/2005
9  *
10  * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the project nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37
38 #include <crypto/2sysincludes.h>
39 #include <crypto/2common.h>
40 #include <crypto/2sha.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 SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
49 #define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
50 #define SHA512_F3(x) (ROTR(x,  1) ^ ROTR(x,  8) ^ SHFR(x,  7))
51 #define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x,  6))
52
53 #define UNPACK32(x, str)                                \
54         {                                               \
55                 *((str) + 3) = (uint8_t) ((x)      );   \
56                 *((str) + 2) = (uint8_t) ((x) >>  8);   \
57                 *((str) + 1) = (uint8_t) ((x) >> 16);   \
58                 *((str) + 0) = (uint8_t) ((x) >> 24);   \
59         }
60
61 #define UNPACK64(x, str)                                        \
62         {                                                       \
63                 *((str) + 7) = (uint8_t) x;                     \
64                 *((str) + 6) = (uint8_t) ((uint64_t)x >> 8);    \
65                 *((str) + 5) = (uint8_t) ((uint64_t)x >> 16);   \
66                 *((str) + 4) = (uint8_t) ((uint64_t)x >> 24);   \
67                 *((str) + 3) = (uint8_t) ((uint64_t)x >> 32);   \
68                 *((str) + 2) = (uint8_t) ((uint64_t)x >> 40);   \
69                 *((str) + 1) = (uint8_t) ((uint64_t)x >> 48);   \
70                 *((str) + 0) = (uint8_t) ((uint64_t)x >> 56);   \
71         }
72
73 #define PACK64(str, x)                                          \
74         {                                                       \
75                 *(x) =   ((uint64_t) *((str) + 7)      )        \
76                         | ((uint64_t) *((str) + 6) <<  8)       \
77                         | ((uint64_t) *((str) + 5) << 16)       \
78                         | ((uint64_t) *((str) + 4) << 24)       \
79                         | ((uint64_t) *((str) + 3) << 32)       \
80                         | ((uint64_t) *((str) + 2) << 40)       \
81                         | ((uint64_t) *((str) + 1) << 48)       \
82                         | ((uint64_t) *((str) + 0) << 56);      \
83         }
84
85 /* Macros used for loops unrolling */
86
87 #define SHA512_SCR(i)                                           \
88         {                                                       \
89                 w[i] =  SHA512_F4(w[i -  2]) + w[i -  7]        \
90                         + SHA512_F3(w[i - 15]) + w[i - 16];     \
91         }
92
93 #define SHA512_EXP(a, b, c, d, e, f, g ,h, j)                           \
94         {                                                               \
95                 t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \
96                         + sha512_k[j] + w[j];                           \
97                 t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]);       \
98                 wv[d] += t1;                                            \
99                 wv[h] = t1 + t2;                                        \
100         }
101
102 static const uint64_t sha512_h0[8] = {
103         0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
104         0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
105         0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
106         0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
107 };
108
109 static const uint64_t sha512_k[80] = {
110         0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
111         0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
112         0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
113         0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
114         0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
115         0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
116         0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
117         0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
118         0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
119         0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
120         0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
121         0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
122         0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
123         0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
124         0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
125         0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
126         0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
127         0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
128         0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
129         0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
130         0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
131         0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
132         0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
133         0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
134         0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
135         0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
136         0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
137         0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
138         0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
139         0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
140         0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
141         0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
142         0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
143         0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
144         0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
145         0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
146         0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
147         0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
148         0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
149         0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
150 };
151
152 /* SHA-512 implementation */
153
154 void vb2_sha512_init(struct vb2_sha512_context *ctx)
155 {
156 #ifdef UNROLL_LOOPS_SHA512
157         ctx->h[0] = sha512_h0[0]; ctx->h[1] = sha512_h0[1];
158         ctx->h[2] = sha512_h0[2]; ctx->h[3] = sha512_h0[3];
159         ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5];
160         ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7];
161 #else
162         int i;
163
164         for (i = 0; i < 8; i++)
165                 ctx->h[i] = sha512_h0[i];
166 #endif /* UNROLL_LOOPS_SHA512 */
167
168         ctx->size = 0;
169         ctx->total_size = 0;
170 }
171
172 static void vb2_sha512_transform(struct vb2_sha512_context *ctx,
173                              const uint8_t *message,
174                              unsigned int block_nb)
175 {
176         /* Note that these arrays use 88*8=704 bytes of stack */
177         uint64_t w[80];
178         uint64_t wv[8];
179         uint64_t t1, t2;
180         const uint8_t *sub_block;
181         int i, j;
182
183         for (i = 0; i < (int) block_nb; i++) {
184                 sub_block = message + (i << 7);
185
186 #ifdef UNROLL_LOOPS_SHA512
187                 PACK64(&sub_block[  0], &w[ 0]);
188                 PACK64(&sub_block[  8], &w[ 1]);
189                 PACK64(&sub_block[ 16], &w[ 2]);
190                 PACK64(&sub_block[ 24], &w[ 3]);
191                 PACK64(&sub_block[ 32], &w[ 4]);
192                 PACK64(&sub_block[ 40], &w[ 5]);
193                 PACK64(&sub_block[ 48], &w[ 6]);
194                 PACK64(&sub_block[ 56], &w[ 7]);
195                 PACK64(&sub_block[ 64], &w[ 8]);
196                 PACK64(&sub_block[ 72], &w[ 9]);
197                 PACK64(&sub_block[ 80], &w[10]);
198                 PACK64(&sub_block[ 88], &w[11]);
199                 PACK64(&sub_block[ 96], &w[12]);
200                 PACK64(&sub_block[104], &w[13]);
201                 PACK64(&sub_block[112], &w[14]);
202                 PACK64(&sub_block[120], &w[15]);
203
204                 SHA512_SCR(16); SHA512_SCR(17); SHA512_SCR(18); SHA512_SCR(19);
205                 SHA512_SCR(20); SHA512_SCR(21); SHA512_SCR(22); SHA512_SCR(23);
206                 SHA512_SCR(24); SHA512_SCR(25); SHA512_SCR(26); SHA512_SCR(27);
207                 SHA512_SCR(28); SHA512_SCR(29); SHA512_SCR(30); SHA512_SCR(31);
208                 SHA512_SCR(32); SHA512_SCR(33); SHA512_SCR(34); SHA512_SCR(35);
209                 SHA512_SCR(36); SHA512_SCR(37); SHA512_SCR(38); SHA512_SCR(39);
210                 SHA512_SCR(40); SHA512_SCR(41); SHA512_SCR(42); SHA512_SCR(43);
211                 SHA512_SCR(44); SHA512_SCR(45); SHA512_SCR(46); SHA512_SCR(47);
212                 SHA512_SCR(48); SHA512_SCR(49); SHA512_SCR(50); SHA512_SCR(51);
213                 SHA512_SCR(52); SHA512_SCR(53); SHA512_SCR(54); SHA512_SCR(55);
214                 SHA512_SCR(56); SHA512_SCR(57); SHA512_SCR(58); SHA512_SCR(59);
215                 SHA512_SCR(60); SHA512_SCR(61); SHA512_SCR(62); SHA512_SCR(63);
216                 SHA512_SCR(64); SHA512_SCR(65); SHA512_SCR(66); SHA512_SCR(67);
217                 SHA512_SCR(68); SHA512_SCR(69); SHA512_SCR(70); SHA512_SCR(71);
218                 SHA512_SCR(72); SHA512_SCR(73); SHA512_SCR(74); SHA512_SCR(75);
219                 SHA512_SCR(76); SHA512_SCR(77); SHA512_SCR(78); SHA512_SCR(79);
220
221                 wv[0] = ctx->h[0]; wv[1] = ctx->h[1];
222                 wv[2] = ctx->h[2]; wv[3] = ctx->h[3];
223                 wv[4] = ctx->h[4]; wv[5] = ctx->h[5];
224                 wv[6] = ctx->h[6]; wv[7] = ctx->h[7];
225
226                 j = 0;
227
228                 do {
229                         SHA512_EXP(0,1,2,3,4,5,6,7,j); j++;
230                         SHA512_EXP(7,0,1,2,3,4,5,6,j); j++;
231                         SHA512_EXP(6,7,0,1,2,3,4,5,j); j++;
232                         SHA512_EXP(5,6,7,0,1,2,3,4,j); j++;
233                         SHA512_EXP(4,5,6,7,0,1,2,3,j); j++;
234                         SHA512_EXP(3,4,5,6,7,0,1,2,j); j++;
235                         SHA512_EXP(2,3,4,5,6,7,0,1,j); j++;
236                         SHA512_EXP(1,2,3,4,5,6,7,0,j); j++;
237                 } while (j < 80);
238
239                 ctx->h[0] += wv[0]; ctx->h[1] += wv[1];
240                 ctx->h[2] += wv[2]; ctx->h[3] += wv[3];
241                 ctx->h[4] += wv[4]; ctx->h[5] += wv[5];
242                 ctx->h[6] += wv[6]; ctx->h[7] += wv[7];
243 #else
244                 for (j = 0; j < 16; j++) {
245                         PACK64(&sub_block[j << 3], &w[j]);
246                 }
247
248                 for (j = 16; j < 80; j++) {
249                         SHA512_SCR(j);
250                 }
251
252                 for (j = 0; j < 8; j++) {
253                         wv[j] = ctx->h[j];
254                 }
255
256                 for (j = 0; j < 80; j++) {
257                         t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
258                                 + sha512_k[j] + w[j];
259                         t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
260                         wv[7] = wv[6];
261                         wv[6] = wv[5];
262                         wv[5] = wv[4];
263                         wv[4] = wv[3] + t1;
264                         wv[3] = wv[2];
265                         wv[2] = wv[1];
266                         wv[1] = wv[0];
267                         wv[0] = t1 + t2;
268                 }
269
270                 for (j = 0; j < 8; j++)
271                         ctx->h[j] += wv[j];
272 #endif /* UNROLL_LOOPS_SHA512 */
273         }
274 }
275
276 void vb2_sha512_update(struct vb2_sha512_context *ctx,
277                        const uint8_t *data,
278                        uint32_t size)
279 {
280         unsigned int block_nb;
281         unsigned int new_size, rem_size, tmp_size;
282         const uint8_t *shifted_data;
283
284         tmp_size = VB2_SHA512_BLOCK_SIZE - ctx->size;
285         rem_size = size < tmp_size ? size : tmp_size;
286
287         memcpy(&ctx->block[ctx->size], data, rem_size);
288
289         if (ctx->size + size < VB2_SHA512_BLOCK_SIZE) {
290                 ctx->size += size;
291                 return;
292         }
293
294         new_size = size - rem_size;
295         block_nb = new_size / VB2_SHA512_BLOCK_SIZE;
296
297         shifted_data = data + rem_size;
298
299         vb2_sha512_transform(ctx, ctx->block, 1);
300         vb2_sha512_transform(ctx, shifted_data, block_nb);
301
302         rem_size = new_size % VB2_SHA512_BLOCK_SIZE;
303
304         memcpy(ctx->block, &shifted_data[block_nb << 7],
305                rem_size);
306
307         ctx->size = rem_size;
308         ctx->total_size += (block_nb + 1) << 7;
309 }
310
311 void vb2_sha512_finalize(struct vb2_sha512_context *ctx, uint8_t *digest)
312 {
313         unsigned int block_nb;
314         unsigned int pm_size;
315         unsigned int size_b;
316
317 #ifndef UNROLL_LOOPS_SHA512
318         int i;
319 #endif
320
321         block_nb = 1 + ((VB2_SHA512_BLOCK_SIZE - 17)
322                         < (ctx->size % VB2_SHA512_BLOCK_SIZE));
323
324         size_b = (ctx->total_size + ctx->size) << 3;
325         pm_size = block_nb << 7;
326
327         memset(ctx->block + ctx->size, 0, pm_size - ctx->size);
328         ctx->block[ctx->size] = 0x80;
329         UNPACK32(size_b, ctx->block + pm_size - 4);
330
331         vb2_sha512_transform(ctx, ctx->block, block_nb);
332
333 #ifdef UNROLL_LOOPS_SHA512
334         UNPACK64(ctx->h[0], &digest[ 0]);
335         UNPACK64(ctx->h[1], &digest[ 8]);
336         UNPACK64(ctx->h[2], &digest[16]);
337         UNPACK64(ctx->h[3], &digest[24]);
338         UNPACK64(ctx->h[4], &digest[32]);
339         UNPACK64(ctx->h[5], &digest[40]);
340         UNPACK64(ctx->h[6], &digest[48]);
341         UNPACK64(ctx->h[7], &digest[56]);
342 #else
343         for (i = 0 ; i < 8; i++)
344                 UNPACK64(ctx->h[i], &digest[i << 3]);
345 #endif /* UNROLL_LOOPS_SHA512 */
346 }