Home | History | Annotate | Line # | Download | only in blake2
      1  1.2  jmcneill /*	$NetBSD: blake2s.c,v 1.2 2021/10/17 14:45:45 jmcneill Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*-
      4  1.1  riastrad  * Copyright (c) 2015 Taylor R. Campbell
      5  1.1  riastrad  * All rights reserved.
      6  1.1  riastrad  *
      7  1.1  riastrad  * Redistribution and use in source and binary forms, with or without
      8  1.1  riastrad  * modification, are permitted provided that the following conditions
      9  1.1  riastrad  * are met:
     10  1.1  riastrad  * 1. Redistributions of source code must retain the above copyright
     11  1.1  riastrad  *    notice, this list of conditions and the following disclaimer.
     12  1.1  riastrad  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  riastrad  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  riastrad  *    documentation and/or other materials provided with the distribution.
     15  1.1  riastrad  *
     16  1.1  riastrad  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  1.1  riastrad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  1.1  riastrad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  1.1  riastrad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  1.1  riastrad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  1.1  riastrad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  1.1  riastrad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  1.1  riastrad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  1.1  riastrad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  1.1  riastrad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  1.1  riastrad  * SUCH DAMAGE.
     27  1.1  riastrad  */
     28  1.1  riastrad 
     29  1.1  riastrad #ifdef _KERNEL
     30  1.1  riastrad 
     31  1.1  riastrad #include <sys/cdefs.h>
     32  1.2  jmcneill __KERNEL_RCSID(0, "$NetBSD: blake2s.c,v 1.2 2021/10/17 14:45:45 jmcneill Exp $");
     33  1.1  riastrad 
     34  1.1  riastrad #include <sys/types.h>
     35  1.1  riastrad #include <sys/module.h>
     36  1.1  riastrad 
     37  1.1  riastrad #include <lib/libkern/libkern.h>
     38  1.1  riastrad 
     39  1.1  riastrad #else
     40  1.1  riastrad 
     41  1.1  riastrad #define	_POSIX_C_SOURCE	200809L
     42  1.1  riastrad 
     43  1.1  riastrad #include <assert.h>
     44  1.1  riastrad #include <stdint.h>
     45  1.1  riastrad #include <string.h>
     46  1.1  riastrad 
     47  1.1  riastrad #endif
     48  1.1  riastrad 
     49  1.1  riastrad #include "blake2s.h"
     50  1.1  riastrad 
     51  1.1  riastrad #include <sys/endian.h>
     52  1.1  riastrad 
     53  1.1  riastrad static inline uint32_t
     54  1.1  riastrad rotr32(uint32_t x, unsigned c)
     55  1.1  riastrad {
     56  1.1  riastrad 
     57  1.1  riastrad 	return ((x >> c) | (x << (32 - c)));
     58  1.1  riastrad }
     59  1.1  riastrad 
     60  1.1  riastrad #define	BLAKE2S_G(VA, VB, VC, VD, X, Y)	do				      \
     61  1.1  riastrad {									      \
     62  1.1  riastrad 	(VA) = (VA) + (VB) + (X);					      \
     63  1.1  riastrad 	(VD) = rotr32((VD) ^ (VA), 16);					      \
     64  1.1  riastrad 	(VC) = (VC) + (VD);						      \
     65  1.1  riastrad 	(VB) = rotr32((VB) ^ (VC), 12);					      \
     66  1.1  riastrad 	(VA) = (VA) + (VB) + (Y);					      \
     67  1.1  riastrad 	(VD) = rotr32((VD) ^ (VA), 8);					      \
     68  1.1  riastrad 	(VC) = (VC) + (VD);						      \
     69  1.1  riastrad 	(VB) = rotr32((VB) ^ (VC), 7);					      \
     70  1.1  riastrad } while (0)
     71  1.1  riastrad 
     72  1.1  riastrad static const uint32_t blake2s_iv[8] = {
     73  1.1  riastrad 	0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU,
     74  1.1  riastrad 	0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U,
     75  1.1  riastrad };
     76  1.1  riastrad 
     77  1.1  riastrad static const uint8_t blake2s_sigma[10][16] = {
     78  1.1  riastrad 	{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
     79  1.1  riastrad 	{ 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 },
     80  1.1  riastrad 	{ 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 },
     81  1.1  riastrad 	{  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 },
     82  1.1  riastrad 	{  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 },
     83  1.1  riastrad 	{  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 },
     84  1.1  riastrad 	{ 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 },
     85  1.1  riastrad 	{ 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 },
     86  1.1  riastrad 	{  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 },
     87  1.1  riastrad 	{ 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13,  0 },
     88  1.1  riastrad };
     89  1.1  riastrad 
     90  1.1  riastrad static void
     91  1.1  riastrad blake2s_compress(uint32_t h[8], uint64_t c, uint32_t last,
     92  1.1  riastrad     const uint8_t in[64])
     93  1.1  riastrad {
     94  1.1  riastrad 	uint32_t v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15;
     95  1.1  riastrad 	uint32_t m[16];
     96  1.1  riastrad 	unsigned i;
     97  1.1  riastrad 
     98  1.1  riastrad 	/* Load the variables: first 8 from state, next 8 from IV.  */
     99  1.1  riastrad 	v0 = h[0];
    100  1.1  riastrad 	v1 = h[1];
    101  1.1  riastrad 	v2 = h[2];
    102  1.1  riastrad 	v3 = h[3];
    103  1.1  riastrad 	v4 = h[4];
    104  1.1  riastrad 	v5 = h[5];
    105  1.1  riastrad 	v6 = h[6];
    106  1.1  riastrad 	v7 = h[7];
    107  1.1  riastrad 	v8 = blake2s_iv[0];
    108  1.1  riastrad 	v9 = blake2s_iv[1];
    109  1.1  riastrad 	v10 = blake2s_iv[2];
    110  1.1  riastrad 	v11 = blake2s_iv[3];
    111  1.1  riastrad 	v12 = blake2s_iv[4];
    112  1.1  riastrad 	v13 = blake2s_iv[5];
    113  1.1  riastrad 	v14 = blake2s_iv[6];
    114  1.1  riastrad 	v15 = blake2s_iv[7];
    115  1.1  riastrad 
    116  1.1  riastrad 	/* Incorporate the block counter and whether this is last.  */
    117  1.1  riastrad 	v12 ^= c & 0xffffffffU;
    118  1.1  riastrad 	v13 ^= c >> 32;
    119  1.1  riastrad 	v14 ^= last;
    120  1.1  riastrad 
    121  1.1  riastrad 	/* Load the message block.  */
    122  1.1  riastrad 	for (i = 0; i < 16; i++)
    123  1.1  riastrad 		m[i] = le32dec(in + 4*i);
    124  1.1  riastrad 
    125  1.1  riastrad 	/* Transform the variables.  */
    126  1.1  riastrad 	for (i = 0; i < 10; i++) {
    127  1.1  riastrad 		const uint8_t *sigma = blake2s_sigma[i];
    128  1.1  riastrad 
    129  1.1  riastrad 		BLAKE2S_G(v0, v4,  v8, v12, m[sigma[ 0]], m[sigma[ 1]]);
    130  1.1  riastrad 		BLAKE2S_G(v1, v5,  v9, v13, m[sigma[ 2]], m[sigma[ 3]]);
    131  1.1  riastrad 		BLAKE2S_G(v2, v6, v10, v14, m[sigma[ 4]], m[sigma[ 5]]);
    132  1.1  riastrad 		BLAKE2S_G(v3, v7, v11, v15, m[sigma[ 6]], m[sigma[ 7]]);
    133  1.1  riastrad 		BLAKE2S_G(v0, v5, v10, v15, m[sigma[ 8]], m[sigma[ 9]]);
    134  1.1  riastrad 		BLAKE2S_G(v1, v6, v11, v12, m[sigma[10]], m[sigma[11]]);
    135  1.1  riastrad 		BLAKE2S_G(v2, v7,  v8, v13, m[sigma[12]], m[sigma[13]]);
    136  1.1  riastrad 		BLAKE2S_G(v3, v4,  v9, v14, m[sigma[14]], m[sigma[15]]);
    137  1.1  riastrad 	}
    138  1.1  riastrad 
    139  1.1  riastrad 	/* Update the state.  */
    140  1.1  riastrad 	h[0] ^= v0 ^ v8;
    141  1.1  riastrad 	h[1] ^= v1 ^ v9;
    142  1.1  riastrad 	h[2] ^= v2 ^ v10;
    143  1.1  riastrad 	h[3] ^= v3 ^ v11;
    144  1.1  riastrad 	h[4] ^= v4 ^ v12;
    145  1.1  riastrad 	h[5] ^= v5 ^ v13;
    146  1.1  riastrad 	h[6] ^= v6 ^ v14;
    147  1.1  riastrad 	h[7] ^= v7 ^ v15;
    148  1.1  riastrad 
    149  1.1  riastrad 	(void)explicit_memset(m, 0, sizeof m);
    150  1.1  riastrad }
    151  1.1  riastrad 
    152  1.1  riastrad void
    153  1.1  riastrad blake2s_init(struct blake2s *B, size_t dlen, const void *key, size_t keylen)
    154  1.1  riastrad {
    155  1.1  riastrad 	uint32_t param0;
    156  1.1  riastrad 	unsigned i;
    157  1.1  riastrad 
    158  1.1  riastrad 	assert(0 < dlen);
    159  1.1  riastrad 	assert(dlen <= 32);
    160  1.1  riastrad 	assert(keylen <= 32);
    161  1.1  riastrad 
    162  1.1  riastrad 	/* Record the digest length.  */
    163  1.1  riastrad 	B->dlen = dlen;
    164  1.1  riastrad 
    165  1.1  riastrad 	/* Initialize the buffer.  */
    166  1.1  riastrad 	B->nb = 0;
    167  1.1  riastrad 
    168  1.1  riastrad 	/* Initialize the state.  */
    169  1.1  riastrad 	B->c = 0;
    170  1.1  riastrad 	for (i = 0; i < 8; i++)
    171  1.1  riastrad 		B->h[i] = blake2s_iv[i];
    172  1.1  riastrad 
    173  1.1  riastrad 	/*
    174  1.1  riastrad 	 * Set the parameters.  We support only variable digest and key
    175  1.1  riastrad 	 * lengths: no tree hashing, no salt, no personalization.
    176  1.1  riastrad 	 */
    177  1.1  riastrad 	param0 = 0;
    178  1.1  riastrad 	param0 |= (uint32_t)dlen << 0;
    179  1.1  riastrad 	param0 |= (uint32_t)keylen << 8;
    180  1.1  riastrad 	param0 |= (uint32_t)1 << 16; /* tree fanout = 1 */
    181  1.1  riastrad 	param0 |= (uint32_t)1 << 24; /* tree depth = 1 */
    182  1.1  riastrad 	B->h[0] ^= param0;
    183  1.1  riastrad 
    184  1.1  riastrad 	/* If there's a key, compress it as the first message block.  */
    185  1.1  riastrad 	if (keylen) {
    186  1.1  riastrad 		static const uint8_t zero_block[64];
    187  1.1  riastrad 
    188  1.1  riastrad 		blake2s_update(B, key, keylen);
    189  1.1  riastrad 		blake2s_update(B, zero_block, 64 - keylen);
    190  1.1  riastrad 	}
    191  1.1  riastrad }
    192  1.1  riastrad 
    193  1.1  riastrad void
    194  1.1  riastrad blake2s_update(struct blake2s *B, const void *buf, size_t len)
    195  1.1  riastrad {
    196  1.1  riastrad 	const uint8_t *p = buf;
    197  1.1  riastrad 	size_t n = len;
    198  1.1  riastrad 
    199  1.1  riastrad 	/* Check the current state of the buffer.  */
    200  1.1  riastrad 	if (n <= 64u - B->nb) {
    201  1.1  riastrad 		/* Can at most exactly fill the buffer.  */
    202  1.1  riastrad 		(void)memcpy(&B->b[B->nb], p, n);
    203  1.1  riastrad 		B->nb += n;
    204  1.1  riastrad 		return;
    205  1.1  riastrad 	} else if (0 < B->nb) {
    206  1.1  riastrad 		/* Can fill the buffer and go on.  */
    207  1.1  riastrad 		(void)memcpy(&B->b[B->nb], p, 64 - B->nb);
    208  1.1  riastrad 		B->c += 64;
    209  1.1  riastrad 		blake2s_compress(B->h, B->c, 0, B->b);
    210  1.1  riastrad 		p += 64 - B->nb;
    211  1.1  riastrad 		n -= 64 - B->nb;
    212  1.1  riastrad 	}
    213  1.1  riastrad 
    214  1.1  riastrad 	/* At a block boundary.  Compress straight from the input.  */
    215  1.1  riastrad 	while (64 < n) {
    216  1.1  riastrad 		B->c += 64;
    217  1.1  riastrad 		blake2s_compress(B->h, B->c, 0, p);
    218  1.1  riastrad 		p += 64;
    219  1.1  riastrad 		n -= 64;
    220  1.1  riastrad 	}
    221  1.1  riastrad 
    222  1.1  riastrad 	/*
    223  1.1  riastrad 	 * Put whatever's left in the buffer.  We may fill the buffer,
    224  1.1  riastrad 	 * but we can't compress in that case until we know whether we
    225  1.1  riastrad 	 * are compressing the last block or not.
    226  1.1  riastrad 	 */
    227  1.1  riastrad 	(void)memcpy(B->b, p, n);
    228  1.1  riastrad 	B->nb = n;
    229  1.1  riastrad }
    230  1.1  riastrad 
    231  1.1  riastrad void
    232  1.1  riastrad blake2s_final(struct blake2s *B, void *digest)
    233  1.1  riastrad {
    234  1.1  riastrad 	uint8_t *d = digest;
    235  1.1  riastrad 	unsigned dlen = B->dlen;
    236  1.1  riastrad 	unsigned i;
    237  1.1  riastrad 
    238  1.1  riastrad 	/* Pad with zeros, and do the last compression.  */
    239  1.1  riastrad 	B->c += B->nb;
    240  1.1  riastrad 	for (i = B->nb; i < 64; i++)
    241  1.1  riastrad 		B->b[i] = 0;
    242  1.1  riastrad 	blake2s_compress(B->h, B->c, ~(uint32_t)0, B->b);
    243  1.1  riastrad 
    244  1.1  riastrad 	/* Reveal the first dlen/4 words of the state.  */
    245  1.1  riastrad 	for (i = 0; i < dlen/4; i++)
    246  1.1  riastrad 		le32enc(d + 4*i, B->h[i]);
    247  1.1  riastrad 	d += 4*i;
    248  1.1  riastrad 	dlen -= 4*i;
    249  1.1  riastrad 
    250  1.1  riastrad 	/* If the caller wants a partial word, reveal that too.  */
    251  1.1  riastrad 	if (dlen) {
    252  1.1  riastrad 		uint32_t hi = B->h[i];
    253  1.1  riastrad 
    254  1.1  riastrad 		do {
    255  1.1  riastrad 			*d++ = hi;
    256  1.1  riastrad 			hi >>= 8;
    257  1.1  riastrad 		} while (--dlen);
    258  1.1  riastrad 	}
    259  1.1  riastrad 
    260  1.1  riastrad 	/* Erase the state.  */
    261  1.1  riastrad 	(void)explicit_memset(B, 0, sizeof B);
    262  1.1  riastrad }
    263  1.1  riastrad 
    264  1.1  riastrad void
    265  1.1  riastrad blake2s(void *digest, size_t dlen, const void *key, size_t keylen,
    266  1.1  riastrad     const void *in, size_t inlen)
    267  1.1  riastrad {
    268  1.1  riastrad 	struct blake2s ctx;
    269  1.1  riastrad 
    270  1.1  riastrad 	blake2s_init(&ctx, dlen, key, keylen);
    271  1.1  riastrad 	blake2s_update(&ctx, in, inlen);
    272  1.1  riastrad 	blake2s_final(&ctx, digest);
    273  1.1  riastrad }
    274  1.1  riastrad 
    275  1.1  riastrad static void
    276  1.1  riastrad blake2_selftest_prng(void *buf, size_t len, uint32_t seed)
    277  1.1  riastrad {
    278  1.1  riastrad 	uint8_t *p = buf;
    279  1.1  riastrad 	size_t n = len;
    280  1.1  riastrad 	uint32_t t, a, b;
    281  1.1  riastrad 
    282  1.1  riastrad 	a = 0xdead4bad * seed;
    283  1.1  riastrad 	b = 1;
    284  1.1  riastrad 
    285  1.1  riastrad 	while (n--) {
    286  1.1  riastrad 		t = a + b;
    287  1.1  riastrad 		*p++ = t >> 24;
    288  1.1  riastrad 		a = b;
    289  1.1  riastrad 		b = t;
    290  1.1  riastrad 	}
    291  1.1  riastrad }
    292  1.1  riastrad 
    293  1.1  riastrad int
    294  1.1  riastrad blake2s_selftest(void)
    295  1.1  riastrad {
    296  1.1  riastrad 	const uint8_t d0[32] = {
    297  1.1  riastrad 		0x6a,0x41,0x1f,0x08,0xce,0x25,0xad,0xcd,
    298  1.1  riastrad 		0xfb,0x02,0xab,0xa6,0x41,0x45,0x1c,0xec,
    299  1.1  riastrad 		0x53,0xc5,0x98,0xb2,0x4f,0x4f,0xc7,0x87,
    300  1.1  riastrad 		0xfb,0xdc,0x88,0x79,0x7f,0x4c,0x1d,0xfe,
    301  1.1  riastrad 	};
    302  1.1  riastrad 	const unsigned dlen[4] = { 16, 20, 28, 32 };
    303  1.1  riastrad 	const unsigned mlen[6] = { 0, 3, 64, 65, 255, 1024 };
    304  1.1  riastrad 	uint8_t m[1024], d[32], k[32];
    305  1.1  riastrad 	struct blake2s ctx;
    306  1.1  riastrad 	unsigned di, mi, i;
    307  1.1  riastrad 
    308  1.1  riastrad 	blake2s_init(&ctx, 32, NULL, 0);
    309  1.1  riastrad 	for (di = 0; di < 4; di++) {
    310  1.1  riastrad 		for (mi = 0; mi < 6; mi++) {
    311  1.1  riastrad 			blake2_selftest_prng(m, mlen[mi], mlen[mi]);
    312  1.1  riastrad 			blake2s(d, dlen[di], NULL, 0, m, mlen[mi]);
    313  1.1  riastrad 			blake2s_update(&ctx, d, dlen[di]);
    314  1.1  riastrad 
    315  1.1  riastrad 			blake2_selftest_prng(k, dlen[di], dlen[di]);
    316  1.1  riastrad 			blake2s(d, dlen[di], k, dlen[di], m, mlen[mi]);
    317  1.1  riastrad 			blake2s_update(&ctx, d, dlen[di]);
    318  1.1  riastrad 		}
    319  1.1  riastrad 	}
    320  1.1  riastrad 	blake2s_final(&ctx, d);
    321  1.1  riastrad 	for (i = 0; i < 32; i++) {
    322  1.1  riastrad 		if (d[i] != d0[i])
    323  1.1  riastrad 			return -1;
    324  1.1  riastrad 	}
    325  1.1  riastrad 
    326  1.1  riastrad 	return 0;
    327  1.1  riastrad }
    328  1.1  riastrad 
    329  1.1  riastrad #ifdef _KERNEL
    330  1.1  riastrad 
    331  1.1  riastrad MODULE(MODULE_CLASS_MISC, blake2s, NULL);
    332  1.1  riastrad 
    333  1.1  riastrad static int
    334  1.1  riastrad blake2s_modcmd(modcmd_t cmd, void *opaque)
    335  1.1  riastrad {
    336  1.1  riastrad 
    337  1.1  riastrad 	switch (cmd) {
    338  1.1  riastrad 	case MODULE_CMD_INIT:
    339  1.1  riastrad 		if (blake2s_selftest())
    340  1.1  riastrad 			panic("blake2s: self-test failed");
    341  1.2  jmcneill 		aprint_debug("blake2s: self-test passed\n");
    342  1.1  riastrad 		return 0;
    343  1.1  riastrad 	case MODULE_CMD_FINI:
    344  1.1  riastrad 		return 0;
    345  1.1  riastrad 	default:
    346  1.1  riastrad 		return ENOTTY;
    347  1.1  riastrad 	}
    348  1.1  riastrad }
    349  1.1  riastrad 
    350  1.1  riastrad #endif
    351