178acc472SPeter Tyser /* 278acc472SPeter Tyser * FIPS-180-2 compliant SHA-256 implementation 378acc472SPeter Tyser * 478acc472SPeter Tyser * Copyright (C) 2001-2003 Christophe Devine 578acc472SPeter Tyser * 678acc472SPeter Tyser * This program is free software; you can redistribute it and/or modify 778acc472SPeter Tyser * it under the terms of the GNU General Public License as published by 878acc472SPeter Tyser * the Free Software Foundation; either version 2 of the License, or 978acc472SPeter Tyser * (at your option) any later version. 1078acc472SPeter Tyser * 1178acc472SPeter Tyser * This program is distributed in the hope that it will be useful, 1278acc472SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 1378acc472SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1478acc472SPeter Tyser * GNU General Public License for more details. 1578acc472SPeter Tyser * 1678acc472SPeter Tyser * You should have received a copy of the GNU General Public License 1778acc472SPeter Tyser * along with this program; if not, write to the Free Software 1878acc472SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1978acc472SPeter Tyser */ 2078acc472SPeter Tyser 2178acc472SPeter Tyser #ifndef USE_HOSTCC 2278acc472SPeter Tyser #include <common.h> 2378acc472SPeter Tyser #endif /* USE_HOSTCC */ 2478acc472SPeter Tyser #include <watchdog.h> 2578acc472SPeter Tyser #include <linux/string.h> 2678acc472SPeter Tyser #include <sha256.h> 2778acc472SPeter Tyser 2878acc472SPeter Tyser /* 2978acc472SPeter Tyser * 32-bit integer manipulation macros (big endian) 3078acc472SPeter Tyser */ 3178acc472SPeter Tyser #ifndef GET_UINT32_BE 3278acc472SPeter Tyser #define GET_UINT32_BE(n,b,i) { \ 3378acc472SPeter Tyser (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ 3478acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 1] << 16 ) \ 3578acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 2] << 8 ) \ 3678acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 3] ); \ 3778acc472SPeter Tyser } 3878acc472SPeter Tyser #endif 3978acc472SPeter Tyser #ifndef PUT_UINT32_BE 4078acc472SPeter Tyser #define PUT_UINT32_BE(n,b,i) { \ 4178acc472SPeter Tyser (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 4278acc472SPeter Tyser (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 4378acc472SPeter Tyser (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 4478acc472SPeter Tyser (b)[(i) + 3] = (unsigned char) ( (n) ); \ 4578acc472SPeter Tyser } 4678acc472SPeter Tyser #endif 4778acc472SPeter Tyser 4878acc472SPeter Tyser void sha256_starts(sha256_context * ctx) 4978acc472SPeter Tyser { 5078acc472SPeter Tyser ctx->total[0] = 0; 5178acc472SPeter Tyser ctx->total[1] = 0; 5278acc472SPeter Tyser 5378acc472SPeter Tyser ctx->state[0] = 0x6A09E667; 5478acc472SPeter Tyser ctx->state[1] = 0xBB67AE85; 5578acc472SPeter Tyser ctx->state[2] = 0x3C6EF372; 5678acc472SPeter Tyser ctx->state[3] = 0xA54FF53A; 5778acc472SPeter Tyser ctx->state[4] = 0x510E527F; 5878acc472SPeter Tyser ctx->state[5] = 0x9B05688C; 5978acc472SPeter Tyser ctx->state[6] = 0x1F83D9AB; 6078acc472SPeter Tyser ctx->state[7] = 0x5BE0CD19; 6178acc472SPeter Tyser } 6278acc472SPeter Tyser 63*ec7381fbSSimon Glass static void sha256_process(sha256_context *ctx, const uint8_t data[64]) 6478acc472SPeter Tyser { 6578acc472SPeter Tyser uint32_t temp1, temp2; 6678acc472SPeter Tyser uint32_t W[64]; 6778acc472SPeter Tyser uint32_t A, B, C, D, E, F, G, H; 6878acc472SPeter Tyser 6978acc472SPeter Tyser GET_UINT32_BE(W[0], data, 0); 7078acc472SPeter Tyser GET_UINT32_BE(W[1], data, 4); 7178acc472SPeter Tyser GET_UINT32_BE(W[2], data, 8); 7278acc472SPeter Tyser GET_UINT32_BE(W[3], data, 12); 7378acc472SPeter Tyser GET_UINT32_BE(W[4], data, 16); 7478acc472SPeter Tyser GET_UINT32_BE(W[5], data, 20); 7578acc472SPeter Tyser GET_UINT32_BE(W[6], data, 24); 7678acc472SPeter Tyser GET_UINT32_BE(W[7], data, 28); 7778acc472SPeter Tyser GET_UINT32_BE(W[8], data, 32); 7878acc472SPeter Tyser GET_UINT32_BE(W[9], data, 36); 7978acc472SPeter Tyser GET_UINT32_BE(W[10], data, 40); 8078acc472SPeter Tyser GET_UINT32_BE(W[11], data, 44); 8178acc472SPeter Tyser GET_UINT32_BE(W[12], data, 48); 8278acc472SPeter Tyser GET_UINT32_BE(W[13], data, 52); 8378acc472SPeter Tyser GET_UINT32_BE(W[14], data, 56); 8478acc472SPeter Tyser GET_UINT32_BE(W[15], data, 60); 8578acc472SPeter Tyser 8678acc472SPeter Tyser #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 8778acc472SPeter Tyser #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 8878acc472SPeter Tyser 8978acc472SPeter Tyser #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 9078acc472SPeter Tyser #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 9178acc472SPeter Tyser 9278acc472SPeter Tyser #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 9378acc472SPeter Tyser #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 9478acc472SPeter Tyser 9578acc472SPeter Tyser #define F0(x,y,z) ((x & y) | (z & (x | y))) 9678acc472SPeter Tyser #define F1(x,y,z) (z ^ (x & (y ^ z))) 9778acc472SPeter Tyser 9878acc472SPeter Tyser #define R(t) \ 9978acc472SPeter Tyser ( \ 10078acc472SPeter Tyser W[t] = S1(W[t - 2]) + W[t - 7] + \ 10178acc472SPeter Tyser S0(W[t - 15]) + W[t - 16] \ 10278acc472SPeter Tyser ) 10378acc472SPeter Tyser 10478acc472SPeter Tyser #define P(a,b,c,d,e,f,g,h,x,K) { \ 10578acc472SPeter Tyser temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 10678acc472SPeter Tyser temp2 = S2(a) + F0(a,b,c); \ 10778acc472SPeter Tyser d += temp1; h = temp1 + temp2; \ 10878acc472SPeter Tyser } 10978acc472SPeter Tyser 11078acc472SPeter Tyser A = ctx->state[0]; 11178acc472SPeter Tyser B = ctx->state[1]; 11278acc472SPeter Tyser C = ctx->state[2]; 11378acc472SPeter Tyser D = ctx->state[3]; 11478acc472SPeter Tyser E = ctx->state[4]; 11578acc472SPeter Tyser F = ctx->state[5]; 11678acc472SPeter Tyser G = ctx->state[6]; 11778acc472SPeter Tyser H = ctx->state[7]; 11878acc472SPeter Tyser 11978acc472SPeter Tyser P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98); 12078acc472SPeter Tyser P(H, A, B, C, D, E, F, G, W[1], 0x71374491); 12178acc472SPeter Tyser P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF); 12278acc472SPeter Tyser P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5); 12378acc472SPeter Tyser P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B); 12478acc472SPeter Tyser P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1); 12578acc472SPeter Tyser P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4); 12678acc472SPeter Tyser P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5); 12778acc472SPeter Tyser P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98); 12878acc472SPeter Tyser P(H, A, B, C, D, E, F, G, W[9], 0x12835B01); 12978acc472SPeter Tyser P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); 13078acc472SPeter Tyser P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); 13178acc472SPeter Tyser P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); 13278acc472SPeter Tyser P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); 13378acc472SPeter Tyser P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); 13478acc472SPeter Tyser P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); 13578acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); 13678acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); 13778acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); 13878acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); 13978acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); 14078acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); 14178acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); 14278acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); 14378acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); 14478acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); 14578acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); 14678acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); 14778acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); 14878acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); 14978acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); 15078acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(31), 0x14292967); 15178acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); 15278acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); 15378acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); 15478acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); 15578acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); 15678acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); 15778acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); 15878acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); 15978acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); 16078acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); 16178acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); 16278acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); 16378acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); 16478acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); 16578acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); 16678acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); 16778acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); 16878acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); 16978acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); 17078acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); 17178acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); 17278acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); 17378acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); 17478acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); 17578acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); 17678acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); 17778acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); 17878acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); 17978acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); 18078acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); 18178acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); 18278acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); 18378acc472SPeter Tyser 18478acc472SPeter Tyser ctx->state[0] += A; 18578acc472SPeter Tyser ctx->state[1] += B; 18678acc472SPeter Tyser ctx->state[2] += C; 18778acc472SPeter Tyser ctx->state[3] += D; 18878acc472SPeter Tyser ctx->state[4] += E; 18978acc472SPeter Tyser ctx->state[5] += F; 19078acc472SPeter Tyser ctx->state[6] += G; 19178acc472SPeter Tyser ctx->state[7] += H; 19278acc472SPeter Tyser } 19378acc472SPeter Tyser 194*ec7381fbSSimon Glass void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length) 19578acc472SPeter Tyser { 19678acc472SPeter Tyser uint32_t left, fill; 19778acc472SPeter Tyser 19878acc472SPeter Tyser if (!length) 19978acc472SPeter Tyser return; 20078acc472SPeter Tyser 20178acc472SPeter Tyser left = ctx->total[0] & 0x3F; 20278acc472SPeter Tyser fill = 64 - left; 20378acc472SPeter Tyser 20478acc472SPeter Tyser ctx->total[0] += length; 20578acc472SPeter Tyser ctx->total[0] &= 0xFFFFFFFF; 20678acc472SPeter Tyser 20778acc472SPeter Tyser if (ctx->total[0] < length) 20878acc472SPeter Tyser ctx->total[1]++; 20978acc472SPeter Tyser 21078acc472SPeter Tyser if (left && length >= fill) { 21178acc472SPeter Tyser memcpy((void *) (ctx->buffer + left), (void *) input, fill); 21278acc472SPeter Tyser sha256_process(ctx, ctx->buffer); 21378acc472SPeter Tyser length -= fill; 21478acc472SPeter Tyser input += fill; 21578acc472SPeter Tyser left = 0; 21678acc472SPeter Tyser } 21778acc472SPeter Tyser 21878acc472SPeter Tyser while (length >= 64) { 21978acc472SPeter Tyser sha256_process(ctx, input); 22078acc472SPeter Tyser length -= 64; 22178acc472SPeter Tyser input += 64; 22278acc472SPeter Tyser } 22378acc472SPeter Tyser 22478acc472SPeter Tyser if (length) 22578acc472SPeter Tyser memcpy((void *) (ctx->buffer + left), (void *) input, length); 22678acc472SPeter Tyser } 22778acc472SPeter Tyser 22878acc472SPeter Tyser static uint8_t sha256_padding[64] = { 22978acc472SPeter Tyser 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23078acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23178acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23278acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 23378acc472SPeter Tyser }; 23478acc472SPeter Tyser 23578acc472SPeter Tyser void sha256_finish(sha256_context * ctx, uint8_t digest[32]) 23678acc472SPeter Tyser { 23778acc472SPeter Tyser uint32_t last, padn; 23878acc472SPeter Tyser uint32_t high, low; 23978acc472SPeter Tyser uint8_t msglen[8]; 24078acc472SPeter Tyser 24178acc472SPeter Tyser high = ((ctx->total[0] >> 29) 24278acc472SPeter Tyser | (ctx->total[1] << 3)); 24378acc472SPeter Tyser low = (ctx->total[0] << 3); 24478acc472SPeter Tyser 24578acc472SPeter Tyser PUT_UINT32_BE(high, msglen, 0); 24678acc472SPeter Tyser PUT_UINT32_BE(low, msglen, 4); 24778acc472SPeter Tyser 24878acc472SPeter Tyser last = ctx->total[0] & 0x3F; 24978acc472SPeter Tyser padn = (last < 56) ? (56 - last) : (120 - last); 25078acc472SPeter Tyser 25178acc472SPeter Tyser sha256_update(ctx, sha256_padding, padn); 25278acc472SPeter Tyser sha256_update(ctx, msglen, 8); 25378acc472SPeter Tyser 25478acc472SPeter Tyser PUT_UINT32_BE(ctx->state[0], digest, 0); 25578acc472SPeter Tyser PUT_UINT32_BE(ctx->state[1], digest, 4); 25678acc472SPeter Tyser PUT_UINT32_BE(ctx->state[2], digest, 8); 25778acc472SPeter Tyser PUT_UINT32_BE(ctx->state[3], digest, 12); 25878acc472SPeter Tyser PUT_UINT32_BE(ctx->state[4], digest, 16); 25978acc472SPeter Tyser PUT_UINT32_BE(ctx->state[5], digest, 20); 26078acc472SPeter Tyser PUT_UINT32_BE(ctx->state[6], digest, 24); 26178acc472SPeter Tyser PUT_UINT32_BE(ctx->state[7], digest, 28); 26278acc472SPeter Tyser } 263*ec7381fbSSimon Glass 264*ec7381fbSSimon Glass /* 265*ec7381fbSSimon Glass * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz' 266*ec7381fbSSimon Glass * bytes of input processed. 267*ec7381fbSSimon Glass */ 268*ec7381fbSSimon Glass void sha256_csum_wd(const unsigned char *input, unsigned int ilen, 269*ec7381fbSSimon Glass unsigned char *output, unsigned int chunk_sz) 270*ec7381fbSSimon Glass { 271*ec7381fbSSimon Glass sha256_context ctx; 272*ec7381fbSSimon Glass #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 273*ec7381fbSSimon Glass unsigned char *end, *curr; 274*ec7381fbSSimon Glass int chunk; 275*ec7381fbSSimon Glass #endif 276*ec7381fbSSimon Glass 277*ec7381fbSSimon Glass sha256_starts(&ctx); 278*ec7381fbSSimon Glass 279*ec7381fbSSimon Glass #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 280*ec7381fbSSimon Glass curr = input; 281*ec7381fbSSimon Glass end = input + ilen; 282*ec7381fbSSimon Glass while (curr < end) { 283*ec7381fbSSimon Glass chunk = end - curr; 284*ec7381fbSSimon Glass if (chunk > chunk_sz) 285*ec7381fbSSimon Glass chunk = chunk_sz; 286*ec7381fbSSimon Glass sha256_update(&ctx, curr, chunk); 287*ec7381fbSSimon Glass curr += chunk; 288*ec7381fbSSimon Glass WATCHDOG_RESET(); 289*ec7381fbSSimon Glass } 290*ec7381fbSSimon Glass #else 291*ec7381fbSSimon Glass sha256_update(&ctx, input, ilen); 292*ec7381fbSSimon Glass #endif 293*ec7381fbSSimon Glass 294*ec7381fbSSimon Glass sha256_finish(&ctx, output); 295*ec7381fbSSimon Glass } 296