Subject
aws-lc-rs 1.17.0 is Amazon's safe-Rust cryptography API, designed to be API-compatible with ring. It exposes AEAD (AES-GCM in several variants, AES-GCM-SIV, ChaCha20-Poly1305), digests (the SHA family), HMAC, HKDF and other KDFs, RSA and EC/Ed25519 signatures, ECDH and X25519 key agreement, KEM, AES key wrap, a CSPRNG, and a post-quantum DSA surface. The crate itself implements no cryptographic algorithm in Rust; it is a typed wrapper plus FFI-marshalling layer over the vendored AWS-LC C library, reached through the aws-lc-sys (default, non-FIPS) or aws-lc-fips-sys (fips feature) dependencies. It serves as a rustls crypto provider, an alternative to ring. The published artifact is about 31K lines of Rust across 95 source files with 354 unsafe occurrences in 48 files, almost all wrapping extern "C" calls into the C library.
Methodology
Tools: openvet 0.6.0, grep, diff, find. I compared the published contents/ tree against the upstream vcs/ checkout (github.com/aws/aws-lc-rs, commit 2201001603bde2dbe326ba47ad77c43a1b29c47c, subdirectory aws-lc-rs). I read the manifest and build.rs in full, the central FFI surfaces in full (the AEAD context construction and seal/open marshalling in src/aead/aead_ctx.rs and src/aead/unbound_key.rs, the pointer-lifetime machinery in src/ptr.rs, the RNG in src/rand.rs, library init in src/lib.rs), and surveyed the capability surface (network, filesystem, process, environment) and zeroize usage across the tree.
Scope. This is a scoped audit. Because the cryptography lives in the vendored AWS-LC C library and there are 354 FFI unsafe blocks, the following claims were not evaluated and are left unasserted, and must not be read as either satisfied or violated: crypto-impl-safe, crypto-impl-correct, crypto-safe, unsafe-safe, unsafe-documented, unsafe-minimal, unsafe-tested. This audit verifies supply-chain integrity (VCS byte-equivalence), the capability surface (uses-*), build-time execution, test presence, the impl-* categorization, dependency enumeration, and a representative review of the FFI marshalling. The uses-environment assertion reflects build-time only: the runtime library code contains no std::env access; build.rs reads several AWS_LC_RS_* and CARGO_CFG_* variables.
Results
The published crate is byte-equivalent to the upstream repository: diff -rq over contents/ and vcs/ shows only the expected normalization differences (the cargo-rewritten Cargo.toml, plus Cargo.lock, Cargo.toml.orig, and .cargo_vcs_info.json present only in the published artifact) and publish-excluded tests/, third_party/, and data/ directories. No source file differs.
The crate is benign (is-benign): a content scan of the published files found zero binary files (has-binaries), no obfuscation, and no network, filesystem, process-spawn, or runtime environment access. uses-network, uses-filesystem, and uses-exec are all false; the single std::fs reference is in a doc comment, not code. It exposes cryptography (uses-crypto) but does not implement it in Rust (impl-crypto is false), and likewise implements no parser, interpreter, JIT, protocol, datastructure, standalone algorithm, or concurrency primitive (impl-parser, impl-interpreter, impl-jit, impl-protocol, impl-datastructure, impl-algorithm, impl-concurrency all false). uses-interpreter and uses-jit are false.
A build.rs is present (has-build-exec), so this crate executes code at build time. The script validates that the fips and non-fips features are not both enabled, selects the sys crate, and emits cargo:rustc-cfg directives; it reads build-time environment (uses-environment, environment-safe) and re-exports the sys crate's DEP_AWS_LC_* version variables. It performs no network access, no filesystem writes, no process spawning, and no code generation, so build-exec-safe, build-exec-no-network, build-exec-no-write-out, build-exec-deterministic, and build-exec-minimal hold. Cargo has no install lifecycle, so has-install-exec is false.
The crate uses unsafe pervasively at the FFI boundary (uses-unsafe). The representative paths reviewed are sound: key length is validated against the algorithm before keys cross into EVP_AEAD_CTX_init (src/aead/aead_ctx.rs:235-275); the seal/open paths enforce input-length bounds and ciphertext/plaintext length equality, document their aliasing contract, and read C-written MaybeUninit<usize> output lengths only after the call reports success (src/aead/unbound_key.rs:126-164,438-473); OPENSSL_malloc results are null-checked through LcPtr::new and freed in Drop, with AWS-LC's free functions zeroizing on free (src/ptr.rs:60-130,222-225); and the RNG passes consistent pointer/length pairs and checks the return code (src/rand.rs:205-210). Secret key material is wiped on drop via the zeroize dependency across IVs, PKCS8 buffers, cipher keys, and HKDF/PBKDF2/KDF/RSA/KEM/TLS-PRF secrets.
Concurrency is limited to one-time thread-safe library initialization through std::sync::Once (src/lib.rs:301-309) plus unsafe impl Send/Sync on the immutable-after-init AEAD context; the crate uses but does not implement a synchronization primitive, so uses-concurrency, concurrency-safe, and concurrency-documented hold while impl-concurrency is false. Tests are 283 inline #[test] functions in #[cfg(test)] modules colocated with the source they exercise (has-unit-tests); the upstream tests/ integration directory is excluded from the published crate, and there is no fuzz or property-test harness, so has-integration-tests, has-fuzz-tests, and has-property-tests are false.
No findings were recorded.
Conclusion
aws-lc-rs 1.17.0 is a typed Rust API and FFI-marshalling layer over the vendored AWS-LC C library; the cryptographic implementation itself is out of crate. The published artifact is byte-equivalent to its upstream tag. Its attack surface in Rust is the FFI boundary: 354 unsafe blocks, no network, no filesystem, no process execution, no runtime environment access, and a small benign build script. The AEAD, RNG, pointer-lifetime, and key-zeroization paths reviewed marshal buffers and key material correctly, with consistent pointer/length pairs, null checks, post-success reads of uninitialized outputs, and zeroize-on-drop for secrets. Cryptographic correctness of the C library and exhaustive review of all 354 FFI blocks were out of scope, as noted in Methodology. No findings were recorded.