linux/lib/crypto/sha256.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * SHA-256, as specified in
   4 * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
   5 *
   6 * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
   7 *
   8 * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
   9 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
  10 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  11 * Copyright (c) 2014 Red Hat Inc.
  12 */
  13
  14#include <linux/bitops.h>
  15#include <linux/export.h>
  16#include <linux/module.h>
  17#include <linux/string.h>
  18#include <crypto/sha2.h>
  19#include <asm/unaligned.h>
  20
  21static const u32 SHA256_K[] = {
  22        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
  23        0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  24        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
  25        0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  26        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
  27        0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  28        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
  29        0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  30        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
  31        0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  32        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
  33        0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  34        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
  35        0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  36        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
  37        0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
  38};
  39
  40static inline u32 Ch(u32 x, u32 y, u32 z)
  41{
  42        return z ^ (x & (y ^ z));
  43}
  44
  45static inline u32 Maj(u32 x, u32 y, u32 z)
  46{
  47        return (x & y) | (z & (x | y));
  48}
  49
  50#define e0(x)       (ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22))
  51#define e1(x)       (ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25))
  52#define s0(x)       (ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3))
  53#define s1(x)       (ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10))
  54
  55static inline void LOAD_OP(int I, u32 *W, const u8 *input)
  56{
  57        W[I] = get_unaligned_be32((__u32 *)input + I);
  58}
  59
  60static inline void BLEND_OP(int I, u32 *W)
  61{
  62        W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
  63}
  64
  65#define SHA256_ROUND(i, a, b, c, d, e, f, g, h) do {            \
  66        u32 t1, t2;                                             \
  67        t1 = h + e1(e) + Ch(e, f, g) + SHA256_K[i] + W[i];      \
  68        t2 = e0(a) + Maj(a, b, c);                              \
  69        d += t1;                                                \
  70        h = t1 + t2;                                            \
  71} while (0)
  72
  73static void sha256_transform(u32 *state, const u8 *input, u32 *W)
  74{
  75        u32 a, b, c, d, e, f, g, h;
  76        int i;
  77
  78        /* load the input */
  79        for (i = 0; i < 16; i += 8) {
  80                LOAD_OP(i + 0, W, input);
  81                LOAD_OP(i + 1, W, input);
  82                LOAD_OP(i + 2, W, input);
  83                LOAD_OP(i + 3, W, input);
  84                LOAD_OP(i + 4, W, input);
  85                LOAD_OP(i + 5, W, input);
  86                LOAD_OP(i + 6, W, input);
  87                LOAD_OP(i + 7, W, input);
  88        }
  89
  90        /* now blend */
  91        for (i = 16; i < 64; i += 8) {
  92                BLEND_OP(i + 0, W);
  93                BLEND_OP(i + 1, W);
  94                BLEND_OP(i + 2, W);
  95                BLEND_OP(i + 3, W);
  96                BLEND_OP(i + 4, W);
  97                BLEND_OP(i + 5, W);
  98                BLEND_OP(i + 6, W);
  99                BLEND_OP(i + 7, W);
 100        }
 101
 102        /* load the state into our registers */
 103        a = state[0];  b = state[1];  c = state[2];  d = state[3];
 104        e = state[4];  f = state[5];  g = state[6];  h = state[7];
 105
 106        /* now iterate */
 107        for (i = 0; i < 64; i += 8) {
 108                SHA256_ROUND(i + 0, a, b, c, d, e, f, g, h);
 109                SHA256_ROUND(i + 1, h, a, b, c, d, e, f, g);
 110                SHA256_ROUND(i + 2, g, h, a, b, c, d, e, f);
 111                SHA256_ROUND(i + 3, f, g, h, a, b, c, d, e);
 112                SHA256_ROUND(i + 4, e, f, g, h, a, b, c, d);
 113                SHA256_ROUND(i + 5, d, e, f, g, h, a, b, c);
 114                SHA256_ROUND(i + 6, c, d, e, f, g, h, a, b);
 115                SHA256_ROUND(i + 7, b, c, d, e, f, g, h, a);
 116        }
 117
 118        state[0] += a; state[1] += b; state[2] += c; state[3] += d;
 119        state[4] += e; state[5] += f; state[6] += g; state[7] += h;
 120}
 121
 122void sha256_update(struct sha256_state *sctx, const u8 *data, unsigned int len)
 123{
 124        unsigned int partial, done;
 125        const u8 *src;
 126        u32 W[64];
 127
 128        partial = sctx->count & 0x3f;
 129        sctx->count += len;
 130        done = 0;
 131        src = data;
 132
 133        if ((partial + len) > 63) {
 134                if (partial) {
 135                        done = -partial;
 136                        memcpy(sctx->buf + partial, data, done + 64);
 137                        src = sctx->buf;
 138                }
 139
 140                do {
 141                        sha256_transform(sctx->state, src, W);
 142                        done += 64;
 143                        src = data + done;
 144                } while (done + 63 < len);
 145
 146                memzero_explicit(W, sizeof(W));
 147
 148                partial = 0;
 149        }
 150        memcpy(sctx->buf + partial, src, len - done);
 151}
 152EXPORT_SYMBOL(sha256_update);
 153
 154void sha224_update(struct sha256_state *sctx, const u8 *data, unsigned int len)
 155{
 156        sha256_update(sctx, data, len);
 157}
 158EXPORT_SYMBOL(sha224_update);
 159
 160static void __sha256_final(struct sha256_state *sctx, u8 *out, int digest_words)
 161{
 162        __be32 *dst = (__be32 *)out;
 163        __be64 bits;
 164        unsigned int index, pad_len;
 165        int i;
 166        static const u8 padding[64] = { 0x80, };
 167
 168        /* Save number of bits */
 169        bits = cpu_to_be64(sctx->count << 3);
 170
 171        /* Pad out to 56 mod 64. */
 172        index = sctx->count & 0x3f;
 173        pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
 174        sha256_update(sctx, padding, pad_len);
 175
 176        /* Append length (before padding) */
 177        sha256_update(sctx, (const u8 *)&bits, sizeof(bits));
 178
 179        /* Store state in digest */
 180        for (i = 0; i < digest_words; i++)
 181                put_unaligned_be32(sctx->state[i], &dst[i]);
 182
 183        /* Zeroize sensitive information. */
 184        memzero_explicit(sctx, sizeof(*sctx));
 185}
 186
 187void sha256_final(struct sha256_state *sctx, u8 *out)
 188{
 189        __sha256_final(sctx, out, 8);
 190}
 191EXPORT_SYMBOL(sha256_final);
 192
 193void sha224_final(struct sha256_state *sctx, u8 *out)
 194{
 195        __sha256_final(sctx, out, 7);
 196}
 197EXPORT_SYMBOL(sha224_final);
 198
 199void sha256(const u8 *data, unsigned int len, u8 *out)
 200{
 201        struct sha256_state sctx;
 202
 203        sha256_init(&sctx);
 204        sha256_update(&sctx, data, len);
 205        sha256_final(&sctx, out);
 206}
 207EXPORT_SYMBOL(sha256);
 208
 209MODULE_LICENSE("GPL");
 210