| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* GATE PROJECT LICENSE: | ||
| 2 | +----------------------------------------------------------------------------+ | ||
| 3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
| 4 | | All rights reserved. | | ||
| 5 | | | | ||
| 6 | | Redistribution and use in source and binary forms, with or without | | ||
| 7 | | modification, are permitted provided that the following conditions are met:| | ||
| 8 | | | | ||
| 9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
| 10 | | this list of conditions and the following disclaimer. | | ||
| 11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
| 12 | | notice, this list of conditions and the following disclaimer in the | | ||
| 13 | | documentation and/or other materials provided with the distribution. | | ||
| 14 | | | | ||
| 15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
| 16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
| 17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
| 18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
| 19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
| 20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
| 21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
| 22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
| 23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
| 24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
| 25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
| 26 | +----------------------------------------------------------------------------+ | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include "gate/encode/sha256hash.h" | ||
| 30 | #include "gate/memalloc.h" | ||
| 31 | |||
| 32 | /* Public information: http://en.wikipedia.org/wiki/SHA-2 */ | ||
| 33 | |||
| 34 | 336 | static unsigned long uint32_load(unsigned char const* buffer) | |
| 35 | { | ||
| 36 | 336 | return (((unsigned long)buffer[0] & 0xff) << 24) | |
| 37 | 336 | | (((unsigned long)buffer[1] & 0xff) << 16) | |
| 38 | 336 | | (((unsigned long)buffer[2] & 0xff) << 8) | |
| 39 | 336 | | (((unsigned long)buffer[3] & 0xff)) | |
| 40 | ; | ||
| 41 | } | ||
| 42 | |||
| 43 | 110 | static void uint32_save(unsigned long value, unsigned char* buffer) | |
| 44 | { | ||
| 45 | 110 | buffer[0] = (unsigned char)((value >> 24) & 0xff); | |
| 46 | 110 | buffer[1] = (unsigned char)((value >> 16) & 0xff); | |
| 47 | 110 | buffer[2] = (unsigned char)((value >> 8) & 0xff); | |
| 48 | 110 | buffer[3] = (unsigned char)((value) & 0xff); | |
| 49 | 110 | } | |
| 50 | |||
| 51 | 12096 | static unsigned long rotate_right32(unsigned long value, unsigned n) | |
| 52 | { | ||
| 53 | 12096 | return ((value >> n) & 0xffffffff) | ((value << (32 - n)) & 0xffffffff); | |
| 54 | } | ||
| 55 | |||
| 56 | static unsigned long const k[64] = { | ||
| 57 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | ||
| 58 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | ||
| 59 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | ||
| 60 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | ||
| 61 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | ||
| 62 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | ||
| 63 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | ||
| 64 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | ||
| 65 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | ||
| 66 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | ||
| 67 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | ||
| 68 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | ||
| 69 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | ||
| 70 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | ||
| 71 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | ||
| 72 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | ||
| 73 | }; | ||
| 74 | |||
| 75 | 21 | static void gate_sha256_add(gate_sha256_t* context, unsigned char const* block) | |
| 76 | { | ||
| 77 | unsigned n; | ||
| 78 | unsigned long s0; | ||
| 79 | unsigned long s1; | ||
| 80 | |||
| 81 | 21 | unsigned long a = context->h0; | |
| 82 | 21 | unsigned long b = context->h1; | |
| 83 | 21 | unsigned long c = context->h2; | |
| 84 | 21 | unsigned long d = context->h3; | |
| 85 | 21 | unsigned long e = context->h4; | |
| 86 | 21 | unsigned long f = context->h5; | |
| 87 | 21 | unsigned long g = context->h6; | |
| 88 | 21 | unsigned long h = context->h7; | |
| 89 | |||
| 90 | unsigned long w[64]; | ||
| 91 | |||
| 92 |
2/2✓ Branch 0 taken 336 times.
✓ Branch 1 taken 21 times.
|
357 | for (n = 0; n != 16; ++n) |
| 93 | { | ||
| 94 | 336 | w[n] = uint32_load(&block[n * 4]); | |
| 95 | } | ||
| 96 | |||
| 97 |
2/2✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 21 times.
|
1029 | for (n = 16; n < 64; ++n) |
| 98 | { | ||
| 99 | 1008 | s0 = rotate_right32(w[n - 15], 7) ^ rotate_right32(w[n - 15], 18) ^ (w[n - 15] >> 3); | |
| 100 | 1008 | s1 = rotate_right32(w[n - 2], 17) ^ rotate_right32(w[n - 2], 19) ^ (w[n - 2] >> 10); | |
| 101 | 1008 | w[n] = (w[n - 16] + s0 + w[n - 7] + s1) & 0xffffffff; | |
| 102 | } | ||
| 103 | |||
| 104 |
2/2✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 21 times.
|
1365 | for (n = 0; n < 64; ++n) |
| 105 | { | ||
| 106 | unsigned long ch; | ||
| 107 | unsigned long temp1; | ||
| 108 | unsigned long temp2; | ||
| 109 | unsigned long maj; | ||
| 110 | |||
| 111 | 1344 | s1 = rotate_right32(e, 6) ^ rotate_right32(e, 11) ^ rotate_right32(e, 25); | |
| 112 | 1344 | ch = (e & f) ^ ((~e) & g); | |
| 113 | 1344 | temp1 = (h + s1 + ch + k[n] + w[n]) & 0xffffffff; | |
| 114 | 1344 | s0 = rotate_right32(a, 2) ^ rotate_right32(a, 13) ^ rotate_right32(a, 22); | |
| 115 | 1344 | maj = (a & b) ^ (a & c) ^ (b & c); | |
| 116 | 1344 | temp2 = (s0 + maj) & 0xffffffff; | |
| 117 | |||
| 118 | 1344 | h = g; | |
| 119 | 1344 | g = f; | |
| 120 | 1344 | f = e; | |
| 121 | 1344 | e = (d + temp1) & 0xffffffff; | |
| 122 | 1344 | d = c; | |
| 123 | 1344 | c = b; | |
| 124 | 1344 | b = a; | |
| 125 | 1344 | a = (temp1 + temp2) & 0xffffffff; | |
| 126 | } | ||
| 127 | |||
| 128 | 21 | context->h0 = (context->h0 + a) & 0xffffffff; | |
| 129 | 21 | context->h1 = (context->h1 + b) & 0xffffffff; | |
| 130 | 21 | context->h2 = (context->h2 + c) & 0xffffffff; | |
| 131 | 21 | context->h3 = (context->h3 + d) & 0xffffffff; | |
| 132 | 21 | context->h4 = (context->h4 + e) & 0xffffffff; | |
| 133 | 21 | context->h5 = (context->h5 + f) & 0xffffffff; | |
| 134 | 21 | context->h6 = (context->h6 + g) & 0xffffffff; | |
| 135 | 21 | context->h7 = (context->h7 + h) & 0xffffffff; | |
| 136 | 21 | } | |
| 137 | |||
| 138 | 13 | void gate_sha256_init(gate_sha256_t* context) | |
| 139 | { | ||
| 140 | 13 | context->h0 = 0x6a09e667; | |
| 141 | 13 | context->h1 = 0xbb67ae85; | |
| 142 | 13 | context->h2 = 0x3c6ef372; | |
| 143 | 13 | context->h3 = 0xa54ff53a; | |
| 144 | 13 | context->h4 = 0x510e527f; | |
| 145 | 13 | context->h5 = 0x9b05688c; | |
| 146 | 13 | context->h6 = 0x1f83d9ab; | |
| 147 | 13 | context->h7 = 0x5be0cd19; | |
| 148 | |||
| 149 | 13 | context->bufferused = 0; | |
| 150 | 13 | context->msglength = 0; | |
| 151 | 13 | } | |
| 152 | 11 | void gate_sha256_update(gate_sha256_t* context, void const* buffer, gate_size_t length) | |
| 153 | { | ||
| 154 | 11 | unsigned char const* ptr = (unsigned char const*)buffer; | |
| 155 | |||
| 156 | 11 | context->msglength += length; | |
| 157 | |||
| 158 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
|
11 | if (context->bufferused > 0) |
| 159 | { | ||
| 160 | 1 | gate_size_t freebytes = GATE_SHA256_BLOCK_LENGTH - context->bufferused; | |
| 161 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (length < freebytes) |
| 162 | { | ||
| 163 | ✗ | gate_mem_copy(&context->buffer[context->bufferused], ptr, length); | |
| 164 | ✗ | context->bufferused += length; | |
| 165 | ✗ | return; | |
| 166 | } | ||
| 167 | else | ||
| 168 | { | ||
| 169 | 1 | gate_mem_copy(&context->buffer[context->bufferused], ptr, freebytes); | |
| 170 | 1 | gate_sha256_add(context, &context->buffer[0]); | |
| 171 | 1 | context->bufferused = 0; | |
| 172 | 1 | ptr += freebytes; | |
| 173 | 1 | length -= freebytes; | |
| 174 | } | ||
| 175 | } | ||
| 176 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 11 times.
|
20 | while (length >= GATE_SHA256_BLOCK_LENGTH) |
| 177 | { | ||
| 178 | 9 | gate_sha256_add(context, ptr); | |
| 179 | 9 | ptr += GATE_SHA256_BLOCK_LENGTH; | |
| 180 | 9 | length -= GATE_SHA256_BLOCK_LENGTH; | |
| 181 | } | ||
| 182 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if (length > 0) |
| 183 | { | ||
| 184 | 11 | gate_mem_copy(context->buffer, ptr, length); | |
| 185 | 11 | context->bufferused = length; | |
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | 11 | void gate_sha256_finish(gate_sha256_t* context, gate_sha256_result_t* result) | |
| 190 | { | ||
| 191 | 11 | gate_uint64_t bitlen = context->msglength * 8; | |
| 192 | 11 | unsigned long bitlen_high = (unsigned long)(bitlen >> 32) & 0xffffffff; | |
| 193 | 11 | unsigned long bitlen_low = (unsigned long)(bitlen & 0xffffffff); | |
| 194 | 11 | gate_size_t freebytes = (GATE_SHA256_BLOCK_LENGTH - context->bufferused - 1); | |
| 195 | 11 | context->buffer[context->bufferused++] = 0x80; | |
| 196 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
|
11 | if (freebytes < 8) |
| 197 | { | ||
| 198 | ✗ | gate_mem_clear(&context->buffer[context->bufferused], freebytes); | |
| 199 | ✗ | gate_sha256_add(context, &context->buffer[0]); | |
| 200 | ✗ | freebytes = GATE_SHA256_BLOCK_LENGTH; | |
| 201 | ✗ | context->bufferused = 0; | |
| 202 | } | ||
| 203 | 11 | gate_mem_clear(&context->buffer[context->bufferused], GATE_SHA256_BLOCK_LENGTH - 8 - context->bufferused); | |
| 204 | 11 | uint32_save(bitlen_high, &context->buffer[GATE_SHA256_BLOCK_LENGTH - 8]); | |
| 205 | 11 | uint32_save(bitlen_low, &context->buffer[GATE_SHA256_BLOCK_LENGTH - 4]); | |
| 206 | |||
| 207 | 11 | gate_sha256_add(context, context->buffer); | |
| 208 | |||
| 209 | 11 | uint32_save(context->h0, &result->hash[0]); | |
| 210 | 11 | uint32_save(context->h1, &result->hash[4]); | |
| 211 | 11 | uint32_save(context->h2, &result->hash[8]); | |
| 212 | 11 | uint32_save(context->h3, &result->hash[12]); | |
| 213 | 11 | uint32_save(context->h4, &result->hash[16]); | |
| 214 | 11 | uint32_save(context->h5, &result->hash[20]); | |
| 215 | 11 | uint32_save(context->h6, &result->hash[24]); | |
| 216 | 11 | uint32_save(context->h7, &result->hash[28]); | |
| 217 | 11 | } | |
| 218 |