tls

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

commit c9f625de9349f34b63cf277ed7d08c4a10bb8b73
parent 913cef345e46ea44aee5e08bb35d9d242ba98356
Author: MikoĊ‚aj Lenczewski <mikolaj@lenczewski.org>
Date:   Sun, 20 Sep 2026 23:38:45 +0100

Clean up implementations

Diffstat:
Mhkdf.c | 2+-
Mhmac.c | 2++
Mhmac.h | 4+---
Msha.c | 39+++++++++++++++++++++++++++++++++++----
Msha.h | 31+------------------------------
Mtest/test-hkdf.c | 1+
Mtest/test-hmac.c | 1+
Mtest/test-sha224.c | 2++
Mtest/test-sha256.c | 2++
Mtest/test-sha384.c | 2++
Mtest/test-sha512-224.c | 2++
Mtest/test-sha512-256.c | 2++
Mtest/test-sha512.c | 2++
Ax25519.c | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mx25519.h | 205++-----------------------------------------------------------------------------
15 files changed, 265 insertions(+), 239 deletions(-)

diff --git a/hkdf.c b/hkdf.c @@ -1,6 +1,6 @@ #include "hkdf.h" -#include <stdio.h> +#include <assert.h> size_t hkdf_digest_size(struct hmac_hash const *hash, size_t rounds) diff --git a/hmac.c b/hmac.c @@ -1,5 +1,7 @@ #include "hmac.h" +#include <assert.h> + void hmac_gen_iv_block(struct hmac_ctx *ctx, struct hmac_hash const *hash, void *restrict hash_ctx, diff --git a/hmac.h b/hmac.h @@ -3,9 +3,7 @@ #ifndef HMAC_H #define HMAC_H -#include <assert.h> -#include <stdint.h> -#include <string.h> +#include <stddef.h> #define HMAC_BLOCK_SIZE 64 #define HMAC_IPAD_BYTE 0x36 diff --git a/sha.c b/sha.c @@ -1,5 +1,36 @@ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + #include "sha.h" +#include <assert.h> +#include <endian.h> +#include <string.h> + +// sha operations +// =========================================================================== + +#define SHA_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define SHA_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#define SHA_SHR(x, n) ((x) >> (n)) + +// sha functions +// =========================================================================== + +#define SHA_Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define SHA_Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define SHA256_S0(x) (SHA_ROTR32((x), 2) ^ SHA_ROTR32((x), 13) ^ SHA_ROTR32((x), 22)) +#define SHA256_S1(x) (SHA_ROTR32((x), 6) ^ SHA_ROTR32((x), 11) ^ SHA_ROTR32((x), 25)) +#define SHA256_s0(x) (SHA_ROTR32((x), 7) ^ SHA_ROTR32((x), 18) ^ SHA_SHR((x), 3)) +#define SHA256_s1(x) (SHA_ROTR32((x), 17) ^ SHA_ROTR32((x), 19) ^ SHA_SHR((x), 10)) + +#define SHA512_S0(x) (SHA_ROTR64((x), 28) ^ SHA_ROTR64((x), 34) ^ SHA_ROTR64((x), 39)) +#define SHA512_S1(x) (SHA_ROTR64((x), 14) ^ SHA_ROTR64((x), 18) ^ SHA_ROTR64((x), 41)) +#define SHA512_s0(x) (SHA_ROTR64((x), 1) ^ SHA_ROTR64((x), 8) ^ SHA_SHR((x), 7)) +#define SHA512_s1(x) (SHA_ROTR64((x), 19) ^ SHA_ROTR64((x), 61) ^ SHA_SHR((x), 6)) + // sha constants // =========================================================================== @@ -63,7 +94,7 @@ sha256_init(struct sha256_ctx *ctx) ctx->digest[7] = 0x5be0cd19; } -static inline void +static void _sha256_block(struct sha256_ctx *ctx) { sha256_word_t a, b, c, d, e, f, g, h, t, t1, t2; @@ -139,7 +170,7 @@ sha256_push(struct sha256_ctx *ctx, void const *buf, size_t len) } } -static inline void +static void _sha256_digest_bswap(struct sha256_ctx *ctx, void *digest, size_t words) { sha256_word_t *out = digest; @@ -252,7 +283,7 @@ sha512_init(struct sha512_ctx *ctx) ctx->digest[7] = 0x5be0cd19137e2179; } -static inline void +static void _sha512_block(struct sha512_ctx *ctx) { sha512_word_t a, b, c, d, e, f, g, h, t, t1, t2; @@ -328,7 +359,7 @@ sha512_push(struct sha512_ctx *ctx, void const *buf, size_t len) } } -static inline void +static void _sha512_digest_bswap(struct sha512_ctx *ctx, void *digest, size_t words) { sha512_word_t *out = digest; diff --git a/sha.h b/sha.h @@ -3,16 +3,10 @@ #ifndef SHA_H #define SHA_H -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#include <assert.h> -#include <endian.h> #include <limits.h> #include <stdalign.h> +#include <stddef.h> #include <stdint.h> -#include <string.h> // sha definitions and constants // =========================================================================== @@ -88,29 +82,6 @@ struct sha512_ctx { #define SHA512_256_DIGEST_WORDS (SHA512_256_DIGEST_BITS / SHA512_WORD_BITS) #define SHA512_256_DIGEST_SIZE (SHA512_256_DIGEST_BITS / CHAR_BIT) -// sha operations -// =========================================================================== - -#define SHA_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) -#define SHA_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) -#define SHA_SHR(x, n) ((x) >> (n)) - -// sha functions -// =========================================================================== - -#define SHA_Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) -#define SHA_Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -#define SHA256_S0(x) (SHA_ROTR32((x), 2) ^ SHA_ROTR32((x), 13) ^ SHA_ROTR32((x), 22)) -#define SHA256_S1(x) (SHA_ROTR32((x), 6) ^ SHA_ROTR32((x), 11) ^ SHA_ROTR32((x), 25)) -#define SHA256_s0(x) (SHA_ROTR32((x), 7) ^ SHA_ROTR32((x), 18) ^ SHA_SHR((x), 3)) -#define SHA256_s1(x) (SHA_ROTR32((x), 17) ^ SHA_ROTR32((x), 19) ^ SHA_SHR((x), 10)) - -#define SHA512_S0(x) (SHA_ROTR64((x), 28) ^ SHA_ROTR64((x), 34) ^ SHA_ROTR64((x), 39)) -#define SHA512_S1(x) (SHA_ROTR64((x), 14) ^ SHA_ROTR64((x), 18) ^ SHA_ROTR64((x), 41)) -#define SHA512_s0(x) (SHA_ROTR64((x), 1) ^ SHA_ROTR64((x), 8) ^ SHA_SHR((x), 7)) -#define SHA512_s1(x) (SHA_ROTR64((x), 19) ^ SHA_ROTR64((x), 61) ^ SHA_SHR((x), 6)) - // sha256 // =========================================================================== diff --git a/test/test-hkdf.c b/test/test-hkdf.c @@ -2,6 +2,7 @@ #include "hmac-sha2.h" #include <stdio.h> +#include <string.h> #define HKDF_ROUNDS 2 #define HKDF_DIGEST_SIZE (SHA256_DIGEST_SIZE * HKDF_ROUNDS) diff --git a/test/test-hmac.c b/test/test-hmac.c @@ -1,6 +1,7 @@ #include "hmac-sha2.h" #include <stdio.h> +#include <string.h> int main(void) diff --git a/test/test-sha224.c b/test/test-sha224.c @@ -1,5 +1,7 @@ #include "sha.h" + #include <stdio.h> +#include <string.h> int main(void) diff --git a/test/test-sha256.c b/test/test-sha256.c @@ -1,5 +1,7 @@ #include "sha.h" + #include <stdio.h> +#include <string.h> int main(void) diff --git a/test/test-sha384.c b/test/test-sha384.c @@ -1,5 +1,7 @@ #include "sha.h" + #include <stdio.h> +#include <string.h> int main(void) diff --git a/test/test-sha512-224.c b/test/test-sha512-224.c @@ -1,5 +1,7 @@ #include "sha.h" + #include <stdio.h> +#include <string.h> int main(void) diff --git a/test/test-sha512-256.c b/test/test-sha512-256.c @@ -1,5 +1,7 @@ #include "sha.h" + #include <stdio.h> +#include <string.h> int main(void) diff --git a/test/test-sha512.c b/test/test-sha512.c @@ -1,5 +1,7 @@ #include "sha.h" + #include <stdio.h> +#include <string.h> int main(void) diff --git a/x25519.c b/x25519.c @@ -0,0 +1,207 @@ +#include "x25519.h" + +static void +x25519_unpack(struct x25519_field_element *out, struct x25519_point const *in) +{ + for (size_t i = 0; i < 16; i++) { + out->vs[i] = in->vs[2*i] + ((int64_t) in->vs[(2*i) + 1] << 8); + } + + out->vs[15] &= 0x7fff; +} + +static void +x25519_carry(struct x25519_field_element *elem) +{ + int64_t carry; + for (size_t i = 0; i < 16; i++) { + carry = elem->vs[i] >> 16; + + elem->vs[i] -= carry << 16; + + if (i < 15) { + elem->vs[i + 1] += carry; + } else { // i == 15 + elem->vs[0] += 38 * carry; + } + } +} + +static void +x25519_fadd(struct x25519_field_element *out, + struct x25519_field_element const *a, + struct x25519_field_element const *b) +{ + for (size_t i = 0; i < 16; i++) { + out->vs[i] = a->vs[i] + b->vs[i]; + } +} + +static void +x25519_fsub(struct x25519_field_element *out, + struct x25519_field_element const *a, + struct x25519_field_element const *b) +{ + for (size_t i = 0; i < 16; i++) { + out->vs[i] = a->vs[i] - b->vs[i]; + } +} + +static void +x25519_fmul(struct x25519_field_element *out, + struct x25519_field_element const *a, + struct x25519_field_element const *b) +{ + int64_t product[31]; + memset(product, 0, sizeof product); // TODO: is this elided? + + for (size_t i = 0; i < 16; i++) { + for (size_t j = 0; j < 16; j++) { + product[i + j] = a->vs[i] * b->vs[j]; + } + } + + for (size_t i = 0; i < 15; i++) { + product[i] += 38 * product[i + 16]; + } + + memcpy(out->vs, product, sizeof out->vs); + x25519_carry(out); + x25519_carry(out); +} + +static void +x25519_finv(struct x25519_field_element *out, + struct x25519_field_element const *in) +{ + struct x25519_field_element c; + memcpy(&c, in, sizeof c); + + for (int i = 253; i >= 0; i--) { + x25519_fmul(&c, &c, &c); + + if (i != 2 && i != 4) + x25519_fmul(&c, &c, in); + } + + memcpy(out, &c, sizeof c); +} + +static void +x25519_swap(struct x25519_field_element *p, + struct x25519_field_element *q, + size_t bit) +{ + int64_t c = ~(bit - 1); + for (size_t i = 0; i < 16; i++) { + int64_t t = c & (p->vs[i] ^ q->vs[i]); + p->vs[i] ^= t; + q->vs[i] ^= t; + } +} + +static void +x25519_pack(struct x25519_point *out, struct x25519_field_element const *in) +{ + int carry; + struct x25519_field_element m, t; + memcpy(&t, in, sizeof t); + + // reduce module p + x25519_carry(&t); x25519_carry(&t); x25519_carry(&t); + + for (size_t j = 0; j < 2; j++) { + m.vs[0] = t.vs[0] - 0xffed; + for (size_t i = 1; i < 15; i++) { + m.vs[i] = t.vs[i] - 0xffff - ((m.vs[i - 1] >> 16) & 1); + m.vs[i - 1] &= 0xffff; + } + + m.vs[15] = t.vs[15] - 0x7fff - ((m.vs[14] >> 16) & 1); + carry = (m.vs[15] >> 16) & 1; + m.vs[14] &= 0xffff; + + x25519_swap(&t, &m, 1 - carry); + } + + for (size_t i = 0; i < 16; i++) { + out->vs[2*i] = t.vs[i] & 0xff; + out->vs[(2*i) + 1] = t.vs[i] >> 8; + } +} + +static void +x25519_scalarmult(struct x25519_point *restrict out, + struct x25519_point const *restrict scalar, + struct x25519_point const *restrict point) +{ + static const struct x25519_field_element _121665 = { + .vs = { 0xdb41, 1 } + }; + + uint8_t clamped[32]; + int64_t bit; + + struct x25519_field_element a, b, c, d, e, f, x; + + memcpy(clamped, scalar, sizeof clamped); + clamped[0] &= 0xf8; + clamped[31] = (clamped[31] & 0x7f) | 0x40; + + x25519_unpack(&x, point); + + memcpy(&b, &x, sizeof b); + memset(&d, 0, sizeof d); + memset(&c, 0, sizeof c); + memset(&a, 0, sizeof a); + a.vs[0] = d.vs[0] = 1; + + for (int i = 254; i >= 0; i--) { + bit = (clamped[i >> 3] >> (i & 7)) & 1; + + x25519_swap(&a, &b, bit); + x25519_swap(&c, &d, bit); + + x25519_fadd(&e, &a, &c); + x25519_fsub(&a, &a, &c); + x25519_fadd(&c, &b, &d); + x25519_fsub(&b, &b, &d); + x25519_fmul(&d, &e, &f); + x25519_fmul(&f, &a, &a); + x25519_fmul(&a, &c, &a); + x25519_fmul(&c, &b, &e); + x25519_fadd(&e, &a, &c); + x25519_fsub(&a, &a, &c); + x25519_fmul(&b, &a, &a); + x25519_fsub(&c, &d, &f); + x25519_fmul(&a, &c, &_121665); + x25519_fadd(&a, &a, &d); + x25519_fmul(&c, &c, &a); + x25519_fmul(&a, &d, &f); + x25519_fmul(&d, &b, &x); + x25519_fmul(&b, &e, &e); + + x25519_swap(&a, &b, bit); + x25519_swap(&c, &d, bit); + } + + x25519_finv(&c, &c); + x25519_fmul(&a, &a, &c); + x25519_pack(out, &a); +} + +void +x25519_genpubkey(struct x25519_point *restrict pk, + struct x25519_point const *restrict sk) +{ + static const struct x25519_point _9 = { .vs = {9} }; + x25519_scalarmult(pk, sk, &_9); +} + +void +x25519(struct x25519_point *restrict out, + struct x25519_point const *restrict pk, + struct x25519_point const *restrict sk) +{ + x25519_scalarmult(out, sk, pk); +} diff --git a/x25519.h b/x25519.h @@ -11,208 +11,11 @@ struct x25519_field_element { int64_t vs[16]; // array of 16, 16-bit numbers (stored as 64-bit) }; -static inline void -x25519_unpack(struct x25519_field_element *out, struct x25519_point const *in) -{ - for (size_t i = 0; i < 16; i++) { - out->vs[i] = in->vs[2*i] + ((int64_t) in->vs[(2*i) + 1] << 8); - } - - out->vs[15] &= 0x7fff; -} - -static inline void -x25519_carry(struct x25519_field_element *elem) -{ - int64_t carry; - for (size_t i = 0; i < 16; i++) { - carry = elem->vs[i] >> 16; - - elem->vs[i] -= carry << 16; - - if (i < 15) { - elem->vs[i + 1] += carry; - } else { // i == 15 - elem->vs[0] += 38 * carry; - } - } -} - -static inline void -x25519_fadd(struct x25519_field_element *out, - struct x25519_field_element const *a, - struct x25519_field_element const *b) -{ - for (size_t i = 0; i < 16; i++) { - out->vs[i] = a->vs[i] + b->vs[i]; - } -} - -static inline void -x25519_fsub(struct x25519_field_element *out, - struct x25519_field_element const *a, - struct x25519_field_element const *b) -{ - for (size_t i = 0; i < 16; i++) { - out->vs[i] = a->vs[i] - b->vs[i]; - } -} - -static inline void -x25519_fmul(struct x25519_field_element *out, - struct x25519_field_element const *a, - struct x25519_field_element const *b) -{ - int64_t product[31]; - memset(product, 0, sizeof product); // TODO: is this elided? - - for (size_t i = 0; i < 16; i++) { - for (size_t j = 0; j < 16; j++) { - product[i + j] = a->vs[i] * b->vs[j]; - } - } - - for (size_t i = 0; i < 15; i++) { - product[i] += 38 * product[i + 16]; - } - - memcpy(out->vs, product, sizeof out->vs); - x25519_carry(out); - x25519_carry(out); -} - -static inline void -x25519_finv(struct x25519_field_element *out, - struct x25519_field_element const *in) -{ - struct x25519_field_element c; - memcpy(&c, in, sizeof c); - - for (int i = 253; i >= 0; i--) { - x25519_fmul(&c, &c, &c); - - if (i != 2 && i != 4) - x25519_fmul(&c, &c, in); - } - - memcpy(out, &c, sizeof c); -} - -static inline void -x25519_swap(struct x25519_field_element *p, - struct x25519_field_element *q, - size_t bit) -{ - int64_t c = ~(bit - 1); - for (size_t i = 0; i < 16; i++) { - int64_t t = c & (p->vs[i] ^ q->vs[i]); - p->vs[i] ^= t; - q->vs[i] ^= t; - } -} - -static inline void -x25519_pack(struct x25519_point *out, struct x25519_field_element const *in) -{ - int carry; - struct x25519_field_element m, t; - memcpy(&t, in, sizeof t); - - // reduce module p - x25519_carry(&t); x25519_carry(&t); x25519_carry(&t); - - for (size_t j = 0; j < 2; j++) { - m.vs[0] = t.vs[0] - 0xffed; - for (size_t i = 1; i < 15; i++) { - m.vs[i] = t.vs[i] - 0xffff - ((m.vs[i - 1] >> 16) & 1); - m.vs[i - 1] &= 0xffff; - } - - m.vs[15] = t.vs[15] - 0x7fff - ((m.vs[14] >> 16) & 1); - carry = (m.vs[15] >> 16) & 1; - m.vs[14] &= 0xffff; - - x25519_swap(&t, &m, 1 - carry); - } - - for (size_t i = 0; i < 16; i++) { - out->vs[2*i] = t.vs[i] & 0xff; - out->vs[(2*i) + 1] = t.vs[i] >> 8; - } -} - -static inline void -x25519_scalarmult(struct x25519_point *restrict out, - struct x25519_point const *restrict scalar, - struct x25519_point const *restrict point) -{ - static const struct x25519_field_element _121665 = { - .vs = { 0xdb41, 1 } - }; - - uint8_t clamped[32]; - int64_t bit; - - struct x25519_field_element a, b, c, d, e, f, x; - - memcpy(clamped, scalar, sizeof clamped); - clamped[0] &= 0xf8; - clamped[31] = (clamped[31] & 0x7f) | 0x40; - - x25519_unpack(&x, point); - - memcpy(&b, &x, sizeof b); - memset(&d, 0, sizeof d); - memset(&c, 0, sizeof c); - memset(&a, 0, sizeof a); - a.vs[0] = d.vs[0] = 1; - - for (int i = 254; i >= 0; i--) { - bit = (clamped[i >> 3] >> (i & 7)) & 1; - - x25519_swap(&a, &b, bit); - x25519_swap(&c, &d, bit); - - x25519_fadd(&e, &a, &c); - x25519_fsub(&a, &a, &c); - x25519_fadd(&c, &b, &d); - x25519_fsub(&b, &b, &d); - x25519_fmul(&d, &e, &f); - x25519_fmul(&f, &a, &a); - x25519_fmul(&a, &c, &a); - x25519_fmul(&c, &b, &e); - x25519_fadd(&e, &a, &c); - x25519_fsub(&a, &a, &c); - x25519_fmul(&b, &a, &a); - x25519_fsub(&c, &d, &f); - x25519_fmul(&a, &c, &_121665); - x25519_fadd(&a, &a, &d); - x25519_fmul(&c, &c, &a); - x25519_fmul(&a, &d, &f); - x25519_fmul(&d, &b, &x); - x25519_fmul(&b, &e, &e); - - x25519_swap(&a, &b, bit); - x25519_swap(&c, &d, bit); - } - - x25519_finv(&c, &c); - x25519_fmul(&a, &a, &c); - x25519_pack(out, &a); -} - -static inline void +void x25519_genpubkey(struct x25519_point *restrict pk, - struct x25519_point const *restrict sk) -{ - static const struct x25519_point _9 = { .vs = {9} }; - x25519_scalarmult(pk, sk, &_9); -} + struct x25519_point const *restrict sk); -static inline void +void x25519(struct x25519_point *restrict out, struct x25519_point const *restrict pk, - struct x25519_point const *restrict sk) -{ - x25519_scalarmult(out, sk, pk); -} + struct x25519_point const *restrict sk);