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