xref: /haiku/src/libs/libsolv/solv/sha2.c (revision f491972ca97c30b7b4ff6cf072de7bb345d58a69)
1 /*
2  * FILE:	sha2.c
3  * AUTHOR:	Aaron D. Gifford <me@aarongifford.com>
4  *
5  * Copyright (c) 2000-2001, Aaron D. Gifford
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holder nor the names of contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
33  */
34 
35 #include <sys/types.h>
36 #include <string.h>     /* memcpy()/memset() or bcopy()/bzero() */
37 /* #include <assert.h> */   /* assert() */
38 #include <stdio.h>
39 #include <sys/uio.h>
40 #include <unistd.h>
41 #include <inttypes.h>
42 
43 #include "sha2.h"
44 
45 
46 /*
47  * ASSERT NOTE:
48  * Some sanity checking code is included using assert().  On my FreeBSD
49  * system, this additional code can be removed by compiling with NDEBUG
50  * defined.  Check your own systems manpage on assert() to see how to
51  * compile WITHOUT the sanity checking code on your system.
52  *
53  * UNROLLED TRANSFORM LOOP NOTE:
54  * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
55  * loop version for the hash transform rounds (defined using macros
56  * later in this file).  Either define on the command line, for example:
57  *
58  *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
59  *
60  * or define below:
61  *
62  *   #define SHA2_UNROLL_TRANSFORM
63  *
64  */
65 
66  #define SHA2_UNROLL_TRANSFORM
67 
68 
69 /*** SHA-256/384/512 Machine Architecture Definitions *****************/
70 /*
71  * BYTE_ORDER NOTE:
72  *
73  * Please make sure that your system defines BYTE_ORDER.  If your
74  * architecture is little-endian, make sure it also defines
75  * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
76  * equivilent.
77  *
78  * If your system does not define the above, then you can do so by
79  * hand like this:
80  *
81  *   #define LITTLE_ENDIAN 1234
82  *   #define BIG_ENDIAN    4321
83  *
84  * And for little-endian machines, add:
85  *
86  *   #define BYTE_ORDER LITTLE_ENDIAN
87  *
88  * Or for big-endian machines:
89  *
90  *   #define BYTE_ORDER BIG_ENDIAN
91  *
92  * The FreeBSD machine this was written on defines BYTE_ORDER
93  * appropriately by including <sys/types.h> (which in turn includes
94  * <machine/endian.h> where the appropriate definitions are actually
95  * made).
96  */
97 
98 /*
99  * Define the following sha2_* types to types of the correct length on
100  * the native archtecture.   Most BSD systems and Linux define u_intXX_t
101  * types.  Machines with very recent ANSI C headers, can use the
102  * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
103  * during compile or in the sha.h header file.
104  *
105  * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
106  * will need to define these three typedefs below (and the appropriate
107  * ones in sha.h too) by hand according to their system architecture.
108  *
109  * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
110  * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
111  */
112 typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
113 typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
114 typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
115 
116 
117 /*** SHA-256/384/512 Various Length Definitions ***********************/
118 /* NOTE: Most of these are in sha2.h */
119 #define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
120 #define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
121 #define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
122 
123 
124 /*** ENDIAN REVERSAL MACROS *******************************************/
125 #ifndef WORDS_BIGENDIAN
126 #define REVERSE32(w,x)	{ \
127 	sha2_word32 tmp = (w); \
128 	tmp = (tmp >> 16) | (tmp << 16); \
129 	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
130 }
131 #define REVERSE64(w,x)	{ \
132 	sha2_word64 tmp = (w); \
133 	tmp = (tmp >> 32) | (tmp << 32); \
134 	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
135 	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
136 	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
137 	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
138 }
139 #endif /* !WORDS_BIGENDIAN */
140 
141 /*
142  * Macro for incrementally adding the unsigned 64-bit integer n to the
143  * unsigned 128-bit integer (represented using a two-element array of
144  * 64-bit words):
145  */
146 #define ADDINC128(w,n)	{ \
147 	(w)[0] += (sha2_word64)(n); \
148 	if ((w)[0] < (n)) { \
149 		(w)[1]++; \
150 	} \
151 }
152 
153 /*
154  * Macros for copying blocks of memory and for zeroing out ranges
155  * of memory.  Using these macros makes it easy to switch from
156  * using memset()/memcpy() and using bzero()/bcopy().
157  *
158  * Please define either SHA2_USE_MEMSET_MEMCPY or define
159  * SHA2_USE_BZERO_BCOPY depending on which function set you
160  * choose to use:
161  */
162 #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
163 /* Default to memset()/memcpy() if no option is specified */
164 #define	SHA2_USE_MEMSET_MEMCPY	1
165 #endif
166 #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
167 /* Abort with an error if BOTH options are defined */
168 #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
169 #endif
170 
171 #ifdef SHA2_USE_MEMSET_MEMCPY
172 #define MEMSET_BZERO(p,l)	memset((p), 0, (l))
173 #define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
174 #endif
175 #ifdef SHA2_USE_BZERO_BCOPY
176 #define MEMSET_BZERO(p,l)	bzero((p), (l))
177 #define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
178 #endif
179 
180 
181 /*** THE SIX LOGICAL FUNCTIONS ****************************************/
182 /*
183  * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
184  *
185  *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
186  *   S is a ROTATION) because the SHA-256/384/512 description document
187  *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
188  *   same "backwards" definition.
189  */
190 /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
191 #define R(b,x) 		((x) >> (b))
192 /* 32-bit Rotate-right (used in SHA-256): */
193 #define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
194 /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
195 #define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
196 
197 /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
198 #define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
199 #define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
200 
201 /* Four of six logical functions used in SHA-256: */
202 #define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
203 #define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
204 #define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
205 #define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
206 
207 /* Four of six logical functions used in SHA-384 and SHA-512: */
208 #define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
209 #define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
210 #define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
211 #define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
212 
213 /*** INTERNAL FUNCTION PROTOTYPES *************************************/
214 /* NOTE: These should not be accessed directly from outside this
215  * library -- they are intended for private internal visibility/use
216  * only.
217  */
218 static void SHA512_Last(SHA512_CTX*);
219 static void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
220 static void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
221 
222 
223 /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
224 /* Hash constant words K for SHA-256: */
225 const static sha2_word32 K256[64] = {
226 	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
227 	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
228 	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
229 	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
230 	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
231 	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
232 	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
233 	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
234 	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
235 	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
236 	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
237 	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
238 	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
239 	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
240 	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
241 	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
242 };
243 
244 /* Initial hash value H for SHA-256: */
245 const static sha2_word32 sha256_initial_hash_value[8] = {
246 	0x6a09e667UL,
247 	0xbb67ae85UL,
248 	0x3c6ef372UL,
249 	0xa54ff53aUL,
250 	0x510e527fUL,
251 	0x9b05688cUL,
252 	0x1f83d9abUL,
253 	0x5be0cd19UL
254 };
255 
256 /* Hash constant words K for SHA-384 and SHA-512: */
257 const static sha2_word64 K512[80] = {
258 	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
259 	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
260 	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
261 	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
262 	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
263 	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
264 	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
265 	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
266 	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
267 	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
268 	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
269 	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
270 	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
271 	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
272 	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
273 	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
274 	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
275 	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
276 	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
277 	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
278 	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
279 	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
280 	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
281 	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
282 	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
283 	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
284 	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
285 	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
286 	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
287 	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
288 	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
289 	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
290 	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
291 	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
292 	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
293 	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
294 	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
295 	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
296 	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
297 	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
298 };
299 
300 /* Initial hash value H for SHA-384 */
301 const static sha2_word64 sha384_initial_hash_value[8] = {
302 	0xcbbb9d5dc1059ed8ULL,
303 	0x629a292a367cd507ULL,
304 	0x9159015a3070dd17ULL,
305 	0x152fecd8f70e5939ULL,
306 	0x67332667ffc00b31ULL,
307 	0x8eb44a8768581511ULL,
308 	0xdb0c2e0d64f98fa7ULL,
309 	0x47b5481dbefa4fa4ULL
310 };
311 
312 /* Initial hash value H for SHA-512 */
313 const static sha2_word64 sha512_initial_hash_value[8] = {
314 	0x6a09e667f3bcc908ULL,
315 	0xbb67ae8584caa73bULL,
316 	0x3c6ef372fe94f82bULL,
317 	0xa54ff53a5f1d36f1ULL,
318 	0x510e527fade682d1ULL,
319 	0x9b05688c2b3e6c1fULL,
320 	0x1f83d9abfb41bd6bULL,
321 	0x5be0cd19137e2179ULL
322 };
323 
324 /*
325  * Constant used by SHA256/384/512_End() functions for converting the
326  * digest to a readable hexadecimal character string:
327  */
328 static const char *sha2_hex_digits = "0123456789abcdef";
329 
330 
331 /*** SHA-256: *********************************************************/
solv_SHA256_Init(SHA256_CTX * context)332 void solv_SHA256_Init(SHA256_CTX* context) {
333 	if (context == (SHA256_CTX*)0) {
334 		return;
335 	}
336 	MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
337 	MEMSET_BZERO((char *)context->buffer, SHA256_BLOCK_LENGTH);
338 	context->bitcount = 0;
339 }
340 
341 #ifdef SHA2_UNROLL_TRANSFORM
342 
343 /* Unrolled SHA-256 round macros: */
344 
345 #ifndef WORDS_BIGENDIAN
346 
347 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
348 	REVERSE32(*data++, W256[j]); \
349 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
350              K256[j] + W256[j]; \
351 	(d) += T1; \
352 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
353 	j++
354 
355 
356 #else /* !WORDS_BIGENDIAN */
357 
358 #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
359 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
360 	     K256[j] + (W256[j] = *data++); \
361 	(d) += T1; \
362 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
363 	j++
364 
365 #endif /* !WORDS_BIGENDIAN */
366 
367 #define ROUND256(a,b,c,d,e,f,g,h)	\
368 	s0 = W256[(j+1)&0x0f]; \
369 	s0 = sigma0_256(s0); \
370 	s1 = W256[(j+14)&0x0f]; \
371 	s1 = sigma1_256(s1); \
372 	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
373 	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
374 	(d) += T1; \
375 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
376 	j++
377 
SHA256_Transform(SHA256_CTX * context,const sha2_word32 * data)378 static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
379 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
380 	sha2_word32	T1, *W256;
381 	int		j;
382 
383 	W256 = context->buffer;
384 
385 	/* Initialize registers with the prev. intermediate value */
386 	a = context->state[0];
387 	b = context->state[1];
388 	c = context->state[2];
389 	d = context->state[3];
390 	e = context->state[4];
391 	f = context->state[5];
392 	g = context->state[6];
393 	h = context->state[7];
394 
395 	j = 0;
396 	do {
397 		/* Rounds 0 to 15 (unrolled): */
398 		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
399 		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
400 		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
401 		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
402 		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
403 		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
404 		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
405 		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
406 	} while (j < 16);
407 
408 	/* Now for the remaining rounds to 64: */
409 	do {
410 		ROUND256(a,b,c,d,e,f,g,h);
411 		ROUND256(h,a,b,c,d,e,f,g);
412 		ROUND256(g,h,a,b,c,d,e,f);
413 		ROUND256(f,g,h,a,b,c,d,e);
414 		ROUND256(e,f,g,h,a,b,c,d);
415 		ROUND256(d,e,f,g,h,a,b,c);
416 		ROUND256(c,d,e,f,g,h,a,b);
417 		ROUND256(b,c,d,e,f,g,h,a);
418 	} while (j < 64);
419 
420 	/* Compute the current intermediate hash value */
421 	context->state[0] += a;
422 	context->state[1] += b;
423 	context->state[2] += c;
424 	context->state[3] += d;
425 	context->state[4] += e;
426 	context->state[5] += f;
427 	context->state[6] += g;
428 	context->state[7] += h;
429 
430 	/* Clean up */
431 	a = b = c = d = e = f = g = h = T1 = 0;
432 }
433 
434 #else /* SHA2_UNROLL_TRANSFORM */
435 
SHA256_Transform(SHA256_CTX * context,const sha2_word32 * data)436 static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
437 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
438 	sha2_word32	T1, T2, *W256;
439 	int		j;
440 
441 	W256 = context->buffer;
442 
443 	/* Initialize registers with the prev. intermediate value */
444 	a = context->state[0];
445 	b = context->state[1];
446 	c = context->state[2];
447 	d = context->state[3];
448 	e = context->state[4];
449 	f = context->state[5];
450 	g = context->state[6];
451 	h = context->state[7];
452 
453 	j = 0;
454 	do {
455 #ifndef WORDS_BIGENDIAN
456 		/* Copy data while converting to host byte order */
457 		REVERSE32(*data++,W256[j]);
458 		/* Apply the SHA-256 compression function to update a..h */
459 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
460 #else /* !WORDS_BIGENDIAN */
461 		/* Apply the SHA-256 compression function to update a..h with copy */
462 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
463 #endif /* !WORDS_BIGENDIAN */
464 		T2 = Sigma0_256(a) + Maj(a, b, c);
465 		h = g;
466 		g = f;
467 		f = e;
468 		e = d + T1;
469 		d = c;
470 		c = b;
471 		b = a;
472 		a = T1 + T2;
473 
474 		j++;
475 	} while (j < 16);
476 
477 	do {
478 		/* Part of the message block expansion: */
479 		s0 = W256[(j+1)&0x0f];
480 		s0 = sigma0_256(s0);
481 		s1 = W256[(j+14)&0x0f];
482 		s1 = sigma1_256(s1);
483 
484 		/* Apply the SHA-256 compression function to update a..h */
485 		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
486 		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
487 		T2 = Sigma0_256(a) + Maj(a, b, c);
488 		h = g;
489 		g = f;
490 		f = e;
491 		e = d + T1;
492 		d = c;
493 		c = b;
494 		b = a;
495 		a = T1 + T2;
496 
497 		j++;
498 	} while (j < 64);
499 
500 	/* Compute the current intermediate hash value */
501 	context->state[0] += a;
502 	context->state[1] += b;
503 	context->state[2] += c;
504 	context->state[3] += d;
505 	context->state[4] += e;
506 	context->state[5] += f;
507 	context->state[6] += g;
508 	context->state[7] += h;
509 
510 	/* Clean up */
511 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
512 }
513 
514 #endif /* SHA2_UNROLL_TRANSFORM */
515 
solv_SHA256_Update(SHA256_CTX * context,const sha2_byte * data,size_t len)516 void solv_SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
517 	unsigned int	freespace, usedspace;
518 
519 	if (len == 0) {
520 		/* Calling with no data is valid - we do nothing */
521 		return;
522 	}
523 
524 	/* Sanity check: */
525 	/* assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); */
526 
527 	usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
528 	if (usedspace > 0) {
529 		/* Calculate how much free space is available in the buffer */
530 		freespace = SHA256_BLOCK_LENGTH - usedspace;
531 
532 		if (len >= freespace) {
533 			/* Fill the buffer completely and process it */
534 			MEMCPY_BCOPY(&((char *)context->buffer)[usedspace], data, freespace);
535 			context->bitcount += freespace << 3;
536 			len -= freespace;
537 			data += freespace;
538 			SHA256_Transform(context, context->buffer);
539 		} else {
540 			/* The buffer is not yet full */
541 			MEMCPY_BCOPY(&((char *)context->buffer)[usedspace], data, len);
542 			context->bitcount += len << 3;
543 			/* Clean up: */
544 			usedspace = freespace = 0;
545 			return;
546 		}
547 	}
548 	while (len >= SHA256_BLOCK_LENGTH) {
549 		/* Process as many complete blocks as we can */
550 		SHA256_Transform(context, (sha2_word32*)data);
551 		context->bitcount += SHA256_BLOCK_LENGTH << 3;
552 		len -= SHA256_BLOCK_LENGTH;
553 		data += SHA256_BLOCK_LENGTH;
554 	}
555 	if (len > 0) {
556 		/* There's left-overs, so save 'em */
557 		MEMCPY_BCOPY((char *)context->buffer, data, len);
558 		context->bitcount += len << 3;
559 	}
560 	/* Clean up: */
561 	usedspace = freespace = 0;
562 }
563 
solv_SHA256_Final(sha2_byte digest[],SHA256_CTX * context)564 void solv_SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
565 	sha2_word32	*d = (sha2_word32*)digest;
566 	unsigned int	usedspace;
567 
568 	/* Sanity check: */
569 	/* assert(context != (SHA256_CTX*)0); */
570 
571 	/* If no digest buffer is passed, we don't bother doing this: */
572 	if (digest != (sha2_byte*)0) {
573 		usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
574 #ifndef WORDS_BIGENDIAN
575 		/* Convert FROM host byte order */
576 		REVERSE64(context->bitcount,context->bitcount);
577 #endif
578 		if (usedspace > 0) {
579 			/* Begin padding with a 1 bit: */
580 			((char *)context->buffer)[usedspace++] = 0x80;
581 
582 			if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
583 				/* Set-up for the last transform: */
584 				MEMSET_BZERO(&((char *)context->buffer)[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
585 			} else {
586 				if (usedspace < SHA256_BLOCK_LENGTH) {
587 					MEMSET_BZERO(&((char *)context->buffer)[usedspace], SHA256_BLOCK_LENGTH - usedspace);
588 				}
589 				/* Do second-to-last transform: */
590 				SHA256_Transform(context, context->buffer);
591 
592 				/* And set-up for the last transform: */
593 				MEMSET_BZERO((char *)context->buffer, SHA256_SHORT_BLOCK_LENGTH);
594 			}
595 		} else {
596 			/* Set-up for the last transform: */
597 			MEMSET_BZERO((char *)context->buffer, SHA256_SHORT_BLOCK_LENGTH);
598 
599 			/* Begin padding with a 1 bit: */
600 			*((char *)context->buffer) = 0x80;
601 		}
602 		/* Set the bit count: */
603 		MEMCPY_BCOPY(&((char *)context->buffer)[SHA256_SHORT_BLOCK_LENGTH], (char *)(&context->bitcount), 8);
604 
605 		/* Final transform: */
606 		SHA256_Transform(context, context->buffer);
607 
608 #ifndef WORDS_BIGENDIAN
609 		{
610 			/* Convert TO host byte order */
611 			int	j;
612 			for (j = 0; j < 8; j++) {
613 				REVERSE32(context->state[j],context->state[j]);
614 				*d++ = context->state[j];
615 			}
616 		}
617 #else
618 		MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
619 #endif
620 	}
621 
622 	/* Clean up state data: */
623 	MEMSET_BZERO(context, sizeof(context));
624 	usedspace = 0;
625 }
626 
solv_SHA256_End(SHA256_CTX * context,char buffer[])627 char *solv_SHA256_End(SHA256_CTX* context, char buffer[]) {
628 	sha2_byte	digest[SHA256_DIGEST_LENGTH], *d = digest;
629 	int		i;
630 
631 	/* Sanity check: */
632 	/* assert(context != (SHA256_CTX*)0); */
633 
634 	if (buffer != (char*)0) {
635 		solv_SHA256_Final(digest, context);
636 
637 		for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
638 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
639 			*buffer++ = sha2_hex_digits[*d & 0x0f];
640 			d++;
641 		}
642 		*buffer = (char)0;
643 	} else {
644 		MEMSET_BZERO(context, sizeof(context));
645 	}
646 	MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
647 	return buffer;
648 }
649 
solv_SHA256_Data(const sha2_byte * data,size_t len,char digest[SHA256_DIGEST_STRING_LENGTH])650 char* solv_SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
651 	SHA256_CTX	context;
652 
653 	solv_SHA256_Init(&context);
654 	solv_SHA256_Update(&context, data, len);
655 	return solv_SHA256_End(&context, digest);
656 }
657 
658 
659 /*** SHA-512: *********************************************************/
solv_SHA512_Init(SHA512_CTX * context)660 void solv_SHA512_Init(SHA512_CTX* context) {
661 	if (context == (SHA512_CTX*)0) {
662 		return;
663 	}
664 	MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
665 	MEMSET_BZERO((char *)context->buffer, SHA512_BLOCK_LENGTH);
666 	context->bitcount[0] = context->bitcount[1] =  0;
667 }
668 
669 #ifdef SHA2_UNROLL_TRANSFORM
670 
671 /* Unrolled SHA-512 round macros: */
672 #ifndef WORDS_BIGENDIAN
673 
674 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
675 	REVERSE64(*data++, W512[j]); \
676 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
677              K512[j] + W512[j]; \
678 	(d) += T1, \
679 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
680 	j++
681 
682 
683 #else /* !WORDS_BIGENDIAN */
684 
685 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
686 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
687              K512[j] + (W512[j] = *data++); \
688 	(d) += T1; \
689 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
690 	j++
691 
692 #endif /* !WORDS_BIGENDIAN */
693 
694 #define ROUND512(a,b,c,d,e,f,g,h)	\
695 	s0 = W512[(j+1)&0x0f]; \
696 	s0 = sigma0_512(s0); \
697 	s1 = W512[(j+14)&0x0f]; \
698 	s1 = sigma1_512(s1); \
699 	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
700              (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
701 	(d) += T1; \
702 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
703 	j++
704 
SHA512_Transform(SHA512_CTX * context,const sha2_word64 * data)705 static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
706 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
707 	sha2_word64	T1, *W512 = context->buffer;
708 	int		j;
709 
710 	/* Initialize registers with the prev. intermediate value */
711 	a = context->state[0];
712 	b = context->state[1];
713 	c = context->state[2];
714 	d = context->state[3];
715 	e = context->state[4];
716 	f = context->state[5];
717 	g = context->state[6];
718 	h = context->state[7];
719 
720 	j = 0;
721 	do {
722 		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
723 		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
724 		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
725 		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
726 		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
727 		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
728 		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
729 		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
730 	} while (j < 16);
731 
732 	/* Now for the remaining rounds up to 79: */
733 	do {
734 		ROUND512(a,b,c,d,e,f,g,h);
735 		ROUND512(h,a,b,c,d,e,f,g);
736 		ROUND512(g,h,a,b,c,d,e,f);
737 		ROUND512(f,g,h,a,b,c,d,e);
738 		ROUND512(e,f,g,h,a,b,c,d);
739 		ROUND512(d,e,f,g,h,a,b,c);
740 		ROUND512(c,d,e,f,g,h,a,b);
741 		ROUND512(b,c,d,e,f,g,h,a);
742 	} while (j < 80);
743 
744 	/* Compute the current intermediate hash value */
745 	context->state[0] += a;
746 	context->state[1] += b;
747 	context->state[2] += c;
748 	context->state[3] += d;
749 	context->state[4] += e;
750 	context->state[5] += f;
751 	context->state[6] += g;
752 	context->state[7] += h;
753 
754 	/* Clean up */
755 	a = b = c = d = e = f = g = h = T1 = 0;
756 }
757 
758 #else /* SHA2_UNROLL_TRANSFORM */
759 
SHA512_Transform(SHA512_CTX * context,const sha2_word64 * data)760 static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
761 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
762 	sha2_word64	T1, T2, *W512 = context->buffer;
763 	int		j;
764 
765 	/* Initialize registers with the prev. intermediate value */
766 	a = context->state[0];
767 	b = context->state[1];
768 	c = context->state[2];
769 	d = context->state[3];
770 	e = context->state[4];
771 	f = context->state[5];
772 	g = context->state[6];
773 	h = context->state[7];
774 
775 	j = 0;
776 	do {
777 #ifndef WORDS_BIGENDIAN
778 		/* Convert TO host byte order */
779 		REVERSE64(*data++, W512[j]);
780 		/* Apply the SHA-512 compression function to update a..h */
781 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
782 #else /* !WORDS_BIGENDIAN */
783 		/* Apply the SHA-512 compression function to update a..h with copy */
784 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
785 #endif /* !WORDS_BIGENDIAN */
786 		T2 = Sigma0_512(a) + Maj(a, b, c);
787 		h = g;
788 		g = f;
789 		f = e;
790 		e = d + T1;
791 		d = c;
792 		c = b;
793 		b = a;
794 		a = T1 + T2;
795 
796 		j++;
797 	} while (j < 16);
798 
799 	do {
800 		/* Part of the message block expansion: */
801 		s0 = W512[(j+1)&0x0f];
802 		s0 = sigma0_512(s0);
803 		s1 = W512[(j+14)&0x0f];
804 		s1 =  sigma1_512(s1);
805 
806 		/* Apply the SHA-512 compression function to update a..h */
807 		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
808 		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
809 		T2 = Sigma0_512(a) + Maj(a, b, c);
810 		h = g;
811 		g = f;
812 		f = e;
813 		e = d + T1;
814 		d = c;
815 		c = b;
816 		b = a;
817 		a = T1 + T2;
818 
819 		j++;
820 	} while (j < 80);
821 
822 	/* Compute the current intermediate hash value */
823 	context->state[0] += a;
824 	context->state[1] += b;
825 	context->state[2] += c;
826 	context->state[3] += d;
827 	context->state[4] += e;
828 	context->state[5] += f;
829 	context->state[6] += g;
830 	context->state[7] += h;
831 
832 	/* Clean up */
833 	a = b = c = d = e = f = g = h = T1 = T2 = 0;
834 }
835 
836 #endif /* SHA2_UNROLL_TRANSFORM */
837 
solv_SHA512_Update(SHA512_CTX * context,const sha2_byte * data,size_t len)838 void solv_SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
839 	unsigned int	freespace, usedspace;
840 
841 	if (len == 0) {
842 		/* Calling with no data is valid - we do nothing */
843 		return;
844 	}
845 
846 	/* Sanity check: */
847 	/* assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); */
848 
849 	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
850 	if (usedspace > 0) {
851 		/* Calculate how much free space is available in the buffer */
852 		freespace = SHA512_BLOCK_LENGTH - usedspace;
853 
854 		if (len >= freespace) {
855 			/* Fill the buffer completely and process it */
856 			MEMCPY_BCOPY(&((char *)context->buffer)[usedspace], data, freespace);
857 			ADDINC128(context->bitcount, freespace << 3);
858 			len -= freespace;
859 			data += freespace;
860 			SHA512_Transform(context, context->buffer);
861 		} else {
862 			/* The buffer is not yet full */
863 			MEMCPY_BCOPY(&((char *)context->buffer)[usedspace], data, len);
864 			ADDINC128(context->bitcount, len << 3);
865 			/* Clean up: */
866 			usedspace = freespace = 0;
867 			return;
868 		}
869 	}
870 	while (len >= SHA512_BLOCK_LENGTH) {
871 		/* Process as many complete blocks as we can */
872 		SHA512_Transform(context, (sha2_word64*)data);
873 		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
874 		len -= SHA512_BLOCK_LENGTH;
875 		data += SHA512_BLOCK_LENGTH;
876 	}
877 	if (len > 0) {
878 		/* There's left-overs, so save 'em */
879 		MEMCPY_BCOPY((char *)context->buffer, data, len);
880 		ADDINC128(context->bitcount, len << 3);
881 	}
882 	/* Clean up: */
883 	usedspace = freespace = 0;
884 }
885 
SHA512_Last(SHA512_CTX * context)886 static void SHA512_Last(SHA512_CTX* context) {
887 	unsigned int	usedspace;
888 
889 	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
890 #ifndef WORDS_BIGENDIAN
891 	/* Convert FROM host byte order */
892 	REVERSE64(context->bitcount[0],context->bitcount[0]);
893 	REVERSE64(context->bitcount[1],context->bitcount[1]);
894 #endif
895 	if (usedspace > 0) {
896 		/* Begin padding with a 1 bit: */
897 		((char *)context->buffer)[usedspace++] = 0x80;
898 
899 		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
900 			/* Set-up for the last transform: */
901 			MEMSET_BZERO(&((char *)context->buffer)[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
902 		} else {
903 			if (usedspace < SHA512_BLOCK_LENGTH) {
904 				MEMSET_BZERO(&((char *)context->buffer)[usedspace], SHA512_BLOCK_LENGTH - usedspace);
905 			}
906 			/* Do second-to-last transform: */
907 			SHA512_Transform(context, context->buffer);
908 
909 			/* And set-up for the last transform: */
910 			MEMSET_BZERO((char *)context->buffer, SHA512_BLOCK_LENGTH - 2);
911 		}
912 	} else {
913 		/* Prepare for final transform: */
914 		MEMSET_BZERO((char *)context->buffer, SHA512_SHORT_BLOCK_LENGTH);
915 
916 		/* Begin padding with a 1 bit: */
917 		*((char *)context->buffer) = 0x80;
918 	}
919 	/* Store the length of input data (in bits): */
920         MEMCPY_BCOPY(&((char *)context->buffer)[SHA512_SHORT_BLOCK_LENGTH], (char *)(&context->bitcount[1]), 8);
921         MEMCPY_BCOPY(&((char *)context->buffer)[SHA512_SHORT_BLOCK_LENGTH + 8], (char *)(&context->bitcount[0]), 8);
922 
923 	/* Final transform: */
924 	SHA512_Transform(context, context->buffer);
925 }
926 
solv_SHA512_Final(sha2_byte digest[],SHA512_CTX * context)927 void solv_SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
928 	sha2_word64	*d = (sha2_word64*)digest;
929 
930 	/* Sanity check: */
931 	/* assert(context != (SHA512_CTX*)0); */
932 
933 	/* If no digest buffer is passed, we don't bother doing this: */
934 	if (digest != (sha2_byte*)0) {
935 		SHA512_Last(context);
936 
937 		/* Save the hash data for output: */
938 #ifndef WORDS_BIGENDIAN
939 		{
940 			/* Convert TO host byte order */
941 			int	j;
942 			for (j = 0; j < 8; j++) {
943 				REVERSE64(context->state[j],context->state[j]);
944 				*d++ = context->state[j];
945 			}
946 		}
947 #else
948 		MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
949 #endif
950 	}
951 
952 	/* Zero out state data */
953 	MEMSET_BZERO(context, sizeof(context));
954 }
955 
solv_SHA512_End(SHA512_CTX * context,char buffer[])956 char *solv_SHA512_End(SHA512_CTX* context, char buffer[]) {
957 	sha2_byte	digest[SHA512_DIGEST_LENGTH], *d = digest;
958 	int		i;
959 
960 	/* Sanity check: */
961 	/* assert(context != (SHA512_CTX*)0); */
962 
963 	if (buffer != (char*)0) {
964 		solv_SHA512_Final(digest, context);
965 
966 		for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
967 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
968 			*buffer++ = sha2_hex_digits[*d & 0x0f];
969 			d++;
970 		}
971 		*buffer = (char)0;
972 	} else {
973 		MEMSET_BZERO(context, sizeof(context));
974 	}
975 	MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
976 	return buffer;
977 }
978 
solv_SHA512_Data(const sha2_byte * data,size_t len,char digest[SHA512_DIGEST_STRING_LENGTH])979 char* solv_SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
980 	SHA512_CTX	context;
981 
982 	solv_SHA512_Init(&context);
983 	solv_SHA512_Update(&context, data, len);
984 	return solv_SHA512_End(&context, digest);
985 }
986 
987 
988 /*** SHA-384: *********************************************************/
solv_SHA384_Init(SHA384_CTX * context)989 void solv_SHA384_Init(SHA384_CTX* context) {
990 	if (context == (SHA384_CTX*)0) {
991 		return;
992 	}
993 	MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
994 	MEMSET_BZERO((char *)context->buffer, SHA384_BLOCK_LENGTH);
995 	context->bitcount[0] = context->bitcount[1] = 0;
996 }
997 
solv_SHA384_Update(SHA384_CTX * context,const sha2_byte * data,size_t len)998 void solv_SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
999 	solv_SHA512_Update((SHA512_CTX*)context, data, len);
1000 }
1001 
solv_SHA384_Final(sha2_byte digest[],SHA384_CTX * context)1002 void solv_SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
1003 	sha2_word64	*d = (sha2_word64*)digest;
1004 
1005 	/* Sanity check: */
1006 	/* assert(context != (SHA384_CTX*)0); */
1007 
1008 	/* If no digest buffer is passed, we don't bother doing this: */
1009 	if (digest != (sha2_byte*)0) {
1010 		SHA512_Last((SHA512_CTX*)context);
1011 
1012 		/* Save the hash data for output: */
1013 #ifndef WORDS_BIGENDIAN
1014 		{
1015 			/* Convert TO host byte order */
1016 			int	j;
1017 			for (j = 0; j < 6; j++) {
1018 				REVERSE64(context->state[j],context->state[j]);
1019 				*d++ = context->state[j];
1020 			}
1021 		}
1022 #else
1023 		MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
1024 #endif
1025 	}
1026 
1027 	/* Zero out state data */
1028 	MEMSET_BZERO(context, sizeof(context));
1029 }
1030 
solv_SHA384_End(SHA384_CTX * context,char buffer[])1031 char *solv_SHA384_End(SHA384_CTX* context, char buffer[]) {
1032 	sha2_byte	digest[SHA384_DIGEST_LENGTH], *d = digest;
1033 	int		i;
1034 
1035 	/* Sanity check: */
1036 	/* assert(context != (SHA384_CTX*)0); */
1037 
1038 	if (buffer != (char*)0) {
1039 		solv_SHA384_Final(digest, context);
1040 
1041 		for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
1042 			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
1043 			*buffer++ = sha2_hex_digits[*d & 0x0f];
1044 			d++;
1045 		}
1046 		*buffer = (char)0;
1047 	} else {
1048 		MEMSET_BZERO(context, sizeof(context));
1049 	}
1050 	MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
1051 	return buffer;
1052 }
1053 
solv_SHA384_Data(const sha2_byte * data,size_t len,char digest[SHA384_DIGEST_STRING_LENGTH])1054 char* solv_SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
1055 	SHA384_CTX	context;
1056 
1057 	solv_SHA384_Init(&context);
1058 	solv_SHA384_Update(&context, data, len);
1059 	return solv_SHA384_End(&context, digest);
1060 }
1061