Skip to content

Commit 13804e3

Browse files
signature: Add Signature operation
Implement: * OSSL_FUNC_SIGNATURE_SIGN_INIT as indicated by https://www.openssl.org/docs/man3.0/man7/provider-signature.html Signed-off-by: Tomás González <tomasagustin.gonzalezorlando@arm.com>
1 parent c359c45 commit 13804e3

File tree

3 files changed

+130
-3
lines changed

3 files changed

+130
-3
lines changed

parsec-openssl-provider/src/keymgmt/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
};
1616
use parsec_openssl2::types::VOID_PTR;
1717
use parsec_openssl2::*;
18-
use std::sync::{Arc, Mutex};
18+
use std::sync::{Arc, Mutex, MutexGuard};
1919

2020
pub struct ParsecProviderKeyObject {
2121
provctx: Arc<ParsecProviderContext>,
@@ -39,6 +39,14 @@ impl ParsecProviderKeyObject {
3939
key_name: None.into(),
4040
}
4141
}
42+
43+
pub fn get_provctx(&self) -> Arc<ParsecProviderContext> {
44+
self.provctx.clone()
45+
}
46+
47+
pub fn get_key_name(&self) -> MutexGuard<'_, Option<String>> {
48+
self.key_name.lock().unwrap()
49+
}
4250
}
4351

4452
/*

parsec-openssl-provider/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ openssl_errors::openssl_errors! {
117117
PROVIDER_KEYMGMT_SET_PARAMS("parsec_provider_kmgmt_set_params");
118118
PROVIDER_KEYMGMT_VALIDATE("parsec_provider_kmgmt_validate");
119119
PROVIDER_QUERY("parsec_provider_query");
120+
PROVIDER_SIGNATURE_SIGN("parsec_provider_signature_sign");
120121
PROVIDER_SIGNATURE_SIGN_INIT("parsec_provider_signature_sign_init");
121122
PROVIDER_TEARDOWN("parsec_provider_teardown");
122123
}

parsec-openssl-provider/src/signature/mod.rs

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
use crate::keymgmt::ParsecProviderKeyObject;
55
use crate::openssl_bindings::{
66
OSSL_ALGORITHM, OSSL_DISPATCH, OSSL_FUNC_SIGNATURE_FREECTX, OSSL_FUNC_SIGNATURE_NEWCTX,
7-
OSSL_FUNC_SIGNATURE_SIGN_INIT, OSSL_PARAM,
7+
OSSL_FUNC_SIGNATURE_SIGN, OSSL_FUNC_SIGNATURE_SIGN_INIT, OSSL_PARAM,
88
};
99
use crate::{
1010
PARSEC_PROVIDER_DESCRIPTION_ECDSA, PARSEC_PROVIDER_DESCRIPTION_RSA,
1111
PARSEC_PROVIDER_DFLT_PROPERTIES, PARSEC_PROVIDER_ECDSA_NAME, PARSEC_PROVIDER_RSA_NAME,
1212
};
13+
use parsec_client::core::interface::operations::psa_algorithm::Algorithm;
14+
use parsec_client::core::interface::operations::psa_key_attributes::{Attributes, EccFamily, Type};
1315
use parsec_openssl2::types::VOID_PTR;
1416
use parsec_openssl2::*;
1517

@@ -97,20 +99,136 @@ unsafe extern "C" fn parsec_provider_signature_sign_init(
9799
}
98100
}
99101

102+
fn get_signature_len(key_attrs: Attributes) -> Result<usize, String> {
103+
match key_attrs.key_type {
104+
Type::RsaKeyPair => Ok(key_attrs.bits / 8),
105+
Type::EccKeyPair {
106+
curve_family: EccFamily::SecpR1,
107+
} => {
108+
let size_times_two: usize = key_attrs.bits * 2;
109+
Ok(size_times_two.div_ceil(8))
110+
}
111+
_ => Err("Key type not recognized".to_string()),
112+
}
113+
}
114+
115+
/*
116+
performs the actual signing itself. A previously initialised signature context is passed in the ctx parameter. The data
117+
to be signed is pointed to be the tbs parameter which is tbslen bytes long. Unless sig is NULL, the signature should be
118+
written to the location pointed to by the sig parameter and it should not exceed sigsize bytes in length. The length of
119+
the signature should be written to *siglen. If sig is NULL then the maximum length of the signature should be written
120+
to *siglen.
121+
*/
122+
unsafe extern "C" fn parsec_provider_signature_sign(
123+
ctx: VOID_PTR,
124+
sig: *mut std::os::raw::c_uchar,
125+
siglen: *mut std::os::raw::c_uint,
126+
sigsize: std::os::raw::c_uint,
127+
tbs: *const std::os::raw::c_uchar,
128+
tbslen: std::os::raw::c_uint,
129+
) -> std::os::raw::c_int {
130+
let result = super::r#catch(Some(|| super::Error::PROVIDER_SIGNATURE_SIGN), || {
131+
if ctx.is_null() || tbs.is_null() || siglen.is_null() {
132+
return Err("Received unexpected NULL pointer as an argument.".into());
133+
}
134+
135+
Arc::increment_strong_count(ctx as *const ParsecProviderSignatureContext);
136+
let arc_sig_ctx = Arc::from_raw(ctx as *const ParsecProviderSignatureContext);
137+
138+
let keyobj = match *arc_sig_ctx.keyobj.lock().unwrap() {
139+
None => {
140+
return Err("Key Object not set. This should be done through sign_init()".into())
141+
}
142+
Some(ref keyobj) => keyobj.clone(),
143+
};
144+
145+
let key_name_binding = keyobj.get_key_name();
146+
let key_name = match *key_name_binding {
147+
None => return Err("Key name not set in the Key Object".into()),
148+
Some(ref name) => name,
149+
};
150+
151+
let key_attributes = keyobj
152+
.get_provctx()
153+
.get_client()
154+
.key_attributes(key_name)
155+
.map_err(|e| format!("Failed to get specified key's attributes: {}", e))?;
156+
let siglength = get_signature_len(key_attributes).map_err(|e| {
157+
format!(
158+
"Failed to Get correct signature length for the given key: {}",
159+
e
160+
)
161+
})?;
162+
163+
if sig.is_null() {
164+
*siglen = siglength as std::os::raw::c_uint;
165+
return Ok(OPENSSL_SUCCESS);
166+
}
167+
168+
if tbs.is_null() {
169+
return Err("Received unexpected NULL pointer as an argument.".into());
170+
}
171+
172+
let tbs_slice: &[u8] = core::slice::from_raw_parts(tbs, tbslen as usize);
173+
174+
let sign_algorithm = match key_attributes.policy.permitted_algorithms {
175+
Algorithm::AsymmetricSignature(signature_algo) => signature_algo,
176+
_ => {
177+
return Err(
178+
"Specified key does not permit the AsymmetricSignature algorithm".into(),
179+
)
180+
}
181+
};
182+
183+
let sign_res: Vec<u8> = keyobj
184+
.get_provctx()
185+
.get_client()
186+
.psa_sign_hash(key_name, tbs_slice, sign_algorithm)
187+
.map_err(|_| "Parsec Client failed to sign".to_string())?;
188+
189+
if sigsize >= sign_res.len() as u32 {
190+
std::ptr::copy(sign_res.as_ptr(), sig, sign_res.len());
191+
*siglen = sign_res.len() as u32;
192+
Ok(OPENSSL_SUCCESS)
193+
} else {
194+
Err(format!(
195+
"Signature length is bigger than sigsize. Signature length: {}",
196+
sign_res.len()
197+
)
198+
.into())
199+
}
200+
});
201+
202+
match result {
203+
Ok(result) => result,
204+
Err(()) => OPENSSL_ERROR,
205+
}
206+
}
207+
100208
pub type SignatureNewCtxPtr =
101209
unsafe extern "C" fn(VOID_PTR, *const std::os::raw::c_char) -> VOID_PTR;
102210
pub type SignatureFreeCtxPtr = unsafe extern "C" fn(VOID_PTR);
211+
pub type SignatureSignPtr = unsafe extern "C" fn(
212+
VOID_PTR,
213+
*mut std::os::raw::c_uchar,
214+
*mut std::os::raw::c_uint,
215+
std::os::raw::c_uint,
216+
*const std::os::raw::c_uchar,
217+
std::os::raw::c_uint,
218+
) -> std::os::raw::c_int;
103219
pub type SignatureSignInitPtr =
104220
unsafe extern "C" fn(VOID_PTR, VOID_PTR, *const OSSL_PARAM) -> std::os::raw::c_int;
105221

