1/* 2 * Copyright 2017, DornerWorks 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 * 6 * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 7 * a DARPA SBIR, Contract Number D16PC00107. 8 * 9 * Approved for Public Release, Distribution Unlimited. 10 * 11 */ 12 13/* 14 * public domain sha256 crypt implementation 15 * 16 * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt 17 * in this implementation at least 32bit int is assumed, 18 * key length is limited, the $5$ prefix is mandatory, '\n' and ':' is rejected 19 * in the salt and rounds= setting must contain a valid iteration count, 20 * on error "*" is returned. 21 */ 22#include <printf.h> 23#include <types.h> 24#include <strops.h> 25 26#include "../crypt_sha256.h" 27 28#define KEY_MAX 256 29#define SALT_MAX 16 30#define ROUNDS_DEFAULT 5000 31#define ROUNDS_MIN 1000 32#define ROUNDS_MAX 9999999 33 34/* public domain sha256 implementation based on fips180-3 */ 35 36static uint32_t ror(uint32_t n, int k) 37{ 38 return (n >> k) | (n << (32 - k)); 39} 40#define Ch(x,y,z) (z ^ (x & (y ^ z))) 41#define Maj(x,y,z) ((x & y) | (z & (x | y))) 42#define S0(x) (ror(x,2) ^ ror(x,13) ^ ror(x,22)) 43#define S1(x) (ror(x,6) ^ ror(x,11) ^ ror(x,25)) 44#define R0(x) (ror(x,7) ^ ror(x,18) ^ (x>>3)) 45#define R1(x) (ror(x,17) ^ ror(x,19) ^ (x>>10)) 46 47static const uint32_t K[64] = { 48 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 49 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 50 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 51 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 52 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 53 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 54 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 55 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 56}; 57 58static void processblock(sha256_t *s, const uint8_t *buf) 59{ 60 uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h; 61 int i; 62 63 for (i = 0; i < 16; i++) { 64 W[i] = (uint32_t)buf[4 * i] << 24; 65 W[i] |= (uint32_t)buf[4 * i + 1] << 16; 66 W[i] |= (uint32_t)buf[4 * i + 2] << 8; 67 W[i] |= buf[4 * i + 3]; 68 } 69 for (; i < 64; i++) { 70 W[i] = R1(W[i - 2]) + W[i - 7] + R0(W[i - 15]) + W[i - 16]; 71 } 72 a = s->h[0]; 73 b = s->h[1]; 74 c = s->h[2]; 75 d = s->h[3]; 76 e = s->h[4]; 77 f = s->h[5]; 78 g = s->h[6]; 79 h = s->h[7]; 80 for (i = 0; i < 64; i++) { 81 t1 = h + S1(e) + Ch(e, f, g) + K[i] + W[i]; 82 t2 = S0(a) + Maj(a, b, c); 83 h = g; 84 g = f; 85 f = e; 86 e = d + t1; 87 d = c; 88 c = b; 89 b = a; 90 a = t1 + t2; 91 } 92 s->h[0] += a; 93 s->h[1] += b; 94 s->h[2] += c; 95 s->h[3] += d; 96 s->h[4] += e; 97 s->h[5] += f; 98 s->h[6] += g; 99 s->h[7] += h; 100} 101 102static void pad(sha256_t *s) 103{ 104 unsigned r = s->len % 64; 105 106 s->buf[r++] = 0x80; 107 if (r > 56) { 108 memset(s->buf + r, 0, 64 - r); 109 r = 0; 110 processblock(s, s->buf); 111 } 112 memset(s->buf + r, 0, 56 - r); 113 s->len *= 8; 114 s->buf[56] = s->len >> 56; 115 s->buf[57] = s->len >> 48; 116 s->buf[58] = s->len >> 40; 117 s->buf[59] = s->len >> 32; 118 s->buf[60] = s->len >> 24; 119 s->buf[61] = s->len >> 16; 120 s->buf[62] = s->len >> 8; 121 s->buf[63] = s->len; 122 processblock(s, s->buf); 123} 124 125void sha256_init(sha256_t *s) 126{ 127 s->len = 0; 128 s->h[0] = 0x6a09e667; 129 s->h[1] = 0xbb67ae85; 130 s->h[2] = 0x3c6ef372; 131 s->h[3] = 0xa54ff53a; 132 s->h[4] = 0x510e527f; 133 s->h[5] = 0x9b05688c; 134 s->h[6] = 0x1f83d9ab; 135 s->h[7] = 0x5be0cd19; 136} 137 138void sha256_sum(sha256_t *s, uint8_t *md) 139{ 140 int i; 141 142 pad(s); 143 for (i = 0; i < 8; i++) { 144 md[4 * i] = s->h[i] >> 24; 145 md[4 * i + 1] = s->h[i] >> 16; 146 md[4 * i + 2] = s->h[i] >> 8; 147 md[4 * i + 3] = s->h[i]; 148 } 149} 150 151void sha256_update(sha256_t *s, const void *m, unsigned long len) 152{ 153 const uint8_t *p = m; 154 unsigned r = s->len % 64; 155 156 s->len += len; 157 if (r) { 158 if (len < 64 - r) { 159 memcpy(s->buf + r, p, len); 160 return; 161 } 162 memcpy(s->buf + r, p, 64 - r); 163 len -= 64 - r; 164 p += 64 - r; 165 processblock(s, s->buf); 166 } 167 for (; len >= 64; len -= 64, p += 64) { 168 processblock(s, p); 169 } 170 memcpy(s->buf, p, len); 171} 172