Skip to content

Commit 014bd8a

Browse files
committed
Changed local_ids for Atomic counter and removed key_slot_semaphore.
Signed-off-by: Samuel Bailey <[email protected]>
1 parent 5fe158a commit 014bd8a

File tree

3 files changed

+40
-70
lines changed

3 files changed

+40
-70
lines changed

src/providers/mbed_provider/asym_sign.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ impl MbedProvider {
1616
op: psa_sign_hash::Operation,
1717
) -> Result<psa_sign_hash::Result> {
1818
info!("Mbed Provider - Asym Sign");
19-
let _semaphore_guard = self.key_slot_semaphore.access();
2019
let key_name = op.key_name;
2120
let hash = op.hash;
2221
let alg = op.alg;
@@ -53,7 +52,6 @@ impl MbedProvider {
5352
op: psa_verify_hash::Operation,
5453
) -> Result<psa_verify_hash::Result> {
5554
info!("Mbed Provider - Asym Verify");
56-
let _semaphore_guard = self.key_slot_semaphore.access();
5755
let key_name = op.key_name;
5856
let hash = op.hash;
5957
let alg = op.alg;

src/providers/mbed_provider/key_management.rs

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Copyright 2020 Contributors to the Parsec project.
22
// SPDX-License-Identifier: Apache-2.0
3-
use super::{LocalIdStore, MbedProvider};
3+
use super::MbedProvider;
44
use crate::authenticators::ApplicationName;
55
use crate::key_info_managers;
66
use crate::key_info_managers::{KeyInfo, KeyTriple, ManageKeyInfo};
7+
use log::error;
78
use log::{info, warn};
89
use parsec_interface::operations::psa_key_attributes::Attributes;
910
use parsec_interface::operations::{
@@ -12,8 +13,7 @@ use parsec_interface::operations::{
1213
use parsec_interface::requests::{ProviderID, ResponseStatus, Result};
1314
use psa_crypto::operations::key_management as psa_crypto_key_management;
1415
use psa_crypto::types::key;
15-
use rand::rngs::SmallRng;
16-
use rand::{Rng, SeedableRng};
16+
use std::sync::atomic::{AtomicU32, Ordering::Relaxed};
1717

1818
/// Gets a PSA Key ID from the Key Info Manager.
1919
/// Wrapper around the get method of the Key Info Manager to convert the key ID to the psa_key_id_t
@@ -46,42 +46,40 @@ fn create_key_id(
4646
key_triple: KeyTriple,
4747
key_attributes: Attributes,
4848
store_handle: &mut dyn ManageKeyInfo,
49-
local_ids_handle: &mut LocalIdStore,
49+
max_current_id: &AtomicU32,
5050
) -> Result<key::psa_key_id_t> {
51-
let mut rng = SmallRng::from_entropy();
52-
let mut key_id = rng.gen_range(key::PSA_KEY_ID_USER_MIN, key::PSA_KEY_ID_USER_MAX + 1);
53-
54-
while local_ids_handle.contains(&key_id) {
55-
key_id = rng.gen_range(key::PSA_KEY_ID_USER_MIN, key::PSA_KEY_ID_USER_MAX + 1);
51+
// fetch_add adds 1 to the old value and returns the old value, so add 1 to local value for new ID
52+
let new_key_id = max_current_id.fetch_add(1, Relaxed) + 1;
53+
if new_key_id > key::PSA_KEY_ID_USER_MAX {
54+
// If storing key failed and no other keys were created in the mean time, it is safe to
55+
// decrement the key counter.
56+
let _ = max_current_id.store(key::PSA_KEY_ID_USER_MAX, Relaxed);
57+
error!(
58+
"PSA max key ID limit of {} reached",
59+
key::PSA_KEY_ID_USER_MAX
60+
);
61+
return Err(ResponseStatus::PsaErrorInsufficientMemory);
5662
}
63+
5764
let key_info = KeyInfo {
58-
id: key_id.to_ne_bytes().to_vec(),
65+
id: new_key_id.to_ne_bytes().to_vec(),
5966
attributes: key_attributes,
6067
};
6168
match store_handle.insert(key_triple.clone(), key_info) {
6269
Ok(insert_option) => {
6370
if insert_option.is_some() {
6471
warn!("Overwriting Key triple mapping ({})", key_triple);
6572
}
66-
let _ = local_ids_handle.insert(key_id);
67-
68-
Ok(key_id)
73+
Ok(new_key_id)
6974
}
7075
Err(string) => Err(key_info_managers::to_response_status(string)),
7176
}
7277
}
7378

74-
fn remove_key_id(
75-
key_triple: &KeyTriple,
76-
key_id: key::psa_key_id_t,
77-
store_handle: &mut dyn ManageKeyInfo,
78-
local_ids_handle: &mut LocalIdStore,
79-
) -> Result<()> {
79+
fn remove_key_id(key_triple: &KeyTriple, store_handle: &mut dyn ManageKeyInfo) -> Result<()> {
80+
// ID Counter not affected as overhead and extra complication deemed unnecessary
8081
match store_handle.remove(key_triple) {
81-
Ok(_) => {
82-
let _ = local_ids_handle.remove(&key_id);
83-
Ok(())
84-
}
82+
Ok(_) => Ok(()),
8583
Err(string) => Err(key_info_managers::to_response_status(string)),
8684
}
8785
}
@@ -99,23 +97,21 @@ impl MbedProvider {
9997
op: psa_generate_key::Operation,
10098
) -> Result<psa_generate_key::Result> {
10199
info!("Mbed Provider - Create Key");
102-
let _semaphore_guard = self.key_slot_semaphore.access();
103100
let key_name = op.key_name;
104101
let key_attributes = op.attributes;
105102
let key_triple = KeyTriple::new(app_name, ProviderID::MbedCrypto, key_name);
106103
let mut store_handle = self
107104
.key_info_store
108105
.write()
109106
.expect("Key store lock poisoned");
110-
let mut local_ids_handle = self.local_ids.write().expect("Local ID lock poisoned");
111107
if key_info_exists(&key_triple, &*store_handle)? {
112108
return Err(ResponseStatus::PsaErrorAlreadyExists);
113109
}
114110
let key_id = create_key_id(
115111
key_triple.clone(),
116112
key_attributes,
117113
&mut *store_handle,
118-
&mut local_ids_handle,
114+
&self.id_counter,
119115
)?;
120116

121117
let _guard = self
@@ -126,12 +122,7 @@ impl MbedProvider {
126122
match psa_crypto_key_management::generate(key_attributes, Some(key_id)) {
127123
Ok(_) => Ok(psa_generate_key::Result {}),
128124
Err(error) => {
129-
remove_key_id(
130-
&key_triple,
131-
key_id,
132-
&mut *store_handle,
133-
&mut local_ids_handle,
134-
)?;
125+
remove_key_id(&key_triple, &mut *store_handle)?;
135126
let error = ResponseStatus::from(error);
136127
format_error!("Generate key status: {}", error);
137128
Err(error)
@@ -145,7 +136,6 @@ impl MbedProvider {
145136
op: psa_import_key::Operation,
146137
) -> Result<psa_import_key::Result> {
147138
info!("Mbed Provider - Import Key");
148-
let _semaphore_guard = self.key_slot_semaphore.access();
149139
let key_name = op.key_name;
150140
let key_attributes = op.attributes;
151141
let key_data = op.data;
@@ -154,15 +144,14 @@ impl MbedProvider {
154144
.key_info_store
155145
.write()
156146
.expect("Key store lock poisoned");
157-
let mut local_ids_handle = self.local_ids.write().expect("Local ID lock poisoned");
158147
if key_info_exists(&key_triple, &*store_handle)? {
159148
return Err(ResponseStatus::PsaErrorAlreadyExists);
160149
}
161150
let key_id = create_key_id(
162151
key_triple.clone(),
163152
key_attributes,
164153
&mut *store_handle,
165-
&mut local_ids_handle,
154+
&self.id_counter,
166155
)?;
167156

168157
let _guard = self
@@ -173,12 +162,7 @@ impl MbedProvider {
173162
match psa_crypto_key_management::import(key_attributes, Some(key_id), &key_data[..]) {
174163
Ok(_) => Ok(psa_import_key::Result {}),
175164
Err(error) => {
176-
remove_key_id(
177-
&key_triple,
178-
key_id,
179-
&mut *store_handle,
180-
&mut local_ids_handle,
181-
)?;
165+
remove_key_id(&key_triple, &mut *store_handle)?;
182166
let error = ResponseStatus::from(error);
183167
format_error!("Import key status: {}", error);
184168
Err(error)
@@ -192,7 +176,6 @@ impl MbedProvider {
192176
op: psa_export_public_key::Operation,
193177
) -> Result<psa_export_public_key::Result> {
194178
info!("Mbed Provider - Export Public Key");
195-
let _semaphore_guard = self.key_slot_semaphore.access();
196179
let key_name = op.key_name;
197180
let key_triple = KeyTriple::new(app_name, ProviderID::MbedCrypto, key_name);
198181
let store_handle = self.key_info_store.read().expect("Key store lock poisoned");
@@ -220,14 +203,12 @@ impl MbedProvider {
220203
op: psa_destroy_key::Operation,
221204
) -> Result<psa_destroy_key::Result> {
222205
info!("Mbed Provider - Destroy Key");
223-
let _semaphore_guard = self.key_slot_semaphore.access();
224206
let key_name = op.key_name;
225207
let key_triple = KeyTriple::new(app_name, ProviderID::MbedCrypto, key_name);
226208
let mut store_handle = self
227209
.key_info_store
228210
.write()
229211
.expect("Key store lock poisoned");
230-
let mut local_ids_handle = self.local_ids.write().expect("Local ID lock poisoned");
231212
let key_id = get_key_id(&key_triple, &*store_handle)?;
232213

233214
let _guard = self
@@ -247,12 +228,7 @@ impl MbedProvider {
247228

248229
match destroy_key_status {
249230
Ok(()) => {
250-
remove_key_id(
251-
&key_triple,
252-
key_id,
253-
&mut *store_handle,
254-
&mut local_ids_handle,
255-
)?;
231+
remove_key_id(&key_triple, &mut *store_handle)?;
256232
Ok(psa_destroy_key::Result {})
257233
}
258234
Err(error) => {

src/providers/mbed_provider/mod.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ use parsec_interface::requests::{Opcode, ProviderID, ResponseStatus, Result};
1414
use psa_crypto::types::{key, status};
1515
use std::collections::HashSet;
1616
use std::io::{Error, ErrorKind};
17-
use std::sync::{Arc, Mutex, RwLock};
18-
use std_semaphore::Semaphore;
17+
use std::sync::{
18+
atomic::{AtomicU32, Ordering::Relaxed},
19+
Arc, Mutex, RwLock,
20+
};
1921
use uuid::Uuid;
2022

2123
mod asym_sign;
2224
#[allow(dead_code)]
2325
mod key_management;
2426

25-
type LocalIdStore = HashSet<key::psa_key_id_t>;
26-
const PSA_KEY_SLOT_COUNT: isize = 32;
2727
const SUPPORTED_OPCODES: [Opcode; 6] = [
2828
Opcode::PsaGenerateKey,
2929
Opcode::PsaDestroyKey,
@@ -42,18 +42,16 @@ pub struct MbedProvider {
4242
// reference it to match with the method prototypes.
4343
#[derivative(Debug = "ignore")]
4444
key_info_store: Arc<RwLock<dyn ManageKeyInfo + Send + Sync>>,
45-
local_ids: RwLock<LocalIdStore>,
4645
// Calls to `psa_open_key`, `psa_generate_key` and `psa_destroy_key` are not thread safe - the slot
4746
// allocation mechanism in Mbed Crypto can return the same key slot for overlapping calls.
4847
// `key_handle_mutex` is use as a way of securing access to said operations among the threads.
4948
// This issue tracks progress on fixing the original problem in Mbed Crypto:
5049
// https://github.com/ARMmbed/mbed-crypto/issues/266
5150
key_handle_mutex: Mutex<()>,
52-
// As mentioned above, calls dealing with key slot allocation are not secured for concurrency.
53-
// `key_slot_semaphore` is used to ensure that only `PSA_KEY_SLOT_COUNT` threads can have slots
54-
// assigned at any time.
55-
#[derivative(Debug = "ignore")]
56-
key_slot_semaphore: Semaphore,
51+
52+
// Holds the highest ID of all keys (including destroyed keys). New keys will receive an ID of
53+
// id_counter + 1. Once id_counter reaches the highest allowed ID, no more keys can be created.
54+
id_counter: AtomicU32,
5755
}
5856

5957
impl MbedProvider {
@@ -70,21 +68,17 @@ impl MbedProvider {
7068
}
7169
let mbed_provider = MbedProvider {
7270
key_info_store,
73-
local_ids: RwLock::new(HashSet::new()),
7471
key_handle_mutex: Mutex::new(()),
75-
key_slot_semaphore: Semaphore::new(PSA_KEY_SLOT_COUNT),
72+
id_counter: AtomicU32::new(key::PSA_KEY_ID_USER_MIN),
7673
};
74+
let mut max_key_id: key::psa_key_id_t = key::PSA_KEY_ID_USER_MIN;
7775
{
7876
// The local scope allows to drop store_handle and local_ids_handle in order to return
7977
// the mbed_provider.
8078
let mut store_handle = mbed_provider
8179
.key_info_store
8280
.write()
8381
.expect("Key store lock poisoned");
84-
let mut local_ids_handle = mbed_provider
85-
.local_ids
86-
.write()
87-
.expect("Local ID lock poisoned");
8882
let mut to_remove: Vec<KeyTriple> = Vec::new();
8983
// Go through all MbedProvider key triple to key info mappings and check if they are still
9084
// present.
@@ -104,7 +98,9 @@ impl MbedProvider {
10498
let pc_key_id = key::Id::from_persistent_key_id(key_id);
10599
match key::Attributes::from_key_id(pc_key_id) {
106100
Ok(_) => {
107-
let _ = local_ids_handle.insert(key_id);
101+
if key_id > max_key_id {
102+
max_key_id = key_id;
103+
}
108104
}
109105
Err(status::Error::DoesNotExist) => to_remove.push(key_triple.clone()),
110106
Err(e) => {
@@ -129,7 +125,7 @@ impl MbedProvider {
129125
}
130126
}
131127
}
132-
128+
mbed_provider.id_counter.store(max_key_id, Relaxed);
133129
Some(mbed_provider)
134130
}
135131
}

0 commit comments

Comments
 (0)