178acc472SPeter Tyser /* 278acc472SPeter Tyser * FIPS-180-2 compliant SHA-256 implementation 378acc472SPeter Tyser * 478acc472SPeter Tyser * Copyright (C) 2001-2003 Christophe Devine 578acc472SPeter Tyser * 61a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 778acc472SPeter Tyser */ 878acc472SPeter Tyser 978acc472SPeter Tyser #ifndef USE_HOSTCC 1078acc472SPeter Tyser #include <common.h> 11822ef00eSAndreas Bießmann #include <linux/string.h> 12822ef00eSAndreas Bießmann #else 13822ef00eSAndreas Bießmann #include <string.h> 1478acc472SPeter Tyser #endif /* USE_HOSTCC */ 1578acc472SPeter Tyser #include <watchdog.h> 162b9912e6SJeroen Hofstee #include <u-boot/sha256.h> 1778acc472SPeter Tyser 18*c87e576eSLoic Poulain #include <linux/compiler.h> 19*c87e576eSLoic Poulain 20*c87e576eSLoic Poulain #ifdef USE_HOSTCC 21*c87e576eSLoic Poulain #undef __weak 22*c87e576eSLoic Poulain #define __weak 23*c87e576eSLoic Poulain #endif 24*c87e576eSLoic Poulain 25da29f299SAndrew Duda const uint8_t sha256_der_prefix[SHA256_DER_LEN] = { 26da29f299SAndrew Duda 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 27da29f299SAndrew Duda 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 28da29f299SAndrew Duda 0x00, 0x04, 0x20 29da29f299SAndrew Duda }; 30da29f299SAndrew Duda 3178acc472SPeter Tyser /* 3278acc472SPeter Tyser * 32-bit integer manipulation macros (big endian) 3378acc472SPeter Tyser */ 3478acc472SPeter Tyser #ifndef GET_UINT32_BE 3578acc472SPeter Tyser #define GET_UINT32_BE(n,b,i) { \ 3678acc472SPeter Tyser (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ 3778acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 1] << 16 ) \ 3878acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 2] << 8 ) \ 3978acc472SPeter Tyser | ( (unsigned long) (b)[(i) + 3] ); \ 4078acc472SPeter Tyser } 4178acc472SPeter Tyser #endif 4278acc472SPeter Tyser #ifndef PUT_UINT32_BE 4378acc472SPeter Tyser #define PUT_UINT32_BE(n,b,i) { \ 4478acc472SPeter Tyser (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 4578acc472SPeter Tyser (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 4678acc472SPeter Tyser (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 4778acc472SPeter Tyser (b)[(i) + 3] = (unsigned char) ( (n) ); \ 4878acc472SPeter Tyser } 4978acc472SPeter Tyser #endif 5078acc472SPeter Tyser 5178acc472SPeter Tyser void sha256_starts(sha256_context * ctx) 5278acc472SPeter Tyser { 5378acc472SPeter Tyser ctx->total[0] = 0; 5478acc472SPeter Tyser ctx->total[1] = 0; 5578acc472SPeter Tyser 5678acc472SPeter Tyser ctx->state[0] = 0x6A09E667; 5778acc472SPeter Tyser ctx->state[1] = 0xBB67AE85; 5878acc472SPeter Tyser ctx->state[2] = 0x3C6EF372; 5978acc472SPeter Tyser ctx->state[3] = 0xA54FF53A; 6078acc472SPeter Tyser ctx->state[4] = 0x510E527F; 6178acc472SPeter Tyser ctx->state[5] = 0x9B05688C; 6278acc472SPeter Tyser ctx->state[6] = 0x1F83D9AB; 6378acc472SPeter Tyser ctx->state[7] = 0x5BE0CD19; 6478acc472SPeter Tyser } 6578acc472SPeter Tyser 66*c87e576eSLoic Poulain static void sha256_process_one(sha256_context *ctx, const uint8_t data[64]) 6778acc472SPeter Tyser { 6878acc472SPeter Tyser uint32_t temp1, temp2; 6978acc472SPeter Tyser uint32_t W[64]; 7078acc472SPeter Tyser uint32_t A, B, C, D, E, F, G, H; 7178acc472SPeter Tyser 7278acc472SPeter Tyser GET_UINT32_BE(W[0], data, 0); 7378acc472SPeter Tyser GET_UINT32_BE(W[1], data, 4); 7478acc472SPeter Tyser GET_UINT32_BE(W[2], data, 8); 7578acc472SPeter Tyser GET_UINT32_BE(W[3], data, 12); 7678acc472SPeter Tyser GET_UINT32_BE(W[4], data, 16); 7778acc472SPeter Tyser GET_UINT32_BE(W[5], data, 20); 7878acc472SPeter Tyser GET_UINT32_BE(W[6], data, 24); 7978acc472SPeter Tyser GET_UINT32_BE(W[7], data, 28); 8078acc472SPeter Tyser GET_UINT32_BE(W[8], data, 32); 8178acc472SPeter Tyser GET_UINT32_BE(W[9], data, 36); 8278acc472SPeter Tyser GET_UINT32_BE(W[10], data, 40); 8378acc472SPeter Tyser GET_UINT32_BE(W[11], data, 44); 8478acc472SPeter Tyser GET_UINT32_BE(W[12], data, 48); 8578acc472SPeter Tyser GET_UINT32_BE(W[13], data, 52); 8678acc472SPeter Tyser GET_UINT32_BE(W[14], data, 56); 8778acc472SPeter Tyser GET_UINT32_BE(W[15], data, 60); 8878acc472SPeter Tyser 8978acc472SPeter Tyser #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 9078acc472SPeter Tyser #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 9178acc472SPeter Tyser 9278acc472SPeter Tyser #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 9378acc472SPeter Tyser #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 9478acc472SPeter Tyser 9578acc472SPeter Tyser #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 9678acc472SPeter Tyser #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 9778acc472SPeter Tyser 9878acc472SPeter Tyser #define F0(x,y,z) ((x & y) | (z & (x | y))) 9978acc472SPeter Tyser #define F1(x,y,z) (z ^ (x & (y ^ z))) 10078acc472SPeter Tyser 10178acc472SPeter Tyser #define R(t) \ 10278acc472SPeter Tyser ( \ 10378acc472SPeter Tyser W[t] = S1(W[t - 2]) + W[t - 7] + \ 10478acc472SPeter Tyser S0(W[t - 15]) + W[t - 16] \ 10578acc472SPeter Tyser ) 10678acc472SPeter Tyser 10778acc472SPeter Tyser #define P(a,b,c,d,e,f,g,h,x,K) { \ 10878acc472SPeter Tyser temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 10978acc472SPeter Tyser temp2 = S2(a) + F0(a,b,c); \ 11078acc472SPeter Tyser d += temp1; h = temp1 + temp2; \ 11178acc472SPeter Tyser } 11278acc472SPeter Tyser 11378acc472SPeter Tyser A = ctx->state[0]; 11478acc472SPeter Tyser B = ctx->state[1]; 11578acc472SPeter Tyser C = ctx->state[2]; 11678acc472SPeter Tyser D = ctx->state[3]; 11778acc472SPeter Tyser E = ctx->state[4]; 11878acc472SPeter Tyser F = ctx->state[5]; 11978acc472SPeter Tyser G = ctx->state[6]; 12078acc472SPeter Tyser H = ctx->state[7]; 12178acc472SPeter Tyser 12278acc472SPeter Tyser P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98); 12378acc472SPeter Tyser P(H, A, B, C, D, E, F, G, W[1], 0x71374491); 12478acc472SPeter Tyser P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF); 12578acc472SPeter Tyser P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5); 12678acc472SPeter Tyser P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B); 12778acc472SPeter Tyser P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1); 12878acc472SPeter Tyser P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4); 12978acc472SPeter Tyser P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5); 13078acc472SPeter Tyser P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98); 13178acc472SPeter Tyser P(H, A, B, C, D, E, F, G, W[9], 0x12835B01); 13278acc472SPeter Tyser P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); 13378acc472SPeter Tyser P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); 13478acc472SPeter Tyser P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); 13578acc472SPeter Tyser P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); 13678acc472SPeter Tyser P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); 13778acc472SPeter Tyser P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); 13878acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); 13978acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); 14078acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); 14178acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); 14278acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); 14378acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); 14478acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); 14578acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); 14678acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); 14778acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); 14878acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); 14978acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); 15078acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); 15178acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); 15278acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); 15378acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(31), 0x14292967); 15478acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); 15578acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); 15678acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); 15778acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); 15878acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); 15978acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); 16078acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); 16178acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); 16278acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); 16378acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); 16478acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); 16578acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); 16678acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); 16778acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); 16878acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); 16978acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); 17078acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); 17178acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); 17278acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); 17378acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); 17478acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); 17578acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); 17678acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); 17778acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); 17878acc472SPeter Tyser P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); 17978acc472SPeter Tyser P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); 18078acc472SPeter Tyser P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); 18178acc472SPeter Tyser P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); 18278acc472SPeter Tyser P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); 18378acc472SPeter Tyser P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); 18478acc472SPeter Tyser P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); 18578acc472SPeter Tyser P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); 18678acc472SPeter Tyser 18778acc472SPeter Tyser ctx->state[0] += A; 18878acc472SPeter Tyser ctx->state[1] += B; 18978acc472SPeter Tyser ctx->state[2] += C; 19078acc472SPeter Tyser ctx->state[3] += D; 19178acc472SPeter Tyser ctx->state[4] += E; 19278acc472SPeter Tyser ctx->state[5] += F; 19378acc472SPeter Tyser ctx->state[6] += G; 19478acc472SPeter Tyser ctx->state[7] += H; 19578acc472SPeter Tyser } 19678acc472SPeter Tyser 197*c87e576eSLoic Poulain __weak void sha256_process(sha256_context *ctx, const unsigned char *data, 198*c87e576eSLoic Poulain unsigned int blocks) 199*c87e576eSLoic Poulain { 200*c87e576eSLoic Poulain if (!blocks) 201*c87e576eSLoic Poulain return; 202*c87e576eSLoic Poulain 203*c87e576eSLoic Poulain while (blocks--) { 204*c87e576eSLoic Poulain sha256_process_one(ctx, data); 205*c87e576eSLoic Poulain data += 64; 206*c87e576eSLoic Poulain } 207*c87e576eSLoic Poulain } 208*c87e576eSLoic Poulain 209ec7381fbSSimon Glass void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length) 21078acc472SPeter Tyser { 21178acc472SPeter Tyser uint32_t left, fill; 21278acc472SPeter Tyser 21378acc472SPeter Tyser if (!length) 21478acc472SPeter Tyser return; 21578acc472SPeter Tyser 21678acc472SPeter Tyser left = ctx->total[0] & 0x3F; 21778acc472SPeter Tyser fill = 64 - left; 21878acc472SPeter Tyser 21978acc472SPeter Tyser ctx->total[0] += length; 22078acc472SPeter Tyser ctx->total[0] &= 0xFFFFFFFF; 22178acc472SPeter Tyser 22278acc472SPeter Tyser if (ctx->total[0] < length) 22378acc472SPeter Tyser ctx->total[1]++; 22478acc472SPeter Tyser 22578acc472SPeter Tyser if (left && length >= fill) { 22678acc472SPeter Tyser memcpy((void *) (ctx->buffer + left), (void *) input, fill); 227*c87e576eSLoic Poulain sha256_process(ctx, ctx->buffer, 1); 22878acc472SPeter Tyser length -= fill; 22978acc472SPeter Tyser input += fill; 23078acc472SPeter Tyser left = 0; 23178acc472SPeter Tyser } 23278acc472SPeter Tyser 233*c87e576eSLoic Poulain sha256_process(ctx, input, length / 64); 234*c87e576eSLoic Poulain input += length / 64 * 64; 235*c87e576eSLoic Poulain length = length % 64; 23678acc472SPeter Tyser 23778acc472SPeter Tyser if (length) 23878acc472SPeter Tyser memcpy((void *) (ctx->buffer + left), (void *) input, length); 23978acc472SPeter Tyser } 24078acc472SPeter Tyser 24178acc472SPeter Tyser static uint8_t sha256_padding[64] = { 24278acc472SPeter Tyser 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24378acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24478acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24578acc472SPeter Tyser 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 24678acc472SPeter Tyser }; 24778acc472SPeter Tyser 24878acc472SPeter Tyser void sha256_finish(sha256_context * ctx, uint8_t digest[32]) 24978acc472SPeter Tyser { 25078acc472SPeter Tyser uint32_t last, padn; 25178acc472SPeter Tyser uint32_t high, low; 25278acc472SPeter Tyser uint8_t msglen[8]; 25378acc472SPeter Tyser 25478acc472SPeter Tyser high = ((ctx->total[0] >> 29) 25578acc472SPeter Tyser | (ctx->total[1] << 3)); 25678acc472SPeter Tyser low = (ctx->total[0] << 3); 25778acc472SPeter Tyser 25878acc472SPeter Tyser PUT_UINT32_BE(high, msglen, 0); 25978acc472SPeter Tyser PUT_UINT32_BE(low, msglen, 4); 26078acc472SPeter Tyser 26178acc472SPeter Tyser last = ctx->total[0] & 0x3F; 26278acc472SPeter Tyser padn = (last < 56) ? (56 - last) : (120 - last); 26378acc472SPeter Tyser 26478acc472SPeter Tyser sha256_update(ctx, sha256_padding, padn); 26578acc472SPeter Tyser sha256_update(ctx, msglen, 8); 26678acc472SPeter Tyser 26778acc472SPeter Tyser PUT_UINT32_BE(ctx->state[0], digest, 0); 26878acc472SPeter Tyser PUT_UINT32_BE(ctx->state[1], digest, 4); 26978acc472SPeter Tyser PUT_UINT32_BE(ctx->state[2], digest, 8); 27078acc472SPeter Tyser PUT_UINT32_BE(ctx->state[3], digest, 12); 27178acc472SPeter Tyser PUT_UINT32_BE(ctx->state[4], digest, 16); 27278acc472SPeter Tyser PUT_UINT32_BE(ctx->state[5], digest, 20); 27378acc472SPeter Tyser PUT_UINT32_BE(ctx->state[6], digest, 24); 27478acc472SPeter Tyser PUT_UINT32_BE(ctx->state[7], digest, 28); 27578acc472SPeter Tyser } 276ec7381fbSSimon Glass 277ec7381fbSSimon Glass /* 278fc474da5SJoseph Chen * Output = SHA-256( input buffer ). 279fc474da5SJoseph Chen */ 280fc474da5SJoseph Chen void sha256_csum(const unsigned char *input, unsigned int ilen, 281fc474da5SJoseph Chen unsigned char *output) 282fc474da5SJoseph Chen { 283fc474da5SJoseph Chen sha256_context ctx; 284fc474da5SJoseph Chen 285fc474da5SJoseph Chen sha256_starts(&ctx); 286fc474da5SJoseph Chen sha256_update(&ctx, input, ilen); 287fc474da5SJoseph Chen sha256_finish(&ctx, output); 288fc474da5SJoseph Chen } 289fc474da5SJoseph Chen 290fc474da5SJoseph Chen /* 291ec7381fbSSimon Glass * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz' 292ec7381fbSSimon Glass * bytes of input processed. 293ec7381fbSSimon Glass */ 294ec7381fbSSimon Glass void sha256_csum_wd(const unsigned char *input, unsigned int ilen, 295ec7381fbSSimon Glass unsigned char *output, unsigned int chunk_sz) 296ec7381fbSSimon Glass { 297ec7381fbSSimon Glass sha256_context ctx; 298ec7381fbSSimon Glass #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 2992842c1c2SHeiko Schocher const unsigned char *end; 3002842c1c2SHeiko Schocher unsigned char *curr; 301ec7381fbSSimon Glass int chunk; 302ec7381fbSSimon Glass #endif 303ec7381fbSSimon Glass 304ec7381fbSSimon Glass sha256_starts(&ctx); 305ec7381fbSSimon Glass 306ec7381fbSSimon Glass #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) 3072842c1c2SHeiko Schocher curr = (unsigned char *)input; 308ec7381fbSSimon Glass end = input + ilen; 309ec7381fbSSimon Glass while (curr < end) { 310ec7381fbSSimon Glass chunk = end - curr; 311ec7381fbSSimon Glass if (chunk > chunk_sz) 312ec7381fbSSimon Glass chunk = chunk_sz; 313ec7381fbSSimon Glass sha256_update(&ctx, curr, chunk); 314ec7381fbSSimon Glass curr += chunk; 315ec7381fbSSimon Glass WATCHDOG_RESET(); 316ec7381fbSSimon Glass } 317ec7381fbSSimon Glass #else 318ec7381fbSSimon Glass sha256_update(&ctx, input, ilen); 319ec7381fbSSimon Glass #endif 320ec7381fbSSimon Glass 321ec7381fbSSimon Glass sha256_finish(&ctx, output); 322ec7381fbSSimon Glass } 323