1use p256::ecdsa;
8use p256::ecdsa::signature::hazmat::PrehashSigner;
9
10use kernel::hil;
11use kernel::hil::public_key_crypto::keys::SetKeyBySliceClient;
12use kernel::utilities::cells::{OptionalCell, TakeCell};
13use kernel::ErrorCode;
14
15enum State {
16 Signing,
17 ChangingKey(&'static mut [u8; 64]),
18}
19
20pub struct EcdsaP256SignatureSigner<'a> {
21 client: OptionalCell<&'a dyn hil::public_key_crypto::signature::ClientSign<32, 64>>,
22 client_key_set: OptionalCell<&'a dyn hil::public_key_crypto::keys::SetKeyBySliceClient<64>>,
23 signing_key: TakeCell<'static, [u8; 32]>,
24 hash_storage: TakeCell<'static, [u8; 32]>,
25 signature_storage: TakeCell<'static, [u8; 64]>,
26 deferred_call: kernel::deferred_call::DeferredCall,
27 state: OptionalCell<State>,
28}
29
30impl EcdsaP256SignatureSigner<'_> {
31 pub fn new(signing_key: &'static mut [u8; 32]) -> Self {
32 Self {
33 client: OptionalCell::empty(),
34 client_key_set: OptionalCell::empty(),
35 signing_key: TakeCell::new(signing_key),
36 hash_storage: TakeCell::empty(),
37 signature_storage: TakeCell::empty(),
38 deferred_call: kernel::deferred_call::DeferredCall::new(),
39 state: OptionalCell::empty(),
40 }
41 }
42}
43
44impl<'a> hil::public_key_crypto::signature::SignatureSign<'a, 32, 64>
45 for EcdsaP256SignatureSigner<'a>
46{
47 fn set_sign_client(
48 &self,
49 client: &'a dyn hil::public_key_crypto::signature::ClientSign<32, 64>,
50 ) {
51 self.client.replace(client);
52 }
53
54 fn sign(
55 &self,
56 hash: &'static mut [u8; 32],
57 signature: &'static mut [u8; 64],
58 ) -> Result<
59 (),
60 (
61 kernel::ErrorCode,
62 &'static mut [u8; 32],
63 &'static mut [u8; 64],
64 ),
65 > {
66 if self.signing_key.is_some() {
67 self.signing_key
68 .map(|skey| {
69 let skey: &[u8; 32] = skey;
70 if let Ok(ecdsa_key) = ecdsa::SigningKey::from_bytes(skey.into()) {
71 let maybe_sig: Result<ecdsa::Signature, _> = ecdsa_key.sign_prehash(hash);
72 if let Ok(sig) = maybe_sig {
73 signature.copy_from_slice(&sig.to_bytes());
74 self.hash_storage.replace(hash);
75 self.signature_storage.replace(signature);
76 self.state.set(State::Signing);
77 self.deferred_call.set();
78 Ok(())
79 } else {
80 Err((kernel::ErrorCode::FAIL, hash, signature))
81 }
82 } else {
83 Err((kernel::ErrorCode::INVAL, hash, signature))
84 }
85 })
86 .unwrap()
87 } else {
88 Err((kernel::ErrorCode::FAIL, hash, signature))
89 }
90 }
91}
92
93impl<'a> hil::public_key_crypto::keys::SetKeyBySlice<'a, 64> for EcdsaP256SignatureSigner<'a> {
94 fn set_key(
95 &self,
96 key: &'static mut [u8; 64],
97 ) -> Result<(), (ErrorCode, &'static mut [u8; 64])> {
98 self.state.set(State::ChangingKey(key));
101 self.deferred_call.set();
102 Ok(())
103 }
104
105 fn set_client(&self, client: &'a dyn SetKeyBySliceClient<64>) {
106 self.client_key_set.replace(client);
107 }
108}
109
110impl kernel::deferred_call::DeferredCallClient for EcdsaP256SignatureSigner<'_> {
111 fn handle_deferred_call(&self) {
112 if let Some(s) = self.state.take() {
113 match s {
114 State::Signing => {
115 self.client.map(|client| {
116 if let Some(h) = self.hash_storage.take() {
117 if let Some(s) = self.signature_storage.take() {
118 client.signing_done(Ok(()), h, s);
119 }
120 }
121 });
122 }
123 State::ChangingKey(key) => {
124 self.signing_key.map(|skey| {
125 skey.copy_from_slice(key);
126 });
127
128 self.client_key_set.map(|client| {
129 client.set_key_done(key, Ok(()));
130 });
131 }
132 }
133 }
134 }
135
136 fn register(&'static self) {
137 self.deferred_call.register(self);
138 }
139}