1 /* SHA-256 and SHA-512 implementation based on code by Oliver Gay 2 * <olivier.gay (at) a3.epfl.ch> under a BSD-style license. See below. 3 */ 4 5 /* 6 * FIPS 180-2 SHA-224/256/384/512 implementation 7 * Last update: 02/02/2007 8 * Issue date: 04/30/2005 9 * 10 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay (at) a3.epfl.ch> 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the project nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include "sysincludes.h" 39 40 #include "cryptolib.h" 41 #include "utility.h" 42 43 #define SHFR(x, n) (x >> n) 44 #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) 45 #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) 46 #define CH(x, y, z) ((x & y) ^ (~x & z)) 47 #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) 48 49 #define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) 50 #define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) 51 #define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) 52 #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) 53 54 #define UNPACK32(x, str) \ 55 { \ 56 *((str) + 3) = (uint8_t) ((x) ); \ 57 *((str) + 2) = (uint8_t) ((x) >> 8); \ 58 *((str) + 1) = (uint8_t) ((x) >> 16); \ 59 *((str) + 0) = (uint8_t) ((x) >> 24); \ 60 } 61 62 #define PACK32(str, x) \ 63 { \ 64 *(x) = ((uint32_t) *((str) + 3) ) \ 65 | ((uint32_t) *((str) + 2) << 8) \ 66 | ((uint32_t) *((str) + 1) << 16) \ 67 | ((uint32_t) *((str) + 0) << 24); \ 68 } 69 70 /* Macros used for loops unrolling */ 71 72 #define SHA256_SCR(i) \ 73 { \ 74 w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \ 75 + SHA256_F3(w[i - 15]) + w[i - 16]; \ 76 } 77 78 #define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ 79 { \ 80 t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ 81 + sha256_k[j] + w[j]; \ 82 t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ 83 wv[d] += t1; \ 84 wv[h] = t1 + t2; \ 85 } 86 87 static const uint32_t sha256_h0[8] = { 88 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 89 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; 90 91 static const uint32_t sha256_k[64] = { 92 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 93 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 94 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 95 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 96 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 97 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 98 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 99 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 100 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 101 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 102 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 103 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 104 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 105 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 106 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 107 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; 108 109 110 /* SHA-256 implementation */ 111 void SHA256_init(VB_SHA256_CTX *ctx) { 112 #ifndef UNROLL_LOOPS 113 int i; 114 for (i = 0; i < 8; i++) { 115 ctx->h[i] = sha256_h0[i]; 116 } 117 #else 118 ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1]; 119 ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3]; 120 ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5]; 121 ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7]; 122 #endif /* !UNROLL_LOOPS */ 123 124 ctx->len = 0; 125 ctx->tot_len = 0; 126 } 127 128 129 static void SHA256_transform(VB_SHA256_CTX* ctx, const uint8_t* message, 130 unsigned int block_nb) { 131 uint32_t w[64]; 132 uint32_t wv[8]; 133 uint32_t t1, t2; 134 const unsigned char *sub_block; 135 int i; 136 137 #ifndef UNROLL_LOOPS 138 int j; 139 #endif 140 141 for (i = 0; i < (int) block_nb; i++) { 142 sub_block = message + (i << 6); 143 144 #ifndef UNROLL_LOOPS 145 for (j = 0; j < 16; j++) { 146 PACK32(&sub_block[j << 2], &w[j]); 147 } 148 149 for (j = 16; j < 64; j++) { 150 SHA256_SCR(j); 151 } 152 153 for (j = 0; j < 8; j++) { 154 wv[j] = ctx->h[j]; 155 } 156 157 for (j = 0; j < 64; j++) { 158 t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) 159 + sha256_k[j] + w[j]; 160 t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); 161 wv[7] = wv[6]; 162 wv[6] = wv[5]; 163 wv[5] = wv[4]; 164 wv[4] = wv[3] + t1; 165 wv[3] = wv[2]; 166 wv[2] = wv[1]; 167 wv[1] = wv[0]; 168 wv[0] = t1 + t2; 169 } 170 171 for (j = 0; j < 8; j++) { 172 ctx->h[j] += wv[j]; 173 } 174 #else 175 PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]); 176 PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]); 177 PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]); 178 PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]); 179 PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]); 180 PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]); 181 PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]); 182 PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]); 183 184 SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19); 185 SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23); 186 SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27); 187 SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31); 188 SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35); 189 SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39); 190 SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43); 191 SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47); 192 SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51); 193 SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55); 194 SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59); 195 SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63); 196 197 wv[0] = ctx->h[0]; wv[1] = ctx->h[1]; 198 wv[2] = ctx->h[2]; wv[3] = ctx->h[3]; 199 wv[4] = ctx->h[4]; wv[5] = ctx->h[5]; 200 wv[6] = ctx->h[6]; wv[7] = ctx->h[7]; 201 202 SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1); 203 SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3); 204 SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5); 205 SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7); 206 SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9); 207 SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11); 208 SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13); 209 SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15); 210 SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17); 211 SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19); 212 SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21); 213 SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23); 214 SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25); 215 SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27); 216 SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29); 217 SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31); 218 SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33); 219 SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35); 220 SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37); 221 SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39); 222 SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41); 223 SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43); 224 SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45); 225 SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47); 226 SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49); 227 SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51); 228 SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53); 229 SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55); 230 SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57); 231 SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59); 232 SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61); 233 SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63); 234 235 ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; 236 ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; 237 ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; 238 ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; 239 #endif /* !UNROLL_LOOPS */ 240 } 241 } 242 243 244 245 void SHA256_update(VB_SHA256_CTX* ctx, const uint8_t* data, uint32_t len) { 246 unsigned int block_nb; 247 unsigned int new_len, rem_len, tmp_len; 248 const uint8_t *shifted_data; 249 250 tmp_len = SHA256_BLOCK_SIZE - ctx->len; 251 rem_len = len < tmp_len ? len : tmp_len; 252 253 Memcpy(&ctx->block[ctx->len], data, rem_len); 254 255 if (ctx->len + len < SHA256_BLOCK_SIZE) { 256 ctx->len += len; 257 return; 258 } 259 260 new_len = len - rem_len; 261 block_nb = new_len / SHA256_BLOCK_SIZE; 262 263 shifted_data = data + rem_len; 264 265 SHA256_transform(ctx, ctx->block, 1); 266 SHA256_transform(ctx, shifted_data, block_nb); 267 268 rem_len = new_len % SHA256_BLOCK_SIZE; 269 270 Memcpy(ctx->block, &shifted_data[block_nb << 6], 271 rem_len); 272 273 ctx->len = rem_len; 274 ctx->tot_len += (block_nb + 1) << 6; 275 } 276 277 uint8_t* SHA256_final(VB_SHA256_CTX* ctx) { 278 unsigned int block_nb; 279 unsigned int pm_len; 280 unsigned int len_b; 281 #ifndef UNROLL_LOOPS 282 int i; 283 #endif 284 285 block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) 286 < (ctx->len % SHA256_BLOCK_SIZE))); 287 288 len_b = (ctx->tot_len + ctx->len) << 3; 289 pm_len = block_nb << 6; 290 291 Memset(ctx->block + ctx->len, 0, pm_len - ctx->len); 292 ctx->block[ctx->len] = 0x80; 293 UNPACK32(len_b, ctx->block + pm_len - 4); 294 295 SHA256_transform(ctx, ctx->block, block_nb); 296 297 #ifndef UNROLL_LOOPS 298 for (i = 0 ; i < 8; i++) { 299 UNPACK32(ctx->h[i], &ctx->buf[i << 2]); 300 } 301 #else 302 UNPACK32(ctx->h[0], &ctx->buf[ 0]); 303 UNPACK32(ctx->h[1], &ctx->buf[ 4]); 304 UNPACK32(ctx->h[2], &ctx->buf[ 8]); 305 UNPACK32(ctx->h[3], &ctx->buf[12]); 306 UNPACK32(ctx->h[4], &ctx->buf[16]); 307 UNPACK32(ctx->h[5], &ctx->buf[20]); 308 UNPACK32(ctx->h[6], &ctx->buf[24]); 309 UNPACK32(ctx->h[7], &ctx->buf[28]); 310 #endif /* !UNROLL_LOOPS */ 311 312 return ctx->buf; 313 } 314 315 uint8_t* internal_SHA256(const uint8_t* data, uint64_t len, uint8_t* digest) { 316 const uint8_t* input_ptr; 317 const uint8_t* result; 318 uint64_t remaining_len; 319 int i; 320 VB_SHA256_CTX ctx; 321 322 SHA256_init(&ctx); 323 324 input_ptr = data; 325 remaining_len = len; 326 327 /* Process data in at most UINT32_MAX byte chunks at a time. */ 328 while (remaining_len) { 329 uint32_t block_size; 330 block_size = (uint32_t) ((remaining_len >= UINT32_MAX) ? 331 UINT32_MAX : remaining_len); 332 SHA256_update(&ctx, input_ptr, block_size); 333 remaining_len -= block_size; 334 input_ptr += block_size; 335 } 336 337 result = SHA256_final(&ctx); 338 for (i = 0; i < SHA256_DIGEST_SIZE; ++i) { 339 digest[i] = *result++; 340 } 341 return digest; 342 } 343