tls

tls.git
git clone git://git.lenczewski.org/tls.git
Log | Files | Refs

sha.c (14659B)


      1 #ifndef _GNU_SOURCE
      2 # define _GNU_SOURCE 1
      3 #endif
      4 
      5 #include "sha.h"
      6 
      7 #include <assert.h>
      8 #include <endian.h>
      9 #include <string.h>
     10 
     11 // sha operations
     12 // ===========================================================================
     13 
     14 #define SHA_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
     15 #define SHA_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
     16 #define SHA_SHR(x, n) ((x) >> (n))
     17 
     18 // sha functions
     19 // ===========================================================================
     20 
     21 #define SHA_Ch(x, y, z)		(((x) & (y)) ^ ((~(x)) & (z)))
     22 #define SHA_Maj(x, y, z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
     23 
     24 #define SHA256_S0(x)		(SHA_ROTR32((x),  2) ^ SHA_ROTR32((x), 13) ^ SHA_ROTR32((x), 22))
     25 #define SHA256_S1(x)		(SHA_ROTR32((x),  6) ^ SHA_ROTR32((x), 11) ^ SHA_ROTR32((x), 25))
     26 #define SHA256_s0(x)		(SHA_ROTR32((x),  7) ^ SHA_ROTR32((x), 18) ^ SHA_SHR((x), 3))
     27 #define SHA256_s1(x)		(SHA_ROTR32((x), 17) ^ SHA_ROTR32((x), 19) ^ SHA_SHR((x), 10))
     28 
     29 #define SHA512_S0(x)		(SHA_ROTR64((x), 28) ^ SHA_ROTR64((x), 34) ^ SHA_ROTR64((x), 39))
     30 #define SHA512_S1(x)		(SHA_ROTR64((x), 14) ^ SHA_ROTR64((x), 18) ^ SHA_ROTR64((x), 41))
     31 #define SHA512_s0(x)		(SHA_ROTR64((x),  1) ^ SHA_ROTR64((x),  8) ^ SHA_SHR((x), 7))
     32 #define SHA512_s1(x)		(SHA_ROTR64((x), 19) ^ SHA_ROTR64((x), 61) ^ SHA_SHR((x), 6))
     33 
     34 // sha constants
     35 // ===========================================================================
     36 
     37 static sha256_word_t const _sha256_constants[] = {
     38 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
     39 	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
     40 	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
     41 	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
     42 	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
     43 	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
     44 	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
     45 	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
     46 	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
     47 	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
     48 	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
     49 	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
     50 	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
     51 	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
     52 	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
     53 	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
     54 };
     55 
     56 static sha512_word_t const _sha512_constants[] = {
     57 	0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
     58 	0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
     59 	0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
     60 	0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
     61 	0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
     62 	0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
     63 	0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
     64 	0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
     65 	0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
     66 	0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
     67 	0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
     68 	0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
     69 	0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
     70 	0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
     71 	0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
     72 	0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
     73 	0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
     74 	0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
     75 	0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
     76 	0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
     77 };
     78 
     79 // sha256
     80 // ===========================================================================
     81 
     82 void
     83 sha256_init(struct sha256_ctx *ctx)
     84 {
     85 	memset(ctx, 0, sizeof *ctx);
     86 
     87 	ctx->digest[0] = 0x6a09e667;
     88 	ctx->digest[1] = 0xbb67ae85;
     89 	ctx->digest[2] = 0x3c6ef372;
     90 	ctx->digest[3] = 0xa54ff53a;
     91 	ctx->digest[4] = 0x510e527f;
     92 	ctx->digest[5] = 0x9b05688c;
     93 	ctx->digest[6] = 0x1f83d9ab;
     94 	ctx->digest[7] = 0x5be0cd19;
     95 }
     96 
     97 static void
     98 _sha256_block(struct sha256_ctx *ctx)
     99 {
    100 	sha256_word_t a, b, c, d, e, f, g, h, t, t1, t2;
    101 
    102 	// load block words
    103 	for (t = 0; t < SHA256_BLOCK_WORDS; t++) {
    104 		ctx->schedule[t] = htobe32(ctx->schedule[t]);
    105 	}
    106 
    107 	// expand out block words into full schedule
    108 	for (; t < SHA256_SCHEDULE_WORDS; t++) {
    109 		ctx->schedule[t] = SHA256_s1(ctx->schedule[t - 2])
    110 				 + ctx->schedule[t - 7]
    111 				 + SHA256_s0(ctx->schedule[t - 15])
    112 				 + ctx->schedule[t - 16];
    113 	}
    114 
    115 	// initialise working variables
    116 	a = ctx->digest[0];
    117 	b = ctx->digest[1];
    118 	c = ctx->digest[2];
    119 	d = ctx->digest[3];
    120 	e = ctx->digest[4];
    121 	f = ctx->digest[5];
    122 	g = ctx->digest[6];
    123 	h = ctx->digest[7];
    124 
    125 	// perform rounds of sha256 compression (as many as words in the schedule)
    126 	for (t = 0; t < SHA256_SCHEDULE_WORDS; t++) {
    127 		t1 = h
    128 		   + SHA256_S1(e)
    129 		   + SHA_Ch(e, f, g)
    130 		   + _sha256_constants[t]
    131 		   + ctx->schedule[t];
    132 
    133 		t2 = SHA256_S0(a)
    134 		   + SHA_Maj(a, b, c);
    135 
    136 		h = g;
    137 		g = f;
    138 		f = e;
    139 		e = d + t1;
    140 		d = c;
    141 		c = b;
    142 		b = a;
    143 		a = t1 + t2;
    144 	}
    145 
    146 	// save intermediate hash
    147 	ctx->digest[0] += a;
    148 	ctx->digest[1] += b;
    149 	ctx->digest[2] += c;
    150 	ctx->digest[3] += d;
    151 	ctx->digest[4] += e;
    152 	ctx->digest[5] += f;
    153 	ctx->digest[6] += g;
    154 	ctx->digest[7] += h;
    155 }
    156 
    157 void
    158 sha256_push(struct sha256_ctx *ctx, void const *buf, size_t len)
    159 {
    160 	unsigned char const *ptr = buf, *end = ptr + len;
    161 	unsigned char *block = ((unsigned char *) ctx->schedule);
    162 
    163 	while (ptr < end) {
    164 		size_t idx = ctx->ctr++ & SHA256_BLOCK_MASK;
    165 		block[idx] = *ptr++;
    166 
    167 		if (idx == SHA256_BLOCK_MASK) { // filled a block; hash it
    168 			_sha256_block(ctx);
    169 		}
    170 	}
    171 }
    172 
    173 static void
    174 _sha256_digest_bswap(struct sha256_ctx *ctx, void *digest, size_t words)
    175 {
    176 	sha256_word_t *out = digest;
    177 	for (size_t i = 0; i < words; i++)
    178 		out[i] = htobe32(ctx->digest[i]);
    179 }
    180 
    181 void
    182 sha256_dgst(struct sha256_ctx *ctx, unsigned char digest[static SHA256_DIGEST_SIZE])
    183 {
    184 	unsigned char *block = ((unsigned char *) ctx->schedule);
    185 	unsigned char *cur = block + (ctx->ctr & SHA256_BLOCK_MASK);
    186 	unsigned char *end = block + SHA256_BLOCK_SIZE;
    187 	unsigned char *len = end - (64 / CHAR_BIT);
    188 
    189 	// TODO: handle 64-bit overflow here
    190 	assert(ctx->ctr < (UINT64_MAX / CHAR_BIT));
    191 	uint64_t bits = ctx->ctr * CHAR_BIT;
    192 
    193 	// append the 1 bit
    194 	*cur++ = 0x80;
    195 
    196 	// can we fit our message bit length? if not, add an extra padding block
    197 	if (len < cur) {
    198 		memset(cur, 0, end - cur);
    199 		_sha256_block(ctx);
    200 
    201 		cur = block;
    202 	}
    203 
    204 	// pad out final block
    205 	memset(cur, 0, len - cur);
    206 
    207 	// write out message bit length
    208 	((uint64_t *) len)[0] = htobe64(bits);
    209 
    210 	// hash final block
    211 	_sha256_block(ctx);
    212 
    213 	// write out internally host-endian hash as big-endian hash
    214 	_sha256_digest_bswap(ctx, digest, SHA256_DIGEST_WORDS);
    215 }
    216 
    217 void
    218 sha256(void const *buf, size_t len, unsigned char digest[static SHA256_DIGEST_SIZE])
    219 {
    220 	struct sha256_ctx ctx;
    221 	sha256_init(&ctx);
    222 	sha256_push(&ctx, buf, len);
    223 	sha256_dgst(&ctx, digest);
    224 }
    225 
    226 // sha224
    227 // ===========================================================================
    228 
    229 void
    230 sha224_init(struct sha256_ctx *ctx)
    231 {
    232 	memset(ctx, 0, sizeof *ctx);
    233 
    234 	ctx->digest[0] = 0xc1059ed8;
    235 	ctx->digest[1] = 0x367cd507;
    236 	ctx->digest[2] = 0x3070dd17;
    237 	ctx->digest[3] = 0xf70e5939;
    238 	ctx->digest[4] = 0xffc00b31;
    239 	ctx->digest[5] = 0x68581511;
    240 	ctx->digest[6] = 0x64f98fa7;
    241 	ctx->digest[7] = 0xbefa4fa4;
    242 }
    243 
    244 void
    245 sha224_push(struct sha256_ctx *ctx, void const *buf, size_t len)
    246 {
    247 	sha256_push(ctx, buf, len);
    248 }
    249 
    250 void
    251 sha224_dgst(struct sha256_ctx *ctx, unsigned char digest[static SHA224_DIGEST_SIZE])
    252 {
    253 	unsigned char tmp[SHA256_DIGEST_SIZE];
    254 	sha256_dgst(ctx, tmp);
    255 
    256 	memcpy(digest, tmp, SHA224_DIGEST_SIZE);
    257 }
    258 
    259 void
    260 sha224(void const *buf, size_t len, unsigned char digest[static SHA224_DIGEST_SIZE])
    261 {
    262 	struct sha256_ctx ctx;
    263 	sha224_init(&ctx);
    264 	sha224_push(&ctx, buf, len);
    265 	sha224_dgst(&ctx, digest);
    266 }
    267 
    268 // sha512
    269 // ===========================================================================
    270 
    271 void
    272 sha512_init(struct sha512_ctx *ctx)
    273 {
    274 	memset(ctx, 0, sizeof *ctx);
    275 
    276 	ctx->digest[0] = 0x6a09e667f3bcc908;
    277 	ctx->digest[1] = 0xbb67ae8584caa73b;
    278 	ctx->digest[2] = 0x3c6ef372fe94f82b;
    279 	ctx->digest[3] = 0xa54ff53a5f1d36f1;
    280 	ctx->digest[4] = 0x510e527fade682d1;
    281 	ctx->digest[5] = 0x9b05688c2b3e6c1f;
    282 	ctx->digest[6] = 0x1f83d9abfb41bd6b;
    283 	ctx->digest[7] = 0x5be0cd19137e2179;
    284 }
    285 
    286 static void
    287 _sha512_block(struct sha512_ctx *ctx)
    288 {
    289 	sha512_word_t a, b, c, d, e, f, g, h, t, t1, t2;
    290 
    291 	// load block words
    292 	for (t = 0; t < SHA512_BLOCK_WORDS; t++) {
    293 		ctx->schedule[t] = htobe64(ctx->schedule[t]);
    294 	}
    295 
    296 	// expand out block words into full schedule
    297 	for (; t < SHA512_SCHEDULE_WORDS; t++) {
    298 		ctx->schedule[t] = SHA512_s1(ctx->schedule[t - 2])
    299 				 + ctx->schedule[t - 7]
    300 				 + SHA512_s0(ctx->schedule[t - 15])
    301 				 + ctx->schedule[t - 16];
    302 	}
    303 
    304 	// initialise working variables
    305 	a = ctx->digest[0];
    306 	b = ctx->digest[1];
    307 	c = ctx->digest[2];
    308 	d = ctx->digest[3];
    309 	e = ctx->digest[4];
    310 	f = ctx->digest[5];
    311 	g = ctx->digest[6];
    312 	h = ctx->digest[7];
    313 
    314 	// perform rounds of sha512 compression (as many as words in our schedule)
    315 	for (t = 0; t < SHA512_SCHEDULE_WORDS; t++) {
    316 		t1 = h
    317 		   + SHA512_S1(e)
    318 		   + SHA_Ch(e, f, g)
    319 		   + _sha512_constants[t]
    320 		   + ctx->schedule[t];
    321 
    322 		t2 = SHA512_S0(a)
    323 		   + SHA_Maj(a, b, c);
    324 
    325 		h = g;
    326 		g = f;
    327 		f = e;
    328 		e = d + t1;
    329 		d = c;
    330 		c = b;
    331 		b = a;
    332 		a = t1 + t2;
    333 	}
    334 
    335 	// save intermediate hash
    336 	ctx->digest[0] += a;
    337 	ctx->digest[1] += b;
    338 	ctx->digest[2] += c;
    339 	ctx->digest[3] += d;
    340 	ctx->digest[4] += e;
    341 	ctx->digest[5] += f;
    342 	ctx->digest[6] += g;
    343 	ctx->digest[7] += h;
    344 }
    345 
    346 void
    347 sha512_push(struct sha512_ctx *ctx, void const *buf, size_t len)
    348 {
    349 	unsigned char const *ptr = buf, *end = ptr + len;
    350 	unsigned char *block = ((unsigned char *) ctx->schedule);
    351 
    352 	while (ptr < end) {
    353 		size_t idx = ctx->ctr++ & SHA512_BLOCK_MASK;
    354 		block[idx] = *ptr++;
    355 
    356 		if (idx == SHA512_BLOCK_MASK) { // filled a block; hash it
    357 			_sha512_block(ctx);
    358 		}
    359 	}
    360 }
    361 
    362 static void
    363 _sha512_digest_bswap(struct sha512_ctx *ctx, void *digest, size_t words)
    364 {
    365 	sha512_word_t *out = digest;
    366 	for (size_t i = 0; i < words; i++)
    367 		out[i] = htobe64(ctx->digest[i]);
    368 }
    369 
    370 void
    371 sha512_dgst(struct sha512_ctx *ctx, unsigned char digest[static SHA512_DIGEST_SIZE])
    372 {
    373 	unsigned char *block = ((unsigned char *) ctx->schedule);
    374 	unsigned char *cur = block + (ctx->ctr & SHA512_BLOCK_MASK);
    375 	unsigned char *end = block + SHA512_BLOCK_SIZE;
    376 	unsigned char *len = end - (128 / CHAR_BIT);
    377 
    378 	// TODO: handle 128-bit overflow here
    379 	assert(ctx->ctr < (UINT64_MAX / CHAR_BIT));
    380 	__uint128_t bits = ctx->ctr * CHAR_BIT;
    381 
    382 	// append the 1 bit
    383 	*cur++ = 0x80;
    384 
    385 	// can we fit our message bit length? if not, add an extra padding block
    386 	if (len < cur) {
    387 		memset(cur, 0, end - cur);
    388 		_sha512_block(ctx);
    389 
    390 		cur = block;
    391 	}
    392 
    393 	// pad out final block
    394 	memset(cur, 0, len - cur);
    395 
    396 	// write out message bit length
    397 	__uint128_t hi = (__uint128_t) htobe64(bits & UINT64_MAX);
    398 	__uint128_t lo = (__uint128_t) htobe64(bits >> 64);
    399 	((__uint128_t *) len)[0] = (hi << 64) | (lo);
    400 
    401 	// hash final block
    402 	_sha512_block(ctx);
    403 
    404 	// write out internally host-endian hash as big-endian hash
    405 	_sha512_digest_bswap(ctx, digest, SHA512_DIGEST_WORDS);
    406 }
    407 
    408 void
    409 sha512(void const *buf, size_t len, unsigned char digest[static SHA512_DIGEST_SIZE])
    410 {
    411 	struct sha512_ctx ctx;
    412 	sha512_init(&ctx);
    413 	sha512_push(&ctx, buf, len);
    414 	sha512_dgst(&ctx, digest);
    415 }
    416 
    417 // sha384
    418 // ===========================================================================
    419 
    420 void
    421 sha384_init(struct sha512_ctx *ctx)
    422 {
    423 	memset(ctx, 0, sizeof *ctx);
    424 
    425 	ctx->digest[0] = 0xcbbb9d5dc1059ed8;
    426 	ctx->digest[1] = 0x629a292a367cd507;
    427 	ctx->digest[2] = 0x9159015a3070dd17;
    428 	ctx->digest[3] = 0x152fecd8f70e5939;
    429 	ctx->digest[4] = 0x67332667ffc00b31;
    430 	ctx->digest[5] = 0x8eb44a8768581511;
    431 	ctx->digest[6] = 0xdb0c2e0d64f98fa7;
    432 	ctx->digest[7] = 0x47b5481dbefa4fa4;
    433 }
    434 
    435 void
    436 sha384_push(struct sha512_ctx *ctx, void const *buf, size_t len)
    437 {
    438 	sha512_push(ctx, buf, len);
    439 }
    440 
    441 void
    442 sha384_dgst(struct sha512_ctx *ctx, unsigned char digest[static SHA384_DIGEST_SIZE])
    443 {
    444 	unsigned char tmp[SHA512_DIGEST_SIZE];
    445 	sha512_dgst(ctx, tmp);
    446 
    447 	memcpy(digest, tmp, SHA384_DIGEST_SIZE);
    448 }
    449 
    450 void
    451 sha384(void const *buf, size_t len, unsigned char digest[static SHA384_DIGEST_SIZE])
    452 {
    453 	struct sha512_ctx ctx;
    454 	sha384_init(&ctx);
    455 	sha384_push(&ctx, buf, len);
    456 	sha384_dgst(&ctx, digest);
    457 }
    458 
    459 // sha512/224
    460 // ===========================================================================
    461 
    462 void
    463 sha512_224_init(struct sha512_ctx *ctx)
    464 {
    465 	memset(ctx, 0, sizeof *ctx);
    466 
    467 	ctx->digest[0] = 0x8c3d37c819544da2;
    468 	ctx->digest[1] = 0x73e1996689dcd4d6;
    469 	ctx->digest[2] = 0x1dfab7ae32ff9c82;
    470 	ctx->digest[3] = 0x679dd514582f9fcf;
    471 	ctx->digest[4] = 0x0f6d2b697bd44da8;
    472 	ctx->digest[5] = 0x77e36f7304c48942;
    473 	ctx->digest[6] = 0x3f9d85a86a1d36c8;
    474 	ctx->digest[7] = 0x1112e6ad91d692a1;
    475 }
    476 
    477 void
    478 sha512_224_push(struct sha512_ctx *ctx, void const *buf, size_t len)
    479 {
    480 	sha512_push(ctx, buf, len);
    481 }
    482 
    483 void
    484 sha512_224_dgst(struct sha512_ctx *ctx, unsigned char digest[static SHA512_224_DIGEST_SIZE])
    485 {
    486 	unsigned char tmp[SHA512_DIGEST_SIZE];
    487 	sha512_dgst(ctx, tmp);
    488 
    489 	memcpy(digest, tmp, SHA512_224_DIGEST_SIZE);
    490 }
    491 
    492 void
    493 sha512_224(void const *buf, size_t len, unsigned char digest[static SHA512_224_DIGEST_SIZE])
    494 {
    495 	struct sha512_ctx ctx;
    496 	sha512_224_init(&ctx);
    497 	sha512_224_push(&ctx, buf, len);
    498 	sha512_224_dgst(&ctx, digest);
    499 }
    500 
    501 // sha512/256
    502 // ===========================================================================
    503 
    504 void
    505 sha512_256_init(struct sha512_ctx *ctx)
    506 {
    507 	memset(ctx, 0, sizeof *ctx);
    508 
    509 	ctx->digest[0] = 0x22312194fc2bf72c;
    510 	ctx->digest[1] = 0x9f555fa3c84c64c2;
    511 	ctx->digest[2] = 0x2393b86b6f53b151;
    512 	ctx->digest[3] = 0x963877195940eabd;
    513 	ctx->digest[4] = 0x96283ee2A88effe3;
    514 	ctx->digest[5] = 0xbe5e1e2553863992;
    515 	ctx->digest[6] = 0x2b0199fc2c85b8aa;
    516 	ctx->digest[7] = 0x0eb72ddc81c52ca2;
    517 }
    518 
    519 void
    520 sha512_256_push(struct sha512_ctx *ctx, void const *buf, size_t len)
    521 {
    522 	sha512_push(ctx, buf, len);
    523 }
    524 
    525 void
    526 sha512_256_dgst(struct sha512_ctx *ctx, unsigned char digest[static SHA512_256_DIGEST_SIZE])
    527 {
    528 	unsigned char tmp[SHA512_DIGEST_SIZE];
    529 	sha512_dgst(ctx, tmp);
    530 
    531 	memcpy(digest, tmp, SHA512_256_DIGEST_SIZE);
    532 }
    533 
    534 void
    535 sha512_256(void const *buf, size_t len, unsigned char digest[static SHA512_256_DIGEST_SIZE])
    536 {
    537 	struct sha512_ctx ctx;
    538 	sha512_256_init(&ctx);
    539 	sha512_256_push(&ctx, buf, len);
    540 	sha512_256_dgst(&ctx, digest);
    541 }