From f8c16e394d96d7291639252857d27b6051f50b36 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Wed, 11 Dec 2024 17:06:26 -0500 Subject: [PATCH] Stabilize ML-KEM; bump to v1.12.0 --- aws-lc-rs/Cargo.toml | 4 +- aws-lc-rs/Makefile | 12 ++-- aws-lc-rs/src/kem.rs | 114 +++++++++++++--------------------- aws-lc-rs/src/unstable/kem.rs | 57 +++-------------- 4 files changed, 56 insertions(+), 131 deletions(-) diff --git a/aws-lc-rs/Cargo.toml b/aws-lc-rs/Cargo.toml index 3a74ce7698c..c3f1c895a63 100644 --- a/aws-lc-rs/Cargo.toml +++ b/aws-lc-rs/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "aws-lc-rs" authors = ["AWS-LibCrypto"] -version = "1.11.1" +version = "1.12.0" # this crate re-exports whatever sys crate that was selected -links = "aws_lc_rs_1_11_1_sys" +links = "aws_lc_rs_1_12_0_sys" edition = "2021" rust-version = "1.63.0" keywords = ["crypto", "cryptography", "security"] diff --git a/aws-lc-rs/Makefile b/aws-lc-rs/Makefile index 38a431ceaf8..f60c8de1268 100644 --- a/aws-lc-rs/Makefile +++ b/aws-lc-rs/Makefile @@ -32,14 +32,12 @@ test: cargo test --all-targets --features unstable cargo test --release --all-targets cargo test --release --all-targets --features bindgen,unstable -ifeq ($(UNAME_S),Linux) cargo test --release --all-targets --features fips,unstable - cargo test --no-default-features --features fips,unstable -endif - cargo test --no-default-features --features aws-lc-sys,unstable - cargo test --no-default-features --features aws-lc-sys,ring-sig-verify,unstable - cargo test --no-default-features --features aws-lc-sys,ring-io,unstable - cargo test --no-default-features --features aws-lc-sys,alloc,unstable + cargo test --no-default-features --all-targets --features fips,unstable + cargo test --no-default-features --all-targets --features aws-lc-sys,unstable + cargo test --no-default-features --all-targets --features aws-lc-sys,ring-sig-verify,unstable + cargo test --no-default-features --all-targets --features aws-lc-sys,ring-io,unstable + cargo test --no-default-features --all-targets --features aws-lc-sys,alloc,unstable msrv: cargo msrv verify diff --git a/aws-lc-rs/src/kem.rs b/aws-lc-rs/src/kem.rs index 121ea24774e..f4aad43d6ea 100644 --- a/aws-lc-rs/src/kem.rs +++ b/aws-lc-rs/src/kem.rs @@ -12,7 +12,7 @@ //! ```ignore //! use aws_lc_rs::{ //! kem::{Ciphertext, DecapsulationKey, EncapsulationKey}, -//! unstable::kem::{ML_KEM_512} +//! kem::{ML_KEM_512} //! }; //! //! // Alice generates their (private) decapsulation key. @@ -60,65 +60,48 @@ use aws_lc::{ use core::{cmp::Ordering, ptr::null_mut}; use zeroize::Zeroize; -#[cfg(not(feature = "fips"))] -pub(crate) mod semistable { - #![allow(unused)] - - use super::{Algorithm, AlgorithmId}; - - const ML_KEM_512_SHARED_SECRET_LENGTH: usize = 32; - const ML_KEM_512_PUBLIC_KEY_LENGTH: usize = 800; - const ML_KEM_512_SECRET_KEY_LENGTH: usize = 1632; - const ML_KEM_512_CIPHERTEXT_LENGTH: usize = 768; - - const ML_KEM_768_SHARED_SECRET_LENGTH: usize = 32; - const ML_KEM_768_PUBLIC_KEY_LENGTH: usize = 1184; - const ML_KEM_768_SECRET_KEY_LENGTH: usize = 2400; - const ML_KEM_768_CIPHERTEXT_LENGTH: usize = 1088; - - const ML_KEM_1024_SHARED_SECRET_LENGTH: usize = 32; - const ML_KEM_1024_PUBLIC_KEY_LENGTH: usize = 1568; - const ML_KEM_1024_SECRET_KEY_LENGTH: usize = 3168; - const ML_KEM_1024_CIPHERTEXT_LENGTH: usize = 1568; - - /// NIST FIPS 203 ML-KEM-512 algorithm. - pub const ML_KEM_512: Algorithm = Algorithm { - id: AlgorithmId::MlKem512, - decapsulate_key_size: ML_KEM_512_SECRET_KEY_LENGTH, - encapsulate_key_size: ML_KEM_512_PUBLIC_KEY_LENGTH, - ciphertext_size: ML_KEM_512_CIPHERTEXT_LENGTH, - shared_secret_size: ML_KEM_512_SHARED_SECRET_LENGTH, - }; - - /// NIST FIPS 203 ML-KEM-768 algorithm. - pub const ML_KEM_768: Algorithm = Algorithm { - id: AlgorithmId::MlKem768, - decapsulate_key_size: ML_KEM_768_SECRET_KEY_LENGTH, - encapsulate_key_size: ML_KEM_768_PUBLIC_KEY_LENGTH, - ciphertext_size: ML_KEM_768_CIPHERTEXT_LENGTH, - shared_secret_size: ML_KEM_768_SHARED_SECRET_LENGTH, - }; +const ML_KEM_512_SHARED_SECRET_LENGTH: usize = 32; +const ML_KEM_512_PUBLIC_KEY_LENGTH: usize = 800; +const ML_KEM_512_SECRET_KEY_LENGTH: usize = 1632; +const ML_KEM_512_CIPHERTEXT_LENGTH: usize = 768; + +const ML_KEM_768_SHARED_SECRET_LENGTH: usize = 32; +const ML_KEM_768_PUBLIC_KEY_LENGTH: usize = 1184; +const ML_KEM_768_SECRET_KEY_LENGTH: usize = 2400; +const ML_KEM_768_CIPHERTEXT_LENGTH: usize = 1088; + +const ML_KEM_1024_SHARED_SECRET_LENGTH: usize = 32; +const ML_KEM_1024_PUBLIC_KEY_LENGTH: usize = 1568; +const ML_KEM_1024_SECRET_KEY_LENGTH: usize = 3168; +const ML_KEM_1024_CIPHERTEXT_LENGTH: usize = 1568; + +/// NIST FIPS 203 ML-KEM-512 algorithm. +pub const ML_KEM_512: Algorithm = Algorithm { + id: AlgorithmId::MlKem512, + decapsulate_key_size: ML_KEM_512_SECRET_KEY_LENGTH, + encapsulate_key_size: ML_KEM_512_PUBLIC_KEY_LENGTH, + ciphertext_size: ML_KEM_512_CIPHERTEXT_LENGTH, + shared_secret_size: ML_KEM_512_SHARED_SECRET_LENGTH, +}; - /// NIST FIPS 203 ML-KEM-1024 algorithm. - pub const ML_KEM_1024: Algorithm = Algorithm { - id: AlgorithmId::MlKem1024, - decapsulate_key_size: ML_KEM_1024_SECRET_KEY_LENGTH, - encapsulate_key_size: ML_KEM_1024_PUBLIC_KEY_LENGTH, - ciphertext_size: ML_KEM_1024_CIPHERTEXT_LENGTH, - shared_secret_size: ML_KEM_1024_SHARED_SECRET_LENGTH, - }; -} +/// NIST FIPS 203 ML-KEM-768 algorithm. +pub const ML_KEM_768: Algorithm = Algorithm { + id: AlgorithmId::MlKem768, + decapsulate_key_size: ML_KEM_768_SECRET_KEY_LENGTH, + encapsulate_key_size: ML_KEM_768_PUBLIC_KEY_LENGTH, + ciphertext_size: ML_KEM_768_CIPHERTEXT_LENGTH, + shared_secret_size: ML_KEM_768_SHARED_SECRET_LENGTH, +}; -#[cfg(feature = "fips")] -mod missing_nid { - pub const NID_MLKEM512: i32 = 988; - pub const NID_MLKEM768: i32 = 989; - pub const NID_MLKEM1024: i32 = 990; -} +/// NIST FIPS 203 ML-KEM-1024 algorithm. +pub const ML_KEM_1024: Algorithm = Algorithm { + id: AlgorithmId::MlKem1024, + decapsulate_key_size: ML_KEM_1024_SECRET_KEY_LENGTH, + encapsulate_key_size: ML_KEM_1024_PUBLIC_KEY_LENGTH, + ciphertext_size: ML_KEM_1024_CIPHERTEXT_LENGTH, + shared_secret_size: ML_KEM_1024_SHARED_SECRET_LENGTH, +}; -#[cfg(feature = "fips")] -use self::missing_nid::{NID_MLKEM1024, NID_MLKEM512, NID_MLKEM768}; -#[cfg(not(feature = "fips"))] use aws_lc::{NID_MLKEM1024, NID_MLKEM512, NID_MLKEM768}; /// An identifier for a KEM algorithm. @@ -192,9 +175,6 @@ where } /// Identifier for a KEM algorithm. -/// -/// See [`crate::unstable::kem::AlgorithmId`] and [`crate::unstable::kem::get_algorithm`] for -/// access to algorithms not subject to semantic versioning guarantees. #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq)] pub enum AlgorithmId { @@ -529,15 +509,10 @@ fn kem_key_generate(nid: i32) -> Result, Unspecified> { #[cfg(test)] mod tests { use super::{Ciphertext, SharedSecret}; - - #[cfg(not(feature = "fips"))] - use crate::error::KeyRejected; - - #[cfg(not(feature = "fips"))] use super::{DecapsulationKey, EncapsulationKey}; + use crate::error::KeyRejected; - #[cfg(not(feature = "fips"))] - use crate::kem::semistable::{ML_KEM_1024, ML_KEM_512, ML_KEM_768}; + use crate::kem::{ML_KEM_1024, ML_KEM_512, ML_KEM_768}; #[test] fn ciphertext() { @@ -559,7 +534,6 @@ mod tests { } #[test] - #[cfg(not(feature = "fips"))] fn test_kem_serialize() { for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] { let priv_key = DecapsulationKey::generate(algorithm).unwrap(); @@ -579,7 +553,6 @@ mod tests { } #[test] - #[cfg(not(feature = "fips"))] fn test_kem_wrong_sizes() { for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] { let too_long_bytes = vec![0u8; algorithm.encapsulate_key_size() + 1]; @@ -599,7 +572,6 @@ mod tests { } #[test] - #[cfg(not(feature = "fips"))] fn test_kem_e2e() { for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] { let priv_key = DecapsulationKey::generate(algorithm).unwrap(); @@ -619,7 +591,6 @@ mod tests { } #[test] - #[cfg(not(feature = "fips"))] fn test_serialized_kem_e2e() { for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] { let priv_key = DecapsulationKey::generate(algorithm).unwrap(); @@ -648,7 +619,6 @@ mod tests { } #[test] - #[cfg(not(feature = "fips"))] fn test_debug_fmt() { let private = DecapsulationKey::generate(&ML_KEM_512).expect("successful generation"); assert_eq!( diff --git a/aws-lc-rs/src/unstable/kem.rs b/aws-lc-rs/src/unstable/kem.rs index 60ae941154a..3f5c0ea4015 100644 --- a/aws-lc-rs/src/unstable/kem.rs +++ b/aws-lc-rs/src/unstable/kem.rs @@ -1,58 +1,14 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -//! Unstable KEM Algorithms for usage with the [`crate::kem`] module. -//! -//! # ⚠️ Warning -//! Algorithms contained in this module are subject to changes, relocation, -//! or removal across minor releases, and thus are not subject to semantic versioning policies. -//! -//! # Example -//! -//! ```ignore -//! use aws_lc_rs::{ -//! kem::{Ciphertext, DecapsulationKey, EncapsulationKey}, -//! unstable::kem::{ML_KEM_512} -//! }; -//! -//! // Alice generates their (private) decapsulation key. -//! let decapsulation_key = DecapsulationKey::generate(&ML_KEM_512)?; -//! -//! // Alices computes the (public) encapsulation key. -//! let encapsulation_key = decapsulation_key.encapsulation_key()?; -//! -//! let encapsulation_key_bytes = encapsulation_key.key_bytes()?; -//! -//! // Alice sends the encapsulation key bytes to bob through some -//! // protocol message. -//! let encapsulation_key_bytes = encapsulation_key_bytes.as_ref(); -//! -//! // Bob constructs the (public) encapsulation key from the key bytes provided by Alice. -//! let retrieved_encapsulation_key = EncapsulationKey::new(&ML_KEM_512, encapsulation_key_bytes)?; -//! -//! // Bob executes the encapsulation algorithm to to produce their copy of the secret, and associated ciphertext. -//! let (ciphertext, bob_secret) = retrieved_encapsulation_key.encapsulate()?; -//! -//! // Alice receives ciphertext bytes from bob -//! let ciphertext_bytes = ciphertext.as_ref(); -//! -//! // Bob sends Alice the ciphertext computed from the encapsulation algorithm, Alice runs decapsulation to derive their -//! // copy of the secret. -//! let alice_secret = decapsulation_key.decapsulate(Ciphertext::from(ciphertext_bytes))?; -//! -//! // Alice and Bob have now arrived to the same secret -//! assert_eq!(alice_secret.as_ref(), bob_secret.as_ref()); -//! -//! # Ok::<(), aws_lc_rs::error::Unspecified>(()) -//! ``` - +#![allow(deprecated)] use core::fmt::Debug; use crate::kem::Algorithm; use aws_lc::{NID_KYBER1024_R3, NID_KYBER512_R3, NID_KYBER768_R3}; -#[cfg(not(feature = "fips"))] -pub use crate::kem::semistable::{ML_KEM_1024, ML_KEM_512, ML_KEM_768}; +#[deprecated(note = "use aws_lc_rs::kem::{ML_KEM_512, ML_KEM_768, ML_KEM_1024}")] +pub use crate::kem::{ML_KEM_1024, ML_KEM_512, ML_KEM_768}; // Key lengths defined as stated on the CRYSTALS website: // https://pq-crystals.org/kyber/ @@ -108,15 +64,15 @@ const KYBER1024_R3: Algorithm = Algorithm { #[derive(Clone, Copy, Debug, PartialEq)] pub enum AlgorithmId { /// NIST Round 3 submission of the Kyber-512 algorithm. - #[deprecated] + #[deprecated(note = "use aws_lc_rs:kem::ML_KEM_512")] Kyber512_R3, /// NIST Round 3 submission of the Kyber-768 algorithm. - #[deprecated] + #[deprecated(note = "use aws_lc_rs:kem::ML_KEM_768")] Kyber768_R3, /// NIST Round 3 submission of the Kyber-1024 algorithm. - #[deprecated] + #[deprecated(note = "use aws_lc_rs:kem::ML_KEM_1024")] Kyber1024_R3, } @@ -255,6 +211,7 @@ mod tests { } #[test] + fn test_debug_fmt() { let alg = get_algorithm(AlgorithmId::Kyber512_R3).expect("algorithm retrievable"); let private = DecapsulationKey::generate(alg).expect("successful generation");