wasi_crypto/symmetric/
key.rs1use std::sync::{Arc, Mutex, MutexGuard};
2
3use super::*;
4use crate::array_output::*;
5use crate::version::*;
6use crate::CryptoCtx;
7
8#[derive(Clone)]
9pub struct SymmetricKey {
10 inner: Arc<Mutex<Box<dyn SymmetricKeyLike>>>,
11}
12
13pub trait SymmetricKeyBuilder {
14 fn generate(&self, options: Option<SymmetricOptions>) -> Result<SymmetricKey, CryptoError>;
15
16 fn import(&self, raw: &[u8]) -> Result<SymmetricKey, CryptoError>;
17
18 fn key_len(&self) -> Result<usize, CryptoError>;
19}
20
21impl SymmetricKey {
22 pub fn new(symmetric_key_like: Box<dyn SymmetricKeyLike>) -> Self {
23 SymmetricKey {
24 inner: Arc::new(Mutex::new(symmetric_key_like)),
25 }
26 }
27
28 pub fn inner(&self) -> MutexGuard<'_, Box<dyn SymmetricKeyLike>> {
29 self.inner.lock().unwrap()
30 }
31
32 pub fn locked<T, U>(&self, mut f: T) -> U
33 where
34 T: FnMut(MutexGuard<'_, Box<dyn SymmetricKeyLike>>) -> U,
35 {
36 f(self.inner())
37 }
38
39 pub fn alg(&self) -> SymmetricAlgorithm {
40 self.inner().alg()
41 }
42
43 pub fn builder(alg_str: &str) -> Result<Box<dyn SymmetricKeyBuilder>, CryptoError> {
44 let alg = SymmetricAlgorithm::try_from(alg_str)?;
45 let builder = match alg {
46 SymmetricAlgorithm::HmacSha256 | SymmetricAlgorithm::HmacSha512 => {
47 HmacSha2SymmetricKeyBuilder::new(alg)
48 }
49 SymmetricAlgorithm::HkdfSha256Expand
50 | SymmetricAlgorithm::HkdfSha256Extract
51 | SymmetricAlgorithm::HkdfSha512Expand
52 | SymmetricAlgorithm::HkdfSha512Extract => HkdfSymmetricKeyBuilder::new(alg),
53 SymmetricAlgorithm::Aes128Gcm | SymmetricAlgorithm::Aes256Gcm => {
54 AesGcmSymmetricKeyBuilder::new(alg)
55 }
56 SymmetricAlgorithm::Xoodyak128 | SymmetricAlgorithm::Xoodyak160 => {
57 XoodyakSymmetricKeyBuilder::new(alg)
58 }
59 SymmetricAlgorithm::ChaCha20Poly1305 | SymmetricAlgorithm::XChaCha20Poly1305 => {
60 ChaChaPolySymmetricKeyBuilder::new(alg)
61 }
62 _ => bail!(CryptoError::InvalidOperation),
63 };
64 Ok(builder)
65 }
66
67 fn generate(
68 alg_str: &str,
69 options: Option<SymmetricOptions>,
70 ) -> Result<SymmetricKey, CryptoError> {
71 let builder = Self::builder(alg_str)?;
72 builder.generate(options)
73 }
74
75 fn import(alg_str: &str, raw: &[u8]) -> Result<SymmetricKey, CryptoError> {
76 let builder = Self::builder(alg_str)?;
77 builder.import(raw)
78 }
79}
80
81pub trait SymmetricKeyLike: Sync + Send {
82 fn as_any(&self) -> &dyn Any;
83 fn alg(&self) -> SymmetricAlgorithm;
84 fn as_raw(&self) -> Result<&[u8], CryptoError>;
85}
86
87impl CryptoCtx {
88 pub fn symmetric_key_generate(
89 &self,
90 alg_str: &str,
91 options_handle: Option<Handle>,
92 ) -> Result<Handle, CryptoError> {
93 let options = match options_handle {
94 None => None,
95 Some(options_handle) => {
96 Some(self.handles.options.get(options_handle)?.into_symmetric()?)
97 }
98 };
99 let symmetric_key = SymmetricKey::generate(alg_str, options)?;
100 let handle = self.handles.symmetric_key.register(symmetric_key)?;
101 Ok(handle)
102 }
103
104 pub fn symmetric_key_import(&self, alg_str: &str, raw: &[u8]) -> Result<Handle, CryptoError> {
105 let symmetric_key = SymmetricKey::import(alg_str, raw)?;
106 let handle = self.handles.symmetric_key.register(symmetric_key)?;
107 Ok(handle)
108 }
109
110 pub fn symmetric_key_export(
111 &self,
112 symmetric_key_handle: Handle,
113 ) -> Result<Handle, CryptoError> {
114 let symmetric_key = self.handles.symmetric_key.get(symmetric_key_handle)?;
115 let array_output_handle =
116 ArrayOutput::register(&self.handles, symmetric_key.inner().as_raw()?.to_vec())?;
117 Ok(array_output_handle)
118 }
119
120 pub fn symmetric_key_id(
121 &self,
122 symmetric_key_handle: Handle,
123 ) -> Result<(Vec<u8>, Version), CryptoError> {
124 let _symmetric_key = self.handles.symmetric_key.get(symmetric_key_handle)?;
125 bail!(CryptoError::UnsupportedFeature)
126 }
127
128 pub fn symmetric_key_close(&self, symmetric_key_handle: Handle) -> Result<(), CryptoError> {
129 self.handles.symmetric_key.close(symmetric_key_handle)
130 }
131}