Update documentation to reflect Rust native backend migration
ober
2f1ac00833501ba643dc7a40e551e6bbc6d8174f
--- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ SCHEME = scheme LIBDIRS = lib -# Base directory for chez-* repos (clone from github.com/ober/chez-*) +# Base directory for chez-* repos (legacy C FFI — see `make native` for Rust backend) CHEZ_EXT_DIR ?= $(HOME)/src -# External chez-* library paths for wrapper modules -CHEZ_EXT_LIBDIRS = $(CHEZ_EXT_DIR)/chez-https/src:$(CHEZ_EXT_DIR)/chez-ssl/src:$(CHEZ_EXT_DIR)/chez-zlib/src:$(CHEZ_EXT_DIR)/chez-pcre2:$(CHEZ_EXT_DIR)/chez-yaml:$(CHEZ_EXT_DIR)/chez-leveldb:$(CHEZ_EXT_DIR)/chez-epoll/src:$(CHEZ_EXT_DIR)/chez-inotify/src:$(CHEZ_EXT_DIR)/chez-crypto/src:$(CHEZ_EXT_DIR)/chez-sqlite/src:$(CHEZ_EXT_DIR)/chez-postgresql/src -# Shared object paths for FFI-based chez-* libraries +# External chez-* library paths for legacy wrapper modules +CHEZ_EXT_LIBDIRS = $(CHEZ_EXT_DIR)/chez-https/src:$(CHEZ_EXT_DIR)/chez-ssl/src:$(CHEZ_EXT_DIR)/chez-zlib/src:$(CHEZ_EXT_DIR)/chez-pcre2:$(CHEZ_EXT_DIR)/chez-leveldb:$(CHEZ_EXT_DIR)/chez-epoll/src:$(CHEZ_EXT_DIR)/chez-inotify/src:$(CHEZ_EXT_DIR)/chez-crypto/src:$(CHEZ_EXT_DIR)/chez-sqlite/src:$(CHEZ_EXT_DIR)/chez-postgresql/src +# Shared object paths for legacy FFI-based chez-* libraries CHEZ_EXT_LDPATH = $(CHEZ_EXT_DIR)/chez-ssl:$(CHEZ_EXT_DIR)/chez-zlib:$(CHEZ_EXT_DIR)/chez-pcre2:$(CHEZ_EXT_DIR)/chez-leveldb:$(CHEZ_EXT_DIR)/chez-epoll:$(CHEZ_EXT_DIR)/chez-inotify:$(CHEZ_EXT_DIR)/chez-crypto:$(CHEZ_EXT_DIR)/chez-sqlite:$(CHEZ_EXT_DIR)/chez-postgresql .PHONY: test test-reader test-core test-runtime test-stdlib test-ffi test-modules test-expanded test-features test-wrappers test-phase4a test-phase4b test-phase4c test-phase4d test-phase4e test-phase4f test-phase5 test-phase5e test-phase6 test-phase7 test-phase8 test-functional test-repl test-security test-native test-gaps native clean-native audit-native clean fuzz fuzz-smoke fuzz-deep fuzz-reader-fuzz fuzz-json-fuzz fuzz-http2-fuzz fuzz-websocket-fuzz fuzz-dns-fuzz fuzz-pregexp-fuzz fuzz-csv-fuzz fuzz-base64-fuzz fuzz-hex-fuzz fuzz-uri-fuzz fuzz-format-fuzz fuzz-router-fuzz fuzz-sandbox-fuzz --- a/README.md +++ b/README.md @@ -136,7 +136,28 @@ scheme --libdirs lib --script your-file.ss | `(jerboa wasm codegen)` | Scheme→WASM compiler (pure i32 subset) | | `(jerboa wasm runtime)` | Stack-based WASM interpreter | -### External Library Wrappers (require [chez-*](https://github.com/ober) libraries) +### Rust Native Backend (`libjerboa_native.so`) + +Jerboa includes a unified Rust shared library that replaces most C dependencies with memory-safe implementations. Build with `make native` (requires Rust toolchain). + +| Module | Rust Crate | Provides | +|--------|------------|----------| +| `(std crypto native-rust)` | ring | SHA-1/256/384/512, HMAC-SHA256, AES-256-GCM, PBKDF2, CSPRNG, constant-time compare | +| `(std crypto secure-mem)` | libc (mmap/mlock) | `secure-alloc`, `secure-free`, `secure-wipe` — guard-paged, mlock'd memory outside GC | +| `(std compress native-rust)` | flate2 | `deflate-bytevector`, `inflate-bytevector`, `gzip-bytevector`, `gunzip-bytevector` with size limits | +| `(std regex-native)` | regex (NFA) | `regex-compile`, `regex-match?`, `regex-find`, `regex-replace-all` — ReDoS-immune | +| `(std db sqlite-native)` | rusqlite (bundled) | `sqlite-open`, `sqlite-exec`, `sqlite-prepare`, parameterized queries | +| `(std db postgresql-native)` | rust-postgres | `pg-connect`, `pg-exec`, `pg-query`, parameterized queries | +| `(std os epoll-native)` | libc | `epoll-create`, `epoll-ctl`, `epoll-wait` | +| `(std os inotify-native)` | libc | `inotify-init`, `inotify-add-watch`, `inotify-read-events` | +| `(std os landlock-native)` | libc (syscalls) | Landlock LSM ABI v1-v7 — filesystem and network sandboxing | + +See [docs/native-rust.md](docs/native-rust.md) for architecture, C ABI design, and migration details. + +### Legacy C Library Wrappers (require [chez-*](https://github.com/ober) libraries) + +These modules use external C libraries via chez-* FFI shims. They remain functional but are being superseded by the Rust native backend above. + | Module | Wraps | Provides | |--------|-------|----------| | `(std net request)` | [chez-https](https://github.com/ober/chez-https) | `http-get`, `http-post`, `http-put`, `http-delete`, `url-encode` | @@ -175,16 +196,18 @@ One import for everything: ```bash make test # Core tests (289 tests) make test-features # Phase 2+3 feature tests (637 tests) -make test-wrappers # External library wrapper tests (27 tests) +make test-native # Rust native backend tests (requires `make native` first) +make test-wrappers # Legacy chez-* library wrapper tests (27 tests) make test-all # Everything (953+ tests) ``` -Runs 289 core tests across reader, core macros, runtime, standard library, FFI, module paths, and expanded stdlib. Feature tests add 637 more for Phase 2 and Phase 3 libraries. Wrapper tests add 27 more for chez-* library integrations. +Runs 289 core tests across reader, core macros, runtime, standard library, FFI, module paths, and expanded stdlib. Feature tests add 637 more for Phase 2 and Phase 3 libraries. Native tests cover the Rust backend (crypto, compression, regex, databases, OS). Wrapper tests cover the legacy chez-* C library integrations. ## Requirements - [Chez Scheme](https://cisco.github.io/ChezScheme/) 10.x (stock, unmodified) -- Optional: [chez-*](https://github.com/ober) libraries for networking, compression, PCRE2, LevelDB, SQLite, PostgreSQL, epoll, inotify, crypto +- Optional: [Rust toolchain](https://rustup.rs/) for building `libjerboa_native.so` (crypto, compression, regex, databases, OS integration) +- Optional (legacy): [chez-*](https://github.com/ober) libraries for networking, compression, PCRE2, LevelDB, SQLite, PostgreSQL, epoll, inotify, crypto ## Project Structure @@ -234,25 +257,36 @@ lib/ temporaries.sls # :std/os/temporaries signal.sls # :std/os/signal fdio.sls # :std/os/fdio - epoll.sls # :std/os/epoll (wraps chez-epoll) - inotify.sls # :std/os/inotify (wraps chez-inotify) + epoll.sls # :std/os/epoll (wraps chez-epoll — legacy) + epoll-native.sls # :std/os/epoll-native (Rust via libjerboa_native.so) + inotify.sls # :std/os/inotify (wraps chez-inotify — legacy) + inotify-native.sls # :std/os/inotify-native (Rust via libjerboa_native.so) + landlock-native.sls # :std/os/landlock-native (Rust via libjerboa_native.so) net/ - request.sls # :std/net/request (wraps chez-https) - httpd.sls # :std/net/httpd (wraps chez-https) - ssl.sls # :std/net/ssl (wraps chez-ssl) + request.sls # :std/net/request (wraps chez-https — legacy) + httpd.sls # :std/net/httpd (wraps chez-https — legacy) + ssl.sls # :std/net/ssl (wraps chez-ssl — legacy) compress/ - zlib.sls # :std/compress/zlib (wraps chez-zlib) + zlib.sls # :std/compress/zlib (wraps chez-zlib — legacy) + native-rust.sls # :std/compress/native-rust (flate2 via libjerboa_native.so) db/ - leveldb.sls # :std/db/leveldb (wraps chez-leveldb) - sqlite.sls # :std/db/sqlite (wraps chez-sqlite) - postgresql.sls # :std/db/postgresql (wraps chez-postgresql) + leveldb.sls # :std/db/leveldb (wraps chez-leveldb — legacy) + sqlite.sls # :std/db/sqlite (wraps chez-sqlite — legacy) + sqlite-native.sls # :std/db/sqlite-native (rusqlite via libjerboa_native.so) + postgresql.sls # :std/db/postgresql (wraps chez-postgresql — legacy) + postgresql-native.sls # :std/db/postgresql-native (rust-postgres via libjerboa_native.so) crypto/ digest.sls # :std/crypto/digest - cipher.sls # :std/crypto/cipher (wraps chez-crypto) - hmac.sls # :std/crypto/hmac (wraps chez-crypto) - pkey.sls # :std/crypto/pkey (wraps chez-crypto) - kdf.sls # :std/crypto/kdf (wraps chez-crypto) - etc.sls # :std/crypto/etc (wraps chez-crypto) + native.sls # :std/crypto/native (direct OpenSSL FFI — legacy) + native-rust.sls # :std/crypto/native-rust (ring via libjerboa_native.so) + secure-mem.sls # :std/crypto/secure-mem (mlock'd memory via Rust) + cipher.sls # :std/crypto/cipher (wraps chez-crypto — legacy) + hmac.sls # :std/crypto/hmac (wraps chez-crypto — legacy) + pkey.sls # :std/crypto/pkey (wraps chez-crypto — legacy) + kdf.sls # :std/crypto/kdf (wraps chez-crypto — legacy) + etc.sls # :std/crypto/etc (wraps chez-crypto — legacy) + native.sls # :std/native — Rust native library loader + regex-native.sls # :std/regex-native (Rust NFA regex via libjerboa_native.so) foreign.sls # :std/foreign — FFI DSL cli/ getopt.sls # :std/cli/getopt @@ -260,9 +294,23 @@ lib/ srfi-13.sls # :std/srfi/13 srfi-19.sls # :std/srfi/19 pregexp.sls # :std/pregexp - pcre2.sls # :std/pcre2 (wraps chez-pcre2) + pcre2.sls # :std/pcre2 (wraps chez-pcre2 — legacy) test.sls # :std/test logger.sls # :std/logger +jerboa-native-rs/ # Rust native library project + Cargo.toml # ring, flate2, regex, rusqlite, postgres, inotify, libc + src/ + lib.rs # top-level: module declarations, init + crypto.rs # ring: digest, hmac, aead, csprng, pbkdf2, scrypt + compress.rs # flate2: deflate, inflate, gzip, gunzip + regex_native.rs # regex crate: compile, match, find, replace + sqlite.rs # rusqlite: open, prepare, bind, step, finalize + postgres_native.rs # rust-postgres: connect, query, execute + epoll.rs # epoll: create, ctl, wait + inotify_native.rs # inotify: init, add_watch, read_events + landlock.rs # landlock: ABI v1-v7, filesystem + network rules + secure_mem.rs # mlock, guard pages, explicit_bzero + panic.rs # catch_unwind wrapper for all extern "C" functions tests/ test-reader.ss # 65 reader tests test-core.ss # 68 core macro tests --- a/docs/actor-model.md +++ b/docs/actor-model.md @@ -222,7 +222,7 @@ To convert a time object to a float without SRFI-19: │ (std misc channel) — bounded channels + select │ │ (std misc thread) — Gambit thread API │ │ (std task) — task groups + futures │ -│ (std net ssl) — TCP+TLS via chez-ssl │ +│ (std net ssl) — TCP+TLS via chez-ssl (legacy) │ │ (jerboa core) — match, def, defstruct │ └──────────────────────────────────────────────────────┘ ``` @@ -3426,7 +3426,7 @@ Implementation checklist: **File**: `lib/std/actor/transport.sls` **Test**: `tests/test-actor-transport.ss` -**Dependencies**: `core.sls`, `(std net ssl)` (chez-ssl fd-based TCP) +**Dependencies**: `core.sls`, `(std net ssl)` (chez-ssl fd-based TCP — legacy, no Rust replacement yet) Implementation checklist: - [x] `message->bytes` serializes to 4-byte-length-prefixed fasl bytevector @@ -3451,7 +3451,7 @@ Implementation checklist: remote `(id node)` branches took 2 args. Fixed remote to take 3 args `(id node 'remote)` so `case-lambda` dispatch works correctly. -**Note**: TCP integration uses `(std net ssl)` / `chez-ssl` fd-based API: +**Note**: TCP integration uses `(std net ssl)` / `chez-ssl` fd-based API (legacy — no Rust replacement yet): `tcp-connect`, `tcp-listen`, `tcp-accept`, `tcp-read`, `tcp-write`, `tcp-close`. Run tests from the `chez-ssl` directory (or with full .so path) so `chez_ssl_shim.so` loads. @@ -3547,7 +3547,7 @@ JSON would require explicit conversion for every message type. ### Why cookie authentication instead of TLS client certs? Cookie auth (shared secret) is simpler to set up and sufficient for a trusted -private network. TLS with chez-ssl can be layered on top for encryption without +private network. TLS via chez-ssl (legacy) can be layered on top for encryption without changing the authentication model. ### Why monitors instead of links for supervision? --- a/docs/architecture-split.md +++ b/docs/architecture-split.md @@ -41,21 +41,27 @@ Examples of what belongs here: ## Current Inventory -### Correctly placed in chez-* (FFI shims) +### Replaced by Rust native backend (`libjerboa_native.so`) -These are pure C glue — no logic beyond marshaling: +These chez-* C FFI shims have Rust replacements in `jerboa-native-rs/`. The Rust modules are the recommended backend; the chez-* modules remain as legacy fallbacks. + +| chez-* (legacy) | Rust replacement | Jerboa module | +|------------------|-----------------|---------------| +| chez-crypto (OpenSSL) | ring | `(std crypto native-rust)` | +| chez-zlib (libz) | flate2 | `(std compress native-rust)` | +| chez-pcre2 (libpcre2) | regex (NFA, ReDoS-immune) | `(std regex-native)` | +| chez-sqlite (libsqlite3) | rusqlite (bundled) | `(std db sqlite-native)` | +| chez-postgresql (libpq) | rust-postgres | `(std db postgresql-native)` | +| chez-epoll (syscalls) | libc (Rust) | `(std os epoll-native)` | +| chez-inotify (syscalls) | libc (Rust) | `(std os inotify-native)` | +| — (landlock-shim.c) | libc (Rust) | `(std os landlock-native)` | + +### Still chez-* only (no Rust replacement yet) | Library | C Library | What It Does | |---------|-----------|-------------| -| chez-ssl | OpenSSL | `ssl-connect`, `ssl-read`, `ssl-write` — direct SSL_* calls | -| chez-zlib | zlib | `gzip-bytevector`, `gunzip-bytevector` — direct compress/uncompress | -| chez-crypto | OpenSSL libcrypto | Hash, HMAC, cipher, Ed25519 — direct EVP_* calls | -| chez-sqlite | SQLite3 | `sqlite-open`, `sqlite-exec`, `sqlite-prepare` — direct sqlite3_* calls | -| chez-postgresql | libpq | `pg-connect`, `pg-exec` — direct PQ* calls | +| chez-ssl | OpenSSL | `ssl-connect`, `ssl-read`, `ssl-write` — direct SSL_* calls (rustls-ffi planned) | | chez-leveldb | LevelDB | `leveldb-open`, `leveldb-put`, `leveldb-get` — direct C API | -| chez-pcre2 | PCRE2 | `pcre2-compile`, `pcre2-match` — direct pcre2_* calls | -| chez-epoll | Linux kernel | `epoll-create`, `epoll-wait` — direct syscalls | -| chez-inotify | Linux kernel | `inotify-init`, `inotify-add-watch` — direct syscalls | | chez-scintilla | Scintilla | Editor widget message passing — direct Scintilla API | | chez-qt | Qt6 | Widget creation, signals/slots — direct Qt C++ shim | --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,8 @@ Updated 2026-03-22. - [whats-new.md](whats-new.md) — What's new: 33 modules added in latest push - [whatsnew.md](whatsnew.md) — Earlier additions: translator enhancements and initial stdlib - [pending.md](pending.md) — Roadmap: what's left to make Jerboa better -- [architecture-split.md](architecture-split.md) — Design: chez-* (FFI shims) vs jerboa (application logic) +- [architecture-split.md](architecture-split.md) — Design: Rust native / chez-* (FFI backends) vs jerboa (application logic) +- [native-rust.md](native-rust.md) — Rust native library: architecture, migration status, C ABI design - [rocks.md](rocks.md) — Distribution and packaging ## Security --- a/docs/native-rust.md +++ b/docs/native-rust.md @@ -1,6 +1,6 @@ # Replacing C Dependencies with a Unified Rust Native Library -Replace Jerboa's 10+ C library dependencies with a single Rust shared library. Every C library Jerboa currently links becomes a Rust crate with memory safety, no backtracking, and audited implementations — callable from Chez Scheme via the same `foreign-procedure` FFI. +Jerboa's C library dependencies are being replaced with a single Rust shared library (`libjerboa_native.so`). Rust implementations are complete for crypto, compression, regex, databases, and OS integration. TLS (rustls) and LevelDB are still pending. The legacy chez-* C wrappers remain available as fallbacks. Every Rust module is callable from Chez Scheme via the same `foreign-procedure` FFI. --- @@ -753,27 +753,29 @@ The result is a single binary with zero runtime dependencies beyond libc — Che ## Migration Strategy -### Phase 1: Parallel Installation +### Current Status -Both C libraries and the Rust library are available. Jerboa modules detect which is present and choose: +We are in **Phase 1** (parallel installation). The Rust implementations are complete for crypto, compression, regex, databases (SQLite, PostgreSQL), and OS integration (epoll, inotify, landlock). However, the "default" modules (e.g., `(std db sqlite)`, `(std crypto cipher)`) still import from chez-* C libraries. The Rust-backed modules are available as separate imports (e.g., `(std db sqlite-native)`, `(std crypto native-rust)`). + +**TLS is deferred** — `(std net ssl)` still requires chez-ssl / OpenSSL. The rustls-ffi integration is planned but not yet implemented due to the complexity of stateful TLS session management. + +### Phase 1: Parallel Installation (CURRENT) + +Both C libraries and the Rust library are available as separate modules. New code should prefer the `-native` / `native-rust` modules: ```scheme -(define use-native-crypto? - (guard (e [#t #f]) - (load-shared-object "libjerboa_native.so") - #t)) - -(define sha256 - (if use-native-crypto? - jerboa-native-sha256 ;; Rust ring - openssl-sha256)) ;; C libcrypto +;; Preferred — uses Rust ring via libjerboa_native.so +(import (std crypto native-rust)) + +;; Legacy — uses OpenSSL via chez-crypto +(import (std crypto cipher)) ``` This allows incremental testing — run the full test suite against both backends and compare results. ### Phase 2: Native-First -The Rust library becomes the default. C libraries are the fallback for platforms where Rust isn't available (rare — Rust supports all major platforms). +The Rust library becomes the default import for all modules that have Rust replacements. The chez-* modules become explicitly legacy. ### Phase 3: C Removal --- a/docs/pending.md +++ b/docs/pending.md @@ -4,7 +4,7 @@ Last updated: 2026-03-22. ## Current State -500 modules, ~123K lines, 2,900+ tests, 13 fuzz harnesses. Full Gerbil API surface on stock Chez Scheme. 15 chez-* companion libraries. A complete editor (jerboa-emacs) with TUI + Qt, Org-mode, LSP, Git. +500 modules, ~123K lines, 2,900+ tests, 13 fuzz harnesses. Full Gerbil API surface on stock Chez Scheme. Rust native backend (`libjerboa_native.so`) for crypto, compression, regex, databases, and OS integration. Legacy chez-* C FFI shims still available as fallbacks. A complete editor (jerboa-emacs) with TUI + Qt, Org-mode, LSP, Git. --- @@ -27,7 +27,7 @@ Jerboa keeps thin `(std srfi srfi-N)` re-export wrappers for namespace/conflict ### Integrate Remaining chez-* Libraries -Three chez-* libraries are built and tested but not in jerboa's Makefile: +Most chez-* C FFI libraries have been superseded by the Rust native backend (see `docs/native-rust.md`). The remaining chez-* libraries that still need integration: | Library | Integration | |---------|------------| @@ -37,6 +37,13 @@ Three chez-* libraries are built and tested but not in jerboa's Makefile: `chez-ssh` is done — protocol logic split into `(std net ssh ...)` (10 modules, 3,132 lines), FFI stays in `(chez-ssh crypto)`. +### Complete Rust Native Migration + +Move remaining modules from chez-* to Rust native: +- **TLS**: `(std net ssl)` still uses chez-ssl / OpenSSL — need rustls-ffi integration +- **LevelDB**: `(std db leveldb)` still uses chez-leveldb — need rusty-leveldb or sled +- **Default imports**: Main modules (e.g., `(std db sqlite)`) still import from chez-* — need to rewire to `-native` modules + ### Web Framework `(std net httpd)`, `(std net router)`, `(std text json)`, `(std db sqlite)`, `(std db conpool)`, `(std net websocket)`, `(std net rate)`, `(std net security-headers)` all exist. Glue them into `(std web)`: @@ -49,7 +56,7 @@ Three chez-* libraries are built and tested but not in jerboa's Makefile: ### Database Migrations -`(std db migrate)` — numbered migration files, up/down, tracking table. Works with both chez-sqlite and chez-postgresql. +`(std db migrate)` — numbered migration files, up/down, tracking table. Works with both SQLite and PostgreSQL (via Rust native or legacy chez-* backends). --- @@ -84,7 +91,7 @@ Instrument mutex/hashtable operations, detect happens-before violations, report The current CLAUDE.md is oriented toward Gerbil MCP tools. It should also have: - Jerboa-specific patterns and idioms - Common R6RS gotchas (definition context, phase separation) -- Which chez-* library to use for what +- Which backend to use (Rust native vs legacy chez-*) for what - How jerboa's module namespace maps to Gerbil's - Testing conventions @@ -107,4 +114,4 @@ Things that would be cool but aren't blocking anything: - **Windows graceful degradation** — security modules warn instead of crash on non-Linux - **WASM Chez** — run jerboa in the browser (experimental territory) - **jemacs inline eval** — evaluate expression in buffer, show result inline (REPL-driven development) -- **jemacs package browser** — browse chez-* libraries from the editor +- **jemacs package browser** — browse available libraries (Rust native + chez-*) from the editor --- a/docs/security-reference.md +++ b/docs/security-reference.md @@ -349,19 +349,19 @@ Reads directly from `/dev/urandom`. Never uses Chez's `(random N)` for security ### Digests -- `(std crypto digest)` and `(std crypto native)` -Via OpenSSL libcrypto FFI: MD5, SHA-1, SHA-256, SHA-384, SHA-512. +Via OpenSSL libcrypto FFI (legacy) or Rust ring (recommended): MD5, SHA-1, SHA-256, SHA-384, SHA-512. ### HMAC -- `(std crypto hmac)` and `(std crypto native)` -HMAC-SHA256 via OpenSSL EVP interface. +HMAC-SHA256 via OpenSSL EVP interface (legacy) or Rust ring (recommended). ### AEAD -- `(std crypto aead)` -AES-256-GCM via OpenSSL EVP: `aead-encrypt`, `aead-decrypt`, `aead-key-generate`. 12-byte IV, 16-byte tag. +AES-256-GCM via OpenSSL EVP (legacy) or Rust ring (recommended): `aead-encrypt`, `aead-decrypt`, `aead-key-generate`. 12-byte IV, 16-byte tag. -### Rust-backed crypto -- `(std crypto native-rust)` +### Rust-backed crypto (recommended) -- `(std crypto native-rust)` -Drop-in replacement using `ring` via `libjerboa_native.so` (Rust). No OpenSSL dependency. +Recommended backend using `ring` via `libjerboa_native.so` (Rust). No OpenSSL dependency. Build with `make native`. | Function | Description | |----------|-------------| @@ -380,11 +380,11 @@ Available via `(std crypto native-rust)`. Useful when AES-NI hardware is unavail ### scrypt KDF -Available via both `(std crypto kdf)` (wraps `chez-crypto`) and `(std crypto native-rust)` (`rust-scrypt`). +Available via both `(std crypto kdf)` (wraps `chez-crypto` — legacy) and `(std crypto native-rust)` (`rust-scrypt` — recommended). ### Password hashing -- `(std crypto password)` -PBKDF2-HMAC-SHA256 via OpenSSL. 600,000 iterations default (OWASP 2023 recommendation). +PBKDF2-HMAC-SHA256 via OpenSSL (legacy) or Rust ring (recommended). 600,000 iterations default (OWASP 2023 recommendation). - `password-hash` -- derive hash from password + salt - `password-verify` -- constant-time verification @@ -442,7 +442,7 @@ These modules are implemented but not covered in depth above. These are known gaps. They are not on any roadmap in this document -- just honest statements about what does not exist. - **No formal verification.** The security modules are tested but not formally proved. No Coq/Isabelle/ACL2 proofs exist. -- **No FIPS 140-3 validation.** The crypto uses OpenSSL or ring, which can be FIPS-validated, but Jerboa itself has not undergone FIPS evaluation. +- **No FIPS 140-3 validation.** The crypto uses ring (recommended) or OpenSSL (legacy), which can be FIPS-validated, but Jerboa itself has not undergone FIPS evaluation. - **No covert channel analysis.** Chez Scheme's GC is a timing side channel. No mitigation exists for timing, storage, or resource-exhaustion covert channels. - **No Common Criteria evaluation.** No Protection Profile, Security Target, or EAL evaluation has been performed. - **Seccomp is x86_64 only.** The BPF bytecode generator hardcodes `AUDIT_ARCH_X86_64` and x86_64 syscall numbers. @@ -452,7 +452,7 @@ These are known gaps. They are not on any roadmap in this document -- just hones - **No TOCTOU-safe path checking.** `canonicalize-path` uses `realpath(3)` before access, not `O_NOFOLLOW` + `/proc/self/fd/N` after open. - **`define-syntax` remains in the sandbox allowlist.** Macro definition in sandboxed code is possible. Whether this is a risk depends on the use case. - **No max-output-size for sandboxes.** A sandboxed expression can produce unbounded output via `display`/`write`. -- **No Argon2id.** Password hashing uses PBKDF2 (universally available via OpenSSL) rather than Argon2id (requires separate library). +- **No Argon2id.** Password hashing uses PBKDF2 (via OpenSSL or Rust ring) rather than Argon2id (requires separate library). - **FFI audit (Phase 5 of parser hardening) is not started.** Null return checks, type validation, and SQL injection lint rules are unimplemented. - **No red team evaluation.** No independent adversarial testing has been performed. - **Secure memory is outside GC.** The `with-secure-region` API requires manual pointer arithmetic via `foreign-ref`/`foreign-set!`. There is no high-level typed interface.