diff --git a/rust/pv/src/crypto.rs b/rust/pv/src/crypto.rs index fd22eb47..680d011f 100644 --- a/rust/pv/src/crypto.rs +++ b/rust/pv/src/crypto.rs @@ -149,6 +149,31 @@ pub fn gen_ec_key() -> Result> { PKey::from_ec_key(key).map_err(Error::Crypto) } +/// Result type for [`encrypt_aes_gcm`]. +pub struct AesGcmResult { + /// The result. + /// + /// [`Vec`] with the following content: + /// 1. `aad` + /// 2. `encr(conf)` + /// 3. `aes gcm tag` + pub buf: Vec, + /// The position of the authenticated data in [`Self::buf`] + pub aad_range: Range, + /// The position of the encrypted data in [`Self::buf`] + pub encr_range: Range, + /// The position of the tag in [`Self::buf`] + pub tag_range: Range, +} + +impl AesGcmResult { + /// Deconstruct the result to just the resulting data w/o ranges. + pub fn data(self) -> Vec { + let Self { buf, .. } = self; + buf + } +} + /// Encrypt confidential Data with a symmetric key and provida a gcm tag. /// /// * `key` - symmetric key used for encryption @@ -156,21 +181,10 @@ pub fn gen_ec_key() -> Result> { /// * `aad` - additional authentic data /// * `conf` - data to be encrypted /// -/// # Returns -/// [`Vec`] with the following content: -/// 1. `aad` -/// 2. `encr(conf)` -/// 3. `aes gcm tag` -/// /// # Errors /// /// This function will return an error if the data could not be encrypted by OpenSSL. -pub fn encrypt_aes_gcm( - key: &SymKey, - iv: &[u8], - aad: &[u8], - conf: &[u8], -) -> Result<(Vec, Range, Range, Range)> { +pub fn encrypt_aes_gcm(key: &SymKey, iv: &[u8], aad: &[u8], conf: &[u8]) -> Result { let mut tag = vec![0xff; AES_256_GCM_TAG_SIZE]; let encr = match key { SymKey::Aes256(key) => encrypt_aead( @@ -183,7 +197,7 @@ pub fn encrypt_aes_gcm( )?, }; - let mut res = vec![0; aad.len() + encr.len() + tag.len()]; + let mut buf = vec![0; aad.len() + encr.len() + tag.len()]; let aad_range = Range { start: 0, end: aad.len(), @@ -197,10 +211,15 @@ pub fn encrypt_aes_gcm( end: aad.len() + encr.len() + tag.len(), }; - res[aad_range.clone()].copy_from_slice(aad); - res[encr_range.clone()].copy_from_slice(&encr); - res[tag_range.clone()].copy_from_slice(&tag); - Ok((res, aad_range, encr_range, tag_range)) + buf[aad_range.clone()].copy_from_slice(aad); + buf[encr_range.clone()].copy_from_slice(&encr); + buf[tag_range.clone()].copy_from_slice(&tag); + Ok(AesGcmResult { + buf, + aad_range, + encr_range, + tag_range, + }) } /// Calculate the hash of a slice. @@ -367,13 +386,14 @@ mod tests { 0xee, 0x62, 0x98, 0xf7, 0x7e, 0x0c, ]; - let (res, ..) = encrypt_aes_gcm( + let res = encrypt_aes_gcm( &SymKey::Aes256(aes_gcm_key.into()), &aes_gcm_iv, &aes_gcm_aad, &aes_gcm_plain, ) - .unwrap(); + .unwrap() + .data(); assert_eq!(res, aes_gcm_res); } } diff --git a/rust/pv/src/lib.rs b/rust/pv/src/lib.rs index c3c63421..37fd00fc 100644 --- a/rust/pv/src/lib.rs +++ b/rust/pv/src/lib.rs @@ -61,7 +61,7 @@ pub mod request { pub use crate::brcb::{BootHdrMagic, BootHdrTags}; pub use crate::crypto::derive_key; pub use crate::crypto::random_array; - pub use crate::crypto::{encrypt_aes_gcm, gen_ec_key}; + pub use crate::crypto::{encrypt_aes_gcm, gen_ec_key, AesGcmResult}; pub use crate::crypto::{hash, hkdf_rfc_5869}; pub use crate::crypto::{sign_msg, verify_signature}; pub use crate::crypto::{Aes256Key, SymKey, SymKeyType}; diff --git a/rust/pv/src/req.rs b/rust/pv/src/req.rs index 5120c832..dd7d4dd4 100644 --- a/rust/pv/src/req.rs +++ b/rust/pv/src/req.rs @@ -2,7 +2,7 @@ // // Copyright IBM Corp. 2023 -use crate::crypto::AES_256_GCM_TAG_SIZE; +use crate::crypto::{AesGcmResult, AES_256_GCM_TAG_SIZE}; use crate::misc::to_u32; use crate::request::{derive_key, encrypt_aes_gcm, gen_ec_key, random_array, SymKey, SymKeyType}; use crate::{Error, Result}; @@ -14,7 +14,6 @@ use openssl::pkey::{PKey, PKeyRef, Private, Public}; use pv_core::request::{RequestMagic, RequestVersion}; use std::convert::TryInto; use std::mem::size_of; -use std::ops::Range; use utils::assert_size; use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U32}; @@ -96,7 +95,8 @@ impl Encrypt for Keyslot { to: &mut Vec, ) -> Result<()> { let derived_key = derive_key(priv_key, &self.0)?; - let (mut wrpk_and_kst, ..) = encrypt_aes_gcm(&derived_key.into(), &[0; 12], &[], prot_key)?; + let mut wrpk_and_kst = + encrypt_aes_gcm(&derived_key.into(), &[0; 12], &[], prot_key)?.data(); let phk: EcdhPubkeyCoord = self.0.as_ref().try_into()?; to.reserve(80); @@ -252,11 +252,7 @@ impl ReqEncrCtx { /// # Errors /// /// This function will return an error if the data could not be encrypted by OpenSSL. - pub fn encrypt_aead( - &self, - aad: &[u8], - conf: &[u8], - ) -> Result<(Vec, Range, Range, Range)> { + pub fn encrypt_aead(&self, aad: &[u8], conf: &[u8]) -> Result { encrypt_aes_gcm(&self.prot_key, &self.iv, aad, conf) } } diff --git a/rust/pv/src/uvsecret/asrcb.rs b/rust/pv/src/uvsecret/asrcb.rs index ced2285f..39584577 100644 --- a/rust/pv/src/uvsecret/asrcb.rs +++ b/rust/pv/src/uvsecret/asrcb.rs @@ -5,6 +5,7 @@ use super::user_data::UserData; use crate::{ assert_size, + crypto::AesGcmResult, misc::Flags, request::{ hkdf_rfc_5869, @@ -289,7 +290,12 @@ impl AddSecretRequest { //encrypt data w/o aead let conf = self.conf.to_bytes(); let aad = self.aad(ctx, conf.value().len())?; - let (mut buf, aad_range, encr_range, _) = ctx.encrypt_aead(&aad, conf.value())?; + let AesGcmResult { + mut buf, + aad_range, + encr_range, + .. + } = ctx.encrypt_aead(&aad, conf.value())?; drop(aad); @@ -303,7 +309,7 @@ impl AddSecretRequest { // encrypt again with signed data buf[encr_range.clone()].copy_from_slice(conf.value()); ctx.encrypt_aead(&buf[aad_range], &buf[encr_range]) - .map(|(buf, ..)| buf) + .map(|res| res.data()) } } @@ -313,7 +319,7 @@ impl Request for AddSecretRequest { UserData::Null | UserData::Unsigned(_) => { let conf = self.conf.to_bytes(); let aad = self.aad(ctx, conf.value().len())?; - ctx.encrypt_aead(&aad, conf.value()).map(|(buf, ..)| buf) + ctx.encrypt_aead(&aad, conf.value()).map(|res| res.data()) } _ => self.encrypt_with_signed_user_data(ctx), }