Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ independent implementations (C#, Go, Rust, TypeScript).
- Build: CMake. `cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build --parallel`,
then `ctest --test-dir build --output-on-failure` runs the suite (51 tests). The
`netcode_test` target compiles netcode.c into itself with `NETCODE_ENABLE_TESTS`, so it
links only sodium. `-DNETCODE_SANITIZE=ON` adds ASan+UBSan (sodium gets ASan only);
links only sodium. `-DNETCODE_SANITIZE=ON` adds ASan+UBSan (sodium keeps UBSan
except alignment);
`-DNETCODE_FUZZ=ON` builds the `fuzz/` harnesses (libFuzzer where available, else a
standalone file replayer); `-DNETCODE_NONCE_AUDIT=ON` records the key and nonce of every
packet the tests encrypt and fails the run on a repeat (test-only, nothing enters the
Expand Down
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ endif()

include(GNUInstallDirs)

# sanitizers apply to the whole build. the vendored crypto is exempted from UBSan
# below (third-party SIMD code uses intentional type punning / unaligned access that
# UBSan flags but is not netcode's to fix); it still gets AddressSanitizer.
# sanitizers apply to the whole build. the vendored crypto is exempted only from
# UBSan alignment (SIMD kernels use unaligned loads and type punning). nonnull-attribute
# stays on so a NULL zero-length additional-data pointer is a real failure (netcode#186).

if(NETCODE_SANITIZE)
if(MSVC)
Expand Down Expand Up @@ -125,7 +125,7 @@ else()
-Wno-unused-variable
-Wno-type-limits)
if(NETCODE_SANITIZE)
target_compile_options(sodium PRIVATE -fno-sanitize=undefined)
target_compile_options(sodium PRIVATE -fno-sanitize=alignment)
endif()
endif()

Expand Down
2 changes: 1 addition & 1 deletion netcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -6351,7 +6351,7 @@ static void test_connect_token()

static void test_challenge_token()
{
// generate a challenge token
// additional data is NULL, 0. sodium.c must keep nonnull-attribute so this path guards #186.

struct netcode_challenge_token_t input_token;

Expand Down
21 changes: 21 additions & 0 deletions sodium/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,27 @@ Reviewing a new release means:

### Review log

- **1.0.22 attributes (2026-09-08).** Fourteen declarations carried a bare
`__attribute__ ((nonnull))`. This pass was the crypto slice netcode actually
calls (`crypto_stream_chacha20{,_ietf}_xor{,_ic}`,
`crypto_onetimeauth{,_poly1305}{,_verify,_update}`), because a NULL
additional-data pointer with length zero is a valid call and is how netcode
encrypts challenge tokens; the bare attribute aborts a UBSAN build on that
path. Those eleven declarations now match upstream 1.0.22, including
`crypto_aead_xchacha20poly1305_ietf_decrypt_detached` which had
`nonnull(3, 5, 9, 9)` (nonce missing, parameter 9 twice); upstream is
`nonnull(3, 5, 8, 9)`. Nine other divergences remain in the utils slice and
are not reachable from netcode's own code: `sodium_memcmp` and
`sodium_compare` keep a bare nonnull beside unused-result where upstream has
unused-result only; `sodium_bin2hex` and `sodium_bin2base64` keep bare
nonnull against upstream `nonnull(1)`; `sodium_hex2bin` and
`sodium_base642bin` carry `nonnull(1, 3)` against upstream `nonnull(1)`;
`sodium_memzero`, `sodium_add` and `sodium_sub` carry a bare nonnull where
upstream declares none. Header attributes only; crypto text unchanged. The
vendored sodium object's UBSan exemption is alignment only, not all of
undefined, so `test_challenge_token` (additional data NULL, 0) is a real
nonnull-attribute guard. See netcode#186.

- **1.0.22 (reviewed AND incorporated, 2026-07-25).** The vendored slice now carries the
1.0.22 text. Most of 1.0.21/1.0.22 is outside the slice — the ed25519 small-order-point
fix, ipcrypt, XOF/SHA-3, ML-KEM768 / X-Wing and assorted build work do not touch the
Expand Down
22 changes: 11 additions & 11 deletions sodium/sodium.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1, 4, 5)));

int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint64_t ic,
const unsigned char *k)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1, 4, 6)));

void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES])
__attribute__ ((nonnull));
Expand All @@ -143,13 +143,13 @@ int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1, 4, 5)));

int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint32_t ic,
const unsigned char *k)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1, 4, 6)));

void crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES])
__attribute__ ((nonnull));
Expand Down Expand Up @@ -431,7 +431,7 @@ int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 9, 9)));
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9)));

void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES])
__attribute__ ((nonnull));
Expand Down Expand Up @@ -514,13 +514,13 @@ int crypto_onetimeauth_poly1305(unsigned char *out,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1, 4)));

int crypto_onetimeauth_poly1305_verify(const unsigned char *h,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k)
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull));
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4)));

int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state,
const unsigned char *key)
Expand All @@ -529,7 +529,7 @@ int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state,
int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state,
const unsigned char *in,
unsigned long long inlen)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1)));

int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state,
unsigned char *out)
Expand Down Expand Up @@ -572,19 +572,19 @@ const char *crypto_onetimeauth_primitive(void);

int crypto_onetimeauth(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *k)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1, 4)));

int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in,
unsigned long long inlen, const unsigned char *k)
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull));
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4)));

int crypto_onetimeauth_init(crypto_onetimeauth_state *state,
const unsigned char *key) __attribute__ ((nonnull));

int crypto_onetimeauth_update(crypto_onetimeauth_state *state,
const unsigned char *in,
unsigned long long inlen)
__attribute__ ((nonnull));
__attribute__ ((nonnull(1)));

int crypto_onetimeauth_final(crypto_onetimeauth_state *state,
unsigned char *out) __attribute__ ((nonnull));
Expand Down
Loading