diff --git a/aws-lc-rs/src/agreement.rs b/aws-lc-rs/src/agreement.rs index c844665d3ad..fec5357d684 100644 --- a/aws-lc-rs/src/agreement.rs +++ b/aws-lc-rs/src/agreement.rs @@ -62,9 +62,8 @@ use crate::ptr::ConstPointer; pub use ephemeral::{agree_ephemeral, EphemeralPrivateKey}; use crate::aws_lc::{ - EVP_PKEY_CTX_new_id, EVP_PKEY_derive, EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, - EVP_PKEY_get0_EC_KEY, EVP_PKEY_keygen, EVP_PKEY_keygen_init, NID_X9_62_prime256v1, - NID_secp384r1, NID_secp521r1, EVP_PKEY, EVP_PKEY_X25519, NID_X25519, + EVP_PKEY_derive, EVP_PKEY_derive_init, EVP_PKEY_derive_set_peer, EVP_PKEY_get0_EC_KEY, + NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1, EVP_PKEY, EVP_PKEY_X25519, NID_X25519, }; use crate::buffer::Buffer; @@ -74,6 +73,7 @@ use crate::encoding::{ AsBigEndian, AsDer, Curve25519SeedBin, EcPrivateKeyBin, EcPrivateKeyRfc5915Der, EcPublicKeyCompressedBin, EcPublicKeyUncompressedBin, PublicKeyX509Der, }; +use crate::evp_pkey::No_EVP_PKEY_CTX_consumer; use crate::fips::indicator_check; use crate::ptr::LcPtr; use core::fmt; @@ -482,21 +482,7 @@ impl AsBigEndian> for PrivateKey { } pub(crate) fn generate_x25519() -> Result, Unspecified> { - let mut pkey_ctx = LcPtr::new(unsafe { EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, null_mut()) })?; - - if 1 != unsafe { EVP_PKEY_keygen_init(*pkey_ctx.as_mut()) } { - return Err(Unspecified); - } - - let mut pkey: *mut EVP_PKEY = null_mut(); - - if 1 != indicator_check!(unsafe { EVP_PKEY_keygen(*pkey_ctx.as_mut(), &mut pkey) }) { - return Err(Unspecified); - } - - let pkey = LcPtr::new(pkey)?; - - Ok(pkey) + LcPtr::::generate(EVP_PKEY_X25519, No_EVP_PKEY_CTX_consumer) } const MAX_PUBLIC_KEY_LEN: usize = ec::PUBLIC_KEY_MAX_LEN; diff --git a/aws-lc-rs/src/ec.rs b/aws-lc-rs/src/ec.rs index 1530d558bd0..08557fc5395 100644 --- a/aws-lc-rs/src/ec.rs +++ b/aws-lc-rs/src/ec.rs @@ -4,7 +4,6 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC use crate::ec::signature::AlgorithmID; -use core::ptr::null_mut; // TODO: Uncomment when MSRV >= 1.64 use std::os::raw::c_int; @@ -15,12 +14,12 @@ use crate::aws_lc::EC_KEY_check_key; use crate::aws_lc::{ ECDSA_SIG_from_bytes, ECDSA_SIG_get0_r, ECDSA_SIG_get0_s, EC_GROUP_get_curve_name, EC_KEY_get0_group, EC_group_p224, EC_group_p256, EC_group_p384, EC_group_p521, - EC_group_secp256k1, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_set_ec_paramgen_curve_nid, - EVP_PKEY_get0_EC_KEY, EVP_PKEY_keygen, EVP_PKEY_keygen_init, NID_X9_62_prime256v1, - NID_secp224r1, NID_secp256k1, NID_secp384r1, NID_secp521r1, EC_GROUP, EC_KEY, EVP_PKEY, - EVP_PKEY_EC, + EC_group_secp256k1, EVP_PKEY_CTX_set_ec_paramgen_curve_nid, EVP_PKEY_get0_EC_KEY, + NID_X9_62_prime256v1, NID_secp224r1, NID_secp256k1, NID_secp384r1, NID_secp521r1, EC_GROUP, + EC_KEY, EVP_PKEY, EVP_PKEY_EC, }; use crate::error::{KeyRejected, Unspecified}; +#[cfg(feature = "fips")] use crate::fips::indicator_check; use crate::ptr::{ConstPointer, LcPtr}; use crate::signature::Signature; @@ -85,25 +84,14 @@ pub(crate) fn validate_evp_key( #[inline] pub(crate) fn evp_key_generate(nid: c_int) -> Result, Unspecified> { - let mut pkey_ctx = LcPtr::new(unsafe { EVP_PKEY_CTX_new_id(EVP_PKEY_EC, null_mut()) })?; - - if 1 != unsafe { EVP_PKEY_keygen_init(*pkey_ctx.as_mut()) } { - return Err(Unspecified); - } - - if 1 != unsafe { EVP_PKEY_CTX_set_ec_paramgen_curve_nid(*pkey_ctx.as_mut(), nid) } { - return Err(Unspecified); - } - - let mut pkey = null_mut::(); - - if 1 != indicator_check!(unsafe { EVP_PKEY_keygen(*pkey_ctx.as_mut(), &mut pkey) }) { - return Err(Unspecified); - } - - let pkey = LcPtr::new(pkey)?; - - Ok(pkey) + let params_fn = |ctx| { + if 1 == unsafe { EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) } { + Ok(()) + } else { + Err(()) + } + }; + LcPtr::::generate(EVP_PKEY_EC, Some(params_fn)) } #[inline] diff --git a/aws-lc-rs/src/ed25519.rs b/aws-lc-rs/src/ed25519.rs index 569fccbb6a0..02c2f60de49 100644 --- a/aws-lc-rs/src/ed25519.rs +++ b/aws-lc-rs/src/ed25519.rs @@ -5,15 +5,12 @@ use core::fmt; use core::fmt::{Debug, Formatter}; -use core::ptr::null_mut; use std::marker::PhantomData; #[cfg(feature = "ring-sig-verify")] use untrusted::Input; -use crate::aws_lc::{ - EVP_PKEY_CTX_new_id, EVP_PKEY_keygen, EVP_PKEY_keygen_init, EVP_PKEY, EVP_PKEY_ED25519, -}; +use crate::aws_lc::{EVP_PKEY, EVP_PKEY_ED25519}; use crate::buffer::Buffer; use crate::encoding::{ @@ -21,7 +18,6 @@ use crate::encoding::{ }; use crate::error::{KeyRejected, Unspecified}; use crate::evp_pkey::No_EVP_PKEY_CTX_consumer; -use crate::fips::indicator_check; use crate::pkcs8::{Document, Version}; use crate::ptr::LcPtr; use crate::rand::SecureRandom; @@ -172,22 +168,8 @@ impl KeyPair for Ed25519KeyPair { unsafe impl Send for Ed25519KeyPair {} unsafe impl Sync for Ed25519KeyPair {} -pub(crate) fn generate_key() -> Result, ()> { - let mut pkey_ctx = LcPtr::new(unsafe { EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, null_mut()) })?; - - if 1 != unsafe { EVP_PKEY_keygen_init(*pkey_ctx.as_mut()) } { - return Err(()); - } - - let mut pkey = null_mut::(); - - if 1 != indicator_check!(unsafe { EVP_PKEY_keygen(*pkey_ctx.as_mut(), &mut pkey) }) { - return Err(()); - } - - let pkey = LcPtr::new(pkey)?; - - Ok(pkey) +pub(crate) fn generate_key() -> Result, Unspecified> { + LcPtr::::generate(EVP_PKEY_ED25519, No_EVP_PKEY_CTX_consumer) } impl Ed25519KeyPair { diff --git a/aws-lc-rs/src/evp_pkey.rs b/aws-lc-rs/src/evp_pkey.rs index 8dcbd60ae71..2e30972cf40 100644 --- a/aws-lc-rs/src/evp_pkey.rs +++ b/aws-lc-rs/src/evp_pkey.rs @@ -3,11 +3,12 @@ use crate::aws_lc::{ EVP_DigestSign, EVP_DigestSignInit, EVP_DigestVerify, EVP_DigestVerifyInit, EVP_PKEY_CTX_new, - EVP_PKEY_bits, EVP_PKEY_cmp, EVP_PKEY_get0_EC_KEY, EVP_PKEY_get0_RSA, EVP_PKEY_get_raw_private_key, - EVP_PKEY_get_raw_public_key, EVP_PKEY_id, EVP_PKEY_new_raw_private_key, - EVP_PKEY_new_raw_public_key, EVP_PKEY_size, EVP_PKEY_up_ref, EVP_marshal_private_key, - EVP_marshal_private_key_v2, EVP_marshal_public_key, EVP_parse_private_key, - EVP_parse_public_key, EC_KEY, EVP_PKEY, EVP_PKEY_CTX, EVP_PKEY_ED25519, RSA, + EVP_PKEY_CTX_new_id, EVP_PKEY_bits, EVP_PKEY_cmp, EVP_PKEY_get0_EC_KEY, EVP_PKEY_get0_RSA, + EVP_PKEY_get_raw_private_key, EVP_PKEY_get_raw_public_key, EVP_PKEY_id, EVP_PKEY_keygen, + EVP_PKEY_keygen_init, EVP_PKEY_new_raw_private_key, EVP_PKEY_new_raw_public_key, EVP_PKEY_size, + EVP_PKEY_up_ref, EVP_marshal_private_key, EVP_marshal_private_key_v2, EVP_marshal_public_key, + EVP_parse_private_key, EVP_parse_public_key, EC_KEY, EVP_PKEY, EVP_PKEY_CTX, EVP_PKEY_ED25519, + RSA, }; #[cfg(not(feature = "fips"))] use crate::aws_lc::{ @@ -39,7 +40,7 @@ pub(crate) trait EVP_PKEY_CTX_consumer: Fn(*mut EVP_PKEY_CTX) -> Result<(), ()> impl EVP_PKEY_CTX_consumer for T where T: Fn(*mut EVP_PKEY_CTX) -> Result<(), ()> {} -#[allow(non_upper_case_globals)] +#[allow(non_upper_case_globals, clippy::type_complexity)] pub(crate) const No_EVP_PKEY_CTX_consumer: Option Result<(), ()>> = None; impl LcPtr { @@ -409,6 +410,29 @@ impl LcPtr { Ok(()) } + + pub(crate) fn generate(pkey_type: c_int, params_fn: Option) -> Result + where + F: EVP_PKEY_CTX_consumer, + { + let mut pkey_ctx = LcPtr::new(unsafe { EVP_PKEY_CTX_new_id(pkey_type, null_mut()) })?; + + if 1 != unsafe { EVP_PKEY_keygen_init(*pkey_ctx.as_mut()) } { + return Err(Unspecified); + } + + if let Some(pad_fn) = params_fn { + pad_fn(*pkey_ctx.as_mut())?; + } + + let mut pkey = null_mut::(); + + if 1 != indicator_check!(unsafe { EVP_PKEY_keygen(*pkey_ctx.as_mut(), &mut pkey) }) { + return Err(Unspecified); + } + + Ok(LcPtr::new(pkey)?) + } } impl Clone for LcPtr { diff --git a/aws-lc-rs/src/kem.rs b/aws-lc-rs/src/kem.rs index 39d8b600dc3..8a54a5498e0 100644 --- a/aws-lc-rs/src/kem.rs +++ b/aws-lc-rs/src/kem.rs @@ -46,8 +46,8 @@ //! # Ok::<(), aws_lc_rs::error::Unspecified>(()) //! ``` use crate::aws_lc::{ - EVP_PKEY_CTX_kem_set_params, EVP_PKEY_CTX_new_id, EVP_PKEY_decapsulate, EVP_PKEY_encapsulate, - EVP_PKEY_kem_new_raw_public_key, EVP_PKEY_keygen, EVP_PKEY_keygen_init, EVP_PKEY, EVP_PKEY_KEM, + EVP_PKEY_CTX_kem_set_params, EVP_PKEY_decapsulate, EVP_PKEY_encapsulate, + EVP_PKEY_kem_new_raw_public_key, EVP_PKEY, EVP_PKEY_KEM, }; use crate::buffer::Buffer; use crate::encoding::generated_encodings; @@ -55,7 +55,6 @@ use crate::error::{KeyRejected, Unspecified}; use crate::ptr::LcPtr; use alloc::borrow::Cow; use core::cmp::Ordering; -use core::ptr::null_mut; use zeroize::Zeroize; const ML_KEM_512_SHARED_SECRET_LENGTH: usize = 32; @@ -469,18 +468,15 @@ impl AsRef<[u8]> for SharedSecret { // Returns an LcPtr to an EVP_PKEY #[inline] fn kem_key_generate(nid: i32) -> Result, Unspecified> { - let mut ctx = LcPtr::new(unsafe { EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, null_mut()) })?; - if 1 != unsafe { EVP_PKEY_CTX_kem_set_params(*ctx.as_mut(), nid) } - || 1 != unsafe { EVP_PKEY_keygen_init(*ctx.as_mut()) } - { - return Err(Unspecified); - } + let params_fn = |ctx| { + if 1 == unsafe { EVP_PKEY_CTX_kem_set_params(ctx, nid) } { + Ok(()) + } else { + Err(()) + } + }; - let mut key_raw: *mut EVP_PKEY = null_mut(); - if 1 != unsafe { EVP_PKEY_keygen(*ctx.as_mut(), &mut key_raw) } { - return Err(Unspecified); - } - Ok(LcPtr::new(key_raw)?) + LcPtr::::generate(EVP_PKEY_KEM, Some(params_fn)) } #[cfg(test)] diff --git a/aws-lc-rs/src/pq.rs b/aws-lc-rs/src/pq.rs index ab5f48fe51e..3b5b37ba1d4 100644 --- a/aws-lc-rs/src/pq.rs +++ b/aws-lc-rs/src/pq.rs @@ -4,10 +4,9 @@ use crate::aws_lc::{ d2i_PrivateKey, CBB_init, EVP_PKEY_CTX_new_id, EVP_PKEY_CTX_pqdsa_set_params, - EVP_PKEY_get_raw_private_key, EVP_PKEY_get_raw_public_key, EVP_PKEY_keygen, - EVP_PKEY_keygen_init, EVP_PKEY_new, EVP_PKEY_pqdsa_new_raw_private_key, - EVP_PKEY_pqdsa_new_raw_public_key, EVP_marshal_private_key, EVP_marshal_public_key, - EVP_parse_public_key, CBB, EVP_PKEY, EVP_PKEY_PQDSA, + EVP_PKEY_get_raw_private_key, EVP_PKEY_get_raw_public_key, EVP_PKEY_new, + EVP_PKEY_pqdsa_new_raw_private_key, EVP_PKEY_pqdsa_new_raw_public_key, EVP_marshal_private_key, + EVP_marshal_public_key, EVP_parse_public_key, CBB, EVP_PKEY, EVP_PKEY_PQDSA, }; use crate::cbb::LcCBB; use crate::cbs::build_CBS; @@ -18,29 +17,18 @@ use crate::evp_pkey::*; use crate::fips::indicator_check; use crate::ptr::LcPtr; use crate::signature::MAX_LEN; -use std::ffi::c_int; +use std::os::raw::c_int; use std::ptr::null_mut; pub(crate) fn evp_key_pqdsa_generate(nid: c_int) -> Result, Unspecified> { - let mut pkey_ctx = LcPtr::new(unsafe { EVP_PKEY_CTX_new_id(EVP_PKEY_PQDSA, null_mut()) })?; - - if 1 != unsafe { EVP_PKEY_keygen_init(*pkey_ctx.as_mut()) } { - return Err(Unspecified); - } - - if 1 != unsafe { EVP_PKEY_CTX_pqdsa_set_params(*pkey_ctx.as_mut(), nid) } { - return Err(Unspecified); - } - - let mut pkey = null_mut::(); - - if 1 != indicator_check!(unsafe { EVP_PKEY_keygen(*pkey_ctx.as_mut(), &mut pkey) }) { - return Err(Unspecified); - } - - let pkey = LcPtr::new(pkey)?; - - Ok(pkey) + let params_fn = |ctx| { + if 1 == unsafe { EVP_PKEY_CTX_pqdsa_set_params(ctx, nid) } { + return Ok(()); + } else { + return Err(()); + } + }; + LcPtr::::generate(EVP_PKEY_PQDSA, Some(params_fn)) } #[cfg(test)] diff --git a/aws-lc-rs/src/rsa/encryption.rs b/aws-lc-rs/src/rsa/encryption.rs index b2c4e8ffe17..d31187754e3 100644 --- a/aws-lc-rs/src/rsa/encryption.rs +++ b/aws-lc-rs/src/rsa/encryption.rs @@ -61,7 +61,7 @@ impl PrivateDecryptingKey { /// # Errors /// * `Unspecified` for any error that occurs during the generation of the RSA keypair. pub fn generate(size: KeySize) -> Result { - let key = generate_rsa_key(size.bits(), false)?; + let key = generate_rsa_key(size.bits())?; Self::new(key) } @@ -71,13 +71,17 @@ impl PrivateDecryptingKey { /// * `KeySize::Rsa2048` /// * `KeySize::Rsa3072` /// * `KeySize::Rsa4096` + /// * `KeySize::Rsa8192` + /// + /// ## Deprecated + /// This is equivalent to `KeyPair::generate`. /// /// # Errors - /// * `Unspecified`: Any key generation failure. + /// * `Unspecified` for any error that occurs during the generation of the RSA keypair. #[cfg(feature = "fips")] + #[deprecated] pub fn generate_fips(size: KeySize) -> Result { - let key = generate_rsa_key(size.bits(), true)?; - Self::new(key) + Self::generate(size) } /// Construct a `PrivateDecryptingKey` from the provided PKCS#8 (v1) document. diff --git a/aws-lc-rs/src/rsa/key.rs b/aws-lc-rs/src/rsa/key.rs index e131edee254..de3fcae7a3d 100644 --- a/aws-lc-rs/src/rsa/key.rs +++ b/aws-lc-rs/src/rsa/key.rs @@ -7,14 +7,13 @@ use super::{encoding, RsaParameters}; #[cfg(feature = "fips")] use crate::aws_lc::RSA; use crate::aws_lc::{ - EVP_PKEY_assign_RSA, EVP_PKEY_new, RSA_generate_key_ex, RSA_generate_key_fips, RSA_new, - RSA_set0_key, RSA_size, BIGNUM, EVP_PKEY, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, + EVP_PKEY_CTX_set_rsa_keygen_bits, EVP_PKEY_assign_RSA, EVP_PKEY_new, RSA_new, RSA_set0_key, + RSA_size, EVP_PKEY, EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, }; #[cfg(feature = "ring-io")] use crate::aws_lc::{RSA_get0_e, RSA_get0_n}; use crate::encoding::{AsDer, Pkcs8V1Der}; use crate::error::{KeyRejected, Unspecified}; -use crate::fips::indicator_check; #[cfg(feature = "ring-io")] use crate::io; #[cfg(feature = "ring-io")] @@ -111,26 +110,30 @@ impl KeyPair { /// Generate a RSA `KeyPair` of the specified key-strength. /// + /// Supports the following key sizes: + /// * `KeySize::Rsa2048` + /// * `KeySize::Rsa3072` + /// * `KeySize::Rsa4096` + /// * `KeySize::Rsa8192` + /// /// # Errors /// * `Unspecified`: Any key generation failure. pub fn generate(size: KeySize) -> Result { - let private_key = generate_rsa_key(size.bits(), false)?; + let private_key = generate_rsa_key(size.bits())?; Ok(Self::new(private_key)?) } /// Generate a RSA `KeyPair` of the specified key-strength. /// - /// Supports the following key sizes: - /// * `SignatureKeySize::Rsa2048` - /// * `SignatureKeySize::Rsa3072` - /// * `SignatureKeySize::Rsa4096` + /// ## Deprecated + /// This is equivalent to `KeyPair::generate`. /// /// # Errors /// * `Unspecified`: Any key generation failure. #[cfg(feature = "fips")] + #[deprecated] pub fn generate_fips(size: KeySize) -> Result { - let private_key = generate_rsa_key(size.bits(), true)?; - Ok(Self::new(private_key)?) + Self::generate(size) } /// Parses an unencrypted PKCS#8 DER encoded RSA private key. @@ -443,33 +446,16 @@ where } } -pub(super) fn generate_rsa_key(size: c_int, fips: bool) -> Result, Unspecified> { - // We explicitly don't use `EVP_PKEY_keygen`, as it will force usage of either the FIPS or non-FIPS - // keygen function based on the whether the build of AWS-LC had FIPS enbaled. Rather we delegate to the desired - // generation function. - - const RSA_F4: u64 = 65537; - - let mut rsa = DetachableLcPtr::new(unsafe { RSA_new() })?; - - if 1 != if fips { - indicator_check!(unsafe { RSA_generate_key_fips(*rsa.as_mut(), size, null_mut()) }) - } else { - let e: LcPtr = RSA_F4.try_into()?; - unsafe { RSA_generate_key_ex(*rsa.as_mut(), size, *e.as_const(), null_mut()) } - } { - return Err(Unspecified); - } - - let mut evp_pkey = LcPtr::new(unsafe { EVP_PKEY_new() })?; - - if 1 != unsafe { EVP_PKEY_assign_RSA(*evp_pkey.as_mut(), *rsa) } { - return Err(Unspecified); - } - - rsa.detach(); +pub(super) fn generate_rsa_key(size: c_int) -> Result, Unspecified> { + let params_fn = |ctx| { + if 1 == unsafe { EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, size) } { + Ok(()) + } else { + Err(()) + } + }; - Ok(evp_pkey) + LcPtr::::generate(EVP_PKEY_RSA, Some(params_fn)) } #[cfg(feature = "fips")] diff --git a/aws-lc-rs/src/rsa/tests/fips.rs b/aws-lc-rs/src/rsa/tests/fips.rs index c2c0ac19654..7c1c8223b9b 100644 --- a/aws-lc-rs/src/rsa/tests/fips.rs +++ b/aws-lc-rs/src/rsa/tests/fips.rs @@ -11,13 +11,15 @@ macro_rules! generate_key { #[test] fn $name() { // Using the non-fips generator will not set the indicator + #[cfg(not(feature = "fips"))] let _ = assert_fips_status_indicator!(KeyPair::generate($size), FipsServiceStatus::Unset) .expect("key generated"); // Using the fips generator should set the indicator + #[cfg(feature = "fips")] let _ = assert_fips_status_indicator!( - KeyPair::generate_fips($size), + KeyPair::generate($size), FipsServiceStatus::Approved ) .expect("key generated"); @@ -27,6 +29,7 @@ macro_rules! generate_key { #[test] fn $name() { // Using the non-fips generator will not set the indicator + #[cfg(not(feature = "fips"))] let _ = assert_fips_status_indicator!( PrivateDecryptingKey::generate($size), FipsServiceStatus::Unset @@ -34,8 +37,9 @@ macro_rules! generate_key { .expect("key generated"); // Using the fips generator should set the indicator + #[cfg(feature = "fips")] let _ = assert_fips_status_indicator!( - PrivateDecryptingKey::generate_fips($size), + PrivateDecryptingKey::generate($size), FipsServiceStatus::Approved ) .expect("key generated"); diff --git a/aws-lc-rs/tests/rsa_test.rs b/aws-lc-rs/tests/rsa_test.rs index c8953a3f225..b9b128c7e68 100644 --- a/aws-lc-rs/tests/rsa_test.rs +++ b/aws-lc-rs/tests/rsa_test.rs @@ -317,7 +317,7 @@ macro_rules! generate_fips_encode_decode { #[cfg(feature = "fips")] #[test] fn $name() { - let private_key = RsaKeyPair::generate_fips($size).expect("generation"); + let private_key = RsaKeyPair::generate($size).expect("generation"); assert_eq!(true, private_key.is_valid_fips_key()); @@ -388,7 +388,7 @@ macro_rules! encryption_generate_fips_encode_decode { #[cfg(feature = "fips")] #[test] fn $name() { - let private_key = PrivateDecryptingKey::generate_fips($size).expect("generation"); + let private_key = PrivateDecryptingKey::generate($size).expect("generation"); assert_eq!(true, private_key.is_valid_fips_key());