Skip to content

Commit 379fead

Browse files
tgonzalezorlandoarmgowthamsk-arm
authored andcommitted
keymgmt, signature: Start using RwLock for Contexts
Start using RwLock to simplify the access to the Signature and Keymgmt contexts. Signed-off-by: Tomás González <tomasagustin.gonzalezorlando@arm.com>
1 parent e66d0f6 commit 379fead

File tree

2 files changed

+70
-80
lines changed

2 files changed

+70
-80
lines changed

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

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,18 @@ use crate::{
1515
};
1616
use parsec_openssl2::types::VOID_PTR;
1717
use parsec_openssl2::*;
18-
use std::sync::{Arc, Mutex, MutexGuard};
18+
use std::sync::{Arc, RwLock};
1919

2020
pub struct ParsecProviderKeyObject {
2121
provctx: Arc<ParsecProviderContext>,
22-
key_name: Mutex<Option<String>>,
22+
key_name: Option<String>,
2323
}
2424

2525
impl Clone for ParsecProviderKeyObject {
2626
fn clone(&self) -> Self {
27-
let key_name = self.key_name.lock().unwrap();
2827
ParsecProviderKeyObject {
2928
provctx: self.provctx.clone(),
30-
key_name: Mutex::new(key_name.clone()),
29+
key_name: self.key_name.clone(),
3130
}
3231
}
3332
}
@@ -36,16 +35,16 @@ impl ParsecProviderKeyObject {
3635
pub fn new(provctx: Arc<ParsecProviderContext>) -> Self {
3736
ParsecProviderKeyObject {
3837
provctx: provctx.clone(),
39-
key_name: None.into(),
38+
key_name: None,
4039
}
4140
}
4241

4342
pub fn get_provctx(&self) -> Arc<ParsecProviderContext> {
4443
self.provctx.clone()
4544
}
4645

47-
pub fn get_key_name(&self) -> MutexGuard<'_, Option<String>> {
48-
self.key_name.lock().unwrap()
46+
pub fn get_key_name(&self) -> &Option<String> {
47+
&self.key_name
4948
}
5049
}
5150

@@ -57,24 +56,25 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_new(provctx: VOID_PTR) -> VOID_PT
5756
if provctx.is_null() {
5857
return std::ptr::null_mut();
5958
}
60-
let ctx = provctx as *const ParsecProviderContext;
61-
Arc::increment_strong_count(ctx);
62-
let context = Arc::from_raw(ctx);
6359

64-
Arc::into_raw(Arc::new(ParsecProviderKeyObject::new(context))) as VOID_PTR
60+
Arc::increment_strong_count(provctx as *const ParsecProviderContext);
61+
let prov_ctx = Arc::from_raw(provctx as *const ParsecProviderContext);
62+
63+
Arc::into_raw(Arc::new(RwLock::new(ParsecProviderKeyObject::new(
64+
prov_ctx,
65+
)))) as VOID_PTR
6566
}
6667

6768
// should free the passed keydata
6869
pub unsafe extern "C" fn parsec_provider_kmgmt_free(keydata: VOID_PTR) {
6970
if keydata.is_null() {
7071
return;
7172
}
72-
let keydata_ptr = keydata as *const ParsecProviderKeyObject;
73-
let arc_keydata = Arc::from_raw(keydata_ptr);
73+
let key_data = Arc::from_raw(keydata as *const RwLock<ParsecProviderKeyObject>);
7474
// A strong_count of 1 should be guaranteed by OPENSSL, as it doesn't make sense to be calling
7575
// free when you are still using keydata.
76-
assert_eq!(1, Arc::strong_count(&arc_keydata));
77-
// When arc_keydata is dropped, the reference count is decremented and the memory is freed
76+
assert_eq!(1, Arc::strong_count(&key_data));
77+
// When key_data is dropped, the reference count is decremented and the memory is freed
7878
}
7979

