OpenCoverage

blake2s.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/blake2/blake2s.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.-
3 *-
4 * Licensed under the OpenSSL license (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-
21#include "blake2_locl.h"-
22#include "blake2_impl.h"-
23-
24static const uint32_t blake2s_IV[8] =-
25{-
26 0x6A09E667U, 0xBB67AE85U, 0x3C6EF372U, 0xA54FF53AU,-
27 0x510E527FU, 0x9B05688CU, 0x1F83D9ABU, 0x5BE0CD19U-
28};-
29-
30static const uint8_t blake2s_sigma[10][16] =-
31{-
32 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,-
33 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,-
34 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,-
35 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,-
36 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,-
37 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,-
38 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,-
39 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,-
40 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,-
41 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,-
42};-
43-
44/* Set that it's the last block we'll compress */-
45static ossl_inline void blake2s_set_lastblock(BLAKE2S_CTX *S)-
46{-
47 S->f[0] = -1;-
48}
executed 9 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9
49-
50/* Initialize the hashing state. */-
51static ossl_inline void blake2s_init0(BLAKE2S_CTX *S)-
52{-
53 int i;-
54-
55 memset(S, 0, sizeof(BLAKE2S_CTX));-
56 for (i = 0; i < 8; ++i) {
i < 8Description
TRUEevaluated 72 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
9-72
57 S->h[i] = blake2s_IV[i];-
58 }
executed 72 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
72
59}
executed 9 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9
60-
61/* init2 xors IV with input parameter block */-
62static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P)-
63{-
64 const uint8_t *p = (const uint8_t *)(P);-
65 size_t i;-
66-
67 /* The param struct is carefully hand packed, and should be 32 bytes on-
68 * every platform. */-
69 assert(sizeof(BLAKE2S_PARAM) == 32);-
70 blake2s_init0(S);-
71 /* IV XOR ParamBlock */-
72 for (i = 0; i < 8; ++i) {
i < 8Description
TRUEevaluated 72 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
9-72
73 S->h[i] ^= load32(&p[i*4]);-
74 }
executed 72 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
72
75}
executed 9 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9
76-
77/* Initialize the hashing context. Always returns 1. */-
78int BLAKE2s_Init(BLAKE2S_CTX *c)-
79{-
80 BLAKE2S_PARAM P[1];-
81-
82 P->digest_length = BLAKE2S_DIGEST_LENGTH;-
83 P->key_length = 0;-
84 P->fanout = 1;-
85 P->depth = 1;-
86 store32(P->leaf_length, 0);-
87 store48(P->node_offset, 0);-
88 P->node_depth = 0;-
89 P->inner_length = 0;-
90 memset(P->salt, 0, sizeof(P->salt));-
91 memset(P->personal, 0, sizeof(P->personal));-
92 blake2s_init_param(c, P);-
93 return 1;
executed 9 times by 1 test: return 1;
Executed by:
  • libcrypto.so.1.1
9
94}-
95-
96/* Permute the state while xoring in the block of data. */-
97static void blake2s_compress(BLAKE2S_CTX *S,-
98 const uint8_t *blocks,-
99 size_t len)-
100{-
101 uint32_t m[16];-
102 uint32_t v[16];-
103 size_t i;-
104 size_t increment;-
105-
106 /*-
107 * There are two distinct usage vectors for this function:-
108 *-
109 * a) BLAKE2s_Update uses it to process complete blocks,-
110 * possibly more than one at a time;-
111 *-
112 * b) BLAK2s_Final uses it to process last block, always-
113 * single but possibly incomplete, in which case caller-
114 * pads input with zeros.-
115 */-
116 assert(len < BLAKE2S_BLOCKBYTES || len % BLAKE2S_BLOCKBYTES == 0);-
117-
118 /*-
119 * Since last block is always processed with separate call,-
120 * |len| not being multiple of complete blocks can be observed-
121 * only with |len| being less than BLAKE2S_BLOCKBYTES ("less"-
122 * including even zero), which is why following assignment doesn't-
123 * have to reside inside the main loop below.-
124 */-
125 increment = len < BLAKE2S_BLOCKBYTES ? len : BLAKE2S_BLOCKBYTES;
len < 64Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 4 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
4-8
126-
127 for (i = 0; i < 8; ++i) {
i < 8Description
TRUEevaluated 96 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 12 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
12-96
128 v[i] = S->h[i];-
129 }
executed 96 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
96
130-
131 do {-
132 for (i = 0; i < 16; ++i) {
i < 16Description
TRUEevaluated 208 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 13 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
13-208
133 m[i] = load32(blocks + i * sizeof(m[i]));-
134 }
executed 208 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
208
135-
136 /* blake2s_increment_counter */-
137 S->t[0] += increment;-
138 S->t[1] += (S->t[0] < increment);-
139-
140 v[ 8] = blake2s_IV[0];-
141 v[ 9] = blake2s_IV[1];-
142 v[10] = blake2s_IV[2];-
143 v[11] = blake2s_IV[3];-
144 v[12] = S->t[0] ^ blake2s_IV[4];-
145 v[13] = S->t[1] ^ blake2s_IV[5];-
146 v[14] = S->f[0] ^ blake2s_IV[6];-
147 v[15] = S->f[1] ^ blake2s_IV[7];-
148#define G(r,i,a,b,c,d) \-
149 do { \-
150 a = a + b + m[blake2s_sigma[r][2*i+0]]; \-
151 d = rotr32(d ^ a, 16); \-
152 c = c + d; \-
153 b = rotr32(b ^ c, 12); \-
154 a = a + b + m[blake2s_sigma[r][2*i+1]]; \-
155 d = rotr32(d ^ a, 8); \-
156 c = c + d; \-
157 b = rotr32(b ^ c, 7); \-
158 } while (0)-
159#define ROUND(r) \-
160 do { \-
161 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \-
162 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \-
163 G(r,2,v[ 2],v[ 6],v[10],v[14]); \-
164 G(r,3,v[ 3],v[ 7],v[11],v[15]); \-
165 G(r,4,v[ 0],v[ 5],v[10],v[15]); \-
166 G(r,5,v[ 1],v[ 6],v[11],v[12]); \-
167 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \-
168 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \-
169 } while (0)-
170#if defined(OPENSSL_SMALL_FOOTPRINT)-
171 /* almost 3x reduction on x86_64, 4.5x on ARMv8, 4x on ARMv4 */-
172 for (i = 0; i < 10; i++) {-
173 ROUND(i);-
174 }-
175#else-
176 ROUND(0);-
177 ROUND(1);-
178 ROUND(2);-
179 ROUND(3);-
180 ROUND(4);-
181 ROUND(5);-
182 ROUND(6);-
183 ROUND(7);-
184 ROUND(8);-
185 ROUND(9);-
186#endif-
187-
188 for (i = 0; i < 8; ++i) {
i < 8Description
TRUEevaluated 104 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 13 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
13-104
189 S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];-
190 }
executed 104 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
104
191#undef G-
192#undef ROUND-
193 blocks += increment;-
194 len -= increment;-
195 } while (len);
executed 13 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
lenDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 12 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
1-13
196}
executed 12 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
12
197-
198/* Absorb the input data into the hash state. Always returns 1. */-
199int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen)-
200{-
201 const uint8_t *in = data;-
202 size_t fill;-
203-
204 /*-
205 * Intuitively one would expect intermediate buffer, c->buf, to-
206 * store incomplete blocks. But in this case we are interested to-
207 * temporarily stash even complete blocks, because last one in the-
208 * stream has to be treated in special way, and at this point we-
209 * don't know if last block in *this* call is last one "ever". This-
210 * is the reason for why |datalen| is compared as >, and not >=.-
211 */-
212 fill = sizeof(c->buf) - c->buflen;-
213 if (datalen > fill) {
datalen > fillDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 6 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
3-6
214 if (c->buflen) {
c->buflenDescription
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-3
215 memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */-
216 blake2s_compress(c, c->buf, BLAKE2S_BLOCKBYTES);-
217 c->buflen = 0;-
218 in += fill;-
219 datalen -= fill;-
220 }
never executed: end of block
0
221 if (datalen > BLAKE2S_BLOCKBYTES) {
datalen > 64Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-3
222 size_t stashlen = datalen % BLAKE2S_BLOCKBYTES;-
223 /*-
224 * If |datalen| is a multiple of the blocksize, stash-
225 * last complete block, it can be final one...-
226 */-
227 stashlen = stashlen ? stashlen : BLAKE2S_BLOCKBYTES;
stashlenDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 1 time by 1 test
Evaluated by:
  • libcrypto.so.1.1
1-2
228 datalen -= stashlen;-
229 blake2s_compress(c, in, datalen);-
230 in += datalen;-
231 datalen = stashlen;-
232 }
executed 3 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
3
233 }
executed 3 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
3
234-
235 assert(datalen <= BLAKE2S_BLOCKBYTES);-
236-
237 memcpy(c->buf + c->buflen, in, datalen);-
238 c->buflen += datalen; /* Be lazy, do not compress */-
239-
240 return 1;
executed 9 times by 1 test: return 1;
Executed by:
  • libcrypto.so.1.1
9
241}-
242-
243/*-
244 * Calculate the final hash and save it in md.-
245 * Always returns 1.-
246 */-
247int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c)-
248{-
249 int i;-
250-
251 blake2s_set_lastblock(c);-
252 /* Padding */-
253 memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);-
254 blake2s_compress(c, c->buf, c->buflen);-
255-
256 /* Output full hash to temp buffer */-
257 for (i = 0; i < 8; ++i) {
i < 8Description
TRUEevaluated 72 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
9-72
258 store32(md + sizeof(c->h[i]) * i, c->h[i]);-
259 }
executed 72 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
72
260-
261 OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX));-
262 return 1;
executed 9 times by 1 test: return 1;
Executed by:
  • libcrypto.so.1.1
9
263}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2