1 /* $NetBSD: sha.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <config.h> 37 #include <krb5/roken.h> 38 39 #include "hash.h" 40 #include "sha.h" 41 42 #define A m->counter[0] 43 #define B m->counter[1] 44 #define C m->counter[2] 45 #define D m->counter[3] 46 #define E m->counter[4] 47 #define X data 48 49 int 50 SHA1_Init (struct sha *m) 51 { 52 m->sz[0] = 0; 53 m->sz[1] = 0; 54 A = 0x67452301; 55 B = 0xefcdab89; 56 C = 0x98badcfe; 57 D = 0x10325476; 58 E = 0xc3d2e1f0; 59 return 1; 60 } 61 62 63 #define F0(x,y,z) CRAYFIX((x & y) | (~x & z)) 64 #define F1(x,y,z) (x ^ y ^ z) 65 #define F2(x,y,z) ((x & y) | (x & z) | (y & z)) 66 #define F3(x,y,z) F1(x,y,z) 67 68 #define K0 0x5a827999 69 #define K1 0x6ed9eba1 70 #define K2 0x8f1bbcdc 71 #define K3 0xca62c1d6 72 73 #define DO(t,f,k) \ 74 do { \ 75 uint32_t temp; \ 76 \ 77 temp = cshift(AA, 5) + f(BB,CC,DD) + EE + data[t] + k; \ 78 EE = DD; \ 79 DD = CC; \ 80 CC = cshift(BB, 30); \ 81 BB = AA; \ 82 AA = temp; \ 83 } while(0) 84 85 static inline void 86 calc (struct sha *m, uint32_t *in) 87 { 88 uint32_t AA, BB, CC, DD, EE; 89 uint32_t data[80]; 90 int i; 91 92 AA = A; 93 BB = B; 94 CC = C; 95 DD = D; 96 EE = E; 97 98 for (i = 0; i < 16; ++i) 99 data[i] = in[i]; 100 for (i = 16; i < 80; ++i) 101 data[i] = cshift(data[i-3] ^ data[i-8] ^ data[i-14] ^ data[i-16], 1); 102 103 /* t=[0,19] */ 104 105 DO(0,F0,K0); 106 DO(1,F0,K0); 107 DO(2,F0,K0); 108 DO(3,F0,K0); 109 DO(4,F0,K0); 110 DO(5,F0,K0); 111 DO(6,F0,K0); 112 DO(7,F0,K0); 113 DO(8,F0,K0); 114 DO(9,F0,K0); 115 DO(10,F0,K0); 116 DO(11,F0,K0); 117 DO(12,F0,K0); 118 DO(13,F0,K0); 119 DO(14,F0,K0); 120 DO(15,F0,K0); 121 DO(16,F0,K0); 122 DO(17,F0,K0); 123 DO(18,F0,K0); 124 DO(19,F0,K0); 125 126 /* t=[20,39] */ 127 128 DO(20,F1,K1); 129 DO(21,F1,K1); 130 DO(22,F1,K1); 131 DO(23,F1,K1); 132 DO(24,F1,K1); 133 DO(25,F1,K1); 134 DO(26,F1,K1); 135 DO(27,F1,K1); 136 DO(28,F1,K1); 137 DO(29,F1,K1); 138 DO(30,F1,K1); 139 DO(31,F1,K1); 140 DO(32,F1,K1); 141 DO(33,F1,K1); 142 DO(34,F1,K1); 143 DO(35,F1,K1); 144 DO(36,F1,K1); 145 DO(37,F1,K1); 146 DO(38,F1,K1); 147 DO(39,F1,K1); 148 149 /* t=[40,59] */ 150 151 DO(40,F2,K2); 152 DO(41,F2,K2); 153 DO(42,F2,K2); 154 DO(43,F2,K2); 155 DO(44,F2,K2); 156 DO(45,F2,K2); 157 DO(46,F2,K2); 158 DO(47,F2,K2); 159 DO(48,F2,K2); 160 DO(49,F2,K2); 161 DO(50,F2,K2); 162 DO(51,F2,K2); 163 DO(52,F2,K2); 164 DO(53,F2,K2); 165 DO(54,F2,K2); 166 DO(55,F2,K2); 167 DO(56,F2,K2); 168 DO(57,F2,K2); 169 DO(58,F2,K2); 170 DO(59,F2,K2); 171 172 /* t=[60,79] */ 173 174 DO(60,F3,K3); 175 DO(61,F3,K3); 176 DO(62,F3,K3); 177 DO(63,F3,K3); 178 DO(64,F3,K3); 179 DO(65,F3,K3); 180 DO(66,F3,K3); 181 DO(67,F3,K3); 182 DO(68,F3,K3); 183 DO(69,F3,K3); 184 DO(70,F3,K3); 185 DO(71,F3,K3); 186 DO(72,F3,K3); 187 DO(73,F3,K3); 188 DO(74,F3,K3); 189 DO(75,F3,K3); 190 DO(76,F3,K3); 191 DO(77,F3,K3); 192 DO(78,F3,K3); 193 DO(79,F3,K3); 194 195 A += AA; 196 B += BB; 197 C += CC; 198 D += DD; 199 E += EE; 200 } 201 202 /* 203 * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu> 204 */ 205 206 #if !defined(WORDS_BIGENDIAN) || defined(_CRAY) 207 static inline uint32_t 208 swap_uint32_t (uint32_t t) 209 { 210 #define ROL(x,n) ((x)<<(n))|((x)>>(32-(n))) 211 uint32_t temp1, temp2; 212 213 temp1 = cshift(t, 16); 214 temp2 = temp1 >> 8; 215 temp1 &= 0x00ff00ff; 216 temp2 &= 0x00ff00ff; 217 temp1 <<= 8; 218 return temp1 | temp2; 219 } 220 #endif 221 222 struct x32{ 223 unsigned int a:32; 224 unsigned int b:32; 225 }; 226 227 int 228 SHA1_Update (struct sha *m, const void *v, size_t len) 229 { 230 const unsigned char *p = v; 231 size_t old_sz = m->sz[0]; 232 size_t offset; 233 234 m->sz[0] += len * 8; 235 if (m->sz[0] < old_sz) 236 ++m->sz[1]; 237 offset = (old_sz / 8) % 64; 238 while(len > 0){ 239 size_t l = min(len, 64 - offset); 240 memcpy(m->save + offset, p, l); 241 offset += l; 242 p += l; 243 len -= l; 244 if(offset == 64){ 245 #if !defined(WORDS_BIGENDIAN) || defined(_CRAY) 246 int i; 247 uint32_t SHA1current[16]; 248 struct x32 *us = (struct x32*)m->save; 249 for(i = 0; i < 8; i++){ 250 SHA1current[2*i+0] = swap_uint32_t(us[i].a); 251 SHA1current[2*i+1] = swap_uint32_t(us[i].b); 252 } 253 calc(m, SHA1current); 254 #else 255 calc(m, (uint32_t*)m->save); 256 #endif 257 offset = 0; 258 } 259 } 260 return 1; 261 } 262 263 int 264 SHA1_Final (void *res, struct sha *m) 265 { 266 unsigned char zeros[72]; 267 unsigned offset = (m->sz[0] / 8) % 64; 268 unsigned int dstart = (120 - offset - 1) % 64 + 1; 269 270 *zeros = 0x80; 271 memset (zeros + 1, 0, sizeof(zeros) - 1); 272 zeros[dstart+7] = (m->sz[0] >> 0) & 0xff; 273 zeros[dstart+6] = (m->sz[0] >> 8) & 0xff; 274 zeros[dstart+5] = (m->sz[0] >> 16) & 0xff; 275 zeros[dstart+4] = (m->sz[0] >> 24) & 0xff; 276 zeros[dstart+3] = (m->sz[1] >> 0) & 0xff; 277 zeros[dstart+2] = (m->sz[1] >> 8) & 0xff; 278 zeros[dstart+1] = (m->sz[1] >> 16) & 0xff; 279 zeros[dstart+0] = (m->sz[1] >> 24) & 0xff; 280 SHA1_Update (m, zeros, dstart + 8); 281 { 282 int i; 283 unsigned char *r = (unsigned char*)res; 284 285 for (i = 0; i < 5; ++i) { 286 r[4*i+3] = m->counter[i] & 0xFF; 287 r[4*i+2] = (m->counter[i] >> 8) & 0xFF; 288 r[4*i+1] = (m->counter[i] >> 16) & 0xFF; 289 r[4*i] = (m->counter[i] >> 24) & 0xFF; 290 } 291 } 292 #if 0 293 { 294 int i; 295 uint32_t *r = (uint32_t *)res; 296 297 for (i = 0; i < 5; ++i) 298 r[i] = swap_uint32_t (m->counter[i]); 299 } 300 #endif 301 return 1; 302 } 303