From 3e4de8a134795ea1c0b1ee97c397f6155f95862e Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 23 Jan 2026 23:07:00 +0100 Subject: [PATCH] Change crypto_core_ed25519_from_string to take a binary string --- .../crypto_core/ed25519/core_ed25519.c | 19 ++++++----- src/libsodium/crypto_core/ed25519/core_h2c.c | 32 +++++++++---------- src/libsodium/crypto_core/ed25519/core_h2c.h | 3 +- .../crypto_core/ed25519/core_ristretto255.c | 26 ++++++++------- .../include/sodium/crypto_core_ed25519.h | 10 +++--- .../include/sodium/crypto_core_ristretto255.h | 12 +++---- test/default/core_ed25519_h2c.c | 29 ++++++++++------- 7 files changed, 73 insertions(+), 58 deletions(-) diff --git a/src/libsodium/crypto_core/ed25519/core_ed25519.c b/src/libsodium/crypto_core/ed25519/core_ed25519.c index 93fd800d..41b517b8 100644 --- a/src/libsodium/crypto_core/ed25519/core_ed25519.c +++ b/src/libsodium/crypto_core/ed25519/core_ed25519.c @@ -61,7 +61,8 @@ crypto_core_ed25519_sub(unsigned char *r, static int _string_to_points(unsigned char * const px, const size_t n, - const char *ctx, const unsigned char *msg, size_t msg_len, + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, int hash_alg) { unsigned char h[crypto_core_ed25519_HASHBYTES]; @@ -71,7 +72,7 @@ _string_to_points(unsigned char * const px, const size_t n, if (n > 2U) { abort(); /* LCOV_EXCL_LINE */ } - if (core_h2c_string_to_hash(h_be, n * HASH_GE_L, ctx, msg, msg_len, + if (core_h2c_string_to_hash(h_be, n * HASH_GE_L, ctx, ctx_len, msg, msg_len, hash_alg) != 0) { return -1; } @@ -88,20 +89,22 @@ _string_to_points(unsigned char * const px, const size_t n, int crypto_core_ed25519_from_string(unsigned char p[crypto_core_ed25519_BYTES], - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) { - return _string_to_points(p, 1, ctx, msg, msg_len, hash_alg); + return _string_to_points(p, 1, ctx, ctx_len, msg, msg_len, hash_alg); } int crypto_core_ed25519_from_string_ro(unsigned char p[crypto_core_ed25519_BYTES], - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) { unsigned char px[2 * crypto_core_ed25519_BYTES]; - if (_string_to_points(px, 2, ctx, msg, msg_len, hash_alg) != 0) { + if (_string_to_points(px, 2, ctx, ctx_len, msg, msg_len, hash_alg) != 0) { return -1; } return crypto_core_ed25519_add(p, &px[0], &px[crypto_core_ed25519_BYTES]); diff --git a/src/libsodium/crypto_core/ed25519/core_h2c.c b/src/libsodium/crypto_core/ed25519/core_h2c.c index 37f3ed59..58f6626f 100644 --- a/src/libsodium/crypto_core/ed25519/core_h2c.c +++ b/src/libsodium/crypto_core/ed25519/core_h2c.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "core_h2c.h" #include "crypto_hash_sha256.h" @@ -12,7 +11,8 @@ #define HASH_BLOCKBYTES 64U static int -core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char *ctx, +core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, + const unsigned char *ctx, size_t ctx_len, const unsigned char *msg, size_t msg_len) { crypto_hash_sha256_state st; @@ -21,7 +21,6 @@ core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char unsigned char ux[HASH_BYTES] = { 0 }; unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; unsigned char ctx_len_u8; - size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; size_t i, j; assert(h_len <= 0xff); @@ -30,9 +29,9 @@ core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char crypto_hash_sha256_update(&st, (const unsigned char *) "H2C-OVERSIZE-DST-", sizeof "H2C-OVERSIZE-DST-" - 1U); - crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_update(&st, ctx, ctx_len); crypto_hash_sha256_final(&st, u0); - ctx = (const char *) u0; + ctx = u0; ctx_len = HASH_BYTES; COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); } @@ -41,7 +40,7 @@ core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char crypto_hash_sha256_update(&st, empty_block, sizeof empty_block); crypto_hash_sha256_update(&st, msg, msg_len); crypto_hash_sha256_update(&st, t, 3U); - crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_update(&st, ctx, ctx_len); crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); crypto_hash_sha256_final(&st, u0); @@ -53,7 +52,7 @@ core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char crypto_hash_sha256_init(&st); crypto_hash_sha256_update(&st, ux, HASH_BYTES); crypto_hash_sha256_update(&st, &t[2], 1U); - crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_update(&st, ctx, ctx_len); crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); crypto_hash_sha256_final(&st, ux); memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); @@ -68,7 +67,8 @@ core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char #define HASH_BLOCKBYTES 128U static int -core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char *ctx, +core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, + const unsigned char *ctx, size_t ctx_len, const unsigned char *msg, size_t msg_len) { crypto_hash_sha512_state st; @@ -77,7 +77,6 @@ core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char unsigned char ux[HASH_BYTES] = { 0 }; unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; unsigned char ctx_len_u8; - size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; size_t i, j; assert(h_len <= 0xff); @@ -86,9 +85,9 @@ core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char crypto_hash_sha512_update(&st, (const unsigned char *) "H2C-OVERSIZE-DST-", sizeof "H2C-OVERSIZE-DST-" - 1U); - crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_update(&st, ctx, ctx_len); crypto_hash_sha512_final(&st, u0); - ctx = (const char *) u0; + ctx = u0; ctx_len = HASH_BYTES; COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); } @@ -97,7 +96,7 @@ core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char crypto_hash_sha512_update(&st, empty_block, sizeof empty_block); crypto_hash_sha512_update(&st, msg, msg_len); crypto_hash_sha512_update(&st, t, 3U); - crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_update(&st, ctx, ctx_len); crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); crypto_hash_sha512_final(&st, u0); @@ -109,7 +108,7 @@ core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char crypto_hash_sha512_init(&st); crypto_hash_sha512_update(&st, ux, HASH_BYTES); crypto_hash_sha512_update(&st, &t[2], 1U); - crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_update(&st, ctx, ctx_len); crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); crypto_hash_sha512_final(&st, ux); memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); @@ -118,14 +117,15 @@ core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char } int -core_h2c_string_to_hash(unsigned char *h, const size_t h_len, const char *ctx, +core_h2c_string_to_hash(unsigned char *h, const size_t h_len, + const unsigned char *ctx, size_t ctx_len, const unsigned char *msg, size_t msg_len, int hash_alg) { switch (hash_alg) { case CORE_H2C_SHA256: - return core_h2c_string_to_hash_sha256(h, h_len, ctx, msg, msg_len); + return core_h2c_string_to_hash_sha256(h, h_len, ctx, ctx_len, msg, msg_len); case CORE_H2C_SHA512: - return core_h2c_string_to_hash_sha512(h, h_len, ctx, msg, msg_len); + return core_h2c_string_to_hash_sha512(h, h_len, ctx, ctx_len, msg, msg_len); default: errno = EINVAL; return -1; diff --git a/src/libsodium/crypto_core/ed25519/core_h2c.h b/src/libsodium/crypto_core/ed25519/core_h2c.h index e595b80c..e10760ec 100644 --- a/src/libsodium/crypto_core/ed25519/core_h2c.h +++ b/src/libsodium/crypto_core/ed25519/core_h2c.h @@ -6,7 +6,8 @@ #define CORE_H2C_SHA256 1 #define CORE_H2C_SHA512 2 -int core_h2c_string_to_hash(unsigned char *h, const size_t h_len, const char *ctx, +int core_h2c_string_to_hash(unsigned char *h, const size_t h_len, + const unsigned char *ctx, size_t ctx_len, const unsigned char *msg, size_t msg_len, int hash_alg); #endif diff --git a/src/libsodium/crypto_core/ed25519/core_ristretto255.c b/src/libsodium/crypto_core/ed25519/core_ristretto255.c index 6d3a85cd..9cf57fd6 100644 --- a/src/libsodium/crypto_core/ed25519/core_ristretto255.c +++ b/src/libsodium/crypto_core/ed25519/core_ristretto255.c @@ -65,12 +65,13 @@ crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r) static int _string_to_element(unsigned char *p, - const char *ctx, const unsigned char *msg, size_t msg_len, + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, int hash_alg) { unsigned char h[crypto_core_ristretto255_HASHBYTES]; - if (core_h2c_string_to_hash(h, sizeof h, ctx, msg, msg_len, + if (core_h2c_string_to_hash(h, sizeof h, ctx, ctx_len, msg, msg_len, hash_alg) != 0) { return -1; } @@ -81,18 +82,20 @@ _string_to_element(unsigned char *p, int crypto_core_ristretto255_from_string(unsigned char p[crypto_core_ristretto255_BYTES], - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) { - return _string_to_element(p, ctx, msg, msg_len, hash_alg); + return _string_to_element(p, ctx, ctx_len, msg, msg_len, hash_alg); } int crypto_core_ristretto255_from_string_ro(unsigned char p[crypto_core_ristretto255_BYTES], - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) { - return crypto_core_ristretto255_from_string(p, ctx, msg, msg_len, hash_alg); + return crypto_core_ristretto255_from_string(p, ctx, ctx_len, msg, msg_len, hash_alg); } void @@ -169,14 +172,15 @@ crypto_core_ristretto255_scalar_is_canonical(const unsigned char *s) int crypto_core_ristretto255_scalar_from_string(unsigned char *s, - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) { unsigned char h[crypto_core_ristretto255_NONREDUCEDSCALARBYTES]; unsigned char h_be[HASH_SC_L]; size_t i; - if (core_h2c_string_to_hash(h_be, sizeof h_be, ctx, msg, msg_len, + if (core_h2c_string_to_hash(h_be, sizeof h_be, ctx, ctx_len, msg, msg_len, hash_alg) != 0) { return -1; } diff --git a/src/libsodium/include/sodium/crypto_core_ed25519.h b/src/libsodium/include/sodium/crypto_core_ed25519.h index d2bfb295..9114017e 100644 --- a/src/libsodium/include/sodium/crypto_core_ed25519.h +++ b/src/libsodium/include/sodium/crypto_core_ed25519.h @@ -47,14 +47,16 @@ int crypto_core_ed25519_sub(unsigned char *r, SODIUM_EXPORT int crypto_core_ed25519_from_string(unsigned char p[crypto_core_ed25519_BYTES], - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_core_ed25519_from_string_ro(unsigned char p[crypto_core_ed25519_BYTES], - const char *ctx, const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) __attribute__ ((nonnull(1))); SODIUM_EXPORT diff --git a/src/libsodium/include/sodium/crypto_core_ristretto255.h b/src/libsodium/include/sodium/crypto_core_ristretto255.h index 5fc3a1be..30c7faee 100644 --- a/src/libsodium/include/sodium/crypto_core_ristretto255.h +++ b/src/libsodium/include/sodium/crypto_core_ristretto255.h @@ -48,16 +48,16 @@ int crypto_core_ristretto255_from_hash(unsigned char *p, SODIUM_EXPORT int crypto_core_ristretto255_from_string(unsigned char p[crypto_core_ristretto255_BYTES], - const char *ctx, - const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_core_ristretto255_from_string_ro(unsigned char p[crypto_core_ristretto255_BYTES], - const char *ctx, - const unsigned char *msg, - size_t msg_len, int hash_alg) + const unsigned char *ctx, size_t ctx_len, + const unsigned char *msg, size_t msg_len, + int hash_alg) __attribute__ ((nonnull(1))); SODIUM_EXPORT diff --git a/test/default/core_ed25519_h2c.c b/test/default/core_ed25519_h2c.c index 020e9c98..6a70cf5b 100644 --- a/test/default/core_ed25519_h2c.c +++ b/test/default/core_ed25519_h2c.c @@ -101,14 +101,18 @@ main(void) } if (test_data[i].ro == 0) { if (crypto_core_ed25519_from_string( - y, "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_NU_", + y, + (const unsigned char *) "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_NU_", + sizeof("QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_NU_") - 1U, (const unsigned char *) test_data[i].msg, strlen(test_data[i].msg), H2CHASH) != 0) { printf("crypto_core_ed25519_from_string() failed\n"); } } else { if (crypto_core_ed25519_from_string_ro( - y, "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_RO_", + y, + (const unsigned char *) "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_RO_", + sizeof("QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_RO_") - 1U, (const unsigned char *) test_data[i].msg, strlen(test_data[i].msg), H2CHASH) != 0) { printf("crypto_core_ed25519_from_string_ro() failed\n"); @@ -128,32 +132,33 @@ main(void) } } - if (crypto_core_ed25519_from_string(y, NULL, (const unsigned char *) "msg", + if (crypto_core_ed25519_from_string(y, NULL, 0U, (const unsigned char *) "msg", 3U, H2CHASH) != 0 || - crypto_core_ed25519_from_string(y, "", guard_page, 0U, H2CHASH) != 0 || + crypto_core_ed25519_from_string(y, (const unsigned char *) "", 0U, + guard_page, 0U, H2CHASH) != 0 || crypto_core_ed25519_from_string_ro( - y, NULL, (const unsigned char *) "msg", 3U, H2CHASH) != 0 || - crypto_core_ed25519_from_string_ro(y, "", guard_page, 0U, - H2CHASH) != 0) { + y, NULL, 0U, (const unsigned char *) "msg", 3U, H2CHASH) != 0 || + crypto_core_ed25519_from_string_ro(y, (const unsigned char *) "", 0U, + guard_page, 0U, H2CHASH) != 0) { printf("Failed with empty parameters"); } oversized_ctx = (char *) sodium_malloc(oversized_ctx_len); - memset(oversized_ctx, 'X', oversized_ctx_len - 1U); - oversized_ctx[oversized_ctx_len - 1U] = 0; - crypto_core_ed25519_from_string(y, oversized_ctx, + memset(oversized_ctx, 'X', oversized_ctx_len); + crypto_core_ed25519_from_string(y, (const unsigned char *) oversized_ctx, + oversized_ctx_len - 1U, (const unsigned char *) "msg", 3U, H2CHASH); sodium_bin2hex(y_hex, crypto_core_ed25519_BYTES * 2U + 1U, y, crypto_core_ed25519_BYTES); printf("NU with oversized context: %s\n", y_hex); - crypto_core_ed25519_from_string_ro(y, oversized_ctx, + crypto_core_ed25519_from_string_ro(y, (const unsigned char *) oversized_ctx, + oversized_ctx_len - 1U, (const unsigned char *) "msg", 3U, H2CHASH); sodium_bin2hex(y_hex, crypto_core_ed25519_BYTES * 2U + 1U, y, crypto_core_ed25519_BYTES); printf("RO with oversized context: %s\n", y_hex); - sodium_free(oversized_ctx); sodium_free(y_hex); sodium_free(expected_y_hex);