xref: /minix3/crypto/external/bsd/heimdal/dist/lib/hcrypto/sha256.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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