Line data Source code
1 : /**
2 : * The MIT License (MIT)
3 : *
4 : * Copyright (c) 2021 RSK Labs Ltd
5 : *
6 : * Permission is hereby granted, free of charge, to any person obtaining a copy
7 : * of this software and associated documentation files (the "Software"), to
8 : * deal in the Software without restriction, including without limitation the
9 : * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 : * sell copies of the Software, and to permit persons to whom the Software is
11 : * furnished to do so, subject to the following conditions:
12 : *
13 : * The above copyright notice and this permission notice shall be included in
14 : * all copies or substantial portions of the Software.
15 : *
16 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 : * IN THE SOFTWARE.
23 : */
24 :
25 : /*********************************************************************
26 : * Filename: sha256.c
27 : * Author: Brad Conte (brad AT bradconte.com)
28 : * Copyright:
29 : * Disclaimer: This code is presented "as is" without any guarantees.
30 : * Details: Implementation of the SHA-256 hashing algorithm.
31 : SHA-256 is one of the three algorithms in the SHA2
32 : specification. The others, SHA-384 and SHA-512, are not
33 : offered in this implementation.
34 : Algorithm specification can be found here:
35 : * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
36 : This implementation uses little endian byte order.
37 : *********************************************************************/
38 :
39 : /*************************** HEADER FILES ***************************/
40 : #include <stdlib.h>
41 : #include <memory.h>
42 : #include "sha256.h"
43 :
44 : /****************************** MACROS ******************************/
45 : #define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
46 : #define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
47 :
48 : #define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
49 : #define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
50 : #define EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22))
51 : #define EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25))
52 : #define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3))
53 : #define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10))
54 :
55 : /**************************** VARIABLES *****************************/
56 : static const uint32_t k[64] = {
57 : 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
58 : 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
59 : 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
60 : 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
61 : 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
62 : 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
63 : 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
64 : 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
65 : 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
66 : 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
67 : 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
68 :
69 : /*********************** FUNCTION DEFINITIONS ***********************/
70 6 : static void sha256_transform(SHA256_CTX *ctx, const uint8_t data[]) {
71 : uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
72 :
73 102 : for (i = 0, j = 0; i < 16; ++i, j += 4)
74 96 : m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) |
75 96 : (data[j + 3]);
76 294 : for (; i < 64; ++i)
77 288 : m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
78 :
79 6 : a = ctx->state[0];
80 6 : b = ctx->state[1];
81 6 : c = ctx->state[2];
82 6 : d = ctx->state[3];
83 6 : e = ctx->state[4];
84 6 : f = ctx->state[5];
85 6 : g = ctx->state[6];
86 6 : h = ctx->state[7];
87 :
88 390 : for (i = 0; i < 64; ++i) {
89 384 : t1 = h + EP1(e) + CH(e, f, g) + k[i] + m[i];
90 384 : t2 = EP0(a) + MAJ(a, b, c);
91 384 : h = g;
92 384 : g = f;
93 384 : f = e;
94 384 : e = d + t1;
95 384 : d = c;
96 384 : c = b;
97 384 : b = a;
98 384 : a = t1 + t2;
99 : }
100 :
101 6 : ctx->state[0] += a;
102 6 : ctx->state[1] += b;
103 6 : ctx->state[2] += c;
104 6 : ctx->state[3] += d;
105 6 : ctx->state[4] += e;
106 6 : ctx->state[5] += f;
107 6 : ctx->state[6] += g;
108 6 : ctx->state[7] += h;
109 6 : }
110 :
111 2 : void sha256_init(SHA256_CTX *ctx) {
112 2 : ctx->datalen = 0;
113 2 : ctx->bitlen = 0;
114 2 : ctx->state[0] = 0x6a09e667;
115 2 : ctx->state[1] = 0xbb67ae85;
116 2 : ctx->state[2] = 0x3c6ef372;
117 2 : ctx->state[3] = 0xa54ff53a;
118 2 : ctx->state[4] = 0x510e527f;
119 2 : ctx->state[5] = 0x9b05688c;
120 2 : ctx->state[6] = 0x1f83d9ab;
121 2 : ctx->state[7] = 0x5be0cd19;
122 2 : }
123 :
124 : #define EXTRACT_BIGENDIAN(buf, offset, n) \
125 : { \
126 : unsigned int __ix; \
127 : for (__ix = 0; __ix < sizeof(n); __ix++) { \
128 : n <<= 8; \
129 : n |= (buf)[(offset) + __ix]; \
130 : } \
131 : }
132 :
133 : /*
134 : * Update sha256 context to the given mid state.
135 : *
136 : * @arg [out] ctx SHA256 context to update
137 : * @arg [in] midstate pointer to midstate buffer
138 : *
139 : * Mid state must be 52 bytes long:
140 : * - midstate[0:8]: ignore
141 : * - midstate[8:16]: counter, as a big-endian uint64_t
142 : * - midstate[16:48]: current hash, as 8 big-endian uint32_t integers
143 : * - midstate[48:52]: ignore
144 : */
145 2 : void sha256_midstate(SHA256_CTX *ctx, uint8_t *midstate) {
146 2 : uint64_t counter = 0;
147 18 : EXTRACT_BIGENDIAN(midstate, 8, counter);
148 2 : ctx->bitlen = counter << 3;
149 18 : for (int i = 0; i < 8; i++) {
150 80 : EXTRACT_BIGENDIAN(
151 : midstate, 16 + i * sizeof(ctx->state[i]), ctx->state[i]);
152 : }
153 2 : }
154 :
155 2 : void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len) {
156 : uint32_t i;
157 :
158 261 : for (i = 0; i < len; ++i) {
159 259 : ctx->data[ctx->datalen] = data[i];
160 259 : ctx->datalen++;
161 259 : if (ctx->datalen == 64) {
162 3 : sha256_transform(ctx, ctx->data);
163 3 : ctx->bitlen += 512;
164 3 : ctx->datalen = 0;
165 : }
166 : }
167 2 : }
168 :
169 2 : void sha256_final(SHA256_CTX *ctx, uint8_t hash[]) {
170 : uint32_t i;
171 :
172 2 : i = ctx->datalen;
173 :
174 : // Pad whatever data is left in the buffer.
175 2 : if (ctx->datalen < 56) {
176 1 : ctx->data[i++] = 0x80;
177 46 : while (i < 56)
178 45 : ctx->data[i++] = 0x00;
179 : } else {
180 1 : ctx->data[i++] = 0x80;
181 7 : while (i < 64)
182 6 : ctx->data[i++] = 0x00;
183 1 : sha256_transform(ctx, ctx->data);
184 1 : memset(ctx->data, 0, 56);
185 : }
186 :
187 : // Append to the padding the total message's length in bits and transform.
188 2 : ctx->bitlen += ctx->datalen * 8;
189 2 : ctx->data[63] = ctx->bitlen;
190 2 : ctx->data[62] = ctx->bitlen >> 8;
191 2 : ctx->data[61] = ctx->bitlen >> 16;
192 2 : ctx->data[60] = ctx->bitlen >> 24;
193 2 : ctx->data[59] = ctx->bitlen >> 32;
194 2 : ctx->data[58] = ctx->bitlen >> 40;
195 2 : ctx->data[57] = ctx->bitlen >> 48;
196 2 : ctx->data[56] = ctx->bitlen >> 56;
197 2 : sha256_transform(ctx, ctx->data);
198 :
199 : // Since this implementation uses little endian byte ordering and SHA uses
200 : // big endian, reverse all the bytes when copying the final state to the
201 : // output hash.
202 10 : for (i = 0; i < 4; ++i) {
203 8 : hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
204 8 : hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
205 8 : hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
206 8 : hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
207 8 : hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
208 8 : hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
209 8 : hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
210 8 : hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
211 : }
212 2 : }
|