veridian_kernel/crypto/
keystore.rs1#![allow(dead_code)]
6
7use alloc::{collections::BTreeMap, string::String, vec::Vec};
8
9use spin::RwLock;
10
11use super::{CryptoError, CryptoResult};
12use crate::sync::once_lock::OnceLock;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16pub(crate) struct KeyId(pub u64);
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub(crate) enum KeyType {
21 Symmetric,
22 SigningKey,
23 VerifyingKey,
24 EncryptionKey,
25}
26
27#[derive(Debug, Clone)]
29pub(crate) struct Key {
30 pub(crate) id: KeyId,
31 pub(crate) key_type: KeyType,
32 pub(crate) data: Vec<u8>,
33 pub(crate) metadata: KeyMetadata,
34}
35
36#[derive(Debug, Clone)]
38pub(crate) struct KeyMetadata {
39 pub(crate) name: String,
40 pub(crate) created: u64,
41 pub(crate) expires: Option<u64>,
42 pub(crate) usage_count: u64,
43 pub(crate) max_usage: Option<u64>,
44}
45
46pub(crate) struct KeyStore {
48 keys: RwLock<BTreeMap<KeyId, Key>>,
49 next_id: RwLock<u64>,
50}
51
52impl KeyStore {
53 pub(crate) fn new() -> Self {
55 Self {
56 keys: RwLock::new(BTreeMap::new()),
57 next_id: RwLock::new(1),
58 }
59 }
60
61 pub(crate) fn store_key(
63 &self,
64 key_type: KeyType,
65 data: Vec<u8>,
66 name: String,
67 ) -> CryptoResult<KeyId> {
68 let mut next_id = self.next_id.write();
69 let id = KeyId(*next_id);
70 *next_id += 1;
71
72 let key = Key {
73 id,
74 key_type,
75 data,
76 metadata: KeyMetadata {
77 name,
78 created: Self::current_time(),
79 expires: None,
80 usage_count: 0,
81 max_usage: None,
82 },
83 };
84
85 self.keys.write().insert(id, key);
86
87 Ok(id)
88 }
89
90 pub(crate) fn get_key(&self, id: KeyId) -> CryptoResult<Key> {
92 let keys = self.keys.read();
93
94 keys.get(&id).cloned().ok_or(CryptoError::InvalidKey)
95 }
96
97 pub(crate) fn delete_key(&self, id: KeyId) -> CryptoResult<()> {
99 let mut keys = self.keys.write();
100
101 keys.remove(&id).ok_or(CryptoError::InvalidKey).map(|_| ())
102 }
103
104 pub(crate) fn list_keys(&self) -> Vec<KeyId> {
106 self.keys.read().keys().copied().collect()
107 }
108
109 pub(crate) fn use_key(&self, id: KeyId) -> CryptoResult<()> {
111 let mut keys = self.keys.write();
112
113 if let Some(key) = keys.get_mut(&id) {
114 key.metadata.usage_count += 1;
115
116 if let Some(max_usage) = key.metadata.max_usage {
118 if key.metadata.usage_count > max_usage {
119 return Err(CryptoError::InvalidKey);
120 }
121 }
122
123 if let Some(expires) = key.metadata.expires {
125 if Self::current_time() > expires {
126 return Err(CryptoError::InvalidKey);
127 }
128 }
129
130 Ok(())
131 } else {
132 Err(CryptoError::InvalidKey)
133 }
134 }
135
136 pub(crate) fn set_expiration(&self, id: KeyId, expires: u64) -> CryptoResult<()> {
138 let mut keys = self.keys.write();
139
140 if let Some(key) = keys.get_mut(&id) {
141 key.metadata.expires = Some(expires);
142 Ok(())
143 } else {
144 Err(CryptoError::InvalidKey)
145 }
146 }
147
148 pub(crate) fn set_max_usage(&self, id: KeyId, max_usage: u64) -> CryptoResult<()> {
150 let mut keys = self.keys.write();
151
152 if let Some(key) = keys.get_mut(&id) {
153 key.metadata.max_usage = Some(max_usage);
154 Ok(())
155 } else {
156 Err(CryptoError::InvalidKey)
157 }
158 }
159
160 fn current_time() -> u64 {
161 crate::arch::timer::get_timestamp_secs()
162 }
163}
164
165impl Default for KeyStore {
166 fn default() -> Self {
167 Self::new()
168 }
169}
170
171static GLOBAL_KEYSTORE: RwLock<Option<KeyStore>> = RwLock::new(None);
173
174pub(crate) fn init() -> CryptoResult<()> {
176 let keystore = KeyStore::new();
177 *GLOBAL_KEYSTORE.write() = Some(keystore);
178 Ok(())
179}
180
181static KEYSTORE_STORAGE: OnceLock<KeyStore> = OnceLock::new();
183
184pub(crate) fn get_keystore() -> &'static KeyStore {
186 KEYSTORE_STORAGE.get_or_init(KeyStore::new)
187}
188
189#[cfg(test)]
190mod tests {
191 use alloc::vec;
192
193 use super::*;
194
195 #[test]
196 fn test_keystore_operations() {
197 let store = KeyStore::new();
198
199 let key_data = vec![0x42u8; 32];
201 let id = store
202 .store_key(
203 KeyType::Symmetric,
204 key_data.clone(),
205 String::from("test_key"),
206 )
207 .unwrap();
208
209 let retrieved = store.get_key(id).unwrap();
211 assert_eq!(retrieved.data, key_data);
212
213 store.delete_key(id).unwrap();
215
216 assert!(store.get_key(id).is_err());
218 }
219}