diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 68cb459a3dc..9ee0a7b6666 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -149,7 +149,6 @@ jobs: strategy: fail-fast: false matrix: - crate: [ aws-lc-sys, aws-lc-rs ] args: - publish --dry-run steps: @@ -170,8 +169,7 @@ jobs: else exit 0; fi - - name: ${{ matrix.crate }} - working-directory: ./${{ matrix.crate }} + - working-directory: ./aws-lc-sys shell: bash run: AWS_LC_SYS_PREBUILT_NASM=1 cargo publish --dry-run diff --git a/aws-lc-rs-testing/benches/kem_benchmark.rs b/aws-lc-rs-testing/benches/kem_benchmark.rs index afe708156a2..56f9206f4e2 100644 --- a/aws-lc-rs-testing/benches/kem_benchmark.rs +++ b/aws-lc-rs-testing/benches/kem_benchmark.rs @@ -3,20 +3,14 @@ use aws_lc_rs::{ kem::DecapsulationKey, - unstable::kem::{get_algorithm, AlgorithmId}, + kem::{Algorithm, ML_KEM_1024, ML_KEM_512, ML_KEM_768}, }; use criterion::{criterion_group, criterion_main, Criterion}; -#[allow(deprecated)] -const UNSTABLE_ALGORITHMS: &[Option<&aws_lc_rs::kem::Algorithm>] = &[ - get_algorithm(AlgorithmId::Kyber512_R3), - get_algorithm(AlgorithmId::Kyber768_R3), - get_algorithm(AlgorithmId::Kyber1024_R3), -]; +const KEM_ALGORITHMS: &[Algorithm; 3] = &[ML_KEM_512, ML_KEM_768, ML_KEM_1024]; fn bench_kem_keygen(c: &mut Criterion) { - for ele in UNSTABLE_ALGORITHMS { - let ele = ele.unwrap(); + for ele in KEM_ALGORITHMS { let bench_group_name = format!("KEM/{:?}/keygen", ele.id()); let mut group = c.benchmark_group(bench_group_name); group.bench_function("AWS-LC", |b| { @@ -28,8 +22,7 @@ fn bench_kem_keygen(c: &mut Criterion) { } fn bench_kem_encapsulate(c: &mut Criterion) { - for ele in UNSTABLE_ALGORITHMS { - let ele = ele.unwrap(); + for ele in KEM_ALGORITHMS { let bench_group_name = format!("KEM/{:?}/encapsulate", ele.id()); let mut group = c.benchmark_group(bench_group_name); group.bench_function("AWS-LC", |b| { @@ -46,8 +39,7 @@ fn bench_kem_encapsulate(c: &mut Criterion) { } fn bench_kem_decapsulate(c: &mut Criterion) { - for ele in UNSTABLE_ALGORITHMS { - let ele = ele.unwrap(); + for ele in KEM_ALGORITHMS { let bench_group_name = format!("KEM/{:?}/decapsulate", ele.id()); let mut group = c.benchmark_group(bench_group_name); group.bench_function("AWS-LC", |b| { 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/kdf.rs b/aws-lc-rs/src/kdf.rs new file mode 100644 index 00000000000..32fb80037e4 --- /dev/null +++ b/aws-lc-rs/src/kdf.rs @@ -0,0 +1,443 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +//! # Key-based Key Derivation Function (KBKDF) in Counter Mode +//! +//! [`kbkdf_ctr_hmac`] provides an implementation of KDF in Counter Mode using HMAC PRF specified in +//! [NIST SP 800-108r1-upd1](https://doi.org/10.6028/NIST.SP.800-108r1-upd1) section 4.1. Further details +//! regarding the implementation can be found on the accompanying function documentation. +//! +//! Key-based key derivation functions are used to derive additional keys from an existing cryptographic key. +//! +//! ## Example: Usage with HMAC-SHA256 PRF +//! +//! ```rust +//! # use std::error::Error; +//! use aws_lc_rs::kdf::{ +//! get_kbkdf_ctr_hmac_algorithm, kbkdf_ctr_hmac, KbkdfCtrHmacAlgorithm, +//! KbkdfCtrHmacAlgorithmId, +//! }; +//! # +//! # fn main() -> Result<(), Box> { +//! use aws_lc_rs::error::Unspecified; +//! +//! const OUTPUT_KEY_LEN: usize = 16; +//! +//! let key: &[u8] = &[ +//! 0x01, 0x85, 0xfb, 0x76, 0x61, 0xf6, 0xdd, 0x40, 0x8d, 0x98, 0x2f, 0x81, 0x0f, 0xcd, 0x50, +//! 0x04, +//! ]; +//! +//! let info: &[u8] = &[ +//! 0xc3, 0xf1, 0x71, 0x2a, 0x82, 0x61, 0x36, 0x43, 0xe0, 0xf7, 0x63, 0xa7, 0xa0, 0xa3, 0x15, +//! 0x88, 0xb6, 0xae, 0xd9, 0x50, 0x56, 0xdf, 0xc5, 0x12, 0x55, 0x0c, 0xf2, 0xd0, 0x0d, 0x68, +//! 0xa3, 0x2d, +//! ]; +//! +//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; +//! +//! let kbkdf_ctr_hmac_sha256: &KbkdfCtrHmacAlgorithm = +//! get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).ok_or(Unspecified)?; +//! +//! kbkdf_ctr_hmac(kbkdf_ctr_hmac_sha256, key, info, &mut output_key)?; +//! +//! assert_eq!( +//! output_key, +//! [ +//! 0xc6, 0x3f, 0x74, 0x7b, 0x67, 0xbe, 0x71, 0xf5, 0x7b, 0xa4, 0x56, 0x21, 0x17, 0xdd, +//! 0x29, 0x4 +//! ] +//! ); +//! +//! # Ok(()) +//! # } +//! ``` +//! +//! ## Example: Usage with HMAC-SHA256 PRF using NIST FixedInfo Construction +//! +//! ```rust +//! # use std::error::Error; +//! use aws_lc_rs::kdf::{ +//! get_kbkdf_ctr_hmac_algorithm, kbkdf_ctr_hmac, KbkdfCtrHmacAlgorithm, +//! KbkdfCtrHmacAlgorithmId, +//! }; +//! +//! +//! # fn main() -> Result<(), Box> { +//! use aws_lc_rs::error::Unspecified; +//! const OUTPUT_KEY_LEN: usize = 16; +//! +//! let key: &[u8] = &[ +//! 0x01, 0x85, 0xfb, 0x76, 0x61, 0xf6, 0xdd, 0x40, 0x8d, 0x98, 0x2f, 0x81, 0x0f, 0xcd, 0x50, +//! 0x04, +//! ]; +//! +//! let label: &[u8] = b"KBKDF HMAC Counter Label"; +//! let context: &[u8] = b"KBKDF HMAC Counter Context"; +//! +//! let output_len_bits_be: [u8; 4] = { +//! // Multiply `output_len` by eight to convert from bytes to bits +//! // Convert value to a 32-bit big-endian representation +//! let len: u32 = (OUTPUT_KEY_LEN * 8).try_into()?; +//! len.to_be_bytes() +//! }; +//! +//! // FixedInfo String: Label || 0x00 || Context || [L] +//! let mut info = Vec::::new(); +//! info.extend_from_slice(label); +//! info.push(0x0); +//! info.extend_from_slice(context); +//! info.extend_from_slice(&output_len_bits_be); +//! +//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; +//! +//! let kbkdf_ctr_hmac_sha256: &KbkdfCtrHmacAlgorithm = +//! get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).ok_or(Unspecified)?; +//! +//! kbkdf_ctr_hmac(kbkdf_ctr_hmac_sha256, key, &info, &mut output_key)?; +//! +//! assert_eq!( +//! output_key, +//! [ +//! 0xcd, 0xe0, 0x92, 0xc8, 0xfe, 0x96, 0x21, 0x51, 0x88, 0xd4, 0x3d, 0xe4, 0x6c, 0xf6, +//! 0x37, 0xcb +//! ] +//! ); +//! +//! # Ok(()) +//! # } +//! ``` +//! # Single-step Key Derivation Function (SSKDF) +//! +//! [`sskdf_digest`] and [`sskdf_hmac`] provided implementations of a one-step key derivation function defined in +//! section 4 of [NIST SP 800-56Cr2](https://doi.org/10.6028/NIST.SP.800-56Cr2). +//! +//! These functions are used to derive keying material from a shared secret during a key establishment scheme. +//! +//! ## SSKDF using digest +//! +//! ```rust +//! # use std::error::Error; +//! use aws_lc_rs::kdf::{ +//! get_sskdf_digest_algorithm, sskdf_digest, SskdfDigestAlgorithm, SskdfDigestAlgorithmId, +//! }; +//! +//! # fn main() -> Result<(), Box> { +//! use aws_lc_rs::error::Unspecified; +//! +//! const OUTPUT_KEY_LEN: usize = 16; +//! +//! let shared_secret: &[u8] = &[ +//! 0x59, 0x09, 0x6b, 0x7b, 0xb7, 0x2b, 0x94, 0xc5, 0x55, 0x5c, 0x36, 0xc9, 0x76, 0x8f, 0xd8, +//! 0xe4, 0xed, 0x8f, 0x39, 0x5e, 0x78, 0x48, 0x5e, 0xb9, 0xf9, 0xdd, 0x43, 0x65, 0x55, 0x00, +//! 0xed, 0x7a, +//! ]; +//! +//! let info: &[u8] = &[ +//! 0x9b, 0xca, 0xd7, 0xe8, 0xee, 0xf7, 0xb2, 0x1a, 0x98, 0xff, 0x18, 0x60, 0x5c, 0x68, 0x16, +//! 0xbd, +//! ]; +//! +//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; +//! +//! let sskdf_digest_sha256: &SskdfDigestAlgorithm = +//! get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256).ok_or(Unspecified)?; +//! +//! sskdf_digest(sskdf_digest_sha256, shared_secret, info, &mut output_key)?; +//! +//! assert_eq!( +//! output_key, +//! [ +//! 0x21, 0x79, 0x35, 0x6c, 0xdc, 0x30, 0x1, 0xe6, 0x3f, 0x91, 0xb3, 0xc8, 0x10, 0x7, 0xba, +//! 0x31 +//! ] +//! ); +//! # Ok(()) +//! # } +//! ``` +//! +//! ## SSKDF using HMAC +//! +//! ```rust +//! # use std::error::Error; +//! use aws_lc_rs::kdf::{ +//! get_sskdf_hmac_algorithm, sskdf_hmac, SskdfHmacAlgorithm, SskdfHmacAlgorithmId, +//! }; +//! +//! +//! # fn main() -> Result<(), Box> { +//! use aws_lc_rs::error::Unspecified; +//! +//! +//! const OUTPUT_KEY_LEN: usize = 16; +//! +//! let shared_secret: &[u8] = &[ +//! 0x59, 0x09, 0x6b, 0x7b, 0xb7, 0x2b, 0x94, 0xc5, 0x55, 0x5c, 0x36, 0xc9, 0x76, 0x8f, 0xd8, +//! 0xe4, 0xed, 0x8f, 0x39, 0x5e, 0x78, 0x48, 0x5e, 0xb9, 0xf9, 0xdd, 0x43, 0x65, 0x55, 0x00, +//! 0xed, 0x7a, +//! ]; +//! +//! let info: &[u8] = &[ +//! 0x9b, 0xca, 0xd7, 0xe8, 0xee, 0xf7, 0xb2, 0x1a, 0x98, 0xff, 0x18, 0x60, 0x5c, 0x68, 0x16, +//! 0xbd, +//! ]; +//! +//! let salt: &[u8] = &[ +//! 0x2b, 0xc5, 0xf1, 0x6c, 0x48, 0x34, 0x72, 0xd8, 0xda, 0x53, 0xf6, 0xc3, 0x0f, 0x0a, 0xf4, +//! 0x02, +//! ]; +//! +//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; +//! +//! let sskdf_hmac_sha256: &SskdfHmacAlgorithm = +//! get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).ok_or(Unspecified)?; +//! +//! sskdf_hmac( +//! sskdf_hmac_sha256, +//! shared_secret, +//! info, +//! salt, +//! &mut output_key, +//! )?; +//! +//! assert_eq!( +//! output_key, +//! [ +//! 0x4c, 0x36, 0x80, 0x2d, 0xf5, 0xd8, 0xd6, 0x1b, 0xd5, 0xc2, 0x4, 0x7e, 0x5, 0x5a, 0x6d, +//! 0xcb +//! ] +//! ); +//! # Ok(()) +//! # } +//! ``` + +mod kbkdf; +mod sskdf; + +pub use kbkdf::{ + get_kbkdf_ctr_hmac_algorithm, kbkdf_ctr_hmac, KbkdfCtrHmacAlgorithm, KbkdfCtrHmacAlgorithmId, +}; + +pub use sskdf::{ + get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, sskdf_digest, sskdf_hmac, + SskdfDigestAlgorithm, SskdfDigestAlgorithmId, SskdfHmacAlgorithm, SskdfHmacAlgorithmId, +}; + +#[cfg(test)] +mod tests { + use crate::kdf::{ + get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, + kbkdf_ctr_hmac, sskdf::SskdfHmacAlgorithmId, sskdf_digest, sskdf_hmac, + KbkdfCtrHmacAlgorithmId, SskdfDigestAlgorithmId, + }; + + #[test] + fn zero_length_output() { + let mut output = vec![0u8; 0]; + assert!(sskdf_hmac( + get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).expect("algorithm supported"), + &[0u8; 16], + &[], + &[], + &mut output + ) + .is_err()); + assert!(sskdf_digest( + get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256) + .expect("algorithm supported"), + &[0u8; 16], + &[], + &mut output + ) + .is_err()); + assert!(kbkdf_ctr_hmac( + get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256) + .expect("algorithm supported"), + &[0u8; 16], + &[], + &mut output + ) + .is_err()); + } + + #[test] + fn zero_length_secret() { + let mut output = vec![0u8; 16]; + assert!(sskdf_hmac( + get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).expect("algorithm supported"), + &[], + &[], + &[], + &mut output + ) + .is_err()); + assert!(sskdf_digest( + get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256) + .expect("algorithm supported"), + &[], + &[], + &mut output + ) + .is_err()); + assert!(kbkdf_ctr_hmac( + get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256) + .expect("algorithm supported"), + &[], + &[], + &mut output + ) + .is_err()); + } + + #[test] + fn sskdf_digest_test() { + for id in [ + SskdfDigestAlgorithmId::Sha224, + SskdfDigestAlgorithmId::Sha256, + SskdfDigestAlgorithmId::Sha384, + SskdfDigestAlgorithmId::Sha512, + ] { + let alg = get_sskdf_digest_algorithm(id).expect("supported"); + assert_eq!(id, alg.id()); + assert_eq!(format!("{id:?}"), format!("{alg:?}")); + assert_eq!(format!("{id:?}"), format!("{:?}", alg.id())); + let mut output = vec![0u8; 32]; + sskdf_digest(alg, &[1u8; 32], &[2u8; 32], &mut output).expect("success"); + } + } + + #[test] + fn sskdf_hmac_test() { + for id in [ + SskdfHmacAlgorithmId::Sha224, + SskdfHmacAlgorithmId::Sha256, + SskdfHmacAlgorithmId::Sha384, + SskdfHmacAlgorithmId::Sha512, + ] { + let alg = get_sskdf_hmac_algorithm(id).expect("supported"); + assert_eq!(id, alg.id()); + assert_eq!(format!("{id:?}"), format!("{alg:?}")); + assert_eq!(format!("{id:?}"), format!("{:?}", alg.id())); + let mut output = vec![0u8; 32]; + sskdf_hmac(alg, &[1u8; 32], &[2u8; 32], &[3u8; 32], &mut output).expect("success"); + } + } + + #[test] + fn kbkdf_ctr_hmac_test() { + for id in [ + KbkdfCtrHmacAlgorithmId::Sha224, + KbkdfCtrHmacAlgorithmId::Sha256, + KbkdfCtrHmacAlgorithmId::Sha384, + KbkdfCtrHmacAlgorithmId::Sha512, + ] { + let alg = get_kbkdf_ctr_hmac_algorithm(id).expect("supported"); + assert_eq!(id, alg.id()); + assert_eq!(format!("{id:?}"), format!("{alg:?}")); + assert_eq!(format!("{id:?}"), format!("{:?}", alg.id())); + let mut output = vec![0u8; 32]; + kbkdf_ctr_hmac(alg, &[1u8; 32], &[2u8; 32], &mut output).expect("success"); + } + } + + #[test] + fn algorithm_equality() { + let alg1 = get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).unwrap(); + let alg2 = get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).unwrap(); + assert_eq!(alg1, alg2); + let alg2 = get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha512).unwrap(); + assert_ne!(alg1, alg2); + + let alg1 = get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256).unwrap(); + let alg2 = get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256).unwrap(); + assert_eq!(alg1, alg2); + let alg2 = get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha512).unwrap(); + assert_ne!(alg1, alg2); + + let alg1 = get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).unwrap(); + let alg2 = get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).unwrap(); + assert_eq!(alg1, alg2); + let alg2 = get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha512).unwrap(); + assert_ne!(alg1, alg2); + } +} + +#[cfg(test)] +mod more_tests { + use crate::kdf::{ + get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, + KbkdfCtrHmacAlgorithmId, SskdfDigestAlgorithmId, SskdfHmacAlgorithmId, + }; + + macro_rules! assert_get_algorithm { + ($name:ident, $getter:path, $alg:expr) => { + #[test] + fn $name() { + assert!($getter($alg).is_some()); + } + }; + } + + assert_get_algorithm!( + get_sskdf_hmac_algorithm_hmac_sha224, + get_sskdf_hmac_algorithm, + SskdfHmacAlgorithmId::Sha224 + ); + assert_get_algorithm!( + get_sskdf_hmac_algorithm_hmac_sha256, + get_sskdf_hmac_algorithm, + SskdfHmacAlgorithmId::Sha256 + ); + assert_get_algorithm!( + get_sskdf_hmac_algorithm_hmac_sha384, + get_sskdf_hmac_algorithm, + SskdfHmacAlgorithmId::Sha384 + ); + assert_get_algorithm!( + get_sskdf_hmac_algorithm_hmac_sha512, + get_sskdf_hmac_algorithm, + SskdfHmacAlgorithmId::Sha512 + ); + + assert_get_algorithm!( + get_sskdf_digest_algorithm_sha224, + get_sskdf_digest_algorithm, + SskdfDigestAlgorithmId::Sha224 + ); + assert_get_algorithm!( + get_sskdf_digest_algorithm_sha256, + get_sskdf_digest_algorithm, + SskdfDigestAlgorithmId::Sha256 + ); + assert_get_algorithm!( + get_sskdf_digest_algorithm_sha384, + get_sskdf_digest_algorithm, + SskdfDigestAlgorithmId::Sha384 + ); + assert_get_algorithm!( + get_sskdf_digest_algorithm_sha512, + get_sskdf_digest_algorithm, + SskdfDigestAlgorithmId::Sha512 + ); + + assert_get_algorithm!( + get_kbkdf_ctr_hmac_algorithm_sha224, + get_kbkdf_ctr_hmac_algorithm, + KbkdfCtrHmacAlgorithmId::Sha224 + ); + assert_get_algorithm!( + get_kbkdf_ctr_hmac_algorithm_sha256, + get_kbkdf_ctr_hmac_algorithm, + KbkdfCtrHmacAlgorithmId::Sha256 + ); + assert_get_algorithm!( + get_kbkdf_ctr_hmac_algorithm_sha384, + get_kbkdf_ctr_hmac_algorithm, + KbkdfCtrHmacAlgorithmId::Sha384 + ); + assert_get_algorithm!( + get_kbkdf_ctr_hmac_algorithm_sha512, + get_kbkdf_ctr_hmac_algorithm, + KbkdfCtrHmacAlgorithmId::Sha512 + ); +} diff --git a/aws-lc-rs/src/unstable/kdf/kbkdf.rs b/aws-lc-rs/src/kdf/kbkdf.rs similarity index 85% rename from aws-lc-rs/src/unstable/kdf/kbkdf.rs rename to aws-lc-rs/src/kdf/kbkdf.rs index ef75c093ad4..8881d861459 100644 --- a/aws-lc-rs/src/unstable/kdf/kbkdf.rs +++ b/aws-lc-rs/src/kdf/kbkdf.rs @@ -3,28 +3,8 @@ #![allow(clippy::module_name_repetitions)] -#[cfg(not(feature = "fips"))] use aws_lc::KBKDF_ctr_hmac; - use aws_lc::EVP_MD; -#[cfg(feature = "fips")] -use stubs::KBKDF_ctr_hmac; - -#[cfg(feature = "fips")] -mod stubs { - #[allow(non_snake_case)] - pub(super) unsafe fn KBKDF_ctr_hmac( - _out_key: *mut u8, - _out_len: usize, - _digest: *const aws_lc::EVP_MD, - _secret: *const u8, - _secret_len: usize, - _info: *const u8, - _info_len: usize, - ) -> std::os::raw::c_int { - 0 - } -} use crate::{ digest::{match_digest_type, AlgorithmID}, @@ -56,19 +36,11 @@ const KBKDF_CTR_HMAC_SHA512: KbkdfCtrHmacAlgorithm = KbkdfCtrHmacAlgorithm { id: KbkdfCtrHmacAlgorithmId::Sha512, }; -/// Retrieve an unstable [`KbkdfCtrHmacAlgorithm`] using the [`KbkdfCtrHmacAlgorithmId`] specified by `id`. -/// -/// May return [`None`] if the algorithm is not usable with the configured crate feature set (i.e. `fips`). +/// Retrieve [`KbkdfCtrHmacAlgorithm`] using the [`KbkdfCtrHmacAlgorithmId`] specified by `id`. #[must_use] pub const fn get_kbkdf_ctr_hmac_algorithm( id: KbkdfCtrHmacAlgorithmId, ) -> Option<&'static KbkdfCtrHmacAlgorithm> { - #[cfg(feature = "fips")] - { - let _ = id; - None - } - #[cfg(not(feature = "fips"))] { Some(match id { KbkdfCtrHmacAlgorithmId::Sha224 => &KBKDF_CTR_HMAC_SHA224, diff --git a/aws-lc-rs/src/unstable/kdf/sskdf.rs b/aws-lc-rs/src/kdf/sskdf.rs similarity index 84% rename from aws-lc-rs/src/unstable/kdf/sskdf.rs rename to aws-lc-rs/src/kdf/sskdf.rs index 35df79eadf9..fdfade0116c 100644 --- a/aws-lc-rs/src/unstable/kdf/sskdf.rs +++ b/aws-lc-rs/src/kdf/sskdf.rs @@ -4,49 +4,14 @@ #![allow(clippy::module_name_repetitions)] use aws_lc::EVP_MD; -#[cfg(not(feature = "fips"))] use aws_lc::{SSKDF_digest, SSKDF_hmac}; -#[cfg(feature = "fips")] -use stubs::{SSKDF_digest, SSKDF_hmac}; - use crate::{ digest::{match_digest_type, AlgorithmID}, error::Unspecified, ptr::ConstPointer, }; -#[cfg(feature = "fips")] -mod stubs { - #[allow(non_snake_case)] - pub(super) unsafe fn SSKDF_digest( - _out_key: *mut u8, - _out_len: usize, - _digest: *const aws_lc::EVP_MD, - _secret: *const u8, - _secret_len: usize, - _info: *const u8, - _info_len: usize, - ) -> std::os::raw::c_int { - 0 - } - - #[allow(clippy::too_many_arguments, non_snake_case)] - pub(super) unsafe fn SSKDF_hmac( - _out_key: *mut u8, - _out_len: usize, - _digest: *const aws_lc::EVP_MD, - _secret: *const u8, - _secret_len: usize, - _info: *const u8, - _info_len: usize, - _salt: *const u8, - _salt_len: usize, - ) -> std::os::raw::c_int { - 0 - } -} - /// SSKDF with HMAC-SHA224 #[allow(dead_code)] const SSKDF_HMAC_SHA224: SskdfHmacAlgorithm = SskdfHmacAlgorithm { @@ -95,19 +60,11 @@ const SSKDF_DIGEST_SHA512: SskdfDigestAlgorithm = SskdfDigestAlgorithm { id: SskdfDigestAlgorithmId::Sha512, }; -/// Retrieve an unstable [`SskdfHmacAlgorithm`] using the [`SskdfHmacAlgorithmId`] specified by `id`. -/// -/// May return [`None`] if the algorithm is not usable with the configured crate feature set (i.e. `fips`). +/// Retrieve [`SskdfHmacAlgorithm`] using the [`SskdfHmacAlgorithmId`] specified by `id`. #[must_use] pub const fn get_sskdf_hmac_algorithm( id: SskdfHmacAlgorithmId, ) -> Option<&'static SskdfHmacAlgorithm> { - #[cfg(feature = "fips")] - { - let _ = id; - None - } - #[cfg(not(feature = "fips"))] { match id { SskdfHmacAlgorithmId::Sha224 => Some(&SSKDF_HMAC_SHA224), @@ -118,19 +75,11 @@ pub const fn get_sskdf_hmac_algorithm( } } -/// Retrieve an unstable [`SskdfDigestAlgorithm`] using the [`SskdfDigestAlgorithmId`] specified by `id`. -/// -/// May return [`None`] if the algorithm is not usable with the configured crate feature set (i.e. `fips`). +/// Retrieve [`SskdfDigestAlgorithm`] using the [`SskdfDigestAlgorithmId`] specified by `id`. #[must_use] pub const fn get_sskdf_digest_algorithm( id: SskdfDigestAlgorithmId, ) -> Option<&'static SskdfDigestAlgorithm> { - #[cfg(feature = "fips")] - { - let _ = id; - None - } - #[cfg(not(feature = "fips"))] { match id { SskdfDigestAlgorithmId::Sha224 => Some(&SSKDF_DIGEST_SHA224), diff --git a/aws-lc-rs/src/kem.rs b/aws-lc-rs/src/kem.rs index 121ea24774e..125a8969cb6 100644 --- a/aws-lc-rs/src/kem.rs +++ b/aws-lc-rs/src/kem.rs @@ -9,10 +9,10 @@ //! in the exact same way by substituting //! `kem::` for `kem::KYBER512_R3`. //! -//! ```ignore +//! ```rust //! 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/lib.rs b/aws-lc-rs/src/lib.rs index 651c9edadea..421f6d8838d 100644 --- a/aws-lc-rs/src/lib.rs +++ b/aws-lc-rs/src/lib.rs @@ -142,13 +142,13 @@ #![warn(clippy::exhaustive_enums)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +extern crate alloc; #[cfg(feature = "fips")] extern crate aws_lc_fips_sys as aws_lc; - -extern crate alloc; #[cfg(not(feature = "fips"))] extern crate aws_lc_sys as aws_lc; extern crate core; + pub mod aead; pub mod agreement; pub mod constant_time; @@ -179,6 +179,7 @@ mod evp_pkey; mod fips; mod hex; pub mod iv; +pub mod kdf; #[allow(clippy::module_name_repetitions)] pub mod kem; mod ptr; diff --git a/aws-lc-rs/src/unstable.rs b/aws-lc-rs/src/unstable.rs index 313a7557480..9e787ecbe12 100644 --- a/aws-lc-rs/src/unstable.rs +++ b/aws-lc-rs/src/unstable.rs @@ -2,12 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC #![cfg(feature = "unstable")] +#![allow(missing_docs)] //! Unstable aws-lc-rs features. //! //! # ⚠️ Warning //! Features contained within this module, or child modules are subject to changes, relocation, //! or removal across minor releases, and thus are not subject to semantic versioning policies. - +#[deprecated(note = "use `aws_lc_rs::kdf` instead")] pub mod kdf; + +#[deprecated(note = "use `aws_lc_rs::kem` instead")] pub mod kem; diff --git a/aws-lc-rs/src/unstable/kdf.rs b/aws-lc-rs/src/unstable/kdf.rs index 658ca950ecc..83c7dcde947 100644 --- a/aws-lc-rs/src/unstable/kdf.rs +++ b/aws-lc-rs/src/unstable/kdf.rs @@ -1,459 +1,11 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 OR ISC - -//! # Key-based Key Derivation Function (KBKDF) in Counter Mode -//! -//! [`kbkdf_ctr_hmac`] provides an implementation of KDF in Counter Mode using HMAC PRF specified in -//! [NIST SP 800-108r1-upd1](https://doi.org/10.6028/NIST.SP.800-108r1-upd1) section 4.1. Further details -//! regarding the implementation can be found on the accompanying function documentation. -//! -//! Key-based key derivation functions are used to derive additional keys from an existing cryptographic key. -//! -//! ## Example: Usage with HMAC-SHA256 PRF -//! -//! ```rust -//! # use std::error::Error; -//! # -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "fips")] -//! # return Ok(()); -//! use aws_lc_rs::{ -//! error::Unspecified, -//! unstable::kdf::{ -//! get_kbkdf_ctr_hmac_algorithm, kbkdf_ctr_hmac, KbkdfCtrHmacAlgorithm, -//! KbkdfCtrHmacAlgorithmId, -//! }, -//! }; -//! -//! const OUTPUT_KEY_LEN: usize = 16; -//! -//! let key: &[u8] = &[ -//! 0x01, 0x85, 0xfb, 0x76, 0x61, 0xf6, 0xdd, 0x40, 0x8d, 0x98, 0x2f, 0x81, 0x0f, 0xcd, 0x50, -//! 0x04, -//! ]; -//! -//! let info: &[u8] = &[ -//! 0xc3, 0xf1, 0x71, 0x2a, 0x82, 0x61, 0x36, 0x43, 0xe0, 0xf7, 0x63, 0xa7, 0xa0, 0xa3, 0x15, -//! 0x88, 0xb6, 0xae, 0xd9, 0x50, 0x56, 0xdf, 0xc5, 0x12, 0x55, 0x0c, 0xf2, 0xd0, 0x0d, 0x68, -//! 0xa3, 0x2d, -//! ]; -//! -//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; -//! -//! let kbkdf_ctr_hmac_sha256: &KbkdfCtrHmacAlgorithm = -//! get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).ok_or(Unspecified)?; -//! -//! kbkdf_ctr_hmac(kbkdf_ctr_hmac_sha256, key, info, &mut output_key)?; -//! -//! assert_eq!( -//! output_key, -//! [ -//! 0xc6, 0x3f, 0x74, 0x7b, 0x67, 0xbe, 0x71, 0xf5, 0x7b, 0xa4, 0x56, 0x21, 0x17, 0xdd, -//! 0x29, 0x4 -//! ] -//! ); -//! -//! # Ok(()) -//! # } -//! ``` -//! -//! ## Example: Usage with HMAC-SHA256 PRF using NIST FixedInfo Construction -//! -//! ```rust -//! # use std::error::Error; -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "fips")] -//! # return Ok(()); -//! use aws_lc_rs::{ -//! error::Unspecified, -//! unstable::kdf::{ -//! get_kbkdf_ctr_hmac_algorithm, kbkdf_ctr_hmac, KbkdfCtrHmacAlgorithm, -//! KbkdfCtrHmacAlgorithmId, -//! }, -//! }; -//! -//! const OUTPUT_KEY_LEN: usize = 16; -//! -//! let key: &[u8] = &[ -//! 0x01, 0x85, 0xfb, 0x76, 0x61, 0xf6, 0xdd, 0x40, 0x8d, 0x98, 0x2f, 0x81, 0x0f, 0xcd, 0x50, -//! 0x04, -//! ]; -//! -//! let label: &[u8] = b"KBKDF HMAC Counter Label"; -//! let context: &[u8] = b"KBKDF HMAC Counter Context"; -//! -//! let output_len_bits_be: [u8; 4] = { -//! // Multiply `output_len` by eight to convert from bytes to bits -//! // Convert value to a 32-bit big-endian representation -//! let len: u32 = (OUTPUT_KEY_LEN * 8).try_into()?; -//! len.to_be_bytes() -//! }; -//! -//! // FixedInfo String: Label || 0x00 || Context || [L] -//! let mut info = Vec::::new(); -//! info.extend_from_slice(label); -//! info.push(0x0); -//! info.extend_from_slice(context); -//! info.extend_from_slice(&output_len_bits_be); -//! -//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; -//! -//! let kbkdf_ctr_hmac_sha256: &KbkdfCtrHmacAlgorithm = -//! get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).ok_or(Unspecified)?; -//! -//! kbkdf_ctr_hmac(kbkdf_ctr_hmac_sha256, key, &info, &mut output_key)?; -//! -//! assert_eq!( -//! output_key, -//! [ -//! 0xcd, 0xe0, 0x92, 0xc8, 0xfe, 0x96, 0x21, 0x51, 0x88, 0xd4, 0x3d, 0xe4, 0x6c, 0xf6, -//! 0x37, 0xcb -//! ] -//! ); -//! -//! # Ok(()) -//! # } -//! ``` -//! # Single-step Key Derivation Function (SSKDF) -//! -//! [`sskdf_digest`] and [`sskdf_hmac`] provided implementations of a one-step key derivation function defined in -//! section 4 of [NIST SP 800-56Cr2](https://doi.org/10.6028/NIST.SP.800-56Cr2). -//! -//! These functions are used to derive keying material from a shared secret during a key establishment scheme. -//! -//! ## SSKDF using digest -//! -//! ```rust -//! # use std::error::Error; -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "fips")] -//! # return Ok(()); -//! use aws_lc_rs::{ -//! error::Unspecified, -//! unstable::kdf::{ -//! get_sskdf_digest_algorithm, sskdf_digest, SskdfDigestAlgorithm, SskdfDigestAlgorithmId, -//! }, -//! }; -//! -//! const OUTPUT_KEY_LEN: usize = 16; -//! -//! let shared_secret: &[u8] = &[ -//! 0x59, 0x09, 0x6b, 0x7b, 0xb7, 0x2b, 0x94, 0xc5, 0x55, 0x5c, 0x36, 0xc9, 0x76, 0x8f, 0xd8, -//! 0xe4, 0xed, 0x8f, 0x39, 0x5e, 0x78, 0x48, 0x5e, 0xb9, 0xf9, 0xdd, 0x43, 0x65, 0x55, 0x00, -//! 0xed, 0x7a, -//! ]; -//! -//! let info: &[u8] = &[ -//! 0x9b, 0xca, 0xd7, 0xe8, 0xee, 0xf7, 0xb2, 0x1a, 0x98, 0xff, 0x18, 0x60, 0x5c, 0x68, 0x16, -//! 0xbd, -//! ]; -//! -//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; -//! -//! let sskdf_digest_sha256: &SskdfDigestAlgorithm = -//! get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256).ok_or(Unspecified)?; -//! -//! sskdf_digest(sskdf_digest_sha256, shared_secret, info, &mut output_key)?; -//! -//! assert_eq!( -//! output_key, -//! [ -//! 0x21, 0x79, 0x35, 0x6c, 0xdc, 0x30, 0x1, 0xe6, 0x3f, 0x91, 0xb3, 0xc8, 0x10, 0x7, 0xba, -//! 0x31 -//! ] -//! ); -//! # Ok(()) -//! # } -//! ``` -//! -//! ## SSKDF using HMAC -//! -//! ```rust -//! # use std::error::Error; -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "fips")] -//! # return Ok(()); -//! use aws_lc_rs::{ -//! error::Unspecified, -//! unstable::kdf::{ -//! get_sskdf_hmac_algorithm, sskdf_hmac, SskdfHmacAlgorithm, SskdfHmacAlgorithmId, -//! }, -//! }; -//! -//! const OUTPUT_KEY_LEN: usize = 16; -//! -//! let shared_secret: &[u8] = &[ -//! 0x59, 0x09, 0x6b, 0x7b, 0xb7, 0x2b, 0x94, 0xc5, 0x55, 0x5c, 0x36, 0xc9, 0x76, 0x8f, 0xd8, -//! 0xe4, 0xed, 0x8f, 0x39, 0x5e, 0x78, 0x48, 0x5e, 0xb9, 0xf9, 0xdd, 0x43, 0x65, 0x55, 0x00, -//! 0xed, 0x7a, -//! ]; -//! -//! let info: &[u8] = &[ -//! 0x9b, 0xca, 0xd7, 0xe8, 0xee, 0xf7, 0xb2, 0x1a, 0x98, 0xff, 0x18, 0x60, 0x5c, 0x68, 0x16, -//! 0xbd, -//! ]; -//! -//! let salt: &[u8] = &[ -//! 0x2b, 0xc5, 0xf1, 0x6c, 0x48, 0x34, 0x72, 0xd8, 0xda, 0x53, 0xf6, 0xc3, 0x0f, 0x0a, 0xf4, -//! 0x02, -//! ]; -//! -//! let mut output_key = [0u8; OUTPUT_KEY_LEN]; -//! -//! let sskdf_hmac_sha256: &SskdfHmacAlgorithm = -//! get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).ok_or(Unspecified)?; -//! -//! sskdf_hmac( -//! sskdf_hmac_sha256, -//! shared_secret, -//! info, -//! salt, -//! &mut output_key, -//! )?; -//! -//! assert_eq!( -//! output_key, -//! [ -//! 0x4c, 0x36, 0x80, 0x2d, 0xf5, 0xd8, 0xd6, 0x1b, 0xd5, 0xc2, 0x4, 0x7e, 0x5, 0x5a, 0x6d, -//! 0xcb -//! ] -//! ); -//! # Ok(()) -//! # } -//! ``` - -mod kbkdf; -mod sskdf; - -pub use kbkdf::{ - get_kbkdf_ctr_hmac_algorithm, kbkdf_ctr_hmac, KbkdfCtrHmacAlgorithm, KbkdfCtrHmacAlgorithmId, -}; - -pub use sskdf::{ - get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, sskdf_digest, sskdf_hmac, +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC + */ + +#[deprecated(note = "use `aws_lc_rs::kdf` instead")] +pub use crate::kdf::{ + get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, + kbkdf_ctr_hmac, sskdf_digest, sskdf_hmac, KbkdfCtrHmacAlgorithm, KbkdfCtrHmacAlgorithmId, SskdfDigestAlgorithm, SskdfDigestAlgorithmId, SskdfHmacAlgorithm, SskdfHmacAlgorithmId, }; - -#[cfg(test)] -mod tests { - #[cfg(not(feature = "fips"))] - mod notfips { - use crate::unstable::kdf::{ - get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, - kbkdf_ctr_hmac, sskdf::SskdfHmacAlgorithmId, sskdf_digest, sskdf_hmac, - KbkdfCtrHmacAlgorithmId, SskdfDigestAlgorithmId, - }; - - #[test] - fn zero_length_output() { - let mut output = vec![0u8; 0]; - assert!(sskdf_hmac( - get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256) - .expect("algorithm supported"), - &[0u8; 16], - &[], - &[], - &mut output - ) - .is_err()); - assert!(sskdf_digest( - get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256) - .expect("algorithm supported"), - &[0u8; 16], - &[], - &mut output - ) - .is_err()); - assert!(kbkdf_ctr_hmac( - get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256) - .expect("algorithm supported"), - &[0u8; 16], - &[], - &mut output - ) - .is_err()); - } - - #[test] - fn zero_length_secret() { - let mut output = vec![0u8; 16]; - assert!(sskdf_hmac( - get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256) - .expect("algorithm supported"), - &[], - &[], - &[], - &mut output - ) - .is_err()); - assert!(sskdf_digest( - get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256) - .expect("algorithm supported"), - &[], - &[], - &mut output - ) - .is_err()); - assert!(kbkdf_ctr_hmac( - get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256) - .expect("algorithm supported"), - &[], - &[], - &mut output - ) - .is_err()); - } - - #[test] - fn sskdf_digest_test() { - for id in [ - SskdfDigestAlgorithmId::Sha224, - SskdfDigestAlgorithmId::Sha256, - SskdfDigestAlgorithmId::Sha384, - SskdfDigestAlgorithmId::Sha512, - ] { - let alg = get_sskdf_digest_algorithm(id).expect("supported"); - assert_eq!(id, alg.id()); - assert_eq!(format!("{id:?}"), format!("{alg:?}")); - assert_eq!(format!("{id:?}"), format!("{:?}", alg.id())); - let mut output = vec![0u8; 32]; - sskdf_digest(alg, &[1u8; 32], &[2u8; 32], &mut output).expect("success"); - } - } - - #[test] - fn sskdf_hmac_test() { - for id in [ - SskdfHmacAlgorithmId::Sha224, - SskdfHmacAlgorithmId::Sha256, - SskdfHmacAlgorithmId::Sha384, - SskdfHmacAlgorithmId::Sha512, - ] { - let alg = get_sskdf_hmac_algorithm(id).expect("supported"); - assert_eq!(id, alg.id()); - assert_eq!(format!("{id:?}"), format!("{alg:?}")); - assert_eq!(format!("{id:?}"), format!("{:?}", alg.id())); - let mut output = vec![0u8; 32]; - sskdf_hmac(alg, &[1u8; 32], &[2u8; 32], &[3u8; 32], &mut output).expect("success"); - } - } - - #[test] - fn kbkdf_ctr_hmac_test() { - for id in [ - KbkdfCtrHmacAlgorithmId::Sha224, - KbkdfCtrHmacAlgorithmId::Sha256, - KbkdfCtrHmacAlgorithmId::Sha384, - KbkdfCtrHmacAlgorithmId::Sha512, - ] { - let alg = get_kbkdf_ctr_hmac_algorithm(id).expect("supported"); - assert_eq!(id, alg.id()); - assert_eq!(format!("{id:?}"), format!("{alg:?}")); - assert_eq!(format!("{id:?}"), format!("{:?}", alg.id())); - let mut output = vec![0u8; 32]; - kbkdf_ctr_hmac(alg, &[1u8; 32], &[2u8; 32], &mut output).expect("success"); - } - } - - #[test] - fn algorithm_equality() { - let alg1 = get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).unwrap(); - let alg2 = get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha256).unwrap(); - assert_eq!(alg1, alg2); - let alg2 = get_kbkdf_ctr_hmac_algorithm(KbkdfCtrHmacAlgorithmId::Sha512).unwrap(); - assert_ne!(alg1, alg2); - - let alg1 = get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256).unwrap(); - let alg2 = get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha256).unwrap(); - assert_eq!(alg1, alg2); - let alg2 = get_sskdf_digest_algorithm(SskdfDigestAlgorithmId::Sha512).unwrap(); - assert_ne!(alg1, alg2); - - let alg1 = get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).unwrap(); - let alg2 = get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha256).unwrap(); - assert_eq!(alg1, alg2); - let alg2 = get_sskdf_hmac_algorithm(SskdfHmacAlgorithmId::Sha512).unwrap(); - assert_ne!(alg1, alg2); - } - } - - #[cfg(feature = "fips")] - mod fips { - use crate::unstable::kdf::{ - get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, - KbkdfCtrHmacAlgorithmId, SskdfDigestAlgorithmId, SskdfHmacAlgorithmId, - }; - - macro_rules! assert_get_unsupported_algorithm { - ($name:ident, $getter:path, $alg:expr) => { - #[test] - fn $name() { - assert_eq!(None, $getter($alg)); - } - }; - } - - assert_get_unsupported_algorithm!( - get_sskdf_hmac_algorithm_hmac_sha224, - get_sskdf_hmac_algorithm, - SskdfHmacAlgorithmId::Sha224 - ); - assert_get_unsupported_algorithm!( - get_sskdf_hmac_algorithm_hmac_sha256, - get_sskdf_hmac_algorithm, - SskdfHmacAlgorithmId::Sha256 - ); - assert_get_unsupported_algorithm!( - get_sskdf_hmac_algorithm_hmac_sha384, - get_sskdf_hmac_algorithm, - SskdfHmacAlgorithmId::Sha384 - ); - assert_get_unsupported_algorithm!( - get_sskdf_hmac_algorithm_hmac_sha512, - get_sskdf_hmac_algorithm, - SskdfHmacAlgorithmId::Sha512 - ); - - assert_get_unsupported_algorithm!( - get_sskdf_digest_algorithm_sha224, - get_sskdf_digest_algorithm, - SskdfDigestAlgorithmId::Sha224 - ); - assert_get_unsupported_algorithm!( - get_sskdf_digest_algorithm_sha256, - get_sskdf_digest_algorithm, - SskdfDigestAlgorithmId::Sha256 - ); - assert_get_unsupported_algorithm!( - get_sskdf_digest_algorithm_sha384, - get_sskdf_digest_algorithm, - SskdfDigestAlgorithmId::Sha384 - ); - assert_get_unsupported_algorithm!( - get_sskdf_digest_algorithm_sha512, - get_sskdf_digest_algorithm, - SskdfDigestAlgorithmId::Sha512 - ); - - assert_get_unsupported_algorithm!( - get_kbkdf_ctr_hmac_algorithm_sha224, - get_kbkdf_ctr_hmac_algorithm, - KbkdfCtrHmacAlgorithmId::Sha224 - ); - assert_get_unsupported_algorithm!( - get_kbkdf_ctr_hmac_algorithm_sha256, - get_kbkdf_ctr_hmac_algorithm, - KbkdfCtrHmacAlgorithmId::Sha256 - ); - assert_get_unsupported_algorithm!( - get_kbkdf_ctr_hmac_algorithm_sha384, - get_kbkdf_ctr_hmac_algorithm, - KbkdfCtrHmacAlgorithmId::Sha384 - ); - assert_get_unsupported_algorithm!( - get_kbkdf_ctr_hmac_algorithm_sha512, - get_kbkdf_ctr_hmac_algorithm, - KbkdfCtrHmacAlgorithmId::Sha512 - ); - } -} diff --git a/aws-lc-rs/src/unstable/kem.rs b/aws-lc-rs/src/unstable/kem.rs index 60ae941154a..2facb2888d2 100644 --- a/aws-lc-rs/src/unstable/kem.rs +++ b/aws-lc-rs/src/unstable/kem.rs @@ -1,134 +1,21 @@ // 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>(()) -//! ``` - 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}; - -// Key lengths defined as stated on the CRYSTALS website: -// https://pq-crystals.org/kyber/ - -const KYBER512_R3_SECRET_KEY_LENGTH: usize = 1632; -const KYBER512_R3_CIPHERTEXT_LENGTH: usize = 768; -const KYBER512_R3_PUBLIC_KEY_LENGTH: usize = 800; -const KYBER512_R3_SHARED_SECRET_LENGTH: usize = 32; - -const KYBER768_R3_SECRET_KEY_LENGTH: usize = 2400; -const KYBER768_R3_CIPHERTEXT_LENGTH: usize = 1088; -const KYBER768_R3_PUBLIC_KEY_LENGTH: usize = 1184; -const KYBER768_R3_SHARED_SECRET_LENGTH: usize = 32; - -const KYBER1024_R3_SECRET_KEY_LENGTH: usize = 3168; -const KYBER1024_R3_CIPHERTEXT_LENGTH: usize = 1568; -const KYBER1024_R3_PUBLIC_KEY_LENGTH: usize = 1568; -const KYBER1024_R3_SHARED_SECRET_LENGTH: usize = 32; -/// NIST Round 3 submission of the Kyber-512 algorithm. -#[allow(deprecated)] -const KYBER512_R3: Algorithm = Algorithm { - id: AlgorithmId::Kyber512_R3, - decapsulate_key_size: KYBER512_R3_SECRET_KEY_LENGTH, - encapsulate_key_size: KYBER512_R3_PUBLIC_KEY_LENGTH, - ciphertext_size: KYBER512_R3_CIPHERTEXT_LENGTH, - shared_secret_size: KYBER512_R3_SHARED_SECRET_LENGTH, -}; +#[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}; -/// NIST Round 3 submission of the Kyber-768 algorithm. -#[allow(deprecated)] -const KYBER768_R3: Algorithm = Algorithm { - id: AlgorithmId::Kyber768_R3, - decapsulate_key_size: KYBER768_R3_SECRET_KEY_LENGTH, - encapsulate_key_size: KYBER768_R3_PUBLIC_KEY_LENGTH, - ciphertext_size: KYBER768_R3_CIPHERTEXT_LENGTH, - shared_secret_size: KYBER768_R3_SHARED_SECRET_LENGTH, -}; - -/// NIST Round 3 submission of the Kyber-1024 algorithm. -#[allow(deprecated)] -const KYBER1024_R3: Algorithm = Algorithm { - id: AlgorithmId::Kyber1024_R3, - decapsulate_key_size: KYBER1024_R3_SECRET_KEY_LENGTH, - encapsulate_key_size: KYBER1024_R3_PUBLIC_KEY_LENGTH, - ciphertext_size: KYBER1024_R3_CIPHERTEXT_LENGTH, - shared_secret_size: KYBER1024_R3_SHARED_SECRET_LENGTH, -}; - -/// Identifier for an unstable KEM algorithm. -#[allow(non_camel_case_types)] #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq)] -pub enum AlgorithmId { - /// NIST Round 3 submission of the Kyber-512 algorithm. - #[deprecated] - Kyber512_R3, - - /// NIST Round 3 submission of the Kyber-768 algorithm. - #[deprecated] - Kyber768_R3, - - /// NIST Round 3 submission of the Kyber-1024 algorithm. - #[deprecated] - Kyber1024_R3, -} +pub enum AlgorithmId {} impl crate::kem::AlgorithmIdentifier for AlgorithmId { #[inline] fn nid(self) -> i32 { - #[allow(deprecated)] - match self { - AlgorithmId::Kyber512_R3 => NID_KYBER512_R3, - AlgorithmId::Kyber768_R3 => NID_KYBER768_R3, - AlgorithmId::Kyber1024_R3 => NID_KYBER1024_R3, - } + unreachable!("There are no AlgorithmIds") } } @@ -136,138 +23,9 @@ impl crate::sealed::Sealed for AlgorithmId {} /// Retrieve an unstable KEM [`Algorithm`] using the [`AlgorithmId`] specified by `id`. /// May return [`None`] if support for the algorithm has been removed from the unstable module. +/// # ⚠️ Warning +/// This function currently only returns [`None`]. #[must_use] -pub const fn get_algorithm(id: AlgorithmId) -> Option<&'static Algorithm> { - #[allow(deprecated)] - match id { - AlgorithmId::Kyber512_R3 => Some(&KYBER512_R3), - AlgorithmId::Kyber768_R3 => Some(&KYBER768_R3), - AlgorithmId::Kyber1024_R3 => Some(&KYBER1024_R3), - } -} - -#[cfg(test)] -mod tests { - #![allow(deprecated)] - - use crate::{ - error::KeyRejected, - kem::{DecapsulationKey, EncapsulationKey}, - }; - - use super::{get_algorithm, AlgorithmId, KYBER1024_R3, KYBER512_R3, KYBER768_R3}; - - #[test] - fn test_kem_serialize() { - for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] { - let priv_key = DecapsulationKey::generate(algorithm).unwrap(); - assert_eq!(priv_key.algorithm(), algorithm); - - let pub_key = priv_key.encapsulation_key().unwrap(); - let pubkey_raw_bytes = pub_key.key_bytes().unwrap(); - let pub_key_from_bytes = - EncapsulationKey::new(algorithm, pubkey_raw_bytes.as_ref()).unwrap(); - - assert_eq!( - pub_key.key_bytes().unwrap().as_ref(), - pub_key_from_bytes.key_bytes().unwrap().as_ref() - ); - assert_eq!(pub_key.algorithm(), pub_key_from_bytes.algorithm()); - } - } - - #[test] - fn test_kem_wrong_sizes() { - for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] { - let too_long_bytes = vec![0u8; algorithm.encapsulate_key_size() + 1]; - let long_pub_key_from_bytes = EncapsulationKey::new(algorithm, &too_long_bytes); - assert_eq!( - long_pub_key_from_bytes.err(), - Some(KeyRejected::too_large()) - ); - - let too_short_bytes = vec![0u8; algorithm.encapsulate_key_size() - 1]; - let short_pub_key_from_bytes = EncapsulationKey::new(algorithm, &too_short_bytes); - assert_eq!( - short_pub_key_from_bytes.err(), - Some(KeyRejected::too_small()) - ); - } - } - - #[test] - fn test_kem_e2e() { - for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] { - let priv_key = DecapsulationKey::generate(algorithm).unwrap(); - assert_eq!(priv_key.algorithm(), algorithm); - - let pub_key = priv_key.encapsulation_key().unwrap(); - - let (alice_ciphertext, alice_secret) = - pub_key.encapsulate().expect("encapsulate successful"); - - let bob_secret = priv_key - .decapsulate(alice_ciphertext) - .expect("decapsulate successful"); - - assert_eq!(alice_secret.as_ref(), bob_secret.as_ref()); - } - } - - #[test] - fn test_serialized_kem_e2e() { - for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] { - let priv_key = DecapsulationKey::generate(algorithm).unwrap(); - assert_eq!(priv_key.algorithm(), algorithm); - - let pub_key = priv_key.encapsulation_key().unwrap(); - - // Generate public key bytes to send to bob - let pub_key_bytes = pub_key.key_bytes().unwrap(); - - // Test that priv_key's EVP_PKEY isn't entirely freed since we remove this pub_key's reference. - drop(pub_key); - - let retrieved_pub_key = - EncapsulationKey::new(algorithm, pub_key_bytes.as_ref()).unwrap(); - let (ciphertext, bob_secret) = retrieved_pub_key - .encapsulate() - .expect("encapsulate successful"); - - let alice_secret = priv_key - .decapsulate(ciphertext) - .expect("encapsulate successful"); - - assert_eq!(alice_secret.as_ref(), bob_secret.as_ref()); - } - } - - #[test] - fn test_get_algorithm() { - for id in [ - AlgorithmId::Kyber512_R3, - AlgorithmId::Kyber768_R3, - AlgorithmId::Kyber1024_R3, - ] { - let alg = get_algorithm(id).expect("algorithm retrievable"); - assert_eq!(alg.id(), id); - } - } - - #[test] - fn test_debug_fmt() { - let alg = get_algorithm(AlgorithmId::Kyber512_R3).expect("algorithm retrievable"); - let private = DecapsulationKey::generate(alg).expect("successful generation"); - assert_eq!( - format!("{private:?}"), - "DecapsulationKey { algorithm: Kyber512_R3, .. }" - ); - assert_eq!( - format!( - "{:?}", - private.encapsulation_key().expect("public key retrievable") - ), - "EncapsulationKey { algorithm: Kyber512_R3, .. }" - ); - } +pub const fn get_algorithm(_id: AlgorithmId) -> Option<&'static Algorithm> { + None } diff --git a/aws-lc-rs/tests/kdf_test.rs b/aws-lc-rs/tests/kdf_test.rs index 1b32f1e99a6..949c456c8c9 100644 --- a/aws-lc-rs/tests/kdf_test.rs +++ b/aws-lc-rs/tests/kdf_test.rs @@ -5,14 +5,12 @@ use std::error::Error; -use aws_lc_rs::{ - test, test_file, - unstable::kdf::{ - get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, - kbkdf_ctr_hmac, sskdf_digest, sskdf_hmac, KbkdfCtrHmacAlgorithm, KbkdfCtrHmacAlgorithmId, - SskdfDigestAlgorithm, SskdfDigestAlgorithmId, SskdfHmacAlgorithm, SskdfHmacAlgorithmId, - }, +use aws_lc_rs::kdf::{ + get_kbkdf_ctr_hmac_algorithm, get_sskdf_digest_algorithm, get_sskdf_hmac_algorithm, + kbkdf_ctr_hmac, sskdf_digest, sskdf_hmac, KbkdfCtrHmacAlgorithm, KbkdfCtrHmacAlgorithmId, + SskdfDigestAlgorithm, SskdfDigestAlgorithmId, SskdfHmacAlgorithm, SskdfHmacAlgorithmId, }; +use aws_lc_rs::{test, test_file}; #[derive(Clone, Copy)] enum SskdfVariant {