8080
/*
@@ -106,10 +106,6 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_set_params(
106106
if keydata.is_null() || params.is_null() {
107107
Err("Null pointer received as parameter".into())
108108
} else {
109-
let keyobj = keydata as *mut ParsecProviderKeyObject;
110-
Arc::increment_strong_count(keyobj);
111-
let arc_keyobj = Arc::from_raw(keyobj);
112-
113109
let param: openssl_bindings::OSSL_PARAM =
114110
*openssl_returns_nonnull(openssl_bindings::OSSL_PARAM_locate(
115111
params,
@@ -119,8 +115,11 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_set_params(
119115
let key_name: &mut [u8] =
120116
core::slice::from_raw_parts_mut(param.data as *mut u8, param.data_size);
121117

122-
let mut keyobj_key_name = arc_keyobj.key_name.lock().unwrap();
123-
*keyobj_key_name = Some(std::str::from_utf8(key_name)?.to_string());
118+
Arc::increment_strong_count(keydata as *const RwLock<ParsecProviderKeyObject>);
119+
let key_data = Arc::from_raw(keydata as *const RwLock<ParsecProviderKeyObject>);
120+
121+
let mut writer_key_data = key_data.write().unwrap();
122+
writer_key_data.key_name = Some(std::str::from_utf8(key_name)?.to_string());
124123

125124
Ok(OPENSSL_SUCCESS)
126125
}
@@ -147,11 +146,10 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_has(
147146
}
148147

149148
if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
150-
let keydata_ptr = keydata as *const ParsecProviderKeyObject;
151-
Arc::increment_strong_count(keydata_ptr);
152-
let arc_keydata = Arc::from_raw(keydata_ptr);
153-
let key_name = arc_keydata.key_name.lock().unwrap();
154-
if key_name.is_some() {
149+
Arc::increment_strong_count(keydata as *const RwLock<ParsecProviderKeyObject>);
150+
let key_data = Arc::from_raw(keydata as *const RwLock<ParsecProviderKeyObject>);
151+
let reader_key_data = key_data.read().unwrap();
152+
if reader_key_data.key_name.is_some() {
155153
Ok(OPENSSL_SUCCESS)
156154
} else {
157155
Err("key name has not been set.".into())
@@ -171,15 +169,14 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_has(
171169
should import data indicated by selection into keydata with values taken from the OSSL_PARAM array params
172170
*/
173171
pub unsafe extern "C" fn parsec_provider_kmgmt_import(
174-
key_data: VOID_PTR,
172+
keydata: VOID_PTR,
175173
selection: std::os::raw::c_int,
176174
params: *mut OSSL_PARAM,
177175
) -> std::os::raw::c_int {
178176
if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
179177
let result = super::r#catch(Some(|| super::Error::PROVIDER_KEYMGMT_IMPORT), || {
180-
let keydata_ptr = key_data as *const ParsecProviderKeyObject;
181-
Arc::increment_strong_count(keydata_ptr);
182-
let arc_keydata = Arc::from_raw(keydata_ptr);
178+
Arc::increment_strong_count(keydata as *const RwLock<ParsecProviderKeyObject>);
179+
let key_data = Arc::from_raw(keydata as *const RwLock<ParsecProviderKeyObject>);
183180
let param: openssl_bindings::OSSL_PARAM =
184181
*openssl_returns_nonnull(openssl_bindings::OSSL_PARAM_locate(
185182
params,
@@ -191,7 +188,8 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_import(
191188
param.data_size,
192189
));
193190

194-
let keys = arc_keydata
191+
let reader_key_data = key_data.read().unwrap();
192+
let keys = reader_key_data
195193
.provctx
196194
.get_client()
197195
.list_keys()
@@ -206,7 +204,7 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_import(
206204
match result {
207205
// Right now, settable params are the same as the import types, so it's ok to use this
208206
// function
209-
Ok(_) => parsec_provider_kmgmt_set_params(key_data, params),
207+
Ok(_) => parsec_provider_kmgmt_set_params(keydata, params),
210208
Err(()) => OPENSSL_ERROR,
211209
}
212210
} else {
@@ -249,16 +247,16 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_validate(
249247
}
250248

251249
if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
252-
let keydata_ptr = keydata as *const ParsecProviderKeyObject;
253-
Arc::increment_strong_count(keydata_ptr);
254-
let arc_keydata = Arc::from_raw(keydata_ptr);
255-
let key_name = arc_keydata.key_name.lock().unwrap();
250+
Arc::increment_strong_count(keydata as *const RwLock<ParsecProviderKeyObject>);
251+
let key_data = Arc::from_raw(keydata as *const RwLock<ParsecProviderKeyObject>);
252+
let reader_key_data = key_data.read().unwrap();
253+
let key_name = (*reader_key_data).get_key_name();
256254
let result =
257255
super::r#catch(
258256
Some(|| super::Error::PROVIDER_KEYMGMT_VALIDATE),
259-
|| match &*key_name {
257+
|| match key_name {
260258
Some(name) => {
261-
let keys = arc_keydata
259+
let keys = reader_key_data
262260
.provctx
263261
.get_client()
264262
.list_keys()
@@ -301,19 +299,16 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_match(
301299
}
302300

303301
if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
304-
let keydata1_ptr = keydata1 as *const ParsecProviderKeyObject;
305-
let keydata2_ptr = keydata2 as *const ParsecProviderKeyObject;
306-
307-
Arc::increment_strong_count(keydata1_ptr);
308-
Arc::increment_strong_count(keydata2_ptr);
302+
Arc::increment_strong_count(keydata1 as *const RwLock<ParsecProviderKeyObject>);
303+
Arc::increment_strong_count(keydata2 as *const RwLock<ParsecProviderKeyObject>);
309304

310-
let arc_keydata1 = Arc::from_raw(keydata1_ptr);
311-
let arc_keydata2 = Arc::from_raw(keydata2_ptr);
305+
let key_data1 = Arc::from_raw(keydata1 as *const RwLock<ParsecProviderKeyObject>);
306+
let key_data2 = Arc::from_raw(keydata2 as *const RwLock<ParsecProviderKeyObject>);
312307

313-
let key_name1 = arc_keydata1.key_name.lock().unwrap();
314-
let key_name2 = arc_keydata2.key_name.lock().unwrap();
308+
let reader_key_data1 = key_data1.read().unwrap();
309+
let reader_key_data2 = key_data2.read().unwrap();
315310

316-
if *key_name1 == *key_name2 {
311+
if reader_key_data1.key_name == reader_key_data2.key_name {
317312
Ok(OPENSSL_SUCCESS)
318313
} else {
319314
Err("Key names do not match".into())
@@ -338,11 +333,11 @@ pub unsafe extern "C" fn parsec_provider_keymgmt_dup(
338333
selection: std::os::raw::c_int,
339334
) -> VOID_PTR {
340335
if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std::os::raw::c_int != 0 {
341-
let keydata_from_ptr = keydata_from as *const ParsecProviderKeyObject;
342-
Arc::increment_strong_count(keydata_from_ptr);
343-
let arc_keydata_from = Arc::from_raw(keydata_from_ptr);
336+
Arc::increment_strong_count(keydata_from as *const RwLock<ParsecProviderKeyObject>);
337+
let key_data_from = Arc::from_raw(keydata_from as *const RwLock<ParsecProviderKeyObject>);
344338

345-
let duplicate: ParsecProviderKeyObject = (*arc_keydata_from).clone();
339+
let reader_key_data_from = key_data_from.read().unwrap();
340+
let duplicate: RwLock<ParsecProviderKeyObject> = RwLock::new(reader_key_data_from.clone());
346341
Arc::into_raw(Arc::new(duplicate)) as VOID_PTR
347342
} else {
348343
std::ptr::null_mut()
@@ -763,13 +758,12 @@ fn test_kmgmt_dup() {
763758
let duplicated =
764759
unsafe { parsec_provider_keymgmt_dup(keyobj, OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as i32) };
765760

766-
let duplicated_ptr = duplicated as *const ParsecProviderKeyObject;
767761
unsafe {
768-
Arc::increment_strong_count(duplicated_ptr);
769-
let arc_duplicated = Arc::from_raw(duplicated_ptr);
770-
let duplicated_key_name = arc_duplicated.key_name.lock().unwrap();
762+
Arc::increment_strong_count(duplicated as *const RwLock<ParsecProviderKeyObject>);
763+
let arc_duplicated = Arc::from_raw(duplicated as *const RwLock<ParsecProviderKeyObject>);
764+
let reader_dup = arc_duplicated.read().unwrap();
771765

772-
assert_eq!(*duplicated_key_name, Some(my_key_name))
766+
assert_eq!(reader_dup.key_name, Some(my_key_name))
773767
}
774768

775769
unsafe {

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

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,19 @@ use parsec_client::core::interface::operations::psa_key_attributes::{Attributes,
1515
use parsec_openssl2::types::VOID_PTR;
1616
use parsec_openssl2::*;
1717

18-
use std::sync::{Arc, Mutex};
18+
use std::sync::{Arc, RwLock};
1919

2020
struct ParsecProviderSignatureContext {
2121
/* The key object is set in the signature context by calling OSSL_FUNC_signature_sign_init().
2222
Before calling OSSL_FUNC_signature_sign_init(), the key object itself should have been set up
2323
and initialized via keymgmt function calls.
2424
*/
25-
keyobj: Mutex<Option<Arc<ParsecProviderKeyObject>>>,
25+
keyobj: Option<Arc<RwLock<ParsecProviderKeyObject>>>,
2626
}
2727

2828
impl ParsecProviderSignatureContext {
2929
pub fn new() -> Self {
30-
ParsecProviderSignatureContext {
31-
keyobj: Mutex::new(None),
32-
}
30+
ParsecProviderSignatureContext { keyobj: None }
3331
}
3432
}
3533

@@ -47,7 +45,7 @@ pub unsafe extern "C" fn parsec_provider_signature_newctx(
4745
) -> VOID_PTR {
4846
// We are currently ignoring provctx and propq, so no need for input validation (checking for NULL, etc.)
4947

50-
let new_context = Arc::new(ParsecProviderSignatureContext::new());
48+
let new_context = Arc::new(RwLock::new(ParsecProviderSignatureContext::new()));
5149

5250
Arc::into_raw(new_context) as VOID_PTR
5351
}
@@ -58,12 +56,11 @@ pub unsafe extern "C" fn parsec_provider_signature_freectx(ctx: VOID_PTR) {
5856
return;
5957
}
6058

61-
let ctx_ptr = ctx as *const ParsecProviderSignatureContext;
62-
let arc_ctx = Arc::from_raw(ctx_ptr);
59+
let sig_ctx = Arc::from_raw(ctx as *const RwLock<ParsecProviderSignatureContext>);
6360
// A strong_count of 1 should be guaranteed by OPENSSL, as it doesn't make sense to be calling
6461
// free when you are still using the ctx.
65-
assert_eq!(1, Arc::strong_count(&arc_ctx));
66-
// When arc_ctx is dropped, the reference count is decremented and the memory is freed
62+
assert_eq!(1, Arc::strong_count(&sig_ctx));
63+
// When sig_ctx is dropped, the reference count is decremented and the memory is freed
6764
}
6865

6966
/*
@@ -81,15 +78,14 @@ unsafe extern "C" fn parsec_provider_signature_sign_init(
8178
if ctx.is_null() || provkey.is_null() {
8279
return Err("Neither ctx nor provkey pointers should be NULL.".into());
8380
}
84-
let sig_ctx_ptr = ctx as *const ParsecProviderSignatureContext;
85-
Arc::increment_strong_count(sig_ctx_ptr);
86-
let arc_sig_ctx = Arc::from_raw(sig_ctx_ptr);
81+
Arc::increment_strong_count(ctx as *const RwLock<ParsecProviderSignatureContext>);
82+
let sig_ctx = Arc::from_raw(ctx as *const RwLock<ParsecProviderSignatureContext>);
8783

88-
let provkey_ptr = provkey as *const ParsecProviderKeyObject;
89-
Arc::increment_strong_count(provkey_ptr);
90-
let arc_provkey = Arc::from_raw(provkey_ptr);
84+
Arc::increment_strong_count(provkey as *const RwLock<ParsecProviderKeyObject>);
85+
let prov_key = Arc::from_raw(provkey as *const RwLock<ParsecProviderKeyObject>);
9186

92-
*(arc_sig_ctx.keyobj.lock().unwrap()) = Some(arc_provkey.clone());
87+
let mut sig_writable = sig_ctx.write().unwrap();
88+
sig_writable.keyobj = Some(prov_key.clone());
9389
Ok(OPENSSL_SUCCESS)
9490
});
9591

@@ -132,18 +128,18 @@ unsafe extern "C" fn parsec_provider_signature_sign(
132128
return Err("Received unexpected NULL pointer as an argument.".into());
133129
}
134130

135-
Arc::increment_strong_count(ctx as *const ParsecProviderSignatureContext);
136-
let arc_sig_ctx = Arc::from_raw(ctx as *const ParsecProviderSignatureContext);
131+
Arc::increment_strong_count(ctx as *const RwLock<ParsecProviderSignatureContext>);
132+
let sig_ctx = Arc::from_raw(ctx as *const RwLock<ParsecProviderSignatureContext>);
137133

138-
let keyobj = match *arc_sig_ctx.keyobj.lock().unwrap() {
134+
let reader_sig_ctx = sig_ctx.read().unwrap();
135+
let keyobj = match reader_sig_ctx.keyobj {
139136
None => {
140137
return Err("Key Object not set. This should be done through sign_init()".into())
141138
}
142-
Some(ref keyobj) => keyobj.clone(),
139+
Some(ref keyobj) => keyobj.read().unwrap(),
143140
};
144141

145-
let key_name_binding = keyobj.get_key_name();
146-
let key_name = match *key_name_binding {
142+
let key_name = match keyobj.get_key_name() {
147143
None => return Err("Key name not set in the Key Object".into()),
148144
Some(ref name) => name,
149145
};

0 commit comments

Comments
 (0)