From c86ff9fdbf056483ad5e1a95fd21e6d42e6d3a8d Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Mon, 10 Feb 2025 17:25:08 -0500 Subject: [PATCH 1/4] Ensure ConstPointers don't outlive parent --- aws-lc-rs/src/agreement.rs | 9 +++--- aws-lc-rs/src/bn.rs | 2 +- aws-lc-rs/src/cipher.rs | 32 ++++++++++--------- aws-lc-rs/src/digest.rs | 2 +- aws-lc-rs/src/ec.rs | 45 +++++++++++++++------------ aws-lc-rs/src/ec/encoding.rs | 26 +++++++++++----- aws-lc-rs/src/evp_pkey.rs | 14 ++++----- aws-lc-rs/src/ptr.rs | 59 ++++++++++++++++++++++++++++++------ aws-lc-rs/src/rsa/key.rs | 8 ++--- 9 files changed, 128 insertions(+), 69 deletions(-) diff --git a/aws-lc-rs/src/agreement.rs b/aws-lc-rs/src/agreement.rs index ae0b979eb5c..b684b4a33fb 100644 --- a/aws-lc-rs/src/agreement.rs +++ b/aws-lc-rs/src/agreement.rs @@ -62,7 +62,6 @@ use crate::ec::verify_evp_key_nid; use crate::ec::{encoding, evp_key_generate}; use crate::error::{KeyRejected, Unspecified}; use crate::hex; -use crate::ptr::ConstPointer; pub use ephemeral::{agree_ephemeral, EphemeralPrivateKey}; use crate::aws_lc::{ @@ -448,9 +447,11 @@ impl AsDer> for PrivateKey { let mut outp = null_mut::(); let ec_key = { - ConstPointer::new(unsafe { - EVP_PKEY_get0_EC_KEY(*self.inner_key.get_evp_pkey().as_const()) - })? + self.inner_key + .get_evp_pkey() + .project_const_lifetime(unsafe { + |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) + })? }; let length = usize::try_from(unsafe { aws_lc::i2d_ECPrivateKey(*ec_key, &mut outp) }) .map_err(|_| Unspecified)?; diff --git a/aws-lc-rs/src/bn.rs b/aws-lc-rs/src/bn.rs index d84e0639959..a32370781f8 100644 --- a/aws-lc-rs/src/bn.rs +++ b/aws-lc-rs/src/bn.rs @@ -35,7 +35,7 @@ impl TryFrom for DetachableLcPtr { } } -impl ConstPointer { +impl ConstPointer<'_, BIGNUM> { pub(crate) fn to_be_bytes(&self) -> Vec { unsafe { let bn_bytes = BN_num_bytes(**self); diff --git a/aws-lc-rs/src/cipher.rs b/aws-lc-rs/src/cipher.rs index 7d83747035d..4c806252ff6 100644 --- a/aws-lc-rs/src/cipher.rs +++ b/aws-lc-rs/src/cipher.rs @@ -285,21 +285,23 @@ pub enum OperatingMode { impl OperatingMode { fn evp_cipher(&self, algorithm: &Algorithm) -> ConstPointer { - ConstPointer::new(match (self, algorithm.id) { - (OperatingMode::CBC, AlgorithmId::Aes128) => unsafe { EVP_aes_128_cbc() }, - (OperatingMode::CTR, AlgorithmId::Aes128) => unsafe { EVP_aes_128_ctr() }, - (OperatingMode::CFB128, AlgorithmId::Aes128) => unsafe { EVP_aes_128_cfb128() }, - (OperatingMode::ECB, AlgorithmId::Aes128) => unsafe { EVP_aes_128_ecb() }, - (OperatingMode::CBC, AlgorithmId::Aes192) => unsafe { EVP_aes_192_cbc() }, - (OperatingMode::CTR, AlgorithmId::Aes192) => unsafe { EVP_aes_192_ctr() }, - (OperatingMode::CFB128, AlgorithmId::Aes192) => unsafe { EVP_aes_192_cfb128() }, - (OperatingMode::ECB, AlgorithmId::Aes192) => unsafe { EVP_aes_192_ecb() }, - (OperatingMode::CBC, AlgorithmId::Aes256) => unsafe { EVP_aes_256_cbc() }, - (OperatingMode::CTR, AlgorithmId::Aes256) => unsafe { EVP_aes_256_ctr() }, - (OperatingMode::CFB128, AlgorithmId::Aes256) => unsafe { EVP_aes_256_cfb128() }, - (OperatingMode::ECB, AlgorithmId::Aes256) => unsafe { EVP_aes_256_ecb() }, - }) - .unwrap() + unsafe { + ConstPointer::new_static(match (self, algorithm.id) { + (OperatingMode::CBC, AlgorithmId::Aes128) => EVP_aes_128_cbc(), + (OperatingMode::CTR, AlgorithmId::Aes128) => EVP_aes_128_ctr(), + (OperatingMode::CFB128, AlgorithmId::Aes128) => EVP_aes_128_cfb128(), + (OperatingMode::ECB, AlgorithmId::Aes128) => EVP_aes_128_ecb(), + (OperatingMode::CBC, AlgorithmId::Aes192) => EVP_aes_192_cbc(), + (OperatingMode::CTR, AlgorithmId::Aes192) => EVP_aes_192_ctr(), + (OperatingMode::CFB128, AlgorithmId::Aes192) => EVP_aes_192_cfb128(), + (OperatingMode::ECB, AlgorithmId::Aes192) => EVP_aes_192_ecb(), + (OperatingMode::CBC, AlgorithmId::Aes256) => EVP_aes_256_cbc(), + (OperatingMode::CTR, AlgorithmId::Aes256) => EVP_aes_256_ctr(), + (OperatingMode::CFB128, AlgorithmId::Aes256) => EVP_aes_256_cfb128(), + (OperatingMode::ECB, AlgorithmId::Aes256) => EVP_aes_256_ecb(), + }) + .unwrap() + } } } diff --git a/aws-lc-rs/src/digest.rs b/aws-lc-rs/src/digest.rs index c56c9c449f5..c881d63043b 100644 --- a/aws-lc-rs/src/digest.rs +++ b/aws-lc-rs/src/digest.rs @@ -342,7 +342,7 @@ pub const MAX_CHAINING_LEN: usize = MAX_OUTPUT_LEN; /// Match digest types for `EVP_MD` functions. pub(crate) fn match_digest_type(algorithm_id: &AlgorithmID) -> ConstPointer { unsafe { - ConstPointer::new(match algorithm_id { + ConstPointer::new_static(match algorithm_id { AlgorithmID::SHA1 => EVP_sha1(), AlgorithmID::SHA224 => EVP_sha224(), AlgorithmID::SHA256 => EVP_sha256(), diff --git a/aws-lc-rs/src/ec.rs b/aws-lc-rs/src/ec.rs index 76e6b242396..c7943c92b7b 100644 --- a/aws-lc-rs/src/ec.rs +++ b/aws-lc-rs/src/ec.rs @@ -5,8 +5,6 @@ use crate::ec::signature::AlgorithmID; // TODO: Uncomment when MSRV >= 1.64 -use std::os::raw::c_int; - #[cfg(feature = "fips")] use crate::aws_lc::EC_KEY_check_fips; #[cfg(not(feature = "fips"))] @@ -23,6 +21,8 @@ use crate::error::{KeyRejected, Unspecified}; use crate::fips::indicator_check; use crate::ptr::{ConstPointer, LcPtr}; use crate::signature::Signature; +use std::os::raw::c_int; +use std::ptr::null; pub(crate) mod encoding; pub(crate) mod key_pair; @@ -38,7 +38,8 @@ fn verify_ec_key_nid( ec_key: &ConstPointer, expected_curve_nid: i32, ) -> Result<(), KeyRejected> { - let ec_group = ConstPointer::new(unsafe { EC_KEY_get0_group(**ec_key) })?; + let ec_group = + ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_group(**ec_key) })?; let key_nid = unsafe { EC_GROUP_get_curve_name(*ec_group) }; if key_nid != expected_curve_nid { @@ -53,7 +54,8 @@ pub(crate) fn verify_evp_key_nid( evp_pkey: &ConstPointer, expected_curve_nid: i32, ) -> Result<(), KeyRejected> { - let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(**evp_pkey) })?; + let ec_key = + evp_pkey.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_EC_KEY(**evp_pkey) })?; verify_ec_key_nid(&ec_key, expected_curve_nid)?; Ok(()) @@ -64,7 +66,8 @@ pub(crate) fn validate_ec_evp_key( evp_pkey: &ConstPointer, expected_curve_nid: i32, ) -> Result<(), KeyRejected> { - let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(**evp_pkey) })?; + let ec_key = + evp_pkey.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_EC_KEY(**evp_pkey) })?; verify_ec_key_nid(&ec_key, expected_curve_nid)?; #[cfg(not(feature = "fips"))] @@ -94,18 +97,20 @@ pub(crate) fn evp_key_generate(nid: c_int) -> Result, Unspecifie #[inline] #[allow(non_upper_case_globals)] -pub(crate) fn ec_group_from_nid(nid: i32) -> Result, Unspecified> { - Ok(ConstPointer::new(match nid { - NID_secp224r1 => Ok(unsafe { EC_group_p224() }), - NID_X9_62_prime256v1 => Ok(unsafe { EC_group_p256() }), - NID_secp384r1 => Ok(unsafe { EC_group_p384() }), - NID_secp521r1 => Ok(unsafe { EC_group_p521() }), - NID_secp256k1 => Ok(unsafe { EC_group_secp256k1() }), - _ => { - // OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); - Err(Unspecified) - } - }?)?) +pub(crate) fn ec_group_from_nid(nid: i32) -> Result, Unspecified> { + Ok(unsafe { + ConstPointer::new_static(match nid { + NID_secp224r1 => EC_group_p224(), + NID_X9_62_prime256v1 => EC_group_p256(), + NID_secp384r1 => EC_group_p384(), + NID_secp521r1 => EC_group_p521(), + NID_secp256k1 => EC_group_secp256k1(), + _ => { + // OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + null() + } + })? + }) } #[inline] @@ -114,10 +119,12 @@ fn ecdsa_asn1_to_fixed(alg_id: &'static AlgorithmID, sig: &[u8]) -> Result, compressed: bool, ) -> Result<(), Unspecified> { - let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?; - let ec_group = ConstPointer::new(unsafe { EC_KEY_get0_group(*ec_key) })?; - let ec_point = ConstPointer::new(unsafe { EC_KEY_get0_public_key(*ec_key) })?; + let ec_key = evp_pkey.project_const_lifetime(unsafe { + |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) + })?; + let ec_group = + ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_group(**ec_key) })?; + let ec_point = + ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_public_key(**ec_key) })?; let point_conversion_form = if compressed { point_conversion_form_t::POINT_CONVERSION_COMPRESSED @@ -186,8 +190,11 @@ pub(crate) mod sec1 { pub(crate) fn marshal_sec1_private_key( evp_pkey: &LcPtr, ) -> Result, Unspecified> { - let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?; - let ec_group = ConstPointer::new(unsafe { EC_KEY_get0_group(*ec_key) })?; + let ec_key = evp_pkey.project_const_lifetime(unsafe { + |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) + })?; + let ec_group = + ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_group(**ec_key) })?; let nid = unsafe { EC_GROUP_get_curve_name(*ec_group) }; #[allow(non_upper_case_globals)] let key_size: usize = match nid { @@ -196,7 +203,8 @@ pub(crate) mod sec1 { NID_secp521r1 => Ok(66usize), _ => Err(Unspecified), }?; - let private_bn = ConstPointer::new(unsafe { EC_KEY_get0_private_key(*ec_key) })?; + let private_bn = + ec_key.project_const_lifetime(unsafe { |ec_key| EC_KEY_get0_private_key(**ec_key) })?; let mut cbb = LcCBB::new(key_size); if 1 != unsafe { BN_bn2cbb_padded(cbb.as_mut_ptr(), key_size, *private_bn) } { @@ -215,7 +223,7 @@ pub(crate) mod rfc5915 { use crate::cbs::build_CBS; use crate::ec::ec_group_from_nid; use crate::error::{KeyRejected, Unspecified}; - use crate::ptr::{ConstPointer, LcPtr}; + use crate::ptr::LcPtr; pub(crate) fn parse_rfc5915_private_key( key_bytes: &[u8], @@ -234,7 +242,9 @@ pub(crate) mod rfc5915 { pub(crate) fn marshal_rfc5915_private_key( evp_pkey: &LcPtr, ) -> Result, Unspecified> { - let ec_key = ConstPointer::new(unsafe { EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?; + let ec_key = evp_pkey.project_const_lifetime(unsafe { + |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) + })?; let mut cbb = LcCBB::new(evp_pkey.key_size_bytes()); let enc_flags = unsafe { EC_KEY_get_enc_flags(*ec_key) }; if 1 != unsafe { EC_KEY_marshal_private_key(cbb.as_mut_ptr(), *ec_key, enc_flags) } { diff --git a/aws-lc-rs/src/evp_pkey.rs b/aws-lc-rs/src/evp_pkey.rs index 246f15a5b38..337215c8017 100644 --- a/aws-lc-rs/src/evp_pkey.rs +++ b/aws-lc-rs/src/evp_pkey.rs @@ -100,17 +100,15 @@ impl LcPtr { #[allow(dead_code)] pub(crate) fn get_ec_key(&self) -> Result, KeyRejected> { - unsafe { - ConstPointer::new(EVP_PKEY_get0_EC_KEY(*self.as_const())) - .map_err(|()| KeyRejected::wrong_algorithm()) - } + self.project_const_lifetime(unsafe { + |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) + }) + .map_err(|()| KeyRejected::wrong_algorithm()) } pub(crate) fn get_rsa(&self) -> Result, KeyRejected> { - unsafe { - ConstPointer::new(EVP_PKEY_get0_RSA(*self.as_const())) - .map_err(|()| KeyRejected::wrong_algorithm()) - } + self.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_RSA(*evp_pkey.as_const()) }) + .map_err(|()| KeyRejected::wrong_algorithm()) } pub(crate) fn marshal_rfc5280_public_key(&self) -> Result, Unspecified> { diff --git a/aws-lc-rs/src/ptr.rs b/aws-lc-rs/src/ptr.rs index 9f714d5dfd8..b8f9248f3d8 100644 --- a/aws-lc-rs/src/ptr.rs +++ b/aws-lc-rs/src/ptr.rs @@ -1,14 +1,14 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -use core::ops::Deref; - use crate::aws_lc::{ BN_free, ECDSA_SIG_free, EC_GROUP_free, EC_KEY_free, EC_POINT_free, EVP_AEAD_CTX_free, EVP_CIPHER_CTX_free, EVP_PKEY_CTX_free, EVP_PKEY_free, OPENSSL_free, RSA_free, BIGNUM, ECDSA_SIG, EC_GROUP, EC_KEY, EC_POINT, EVP_AEAD_CTX, EVP_CIPHER_CTX, EVP_PKEY, EVP_PKEY_CTX, RSA, }; +use core::ops::Deref; +use std::marker::PhantomData; pub(crate) type LcPtr = ManagedPointer<*mut T>; pub(crate) type DetachableLcPtr = DetachablePointer<*mut T>; @@ -40,12 +40,33 @@ impl Drop for ManagedPointer

{ } } +impl<'a, P: Pointer> From<&'a ManagedPointer

> for ConstPointer<'a, P::T> { + fn from(ptr: &'a ManagedPointer

) -> ConstPointer<'a, P::T> { + ConstPointer { + ptr: ptr.pointer.as_const_ptr(), + _lifetime: PhantomData, + } + } +} + impl ManagedPointer

{ #[inline] pub fn as_const(&self) -> ConstPointer { - ConstPointer { - ptr: self.pointer.as_const_ptr(), + self.into() + } + + pub fn project_const_lifetime<'a, C>( + &'a self, + f: unsafe fn(&'a Self) -> *const C, + ) -> Result, ()> { + let ptr = unsafe { f(self) }; + if ptr.is_null() { + return Err(()); } + Ok(ConstPointer { + ptr, + _lifetime: PhantomData, + }) } #[inline] @@ -133,20 +154,40 @@ impl Drop for DetachablePointer

{ } #[derive(Debug)] -pub(crate) struct ConstPointer { +pub(crate) struct ConstPointer<'a, T> { ptr: *const T, + _lifetime: PhantomData<&'a T>, +} + +impl ConstPointer<'static, T> { + pub unsafe fn new_static(ptr: *const T) -> Result { + if ptr.is_null() { + return Err(()); + } + Ok(ConstPointer { + ptr, + _lifetime: PhantomData, + }) + } } -impl ConstPointer { - pub fn new(ptr: *const T) -> Result, ()> { +impl ConstPointer<'_, T> { + pub fn project_const_lifetime<'a, C>( + &'a self, + f: unsafe fn(&'a Self) -> *const C, + ) -> Result, ()> { + let ptr = unsafe { f(self) }; if ptr.is_null() { return Err(()); } - Ok(ConstPointer { ptr }) + Ok(ConstPointer { + ptr, + _lifetime: PhantomData, + }) } } -impl Deref for ConstPointer { +impl Deref for ConstPointer<'_, T> { type Target = *const T; fn deref(&self) -> &Self::Target { diff --git a/aws-lc-rs/src/rsa/key.rs b/aws-lc-rs/src/rsa/key.rs index 5dcc618b8ff..bf4e2382ef7 100644 --- a/aws-lc-rs/src/rsa/key.rs +++ b/aws-lc-rs/src/rsa/key.rs @@ -16,8 +16,6 @@ use crate::encoding::{AsDer, Pkcs8V1Der, PublicKeyX509Der}; use crate::error::{KeyRejected, Unspecified}; #[cfg(feature = "ring-io")] use crate::io; -#[cfg(feature = "ring-io")] -use crate::ptr::ConstPointer; use crate::ptr::{DetachableLcPtr, LcPtr}; use crate::rsa::PublicEncryptingKey; use crate::sealed::Sealed; @@ -294,9 +292,11 @@ impl PublicKey { #[cfg(feature = "ring-io")] { let pubkey = evp_pkey.get_rsa()?; - let modulus = ConstPointer::new(unsafe { RSA_get0_n(*pubkey) })?; + let modulus = + pubkey.project_const_lifetime(unsafe { |pubkey| RSA_get0_n(**pubkey) })?; let modulus = modulus.to_be_bytes().into_boxed_slice(); - let exponent = ConstPointer::new(unsafe { RSA_get0_e(*pubkey) })?; + let exponent = + pubkey.project_const_lifetime(unsafe { |pubkey| RSA_get0_e(**pubkey) })?; let exponent = exponent.to_be_bytes().into_boxed_slice(); Ok(PublicKey { key, From a20c69a5d9f8d6a53546d4980558be3c0c7a66e5 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Tue, 11 Feb 2025 09:51:50 -0500 Subject: [PATCH 2/4] Migrate functionality to ConstPointer<'_, EVP_PKEY> --- aws-lc-rs/src/agreement.rs | 11 ++- aws-lc-rs/src/ec/encoding.rs | 6 +- aws-lc-rs/src/ec/key_pair.rs | 4 +- aws-lc-rs/src/ec/signature.rs | 2 +- aws-lc-rs/src/ed25519.rs | 24 +++--- aws-lc-rs/src/evp_pkey.rs | 122 +++++++++++++++---------------- aws-lc-rs/src/kem.rs | 2 +- aws-lc-rs/src/pqdsa.rs | 17 +++-- aws-lc-rs/src/pqdsa/key_pair.rs | 6 +- aws-lc-rs/src/pqdsa/signature.rs | 4 +- aws-lc-rs/src/rsa/encoding.rs | 4 +- aws-lc-rs/src/rsa/encryption.rs | 14 ++-- aws-lc-rs/src/rsa/key.rs | 14 ++-- aws-lc-rs/src/rsa/signature.rs | 4 +- 14 files changed, 122 insertions(+), 112 deletions(-) diff --git a/aws-lc-rs/src/agreement.rs b/aws-lc-rs/src/agreement.rs index b684b4a33fb..61a3876ea4e 100644 --- a/aws-lc-rs/src/agreement.rs +++ b/aws-lc-rs/src/agreement.rs @@ -415,7 +415,9 @@ impl PrivateKey { } KeyInner::X25519(priv_key) => { let mut buffer = [0u8; MAX_PUBLIC_KEY_LEN]; - let out_len = priv_key.marshal_raw_public_to_buffer(&mut buffer)?; + let out_len = priv_key + .as_const() + .marshal_raw_public_to_buffer(&mut buffer)?; Ok(PublicKey { inner_key: self.inner_key.clone(), key_bytes: buffer, @@ -477,6 +479,7 @@ impl AsDer> for PrivateKey { Ok(Pkcs8V1Der::new( self.inner_key .get_evp_pkey() + .as_const() .marshal_rfc5208_private_key(Version::V1)?, )) } @@ -510,7 +513,9 @@ impl AsBigEndian> for PrivateKey { return Err(Unspecified); } let evp_pkey = self.inner_key.get_evp_pkey(); - Ok(Curve25519SeedBin::new(evp_pkey.marshal_raw_private_key()?)) + Ok(Curve25519SeedBin::new( + evp_pkey.as_const().marshal_raw_private_key()?, + )) } } @@ -577,7 +582,7 @@ impl AsDer> for PublicKey { | KeyInner::ECDH_P384(evp_pkey) | KeyInner::ECDH_P521(evp_pkey) | KeyInner::X25519(evp_pkey) => { - let der = evp_pkey.marshal_rfc5280_public_key()?; + let der = evp_pkey.as_const().marshal_rfc5280_public_key()?; Ok(PublicKeyX509Der::from(Buffer::new(der))) } } diff --git a/aws-lc-rs/src/ec/encoding.rs b/aws-lc-rs/src/ec/encoding.rs index 2f79b169243..5fc2beee2d3 100644 --- a/aws-lc-rs/src/ec/encoding.rs +++ b/aws-lc-rs/src/ec/encoding.rs @@ -135,9 +135,9 @@ pub(crate) mod sec1 { compressed: bool, ) -> Result, Unspecified> { let pub_key_size = if compressed { - compressed_public_key_size_bytes(evp_pkey.key_size_bits()) + compressed_public_key_size_bytes(evp_pkey.as_const().key_size_bits()) } else { - uncompressed_public_key_size_bytes(evp_pkey.key_size_bits()) + uncompressed_public_key_size_bytes(evp_pkey.as_const().key_size_bits()) }; let mut cbb = LcCBB::new(pub_key_size); marshal_sec1_public_point_into_cbb(&mut cbb, evp_pkey, compressed)?; @@ -245,7 +245,7 @@ pub(crate) mod rfc5915 { let ec_key = evp_pkey.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) })?; - let mut cbb = LcCBB::new(evp_pkey.key_size_bytes()); + let mut cbb = LcCBB::new(evp_pkey.as_const().key_size_bytes()); let enc_flags = unsafe { EC_KEY_get_enc_flags(*ec_key) }; if 1 != unsafe { EC_KEY_marshal_private_key(cbb.as_mut_ptr(), *ec_key, enc_flags) } { return Err(Unspecified); diff --git a/aws-lc-rs/src/ec/key_pair.rs b/aws-lc-rs/src/ec/key_pair.rs index a779a8f2a3c..e92ce6e77ae 100644 --- a/aws-lc-rs/src/ec/key_pair.rs +++ b/aws-lc-rs/src/ec/key_pair.rs @@ -128,7 +128,9 @@ impl EcdsaKeyPair { /// pub fn to_pkcs8v1(&self) -> Result { Ok(Document::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1)?, )) } diff --git a/aws-lc-rs/src/ec/signature.rs b/aws-lc-rs/src/ec/signature.rs index b72b15af69a..dc83bdee62f 100644 --- a/aws-lc-rs/src/ec/signature.rs +++ b/aws-lc-rs/src/ec/signature.rs @@ -121,7 +121,7 @@ impl AsDer> for PublicKey { /// # Errors /// Returns an error if the public key fails to marshal to X.509. fn as_der(&self) -> Result, Unspecified> { - let der = self.evp_pkey.marshal_rfc5280_public_key()?; + let der = self.evp_pkey.as_const().marshal_rfc5280_public_key()?; Ok(PublicKeyX509Der::new(der)) } } diff --git a/aws-lc-rs/src/ed25519.rs b/aws-lc-rs/src/ed25519.rs index 71d9751c906..eb0d06ad9c1 100644 --- a/aws-lc-rs/src/ed25519.rs +++ b/aws-lc-rs/src/ed25519.rs @@ -153,7 +153,7 @@ impl AsDer> for PublicKey { // 2:d=1 hl=2 l= 5 cons: SEQUENCE // 4:d=2 hl=2 l= 3 prim: OBJECT :ED25519 // 9:d=1 hl=2 l= 33 prim: BIT STRING - let der = self.evp_pkey.marshal_rfc5280_public_key()?; + let der = self.evp_pkey.as_const().marshal_rfc5280_public_key()?; Ok(PublicKeyX509Der::from(Buffer::new(der))) } } @@ -182,7 +182,7 @@ impl Ed25519KeyPair { let evp_pkey = generate_key()?; let mut public_key = [0u8; ED25519_PUBLIC_KEY_LEN]; - let out_len: usize = evp_pkey.marshal_raw_public_to_buffer(&mut public_key)?; + let out_len: usize = evp_pkey.as_const().marshal_raw_public_to_buffer(&mut public_key)?; debug_assert_eq!(public_key.len(), out_len); Ok(Self { @@ -219,7 +219,7 @@ impl Ed25519KeyPair { pub fn generate_pkcs8(_rng: &dyn SecureRandom) -> Result { let evp_pkey = generate_key()?; Ok(Document::new( - evp_pkey.marshal_rfc5208_private_key(Version::V2)?, + evp_pkey.as_const().marshal_rfc5208_private_key(Version::V2)?, )) } @@ -230,7 +230,7 @@ impl Ed25519KeyPair { /// pub fn to_pkcs8(&self) -> Result { Ok(Document::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V2)?, + self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V2)?, )) } @@ -251,7 +251,7 @@ impl Ed25519KeyPair { pub fn generate_pkcs8v1(_rng: &dyn SecureRandom) -> Result { let evp_pkey = generate_key()?; Ok(Document::new( - evp_pkey.marshal_rfc5208_private_key(Version::V1)?, + evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, )) } @@ -262,7 +262,7 @@ impl Ed25519KeyPair { /// pub fn to_pkcs8v1(&self) -> Result { Ok(Document::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, )) } @@ -307,7 +307,7 @@ impl Ed25519KeyPair { let evp_pkey = LcPtr::::parse_raw_private_key(seed, EVP_PKEY_ED25519)?; let mut derived_public_key = [0u8; ED25519_PUBLIC_KEY_LEN]; - let out_len: usize = evp_pkey.marshal_raw_public_to_buffer(&mut derived_public_key)?; + let out_len: usize = evp_pkey.as_const().marshal_raw_public_to_buffer(&mut derived_public_key)?; debug_assert_eq!(derived_public_key.len(), out_len); Ok(Self { @@ -360,10 +360,10 @@ impl Ed25519KeyPair { fn parse_pkcs8(pkcs8: &[u8]) -> Result { let evp_pkey = LcPtr::::parse_rfc5208_private_key(pkcs8, EVP_PKEY_ED25519)?; - evp_pkey.validate_as_ed25519()?; + evp_pkey.as_const().validate_as_ed25519()?; let mut public_key = [0u8; ED25519_PUBLIC_KEY_LEN]; - let out_len: usize = evp_pkey.marshal_raw_public_to_buffer(&mut public_key)?; + let out_len: usize = evp_pkey.as_const().marshal_raw_public_to_buffer(&mut public_key)?; debug_assert_eq!(public_key.len(), out_len); Ok(Self { @@ -406,7 +406,7 @@ impl Ed25519KeyPair { /// Currently the function cannot fail, but it might in future implementations. pub fn seed(&self) -> Result, Unspecified> { Ok(Seed { - bytes: self.evp_pkey.marshal_raw_private_key()?.into_boxed_slice(), + bytes: self.evp_pkey.as_const().marshal_raw_private_key()?.into_boxed_slice(), phantom: PhantomData, }) } @@ -419,7 +419,7 @@ impl AsDer> for Ed25519KeyPair { /// `error::Unspecified` on internal error. fn as_der(&self) -> Result, crate::error::Unspecified> { Ok(Pkcs8V1Der::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, )) } } @@ -431,7 +431,7 @@ impl AsDer> for Ed25519KeyPair { /// `error::Unspecified` on internal error. fn as_der(&self) -> Result, crate::error::Unspecified> { Ok(Pkcs8V2Der::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V2)?, + self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V2)?, )) } } diff --git a/aws-lc-rs/src/evp_pkey.rs b/aws-lc-rs/src/evp_pkey.rs index 337215c8017..1975ca9cc40 100644 --- a/aws-lc-rs/src/evp_pkey.rs +++ b/aws-lc-rs/src/evp_pkey.rs @@ -43,7 +43,7 @@ impl EVP_PKEY_CTX_consumer for T where T: Fn(*mut EVP_PKEY_CTX) -> Result<(), #[allow(non_upper_case_globals, clippy::type_complexity)] pub(crate) const No_EVP_PKEY_CTX_consumer: Option Result<(), ()>> = None; -impl LcPtr { +impl ConstPointer<'_, EVP_PKEY> { pub(crate) fn validate_as_ed25519(&self) -> Result<(), KeyRejected> { const ED25519_KEY_TYPE: c_int = EVP_PKEY_ED25519; const ED25519_MIN_BITS: c_int = 253; @@ -79,7 +79,7 @@ impl LcPtr { // EVP_PKEY_X448 = 961; // EVP_PKEY_ED448 = 960; pub(crate) fn id(&self) -> i32 { - unsafe { EVP_PKEY_id(*self.as_const()) } + unsafe { EVP_PKEY_id(**self) } } pub(crate) fn key_size_bytes(&self) -> usize { @@ -87,27 +87,21 @@ impl LcPtr { } pub(crate) fn key_size_bits(&self) -> usize { - unsafe { EVP_PKEY_bits(*self.as_const()) } - .try_into() - .unwrap() + unsafe { EVP_PKEY_bits(**self) }.try_into().unwrap() } pub(crate) fn signature_size_bytes(&self) -> usize { - unsafe { EVP_PKEY_size(*self.as_const()) } - .try_into() - .unwrap() + unsafe { EVP_PKEY_size(**self) }.try_into().unwrap() } #[allow(dead_code)] pub(crate) fn get_ec_key(&self) -> Result, KeyRejected> { - self.project_const_lifetime(unsafe { - |evp_pkey| EVP_PKEY_get0_EC_KEY(*evp_pkey.as_const()) - }) - .map_err(|()| KeyRejected::wrong_algorithm()) + self.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_EC_KEY(**evp_pkey) }) + .map_err(|()| KeyRejected::wrong_algorithm()) } pub(crate) fn get_rsa(&self) -> Result, KeyRejected> { - self.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_RSA(*evp_pkey.as_const()) }) + self.project_const_lifetime(unsafe { |evp_pkey| EVP_PKEY_get0_RSA(**evp_pkey) }) .map_err(|()| KeyRejected::wrong_algorithm()) } @@ -116,43 +110,27 @@ impl LcPtr { // size in bytes for keys ranging from 2048-bit to 4096-bit. So size the initial capacity to be roughly // 500% as a conservative estimate to avoid needing to reallocate for any key in that range. let mut cbb = LcCBB::new(self.key_size_bytes() * 5); - if 1 != unsafe { EVP_marshal_public_key(cbb.as_mut_ptr(), *self.as_const()) } { + if 1 != unsafe { EVP_marshal_public_key(cbb.as_mut_ptr(), **self) } { return Err(Unspecified); } cbb.into_vec() } - pub(crate) fn parse_rfc5280_public_key( - bytes: &[u8], - evp_pkey_type: c_int, - ) -> Result { - let mut cbs = cbs::build_CBS(bytes); - // Also checks the validity of the key - let evp_pkey = LcPtr::new(unsafe { EVP_parse_public_key(&mut cbs) }) - .map_err(|()| KeyRejected::invalid_encoding())?; - evp_pkey - .id() - .eq(&evp_pkey_type) - .then_some(evp_pkey) - .ok_or(KeyRejected::wrong_algorithm()) - } - pub(crate) fn marshal_rfc5208_private_key( &self, version: Version, ) -> Result, Unspecified> { - let key_size_bytes = TryInto::::try_into(unsafe { EVP_PKEY_bits(*self.as_const()) }) - .expect("fit in usize") - / 8; + let key_size_bytes = + TryInto::::try_into(unsafe { EVP_PKEY_bits(**self) }).expect("fit in usize") / 8; let mut cbb = LcCBB::new(key_size_bytes * 5); match version { Version::V1 => { - if 1 != unsafe { EVP_marshal_private_key(cbb.as_mut_ptr(), *self.as_const()) } { + if 1 != unsafe { EVP_marshal_private_key(cbb.as_mut_ptr(), **self) } { return Err(Unspecified); } } Version::V2 => { - if 1 != unsafe { EVP_marshal_private_key_v2(cbb.as_mut_ptr(), *self.as_const()) } { + if 1 != unsafe { EVP_marshal_private_key_v2(cbb.as_mut_ptr(), **self) } { return Err(Unspecified); } } @@ -160,32 +138,9 @@ impl LcPtr { cbb.into_vec() } - pub(crate) fn parse_rfc5208_private_key( - bytes: &[u8], - evp_pkey_type: c_int, - ) -> Result { - let mut cbs = cbs::build_CBS(bytes); - // Also checks the validity of the key - let evp_pkey = LcPtr::new(unsafe { EVP_parse_private_key(&mut cbs) }) - .map_err(|()| KeyRejected::invalid_encoding())?; - evp_pkey - .id() - .eq(&evp_pkey_type) - .then_some(evp_pkey) - .ok_or(KeyRejected::wrong_algorithm()) - } - - #[allow(non_snake_case)] - pub(crate) fn create_EVP_PKEY_CTX(&self) -> Result, ()> { - // The only modification made by EVP_PKEY_CTX_new to `priv_key` is to increment its - // refcount. The modification is made while holding a global lock: - // https://github.com/aws/aws-lc/blob/61503f7fe72457e12d3446853a5452d175560c49/crypto/refcount_lock.c#L29 - LcPtr::new(unsafe { EVP_PKEY_CTX_new(*self.as_mut_unsafe(), null_mut()) }) - } - pub(crate) fn marshal_raw_private_key(&self) -> Result, Unspecified> { let mut size = 0; - if 1 != unsafe { EVP_PKEY_get_raw_private_key(*self.as_const(), null_mut(), &mut size) } { + if 1 != unsafe { EVP_PKEY_get_raw_private_key(**self, null_mut(), &mut size) } { return Err(Unspecified); } let mut buffer = vec![0u8; size]; @@ -199,9 +154,7 @@ impl LcPtr { buffer: &mut [u8], ) -> Result { let mut key_len = buffer.len(); - if 1 == unsafe { - EVP_PKEY_get_raw_private_key(*self.as_const(), buffer.as_mut_ptr(), &mut key_len) - } { + if 1 == unsafe { EVP_PKEY_get_raw_private_key(**self, buffer.as_mut_ptr(), &mut key_len) } { Ok(key_len) } else { Err(Unspecified) @@ -211,7 +164,7 @@ impl LcPtr { #[allow(dead_code)] pub(crate) fn marshal_raw_public_key(&self) -> Result, Unspecified> { let mut size = 0; - if 1 != unsafe { EVP_PKEY_get_raw_public_key(*self.as_const(), null_mut(), &mut size) } { + if 1 != unsafe { EVP_PKEY_get_raw_public_key(**self, null_mut(), &mut size) } { return Err(Unspecified); } let mut buffer = vec![0u8; size]; @@ -229,7 +182,7 @@ impl LcPtr { // `EVP_PKEY_get_raw_public_key` writes the total length // to `encapsulate_key_size` in the event that the buffer we provide is larger then // required. - EVP_PKEY_get_raw_public_key(*self.as_const(), buffer.as_mut_ptr(), &mut key_len) + EVP_PKEY_get_raw_public_key(**self, buffer.as_mut_ptr(), &mut key_len) } { Ok(key_len) } else { @@ -237,6 +190,49 @@ impl LcPtr { } } +} + +impl LcPtr { + pub(crate) fn parse_rfc5280_public_key( + bytes: &[u8], + evp_pkey_type: c_int, + ) -> Result { + let mut cbs = cbs::build_CBS(bytes); + // Also checks the validity of the key + let evp_pkey = LcPtr::new(unsafe { EVP_parse_public_key(&mut cbs) }) + .map_err(|()| KeyRejected::invalid_encoding())?; + evp_pkey + .as_const() + .id() + .eq(&evp_pkey_type) + .then_some(evp_pkey) + .ok_or(KeyRejected::wrong_algorithm()) + } + + pub(crate) fn parse_rfc5208_private_key( + bytes: &[u8], + evp_pkey_type: c_int, + ) -> Result { + let mut cbs = cbs::build_CBS(bytes); + // Also checks the validity of the key + let evp_pkey = LcPtr::new(unsafe { EVP_parse_private_key(&mut cbs) }) + .map_err(|()| KeyRejected::invalid_encoding())?; + evp_pkey + .as_const() + .id() + .eq(&evp_pkey_type) + .then_some(evp_pkey) + .ok_or(KeyRejected::wrong_algorithm()) + } + + #[allow(non_snake_case)] + pub(crate) fn create_EVP_PKEY_CTX(&self) -> Result, ()> { + // The only modification made by EVP_PKEY_CTX_new to `priv_key` is to increment its + // refcount. The modification is made while holding a global lock: + // https://github.com/aws/aws-lc/blob/61503f7fe72457e12d3446853a5452d175560c49/crypto/refcount_lock.c#L29 + LcPtr::new(unsafe { EVP_PKEY_CTX_new(*self.as_mut_unsafe(), null_mut()) }) + } + pub(crate) fn parse_raw_private_key( bytes: &[u8], evp_pkey_type: c_int, diff --git a/aws-lc-rs/src/kem.rs b/aws-lc-rs/src/kem.rs index 52ed528a3b2..6b5c7f5ea21 100644 --- a/aws-lc-rs/src/kem.rs +++ b/aws-lc-rs/src/kem.rs @@ -360,7 +360,7 @@ where let mut encapsulate_bytes = vec![0u8; self.algorithm.encapsulate_key_size()]; let encapsulate_key_size = self .evp_pkey - .marshal_raw_public_to_buffer(&mut encapsulate_bytes)?; + .as_const().marshal_raw_public_to_buffer(&mut encapsulate_bytes)?; debug_assert_eq!(encapsulate_key_size, encapsulate_bytes.len()); encapsulate_bytes.truncate(encapsulate_key_size); diff --git a/aws-lc-rs/src/pqdsa.rs b/aws-lc-rs/src/pqdsa.rs index d23e6216c82..37e30ee6ebf 100644 --- a/aws-lc-rs/src/pqdsa.rs +++ b/aws-lc-rs/src/pqdsa.rs @@ -66,7 +66,7 @@ pub(crate) fn validate_pqdsa_evp_key( evp_pkey: &LcPtr, id: &'static AlgorithmID, ) -> Result<(), KeyRejected> { - if evp_pkey.key_size_bytes() == id.pub_key_size_bytes() { + if evp_pkey.as_const().key_size_bytes() == id.pub_key_size_bytes() { Ok(()) } else { Err(KeyRejected::unspecified()) @@ -102,24 +102,27 @@ mod tests { fn test_keygen() { for nid in [NID_MLDSA44, NID_MLDSA65, NID_MLDSA87] { let key = evp_key_pqdsa_generate(nid).unwrap(); - println!("key size: {:?}", key.key_size_bytes()); + println!("key size: {:?}", key.as_const().key_size_bytes()); test_serialization_for(&key, &AlgorithmID::from_nid(nid).unwrap()); test_signing_for(&key, &AlgorithmID::from_nid(nid).unwrap()); } } fn test_serialization_for(evp_pkey: &LcPtr, id: &AlgorithmID) { - let public_buffer = evp_pkey.marshal_rfc5280_public_key().unwrap(); + let public_buffer = evp_pkey.as_const().marshal_rfc5280_public_key().unwrap(); println!("public marshall: {public_buffer:?}"); let key_public = LcPtr::::parse_rfc5280_public_key(&public_buffer, EVP_PKEY_PQDSA).unwrap(); - let private_buffer = evp_pkey.marshal_rfc5208_private_key(Version::V1).unwrap(); + let private_buffer = evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1) + .unwrap(); println!("private marshall: {private_buffer:?}"); let key_private = LcPtr::::parse_rfc5208_private_key(&private_buffer, EVP_PKEY_PQDSA).unwrap(); - let raw_public_buffer = key_public.marshal_raw_public_key().unwrap(); + let raw_public_buffer = key_public.as_const().marshal_raw_public_key().unwrap(); assert_eq!(raw_public_buffer.len(), id.pub_key_size_bytes()); println!("raw public size: {}", raw_public_buffer.len()); let key_public2 = @@ -129,7 +132,7 @@ mod tests { EVP_PKEY_cmp(*key_public.as_const(), *key_public2.as_const()) }); - let raw_private_buffer = key_private.marshal_raw_private_key().unwrap(); + let raw_private_buffer = key_private.as_const().marshal_raw_private_key().unwrap(); assert_eq!(raw_private_buffer.len(), id.priv_key_size_bytes()); println!("raw private size: {}", raw_private_buffer.len()); let key_private2 = @@ -145,7 +148,7 @@ mod tests { .sign(message, None, No_EVP_PKEY_CTX_consumer) .unwrap(); println!("signature size: {}", signature.len()); - assert_eq!(signature.len(), evp_pkey.signature_size_bytes()); + assert_eq!(signature.len(), evp_pkey.as_const().signature_size_bytes()); assert_eq!(signature.len(), id.signature_size_bytes()); evp_pkey .verify(message, None, No_EVP_PKEY_CTX_consumer, &signature) diff --git a/aws-lc-rs/src/pqdsa/key_pair.rs b/aws-lc-rs/src/pqdsa/key_pair.rs index 343872285f6..bb53ab63dd4 100644 --- a/aws-lc-rs/src/pqdsa/key_pair.rs +++ b/aws-lc-rs/src/pqdsa/key_pair.rs @@ -51,7 +51,7 @@ impl AsDer> for PqdsaPrivateKey<'_> { Ok(Pkcs8V1Der::new( self.0 .evp_pkey - .marshal_rfc5208_private_key(pkcs8::Version::V1)?, + .as_const().marshal_rfc5208_private_key(pkcs8::Version::V1)?, )) } } @@ -59,7 +59,7 @@ impl AsDer> for PqdsaPrivateKey<'_> { impl AsRawBytes> for PqdsaPrivateKey<'_> { fn as_raw_bytes(&self) -> Result, Unspecified> { Ok(PqdsaPrivateKeyRaw::new( - self.0.evp_pkey.marshal_raw_private_key()?, + self.0.evp_pkey.as_const().marshal_raw_private_key()?, )) } } @@ -121,7 +121,7 @@ impl PqdsaKeyPair { /// Returns `Unspecified` if serialization fails. pub fn to_pkcs8(&self) -> Result { Ok(Document::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, )) } diff --git a/aws-lc-rs/src/pqdsa/signature.rs b/aws-lc-rs/src/pqdsa/signature.rs index 312a7cf5d43..3f811717c7c 100644 --- a/aws-lc-rs/src/pqdsa/signature.rs +++ b/aws-lc-rs/src/pqdsa/signature.rs @@ -47,7 +47,7 @@ unsafe impl Sync for PublicKey {} impl PublicKey { pub(crate) fn from_private_evp_pkey(evp_pkey: &LcPtr) -> Result { - let octets = evp_pkey.marshal_raw_public_key()?; + let octets = evp_pkey.as_const().marshal_raw_public_key()?; Ok(Self { evp_pkey: evp_pkey.clone(), octets: octets.into_boxed_slice(), @@ -102,7 +102,7 @@ impl AsDer> for PublicKey { /// # Errors /// Returns an error if the public key fails to marshal to X.509. fn as_der(&self) -> Result, crate::error::Unspecified> { - let der = self.evp_pkey.marshal_rfc5280_public_key()?; + let der = self.evp_pkey.as_const().marshal_rfc5280_public_key()?; Ok(PublicKeyX509Der::from(Buffer::new(der))) } } diff --git a/aws-lc-rs/src/rsa/encoding.rs b/aws-lc-rs/src/rsa/encoding.rs index 4def7947b21..628a45e1eaa 100644 --- a/aws-lc-rs/src/rsa/encoding.rs +++ b/aws-lc-rs/src/rsa/encoding.rs @@ -21,7 +21,7 @@ pub(in crate::rsa) mod rfc8017 { let mut pubkey_bytes = null_mut::(); let mut outlen: usize = 0; if 1 != unsafe { - RSA_public_key_to_bytes(&mut pubkey_bytes, &mut outlen, *pubkey.get_rsa()?) + RSA_public_key_to_bytes(&mut pubkey_bytes, &mut outlen, *pubkey.as_const().get_rsa()?) } { return Err(Unspecified); } @@ -85,7 +85,7 @@ pub(in crate::rsa) mod rfc5280 { pub(in crate::rsa) fn encode_public_key_der( key: &LcPtr, ) -> Result, Unspecified> { - let der = key.marshal_rfc5280_public_key()?; + let der = key.as_const().marshal_rfc5280_public_key()?; Ok(PublicKeyX509Der::from(Buffer::new(der))) } diff --git a/aws-lc-rs/src/rsa/encryption.rs b/aws-lc-rs/src/rsa/encryption.rs index d31187754e3..3dc58b3316f 100644 --- a/aws-lc-rs/src/rsa/encryption.rs +++ b/aws-lc-rs/src/rsa/encryption.rs @@ -44,7 +44,7 @@ impl PrivateDecryptingKey { if !is_rsa_key(key) { return Err(Unspecified); } - match key.key_size_bits() { + match key.as_const().key_size_bits() { 2048..=8192 => Ok(()), _ => Err(Unspecified), } @@ -105,13 +105,13 @@ impl PrivateDecryptingKey { /// Returns the RSA signature size in bytes. #[must_use] pub fn key_size_bytes(&self) -> usize { - self.0.signature_size_bytes() + self.0.as_const().signature_size_bytes() } /// Returns the RSA key size in bits. #[must_use] pub fn key_size_bits(&self) -> usize { - self.0.key_size_bits() + self.0.as_const().key_size_bits() } /// Retrieves the `PublicEncryptingKey` corresponding with this `PrivateDecryptingKey`. @@ -133,7 +133,7 @@ impl Debug for PrivateDecryptingKey { impl AsDer> for PrivateDecryptingKey { fn as_der(&self) -> Result, Unspecified> { Ok(Pkcs8V1Der::new( - self.0.marshal_rfc5208_private_key(Version::V1)?, + self.0.as_const().marshal_rfc5208_private_key(Version::V1)?, )) } } @@ -157,7 +157,7 @@ impl PublicEncryptingKey { if !is_rsa_key(key) { return Err(Unspecified); } - match key.key_size_bits() { + match key.as_const().key_size_bits() { 2048..=8192 => Ok(()), _ => Err(Unspecified), } @@ -174,13 +174,13 @@ impl PublicEncryptingKey { /// Returns the RSA signature size in bytes. #[must_use] pub fn key_size_bytes(&self) -> usize { - self.0.signature_size_bytes() + self.0.as_const().signature_size_bytes() } /// Returns the RSA key size in bits. #[must_use] pub fn key_size_bits(&self) -> usize { - self.0.key_size_bits() + self.0.as_const().key_size_bits() } } diff --git a/aws-lc-rs/src/rsa/key.rs b/aws-lc-rs/src/rsa/key.rs index bf4e2382ef7..01827a77d43 100644 --- a/aws-lc-rs/src/rsa/key.rs +++ b/aws-lc-rs/src/rsa/key.rs @@ -175,7 +175,7 @@ impl KeyPair { if !is_rsa_key(key) { return Err(KeyRejected::unspecified()); } - match key.key_size_bits() { + match key.as_const().key_size_bits() { 2048..=8192 => Ok(()), _ => Err(KeyRejected::unspecified()), } @@ -230,7 +230,7 @@ impl KeyPair { #[must_use] pub fn public_modulus_len(&self) -> usize { // This was already validated to be an RSA key so this can't fail - match self.evp_pkey.get_rsa() { + match self.evp_pkey.as_const().get_rsa() { Ok(rsa) => { // https://github.com/awslabs/aws-lc/blob/main/include/openssl/rsa.h#L99 unsafe { RSA_size(*rsa) as usize } @@ -260,7 +260,9 @@ impl crate::signature::KeyPair for KeyPair { impl AsDer> for KeyPair { fn as_der(&self) -> Result, Unspecified> { Ok(Pkcs8V1Der::new( - self.evp_pkey.marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1)?, )) } } @@ -291,6 +293,7 @@ impl PublicKey { let key = encoding::rfc8017::encode_public_key_der(evp_pkey)?; #[cfg(feature = "ring-io")] { + let evp_pkey = evp_pkey.as_const(); let pubkey = evp_pkey.get_rsa()?; let modulus = pubkey.project_const_lifetime(unsafe { |pubkey| RSA_get0_n(**pubkey) })?; @@ -498,12 +501,13 @@ pub(super) fn generate_rsa_key(size: c_int) -> Result, Unspecifi #[must_use] pub(super) fn is_valid_fips_key(key: &LcPtr) -> bool { // This should always be an RSA key and must-never panic. - let rsa_key = key.get_rsa().expect("RSA EVP_PKEY"); + let evp_pkey = key.as_const(); + let rsa_key = evp_pkey.get_rsa().expect("RSA EVP_PKEY"); 1 == unsafe { RSA_check_fips(*rsa_key as *mut RSA) } } pub(super) fn is_rsa_key(key: &LcPtr) -> bool { - let id = key.id(); + let id = key.as_const().id(); id == EVP_PKEY_RSA || id == EVP_PKEY_RSA_PSS } diff --git a/aws-lc-rs/src/rsa/signature.rs b/aws-lc-rs/src/rsa/signature.rs index d1b18edf78d..164386c5b8f 100644 --- a/aws-lc-rs/src/rsa/signature.rs +++ b/aws-lc-rs/src/rsa/signature.rs @@ -109,7 +109,7 @@ impl RsaParameters { /// `error::Unspecified` on parse error. pub fn public_modulus_len(public_key: &[u8]) -> Result { let rsa = encoding::rfc8017::decode_public_key_der(public_key)?; - Ok(unsafe { RSA_bits(*rsa.get_rsa()?) }) + Ok(unsafe { RSA_bits(*rsa.as_const().get_rsa()?) }) } #[must_use] @@ -222,7 +222,7 @@ pub(crate) fn verify_rsa_signature( signature: &[u8], allowed_bit_size: &RangeInclusive, ) -> Result<(), Unspecified> { - if !allowed_bit_size.contains(&public_key.key_size_bits().try_into()?) { + if !allowed_bit_size.contains(&public_key.as_const().key_size_bits().try_into()?) { return Err(Unspecified); } From 0efed67c664cf510edcaceee63ca2ccdf542c2fe Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Fri, 28 Mar 2025 13:42:22 -0400 Subject: [PATCH 3/4] Fix formatting and clippy --- aws-lc-rs/src/ed25519.rs | 42 +++++++++++++++++++++++++-------- aws-lc-rs/src/evp_pkey.rs | 1 - aws-lc-rs/src/kem.rs | 3 ++- aws-lc-rs/src/pqdsa/key_pair.rs | 7 ++++-- aws-lc-rs/src/rsa/encoding.rs | 6 ++++- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/aws-lc-rs/src/ed25519.rs b/aws-lc-rs/src/ed25519.rs index eb0d06ad9c1..f61ebf533a3 100644 --- a/aws-lc-rs/src/ed25519.rs +++ b/aws-lc-rs/src/ed25519.rs @@ -182,7 +182,9 @@ impl Ed25519KeyPair { let evp_pkey = generate_key()?; let mut public_key = [0u8; ED25519_PUBLIC_KEY_LEN]; - let out_len: usize = evp_pkey.as_const().marshal_raw_public_to_buffer(&mut public_key)?; + let out_len: usize = evp_pkey + .as_const() + .marshal_raw_public_to_buffer(&mut public_key)?; debug_assert_eq!(public_key.len(), out_len); Ok(Self { @@ -219,7 +221,9 @@ impl Ed25519KeyPair { pub fn generate_pkcs8(_rng: &dyn SecureRandom) -> Result { let evp_pkey = generate_key()?; Ok(Document::new( - evp_pkey.as_const().marshal_rfc5208_private_key(Version::V2)?, + evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V2)?, )) } @@ -230,7 +234,9 @@ impl Ed25519KeyPair { /// pub fn to_pkcs8(&self) -> Result { Ok(Document::new( - self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V2)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V2)?, )) } @@ -251,7 +257,9 @@ impl Ed25519KeyPair { pub fn generate_pkcs8v1(_rng: &dyn SecureRandom) -> Result { let evp_pkey = generate_key()?; Ok(Document::new( - evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, + evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1)?, )) } @@ -262,7 +270,9 @@ impl Ed25519KeyPair { /// pub fn to_pkcs8v1(&self) -> Result { Ok(Document::new( - self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1)?, )) } @@ -307,7 +317,9 @@ impl Ed25519KeyPair { let evp_pkey = LcPtr::::parse_raw_private_key(seed, EVP_PKEY_ED25519)?; let mut derived_public_key = [0u8; ED25519_PUBLIC_KEY_LEN]; - let out_len: usize = evp_pkey.as_const().marshal_raw_public_to_buffer(&mut derived_public_key)?; + let out_len: usize = evp_pkey + .as_const() + .marshal_raw_public_to_buffer(&mut derived_public_key)?; debug_assert_eq!(derived_public_key.len(), out_len); Ok(Self { @@ -363,7 +375,9 @@ impl Ed25519KeyPair { evp_pkey.as_const().validate_as_ed25519()?; let mut public_key = [0u8; ED25519_PUBLIC_KEY_LEN]; - let out_len: usize = evp_pkey.as_const().marshal_raw_public_to_buffer(&mut public_key)?; + let out_len: usize = evp_pkey + .as_const() + .marshal_raw_public_to_buffer(&mut public_key)?; debug_assert_eq!(public_key.len(), out_len); Ok(Self { @@ -406,7 +420,11 @@ impl Ed25519KeyPair { /// Currently the function cannot fail, but it might in future implementations. pub fn seed(&self) -> Result, Unspecified> { Ok(Seed { - bytes: self.evp_pkey.as_const().marshal_raw_private_key()?.into_boxed_slice(), + bytes: self + .evp_pkey + .as_const() + .marshal_raw_private_key()? + .into_boxed_slice(), phantom: PhantomData, }) } @@ -419,7 +437,9 @@ impl AsDer> for Ed25519KeyPair { /// `error::Unspecified` on internal error. fn as_der(&self) -> Result, crate::error::Unspecified> { Ok(Pkcs8V1Der::new( - self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1)?, )) } } @@ -431,7 +451,9 @@ impl AsDer> for Ed25519KeyPair { /// `error::Unspecified` on internal error. fn as_der(&self) -> Result, crate::error::Unspecified> { Ok(Pkcs8V2Der::new( - self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V2)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V2)?, )) } } diff --git a/aws-lc-rs/src/evp_pkey.rs b/aws-lc-rs/src/evp_pkey.rs index 1975ca9cc40..836754a590e 100644 --- a/aws-lc-rs/src/evp_pkey.rs +++ b/aws-lc-rs/src/evp_pkey.rs @@ -189,7 +189,6 @@ impl ConstPointer<'_, EVP_PKEY> { Err(Unspecified) } } - } impl LcPtr { diff --git a/aws-lc-rs/src/kem.rs b/aws-lc-rs/src/kem.rs index 6b5c7f5ea21..90c11eda96c 100644 --- a/aws-lc-rs/src/kem.rs +++ b/aws-lc-rs/src/kem.rs @@ -360,7 +360,8 @@ where let mut encapsulate_bytes = vec![0u8; self.algorithm.encapsulate_key_size()]; let encapsulate_key_size = self .evp_pkey - .as_const().marshal_raw_public_to_buffer(&mut encapsulate_bytes)?; + .as_const() + .marshal_raw_public_to_buffer(&mut encapsulate_bytes)?; debug_assert_eq!(encapsulate_key_size, encapsulate_bytes.len()); encapsulate_bytes.truncate(encapsulate_key_size); diff --git a/aws-lc-rs/src/pqdsa/key_pair.rs b/aws-lc-rs/src/pqdsa/key_pair.rs index bb53ab63dd4..6c1bef79024 100644 --- a/aws-lc-rs/src/pqdsa/key_pair.rs +++ b/aws-lc-rs/src/pqdsa/key_pair.rs @@ -51,7 +51,8 @@ impl AsDer> for PqdsaPrivateKey<'_> { Ok(Pkcs8V1Der::new( self.0 .evp_pkey - .as_const().marshal_rfc5208_private_key(pkcs8::Version::V1)?, + .as_const() + .marshal_rfc5208_private_key(pkcs8::Version::V1)?, )) } } @@ -121,7 +122,9 @@ impl PqdsaKeyPair { /// Returns `Unspecified` if serialization fails. pub fn to_pkcs8(&self) -> Result { Ok(Document::new( - self.evp_pkey.as_const().marshal_rfc5208_private_key(Version::V1)?, + self.evp_pkey + .as_const() + .marshal_rfc5208_private_key(Version::V1)?, )) } diff --git a/aws-lc-rs/src/rsa/encoding.rs b/aws-lc-rs/src/rsa/encoding.rs index 628a45e1eaa..f40181c94e8 100644 --- a/aws-lc-rs/src/rsa/encoding.rs +++ b/aws-lc-rs/src/rsa/encoding.rs @@ -21,7 +21,11 @@ pub(in crate::rsa) mod rfc8017 { let mut pubkey_bytes = null_mut::(); let mut outlen: usize = 0; if 1 != unsafe { - RSA_public_key_to_bytes(&mut pubkey_bytes, &mut outlen, *pubkey.as_const().get_rsa()?) + RSA_public_key_to_bytes( + &mut pubkey_bytes, + &mut outlen, + *pubkey.as_const().get_rsa()?, + ) } { return Err(Unspecified); } From 45b7f1049dec41a9485d8f342c4d65b350e43553 Mon Sep 17 00:00:00 2001 From: Justin Smith Date: Wed, 28 May 2025 11:12:18 -0400 Subject: [PATCH 4/4] Fix comment --- aws-lc-rs/src/ec.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aws-lc-rs/src/ec.rs b/aws-lc-rs/src/ec.rs index c7943c92b7b..006466d2beb 100644 --- a/aws-lc-rs/src/ec.rs +++ b/aws-lc-rs/src/ec.rs @@ -3,8 +3,6 @@ // Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC -use crate::ec::signature::AlgorithmID; -// TODO: Uncomment when MSRV >= 1.64 #[cfg(feature = "fips")] use crate::aws_lc::EC_KEY_check_fips; #[cfg(not(feature = "fips"))] @@ -16,11 +14,14 @@ use crate::aws_lc::{ NID_X9_62_prime256v1, NID_secp224r1, NID_secp256k1, NID_secp384r1, NID_secp521r1, EC_GROUP, EC_KEY, EVP_PKEY, EVP_PKEY_EC, }; +use crate::ec::signature::AlgorithmID; use crate::error::{KeyRejected, Unspecified}; #[cfg(feature = "fips")] use crate::fips::indicator_check; use crate::ptr::{ConstPointer, LcPtr}; use crate::signature::Signature; +// TODO: Uncomment when MSRV >= 1.64 +//use core::ffi::c_int; use std::os::raw::c_int; use std::ptr::null;