1*0a6a1f1dSLionel Sambuc /* $NetBSD: sha256.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 2006 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) << (32 - (n))))
45ebfedea0SLionel Sambuc
46ebfedea0SLionel Sambuc #define Sigma0(x) (ROTR(x,2) ^ ROTR(x,13) ^ ROTR(x,22))
47ebfedea0SLionel Sambuc #define Sigma1(x) (ROTR(x,6) ^ ROTR(x,11) ^ ROTR(x,25))
48ebfedea0SLionel Sambuc #define sigma0(x) (ROTR(x,7) ^ ROTR(x,18) ^ ((x)>>3))
49ebfedea0SLionel Sambuc #define sigma1(x) (ROTR(x,17) ^ ROTR(x,19) ^ ((x)>>10))
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 uint32_t constant_256[64] = {
61ebfedea0SLionel Sambuc 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
62ebfedea0SLionel Sambuc 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
63ebfedea0SLionel Sambuc 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
64ebfedea0SLionel Sambuc 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
65ebfedea0SLionel Sambuc 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
66ebfedea0SLionel Sambuc 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
67ebfedea0SLionel Sambuc 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
68ebfedea0SLionel Sambuc 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
69ebfedea0SLionel Sambuc 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
70ebfedea0SLionel Sambuc 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
71ebfedea0SLionel Sambuc 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
72ebfedea0SLionel Sambuc 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
73ebfedea0SLionel Sambuc 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
74ebfedea0SLionel Sambuc 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
75ebfedea0SLionel Sambuc 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
76ebfedea0SLionel Sambuc 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
77ebfedea0SLionel Sambuc };
78ebfedea0SLionel Sambuc
79ebfedea0SLionel Sambuc void
SHA256_Init(SHA256_CTX * m)80ebfedea0SLionel Sambuc SHA256_Init (SHA256_CTX *m)
81ebfedea0SLionel Sambuc {
82ebfedea0SLionel Sambuc m->sz[0] = 0;
83ebfedea0SLionel Sambuc m->sz[1] = 0;
84ebfedea0SLionel Sambuc A = 0x6a09e667;
85ebfedea0SLionel Sambuc B = 0xbb67ae85;
86ebfedea0SLionel Sambuc C = 0x3c6ef372;
87ebfedea0SLionel Sambuc D = 0xa54ff53a;
88ebfedea0SLionel Sambuc E = 0x510e527f;
89ebfedea0SLionel Sambuc F = 0x9b05688c;
90ebfedea0SLionel Sambuc G = 0x1f83d9ab;
91ebfedea0SLionel Sambuc H = 0x5be0cd19;
92ebfedea0SLionel Sambuc }
93ebfedea0SLionel Sambuc
94ebfedea0SLionel Sambuc static void
calc(SHA256_CTX * m,uint32_t * in)95ebfedea0SLionel Sambuc calc (SHA256_CTX *m, uint32_t *in)
96ebfedea0SLionel Sambuc {
97ebfedea0SLionel Sambuc uint32_t AA, BB, CC, DD, EE, FF, GG, HH;
98ebfedea0SLionel Sambuc uint32_t data[64];
99ebfedea0SLionel Sambuc int i;
100ebfedea0SLionel Sambuc
101ebfedea0SLionel Sambuc AA = A;
102ebfedea0SLionel Sambuc BB = B;
103ebfedea0SLionel Sambuc CC = C;
104ebfedea0SLionel Sambuc DD = D;
105ebfedea0SLionel Sambuc EE = E;
106ebfedea0SLionel Sambuc FF = F;
107ebfedea0SLionel Sambuc GG = G;
108ebfedea0SLionel Sambuc HH = H;
109ebfedea0SLionel Sambuc
110ebfedea0SLionel Sambuc for (i = 0; i < 16; ++i)
111ebfedea0SLionel Sambuc data[i] = in[i];
112ebfedea0SLionel Sambuc for (i = 16; i < 64; ++i)
113ebfedea0SLionel Sambuc data[i] = sigma1(data[i-2]) + data[i-7] +
114ebfedea0SLionel Sambuc sigma0(data[i-15]) + data[i - 16];
115ebfedea0SLionel Sambuc
116ebfedea0SLionel Sambuc for (i = 0; i < 64; i++) {
117ebfedea0SLionel Sambuc uint32_t T1, T2;
118ebfedea0SLionel Sambuc
119ebfedea0SLionel Sambuc T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_256[i] + data[i];
120ebfedea0SLionel Sambuc T2 = Sigma0(AA) + Maj(AA,BB,CC);
121ebfedea0SLionel Sambuc
122ebfedea0SLionel Sambuc HH = GG;
123ebfedea0SLionel Sambuc GG = FF;
124ebfedea0SLionel Sambuc FF = EE;
125ebfedea0SLionel Sambuc EE = DD + T1;
126ebfedea0SLionel Sambuc DD = CC;
127ebfedea0SLionel Sambuc CC = BB;
128ebfedea0SLionel Sambuc BB = AA;
129ebfedea0SLionel Sambuc AA = T1 + T2;
130ebfedea0SLionel Sambuc }
131ebfedea0SLionel Sambuc
132ebfedea0SLionel Sambuc A += AA;
133ebfedea0SLionel Sambuc B += BB;
134ebfedea0SLionel Sambuc C += CC;
135ebfedea0SLionel Sambuc D += DD;
136ebfedea0SLionel Sambuc E += EE;
137ebfedea0SLionel Sambuc F += FF;
138ebfedea0SLionel Sambuc G += GG;
139ebfedea0SLionel Sambuc H += HH;
140ebfedea0SLionel Sambuc }
141ebfedea0SLionel Sambuc
142ebfedea0SLionel Sambuc /*
143ebfedea0SLionel Sambuc * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
144ebfedea0SLionel Sambuc */
145ebfedea0SLionel Sambuc
146ebfedea0SLionel Sambuc #if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
147ebfedea0SLionel Sambuc static inline uint32_t
swap_uint32_t(uint32_t t)148ebfedea0SLionel Sambuc swap_uint32_t (uint32_t t)
149ebfedea0SLionel Sambuc {
150ebfedea0SLionel Sambuc #define ROL(x,n) ((x)<<(n))|((x)>>(32-(n)))
151ebfedea0SLionel Sambuc uint32_t temp1, temp2;
152ebfedea0SLionel Sambuc
153ebfedea0SLionel Sambuc temp1 = cshift(t, 16);
154ebfedea0SLionel Sambuc temp2 = temp1 >> 8;
155ebfedea0SLionel Sambuc temp1 &= 0x00ff00ff;
156ebfedea0SLionel Sambuc temp2 &= 0x00ff00ff;
157ebfedea0SLionel Sambuc temp1 <<= 8;
158ebfedea0SLionel Sambuc return temp1 | temp2;
159ebfedea0SLionel Sambuc }
160ebfedea0SLionel Sambuc #endif
161ebfedea0SLionel Sambuc
162ebfedea0SLionel Sambuc struct x32{
163ebfedea0SLionel Sambuc unsigned int a:32;
164ebfedea0SLionel Sambuc unsigned int b:32;
165ebfedea0SLionel Sambuc };
166ebfedea0SLionel Sambuc
167ebfedea0SLionel Sambuc void
SHA256_Update(SHA256_CTX * m,const void * v,size_t len)168ebfedea0SLionel Sambuc SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
169ebfedea0SLionel Sambuc {
170ebfedea0SLionel Sambuc const unsigned char *p = v;
171ebfedea0SLionel Sambuc size_t old_sz = m->sz[0];
172ebfedea0SLionel Sambuc size_t offset;
173ebfedea0SLionel Sambuc
174ebfedea0SLionel Sambuc m->sz[0] += len * 8;
175ebfedea0SLionel Sambuc if (m->sz[0] < old_sz)
176ebfedea0SLionel Sambuc ++m->sz[1];
177ebfedea0SLionel Sambuc offset = (old_sz / 8) % 64;
178ebfedea0SLionel Sambuc while(len > 0){
179ebfedea0SLionel Sambuc size_t l = min(len, 64 - offset);
180ebfedea0SLionel Sambuc memcpy(m->save + offset, p, l);
181ebfedea0SLionel Sambuc offset += l;
182ebfedea0SLionel Sambuc p += l;
183ebfedea0SLionel Sambuc len -= l;
184ebfedea0SLionel Sambuc if(offset == 64){
185ebfedea0SLionel Sambuc #if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
186ebfedea0SLionel Sambuc int i;
187ebfedea0SLionel Sambuc uint32_t current[16];
188ebfedea0SLionel Sambuc struct x32 *us = (struct x32*)m->save;
189ebfedea0SLionel Sambuc for(i = 0; i < 8; i++){
190ebfedea0SLionel Sambuc current[2*i+0] = swap_uint32_t(us[i].a);
191ebfedea0SLionel Sambuc current[2*i+1] = swap_uint32_t(us[i].b);
192ebfedea0SLionel Sambuc }
193ebfedea0SLionel Sambuc calc(m, current);
194ebfedea0SLionel Sambuc #else
195ebfedea0SLionel Sambuc calc(m, (uint32_t*)m->save);
196ebfedea0SLionel Sambuc #endif
197ebfedea0SLionel Sambuc offset = 0;
198ebfedea0SLionel Sambuc }
199ebfedea0SLionel Sambuc }
200ebfedea0SLionel Sambuc }
201ebfedea0SLionel Sambuc
202ebfedea0SLionel Sambuc void
SHA256_Final(void * res,SHA256_CTX * m)203ebfedea0SLionel Sambuc SHA256_Final (void *res, SHA256_CTX *m)
204ebfedea0SLionel Sambuc {
205ebfedea0SLionel Sambuc unsigned char zeros[72];
206ebfedea0SLionel Sambuc unsigned offset = (m->sz[0] / 8) % 64;
207ebfedea0SLionel Sambuc unsigned int dstart = (120 - offset - 1) % 64 + 1;
208ebfedea0SLionel Sambuc
209ebfedea0SLionel Sambuc *zeros = 0x80;
210ebfedea0SLionel Sambuc memset (zeros + 1, 0, sizeof(zeros) - 1);
211ebfedea0SLionel Sambuc zeros[dstart+7] = (m->sz[0] >> 0) & 0xff;
212ebfedea0SLionel Sambuc zeros[dstart+6] = (m->sz[0] >> 8) & 0xff;
213ebfedea0SLionel Sambuc zeros[dstart+5] = (m->sz[0] >> 16) & 0xff;
214ebfedea0SLionel Sambuc zeros[dstart+4] = (m->sz[0] >> 24) & 0xff;
215ebfedea0SLionel Sambuc zeros[dstart+3] = (m->sz[1] >> 0) & 0xff;
216ebfedea0SLionel Sambuc zeros[dstart+2] = (m->sz[1] >> 8) & 0xff;
217ebfedea0SLionel Sambuc zeros[dstart+1] = (m->sz[1] >> 16) & 0xff;
218ebfedea0SLionel Sambuc zeros[dstart+0] = (m->sz[1] >> 24) & 0xff;
219ebfedea0SLionel Sambuc SHA256_Update (m, zeros, dstart + 8);
220ebfedea0SLionel Sambuc {
221ebfedea0SLionel Sambuc int i;
222ebfedea0SLionel Sambuc unsigned char *r = (unsigned char*)res;
223ebfedea0SLionel Sambuc
224ebfedea0SLionel Sambuc for (i = 0; i < 8; ++i) {
225ebfedea0SLionel Sambuc r[4*i+3] = m->counter[i] & 0xFF;
226ebfedea0SLionel Sambuc r[4*i+2] = (m->counter[i] >> 8) & 0xFF;
227ebfedea0SLionel Sambuc r[4*i+1] = (m->counter[i] >> 16) & 0xFF;
228ebfedea0SLionel Sambuc r[4*i] = (m->counter[i] >> 24) & 0xFF;
229ebfedea0SLionel Sambuc }
230ebfedea0SLionel Sambuc }
231ebfedea0SLionel Sambuc }
232