182095Simp/* $NetBSD: sha512.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */ 299638Simp 382095Simp/* 482095Simp * Copyright (c) 2006, 2010 Kungliga Tekniska H��gskolan 582095Simp * (Royal Institute of Technology, Stockholm, Sweden). 682095Simp * All rights reserved. 782095Simp * 882095Simp * Redistribution and use in source and binary forms, with or without 982095Simp * modification, are permitted provided that the following conditions 1082095Simp * are met: 1182095Simp * 1282095Simp * 1. Redistributions of source code must retain the above copyright 1382095Simp * notice, this list of conditions and the following disclaimer. 1482095Simp * 1582095Simp * 2. Redistributions in binary form must reproduce the above copyright 1682095Simp * notice, this list of conditions and the following disclaimer in the 1782095Simp * documentation and/or other materials provided with the distribution. 1882095Simp * 1982095Simp * 3. Neither the name of the Institute nor the names of its contributors 2082095Simp * may be used to endorse or promote products derived from this software 2182095Simp * without specific prior written permission. 2282095Simp * 2382095Simp * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2482095Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25141580Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2682095Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2799638Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2882095Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2982447Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3082095Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3182095Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32119169Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3382095Simp * SUCH DAMAGE. 3482095Simp */ 3599637Simp 3682095Simp#include <config.h> 3782095Simp#include <krb5/roken.h> 3882095Simp 39101805Sru#include "hash.h" 4082095Simp#include "sha.h" 4182095Simp 4282095Simp#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 4382095Simp#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 4499637Simp 4582095Simp#define ROTR(x,n) (((x)>>(n)) | ((x) << (64 - (n)))) 4699637Simp 4782095Simp#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) 4899637Simp#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) 4982095Simp#define sigma0(x) (ROTR(x,1) ^ ROTR(x,8) ^ ((x)>>7)) 5082095Simp#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ ((x)>>6)) 5182095Simp 5282095Simp#define A m->counter[0] 5382447Simp#define B m->counter[1] 5482095Simp#define C m->counter[2] 5582095Simp#define D m->counter[3] 5682095Simp#define E m->counter[4] 5782095Simp#define F m->counter[5] 5882447Simp#define G m->counter[6] 59119169Simp#define H m->counter[7] 6082095Simp 6182447Simpstatic const uint64_t constant_512[80] = { 6282447Simp 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 6382095Simp 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 6482095Simp 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 6582095Simp 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 6682095Simp 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 6782095Simp 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 6882095Simp 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 6982095Simp 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 7082447Simp 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 7182095Simp 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 7282095Simp 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 7382095Simp 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 74119169Simp 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 7582447Simp 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 7682095Simp 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 7782095Simp 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 7882095Simp 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 7982447Simp 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 8082095Simp 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 8182095Simp 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 8282095Simp 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 8382095Simp 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 8482095Simp 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 8582095Simp 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 8682447Simp 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 8782095Simp 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 8882095Simp 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 8982095Simp 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 9082095Simp 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 9182095Simp 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 9282095Simp 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 9399637Simp 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 9482447Simp 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 9582095Simp 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 9682095Simp 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 9782095Simp 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 9882095Simp 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 9982095Simp 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 10082095Simp 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 10182447Simp 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 10282095Simp}; 10399637Simp 104int 105SHA512_Init (SHA512_CTX *m) 106{ 107 m->sz[0] = 0; 108 m->sz[1] = 0; 109 A = 0x6a09e667f3bcc908ULL; 110 B = 0xbb67ae8584caa73bULL; 111 C = 0x3c6ef372fe94f82bULL; 112 D = 0xa54ff53a5f1d36f1ULL; 113 E = 0x510e527fade682d1ULL; 114 F = 0x9b05688c2b3e6c1fULL; 115 G = 0x1f83d9abfb41bd6bULL; 116 H = 0x5be0cd19137e2179ULL; 117 return 1; 118} 119 120static void 121calc (SHA512_CTX *m, uint64_t *in) 122{ 123 uint64_t AA, BB, CC, DD, EE, FF, GG, HH; 124 uint64_t data[80]; 125 int i; 126 127 AA = A; 128 BB = B; 129 CC = C; 130 DD = D; 131 EE = E; 132 FF = F; 133 GG = G; 134 HH = H; 135 136 for (i = 0; i < 16; ++i) 137 data[i] = in[i]; 138 for (i = 16; i < 80; ++i) 139 data[i] = sigma1(data[i-2]) + data[i-7] + 140 sigma0(data[i-15]) + data[i - 16]; 141 142 for (i = 0; i < 80; i++) { 143 uint64_t T1, T2; 144 145 T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_512[i] + data[i]; 146 T2 = Sigma0(AA) + Maj(AA,BB,CC); 147 148 HH = GG; 149 GG = FF; 150 FF = EE; 151 EE = DD + T1; 152 DD = CC; 153 CC = BB; 154 BB = AA; 155 AA = T1 + T2; 156 } 157 158 A += AA; 159 B += BB; 160 C += CC; 161 D += DD; 162 E += EE; 163 F += FF; 164 G += GG; 165 H += HH; 166} 167 168/* 169 * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu> 170 */ 171 172#if !defined(WORDS_BIGENDIAN) || defined(_CRAY) 173static inline uint64_t 174swap_uint64_t (uint64_t t) 175{ 176 uint64_t temp; 177 178 temp = cshift64(t, 32); 179 temp = ((temp & 0xff00ff00ff00ff00ULL) >> 8) | 180 ((temp & 0x00ff00ff00ff00ffULL) << 8); 181 return ((temp & 0xffff0000ffff0000ULL) >> 16) | 182 ((temp & 0x0000ffff0000ffffULL) << 16); 183} 184 185struct x64{ 186 uint64_t a; 187 uint64_t b; 188}; 189#endif 190 191int 192SHA512_Update (SHA512_CTX *m, const void *v, size_t len) 193{ 194 const unsigned char *p = v; 195 size_t old_sz = m->sz[0]; 196 size_t offset; 197 198 m->sz[0] += len * 8; 199 if (m->sz[0] < old_sz) 200 ++m->sz[1]; 201 offset = (old_sz / 8) % 128; 202 while(len > 0){ 203 size_t l = min(len, 128 - offset); 204 memcpy(m->save + offset, p, l); 205 offset += l; 206 p += l; 207 len -= l; 208 if(offset == 128){ 209#if !defined(WORDS_BIGENDIAN) || defined(_CRAY) 210 int i; 211 uint64_t current[16]; 212 struct x64 *us = (struct x64*)m->save; 213 for(i = 0; i < 8; i++){ 214 current[2*i+0] = swap_uint64_t(us[i].a); 215 current[2*i+1] = swap_uint64_t(us[i].b); 216 } 217 calc(m, current); 218#else 219 calc(m, (uint64_t*)m->save); 220#endif 221 offset = 0; 222 } 223 } 224 return 1; 225} 226 227int 228SHA512_Final (void *res, SHA512_CTX *m) 229{ 230 unsigned char zeros[128 + 16]; 231 unsigned offset = (m->sz[0] / 8) % 128; 232 unsigned int dstart = (240 - offset - 1) % 128 + 1; 233 234 *zeros = 0x80; 235 memset (zeros + 1, 0, sizeof(zeros) - 1); 236 zeros[dstart+15] = (m->sz[0] >> 0) & 0xff; 237 zeros[dstart+14] = (m->sz[0] >> 8) & 0xff; 238 zeros[dstart+13] = (m->sz[0] >> 16) & 0xff; 239 zeros[dstart+12] = (m->sz[0] >> 24) & 0xff; 240 zeros[dstart+11] = (m->sz[0] >> 32) & 0xff; 241 zeros[dstart+10] = (m->sz[0] >> 40) & 0xff; 242 zeros[dstart+9] = (m->sz[0] >> 48) & 0xff; 243 zeros[dstart+8] = (m->sz[0] >> 56) & 0xff; 244 245 zeros[dstart+7] = (m->sz[1] >> 0) & 0xff; 246 zeros[dstart+6] = (m->sz[1] >> 8) & 0xff; 247 zeros[dstart+5] = (m->sz[1] >> 16) & 0xff; 248 zeros[dstart+4] = (m->sz[1] >> 24) & 0xff; 249 zeros[dstart+3] = (m->sz[1] >> 32) & 0xff; 250 zeros[dstart+2] = (m->sz[1] >> 40) & 0xff; 251 zeros[dstart+1] = (m->sz[1] >> 48) & 0xff; 252 zeros[dstart+0] = (m->sz[1] >> 56) & 0xff; 253 SHA512_Update (m, zeros, dstart + 16); 254 { 255 int i; 256 unsigned char *r = (unsigned char*)res; 257 258 for (i = 0; i < 8; ++i) { 259 r[8*i+7] = m->counter[i] & 0xFF; 260 r[8*i+6] = (m->counter[i] >> 8) & 0xFF; 261 r[8*i+5] = (m->counter[i] >> 16) & 0xFF; 262 r[8*i+4] = (m->counter[i] >> 24) & 0xFF; 263 r[8*i+3] = (m->counter[i] >> 32) & 0XFF; 264 r[8*i+2] = (m->counter[i] >> 40) & 0xFF; 265 r[8*i+1] = (m->counter[i] >> 48) & 0xFF; 266 r[8*i] = (m->counter[i] >> 56) & 0xFF; 267 } 268 } 269 return 1; 270} 271 272int 273SHA384_Init(SHA384_CTX *m) 274{ 275 m->sz[0] = 0; 276 m->sz[1] = 0; 277 A = 0xcbbb9d5dc1059ed8ULL; 278 B = 0x629a292a367cd507ULL; 279 C = 0x9159015a3070dd17ULL; 280 D = 0x152fecd8f70e5939ULL; 281 E = 0x67332667ffc00b31ULL; 282 F = 0x8eb44a8768581511ULL; 283 G = 0xdb0c2e0d64f98fa7ULL; 284 H = 0x47b5481dbefa4fa4ULL; 285 return 1; 286} 287 288int 289SHA384_Update (SHA384_CTX *m, const void *v, size_t len) 290{ 291 SHA512_Update(m, v, len); 292 return 1; 293} 294 295int 296SHA384_Final (void *res, SHA384_CTX *m) 297{ 298 unsigned char data[SHA512_DIGEST_LENGTH]; 299 SHA512_Final(data, m); 300 memcpy(res, data, SHA384_DIGEST_LENGTH); 301 return 1; 302} 303 304