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