neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

sha256.c (10558B)


      1 /// @file sha256.c
      2 ///
      3 /// FIPS-180-2 compliant SHA-256 implementation
      4 /// GPL by Christophe Devine, applies to older version.
      5 /// Modified for md5deep, in public domain.
      6 /// Modified For Vim, Mohsin Ahmed,
      7 /// (original link www.cs.albany.edu/~mosh no longer available)
      8 /// Mohsin Ahmed states this work is distributed under the VIM License or GPL,
      9 /// at your choice.
     10 ///
     11 /// Vim specific notes:
     12 /// sha256_self_test() is implicitly called once.
     13 
     14 #include <stdbool.h>
     15 #include <stddef.h>
     16 #include <stdio.h>
     17 #include <string.h>
     18 
     19 #include "nvim/ascii_defs.h"
     20 #include "nvim/memory.h"
     21 #include "nvim/sha256.h"
     22 
     23 #include "sha256.c.generated.h"
     24 #define GET_UINT32(n, b, i) { \
     25  (n) = ((uint32_t)(b)[(i)] << 24) \
     26        | ((uint32_t)(b)[(i) + 1] << 16) \
     27        | ((uint32_t)(b)[(i) + 2] <<  8) \
     28        | ((uint32_t)(b)[(i) + 3]); \
     29 }
     30 
     31 #define PUT_UINT32(n, b, i) { \
     32  (b)[(i)] = (uint8_t)((n) >> 24); \
     33  (b)[(i) + 1] = (uint8_t)((n) >> 16); \
     34  (b)[(i) + 2] = (uint8_t)((n) >>  8); \
     35  (b)[(i) + 3] = (uint8_t)((n)); \
     36 }
     37 
     38 void sha256_start(context_sha256_T *ctx)
     39 {
     40  ctx->total[0] = 0;
     41  ctx->total[1] = 0;
     42 
     43  ctx->state[0] = 0x6A09E667;
     44  ctx->state[1] = 0xBB67AE85;
     45  ctx->state[2] = 0x3C6EF372;
     46  ctx->state[3] = 0xA54FF53A;
     47  ctx->state[4] = 0x510E527F;
     48  ctx->state[5] = 0x9B05688C;
     49  ctx->state[6] = 0x1F83D9AB;
     50  ctx->state[7] = 0x5BE0CD19;
     51 }
     52 
     53 static void sha256_process(context_sha256_T *ctx, const uint8_t data[SHA256_BUFFER_SIZE])
     54 {
     55  uint32_t temp1, temp2, W[SHA256_BUFFER_SIZE];
     56  uint32_t A, B, C, D, E, F, G, H;
     57 
     58  GET_UINT32(W[0],  data,  0);
     59  GET_UINT32(W[1],  data,  4);
     60  GET_UINT32(W[2],  data,  8);
     61  GET_UINT32(W[3],  data, 12);
     62  GET_UINT32(W[4],  data, 16);
     63  GET_UINT32(W[5],  data, 20);
     64  GET_UINT32(W[6],  data, 24);
     65  GET_UINT32(W[7],  data, 28);
     66  GET_UINT32(W[8],  data, 32);
     67  GET_UINT32(W[9],  data, 36);
     68  GET_UINT32(W[10], data, 40);
     69  GET_UINT32(W[11], data, 44);
     70  GET_UINT32(W[12], data, 48);
     71  GET_UINT32(W[13], data, 52);
     72  GET_UINT32(W[14], data, 56);
     73  GET_UINT32(W[15], data, 60);
     74 
     75 #define  SHR(x, n) (((x) & 0xFFFFFFFF) >> (n))
     76 #define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n))))
     77 
     78 #define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^  SHR(x, 3))
     79 #define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^  SHR(x, 10))
     80 
     81 #define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
     82 #define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
     83 
     84 #define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
     85 #define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
     86 
     87 #define R(t) \
     88  (W[t] = S1(W[(t) - 2]) + W[(t) - 7] + S0(W[(t) - 15]) + W[(t) - 16])
     89 
     90 #define P(a, b, c, d, e, f, g, h, x, K) { \
     91  temp1 = (h) + S3(e) + F1(e, f, g) + (K) + (x); \
     92  temp2 = S2(a) + F0(a, b, c); \
     93  (d) += temp1; (h) = temp1 + temp2; \
     94 }
     95 
     96  A = ctx->state[0];
     97  B = ctx->state[1];
     98  C = ctx->state[2];
     99  D = ctx->state[3];
    100  E = ctx->state[4];
    101  F = ctx->state[5];
    102  G = ctx->state[6];
    103  H = ctx->state[7];
    104 
    105  P(A, B, C, D, E, F, G, H, W[0],  0x428A2F98);
    106  P(H, A, B, C, D, E, F, G, W[1],  0x71374491);
    107  P(G, H, A, B, C, D, E, F, W[2],  0xB5C0FBCF);
    108  P(F, G, H, A, B, C, D, E, W[3],  0xE9B5DBA5);
    109  P(E, F, G, H, A, B, C, D, W[4],  0x3956C25B);
    110  P(D, E, F, G, H, A, B, C, W[5],  0x59F111F1);
    111  P(C, D, E, F, G, H, A, B, W[6],  0x923F82A4);
    112  P(B, C, D, E, F, G, H, A, W[7],  0xAB1C5ED5);
    113  P(A, B, C, D, E, F, G, H, W[8],  0xD807AA98);
    114  P(H, A, B, C, D, E, F, G, W[9],  0x12835B01);
    115  P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
    116  P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
    117  P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
    118  P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
    119  P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
    120  P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
    121  P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
    122  P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
    123  P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
    124  P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
    125  P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
    126  P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
    127  P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
    128  P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
    129  P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
    130  P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
    131  P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
    132  P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
    133  P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
    134  P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
    135  P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
    136  P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
    137  P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
    138  P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
    139  P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
    140  P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
    141  P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
    142  P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
    143  P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
    144  P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
    145  P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
    146  P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
    147  P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
    148  P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
    149  P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
    150  P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
    151  P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
    152  P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
    153  P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
    154  P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
    155  P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
    156  P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
    157  P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
    158  P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
    159  P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
    160  P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
    161  P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
    162  P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
    163  P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
    164  P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
    165  P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
    166  P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
    167  P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
    168  P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
    169 
    170  ctx->state[0] += A;
    171  ctx->state[1] += B;
    172  ctx->state[2] += C;
    173  ctx->state[3] += D;
    174  ctx->state[4] += E;
    175  ctx->state[5] += F;
    176  ctx->state[6] += G;
    177  ctx->state[7] += H;
    178 }
    179 
    180 void sha256_update(context_sha256_T *ctx, const uint8_t *input, size_t length)
    181 {
    182  if (length == 0) {
    183    return;
    184  }
    185 
    186  uint32_t left = ctx->total[0] & (SHA256_BUFFER_SIZE - 1);  // left < buf size
    187 
    188  ctx->total[0] += (uint32_t)length;
    189  ctx->total[0] &= 0xFFFFFFFF;
    190 
    191  if (ctx->total[0] < length) {
    192    ctx->total[1]++;
    193  }
    194 
    195  size_t fill = SHA256_BUFFER_SIZE - left;
    196 
    197  if (left && (length >= fill)) {
    198    memcpy(ctx->buffer + left, input, fill);
    199    sha256_process(ctx, ctx->buffer);
    200    length -= fill;
    201    input += fill;
    202    left = 0;
    203  }
    204 
    205  while (length >= SHA256_BUFFER_SIZE) {
    206    sha256_process(ctx, input);
    207    length -= SHA256_BUFFER_SIZE;
    208    input += SHA256_BUFFER_SIZE;
    209  }
    210 
    211  if (length) {
    212    memcpy(ctx->buffer + left, input, length);
    213  }
    214 }
    215 
    216 static uint8_t sha256_padding[SHA256_BUFFER_SIZE] = {
    217  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    218  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    219  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    220  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    221 };
    222 
    223 void sha256_finish(context_sha256_T *ctx, uint8_t digest[SHA256_SUM_SIZE])
    224 {
    225  uint32_t high = (ctx->total[0] >> 29) | (ctx->total[1] <<  3);
    226  uint32_t low = (ctx->total[0] <<  3);
    227 
    228  uint8_t msglen[8];
    229  PUT_UINT32(high, msglen, 0);
    230  PUT_UINT32(low,  msglen, 4);
    231 
    232  uint32_t last = ctx->total[0] & 0x3F;
    233  uint32_t padn = (last < 56) ? (56 - last) : (120 - last);
    234 
    235  sha256_update(ctx, sha256_padding, padn);
    236  sha256_update(ctx, msglen,            8);
    237 
    238  PUT_UINT32(ctx->state[0], digest,  0);
    239  PUT_UINT32(ctx->state[1], digest,  4);
    240  PUT_UINT32(ctx->state[2], digest,  8);
    241  PUT_UINT32(ctx->state[3], digest, 12);
    242  PUT_UINT32(ctx->state[4], digest, 16);
    243  PUT_UINT32(ctx->state[5], digest, 20);
    244  PUT_UINT32(ctx->state[6], digest, 24);
    245  PUT_UINT32(ctx->state[7], digest, 28);
    246 }
    247 
    248 #define SHA_STEP 2
    249 
    250 /// Gets the hex digest of the buffer.
    251 ///
    252 /// @param buf
    253 /// @param buf_len
    254 /// @param salt
    255 /// @param salt_len
    256 ///
    257 /// @returns hex digest of "buf[buf_len]" in a static array.
    258 ///          if "salt" is not NULL also do "salt[salt_len]".
    259 const char *sha256_bytes(const uint8_t *restrict buf,  size_t buf_len, const uint8_t *restrict salt,
    260                         size_t salt_len)
    261 {
    262  static char hexit[SHA256_BUFFER_SIZE + 1];  // buf size + NULL
    263 
    264  sha256_self_test();
    265 
    266  context_sha256_T ctx;
    267  sha256_start(&ctx);
    268  sha256_update(&ctx, buf, buf_len);
    269 
    270  if (salt != NULL) {
    271    sha256_update(&ctx, salt, salt_len);
    272  }
    273  uint8_t sha256sum[SHA256_SUM_SIZE];
    274  sha256_finish(&ctx, sha256sum);
    275 
    276  for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
    277    snprintf(hexit + j * SHA_STEP, SHA_STEP + 1, "%02x", sha256sum[j]);
    278  }
    279  hexit[sizeof(hexit) - 1] = NUL;
    280  return hexit;
    281 }
    282 
    283 // These are the standard FIPS-180-2 test vectors
    284 static char *sha_self_test_msg[] = {
    285  "abc",
    286  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
    287  NULL
    288 };
    289 
    290 static char *sha_self_test_vector[] = {
    291  "ba7816bf8f01cfea414140de5dae2223" \
    292  "b00361a396177a9cb410ff61f20015ad",
    293  "248d6a61d20638b8e5c026930c3e6039" \
    294  "a33ce45964ff2167f6ecedd419db06c1",
    295  "cdc76e5c9914fb9281a1c7e284d73e67" \
    296  "f1809a48a497200e046d39ccc7112cd0"
    297 };
    298 
    299 /// Perform a test on the SHA256 algorithm.
    300 ///
    301 /// @returns true if not failures generated.
    302 bool sha256_self_test(void)
    303 {
    304  char output[SHA256_BUFFER_SIZE + 1];  // buf size + NULL
    305  context_sha256_T ctx;
    306  uint8_t buf[1000];
    307  uint8_t sha256sum[SHA256_SUM_SIZE];
    308  const char *hexit;
    309 
    310  static bool sha256_self_tested = false;
    311  static bool failures = false;
    312 
    313  if (sha256_self_tested) {
    314    return failures == false;
    315  }
    316  sha256_self_tested = true;
    317 
    318  for (size_t i = 0; i < 3; i++) {
    319    if (i < 2) {
    320      hexit = sha256_bytes((uint8_t *)sha_self_test_msg[i],
    321                           strlen(sha_self_test_msg[i]),
    322                           NULL, 0);
    323      STRCPY(output, hexit);
    324    } else {
    325      sha256_start(&ctx);
    326      memset(buf, 'a', 1000);
    327 
    328      for (size_t j = 0; j < 1000; j++) {
    329        sha256_update(&ctx, buf, 1000);
    330      }
    331      sha256_finish(&ctx, sha256sum);
    332 
    333      for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
    334        snprintf(output + j * SHA_STEP, SHA_STEP + 1, "%02x", sha256sum[j]);
    335      }
    336    }
    337 
    338    if (memcmp(output, sha_self_test_vector[i], SHA256_BUFFER_SIZE) != 0) {
    339      failures = true;
    340      output[sizeof(output) - 1] = NUL;
    341 
    342      // printf("sha256_self_test %d failed %s\n", i, output);
    343    }
    344  }
    345  return failures == false;
    346 }