uboot/lib/sha256.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * FIPS-180-2 compliant SHA-256 implementation
   4 *
   5 * Copyright (C) 2001-2003  Christophe Devine
   6 */
   7
   8#ifndef USE_HOSTCC
   9#include <common.h>
  10#include <linux/string.h>
  11#else
  12#include <string.h>
  13#endif /* USE_HOSTCC */
  14#include <watchdog.h>
  15#include <u-boot/sha256.h>
  16
  17const uint8_t sha256_der_prefix[SHA256_DER_LEN] = {
  18        0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
  19        0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
  20        0x00, 0x04, 0x20
  21};
  22
  23/*
  24 * 32-bit integer manipulation macros (big endian)
  25 */
  26#ifndef GET_UINT32_BE
  27#define GET_UINT32_BE(n,b,i) {                          \
  28        (n) = ( (unsigned long) (b)[(i)    ] << 24 )    \
  29            | ( (unsigned long) (b)[(i) + 1] << 16 )    \
  30            | ( (unsigned long) (b)[(i) + 2] <<  8 )    \
  31            | ( (unsigned long) (b)[(i) + 3]       );   \
  32}
  33#endif
  34#ifndef PUT_UINT32_BE
  35#define PUT_UINT32_BE(n,b,i) {                          \
  36        (b)[(i)    ] = (unsigned char) ( (n) >> 24 );   \
  37        (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );   \
  38        (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );   \
  39        (b)[(i) + 3] = (unsigned char) ( (n)       );   \
  40}
  41#endif
  42
  43void sha256_starts(sha256_context * ctx)
  44{
  45        ctx->total[0] = 0;
  46        ctx->total[1] = 0;
  47
  48        ctx->state[0] = 0x6A09E667;
  49        ctx->state[1] = 0xBB67AE85;
  50        ctx->state[2] = 0x3C6EF372;
  51        ctx->state[3] = 0xA54FF53A;
  52        ctx->state[4] = 0x510E527F;
  53        ctx->state[5] = 0x9B05688C;
  54        ctx->state[6] = 0x1F83D9AB;
  55        ctx->state[7] = 0x5BE0CD19;
  56}
  57
  58static void sha256_process(sha256_context *ctx, const uint8_t data[64])
  59{
  60        uint32_t temp1, temp2;
  61        uint32_t W[64];
  62        uint32_t A, B, C, D, E, F, G, H;
  63
  64        GET_UINT32_BE(W[0], data, 0);
  65        GET_UINT32_BE(W[1], data, 4);
  66        GET_UINT32_BE(W[2], data, 8);
  67        GET_UINT32_BE(W[3], data, 12);
  68        GET_UINT32_BE(W[4], data, 16);
  69        GET_UINT32_BE(W[5], data, 20);
  70        GET_UINT32_BE(W[6], data, 24);
  71        GET_UINT32_BE(W[7], data, 28);
  72        GET_UINT32_BE(W[8], data, 32);
  73        GET_UINT32_BE(W[9], data, 36);
  74        GET_UINT32_BE(W[10], data, 40);
  75        GET_UINT32_BE(W[11], data, 44);
  76        GET_UINT32_BE(W[12], data, 48);
  77        GET_UINT32_BE(W[13], data, 52);
  78        GET_UINT32_BE(W[14], data, 56);
  79        GET_UINT32_BE(W[15], data, 60);
  80
  81#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
  82#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
  83
  84#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
  85#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
  86
  87#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
  88#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
  89
  90#define F0(x,y,z) ((x & y) | (z & (x | y)))
  91#define F1(x,y,z) (z ^ (x & (y ^ z)))
  92
  93#define R(t)                                    \
  94(                                               \
  95        W[t] = S1(W[t - 2]) + W[t - 7] +        \
  96                S0(W[t - 15]) + W[t - 16]       \
  97)
  98
  99#define P(a,b,c,d,e,f,g,h,x,K) {                \
 100        temp1 = h + S3(e) + F1(e,f,g) + K + x;  \
 101        temp2 = S2(a) + F0(a,b,c);              \
 102        d += temp1; h = temp1 + temp2;          \
 103}
 104
 105        A = ctx->state[0];
 106        B = ctx->state[1];
 107        C = ctx->state[2];
 108        D = ctx->state[3];
 109        E = ctx->state[4];
 110        F = ctx->state[5];
 111        G = ctx->state[6];
 112        H = ctx->state[7];
 113
 114        P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
 115        P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
 116        P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
 117        P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
 118        P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
 119        P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
 120        P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
 121        P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
 122        P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
 123        P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
 124        P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
 125        P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
 126        P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
 127        P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
 128        P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
 129        P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
 130        P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
 131        P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
 132        P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
 133        P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
 134        P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
 135        P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
 136        P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
 137        P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
 138        P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
 139        P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
 140        P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
 141        P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
 142        P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
 143        P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
 144        P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
 145        P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
 146        P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
 147        P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
 148        P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
 149        P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
 150        P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
 151        P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
 152        P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
 153        P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
 154        P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
 155        P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
 156        P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
 157        P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
 158        P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
 159        P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
 160        P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
 161        P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
 162        P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
 163        P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
 164        P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
 165        P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
 166        P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
 167        P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
 168        P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
 169        P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
 170        P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
 171        P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
 172        P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
 173        P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
 174        P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
 175        P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
 176        P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
 177        P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
 178
 179        ctx->state[0] += A;
 180        ctx->state[1] += B;
 181        ctx->state[2] += C;
 182        ctx->state[3] += D;
 183        ctx->state[4] += E;
 184        ctx->state[5] += F;
 185        ctx->state[6] += G;
 186        ctx->state[7] += H;
 187}
 188
 189void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
 190{
 191        uint32_t left, fill;
 192
 193        if (!length)
 194                return;
 195
 196        left = ctx->total[0] & 0x3F;
 197        fill = 64 - left;
 198
 199        ctx->total[0] += length;
 200        ctx->total[0] &= 0xFFFFFFFF;
 201
 202        if (ctx->total[0] < length)
 203                ctx->total[1]++;
 204
 205        if (left && length >= fill) {
 206                memcpy((void *) (ctx->buffer + left), (void *) input, fill);
 207                sha256_process(ctx, ctx->buffer);
 208                length -= fill;
 209                input += fill;
 210                left = 0;
 211        }
 212
 213        while (length >= 64) {
 214                sha256_process(ctx, input);
 215                length -= 64;
 216                input += 64;
 217        }
 218
 219        if (length)
 220                memcpy((void *) (ctx->buffer + left), (void *) input, length);
 221}
 222
 223static uint8_t sha256_padding[64] = {
 224        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 225           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 226           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 227           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 228};
 229
 230void sha256_finish(sha256_context * ctx, uint8_t digest[32])
 231{
 232        uint32_t last, padn;
 233        uint32_t high, low;
 234        uint8_t msglen[8];
 235
 236        high = ((ctx->total[0] >> 29)
 237                | (ctx->total[1] << 3));
 238        low = (ctx->total[0] << 3);
 239
 240        PUT_UINT32_BE(high, msglen, 0);
 241        PUT_UINT32_BE(low, msglen, 4);
 242
 243        last = ctx->total[0] & 0x3F;
 244        padn = (last < 56) ? (56 - last) : (120 - last);
 245
 246        sha256_update(ctx, sha256_padding, padn);
 247        sha256_update(ctx, msglen, 8);
 248
 249        PUT_UINT32_BE(ctx->state[0], digest, 0);
 250        PUT_UINT32_BE(ctx->state[1], digest, 4);
 251        PUT_UINT32_BE(ctx->state[2], digest, 8);
 252        PUT_UINT32_BE(ctx->state[3], digest, 12);
 253        PUT_UINT32_BE(ctx->state[4], digest, 16);
 254        PUT_UINT32_BE(ctx->state[5], digest, 20);
 255        PUT_UINT32_BE(ctx->state[6], digest, 24);
 256        PUT_UINT32_BE(ctx->state[7], digest, 28);
 257}
 258
 259/*
 260 * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz'
 261 * bytes of input processed.
 262 */
 263void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
 264                unsigned char *output, unsigned int chunk_sz)
 265{
 266        sha256_context ctx;
 267#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 268        const unsigned char *end;
 269        unsigned char *curr;
 270        int chunk;
 271#endif
 272
 273        sha256_starts(&ctx);
 274
 275#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 276        curr = (unsigned char *)input;
 277        end = input + ilen;
 278        while (curr < end) {
 279                chunk = end - curr;
 280                if (chunk > chunk_sz)
 281                        chunk = chunk_sz;
 282                sha256_update(&ctx, curr, chunk);
 283                curr += chunk;
 284                WATCHDOG_RESET();
 285        }
 286#else
 287        sha256_update(&ctx, input, ilen);
 288#endif
 289
 290        sha256_finish(&ctx, output);
 291}
 292