106222
const OSSL_FUNC_SIGNATURE_NEWCTX_PTR: SignatureNewCtxPtr = parsec_provider_signature_newctx;
107223
const OSSL_FUNC_SIGNATURE_FREECTX_PTR: SignatureFreeCtxPtr = parsec_provider_signature_freectx;
224+
const OSSL_FUNC_SIGNATURE_SIGN_PTR: SignatureSignPtr = parsec_provider_signature_sign;
108225
const OSSL_FUNC_SIGNATURE_SIGN_INIT_PTR: SignatureSignInitPtr = parsec_provider_signature_sign_init;
109226

110227
const PARSEC_PROVIDER_ECDSA_SIGN_IMPL: [OSSL_DISPATCH; 1] = [ossl_dispatch!()];
111-
const PARSEC_PROVIDER_RSA_SIGN_IMPL: [OSSL_DISPATCH; 4] = [
228+
const PARSEC_PROVIDER_RSA_SIGN_IMPL: [OSSL_DISPATCH; 5] = [
112229
unsafe { ossl_dispatch!(OSSL_FUNC_SIGNATURE_NEWCTX, OSSL_FUNC_SIGNATURE_NEWCTX_PTR) },
113230
unsafe { ossl_dispatch!(OSSL_FUNC_SIGNATURE_FREECTX, OSSL_FUNC_SIGNATURE_FREECTX_PTR) },
231+
unsafe { ossl_dispatch!(OSSL_FUNC_SIGNATURE_SIGN, OSSL_FUNC_SIGNATURE_SIGN_PTR) },
114232
unsafe {
115233
ossl_dispatch!(
116234
OSSL_FUNC_SIGNATURE_SIGN_INIT,

0 commit comments

Comments
 (0)