From e0c38ba95a293b747acee203ead11933a44a4c59 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 1 Jun 2022 12:40:24 +0000 Subject: Add blake2s implementation to stdcrypto Signed-off-by: Laurent Bercot --- src/include/skalibs/blake2s.h | 32 ++++++++++++++ src/include/skalibs/stdcrypto.h | 1 + src/libstdcrypto/blake2s-internal.h | 13 ++++++ src/libstdcrypto/blake2s_final.c | 16 +++++++ src/libstdcrypto/blake2s_init.c | 9 ++++ src/libstdcrypto/blake2s_transform.c | 82 ++++++++++++++++++++++++++++++++++++ src/libstdcrypto/blake2s_update.c | 27 ++++++++++++ 7 files changed, 180 insertions(+) create mode 100644 src/include/skalibs/blake2s.h create mode 100644 src/libstdcrypto/blake2s-internal.h create mode 100644 src/libstdcrypto/blake2s_final.c create mode 100644 src/libstdcrypto/blake2s_init.c create mode 100644 src/libstdcrypto/blake2s_transform.c create mode 100644 src/libstdcrypto/blake2s_update.c (limited to 'src') diff --git a/src/include/skalibs/blake2s.h b/src/include/skalibs/blake2s.h new file mode 100644 index 0000000..1da386d --- /dev/null +++ b/src/include/skalibs/blake2s.h @@ -0,0 +1,32 @@ + /* ISC license. */ + +#ifndef SKALIBS_BLAKE2S_H +#define SKALIBS_BLAKE2S_H + +#include +#include + +typedef struct blake2s_ctx_s blake2s_ctx, *blake2s_ctx_ref ; +struct blake2s_ctx_s +{ + size_t buflen ; + size_t outlen ; + uint32_t h[8] ; + uint32_t t[2] ; + uint32_t f[2] ; + char buf[64] ; +} ; + +#define BLAKE2S_INIT(outlen) { \ + .buflen = 0, \ + .outlen = outlen, \ + .h = { 0x6A09E667UL ^ (0x01010000 | outlen), 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }, \ + .t = { 0, 0 }, \ + .f = { 0, 0 }, \ + .buf = { 0 } } + +extern void blake2s_init (blake2s_ctx *, size_t) ; /* outlen <= 32 */ +extern void blake2s_update (blake2s_ctx *, char const *, size_t) ; +extern void blake2s_final (blake2s_ctx *, char *) ; /* outlen chars */ + +#endif diff --git a/src/include/skalibs/stdcrypto.h b/src/include/skalibs/stdcrypto.h index c04407b..a74c451 100644 --- a/src/include/skalibs/stdcrypto.h +++ b/src/include/skalibs/stdcrypto.h @@ -6,5 +6,6 @@ #include #include #include +#include #endif diff --git a/src/libstdcrypto/blake2s-internal.h b/src/libstdcrypto/blake2s-internal.h new file mode 100644 index 0000000..baeac09 --- /dev/null +++ b/src/libstdcrypto/blake2s-internal.h @@ -0,0 +1,13 @@ + /* ISC license. */ + +#ifndef SKALIBS_BLAKE2S_INTERNAL_H +#define SKALIBS_BLAKE2S_INTERNAL_H + +#include +#include + +#include + +extern void blake2s_transform (blake2s_ctx *, char const *, size_t, uint32_t) ; + +#endif diff --git a/src/libstdcrypto/blake2s_final.c b/src/libstdcrypto/blake2s_final.c new file mode 100644 index 0000000..207d60b --- /dev/null +++ b/src/libstdcrypto/blake2s_final.c @@ -0,0 +1,16 @@ + /* ISC license. */ + +#include + +#include +#include +#include "blake2s-internal.h" + +void blake2s_final (blake2s_ctx *ctx, char *out) +{ + ctx->f[0] = -1 ; + memset(ctx->buf + ctx->buflen, 0, 64 - ctx->buflen) ; + blake2s_transform(ctx, ctx->buf, 1, ctx->buflen) ; + uint32_littlen(ctx->h, 8) ; + memcpy(out, ctx->h, ctx->outlen) ; +} diff --git a/src/libstdcrypto/blake2s_init.c b/src/libstdcrypto/blake2s_init.c new file mode 100644 index 0000000..7460747 --- /dev/null +++ b/src/libstdcrypto/blake2s_init.c @@ -0,0 +1,9 @@ + /* ISC license. */ + +#include + +void blake2s_init (blake2s_ctx *ctx, size_t outlen) +{ + blake2s_ctx c = BLAKE2S_INIT(outlen) ; + *ctx = c ; +} diff --git a/src/libstdcrypto/blake2s_transform.c b/src/libstdcrypto/blake2s_transform.c new file mode 100644 index 0000000..4de3b86 --- /dev/null +++ b/src/libstdcrypto/blake2s_transform.c @@ -0,0 +1,82 @@ + /* ISC license. */ + +#include + +#include +#include +#include "blake2s-internal.h" + +static uint32_t const blake2s_iv[8] = +{ + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL +}; + +static uint8_t const 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 uint32_t ror32 (uint32_t word, unsigned int shift) +{ + return (word >> (shift & 31)) | (word << ((-shift) & 31)) ; +} + +#define G(r, i, a, b, c, d) do \ +{ \ + a += b + m[blake2s_sigma[r][i<<1]] ; \ + d = ror32(d ^ a, 16) ; \ + c += d ; \ + b = ror32(b ^ c, 12) ; \ + a += b + m[blake2s_sigma[r][(i<<1)+1]] ; \ + d = ror32(d ^ a, 8) ; \ + c += d ; \ + b = ror32(b ^ c, 7) ; \ +} while (0) + +void blake2s_transform (blake2s_ctx *ctx, char const *block, size_t n, uint32_t inc) +{ + uint32_t m[16] ; + uint32_t v[16] ; + + while (n--) + { + unsigned int i = 0 ; + ctx->t[0] += inc ; + ctx->t[1] += (ctx->t[0] < inc) ; + for (; i < 16 ; i++) uint32_unpack(block + (i << 2), m + i) ; + for (i = 0 ; i < 8 ; i++) v[i] = ctx->h[i] ; + v[8] = blake2s_iv[0] ; + v[9] = blake2s_iv[1] ; + v[10] = blake2s_iv[2] ; + v[11] = blake2s_iv[3] ; + v[12] = blake2s_iv[4] ^ ctx->t[0] ; + v[13] = blake2s_iv[5] ^ ctx->t[1] ; + v[14] = blake2s_iv[6] ^ ctx->f[0] ; + v[15] = blake2s_iv[7] ^ ctx->f[1] ; + + for (i = 0 ; i < 10 ; i++) + { + G(i, 0, v[0], v[ 4], v[ 8], v[12]) ; + G(i, 1, v[1], v[ 5], v[ 9], v[13]) ; + G(i, 2, v[2], v[ 6], v[10], v[14]) ; + G(i, 3, v[3], v[ 7], v[11], v[15]) ; + G(i, 4, v[0], v[ 5], v[10], v[15]) ; + G(i, 5, v[1], v[ 6], v[11], v[12]) ; + G(i, 6, v[2], v[ 7], v[ 8], v[13]) ; + G(i, 7, v[3], v[ 4], v[ 9], v[14]) ; + } + + for (i = 0 ; i < 8 ; i++) ctx->h[i] ^= v[i] ^ v[i+8] ; + block += 64 ; + } +} diff --git a/src/libstdcrypto/blake2s_update.c b/src/libstdcrypto/blake2s_update.c new file mode 100644 index 0000000..bf0639b --- /dev/null +++ b/src/libstdcrypto/blake2s_update.c @@ -0,0 +1,27 @@ + /* ISC license. */ + +#include + +#include +#include "blake2s-internal.h" + +void blake2s_update (blake2s_ctx *ctx, char const *s, size_t len) +{ + size_t w = 64 - ctx->buflen ; + if (!len) return ; + if (len > w) + { + memcpy(ctx->buf + ctx->buflen, s, w) ; + blake2s_transform(ctx, ctx->buf, 1, 64) ; + ctx->buflen = 0 ; + s += w ; len -= w ; + } + if (len > 64) + { + size_t n = (len+63)/64 - 1 ; + blake2s_transform(ctx, s, n, 64) ; + n <<= 6 ; s += n ; len -= n ; + } + memcpy(ctx->buf + ctx->buflen, s, len) ; + ctx->buflen += len ; +} -- cgit v1.2.3