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