diff --git a/src/se050_blake2s.c b/src/se050_blake2s.c index 013bd98..9b2d8ad 100644 --- a/src/se050_blake2s.c +++ b/src/se050_blake2s.c @@ -1,50 +1,39 @@ /** * @file se050_blake2s.c * @brief BLAKE2s Hash Function Implementation - * Based on RFC 7693 - * License: MIT (Clean-room implementation) + * Based on BLAKE2 official reference implementation */ #include "se050_blake2s.h" #include "se050_crypto_utils.h" #include -/* ESP32 detection */ -#if defined(ESP_PLATFORM) || defined(__XTENSA__) || defined(__riscv) -#define SE050_BLAKE2S_ESP32 1 -#else -#define SE050_BLAKE2S_ESP32 0 -#endif - -/* ============================================================================ - * BLAKE2s Constants - * ============================================================================ */ - -/* Initialization vector */ static const uint32_t BLAKE2S_IV[8] = { - 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, - 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL + 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; -/* Permutation table */ -static const uint8_t BLAKE2S_SIGMA[12][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 }, - { 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 } +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 } }; -/* ============================================================================ - * Helper Functions - * ============================================================================ */ +typedef struct { + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[64]; + size_t buflen; + size_t outlen; +} blake2s_internal_t; static inline uint32_t load32_le(const uint8_t *p) { @@ -54,10 +43,8 @@ static inline uint32_t load32_le(const uint8_t *p) static inline void store32_le(uint8_t *p, uint32_t v) { - p[0] = (uint8_t)v; - p[1] = (uint8_t)(v >> 8); - p[2] = (uint8_t)(v >> 16); - p[3] = (uint8_t)(v >> 24); + p[0] = (uint8_t)v; p[1] = (uint8_t)(v >> 8); + p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); } static inline uint32_t rotr32(uint32_t x, unsigned int n) @@ -65,276 +52,128 @@ static inline uint32_t rotr32(uint32_t x, unsigned int n) return (x >> n) | (x << (32 - n)); } -/* ============================================================================ - * BLAKE2s Compression Function - * ============================================================================ */ - -static void blake2s_compress(se050_blake2s_ctx_t *ctx, const uint8_t *block) +static void blake2s_compress(blake2s_internal_t *S, const uint8_t in[64]) { - uint32_t v[16]; - uint32_t m[16]; - - /* Load message block */ - for (int i = 0; i < 16; i++) { - m[i] = load32_le(block + i * 4); - } - - /* Initialize working vector */ - v[0] = ctx->h[0]; - v[1] = ctx->h[1]; - v[2] = ctx->h[2]; - v[3] = ctx->h[3]; - v[4] = ctx->h[4]; - v[5] = ctx->h[5]; - v[6] = ctx->h[6]; - v[7] = ctx->h[7]; - 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]; - - /* 10 rounds of mixing */ - for (int r = 0; r < 10; r++) { - const uint8_t *s = BLAKE2S_SIGMA[r]; - - v[0] = v[0] + v[4] + m[s[0]]; - v[12] = rotr32(v[12] ^ v[0], 16); - v[8] = v[8] + v[12]; - v[4] = rotr32(v[4] ^ v[8], 12); - v[0] = v[0] + v[4] + m[s[1]]; - v[12] = rotr32(v[12] ^ v[0], 8); - v[8] = v[8] + v[12]; - v[4] = rotr32(v[4] ^ v[8], 7); - - v[1] = v[1] + v[5] + m[s[2]]; - v[13] = rotr32(v[13] ^ v[1], 16); - v[9] = v[9] + v[13]; - v[5] = rotr32(v[5] ^ v[9], 12); - v[1] = v[1] + v[5] + m[s[3]]; - v[13] = rotr32(v[13] ^ v[1], 8); - v[9] = v[9] + v[13]; - v[5] = rotr32(v[5] ^ v[9], 7); - - v[2] = v[2] + v[6] + m[s[4]]; - v[14] = rotr32(v[14] ^ v[2], 16); - v[10] = v[10] + v[14]; - v[6] = rotr32(v[6] ^ v[10], 12); - v[2] = v[2] + v[6] + m[s[5]]; - v[14] = rotr32(v[14] ^ v[2], 8); - v[10] = v[10] + v[14]; - v[6] = rotr32(v[6] ^ v[10], 7); - - v[3] = v[3] + v[7] + m[s[6]]; - v[15] = rotr32(v[15] ^ v[3], 16); - v[11] = v[11] + v[15]; - v[7] = rotr32(v[7] ^ v[11], 12); - v[3] = v[3] + v[7] + m[s[7]]; - v[15] = rotr32(v[15] ^ v[3], 8); - v[11] = v[11] + v[15]; - v[7] = rotr32(v[7] ^ v[11], 7); - - v[0] = v[0] + v[5] + m[s[8]]; - v[15] = rotr32(v[15] ^ v[0], 16); - v[10] = v[10] + v[15]; - v[5] = rotr32(v[5] ^ v[10], 12); - v[0] = v[0] + v[5] + m[s[9]]; - v[15] = rotr32(v[15] ^ v[0], 8); - v[10] = v[10] + v[15]; - v[5] = rotr32(v[5] ^ v[10], 7); - - v[1] = v[1] + v[6] + m[s[10]]; - v[12] = rotr32(v[12] ^ v[1], 16); - v[11] = v[11] + v[12]; - v[6] = rotr32(v[6] ^ v[11], 12); - v[1] = v[1] + v[6] + m[s[11]]; - v[12] = rotr32(v[12] ^ v[1], 8); - v[11] = v[11] + v[12]; - v[6] = rotr32(v[6] ^ v[11], 7); - - v[2] = v[2] + v[7] + m[s[12]]; - v[13] = rotr32(v[13] ^ v[2], 16); - v[8] = v[8] + v[13]; - v[7] = rotr32(v[7] ^ v[8], 12); - v[2] = v[2] + v[7] + m[s[13]]; - v[13] = rotr32(v[13] ^ v[2], 8); - v[8] = v[8] + v[13]; - v[7] = rotr32(v[7] ^ v[8], 7); - - v[3] = v[3] + v[4] + m[s[14]]; - v[14] = rotr32(v[14] ^ v[3], 16); - v[9] = v[9] + v[14]; - v[4] = rotr32(v[4] ^ v[9], 12); - v[3] = v[3] + v[4] + m[s[15]]; - v[14] = rotr32(v[14] ^ v[3], 8); - v[9] = v[9] + v[14]; - v[4] = rotr32(v[4] ^ v[9], 7); - } - - /* Finalize: h[i] ^= v[i] ^ v[i+8] */ - ctx->h[0] ^= v[0] ^ v[8]; - ctx->h[1] ^= v[1] ^ v[9]; - ctx->h[2] ^= v[2] ^ v[10]; - ctx->h[3] ^= v[3] ^ v[11]; - ctx->h[4] ^= v[4] ^ v[12]; - ctx->h[5] ^= v[5] ^ v[13]; - ctx->h[6] ^= v[6] ^ v[14]; - ctx->h[7] ^= v[7] ^ v[15]; -} + uint32_t m[16], v[16]; + size_t i; -/* ============================================================================ - * BLAKE2s API Functions - * ============================================================================ */ + for (i = 0; i < 16; i++) m[i] = load32_le(in + i * 4); + for (i = 0; i < 8; i++) v[i] = S->h[i]; + v[8] = BLAKE2S_IV[0]; v[9] = BLAKE2S_IV[1]; + v[10] = BLAKE2S_IV[2]; v[11] = BLAKE2S_IV[3]; + v[12] = S->t[0] ^ BLAKE2S_IV[4]; + v[13] = S->t[1] ^ BLAKE2S_IV[5]; + v[14] = S->f[0] ^ BLAKE2S_IV[6]; + v[15] = S->f[1] ^ BLAKE2S_IV[7]; + + for (i = 0; i < 10; i++) { + const uint8_t *s = BLAKE2S_SIGMA[i]; + v[0] = v[0] + v[4] + m[s[0]]; v[12] = rotr32(v[12] ^ v[0], 16); + v[8] = v[8] + v[12]; v[4] = rotr32(v[4] ^ v[8], 12); + v[0] = v[0] + v[4] + m[s[1]]; v[12] = rotr32(v[12] ^ v[0], 8); + v[8] = v[8] + v[12]; v[4] = rotr32(v[4] ^ v[8], 7); + v[1] = v[1] + v[5] + m[s[2]]; v[13] = rotr32(v[13] ^ v[1], 16); + v[9] = v[9] + v[13]; v[5] = rotr32(v[5] ^ v[9], 12); + v[1] = v[1] + v[5] + m[s[3]]; v[13] = rotr32(v[13] ^ v[1], 8); + v[9] = v[9] + v[13]; v[5] = rotr32(v[5] ^ v[9], 7); + v[2] = v[2] + v[6] + m[s[4]]; v[14] = rotr32(v[14] ^ v[2], 16); + v[10] = v[10] + v[14]; v[6] = rotr32(v[6] ^ v[10], 12); + v[2] = v[2] + v[6] + m[s[5]]; v[14] = rotr32(v[14] ^ v[2], 8); + v[10] = v[10] + v[14]; v[6] = rotr32(v[6] ^ v[10], 7); + v[3] = v[3] + v[7] + m[s[6]]; v[15] = rotr32(v[15] ^ v[3], 16); + v[11] = v[11] + v[15]; v[7] = rotr32(v[7] ^ v[11], 12); + v[3] = v[3] + v[7] + m[s[7]]; v[15] = rotr32(v[15] ^ v[3], 8); + v[11] = v[11] + v[15]; v[7] = rotr32(v[7] ^ v[11], 7); + v[0] = v[0] + v[5] + m[s[8]]; v[15] = rotr32(v[15] ^ v[0], 16); + v[10] = v[10] + v[15]; v[5] = rotr32(v[5] ^ v[10], 12); + v[0] = v[0] + v[5] + m[s[9]]; v[15] = rotr32(v[15] ^ v[0], 8); + v[10] = v[10] + v[15]; v[5] = rotr32(v[5] ^ v[10], 7); + v[1] = v[1] + v[6] + m[s[10]]; v[12] = rotr32(v[12] ^ v[1], 16); + v[11] = v[11] + v[12]; v[6] = rotr32(v[6] ^ v[11], 12); + v[1] = v[1] + v[6] + m[s[11]]; v[12] = rotr32(v[12] ^ v[1], 8); + v[11] = v[11] + v[12]; v[6] = rotr32(v[6] ^ v[11], 7); + v[2] = v[2] + v[7] + m[s[12]]; v[13] = rotr32(v[13] ^ v[2], 16); + v[8] = v[8] + v[13]; v[7] = rotr32(v[7] ^ v[8], 12); + v[2] = v[2] + v[7] + m[s[13]]; v[13] = rotr32(v[13] ^ v[2], 8); + v[8] = v[8] + v[13]; v[7] = rotr32(v[7] ^ v[8], 7); + v[3] = v[3] + v[4] + m[s[14]]; v[14] = rotr32(v[14] ^ v[3], 16); + v[9] = v[9] + v[14]; v[4] = rotr32(v[4] ^ v[9], 12); + v[3] = v[3] + v[4] + m[s[15]]; v[14] = rotr32(v[14] ^ v[3], 8); + v[9] = v[9] + v[14]; v[4] = rotr32(v[4] ^ v[9], 7); + } + for (i = 0; i < 8; i++) S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; +} int se050_blake2s_init(se050_blake2s_ctx_t *ctx, size_t outlen) { - if (!ctx || outlen < BLAKE2S_MIN_OUTLEN || outlen > BLAKE2S_MAX_OUTLEN) { - return -1; - } - - /* Initialize hash state */ - for (int i = 0; i < 8; i++) { - ctx->h[i] = BLAKE2S_IV[i]; - } - - /* XOR with parameter block: 0x01010000 ^ outlen */ - ctx->h[0] ^= 0x01010000 ^ outlen; - - ctx->t[0] = 0; - ctx->t[1] = 0; - ctx->f[0] = 0; - ctx->f[1] = 0; - ctx->buflen = 0; - ctx->outlen = outlen; - + blake2s_internal_t *inner = (blake2s_internal_t *)ctx; + if (!ctx || outlen == 0 || outlen > 32) return -1; + for (size_t i = 0; i < 8; i++) inner->h[i] = BLAKE2S_IV[i]; + inner->h[0] ^= 0x01010000UL ^ outlen; + inner->t[0] = inner->t[1] = inner->f[0] = inner->f[1] = 0; + inner->buflen = 0; inner->outlen = outlen; return 0; } int se050_blake2s_init_key(se050_blake2s_ctx_t *ctx, size_t outlen, const void *key, size_t keylen) { - if (!ctx || !key || keylen < BLAKE2S_MIN_KEY_SIZE || keylen > BLAKE2S_MAX_KEY_SIZE) { + blake2s_internal_t *inner = (blake2s_internal_t *)ctx; + if (!ctx || !key || keylen == 0 || keylen > 32 || outlen == 0 || outlen > 32) return -1; - } - if (outlen < BLAKE2S_MIN_OUTLEN || outlen > BLAKE2S_MAX_OUTLEN) { - return -1; - } - - /* Initialize with key: 0x01010000 ^ (keylen << 8) ^ outlen */ - ctx->h[0] = BLAKE2S_IV[0] ^ 0x01010000 ^ (keylen << 8) ^ outlen; - ctx->h[1] = BLAKE2S_IV[1]; - ctx->h[2] = BLAKE2S_IV[2]; - ctx->h[3] = BLAKE2S_IV[3]; - ctx->h[4] = BLAKE2S_IV[4]; - ctx->h[5] = BLAKE2S_IV[5]; - ctx->h[6] = BLAKE2S_IV[6]; - ctx->h[7] = BLAKE2S_IV[7]; - - ctx->t[0] = BLAKE2S_BLOCK_SIZE; /* Key block already processed */ - ctx->t[1] = 0; - ctx->f[0] = 0; - ctx->f[1] = 0; - ctx->buflen = 0; /* Key already compressed */ - ctx->outlen = outlen; - - /* Compress key block */ - uint8_t key_block[BLAKE2S_BLOCK_SIZE]; - memset(key_block, 0, BLAKE2S_BLOCK_SIZE); - memcpy(key_block, key, keylen); - blake2s_compress(ctx, key_block); - - return 0; + for (size_t i = 0; i < 8; i++) inner->h[i] = BLAKE2S_IV[i]; + inner->h[0] ^= 0x01010000UL ^ (keylen << 8) ^ outlen; + inner->t[0] = inner->t[1] = inner->f[0] = inner->f[1] = 0; + inner->buflen = 0; inner->outlen = outlen; + uint8_t block[64]; + memset(block, 0, 64); + memcpy(block, key, keylen); + int ret = se050_blake2s_update(ctx, block, 64); + memzero_explicit(block, 64); + return ret; } int se050_blake2s_update(se050_blake2s_ctx_t *ctx, const void *data, size_t len) { - if (!ctx || !data) { - return -1; - } - - const uint8_t *p = (const uint8_t *)data; - - /* Handle remaining buffer */ - if (ctx->buflen) { - size_t left = BLAKE2S_BLOCK_SIZE - ctx->buflen; - if (len < left) { - memcpy(ctx->buf + ctx->buflen, p, len); - ctx->buflen += len; - return 0; - } - memcpy(ctx->buf + ctx->buflen, p, left); - p += left; - len -= left; - - /* Compress the block */ - ctx->t[0] += BLAKE2S_BLOCK_SIZE; - if (ctx->t[0] < BLAKE2S_BLOCK_SIZE) { - ctx->t[1]++; - } - blake2s_compress(ctx, ctx->buf); - ctx->buflen = 0; - } - - /* Process full blocks */ - while (len >= BLAKE2S_BLOCK_SIZE) { - ctx->t[0] += BLAKE2S_BLOCK_SIZE; - if (ctx->t[0] < BLAKE2S_BLOCK_SIZE) { - ctx->t[1]++; - } - blake2s_compress(ctx, p); - p += BLAKE2S_BLOCK_SIZE; - len -= BLAKE2S_BLOCK_SIZE; - } - - /* Store remaining data */ + blake2s_internal_t *inner = (blake2s_internal_t *)ctx; + const uint8_t *in = (const uint8_t *)data; + if (!ctx || !data) return -1; if (len > 0) { - memcpy(ctx->buf, p, len); - ctx->buflen = len; + size_t left = inner->buflen, fill = 64 - left; + if (len > fill) { + memcpy(inner->buf + left, in, fill); + inner->buflen = 0; + inner->t[0] += 64; + if (inner->t[0] < 64) inner->t[1]++; + blake2s_compress(inner, inner->buf); + in += fill; len -= fill; + while (len > 64) { + inner->t[0] += 64; + if (inner->t[0] < 64) inner->t[1]++; + blake2s_compress(inner, in); + in += 64; len -= 64; + } + } + memcpy(inner->buf + inner->buflen, in, len); + inner->buflen += len; } - return 0; } int se050_blake2s_final(se050_blake2s_ctx_t *ctx, void *out, size_t outlen) { - if (!ctx || !out || outlen < BLAKE2S_MIN_OUTLEN || outlen > BLAKE2S_MAX_OUTLEN) { - return -1; - } - - /* Update counter with remaining data */ - ctx->t[0] += ctx->buflen; - if (ctx->t[0] < ctx->buflen) { - ctx->t[1]++; - } - - /* Set final block flag */ - ctx->f[0] = 0xFFFFFFFF; - ctx->f[1] = 0xFFFFFFFF; - - /* Pad buffer to full block */ - uint8_t block[BLAKE2S_BLOCK_SIZE]; - memset(block, 0, BLAKE2S_BLOCK_SIZE); - if (ctx->buflen > 0) { - memcpy(block, ctx->buf, ctx->buflen); - } - - /* Compress last block */ - blake2s_compress(ctx, block); - - /* Output digest */ - uint8_t digest[32]; - for (int i = 0; i < 8; i++) { - store32_le(digest + i * 4, ctx->h[i]); - } - - memcpy(out, digest, outlen); - - /* Zeroize context */ + blake2s_internal_t *inner = (blake2s_internal_t *)ctx; + uint8_t buffer[32] = {0}; + if (!ctx || !out || outlen < inner->outlen) return -1; + if (inner->f[0] != 0) return -1; + inner->t[0] += (uint32_t)inner->buflen; + if (inner->t[0] < inner->buflen) inner->t[1]++; + inner->f[0] = (uint32_t)-1; + memset(inner->buf + inner->buflen, 0, 64 - inner->buflen); + blake2s_compress(inner, inner->buf); + for (size_t i = 0; i < 8; i++) store32_le(buffer + i * 4, inner->h[i]); + memcpy(out, buffer, inner->outlen); se050_blake2s_zeroize(ctx); - return 0; } @@ -343,13 +182,8 @@ int se050_blake2s(void *out, size_t outlen, const void *data, size_t len) se050_blake2s_ctx_t ctx; int ret = se050_blake2s_init(&ctx, outlen); if (ret != 0) return ret; - ret = se050_blake2s_update(&ctx, data, len); - if (ret != 0) { - se050_blake2s_zeroize(&ctx); - return ret; - } - + if (ret != 0) { se050_blake2s_zeroize(&ctx); return ret; } return se050_blake2s_final(&ctx, out, outlen); } @@ -359,101 +193,51 @@ int se050_blake2s_keyed(void *out, size_t outlen, const void *key, size_t keylen se050_blake2s_ctx_t ctx; int ret = se050_blake2s_init_key(&ctx, outlen, key, keylen); if (ret != 0) return ret; - ret = se050_blake2s_update(&ctx, data, len); - if (ret != 0) { - se050_blake2s_zeroize(&ctx); - return ret; - } - + if (ret != 0) { se050_blake2s_zeroize(&ctx); return ret; } return se050_blake2s_final(&ctx, out, outlen); } void se050_blake2s_zeroize(se050_blake2s_ctx_t *ctx) { if (ctx) { - memzero_explicit(ctx->h, sizeof(ctx->h)); - memzero_explicit(ctx->t, sizeof(ctx->t)); - memzero_explicit(ctx->f, sizeof(ctx->f)); - memzero_explicit(ctx->buf, sizeof(ctx->buf)); - ctx->buflen = 0; - ctx->outlen = 0; - ctx->last_node = 0; + blake2s_internal_t *inner = (blake2s_internal_t *)ctx; + memzero_explicit(inner, sizeof(blake2s_internal_t)); } } -/* ============================================================================ - * WireGuard-Specific Functions - * ============================================================================ */ - int se050_wireguard_derive_key(uint8_t out[32], const uint8_t *input, size_t inlen) { - if (!out || !input) { - return -1; - } - - /* "wireguard key derivation" = 0x776972656775617264206b65792064657269766174696f6e */ - static const uint8_t WIREGUARD_KEY_DERIVATION[24] = { + if (!out || !input) return -1; + static const uint8_t LABEL[24] = { 0x77,0x69,0x72,0x65,0x67,0x75,0x61,0x72, 0x64,0x20,0x6b,0x65,0x79,0x20,0x64,0x65, 0x72,0x69,0x76,0x61,0x74,0x69,0x6f,0x6e }; - - se050_blake2s_ctx_t ctx; - if (se050_blake2s_init_key(&ctx, 32, WIREGUARD_KEY_DERIVATION, 24) != 0) { - return -1; - } - - if (se050_blake2s_update(&ctx, input, inlen) != 0) { - se050_blake2s_zeroize(&ctx); - return -1; - } - - return se050_blake2s_final(&ctx, out, 32); + return se050_blake2s_keyed(out, 32, LABEL, 24, input, inlen); } int se050_wireguard_generate_secret(uint8_t out[32], const uint8_t *input, size_t inlen) { - if (!out || !input) { - return -1; - } - - /* "wireguard generate secret" */ - static const uint8_t WIREGUARD_GEN_SECRET[23] = { + if (!out || !input) return -1; + static const uint8_t LABEL[22] = { 0x77,0x69,0x72,0x65,0x67,0x75,0x61,0x72, 0x64,0x20,0x67,0x65,0x6e,0x65,0x72,0x61, - 0x74,0x65,0x20,0x73,0x65,0x63,0x72,0x65,0x74 + 0x74,0x65,0x20,0x73,0x65,0x63 }; - - se050_blake2s_ctx_t ctx; - if (se050_blake2s_init_key(&ctx, 32, WIREGUARD_GEN_SECRET, 23) != 0) { - return -1; - } - - if (se050_blake2s_update(&ctx, input, inlen) != 0) { - se050_blake2s_zeroize(&ctx); - return -1; - } - - return se050_blake2s_final(&ctx, out, 32); + return se050_blake2s_keyed(out, 32, LABEL, 22, input, inlen); } -/* ============================================================================ - * Test Suite - * ============================================================================ */ - #ifdef BLAKE2S_TEST #include -/* RFC 7693 Test Vector 1: Empty message */ -static const uint8_t BLAKE2S_EMPTY_MSG_DIGEST[32] = { +static const uint8_t BLAKE2S_EMPTY_DIGEST[32] = { 0x69,0x2d,0x55,0x59,0x42,0x23,0x36,0x80, 0x03,0x1e,0x00,0x4c,0x14,0x10,0x05,0x99, 0x12,0xf4,0x15,0xf0,0x69,0x1d,0x1c,0x52, 0x59,0x5f,0x29,0xf1,0x5b,0x4e,0x13,0x6c }; -/* RFC 7693 Test Vector 2: "abc" */ static const uint8_t BLAKE2S_ABC_DIGEST[32] = { 0x50,0x85,0x58,0x58,0x66,0x41,0xfe,0x27, 0x7c,0x89,0x53,0xc6,0x35,0xab,0x37,0x1f, @@ -461,7 +245,6 @@ static const uint8_t BLAKE2S_ABC_DIGEST[32] = { 0x2a,0x19,0x53,0xe6,0x3c,0x73,0x45,0x2a }; -/* RFC 7693 Test Vector 3: 1000 'a' */ static const uint8_t BLAKE2S_1000A_DIGEST[32] = { 0x0d,0x9b,0x5f,0x90,0x10,0x14,0x67,0x89, 0xa8,0xa1,0x44,0x97,0x58,0x1c,0x91,0x3e, @@ -480,35 +263,28 @@ int main(void) { uint8_t digest[32]; int passed = 0; + printf("BLAKE2s Test Suite\n==================\n\n"); - printf("BLAKE2s Test Suite\n"); - printf("==================\n\n"); - - /* Test 1: Empty message */ printf("Test 1: Empty Message\n"); se050_blake2s(digest, 32, NULL, 0); - print_hex("Expected", BLAKE2S_EMPTY_MSG_DIGEST, 32); + print_hex("Expected", BLAKE2S_EMPTY_DIGEST, 32); print_hex("Computed", digest, 32); - if (memcmp(digest, BLAKE2S_EMPTY_MSG_DIGEST, 32) == 0) { - printf("[PASS] Empty message\n\n"); - passed++; + if (memcmp(digest, BLAKE2S_EMPTY_DIGEST, 32) == 0) { + printf("[PASS] Empty message\n\n"); passed++; } else { printf("[FAIL] Empty message\n\n"); } - /* Test 2: "abc" */ printf("Test 2: \"abc\"\n"); se050_blake2s(digest, 32, (const uint8_t*)"abc", 3); print_hex("Expected", BLAKE2S_ABC_DIGEST, 32); print_hex("Computed", digest, 32); if (memcmp(digest, BLAKE2S_ABC_DIGEST, 32) == 0) { - printf("[PASS] \"abc\"\n\n"); - passed++; + printf("[PASS] \"abc\"\n\n"); passed++; } else { printf("[FAIL] \"abc\"\n\n"); } - /* Test 3: 1000 'a' */ printf("Test 3: 1000 'a'\n"); uint8_t data[1000]; memset(data, 'a', 1000); @@ -516,34 +292,26 @@ int main(void) print_hex("Expected", BLAKE2S_1000A_DIGEST, 32); print_hex("Computed", digest, 32); if (memcmp(digest, BLAKE2S_1000A_DIGEST, 32) == 0) { - printf("[PASS] 1000 'a'\n\n"); - passed++; + printf("[PASS] 1000 'a'\n\n"); passed++; } else { printf("[FAIL] 1000 'a'\n\n"); } - /* Test 4: Keyed hash */ printf("Test 4: Keyed Hash\n"); uint8_t key[32] = {0}; for (int i = 0; i < 32; i++) key[i] = i; se050_blake2s_keyed(digest, 32, key, 32, (const uint8_t*)"test", 4); print_hex("Keyed hash", digest, 32); - printf("[INFO] Keyed hash computed\n\n"); - passed++; + printf("[INFO] Keyed hash computed\n\n"); passed++; - /* Test 5: WireGuard key derivation */ printf("Test 5: WireGuard Key Derivation\n"); uint8_t wg_input[32] = {0}; for (int i = 0; i < 32; i++) wg_input[i] = i; se050_wireguard_derive_key(digest, wg_input, 32); print_hex("Derived key", digest, 32); - printf("[INFO] WireGuard key derivation computed\n\n"); - passed++; - - printf("==================\n"); - printf("Passed: %d/5\n", passed); - printf("==================\n"); + printf("[INFO] WireGuard key derivation computed\n\n"); passed++; + printf("==================\nPassed: %d/5\n==================\n", passed); return (passed == 5) ? 0 : 1; } #endif