1 1.1 christos /* 2 1.1 christos * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos /* 11 1.1 christos * Derived from the BLAKE2 reference implementation written by Samuel Neves. 12 1.1 christos * Copyright 2012, Samuel Neves <sneves (at) dei.uc.pt> 13 1.1 christos * More information about the BLAKE2 hash function and its implementations 14 1.1 christos * can be found at https://blake2.net. 15 1.1 christos */ 16 1.1 christos 17 1.1 christos #include <assert.h> 18 1.1 christos #include <string.h> 19 1.1 christos #include <openssl/crypto.h> 20 1.1 christos #include "internal/numbers.h" 21 1.1 christos #include "blake2_impl.h" 22 1.1 christos #include "prov/blake2.h" 23 1.1 christos 24 1.1.1.2 christos static const uint64_t blake2b_IV[8] = { 25 1.1 christos 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 26 1.1 christos 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 27 1.1 christos 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 28 1.1 christos 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL 29 1.1 christos }; 30 1.1 christos 31 1.1.1.2 christos static const uint8_t blake2b_sigma[12][16] = { 32 1.1.1.2 christos { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, 33 1.1.1.2 christos { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, 34 1.1.1.2 christos { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, 35 1.1.1.2 christos { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, 36 1.1.1.2 christos { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, 37 1.1.1.2 christos { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, 38 1.1.1.2 christos { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, 39 1.1.1.2 christos { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, 40 1.1.1.2 christos { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, 41 1.1.1.2 christos { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, 42 1.1.1.2 christos { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, 43 1.1.1.2 christos { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } 44 1.1 christos }; 45 1.1 christos 46 1.1 christos /* Set that it's the last block we'll compress */ 47 1.1 christos static ossl_inline void blake2b_set_lastblock(BLAKE2B_CTX *S) 48 1.1 christos { 49 1.1 christos S->f[0] = -1; 50 1.1 christos } 51 1.1 christos 52 1.1 christos /* Initialize the hashing state. */ 53 1.1 christos static ossl_inline void blake2b_init0(BLAKE2B_CTX *S) 54 1.1 christos { 55 1.1 christos int i; 56 1.1 christos 57 1.1 christos memset(S, 0, sizeof(BLAKE2B_CTX)); 58 1.1 christos for (i = 0; i < 8; ++i) { 59 1.1 christos S->h[i] = blake2b_IV[i]; 60 1.1 christos } 61 1.1 christos } 62 1.1 christos 63 1.1 christos /* init xors IV with input parameter block and sets the output length */ 64 1.1 christos static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P) 65 1.1 christos { 66 1.1 christos size_t i; 67 1.1 christos const uint8_t *p = (const uint8_t *)(P); 68 1.1 christos 69 1.1 christos blake2b_init0(S); 70 1.1 christos S->outlen = P->digest_length; 71 1.1 christos 72 1.1 christos /* The param struct is carefully hand packed, and should be 64 bytes on 73 1.1 christos * every platform. */ 74 1.1 christos assert(sizeof(BLAKE2B_PARAM) == 64); 75 1.1 christos /* IV XOR ParamBlock */ 76 1.1 christos for (i = 0; i < 8; ++i) { 77 1.1 christos S->h[i] ^= load64(p + sizeof(S->h[i]) * i); 78 1.1 christos } 79 1.1 christos } 80 1.1 christos 81 1.1 christos /* Initialize the parameter block with default values */ 82 1.1 christos void ossl_blake2b_param_init(BLAKE2B_PARAM *P) 83 1.1 christos { 84 1.1 christos P->digest_length = BLAKE2B_DIGEST_LENGTH; 85 1.1.1.2 christos P->key_length = 0; 86 1.1.1.2 christos P->fanout = 1; 87 1.1.1.2 christos P->depth = 1; 88 1.1 christos store32(P->leaf_length, 0); 89 1.1 christos store64(P->node_offset, 0); 90 1.1.1.2 christos P->node_depth = 0; 91 1.1.1.2 christos P->inner_length = 0; 92 1.1 christos memset(P->reserved, 0, sizeof(P->reserved)); 93 1.1.1.2 christos memset(P->salt, 0, sizeof(P->salt)); 94 1.1 christos memset(P->personal, 0, sizeof(P->personal)); 95 1.1 christos } 96 1.1 christos 97 1.1 christos void ossl_blake2b_param_set_digest_length(BLAKE2B_PARAM *P, uint8_t outlen) 98 1.1 christos { 99 1.1 christos P->digest_length = outlen; 100 1.1 christos } 101 1.1 christos 102 1.1 christos void ossl_blake2b_param_set_key_length(BLAKE2B_PARAM *P, uint8_t keylen) 103 1.1 christos { 104 1.1 christos P->key_length = keylen; 105 1.1 christos } 106 1.1 christos 107 1.1 christos void ossl_blake2b_param_set_personal(BLAKE2B_PARAM *P, const uint8_t *personal, 108 1.1.1.2 christos size_t len) 109 1.1 christos { 110 1.1 christos memcpy(P->personal, personal, len); 111 1.1 christos memset(P->personal + len, 0, BLAKE2B_PERSONALBYTES - len); 112 1.1 christos } 113 1.1 christos 114 1.1 christos void ossl_blake2b_param_set_salt(BLAKE2B_PARAM *P, const uint8_t *salt, 115 1.1.1.2 christos size_t len) 116 1.1 christos { 117 1.1 christos memcpy(P->salt, salt, len); 118 1.1 christos memset(P->salt + len, 0, BLAKE2B_SALTBYTES - len); 119 1.1 christos } 120 1.1 christos 121 1.1 christos /* 122 1.1 christos * Initialize the hashing context with the given parameter block. 123 1.1 christos * Always returns 1. 124 1.1 christos */ 125 1.1 christos int ossl_blake2b_init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P) 126 1.1 christos { 127 1.1 christos blake2b_init_param(c, P); 128 1.1 christos return 1; 129 1.1 christos } 130 1.1 christos 131 1.1 christos /* 132 1.1 christos * Initialize the hashing context with the given parameter block and key. 133 1.1 christos * Always returns 1. 134 1.1 christos */ 135 1.1 christos int ossl_blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, 136 1.1.1.2 christos const void *key) 137 1.1 christos { 138 1.1 christos blake2b_init_param(c, P); 139 1.1 christos 140 1.1 christos /* Pad the key to form first data block */ 141 1.1 christos { 142 1.1.1.2 christos uint8_t block[BLAKE2B_BLOCKBYTES] = { 0 }; 143 1.1 christos 144 1.1 christos memcpy(block, key, P->key_length); 145 1.1 christos ossl_blake2b_update(c, block, BLAKE2B_BLOCKBYTES); 146 1.1 christos OPENSSL_cleanse(block, BLAKE2B_BLOCKBYTES); 147 1.1 christos } 148 1.1 christos 149 1.1 christos return 1; 150 1.1 christos } 151 1.1 christos 152 1.1 christos /* Permute the state while xoring in the block of data. */ 153 1.1 christos static void blake2b_compress(BLAKE2B_CTX *S, 154 1.1.1.2 christos const uint8_t *blocks, 155 1.1.1.2 christos size_t len) 156 1.1 christos { 157 1.1 christos uint64_t m[16]; 158 1.1 christos uint64_t v[16]; 159 1.1 christos int i; 160 1.1 christos size_t increment; 161 1.1 christos 162 1.1 christos /* 163 1.1 christos * There are two distinct usage vectors for this function: 164 1.1 christos * 165 1.1 christos * a) BLAKE2b_Update uses it to process complete blocks, 166 1.1 christos * possibly more than one at a time; 167 1.1 christos * 168 1.1 christos * b) BLAK2b_Final uses it to process last block, always 169 1.1 christos * single but possibly incomplete, in which case caller 170 1.1 christos * pads input with zeros. 171 1.1 christos */ 172 1.1 christos assert(len < BLAKE2B_BLOCKBYTES || len % BLAKE2B_BLOCKBYTES == 0); 173 1.1 christos 174 1.1 christos /* 175 1.1 christos * Since last block is always processed with separate call, 176 1.1 christos * |len| not being multiple of complete blocks can be observed 177 1.1 christos * only with |len| being less than BLAKE2B_BLOCKBYTES ("less" 178 1.1 christos * including even zero), which is why following assignment doesn't 179 1.1 christos * have to reside inside the main loop below. 180 1.1 christos */ 181 1.1 christos increment = len < BLAKE2B_BLOCKBYTES ? len : BLAKE2B_BLOCKBYTES; 182 1.1 christos 183 1.1 christos for (i = 0; i < 8; ++i) { 184 1.1 christos v[i] = S->h[i]; 185 1.1 christos } 186 1.1 christos 187 1.1 christos do { 188 1.1 christos for (i = 0; i < 16; ++i) { 189 1.1 christos m[i] = load64(blocks + i * sizeof(m[i])); 190 1.1 christos } 191 1.1 christos 192 1.1 christos /* blake2b_increment_counter */ 193 1.1 christos S->t[0] += increment; 194 1.1 christos S->t[1] += (S->t[0] < increment); 195 1.1 christos 196 1.1.1.2 christos v[8] = blake2b_IV[0]; 197 1.1.1.2 christos v[9] = blake2b_IV[1]; 198 1.1 christos v[10] = blake2b_IV[2]; 199 1.1 christos v[11] = blake2b_IV[3]; 200 1.1 christos v[12] = S->t[0] ^ blake2b_IV[4]; 201 1.1 christos v[13] = S->t[1] ^ blake2b_IV[5]; 202 1.1 christos v[14] = S->f[0] ^ blake2b_IV[6]; 203 1.1 christos v[15] = S->f[1] ^ blake2b_IV[7]; 204 1.1.1.2 christos #define G(r, i, a, b, c, d) \ 205 1.1.1.2 christos do { \ 206 1.1.1.2 christos a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ 207 1.1.1.2 christos d = rotr64(d ^ a, 32); \ 208 1.1.1.2 christos c = c + d; \ 209 1.1.1.2 christos b = rotr64(b ^ c, 24); \ 210 1.1.1.2 christos a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ 211 1.1.1.2 christos d = rotr64(d ^ a, 16); \ 212 1.1.1.2 christos c = c + d; \ 213 1.1.1.2 christos b = rotr64(b ^ c, 63); \ 214 1.1.1.2 christos } while (0) 215 1.1.1.2 christos #define ROUND(r) \ 216 1.1.1.2 christos do { \ 217 1.1.1.2 christos G(r, 0, v[0], v[4], v[8], v[12]); \ 218 1.1.1.2 christos G(r, 1, v[1], v[5], v[9], v[13]); \ 219 1.1.1.2 christos G(r, 2, v[2], v[6], v[10], v[14]); \ 220 1.1.1.2 christos G(r, 3, v[3], v[7], v[11], v[15]); \ 221 1.1.1.2 christos G(r, 4, v[0], v[5], v[10], v[15]); \ 222 1.1.1.2 christos G(r, 5, v[1], v[6], v[11], v[12]); \ 223 1.1.1.2 christos G(r, 6, v[2], v[7], v[8], v[13]); \ 224 1.1.1.2 christos G(r, 7, v[3], v[4], v[9], v[14]); \ 225 1.1.1.2 christos } while (0) 226 1.1 christos #if defined(OPENSSL_SMALL_FOOTPRINT) 227 1.1 christos /* 3x size reduction on x86_64, almost 7x on ARMv8, 9x on ARMv4 */ 228 1.1 christos for (i = 0; i < 12; i++) { 229 1.1 christos ROUND(i); 230 1.1 christos } 231 1.1 christos #else 232 1.1 christos ROUND(0); 233 1.1 christos ROUND(1); 234 1.1 christos ROUND(2); 235 1.1 christos ROUND(3); 236 1.1 christos ROUND(4); 237 1.1 christos ROUND(5); 238 1.1 christos ROUND(6); 239 1.1 christos ROUND(7); 240 1.1 christos ROUND(8); 241 1.1 christos ROUND(9); 242 1.1 christos ROUND(10); 243 1.1 christos ROUND(11); 244 1.1 christos #endif 245 1.1 christos 246 1.1 christos for (i = 0; i < 8; ++i) { 247 1.1 christos S->h[i] = v[i] ^= v[i + 8] ^ S->h[i]; 248 1.1 christos } 249 1.1 christos #undef G 250 1.1 christos #undef ROUND 251 1.1 christos blocks += increment; 252 1.1 christos len -= increment; 253 1.1 christos } while (len); 254 1.1 christos } 255 1.1 christos 256 1.1 christos /* Absorb the input data into the hash state. Always returns 1. */ 257 1.1 christos int ossl_blake2b_update(BLAKE2B_CTX *c, const void *data, size_t datalen) 258 1.1 christos { 259 1.1 christos const uint8_t *in = data; 260 1.1 christos size_t fill; 261 1.1 christos 262 1.1 christos /* 263 1.1 christos * Intuitively one would expect intermediate buffer, c->buf, to 264 1.1 christos * store incomplete blocks. But in this case we are interested to 265 1.1 christos * temporarily stash even complete blocks, because last one in the 266 1.1 christos * stream has to be treated in special way, and at this point we 267 1.1 christos * don't know if last block in *this* call is last one "ever". This 268 1.1 christos * is the reason for why |datalen| is compared as >, and not >=. 269 1.1 christos */ 270 1.1 christos fill = sizeof(c->buf) - c->buflen; 271 1.1 christos if (datalen > fill) { 272 1.1 christos if (c->buflen) { 273 1.1 christos memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */ 274 1.1 christos blake2b_compress(c, c->buf, BLAKE2B_BLOCKBYTES); 275 1.1 christos c->buflen = 0; 276 1.1 christos in += fill; 277 1.1 christos datalen -= fill; 278 1.1 christos } 279 1.1 christos if (datalen > BLAKE2B_BLOCKBYTES) { 280 1.1 christos size_t stashlen = datalen % BLAKE2B_BLOCKBYTES; 281 1.1 christos /* 282 1.1 christos * If |datalen| is a multiple of the blocksize, stash 283 1.1 christos * last complete block, it can be final one... 284 1.1 christos */ 285 1.1 christos stashlen = stashlen ? stashlen : BLAKE2B_BLOCKBYTES; 286 1.1 christos datalen -= stashlen; 287 1.1 christos blake2b_compress(c, in, datalen); 288 1.1 christos in += datalen; 289 1.1 christos datalen = stashlen; 290 1.1 christos } 291 1.1 christos } 292 1.1 christos 293 1.1 christos assert(datalen <= BLAKE2B_BLOCKBYTES); 294 1.1 christos 295 1.1 christos memcpy(c->buf + c->buflen, in, datalen); 296 1.1 christos c->buflen += datalen; /* Be lazy, do not compress */ 297 1.1 christos 298 1.1 christos return 1; 299 1.1 christos } 300 1.1 christos 301 1.1 christos /* 302 1.1 christos * Calculate the final hash and save it in md. 303 1.1 christos * Always returns 1. 304 1.1 christos */ 305 1.1 christos int ossl_blake2b_final(unsigned char *md, BLAKE2B_CTX *c) 306 1.1 christos { 307 1.1.1.2 christos uint8_t outbuffer[BLAKE2B_OUTBYTES] = { 0 }; 308 1.1 christos uint8_t *target = outbuffer; 309 1.1 christos int iter = (c->outlen + 7) / 8; 310 1.1 christos int i; 311 1.1 christos 312 1.1 christos /* Avoid writing to the temporary buffer if possible */ 313 1.1 christos if ((c->outlen % sizeof(c->h[0])) == 0) 314 1.1 christos target = md; 315 1.1 christos 316 1.1 christos blake2b_set_lastblock(c); 317 1.1 christos /* Padding */ 318 1.1 christos memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen); 319 1.1 christos blake2b_compress(c, c->buf, c->buflen); 320 1.1 christos 321 1.1 christos /* Output full hash to buffer */ 322 1.1 christos for (i = 0; i < iter; ++i) 323 1.1 christos store64(target + sizeof(c->h[i]) * i, c->h[i]); 324 1.1 christos 325 1.1 christos if (target != md) { 326 1.1 christos memcpy(md, target, c->outlen); 327 1.1 christos OPENSSL_cleanse(target, sizeof(outbuffer)); 328 1.1 christos } 329 1.1 christos 330 1.1 christos OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX)); 331 1.1 christos return 1; 332 1.1 christos } 333