Skip to content

Commit 9faed3a

Browse files
simo5Gemini
andcommitted
Unify OsslAsymcipher for all asymmetric cipher ops
This patch refactors the `OsslAsymcipher` structure to provide a unified and comprehensive interface for all asymmetric cipher operations, including **encryption**, **decryption**, **encapsulation**, and **decapsulation**. Previously, encapsulation and decapsulation operations were handled by a separate `OsslEncapsulation` structure. This patch moves the operations previously performed by `OsslEncapsulation` directly into `OsslAsymcipher`. Key changes include: * The `EncOp` enum now includes `Encapsulate` and `Decapsulate` variants. * The `OsslAsymcipher::new` method is enhanced to handle initialization for all four operation types, taking an `Option<&OsslParam>` for parameters to support cases where parameters might be null. * The `OsslEncapsulation` structure and its associated `new_encapsulation` and `new_decapsulation` methods have been **removed**. * The `encapsulate` and `decapsulate` methods of `OsslAsymcipher` now include checks to ensure the `EncOp` matches the intended operation, returning an `WrapperError` if there's a mismatch. Signed-off-by: Simo Sorce <simo@redhat.com> Co-authored-by: Gemini <gemini@google.com>
1 parent 45de8d6 commit 9faed3a

File tree

3 files changed

+40
-68
lines changed

3 files changed

+40
-68
lines changed

