# aws-lc-rs, a ring-compatible Rust crypto library with a FIPS path

> aws-lc-rs wraps AWS-LC in a Rust API that aims to be a drop-in replacement for ring 0.16, with the added option of a FIPS backend for US and Canadian government cryptographic requirements. The compatibility claim covers the API surface, not the module, and the FIPS story is still in progress.

**aws/aws-lc-rs** — aws-lc-rs is a cryptographic library using AWS-LC for its cryptographic operations. The library strives to be API-compatible with the popular Rust library named ring.

- Repository: https://github.com/aws/aws-lc-rs
- Stars: 664 · Forks: 152
- Language: Rust
- License: NOASSERTION
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/aws-aws-lc-rs

## A drop-in replacement for ring, with one specific motive

The repository's motivation section is unusually concrete about why this library exists. Rust developers increasingly need to deploy applications that meet US and Canadian government cryptographic requirements, and the project set out to find how to deliver FIPS-validated cryptography in idiomatic and performant Rust. The finding was that ring, at version 0.16, fulfilled much of what the Rust community wanted from a crypto library but did not meet the needs of developers with FIPS requirements.

That single constraint shapes the whole design. The stated intention is to contribute a drop-in replacement for ring that provides FIPS support and is compatible with the ring API, so that developers with prescribed cryptographic requirements can integrate aws-lc-rs into their applications and deploy them into AWS Regions. The README describes the library as striving to be API-compatible with ring 0.16.

API compatibility is the whole product, and it is a narrower claim than it sounds. It means the function signatures, type names and module structure line up so existing call sites compile. It does not mean the underlying module is the same, and it does not mean the FIPS and non-FIPS builds behave identically in every respect, which is exactly the area where a cryptographic module draws boundaries.

The audience is therefore narrow and identifiable: a Rust team that already depends on ring, faces a compliance-driven requirement for validated cryptography, and would rather change a dependency than rewrite its crypto call sites.

## Three crates, and the project asks you not to use two of them

The repository is a Cargo workspace with three public crates, and the naming convention is worth learning before anything else, because the top-level crate and the FIPS crate are alternatives rather than layers.

`aws-lc-rs` is the crate you are meant to depend on. It is the ring-compatible crypto library, and it does the cryptography through AWS-LC using one of the two low-level crates underneath.

`aws-lc-sys` is the autogenerated set of low-level AWS-LC bindings for Rust, and `aws-lc-fips-sys` is the autogenerated set of low-level bindings that provide FIPS support. The project documentation states plainly that it does not recommend directly relying on these bindings. The reason is visible in the layout: they are generated, so they are a thin FFI surface with no stability guarantee attached to it, and the ring-compatible layer is where the supported API lives.

The FIPS crate is where the compliance story sits. It provides bindings to AWS-LC-FIPS 3.x, which the documentation says has completed FIPS validation testing by an accredited lab and has been submitted to NIST for certification. The static build of AWS-LC-FIPS is used for Linux targets.

That last sentence is the part to notice. The static build is for Linux targets, so a team deploying to a platform with a dynamic module has a different artifact and therefore a different validation question. The project points readers at the NIST Cryptographic Module Validation Program's Modules In Progress List for the current status of the static or dynamic AWS-LC Cryptographic Module, and says a complete list of supported operating environments will be made available in the vendor security policy once the validation certificate has been issued. The project also says it will update its release notes and documentation when FIPS certification status changes.

## Building means compiling C and managing submodules

This is not a pure-Rust crate, and the build is the part that surprises people. The workspace depends on cmake, cc, bindgen, pkg-config and untrusted in its shared dependencies, which is the signature of a crate that compiles native C code and generates bindings to it. The build instructions live in the aws-lc-rs crate's own README rather than at the top of the repository, which is a hint about where the practical detail sits.

The repository Makefile is the best map of the workflow, and the submodule handling is the first thing it deals with. The AWS-LC source itself is vendored as a git submodule, so the tree has to be initialized before anything can be built.

```bash
init-submodules:
	git submodule update --init --recursive
```

The `init` target does more than that. It points git at the repository's own hooks directory, adds the rustfmt and clippy components to the toolchain, and installs a set of cargo tools the project uses for its own development, including rust-script, cargo-llvm-cov, cargo-license, public-api, cargo-msrv and cargo-audit.

```bash
init: init-submodules
	git config core.hooksPath .githooks
	rustup component add rustfmt clippy
	cargo install rust-script cargo-llvm-cov cargo-license public-api cargo-msrv --locked
```

