1*0a6a1f1dSLionel Sambuc /* $NetBSD: sha512.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 2006, 2010 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc * All rights reserved.
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc * are met:
11ebfedea0SLionel Sambuc *
12ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc *
15ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc *
19ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc * without specific prior written permission.
22ebfedea0SLionel Sambuc *
23ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc * SUCH DAMAGE.
34ebfedea0SLionel Sambuc */
35ebfedea0SLionel Sambuc
36ebfedea0SLionel Sambuc #include "config.h"
37ebfedea0SLionel Sambuc
38ebfedea0SLionel Sambuc #include "hash.h"
39ebfedea0SLionel Sambuc #include "sha.h"
40ebfedea0SLionel Sambuc
41ebfedea0SLionel Sambuc #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
42ebfedea0SLionel Sambuc #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
43ebfedea0SLionel Sambuc
44ebfedea0SLionel Sambuc #define ROTR(x,n) (((x)>>(n)) | ((x) << (64 - (n))))
45ebfedea0SLionel Sambuc
46ebfedea0SLionel Sambuc #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
47ebfedea0SLionel Sambuc #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
48ebfedea0SLionel Sambuc #define sigma0(x) (ROTR(x,1) ^ ROTR(x,8) ^ ((x)>>7))
49ebfedea0SLionel Sambuc #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ ((x)>>6))
50ebfedea0SLionel Sambuc
51ebfedea0SLionel Sambuc #define A m->counter[0]
52ebfedea0SLionel Sambuc #define B m->counter[1]
53ebfedea0SLionel Sambuc #define C m->counter[2]
54ebfedea0SLionel Sambuc #define D m->counter[3]
55ebfedea0SLionel Sambuc #define E m->counter[4]
56ebfedea0SLionel Sambuc #define F m->counter[5]
57ebfedea0SLionel Sambuc #define G m->counter[6]
58ebfedea0SLionel Sambuc #define H m->counter[7]
59ebfedea0SLionel Sambuc
60ebfedea0SLionel Sambuc static const uint64_t constant_512[80] = {
61ebfedea0SLionel Sambuc 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
62ebfedea0SLionel Sambuc 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
63ebfedea0SLionel Sambuc 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
64ebfedea0SLionel Sambuc 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
65ebfedea0SLionel Sambuc 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
66ebfedea0SLionel Sambuc 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
67ebfedea0SLionel Sambuc 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
68ebfedea0SLionel Sambuc 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
69ebfedea0SLionel Sambuc 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
70ebfedea0SLionel Sambuc 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
71ebfedea0SLionel Sambuc 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
72ebfedea0SLionel Sambuc 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
73ebfedea0SLionel Sambuc 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
74ebfedea0SLionel Sambuc 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
75ebfedea0SLionel Sambuc 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
76ebfedea0SLionel Sambuc 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
77ebfedea0SLionel Sambuc 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
78ebfedea0SLionel Sambuc 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
79ebfedea0SLionel Sambuc 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
80ebfedea0SLionel Sambuc 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
81ebfedea0SLionel Sambuc 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
82ebfedea0SLionel Sambuc 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
83ebfedea0SLionel Sambuc 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
84ebfedea0SLionel Sambuc 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
85ebfedea0SLionel Sambuc 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
86ebfedea0SLionel Sambuc 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
87ebfedea0SLionel Sambuc 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
88ebfedea0SLionel Sambuc 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
89ebfedea0SLionel Sambuc 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
90ebfedea0SLionel Sambuc 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
91ebfedea0SLionel Sambuc 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
92ebfedea0SLionel Sambuc 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
93ebfedea0SLionel Sambuc 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
94ebfedea0SLionel Sambuc 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
95ebfedea0SLionel Sambuc 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
96ebfedea0SLionel Sambuc 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
97ebfedea0SLionel Sambuc 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
98ebfedea0SLionel Sambuc 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
99ebfedea0SLionel Sambuc 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
100ebfedea0SLionel Sambuc 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
101ebfedea0SLionel Sambuc };
102ebfedea0SLionel Sambuc
103ebfedea0SLionel Sambuc void
SHA512_Init(SHA512_CTX * m)104ebfedea0SLionel Sambuc SHA512_Init (SHA512_CTX *m)
105ebfedea0SLionel Sambuc {
106ebfedea0SLionel Sambuc m->sz[0] = 0;
107ebfedea0SLionel Sambuc m->sz[1] = 0;
108ebfedea0SLionel Sambuc A = 0x6a09e667f3bcc908ULL;
109ebfedea0SLionel Sambuc B = 0xbb67ae8584caa73bULL;
110ebfedea0SLionel Sambuc C = 0x3c6ef372fe94f82bULL;
111ebfedea0SLionel Sambuc D = 0xa54ff53a5f1d36f1ULL;
112ebfedea0SLionel Sambuc E = 0x510e527fade682d1ULL;
113ebfedea0SLionel Sambuc F = 0x9b05688c2b3e6c1fULL;
114ebfedea0SLionel Sambuc G = 0x1f83d9abfb41bd6bULL;
115ebfedea0SLionel Sambuc H = 0x5be0cd19137e2179ULL;
116ebfedea0SLionel Sambuc }
117ebfedea0SLionel Sambuc
118ebfedea0SLionel Sambuc static void
calc(SHA512_CTX * m,uint64_t * in)119ebfedea0SLionel Sambuc calc (SHA512_CTX *m, uint64_t *in)
120ebfedea0SLionel Sambuc {
121ebfedea0SLionel Sambuc uint64_t AA, BB, CC, DD, EE, FF, GG, HH;
122ebfedea0SLionel Sambuc uint64_t data[80];
123ebfedea0SLionel Sambuc int i;
124ebfedea0SLionel Sambuc
125ebfedea0SLionel Sambuc AA = A;
126ebfedea0SLionel Sambuc BB = B;
127ebfedea0SLionel Sambuc CC = C;
128ebfedea0SLionel Sambuc DD = D;
129ebfedea0SLionel Sambuc EE = E;
130ebfedea0SLionel Sambuc FF = F;
131ebfedea0SLionel Sambuc GG = G;
132ebfedea0SLionel Sambuc HH = H;
133ebfedea0SLionel Sambuc
134ebfedea0SLionel Sambuc for (i = 0; i < 16; ++i)
135ebfedea0SLionel Sambuc data[i] = in[i];
136ebfedea0SLionel Sambuc for (i = 16; i < 80; ++i)
137ebfedea0SLionel Sambuc data[i] = sigma1(data[i-2]) + data[i-7] +
138ebfedea0SLionel Sambuc sigma0(data[i-15]) + data[i - 16];
139ebfedea0SLionel Sambuc
140ebfedea0SLionel Sambuc for (i = 0; i < 80; i++) {
141ebfedea0SLionel Sambuc uint64_t T1, T2;
142ebfedea0SLionel Sambuc
143ebfedea0SLionel Sambuc T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_512[i] + data[i];
144ebfedea0SLionel Sambuc T2 = Sigma0(AA) + Maj(AA,BB,CC);
145ebfedea0SLionel Sambuc
146ebfedea0SLionel Sambuc HH = GG;
147ebfedea0SLionel Sambuc GG = FF;
148ebfedea0SLionel Sambuc FF = EE;
149ebfedea0SLionel Sambuc EE = DD + T1;
150ebfedea0SLionel Sambuc DD = CC;
151ebfedea0SLionel Sambuc CC = BB;
152ebfedea0SLionel Sambuc BB = AA;
153ebfedea0SLionel Sambuc AA = T1 + T2;
154ebfedea0SLionel Sambuc }
155ebfedea0SLionel Sambuc
156ebfedea0SLionel Sambuc A += AA;
157ebfedea0SLionel Sambuc B += BB;
158ebfedea0SLionel Sambuc C += CC;
159ebfedea0SLionel Sambuc D += DD;
160ebfedea0SLionel Sambuc E += EE;
161ebfedea0SLionel Sambuc F += FF;
162ebfedea0SLionel Sambuc G += GG;
163ebfedea0SLionel Sambuc H += HH;
164ebfedea0SLionel Sambuc }
165ebfedea0SLionel Sambuc
166ebfedea0SLionel Sambuc /*
167ebfedea0SLionel Sambuc * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
168ebfedea0SLionel Sambuc */
169ebfedea0SLionel Sambuc
170ebfedea0SLionel Sambuc #if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
171ebfedea0SLionel Sambuc static inline uint64_t
swap_uint64_t(uint64_t t)172ebfedea0SLionel Sambuc swap_uint64_t (uint64_t t)
173ebfedea0SLionel Sambuc {
174ebfedea0SLionel Sambuc uint64_t temp;
175ebfedea0SLionel Sambuc
176ebfedea0SLionel Sambuc temp = cshift64(t, 32);
177ebfedea0SLionel Sambuc temp = ((temp & 0xff00ff00ff00ff00ULL) >> 8) |
178ebfedea0SLionel Sambuc ((temp & 0x00ff00ff00ff00ffULL) << 8);
179ebfedea0SLionel Sambuc return ((temp & 0xffff0000ffff0000ULL) >> 16) |
180ebfedea0SLionel Sambuc ((temp & 0x0000ffff0000ffffULL) << 16);
181ebfedea0SLionel Sambuc }
182ebfedea0SLionel Sambuc
183ebfedea0SLionel Sambuc struct x64{
184ebfedea0SLionel Sambuc uint64_t a;
185ebfedea0SLionel Sambuc uint64_t b;
186ebfedea0SLionel Sambuc };
187ebfedea0SLionel Sambuc #endif
188ebfedea0SLionel Sambuc
189ebfedea0SLionel Sambuc void
SHA512_Update(SHA512_CTX * m,const void * v,size_t len)190ebfedea0SLionel Sambuc SHA512_Update (SHA512_CTX *m, const void *v, size_t len)
191ebfedea0SLionel Sambuc {
192ebfedea0SLionel Sambuc const unsigned char *p = v;
193ebfedea0SLionel Sambuc size_t old_sz = m->sz[0];
194ebfedea0SLionel Sambuc size_t offset;
195ebfedea0SLionel Sambuc
196ebfedea0SLionel Sambuc m->sz[0] += len * 8;
197ebfedea0SLionel Sambuc if (m->sz[0] < old_sz)
198ebfedea0SLionel Sambuc ++m->sz[1];
199ebfedea0SLionel Sambuc offset = (old_sz / 8) % 128;
200ebfedea0SLionel Sambuc while(len > 0){
201ebfedea0SLionel Sambuc size_t l = min(len, 128 - offset);
202ebfedea0SLionel Sambuc memcpy(m->save + offset, p, l);
203ebfedea0SLionel Sambuc offset += l;
204ebfedea0SLionel Sambuc p += l;
205ebfedea0SLionel Sambuc len -= l;
206ebfedea0SLionel Sambuc if(offset == 128){
207ebfedea0SLionel Sambuc #if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
208ebfedea0SLionel Sambuc int i;
209ebfedea0SLionel Sambuc uint64_t current[16];
210ebfedea0SLionel Sambuc struct x64 *us = (struct x64*)m->save;
211ebfedea0SLionel Sambuc for(i = 0; i < 8; i++){
212ebfedea0SLionel Sambuc current[2*i+0] = swap_uint64_t(us[i].a);
213ebfedea0SLionel Sambuc current[2*i+1] = swap_uint64_t(us[i].b);
214ebfedea0SLionel Sambuc }
215ebfedea0SLionel Sambuc calc(m, current);
216ebfedea0SLionel Sambuc #else
217ebfedea0SLionel Sambuc calc(m, (uint64_t*)m->save);
218ebfedea0SLionel Sambuc #endif
219ebfedea0SLionel Sambuc offset = 0;
220ebfedea0SLionel Sambuc }
221ebfedea0SLionel Sambuc }
222ebfedea0SLionel Sambuc }
223ebfedea0SLionel Sambuc
224ebfedea0SLionel Sambuc void
SHA512_Final(void * res,SHA512_CTX * m)225ebfedea0SLionel Sambuc SHA512_Final (void *res, SHA512_CTX *m)
226ebfedea0SLionel Sambuc {
227ebfedea0SLionel Sambuc unsigned char zeros[128 + 16];
228ebfedea0SLionel Sambuc unsigned offset = (m->sz[0] / 8) % 128;
229ebfedea0SLionel Sambuc unsigned int dstart = (240 - offset - 1) % 128 + 1;
230ebfedea0SLionel Sambuc
231ebfedea0SLionel Sambuc *zeros = 0x80;
232ebfedea0SLionel Sambuc memset (zeros + 1, 0, sizeof(zeros) - 1);
233ebfedea0SLionel Sambuc zeros[dstart+15] = (m->sz[0] >> 0) & 0xff;
234ebfedea0SLionel Sambuc zeros[dstart+14] = (m->sz[0] >> 8) & 0xff;
235ebfedea0SLionel Sambuc zeros[dstart+13] = (m->sz[0] >> 16) & 0xff;
236ebfedea0SLionel Sambuc zeros[dstart+12] = (m->sz[0] >> 24) & 0xff;
237ebfedea0SLionel Sambuc zeros[dstart+11] = (m->sz[0] >> 32) & 0xff;
238ebfedea0SLionel Sambuc zeros[dstart+10] = (m->sz[0] >> 40) & 0xff;
239ebfedea0SLionel Sambuc zeros[dstart+9] = (m->sz[0] >> 48) & 0xff;
240ebfedea0SLionel Sambuc zeros[dstart+8] = (m->sz[0] >> 56) & 0xff;
241ebfedea0SLionel Sambuc
242ebfedea0SLionel Sambuc zeros[dstart+7] = (m->sz[1] >> 0) & 0xff;
243ebfedea0SLionel Sambuc zeros[dstart+6] = (m->sz[1] >> 8) & 0xff;
244ebfedea0SLionel Sambuc zeros[dstart+5] = (m->sz[1] >> 16) & 0xff;
245ebfedea0SLionel Sambuc zeros[dstart+4] = (m->sz[1] >> 24) & 0xff;
246ebfedea0SLionel Sambuc zeros[dstart+3] = (m->sz[1] >> 32) & 0xff;
247ebfedea0SLionel Sambuc zeros[dstart+2] = (m->sz[1] >> 40) & 0xff;
248ebfedea0SLionel Sambuc zeros[dstart+1] = (m->sz[1] >> 48) & 0xff;
249ebfedea0SLionel Sambuc zeros[dstart+0] = (m->sz[1] >> 56) & 0xff;
250ebfedea0SLionel Sambuc SHA512_Update (m, zeros, dstart + 16);
251ebfedea0SLionel Sambuc {
252ebfedea0SLionel Sambuc int i;
253ebfedea0SLionel Sambuc unsigned char *r = (unsigned char*)res;
254ebfedea0SLionel Sambuc
255ebfedea0SLionel Sambuc for (i = 0; i < 8; ++i) {
256ebfedea0SLionel Sambuc r[8*i+7] = m->counter[i] & 0xFF;
257ebfedea0SLionel Sambuc r[8*i+6] = (m->counter[i] >> 8) & 0xFF;
258ebfedea0SLionel Sambuc r[8*i+5] = (m->counter[i] >> 16) & 0xFF;
259ebfedea0SLionel Sambuc r[8*i+4] = (m->counter[i] >> 24) & 0xFF;
260ebfedea0SLionel Sambuc r[8*i+3] = (m->counter[i] >> 32) & 0XFF;
261ebfedea0SLionel Sambuc r[8*i+2] = (m->counter[i] >> 40) & 0xFF;
262ebfedea0SLionel Sambuc r[8*i+1] = (m->counter[i] >> 48) & 0xFF;
263ebfedea0SLionel Sambuc r[8*i] = (m->counter[i] >> 56) & 0xFF;
264ebfedea0SLionel Sambuc }
265ebfedea0SLionel Sambuc }
266ebfedea0SLionel Sambuc }
267ebfedea0SLionel Sambuc
268ebfedea0SLionel Sambuc void
SHA384_Init(SHA384_CTX * m)269ebfedea0SLionel Sambuc SHA384_Init(SHA384_CTX *m)
270ebfedea0SLionel Sambuc {
271ebfedea0SLionel Sambuc m->sz[0] = 0;
272ebfedea0SLionel Sambuc m->sz[1] = 0;
273ebfedea0SLionel Sambuc A = 0xcbbb9d5dc1059ed8ULL;
274ebfedea0SLionel Sambuc B = 0x629a292a367cd507ULL;
275ebfedea0SLionel Sambuc C = 0x9159015a3070dd17ULL;
276ebfedea0SLionel Sambuc D = 0x152fecd8f70e5939ULL;
277ebfedea0SLionel Sambuc E = 0x67332667ffc00b31ULL;
278ebfedea0SLionel Sambuc F = 0x8eb44a8768581511ULL;
279ebfedea0SLionel Sambuc G = 0xdb0c2e0d64f98fa7ULL;
280ebfedea0SLionel Sambuc H = 0x47b5481dbefa4fa4ULL;
281ebfedea0SLionel Sambuc }
282ebfedea0SLionel Sambuc
283ebfedea0SLionel Sambuc void
SHA384_Update(SHA384_CTX * m,const void * v,size_t len)284ebfedea0SLionel Sambuc SHA384_Update (SHA384_CTX *m, const void *v, size_t len)
285ebfedea0SLionel Sambuc {
286ebfedea0SLionel Sambuc SHA512_Update(m, v, len);
287ebfedea0SLionel Sambuc }
288ebfedea0SLionel Sambuc
289ebfedea0SLionel Sambuc void
SHA384_Final(void * res,SHA384_CTX * m)290ebfedea0SLionel Sambuc SHA384_Final (void *res, SHA384_CTX *m)
291ebfedea0SLionel Sambuc {
292ebfedea0SLionel Sambuc unsigned char data[SHA512_DIGEST_LENGTH];
293ebfedea0SLionel Sambuc SHA512_Final(data, m);
294ebfedea0SLionel Sambuc memcpy(res, data, SHA384_DIGEST_LENGTH);
295ebfedea0SLionel Sambuc }
296ebfedea0SLionel Sambuc
297