hash.c (9369B)
1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr) 2 * 3 * The RSys library is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published 5 * by the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * The RSys library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #define _POSIX_C_SOURCE 200112L 17 18 #include "endianness.h" 19 #include "hash.h" 20 #include "math.h" 21 #include "mem_allocator.h" 22 23 #include <string.h> 24 25 struct buffer { 26 const char* mem; 27 size_t len; 28 }; 29 30 /* Array of round constants: first 32 bits of the fractional parts of the cube 31 * roots of the first 64 primes 2..311 */ 32 static const uint32_t k[64] = { 33 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 34 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 35 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 36 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 37 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 38 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 39 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 40 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 41 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 42 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 43 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 44 }; 45 46 /* Most of this code comes from GnuPG's cipher/sha1.c */ 47 static void 48 sha256_process_chunk(struct sha256_ctx* ctx, const char chunk[64]) 49 { 50 uint32_t w[16]; 51 uint32_t a, b, c, d, e, f, g, h; 52 uint32_t i; 53 54 uint32_t tm; 55 uint32_t t0, t1; 56 57 ASSERT(ctx); 58 59 FOR_EACH(i, 0, 16) { 60 w[i] = big_endian_32(((uint32_t*)chunk)[i]); 61 } 62 63 a = ctx->state[0]; 64 b = ctx->state[1]; 65 c = ctx->state[2]; 66 d = ctx->state[3]; 67 e = ctx->state[4]; 68 f = ctx->state[5]; 69 g = ctx->state[6]; 70 h = ctx->state[7]; 71 72 #define ROL(X, N) (((X) << (N)) | ((X) >> (32 - (N)))) 73 #define S0(X) (ROL(X,25)^ROL(X,14)^(X>>3)) 74 #define S1(X) (ROL(X,15)^ROL(X,13)^(X>>10)) 75 #define SS0(X) (ROL(X,30)^ROL(X,19)^ROL(X,10)) 76 #define SS1(X) (ROL(X,26)^ROL(X,21)^ROL(X,7)) 77 #define M(I) (tm = S1(w[(I- 2)&0x0f]) + w[(I-7)&0x0f] \ 78 + S0(w[(I-15)&0x0f]) + w[I&0x0f], w[I&0x0f] = tm) 79 #define F2(A, B, C) (( A & B ) | (C & (A | B))) 80 #define F1(E, F, G) (G ^ (E & (F ^ G))) 81 #define R(A, B, C, D, E, F, G, H, K, M) { \ 82 t0 = SS0(A) + F2(A, B, C); \ 83 t1 = H + SS1(E) + F1(E, F, G) + K + M; \ 84 D += t1; \ 85 H = t0 + t1; \ 86 } (void)0 87 88 R( a, b, c, d, e, f, g, h, k[ 0], w[ 0] ); 89 R( h, a, b, c, d, e, f, g, k[ 1], w[ 1] ); 90 R( g, h, a, b, c, d, e, f, k[ 2], w[ 2] ); 91 R( f, g, h, a, b, c, d, e, k[ 3], w[ 3] ); 92 R( e, f, g, h, a, b, c, d, k[ 4], w[ 4] ); 93 R( d, e, f, g, h, a, b, c, k[ 5], w[ 5] ); 94 R( c, d, e, f, g, h, a, b, k[ 6], w[ 6] ); 95 R( b, c, d, e, f, g, h, a, k[ 7], w[ 7] ); 96 R( a, b, c, d, e, f, g, h, k[ 8], w[ 8] ); 97 R( h, a, b, c, d, e, f, g, k[ 9], w[ 9] ); 98 R( g, h, a, b, c, d, e, f, k[10], w[10] ); 99 R( f, g, h, a, b, c, d, e, k[11], w[11] ); 100 R( e, f, g, h, a, b, c, d, k[12], w[12] ); 101 R( d, e, f, g, h, a, b, c, k[13], w[13] ); 102 R( c, d, e, f, g, h, a, b, k[14], w[14] ); 103 R( b, c, d, e, f, g, h, a, k[15], w[15] ); 104 R( a, b, c, d, e, f, g, h, k[16], M(16) ); 105 R( h, a, b, c, d, e, f, g, k[17], M(17) ); 106 R( g, h, a, b, c, d, e, f, k[18], M(18) ); 107 R( f, g, h, a, b, c, d, e, k[19], M(19) ); 108 R( e, f, g, h, a, b, c, d, k[20], M(20) ); 109 R( d, e, f, g, h, a, b, c, k[21], M(21) ); 110 R( c, d, e, f, g, h, a, b, k[22], M(22) ); 111 R( b, c, d, e, f, g, h, a, k[23], M(23) ); 112 R( a, b, c, d, e, f, g, h, k[24], M(24) ); 113 R( h, a, b, c, d, e, f, g, k[25], M(25) ); 114 R( g, h, a, b, c, d, e, f, k[26], M(26) ); 115 R( f, g, h, a, b, c, d, e, k[27], M(27) ); 116 R( e, f, g, h, a, b, c, d, k[28], M(28) ); 117 R( d, e, f, g, h, a, b, c, k[29], M(29) ); 118 R( c, d, e, f, g, h, a, b, k[30], M(30) ); 119 R( b, c, d, e, f, g, h, a, k[31], M(31) ); 120 R( a, b, c, d, e, f, g, h, k[32], M(32) ); 121 R( h, a, b, c, d, e, f, g, k[33], M(33) ); 122 R( g, h, a, b, c, d, e, f, k[34], M(34) ); 123 R( f, g, h, a, b, c, d, e, k[35], M(35) ); 124 R( e, f, g, h, a, b, c, d, k[36], M(36) ); 125 R( d, e, f, g, h, a, b, c, k[37], M(37) ); 126 R( c, d, e, f, g, h, a, b, k[38], M(38) ); 127 R( b, c, d, e, f, g, h, a, k[39], M(39) ); 128 R( a, b, c, d, e, f, g, h, k[40], M(40) ); 129 R( h, a, b, c, d, e, f, g, k[41], M(41) ); 130 R( g, h, a, b, c, d, e, f, k[42], M(42) ); 131 R( f, g, h, a, b, c, d, e, k[43], M(43) ); 132 R( e, f, g, h, a, b, c, d, k[44], M(44) ); 133 R( d, e, f, g, h, a, b, c, k[45], M(45) ); 134 R( c, d, e, f, g, h, a, b, k[46], M(46) ); 135 R( b, c, d, e, f, g, h, a, k[47], M(47) ); 136 R( a, b, c, d, e, f, g, h, k[48], M(48) ); 137 R( h, a, b, c, d, e, f, g, k[49], M(49) ); 138 R( g, h, a, b, c, d, e, f, k[50], M(50) ); 139 R( f, g, h, a, b, c, d, e, k[51], M(51) ); 140 R( e, f, g, h, a, b, c, d, k[52], M(52) ); 141 R( d, e, f, g, h, a, b, c, k[53], M(53) ); 142 R( c, d, e, f, g, h, a, b, k[54], M(54) ); 143 R( b, c, d, e, f, g, h, a, k[55], M(55) ); 144 R( a, b, c, d, e, f, g, h, k[56], M(56) ); 145 R( h, a, b, c, d, e, f, g, k[57], M(57) ); 146 R( g, h, a, b, c, d, e, f, k[58], M(58) ); 147 R( f, g, h, a, b, c, d, e, k[59], M(59) ); 148 R( e, f, g, h, a, b, c, d, k[60], M(60) ); 149 R( d, e, f, g, h, a, b, c, k[61], M(61) ); 150 R( c, d, e, f, g, h, a, b, k[62], M(62) ); 151 R( b, c, d, e, f, g, h, a, k[63], M(63) ); 152 153 ctx->state[0] += a; 154 ctx->state[1] += b; 155 ctx->state[2] += c; 156 ctx->state[3] += d; 157 ctx->state[4] += e; 158 ctx->state[5] += f; 159 ctx->state[6] += g; 160 ctx->state[7] += h; 161 } 162 163 /******************************************************************************* 164 * Exported functions 165 ******************************************************************************/ 166 void 167 sha256_ctx_init(struct sha256_ctx* ctx) 168 { 169 /* Initial hash values: first 32 bits of the fractional parts of the square 170 * roots of the first 8 primes 2..19 */ 171 ctx->state[0] = 0x6a09e667; 172 ctx->state[1] = 0xbb67ae85; 173 ctx->state[2] = 0x3c6ef372; 174 ctx->state[3] = 0xa54ff53a; 175 ctx->state[4] = 0x510e527f; 176 ctx->state[5] = 0x9b05688c; 177 ctx->state[6] = 0x1f83d9ab; 178 ctx->state[7] = 0x5be0cd19; 179 ctx->len = 0; 180 ctx->nbits = 0; 181 } 182 183 void 184 sha256_ctx_update 185 (struct sha256_ctx* ctx, 186 const char* bytes, 187 size_t len) 188 { 189 size_t n; 190 uint32_t i; 191 ASSERT(ctx); 192 ASSERT(bytes || !len); 193 194 if(ctx->len) { 195 n = MMIN(64 - ctx->len, len); 196 memcpy(ctx->chunk + ctx->len, bytes, n); 197 ctx->len += (uint32_t)n; 198 bytes += n; 199 len -= n; 200 201 if(ctx->len == 64) { 202 sha256_process_chunk(ctx, ctx->chunk); 203 ctx->nbits += 512; 204 ctx->len = 0; 205 } 206 } 207 208 if(len >= 64) { 209 n = len / 64; 210 FOR_EACH(i, 0, n) { 211 sha256_process_chunk(ctx, bytes); 212 bytes += 64; 213 } 214 ctx->nbits += n * 512; 215 len -= n * 64; 216 } 217 218 if(len) { 219 memcpy(ctx->chunk, bytes, len); 220 ctx->len = (uint32_t)len; 221 } 222 } 223 224 void 225 sha256_ctx_finalize(struct sha256_ctx* ctx, hash256_T hash) 226 { 227 uint32_t i; 228 229 ASSERT(ctx && hash); 230 231 ctx->nbits += ctx->len * 8; /* Update the message's length */ 232 i = ctx->len; 233 234 /* Setup the '1' bit that marks the end of the data */ 235 ctx->chunk[i++] = (char)0x80; 236 237 /* Clean up the bytes after the data up to the last 8 bytes */ 238 if(ctx->len < 56) { 239 memset(ctx->chunk+i, 0, 56-i); 240 } else { 241 memset(ctx->chunk+i, 0, 64-i); 242 sha256_process_chunk(ctx, ctx->chunk); 243 memset(ctx->chunk, 0, 56); 244 } 245 246 /* Store the message's length in bits */ 247 *((uint64_t*)(ctx->chunk + 56)) = big_endian_64(ctx->nbits); 248 sha256_process_chunk(ctx, ctx->chunk); 249 250 /* Store result the result */ 251 ((uint32_t*)hash)[0] = big_endian_32(ctx->state[0]); 252 ((uint32_t*)hash)[1] = big_endian_32(ctx->state[1]); 253 ((uint32_t*)hash)[2] = big_endian_32(ctx->state[2]); 254 ((uint32_t*)hash)[3] = big_endian_32(ctx->state[3]); 255 ((uint32_t*)hash)[4] = big_endian_32(ctx->state[4]); 256 ((uint32_t*)hash)[5] = big_endian_32(ctx->state[5]); 257 ((uint32_t*)hash)[6] = big_endian_32(ctx->state[6]); 258 ((uint32_t*)hash)[7] = big_endian_32(ctx->state[7]); 259 } 260 261 void 262 hash_sha256 263 (const void* data, 264 const size_t len, 265 hash256_T hash) 266 { 267 struct sha256_ctx ctx; 268 ASSERT(hash); 269 ASSERT(data || !len); 270 271 sha256_ctx_init(&ctx); 272 sha256_ctx_update(&ctx, data, len); 273 sha256_ctx_finalize(&ctx, hash); 274 } 275 276 void 277 hash256_to_cstr(const hash256_T hash, char cstr[65]) 278 { 279 size_t i; 280 ASSERT(hash && cstr); 281 FOR_EACH(i, 0, sizeof(hash256_T)) { 282 sprintf(cstr+i*2, "%02x", (uint8_t)hash[i]); 283 } 284 } 285 286 int 287 hash256_eq(const hash256_T hash0, const hash256_T hash1) 288 { 289 return memcmp(hash0, hash1, sizeof(hash256_T)) == 0; 290 }