The remaining targets are how the project keeps its vendored AWS-LC in step with upstream. There are separate targets to update the FIPS submodule and the regular one, and a combined `update-submodules` target, and the update rule for the non-FIPS subtree fetches all refs and then checks out a tag chosen by a semver tool, so the vendored version is pinned by the project's own versioning script rather than by hand.

Other targets in the same file show the quality gates: `lic` runs cargo-license, `audit` runs cargo-audit in dry-run mode, `format` and `clippy` run the nightly toolchain, and there are two public-api diff targets, one against the main branch and one against the latest published release. That last pair is the mechanism that enforces the compatibility promise the project sells, since a public API diff against `latest` will flag any signature change that would break a ring-compatible consumer.

## The workspace layout shows the testing investment

The top-level entry list is long, and most of it is about verifying a cryptographic library rather than shipping an application. Alongside the three published crates there is an `aws-lc-rs-testing` crate, a `links-testing` crate, a `builder-test` crate, a `builder` directory, a `book` directory, a `docker` directory, a `tests` directory and a `scripts` directory.

The separate testing crates are the interesting part. A `links-testing` crate exists to check the linking behaviour of the native library across configurations, which is the kind of thing that breaks when a project targets several operating systems or several toolchains. A `builder` directory plus a `builder-test` crate means the native build logic is itself a testable component, which matters because a cryptographic library that fails to build on your platform is worthless regardless of its API.

The workspace Cargo.toml also shows a release configuration that is unusual for a library. Beyond the standard workspace members list and a resolver set to 2, it defines both a `[profile.bench]` and a `[profile.release-lto]` section, each enabling link-time optimization, with the release profile inheriting from release. For a crate whose purpose is a drop-in replacement, the shipped artifact is the binding layer over a prebuilt or locally compiled native library, so the Rust-side optimization profile is mostly about the thin glue, but it is a deliberate choice rather than a default.

The toolchain and lint configuration is equally deliberate. The workspace pins the tooling it uses, including bindgen 0.73, cc 1.2.41, cmake 0.1.54, zeroize 1.8.1 and untrusted 0.7.1, and the Makefile's clippy target runs with both `clippy::all` and `clippy::pedantic` warnings enabled across all targets. Pedantic clippy on a security-sensitive crate is a reasonable bar, and it also explains why the codebase needs the style guide that sits alongside the contributing notes.

## A library with a security reporting channel, not an issue tracker

aws-lc-rs documents two different channels for two different kinds of report, and the split is unusual enough to be worth reading carefully.

For anything that is not a security problem, the project points at GitHub Issues with a choice of templates, covering feature requests, bug reports and questions about API usage. There is also a link to the API documentation on docs.rs and an invitation to fork the repository.

For a suspected vulnerability in AWS-LC or aws-lc-rs, the project asks that AWS Security be notified through the AWS vulnerability reporting page, and says explicitly that no public GitHub issue should be created. That is the expected arrangement for a library carrying a validation pedigree, since a public issue would disclose the flaw before a fix ships.

There is a third path that most projects do not have. If you package or distribute aws-lc-rs, or use it as part of a large multi-user service, the project says you may be eligible for pre-notification of future releases, and gives a contact address for that. In practice that means a downstream distributor hears about a security release before the public release, which is a meaningful advantage for anyone shipping a product that embeds it.

For an adopter, that channel arrangement is part of the value proposition. A crypto library that you depend on but do not build, in a product you distribute, benefits from being told about a security fix in advance.

## Version 1.18.x and a fast release cadence

The release record shows a steady stream: v1.18.2 on 2026-10-12, v1.18.1 on 2026-09-01, and v1.17.4 on the same day, 2026-09-01. The last push to the repository was on 2026-10-22, ten days after the 1.18.2 release. The project is not archived and the version numbering shows a project shipping point releases on a regular basis across a 1.x line.

Two releases on one day is a normal pattern for a library that maintains parallel branches, and it also means your dependency update can jump a minor version quickly. Since the crate is a drop-in replacement for a specific ring version, the compatibility you care about is with ring 0.16, and the ring version in the workspace dependencies is listed as 0.17.14 for the project's own testing and benchmarking use.

The upgrade cost for a consumer is shaped by that same promise. If the API really is ring-compatible, a version bump is a routine `cargo update` plus a rebuild of the native library, and the public-api diff target against the latest release is the tool the maintainers use to keep that true. If you have taken a dependency on something outside the ring surface, you will feel the change.