ossl/src/asymcipher.rs

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,17 @@ pub fn rsa_enc_params(
7676
pub enum EncOp {
7777
Encrypt,
7878
Decrypt,
79+
Encapsulate,
80+
Decapsulate,
7981
}
8082

81-
/// Higher level wrapper for asymmetric encryption operations with OpenSSL
83+
/// Higher level wrapper for asymmetric cipher operations with OpenSSL
84+
///
85+
/// Supports Encryption, Decryption, Encapsulation, Decapsulation.
86+
/// Whether any of these operation will work also depends on the type
87+
/// of key provided.
88+
///
89+
/// An OsslError is returned if an operation is unsupported.
8290
#[derive(Debug)]
8391
pub struct OsslAsymcipher {
8492
/// The underlying OpenSSL EVP PKEY context.
@@ -93,24 +101,28 @@ impl OsslAsymcipher {
93101
libctx: &OsslContext,
94102
op: EncOp,
95103
key: &mut EvpPkey,
96-
params: &OsslParam,
104+
params: Option<&OsslParam>,
97105
) -> Result<OsslAsymcipher, Error> {
98106
let mut ctx = OsslAsymcipher {
99107
pkey_ctx: key.new_ctx(libctx)?,
100108
op: op,
101109
};
110+
let params_ptr = match params {
111+
Some(p) => p.as_ptr(),
112+
None => std::ptr::null(),
113+
};
102114
let ret = match ctx.op {
103115
EncOp::Encrypt => unsafe {
104-
EVP_PKEY_encrypt_init_ex(
105-
ctx.pkey_ctx.as_mut_ptr(),
106-
params.as_ptr(),
107-
)
116+
EVP_PKEY_encrypt_init_ex(ctx.pkey_ctx.as_mut_ptr(), params_ptr)
108117
},
109118
EncOp::Decrypt => unsafe {
110-
EVP_PKEY_decrypt_init_ex(
111-
ctx.pkey_ctx.as_mut_ptr(),
112-
params.as_ptr(),
113-
)
119+
EVP_PKEY_decrypt_init_ex(ctx.pkey_ctx.as_mut_ptr(), params_ptr)
120+
},
121+
EncOp::Encapsulate => unsafe {
122+
EVP_PKEY_encapsulate_init(ctx.pkey_ctx.as_mut_ptr(), params_ptr)
123+
},
124+
EncOp::Decapsulate => unsafe {
125+
EVP_PKEY_decapsulate_init(ctx.pkey_ctx.as_mut_ptr(), params_ptr)
114126
},
115127
};
116128
if ret != 1 {
@@ -121,8 +133,13 @@ impl OsslAsymcipher {
121133
EncOp::Decrypt => {
122134
trace_ossl!("EVP_PKEY_decrypt_init()");
123135
}
136+
EncOp::Encapsulate => {
137+
trace_ossl!("EVP_PKEY_encapsulate_init()");
138+
}
139+
EncOp::Decapsulate => {
140+
trace_ossl!("EVP_PKEY_decapsulate_init()");
141+
}
124142
}
125-
trace_ossl!("EVP_PKEY_encrypt_init()");
126143
return Err(Error::new(ErrorKind::OsslError));
127144
}
128145
Ok(ctx)
@@ -191,36 +208,6 @@ impl OsslAsymcipher {
191208
}
192209
Ok(outlen)
193210
}
194-
}
195-
196-
/// Higher level wrapper for asymmetric encapsulation operations with OpenSSL
197-
#[derive(Debug)]
198-
pub struct OsslEncapsulation {
199-
/// The underlying OpenSSL EVP PKEY context.
200-
pkey_ctx: EvpPkeyCtx,
201-
}
202-
203-
impl OsslEncapsulation {
204-
/// Initializes a new encapsulation operation
205-
pub fn new_encapsulation(
206-
libctx: &OsslContext,
207-
key: &mut EvpPkey,
208-
) -> Result<OsslEncapsulation, Error> {
209-
let mut ctx = OsslEncapsulation {
210-
pkey_ctx: key.new_ctx(libctx)?,
211-
};
212-
let ret = unsafe {
213-
EVP_PKEY_encapsulate_init(
214-
ctx.pkey_ctx.as_mut_ptr(),
215-
std::ptr::null_mut(),
216-
)
217-
};
218-
if ret != 1 {
219-
trace_ossl!("EVP_PKEY_encapsulate_init()");
220-
return Err(Error::new(ErrorKind::OsslError));
221-
}
222-
Ok(ctx)
223-
}
224211

225212
/// Encapsulates operation, returns ciphertext in the mutable slice and
226213
/// returns an encapsulated key as a vector as well as the actual size
@@ -229,6 +216,9 @@ impl OsslEncapsulation {
229216
&mut self,
230217
ciphertext: &mut [u8],
231218
) -> Result<(Vec<u8>, usize), Error> {
219+
if self.op != EncOp::Encapsulate {
220+
return Err(Error::new(ErrorKind::WrapperError));
221+
}
232222
let mut outlen = 0;
233223
let mut keylen = 0;
234224

@@ -269,30 +259,12 @@ impl OsslEncapsulation {
269259
Ok((keydata, outlen))
270260
}
271261

272-
/// Initializes a new decapsulation operation
273-
pub fn new_decapsulation(
274-
libctx: &OsslContext,
275-
key: &mut EvpPkey,
276-
) -> Result<OsslEncapsulation, Error> {
277-
let mut ctx = OsslEncapsulation {
278-
pkey_ctx: key.new_ctx(libctx)?,
279-
};
280-
let ret = unsafe {
281-
EVP_PKEY_decapsulate_init(
282-
ctx.pkey_ctx.as_mut_ptr(),
283-
std::ptr::null_mut(),
284-
)
285-
};
286-
if ret != 1 {
287-
trace_ossl!("EVP_PKEY_decapsulate_init()");
288-
return Err(Error::new(ErrorKind::OsslError));
289-
}
290-
Ok(ctx)
291-
}
292-
293262
/// Decapsulate operation, takes the ciphertext generated by the peer and
294263
/// returns an encapsulated key as a vector
295264
pub fn decapsulate(&mut self, ciphertext: &[u8]) -> Result<Vec<u8>, Error> {
265+
if self.op != EncOp::Decapsulate {
266+
return Err(Error::new(ErrorKind::WrapperError));
267+
}
296268
let mut keylen = 0;
297269

298270
let ret = unsafe {

src/ossl/mlkem.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::object::Object;
1111
use crate::ossl::common::{osslctx, privkey_from_object, pubkey_from_object};
1212
use crate::pkcs11::*;
1313

14-
use ossl::asymcipher::OsslEncapsulation;
14+
use ossl::asymcipher::{EncOp, OsslAsymcipher};
1515
use ossl::pkey::{EvpPkey, EvpPkeyType, MlkeyData, PkeyData};
1616
use ossl::ErrorKind;
1717

@@ -72,8 +72,6 @@ pub fn mlkem_object_to_pkey(
7272
/// Performs the ML-KEM key encapsulation operation using the recipient's
7373
/// public key.
7474
///
75-
/// Uses the `OsslEncapsulation` API.
76-
///
7775
/// Returns a tuple containing the derived shared secret (`Vec<u8>`) and
7876
/// the actual length of the generated ciphertext written to the `ciphertext`
7977
/// buffer.
@@ -82,7 +80,8 @@ pub fn encapsulate(
8280
ciphertext: &mut [u8],
8381
) -> Result<(Vec<u8>, usize)> {
8482
let mut pubkey = pubkey_from_object(key)?;
85-
let mut ctx = OsslEncapsulation::new_encapsulation(osslctx(), &mut pubkey)?;
83+
let mut ctx =
84+
OsslAsymcipher::new(osslctx(), EncOp::Encapsulate, &mut pubkey, None)?;
8685
match ctx.encapsulate(ciphertext) {
8786
Ok(ret) => Ok(ret),
8887
Err(e) => match e.kind() {
@@ -100,7 +99,8 @@ pub fn encapsulate(
10099
/// Returns the derived shared secret (`Vec<u8>`).
101100
pub fn decapsulate(key: &Object, ciphertext: &[u8]) -> Result<Vec<u8>> {
102101
let mut prikey = privkey_from_object(key)?;
103-
let mut ctx = OsslEncapsulation::new_decapsulation(osslctx(), &mut prikey)?;
102+
let mut ctx =
103+
OsslAsymcipher::new(osslctx(), EncOp::Decapsulate, &mut prikey, None)?;
104104
Ok(ctx.decapsulate(ciphertext)?)
105105
}
106106

src/ossl/rsa.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl RsaPKCSOperation {
290290
osslctx(),
291291
op,
292292
&mut pkey,
293-
&rsa_enc_params(alg, params.as_ref())?,
293+
Some(&rsa_enc_params(alg, params.as_ref())?),
294294
)?;
295295
let keysize = Self::get_key_size(key, info)?;
296296
let maxinput = Self::max_message_len(keysize, mech)?;

0 commit comments

Comments
 (0)