Skip to content
Merged
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
37 changes: 11 additions & 26 deletions .github/workflows/scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,44 +103,29 @@ jobs:
name: libsodium upstream check
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
issues: write
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v4

- name: Compare vendored version to latest upstream release
- name: Compare latest upstream release to the reviewed marker
run: |
set -euo pipefail

vendored=$(grep -oP 'SODIUM_VERSION_STRING\s+"\K[^"]+' sodium/sodium.h)
echo "vendored libsodium: $vendored"
# the record of what has been reviewed lives in sodium/NOTES.md, not in issues.
# fail if a newer upstream release exists than the "Last reviewed" marker there;
# clearing the failure means reviewing the release and updating NOTES.md.

reviewed=$(grep -oP 'Last reviewed upstream release:\s*\K[0-9.]+' sodium/NOTES.md)
echo "last reviewed upstream release (per sodium/NOTES.md): $reviewed"

latest=$(gh api repos/jedisct1/libsodium/releases/latest --jq '.tag_name' | sed 's/-RELEASE$//; s/^v//')
echo "latest upstream release: $latest"

if [ "$vendored" = "$latest" ]; then
echo "vendored subset is up to date"
exit 0
fi

title="libsodium $latest is available (vendored subset is $vendored)"

# don't open a duplicate if an open issue with this exact title already exists
existing=$(gh issue list --state open --search "in:title \"$title\"" --json number --jq 'length')
if [ "$existing" != "0" ]; then
echo "an open issue for $latest already exists; nothing to do"
if [ "$latest" = "$reviewed" ]; then
echo "no unreviewed upstream release"
exit 0
fi

gh issue create \
--title "$title" \
--label dependencies \
--body "The vendored libsodium subset in \`sodium/\` is at **$vendored**, but upstream has released **$latest**.

Review the upstream changelog for security-relevant fixes and, if warranted, regenerate the amalgamated subset per \`sodium/NOTES.md\` (re-run the known-answer validation, including \`test_crypto_aead_vectors\`, afterwards).

Opened automatically by the scheduled \`libsodium upstream check\` job." \
|| echo "could not create issue (the 'dependencies' label may not exist); please create it manually"
echo "::error::libsodium $latest is available and has not been reviewed (marker is $reviewed). Review it against the included slice and update the 'Last reviewed upstream release' marker and review log in sodium/NOTES.md."
exit 1
47 changes: 31 additions & 16 deletions sodium/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,38 @@ ChaCha20, Poly1305, and AEAD implementations are byte-identical across 1.0.17

## Upstream tracking

Vendoring decouples this tree from upstream security updates, so the pinned version
is watched rather than assumed current. The scheduled `libsodium upstream check` job
(`.github/workflows/scheduled.yml`) reads the version from `SODIUM_VERSION_STRING` in
`sodium.h`, compares it to the latest `jedisct1/libsodium` release, and opens a
tracking issue if a newer release exists. When that fires:

1. Read the upstream changelog for changes touching the included slice (ChaCha20,
Poly1305, the two AEAD constructions, and their support code — most releases do
not).
2. If a relevant fix landed, regenerate the amalgamation per "Structure / regenerating"
above and bump `SODIUM_VERSION_STRING`.
3. Re-run the validation below — in particular `test_crypto_aead_vectors`, which runs
in CI on every platform — and confirm the output is still bit-identical to the new
upstream for both AEADs.
Vendoring decouples this tree from upstream security updates, so upstream releases are
watched rather than assumed reviewed. The scheduled `libsodium upstream check` job
(`.github/workflows/scheduled.yml`) compares the latest `jedisct1/libsodium` release to
the marker below and **fails** if a newer, unreviewed release exists — it does not open
issues; this file is the record. To clear it, review the new release and update the
marker (and the log) here.

Last reviewed upstream release: 1.0.22

If the release only touches code outside the included slice, bumping the pinned
version string (so the check goes quiet) is enough; note the reason in the commit.
Reviewing a new release means:

1. Read the upstream changelog for changes touching the **included slice** (ChaCha20,
Poly1305, the two AEAD constructions, and their support code — most releases touch
none of it).
2. If a relevant fix landed, regenerate the amalgamation per "Structure / regenerating"
above, bump `SODIUM_VERSION_STRING`, and re-run the validation below — in particular
`test_crypto_aead_vectors`, which runs in CI on every platform — confirming the output
is still bit-identical to the new upstream for both AEADs.
3. Update the marker above to the reviewed version and add a line to the log, whether or
not the vendored code changed.

### Review log

- **1.0.22 (reviewed; vendored still 1.0.20).** 1.0.21 and 1.0.22 are mostly outside the
included slice — the ed25519 small-order-point fix, ipcrypt, XOF/SHA-3, ML-KEM768 /
X-Wing, and assorted build/platform work do not touch the ChaCha20/Poly1305/AEAD code
netcode uses. **One item does:** 1.0.20-stable/1.0.21 added memory fences after MAC
verification in the AEAD path (a speculative-access hardening — plaintext must not be
read before authentication completes). This appears to touch the ChaCha20-Poly1305
decrypt code in this subset and is **pending incorporation** on the next re-vendor;
it is a defense-in-depth hardening, not a functional or interop change, so the vendored
1.0.20 remains correct and interoperable in the meantime.

## What is included

Expand Down
Loading