Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/crypto/blake2 Import small BLAKE2s implementation.



details:   https://anonhg.NetBSD.org/src/rev/95fcf9b8d3bb
branches:  trunk
changeset: 937497:95fcf9b8d3bb
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Thu Aug 20 21:21:05 2020 +0000

description:
Import small BLAKE2s implementation.

diffstat:

 sys/crypto/blake2/blake2s.c     |  350 ++++++++++++++++++++++++++++++++++++++++
 sys/crypto/blake2/blake2s.h     |   56 ++++++
 sys/crypto/blake2/files.blake2s |    5 +
 3 files changed, 411 insertions(+), 0 deletions(-)

diffs (truncated from 423 to 300 lines):

diff -r 4d4edc7277cd -r 95fcf9b8d3bb sys/crypto/blake2/blake2s.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/crypto/blake2/blake2s.c       Thu Aug 20 21:21:05 2020 +0000
@@ -0,0 +1,350 @@
+/*     $NetBSD: blake2s.c,v 1.1 2020/08/20 21:21:05 riastradh Exp $    */
+
+/*-
+ * Copyright (c) 2015 Taylor R. Campbell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef _KERNEL
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: blake2s.c,v 1.1 2020/08/20 21:21:05 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/module.h>
+
+#include <lib/libkern/libkern.h>
+
+#else
+
+#define        _POSIX_C_SOURCE 200809L
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#endif
+
+#include "blake2s.h"
+
+#include <sys/endian.h>
+
+static inline uint32_t
+rotr32(uint32_t x, unsigned c)
+{
+
+       return ((x >> c) | (x << (32 - c)));
+}
+
+#define        BLAKE2S_G(VA, VB, VC, VD, X, Y) do                                    \
+{                                                                            \
+       (VA) = (VA) + (VB) + (X);                                             \
+       (VD) = rotr32((VD) ^ (VA), 16);                                       \
+       (VC) = (VC) + (VD);                                                   \
+       (VB) = rotr32((VB) ^ (VC), 12);                                       \
+       (VA) = (VA) + (VB) + (Y);                                             \
+       (VD) = rotr32((VD) ^ (VA), 8);                                        \
+       (VC) = (VC) + (VD);                                                   \
+       (VB) = rotr32((VB) ^ (VC), 7);                                        \
+} while (0)
+
+static const uint32_t blake2s_iv[8] = {
+       0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU,
+       0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U,
+};
+
+static const uint8_t blake2s_sigma[10][16] = {
+       {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
+       { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 },
+       { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 },
+       {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 },
+       {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 },
+       {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 },
+       { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 },
+       { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 },
+       {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 },
+       { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13,  0 },
+};
+
+static void
+blake2s_compress(uint32_t h[8], uint64_t c, uint32_t last,
+    const uint8_t in[64])
+{
+       uint32_t v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15;
+       uint32_t m[16];
+       unsigned i;
+
+       /* Load the variables: first 8 from state, next 8 from IV.  */
+       v0 = h[0];
+       v1 = h[1];
+       v2 = h[2];
+       v3 = h[3];
+       v4 = h[4];
+       v5 = h[5];
+       v6 = h[6];
+       v7 = h[7];
+       v8 = blake2s_iv[0];
+       v9 = blake2s_iv[1];
+       v10 = blake2s_iv[2];
+       v11 = blake2s_iv[3];
+       v12 = blake2s_iv[4];
+       v13 = blake2s_iv[5];
+       v14 = blake2s_iv[6];
+       v15 = blake2s_iv[7];
+
+       /* Incorporate the block counter and whether this is last.  */
+       v12 ^= c & 0xffffffffU;
+       v13 ^= c >> 32;
+       v14 ^= last;
+
+       /* Load the message block.  */
+       for (i = 0; i < 16; i++)
+               m[i] = le32dec(in + 4*i);
+
+       /* Transform the variables.  */
+       for (i = 0; i < 10; i++) {
+               const uint8_t *sigma = blake2s_sigma[i];
+
+               BLAKE2S_G(v0, v4,  v8, v12, m[sigma[ 0]], m[sigma[ 1]]);
+               BLAKE2S_G(v1, v5,  v9, v13, m[sigma[ 2]], m[sigma[ 3]]);
+               BLAKE2S_G(v2, v6, v10, v14, m[sigma[ 4]], m[sigma[ 5]]);
+               BLAKE2S_G(v3, v7, v11, v15, m[sigma[ 6]], m[sigma[ 7]]);
+               BLAKE2S_G(v0, v5, v10, v15, m[sigma[ 8]], m[sigma[ 9]]);
+               BLAKE2S_G(v1, v6, v11, v12, m[sigma[10]], m[sigma[11]]);
+               BLAKE2S_G(v2, v7,  v8, v13, m[sigma[12]], m[sigma[13]]);
+               BLAKE2S_G(v3, v4,  v9, v14, m[sigma[14]], m[sigma[15]]);
+       }
+
+       /* Update the state.  */
+       h[0] ^= v0 ^ v8;
+       h[1] ^= v1 ^ v9;
+       h[2] ^= v2 ^ v10;
+       h[3] ^= v3 ^ v11;
+       h[4] ^= v4 ^ v12;
+       h[5] ^= v5 ^ v13;
+       h[6] ^= v6 ^ v14;
+       h[7] ^= v7 ^ v15;
+
+       (void)explicit_memset(m, 0, sizeof m);
+}
+
+void
+blake2s_init(struct blake2s *B, size_t dlen, const void *key, size_t keylen)
+{
+       uint32_t param0;
+       unsigned i;
+
+       assert(0 < dlen);
+       assert(dlen <= 32);
+       assert(keylen <= 32);
+
+       /* Record the digest length.  */
+       B->dlen = dlen;
+
+       /* Initialize the buffer.  */
+       B->nb = 0;
+
+       /* Initialize the state.  */
+       B->c = 0;
+       for (i = 0; i < 8; i++)
+               B->h[i] = blake2s_iv[i];
+
+       /*
+        * Set the parameters.  We support only variable digest and key
+        * lengths: no tree hashing, no salt, no personalization.
+        */
+       param0 = 0;
+       param0 |= (uint32_t)dlen << 0;
+       param0 |= (uint32_t)keylen << 8;
+       param0 |= (uint32_t)1 << 16; /* tree fanout = 1 */
+       param0 |= (uint32_t)1 << 24; /* tree depth = 1 */
+       B->h[0] ^= param0;
+
+       /* If there's a key, compress it as the first message block.  */
+       if (keylen) {
+               static const uint8_t zero_block[64];
+
+               blake2s_update(B, key, keylen);
+               blake2s_update(B, zero_block, 64 - keylen);
+       }
+}
+
+void
+blake2s_update(struct blake2s *B, const void *buf, size_t len)
+{
+       const uint8_t *p = buf;
+       size_t n = len;
+
+       /* Check the current state of the buffer.  */
+       if (n <= 64u - B->nb) {
+               /* Can at most exactly fill the buffer.  */
+               (void)memcpy(&B->b[B->nb], p, n);
+               B->nb += n;
+               return;
+       } else if (0 < B->nb) {
+               /* Can fill the buffer and go on.  */
+               (void)memcpy(&B->b[B->nb], p, 64 - B->nb);
+               B->c += 64;
+               blake2s_compress(B->h, B->c, 0, B->b);
+               p += 64 - B->nb;
+               n -= 64 - B->nb;
+       }
+
+       /* At a block boundary.  Compress straight from the input.  */
+       while (64 < n) {
+               B->c += 64;
+               blake2s_compress(B->h, B->c, 0, p);
+               p += 64;
+               n -= 64;
+       }
+
+       /*
+        * Put whatever's left in the buffer.  We may fill the buffer,
+        * but we can't compress in that case until we know whether we
+        * are compressing the last block or not.
+        */
+       (void)memcpy(B->b, p, n);
+       B->nb = n;
+}
+
+void
+blake2s_final(struct blake2s *B, void *digest)
+{
+       uint8_t *d = digest;
+       unsigned dlen = B->dlen;
+       unsigned i;
+
+       /* Pad with zeros, and do the last compression.  */
+       B->c += B->nb;
+       for (i = B->nb; i < 64; i++)
+               B->b[i] = 0;
+       blake2s_compress(B->h, B->c, ~(uint32_t)0, B->b);
+
+       /* Reveal the first dlen/4 words of the state.  */
+       for (i = 0; i < dlen/4; i++)
+               le32enc(d + 4*i, B->h[i]);
+       d += 4*i;
+       dlen -= 4*i;
+
+       /* If the caller wants a partial word, reveal that too.  */
+       if (dlen) {
+               uint32_t hi = B->h[i];
+
+               do {
+                       *d++ = hi;
+                       hi >>= 8;
+               } while (--dlen);
+       }
+
+       /* Erase the state.  */
+       (void)explicit_memset(B, 0, sizeof B);
+}
+
+void
+blake2s(void *digest, size_t dlen, const void *key, size_t keylen,
+    const void *in, size_t inlen)
+{
+       struct blake2s ctx;
+
+       blake2s_init(&ctx, dlen, key, keylen);
+       blake2s_update(&ctx, in, inlen);
+       blake2s_final(&ctx, digest);
+}
+
+static void
+blake2_selftest_prng(void *buf, size_t len, uint32_t seed)
+{
+       uint8_t *p = buf;
+       size_t n = len;
+       uint32_t t, a, b;
+
+       a = 0xdead4bad * seed;
+       b = 1;
+
+       while (n--) {
+               t = a + b;
+               *p++ = t >> 24;
+               a = b;
+               b = t;
+       }
+}
+
+int
+blake2s_selftest(void)
+{
+       const uint8_t d0[32] = {



Home | Main Index | Thread Index | Old Index