Introduction
aws-lc-rs is a cryptographic library using AWS Libcrypto (AWS-LC) for its cryptographic operations. This library strives to be API-compatible with the popular Rust library named ring (v0.16). It uses one of our auto-generated Foreign Function Interface (FFI) crates (either aws-lc-sys or aws-lc-fips-sys) for binding to AWS-LC for the cryptographic implementations.
Motivation
Rust developers increasingly need to deploy applications that meet US and Canadian government cryptographic requirements. We evaluated how to deliver FIPS validated cryptography in idiomatic and performant Rust, built around our AWS-LC offering. We found that the popular ring library fulfilled much of the cryptographic needs in the Rust community, but it did not meet the needs of developers with FIPS requirements. Our intention is to contribute a drop-in replacement for ring that provides FIPS support and is compatible with the ring (v0.16) API. Rust developers with prescribed cryptographic requirements can seamlessly integrate aws-lc-rs into their applications and deploy them into AWS Regions.
Questions, Feedback and Contributing
We use GitHub Issues for managing feature requests, bug reports, or questions about aws-lc-rs API usage.
Otherwise, if you think you might have found a security impacting issue, please instead follow our Security Notification Process below.
Security Notification Process
If you discover a potential security issue in AWS-LC or aws-lc-rs, we ask that you notify AWS Security via our vulnerability reporting page. Please do not create a public GitHub issue.
If you package or distribute aws-lc-rs, or use aws-lc-rs as part of a large multi-user service, you may be eligible for pre-notification of future aws-lc-rs releases. Please contact aws-lc-pre-notifications@amazon.com.
License
aws-lc-rs is licensed under the Apache-2.0 or the ISC License. The aws-lc-sys and aws-lc-fips-sys libraries contain code from AWS-LC and are licensed under the ISC AND ( Apache-2.0 OR ISC ) AND OpenSSL licenses.
Requirements
This page outlines the requirements for using aws-lc-rs on each target platform.
aws-lc-rs uses aws-lc-sys or aws-lc-fips-sys to provide raw FFI bindings to AWS-LC. Thus,
there are additional build tools required for building these crates into your Rust application.
Quick Summary
| Build Type | C/C++ Compiler | CMake | Bindgen | Go |
|---|---|---|---|---|
Non-FIPS (aws-lc-sys) | Required | Never required | Never required | Never required |
FIPS (aws-lc-fips-sys) | Required | Always required | Required* | Always required |
* Bindgen is required for FIPS builds unless the target has pre-generated bindings.
Pre-generated Bindings
Non-FIPS (aws-lc-sys): Pre-generated "universal" bindings are provided that cover all functions
used by aws-lc-rs. These bindings work across all supported platforms, so bindgen is never
required for aws-lc-rs users.
Note: If you take a direct dependency on
aws-lc-sys(not throughaws-lc-rs), it defaults to using the more complete target-specific bindings. See the pre-generated bindings inaws-lc-sys/src/.
FIPS (aws-lc-fips-sys): Pre-generated bindings are available for a limited set of targets.
See aws-lc-fips-sys/src/ for
the list. Bindgen is required for all other targets.
Tested Platforms
A mostly complete set of platforms for which we test our builds can be found in our CI workflow configuration.
Platform-Specific Requirements
Linux Requirements
Build Requirements
Non-FIPS Builds (aws-lc-sys)
For non-FIPS builds on Linux:
- C/C++ Compiler: Required
- CMake: Never required
- Bindgen: Never required (universal pre-generated bindings are provided)
- Go: Never required
FIPS Builds (aws-lc-fips-sys)
For FIPS builds on Linux:
- C/C++ Compiler: Required
- CMake: Always required
- Go: Always required
- Bindgen: Required unless target has pre-generated bindings (see list below)
Targets with Pre-generated FIPS Bindings
The following Linux targets have pre-generated bindings for aws-lc-fips-sys:
aarch64-unknown-linux-gnuaarch64-unknown-linux-muslx86_64-unknown-linux-gnux86_64-unknown-linux-musl
For other Linux targets using FIPS, bindgen is required.
Summary Table
| Platform | default | fips |
|---|---|---|
aarch64-unknown-linux-gnu | C/C++ Compiler | C/C++ Compiler, CMake & Go |
aarch64-unknown-linux-musl | C/C++ Compiler | C/C++ Compiler, CMake & Go |
x86_64-unknown-linux-gnu | C/C++ Compiler | C/C++ Compiler, CMake & Go |
x86_64-unknown-linux-musl | C/C++ Compiler | C/C++ Compiler, CMake & Go |
| Other Linux targets | C/C++ Compiler | C/C++ Compiler, CMake, Go & Bindgen |
C/C++ Compiler
Amazon Linux (AL2023)
sudo dnf groupinstall -y "Development Tools"
Ubuntu (22.04 LTS)
sudo apt-get install -y build-essential
CMake & Go
CMake and Go are only required for FIPS builds.
Amazon Linux (AL2023)
sudo dnf install -y cmake golang
Ubuntu (22.04 LTS)
sudo apt-get install -y cmake golang
Bindgen (FIPS only)
Bindgen is only required for FIPS builds on platforms that do not have pre-generated bindings.
On most platforms, bindgen requires libclang or llvm package to be installed.
See the requirements page in
The bindgen User Guide for instructions.
libclang / LLVM
Amazon Linux (AL2023)
sudo dnf install -y clang-libs
Ubuntu (22.04 LTS)
sudo apt-get install -y libclang1
bindgen-cli
cargo install --force --locked bindgen-cli
Troubleshooting
See our troubleshooting section.
macOS & iOS Requirements
Build Requirements
Non-FIPS Builds (aws-lc-sys)
For non-FIPS builds on macOS and iOS:
- C/C++ Compiler: Required
- CMake: Never required
- Bindgen: Never required (universal pre-generated bindings are provided)
- Go: Never required
FIPS Builds (aws-lc-fips-sys)
For FIPS builds on macOS:
- C/C++ Compiler: Required
- CMake: Always required
- Go: Always required
- Bindgen: Required unless target has pre-generated bindings (see list below)
Note: FIPS is not supported on iOS targets.
Targets with Pre-generated FIPS Bindings
The following macOS targets have pre-generated bindings for aws-lc-fips-sys:
aarch64-apple-darwinx86_64-apple-darwin
Summary Table
| Platform | default | fips |
|---|---|---|
aarch64-apple-darwin | C/C++ Compiler | C/C++ Compiler, CMake & Go |
x86_64-apple-darwin | C/C++ Compiler | C/C++ Compiler, CMake & Go |
aarch64-apple-ios | C/C++ Compiler | Not Supported |
x86_64-apple-ios | C/C++ Compiler | Not Supported |
C/C++ Compiler
Install Command Line Tools for Xcode which provides a C/C++ compiler environment (LLVM).
CMake
CMake is only required for FIPS builds on macOS.
MacPorts
sudo port install cmake
Homebrew
brew install cmake
Go
Go is only required for FIPS builds.
MacPorts
sudo port install go
Homebrew
brew install go
Bindgen (FIPS only)
Bindgen is only required for FIPS builds on platforms that do not have pre-generated bindings.
On most platforms, bindgen requires libclang or llvm package to be installed.
See the requirements page in
The bindgen User Guide for instructions.
MacPorts
sudo port install clang
Homebrew
brew install llvm
bindgen-cli
cargo install --force --locked bindgen-cli
FIPS Build Note
Building with the "fips" feature on macOS will result in the creation of shared libraries (named like
libaws_lc_fips_0_xx_yy_crypto.dylib and libaws_lc_fips_0_xx_yy_rust_wrapper.dylib). These shared libraries will
likely need to be distributed alongside any executable that depends on aws-lc-rs.
Troubleshooting
See our troubleshooting section.
Windows Requirements
Build Requirements
For non-FIPS builds on Windows, the following requirements apply:
| Platform | default | fips |
|---|---|---|
x86_64-pc-windows-msvc | C/C++ Compiler & *NASM | C/C++ Compiler, CMake, NASM, Go & Ninja |
x86_64-pc-windows-gnu | C/C++ Compiler & *NASM | Not Supported |
i686-pc-windows-msvc | C/C++ Compiler & NASM | Not Supported |
aarch64-pc-windows-msvc | C/C++ Compiler (clang-cl) | C/C++ Compiler (clang-cl), CMake, Go & Ninja |
* NASM is recommended on x86-64 but can be avoided using prebuilt NASM objects. See the Prebuilt NASM objects section below.
Note: FIPS builds on Windows also require
bindgen, as there are no pre-generated FIPS bindings for Windows platforms. See Platform Support for more details.
C/C++ Compiler
Use the following instructions to download Visual Studio Build Tools 2017 or later.
- Download the Build Tools for Visual Studio installer.
- Execute the installer.
- If you have an existing installation chose
Modifyon the existing installation. - Under
WorkloadsselectVisual C++ build tools - Under
Individual componentsselectC++/CLI supportC++ CMake tools for Windows
- For ARM64/aarch64 support, also select:
C++ Clang Compiler for WindowsMSBuild support for LLVM (clang-cl) toolset
- Confirm selections and click
Install
Alternative: Clang Compiler
As an alternative to MSVC, you can use the Clang compiler on Windows. This can be useful for cross-compilation scenarios or when using MSYS2/MinGW environments. When using Clang:
- Install LLVM/Clang from LLVM releases or via MSYS2
- Ensure
clangorclang-clis available in your PATH - For MSYS2 environments, the
clang64orucrt64subsystems provide Clang toolchains
CMake
CMake is only required for FIPS builds on Windows.
- Download Windows CMake Installer
- Execute the installer
- Add the CMake installation binary directory to your PATH.
set PATH="C:\Program Files\CMake\bin;%PATH%"
NASM
NASM is required for x86 and x86-64 builds on Windows.
- Download and install the Netwide Assembler (NASM)
- Add the NASM installation directory to your PATH
set PATH="C:\Program Files\NASM;%PATH%"
Prebuilt NASM objects
Important: Prebuilt NASM objects are only available for Windows platforms. They are never used on Linux, macOS, or any other platform.
Important: If a NASM assembler is detected in your build environment, it is always used to compile assembly files. Prebuilt NASM objects are only used as a fallback when NASM is not available.
For Windows x86-64 (non-FIPS builds only), you can avoid installing NASM by using prebuilt NASM objects. The build will use prebuilt objects only when all of the following conditions are met:
- No NASM assembler is found in the build environment
- The "fips" feature is not enabled
- The target is
x86_64-pc-windows-msvcorx86_64-pc-windows-gnu - Either the
AWS_LC_SYS_PREBUILT_NASMenvironment variable is set to1, or theprebuilt-nasmfeature is enabled
To prevent usage of prebuilt NASM objects, install NASM in the build environment and/or set the variable
AWS_LC_SYS_PREBUILT_NASM to 0 in the build environment.
About prebuilt NASM objects
Prebuilt NASM objects are generated using automation similar to the crate provided pregenerated bindings. See the repository's GitHub workflow configuration for more information. The prebuilt NASM objects are checked into the repository and are available for inspection. For each PR submitted, CI verifies that the NASM objects newly built from source match the NASM objects currently in the repository.
No-assembly build
It is possible to avoid the NASM requirement by setting the AWS_LC_SYS_NO_ASM/AWS_LC_FIPS_SYS_NO_ASM environment
variables. However, this severely impacts performance and can only be used for un-optimized/debug builds. See the
notes in our troubleshooting section.
Go
Go is only required for FIPS builds.
- Download and install Go
- Add the Go installation binary directory to your PATH
set PATH="C:\Program Files\Go\bin;%PATH%"
Ninja
Ninja is only required for FIPS builds on Windows.
- Download and install Ninja
- Add the Ninja installation directory to your PATH
set PATH="C:\ninja\ninja_build;%PATH%"
Bindgen (FIPS only)
Bindgen is required for FIPS builds on Windows, as there are no pre-generated FIPS bindings for Windows platforms.
Using bindgen requires libclang or llvm to be installed.
See the requirements page in
The bindgen User Guide for instructions.
libclang / LLVM
- Download LLVM Installer
- Execute the installer
- Update your environment to set
LIBCLANG_PATHto the bin directory inside LLVM install directory.set LIBCLANG_PATH="C:\Program Files\LLVM\bin"
bindgen-cli
cargo install --force --locked bindgen-cli
FIPS Build Note
Building with the "fips" feature on Windows will result in the creation of shared libraries (named like
aws_lc_fips_0_xx_yy_crypto.dll and aws_lc_fips_0_xx_yy_rust_wrapper.dll). These shared libraries will likely need to
be distributed alongside any executable that depends on aws-lc-rs.
Troubleshooting
See our troubleshooting section.
Platform Support
Pre-generated bindings
aws-lc-rs can utilize pre-generated bindings when operating on the following
build targets.
| Platform | aws-lc-sys | aws-lc-fips-sys |
|---|---|---|
aarch64-apple-darwin | ✓ | ✓ |
aarch64-pc-windows-msvc | ✓ | ✓ ² |
aarch64-unknown-linux-gnu | ✓ | ✓ |
aarch64-unknown-linux-musl | ✓ | ✓ |
i686-pc-windows-msvc | ✓ | Not Supported |
i686-unknown-linux-gnu | ✓ | Not Supported |
x86_64-apple-darwin | ✓ | ✓ |
x86_64-pc-windows-gnu | ✓ | Not Supported |
x86_64-pc-windows-msvc | ✓ | ✓ ² |
x86_64-unknown-linux-gnu | ✓ | ✓ |
x86_64-unknown-linux-musl | ✓ | ✓ |
² FIPS is supported but requires bindgen (no pre-generated FIPS bindings are available for Windows platforms)
Tested platforms
In addition to the platforms with pre-generated bindings listed above, aws-lc-rs CI builds and/or tests on many additional platforms.
See our CI workflow configuration for the complete list of tested platforms.
Build Requirements Summary
For non-FIPS builds (aws-lc-sys):
- C/C++ Compiler: Required
- CMake: Never required
- Bindgen: Never required (universal pre-generated bindings are provided)
- Go: Never required
For FIPS builds (aws-lc-fips-sys):
- C/C++ Compiler: Required
- CMake: Always required
- Go: Always required
- Bindgen: Required unless the target has pre-generated bindings (see table above)
Bindgen for FIPS Builds
For FIPS builds on targets without pre-generated bindings, one of the following options must be used for bindings generation. See requirements page for more information.
- Enable
bindgenfeature in yourCargo.toml:
[dependencies]
aws-lc-rs = { version = "1", features = ["bindgen", "fips"] }
-- OR --
- Install
bindgen-cliin the build environment:
cargo install --force --locked bindgen-cli
Linux Platforms
| Platform | Build | Tests | FIPS |
|---|---|---|---|
aarch64-unknown-linux-gnu | ✓ | ✓ | ✓ |
aarch64-unknown-linux-musl | ✓ | ✓ | ✓ |
arm-unknown-linux-gnueabihf | ✓ | ✓ | |
arm-unknown-linux-musleabi | ✓ | ✓ | ✓ |
arm-unknown-linux-musleabihf | ✓ | ✓ | ✓ |
armv7-unknown-linux-gnueabihf | ✓ | ✓ | |
i686-unknown-linux-gnu | ✓ | ✓ | |
mips-unknown-linux-gnu ¹ | ✓ | ✓ | |
mips-unknown-linux-musl ¹ | ✓ | ✓ | |
mips64-unknown-linux-muslabi64 ¹ | ✓ | ✓ | |
mips64el-unknown-linux-muslabi64 ¹ | ✓ | ✓ | |
powerpc-unknown-linux-gnu | ✓ | ✓ | ✓ |
powerpc64-unknown-linux-gnu | ✓ | ✓ | ✓ |
powerpc64le-unknown-linux-gnu | ✓ | ✓ | ✓ |
riscv64gc-unknown-linux-gnu | ✓ | ✓ | |
s390x-unknown-linux-gnu | ✓ | ✓ | |
x86_64-unknown-linux-gnu | ✓ | ✓ | ✓ |
x86_64-unknown-linux-musl | ✓ | ✓ | ✓ |
¹ Requires nightly Rust toolchain
Apple Platforms
| Platform | Build | Tests | FIPS |
|---|---|---|---|
aarch64-apple-darwin | ✓ | ✓ | ✓ |
aarch64-apple-ios | ✓ | ✓ | |
aarch64-apple-ios-sim | ✓ | ✓ | |
aarch64-apple-tvos-sim ¹ | ✓ | ✓ | |
x86_64-apple-darwin | ✓ | ✓ | ✓ |
x86_64-apple-ios | ✓ |
¹ Requires nightly Rust toolchain
Windows Platforms
| Platform | Build | Tests | FIPS |
|---|---|---|---|
aarch64-pc-windows-msvc | ✓ | ✓ | ✓ |
i686-pc-windows-msvc | ✓ | ✓ | |
x86_64-pc-windows-gnu | ✓ | ✓ | |
x86_64-pc-windows-msvc | ✓ | ✓ | ✓ |
Android Platforms
| Platform | Build | Tests |
|---|---|---|
aarch64-linux-android | ✓ | ✓ |
arm-linux-androideabi | ✓ | ✓ |
armv7-linux-androideabi | ✓ | ✓ |
i686-linux-android | ✓ | |
x86_64-linux-android | ✓ |
BSD Platforms
| Platform | Build | Tests | FIPS |
|---|---|---|---|
x86_64-unknown-freebsd | ✓ | ✓ | ✓ |
x86_64-unknown-netbsd | ✓ | ✓ |
Other Platforms
| Platform | Build | Tests |
|---|---|---|
x86_64-unknown-illumos | ✓ | ✓ |
| OpenHarmony (aarch64) | ✓ | |
| OpenWrt (aarch64-musl) | ✓ | |
| Alpine Linux | ✓ | ✓ |
Frequently Asked Questions
What are the differences between aws-lc-rs and ring?
While we aim to be API-compatible with ring v0.16 there are some differences in our implementation. Please review the
ring-compatibility section of our API reference guide.
Can I run aws-lc-rs on X platform or architecture?
The answer to this question is dependent on several factors based on the target environment:
- Must be a platform and CPU architecture supported by AWS-LC.
- Must be a platform supported by the Rust compiler with support for the full standard library. See the Rust compiler's platform support documentation.
- For non-FIPS builds: Bindgen is never required. The
aws-lc-syscrate provides universal pre-generated bindings that cover all functions used byaws-lc-rs. - For FIPS builds: If
aws-lc-fips-sysdoesn't have pre-generated bindings for your target platform, you must use thebindgencrate feature ofaws-lc-rs, or have the bindgen-cli installed, to enable generation of the FFI bindings for the desired platform and architecture.
Note: If you take a direct dependency on
aws-lc-sys(not throughaws-lc-rs) and need access to the complete AWS-LC API, you may want to use target-specific bindings or enable bindgen for complete API coverage.
- See Requirements and Platform Support for more details on build requirements for various platforms.
If there is a platform or architecture you are interested in seeing support for, please create a GitHub issue.
Resources
Build Environment Variables
The aws-lc-sys crate supports several environment variables that can help configure or troubleshoot
the build process. The aws-lc-fips-sys crate supports most of the same environment variables, but
uses an AWS_LC_FIPS_SYS_ prefix instead of AWS_LC_SYS_.
Note: None of the environment variables below are officially supported, and any one of them might be removed or changed in a future release. Please contact us about any bugs you find in our build process.
Target-Specific Variables
Many of these environment variables also support target-specific variants. For example:
AWS_LC_SYS_CFLAGSapplies to all targetsAWS_LC_SYS_CFLAGS_aarch64_unknown_linux_gnuapplies only to theaarch64-unknown-linux-gnutarget
The target-specific variant takes precedence when both are set.
Library Output
-
AWS_LC_SYS_STATIC|AWS_LC_FIPS_SYS_STATICControls whether the build produces a static or shared library.
1- Build as static library (e.g.,*.a)0- Build as shared/dynamic library (e.g.,*.so,*.dylib,*.dll)
Default: static library
Note: For
aws-lc-fips-sys, static library builds are only supported on Linux and BSD targets with x86_64 or aarch64 architectures. On other platforms, FIPS builds to shared libraries.
Build System
-
AWS_LC_SYS_CMAKE_BUILDERControls which build system is used to compile AWS-LC. This option only applies to
aws-lc-sys.1- Force use of CMake0- Force use of thecccrate builder
Default: The
cccrate builder is used by default. CMake is not required foraws-lc-sys.Note: The
aws-lc-fips-syscrate always requires CMake and does not support this option. -
AWS_LC_SYS_NO_PREGENERATED_SRCWhen set to
1, forces the build to generate CMake source files instead of using pre-generated ones.
Bindings Generation
-
AWS_LC_SYS_EXTERNAL_BINDGEN|AWS_LC_FIPS_SYS_EXTERNAL_BINDGENControls whether to use the external
bindgen-clitool for generating bindings.1- Use externalbindgen-cli(must be installed viacargo install bindgen-cli)0- Use internal bindgen or pre-generated bindings
Note: For users of
aws-lc-rs, bindgen is never required.aws-lc-sysprovides universal bindings that work for users ofaws-lc-rsacross all supported platforms. This option is primarily useful for direct consumers ofaws-lc-syswho need complete API bindings on platforms without pre-generated bindings. -
AWS_LC_SYS_NO_PREFIX|AWS_LC_FIPS_SYS_NO_PREFIXWhen set to
1, the build will not apply a unique prefix to the library name or the symbols it contains. This may be useful in certain linking scenarios but can cause symbol conflicts if multiple versions are linked. -
AWS_LC_SYS_NO_U1_BINDINGSWhen set to
1, uses bindings that don't include the\x01prefix on symbol names. This is automatically enabled for certain backends (like Cranelift) and architectures (like MIPS) that don't support the prefixed symbols.
Assembly and Optimization
-
AWS_LC_SYS_NO_ASM|AWS_LC_FIPS_SYS_NO_ASMWhen set to
1, forces the build to use pure C implementations for all cryptographic operations instead of optimized assembly.Note: When using the CMake builder, this option is only available when
OPT_LEVEL = "0". When using thecccrate builder, this option is available for optimization levels 0, 1, and 2.WARNING: Performance on most platforms is extremely limited by this option. Certain security properties, such as resistance to timing attacks, can only be provided when assembly code is used.
-
AWS_LC_SYS_PREBUILT_NASMControls the use of prebuilt NASM objects on Windows x86-64.
1- Allow use of prebuilt NASM objects0- Prevent use of prebuilt NASM objects (requires NASM to be installed)
See the section on Prebuilt NASM objects for more information.
Compiler Configuration
-
AWS_LC_SYS_CC/AWS_LC_SYS_TARGET_CCSpecifies the C compiler to use. Falls back to the standard
CC/TARGET_CCenvironment variables if not set. -
AWS_LC_SYS_CXX/AWS_LC_SYS_TARGET_CXXSpecifies the C++ compiler to use. Falls back to the standard
CXX/TARGET_CXXenvironment variables if not set. -
AWS_LC_SYS_CFLAGS/AWS_LC_SYS_TARGET_CFLAGSAdditional flags to pass to the C compiler during the AWS-LC build. Falls back to
CFLAGS/TARGET_CFLAGSif not set. -
AWS_LC_SYS_C_STDSpecifies the C language standard to use.
99- Use C9911- Use C11
Default: C11 on most platforms.
Entropy Configuration
-
AWS_LC_SYS_NO_JITTER_ENTROPYWhen set to
1, disables the CPU jitter entropy source in the build. This affects the random number generation subsystem. Use of jitter entropy has a one-time-per-process latency cost, typically around 50ms, for the collection of entropy. This flag may be used to eliminate this latency.Note: This option is only available for
aws-lc-sys.
Advanced Options
-
AWS_LC_SYS_EFFECTIVE_TARGETOverrides the target triple string used for certain build decisions. This affects selection of pre-generated bindings.
Note: This variable does not override the underlying Cargo target configuration (
CARGO_CFG_TARGET_*variables). Build decisions that depend ontarget_os(),target_arch(),target_vendor(), ortarget_env()are not affected by this setting. It is primarily useful for selecting different pre-generated bindings or symbol prefixes when building for targets that are compatible with another target's bindings.