One more constraint belongs here. Because the crate compiles AWS-LC from source or links a prebuilt native library, your build environment needs a C toolchain, CMake and the platform SDK for the targets you ship. The `docker` directory in the repository and the `builder` crate both point at the fact that this is a build-heavy dependency, and teams that assumed a Rust dependency was self-contained will discover otherwise at integration time.

## The licence is a dual grant, and the file decides

The project documentation states that the library is licensed under the Apache-2.0 or the ISC License, and the Makefile header in the repository carries the matching SPDX identifier, `Apache-2.0 OR ISC`. The LICENSE file at the top of the tree is the authoritative text, and the project also ships a NOTICE file alongside it, which is what the Apache-2.0 branch requires when you redistribute.

GitHub's own classification of the repository licence is a custom type it cannot categorize, so do not read anything into that. The reason is visible in the layout: the repository is a Cargo workspace containing several crates, generated bindings and vendored native source, and the classifier cannot pick one label for the tree as a whole. Read the LICENSE file and the NOTICE file to see what obligations attach to the code you actually ship.

For an adopter, the practical licence effect is straightforward. Both Apache-2.0 and ISC are permissive, so you can use the crate in commercial and closed-source products, modify it, and redistribute it, with the obligations being the retention of copyright and licence notices, and, on the Apache-2.0 branch, the marking of modifications and the patent grant. The dual grant lets you pick the terms that suit your distribution model.

There is a detail in the repository that has to be checked rather than assumed. The `aws-lc-sys` and `aws-lc-fips-sys` crates contain generated bindings and point at the AWS-LC source, which is vendored as a submodule with its own licensing. The `lic` Makefile target exists to run cargo-license over the tree, which tells you the project itself treats the license inventory of the workspace as something that needs a tool rather than a reading, and that is where you should look to see exactly which terms ride along with which crate.

## Conclusion

aws-lc-rs suits a Rust team whose deployment environment demands FIPS-validated cryptography and whose codebase already calls ring, because the API compatibility is the point and swapping the backend is the migration. It does not suit a project with no FIPS obligation, where ring itself carries fewer moving parts, and it does not suit anyone who needs a signed validation certificate today, since the AWS-LC-FIPS module has completed lab validation testing and been submitted to NIST but has not yet been certified. Verify first that the FIPS status for your target operating environment is covered by the NIST modules in progress list, that the ring API version your code uses matches the 0.16 surface this library targets, and that the licence file in the repository matches the Apache-2.0 or ISC dual grant the project documentation describes.

## FAQ

### What is the difference between aws-lc-rs and ring in Rust?

aws-lc-rs performs its cryptographic operations with AWS-LC and strives to be API-compatible with ring 0.16, so it is meant to be a drop-in replacement. The motivation section states that ring met most crypto needs in the community but did not meet the needs of developers with FIPS requirements.

### What is the FIPS status of AWS-LC-FIPS?

The project documentation states that AWS-LC-FIPS 3.x has completed FIPS validation testing by an accredited lab and has been submitted to NIST for certification, and it points readers at the NIST Modules In Progress List for the current status of the static or dynamic module. The static build of AWS-LC-FIPS is used for Linux targets.

### Which crate should I depend on, aws-lc-rs or aws-lc-sys?

Depend on aws-lc-rs, the ring-compatible crate. The project documentation calls aws-lc-sys and aws-lc-fips-sys autogenerated low-level bindings and says it does not recommend relying on them directly, since the supported API lives in the layer above.

### How do I report a security issue in aws-lc-rs?

The project asks that you notify AWS Security through the AWS vulnerability reporting page rather than opening a public GitHub issue. Non-security bug reports, feature requests and API usage questions go through GitHub Issues, and distributors of the library may be eligible for pre-notification of future releases.

### What licence does aws-lc-rs use?

The project documentation states that the library is licensed under the Apache-2.0 or the ISC License, and the repository Makefile carries the matching SPDX identifier Apache-2.0 OR ISC. The LICENSE and NOTICE files in the repository are the authoritative text.

## Sources

- [aws/aws-lc-rs on GitHub](https://github.com/aws/aws-lc-rs)
- [Issues](https://github.com/aws/aws-lc-rs/issues)
- [README](https://github.com/aws/aws-lc-rs/blob/main/README.md)
- [Releases](https://github.com/aws/aws-lc-rs/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aws-aws-lc-rs
