capsules_extra/public_key_crypto/
rsa_keys.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Helper library for RSA public and private keys
6
7use core::cell::Cell;
8use kernel::hil::public_key_crypto::keys::{
9    PubKey, PubKeyMut, PubPrivKey, PubPrivKeyMut, RsaKey, RsaKeyMut, RsaPrivKey, RsaPrivKeyMut,
10};
11use kernel::utilities::cells::OptionalCell;
12use kernel::utilities::mut_imut_buffer::MutImutBuffer;
13use kernel::ErrorCode;
14
15// Copy OpenSSL and use e as 65537
16const PUBLIC_EXPONENT: u32 = 65537;
17
18/// A Public/Private RSA key pair
19/// The key is `L` bytes long
20struct RSAKeys<const L: usize> {
21    public_key: OptionalCell<MutImutBuffer<'static, u8>>,
22    public_exponent: Cell<u32>,
23    private_key: OptionalCell<MutImutBuffer<'static, u8>>,
24}
25
26impl<const L: usize> RSAKeys<L> {
27    const fn new() -> Self {
28        Self {
29            public_key: OptionalCell::empty(),
30            public_exponent: Cell::new(PUBLIC_EXPONENT),
31            private_key: OptionalCell::empty(),
32        }
33    }
34
35    /// `public_key` is a buffer containing the public key.
36    /// This is the `L` byte modulus (also called `n`).
37    fn import_public_key(
38        &self,
39        public_key: MutImutBuffer<'static, u8>,
40    ) -> Result<(), (ErrorCode, MutImutBuffer<'static, u8>)> {
41        if public_key.len() != L {
42            return Err((ErrorCode::SIZE, public_key));
43        }
44
45        self.public_key.replace(public_key);
46
47        Ok(())
48    }
49
50    fn pub_key(&self) -> Result<MutImutBuffer<'static, u8>, ErrorCode> {
51        if self.public_key.is_some() {
52            Ok(self.public_key.take().unwrap())
53        } else {
54            Err(ErrorCode::NODEVICE)
55        }
56    }
57
58    fn import_private_key(
59        &self,
60        private_key: MutImutBuffer<'static, u8>,
61    ) -> Result<(), (ErrorCode, MutImutBuffer<'static, u8>)> {
62        if private_key.len() != L {
63            return Err((ErrorCode::SIZE, private_key));
64        }
65
66        self.private_key.replace(private_key);
67
68        Ok(())
69    }
70
71    fn priv_key(&self) -> Result<MutImutBuffer<'static, u8>, ErrorCode> {
72        if self.private_key.is_some() {
73            Ok(self.private_key.take().unwrap())
74        } else {
75            Err(ErrorCode::NODEVICE)
76        }
77    }
78}
79
80impl<const L: usize> PubKey for RSAKeys<L> {
81    /// `public_key` is a buffer containing the public key.
82    /// This is the `L` byte modulus (also called `n`).
83    fn import_public_key(
84        &self,
85        public_key: &'static [u8],
86    ) -> Result<(), (ErrorCode, &'static [u8])> {
87        if public_key.len() != L {
88            return Err((ErrorCode::SIZE, public_key));
89        }
90
91        self.public_key
92            .replace(MutImutBuffer::Immutable(public_key));
93
94        Ok(())
95    }
96
97    fn pub_key(&self) -> Result<&'static [u8], kernel::ErrorCode> {
98        if self.public_key.is_some() {
99            match self.public_key.take().unwrap() {
100                MutImutBuffer::Immutable(ret) => Ok(ret),
101                MutImutBuffer::Mutable(_ret) => unreachable!(),
102            }
103        } else {
104            Err(ErrorCode::NODEVICE)
105        }
106    }
107
108    fn len(&self) -> usize {
109        if let Some(key) = self.public_key.take() {
110            let ret = key.len();
111            self.public_key.set(key);
112            ret
113        } else {
114            0
115        }
116    }
117}
118
119impl<const L: usize> PubKeyMut for RSAKeys<L> {
120    /// `public_key` is a buffer containing the public key.
121    /// This is the `L` byte modulus (also called `n`).
122    fn import_public_key(
123        &self,
124        public_key: &'static mut [u8],
125    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
126        if public_key.len() != L {
127            return Err((ErrorCode::SIZE, public_key));
128        }
129
130        self.public_key.replace(MutImutBuffer::Mutable(public_key));
131
132        Ok(())
133    }
134
135    fn pub_key(&self) -> Result<&'static mut [u8], kernel::ErrorCode> {
136        if self.public_key.is_some() {
137            match self.public_key.take().unwrap() {
138                MutImutBuffer::Mutable(ret) => Ok(ret),
139                MutImutBuffer::Immutable(_ret) => unreachable!(),
140            }
141        } else {
142            Err(ErrorCode::NODEVICE)
143        }
144    }
145
146    fn len(&self) -> usize {
147        if let Some(key) = self.public_key.take() {
148            let ret = key.len();
149            self.public_key.set(key);
150            ret
151        } else {
152            0
153        }
154    }
155}
156
157impl<const L: usize> PubPrivKey for RSAKeys<L> {
158    /// `private_key` is a buffer containing the private key.
159    /// The first `L` bytes are the private_exponent (also called `d`).
160    fn import_private_key(
161        &self,
162        private_key: &'static [u8],
163    ) -> Result<(), (ErrorCode, &'static [u8])> {
164        if private_key.len() != L {
165            return Err((ErrorCode::SIZE, private_key));
166        }
167
168        self.private_key
169            .replace(MutImutBuffer::Immutable(private_key));
170
171        Ok(())
172    }
173
174    fn priv_key(&self) -> Result<&'static [u8], ErrorCode> {
175        if self.private_key.is_some() {
176            match self.private_key.take().unwrap() {
177                MutImutBuffer::Immutable(ret) => Ok(ret),
178                MutImutBuffer::Mutable(_ret) => unreachable!(),
179            }
180        } else {
181            Err(ErrorCode::NODEVICE)
182        }
183    }
184
185    fn len(&self) -> usize {
186        if let Some(key) = self.private_key.take() {
187            let ret = key.len();
188            self.private_key.set(key);
189            ret
190        } else {
191            0
192        }
193    }
194}
195
196impl<const L: usize> PubPrivKeyMut for RSAKeys<L> {
197    /// `private_key` is a buffer containing the private key.
198    /// The first `L` bytes are the private_exponent (also called `d`).
199    fn import_private_key(
200        &self,
201        private_key: &'static mut [u8],
202    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
203        if private_key.len() != L {
204            return Err((ErrorCode::SIZE, private_key));
205        }
206
207        self.private_key
208            .replace(MutImutBuffer::Mutable(private_key));
209
210        Ok(())
211    }
212
213    fn priv_key(&self) -> Result<&'static mut [u8], ErrorCode> {
214        if self.private_key.is_some() {
215            match self.private_key.take().unwrap() {
216                MutImutBuffer::Mutable(ret) => Ok(ret),
217                MutImutBuffer::Immutable(_ret) => unreachable!(),
218            }
219        } else {
220            Err(ErrorCode::NODEVICE)
221        }
222    }
223
224    fn len(&self) -> usize {
225        if let Some(key) = self.private_key.take() {
226            let ret = key.len();
227            self.private_key.set(key);
228            ret
229        } else {
230            0
231        }
232    }
233}
234
235impl<const L: usize> RsaKey for RSAKeys<L> {
236    fn map_modulus(&self, closure: &dyn Fn(&[u8])) -> Option<()> {
237        if let Some(public_key) = self.public_key.take() {
238            match public_key {
239                MutImutBuffer::Mutable(ref _buf) => unreachable!(),
240                MutImutBuffer::Immutable(buf) => {
241                    closure(buf);
242                }
243            }
244            self.public_key.replace(public_key);
245            Some(())
246        } else {
247            None
248        }
249    }
250
251    fn take_modulus(&self) -> Option<&'static [u8]> {
252        if let Some(public_key) = self.public_key.take() {
253            match public_key {
254                MutImutBuffer::Immutable(ret) => Some(ret),
255                MutImutBuffer::Mutable(_ret) => unreachable!(),
256            }
257        } else {
258            None
259        }
260    }
261
262    fn public_exponent(&self) -> Option<u32> {
263        Some(self.public_exponent.get())
264    }
265}
266
267impl<const L: usize> RsaKeyMut for RSAKeys<L> {
268    fn map_modulus(&self, closure: &dyn Fn(&mut [u8])) -> Option<()> {
269        if let Some(mut public_key) = self.public_key.take() {
270            match public_key {
271                MutImutBuffer::Mutable(ref mut buf) => {
272                    closure(buf);
273                }
274                MutImutBuffer::Immutable(_buf) => unreachable!(),
275            }
276            self.public_key.replace(public_key);
277            Some(())
278        } else {
279            None
280        }
281    }
282
283    fn take_modulus(&self) -> Option<&'static mut [u8]> {
284        if let Some(public_key) = self.public_key.take() {
285            match public_key {
286                MutImutBuffer::Mutable(ret) => Some(ret),
287                MutImutBuffer::Immutable(_ret) => unreachable!(),
288            }
289        } else {
290            None
291        }
292    }
293
294    fn public_exponent(&self) -> Option<u32> {
295        Some(self.public_exponent.get())
296    }
297}
298
299impl<const L: usize> RsaPrivKey for RSAKeys<L> {
300    fn map_exponent(&self, closure: &dyn Fn(&[u8])) -> Option<()> {
301        if let Some(private_key) = self.private_key.take() {
302            match private_key {
303                MutImutBuffer::Mutable(ref _buf) => unreachable!(),
304                MutImutBuffer::Immutable(buf) => closure(buf),
305            }
306            self.private_key.replace(private_key);
307            Some(())
308        } else {
309            None
310        }
311    }
312
313    fn take_exponent(&self) -> Option<&'static [u8]> {
314        if let Some(private_key) = self.private_key.take() {
315            match private_key {
316                MutImutBuffer::Immutable(ret) => Some(ret),
317                MutImutBuffer::Mutable(_ret) => unreachable!(),
318            }
319        } else {
320            None
321        }
322    }
323}
324
325impl<const L: usize> RsaPrivKeyMut for RSAKeys<L> {
326    fn map_exponent(&self, closure: &dyn Fn(&mut [u8])) -> Option<()> {
327        if let Some(mut private_key) = self.private_key.take() {
328            match private_key {
329                MutImutBuffer::Mutable(ref mut buf) => closure(buf),
330                MutImutBuffer::Immutable(_buf) => unreachable!(),
331            }
332            self.private_key.replace(private_key);
333            Some(())
334        } else {
335            None
336        }
337    }
338
339    fn take_exponent(&self) -> Option<&'static mut [u8]> {
340        if let Some(private_key) = self.private_key.take() {
341            match private_key {
342                MutImutBuffer::Mutable(ret) => Some(ret),
343                MutImutBuffer::Immutable(_ret) => unreachable!(),
344            }
345        } else {
346            None
347        }
348    }
349}
350
351pub struct RSA2048Keys(RSAKeys<256>);
352
353impl RSA2048Keys {
354    pub const fn new() -> RSA2048Keys {
355        RSA2048Keys(RSAKeys::<256>::new())
356    }
357}
358
359impl PubKey for RSA2048Keys {
360    fn import_public_key(
361        &self,
362        public_key: &'static [u8],
363    ) -> Result<(), (kernel::ErrorCode, &'static [u8])> {
364        let key = self
365            .0
366            .import_public_key(MutImutBuffer::Immutable(public_key));
367
368        match key {
369            Err((e, buf)) => match buf {
370                MutImutBuffer::Immutable(ret) => Err((e, ret)),
371                MutImutBuffer::Mutable(_ret) => unreachable!(),
372            },
373            Ok(()) => Ok(()),
374        }
375    }
376
377    fn pub_key(&self) -> Result<&'static [u8], kernel::ErrorCode> {
378        match self.0.pub_key() {
379            Ok(buf) => match buf {
380                MutImutBuffer::Immutable(ret) => Ok(ret),
381                MutImutBuffer::Mutable(_ret) => unreachable!(),
382            },
383            Err(e) => Err(e),
384        }
385    }
386
387    fn len(&self) -> usize {
388        PubKey::len(&self.0)
389    }
390}
391
392impl PubPrivKey for RSA2048Keys {
393    fn import_private_key(
394        &self,
395        private_key: &'static [u8],
396    ) -> Result<(), (kernel::ErrorCode, &'static [u8])> {
397        let key = self
398            .0
399            .import_private_key(MutImutBuffer::Immutable(private_key));
400
401        match key {
402            Err((e, buf)) => match buf {
403                MutImutBuffer::Immutable(ret) => Err((e, ret)),
404                MutImutBuffer::Mutable(_ret) => unreachable!(),
405            },
406            Ok(()) => Ok(()),
407        }
408    }
409
410    fn priv_key(&self) -> Result<&'static [u8], kernel::ErrorCode> {
411        match self.0.priv_key() {
412            Ok(buf) => match buf {
413                MutImutBuffer::Immutable(ret) => Ok(ret),
414                MutImutBuffer::Mutable(_ret) => unreachable!(),
415            },
416            Err(e) => Err(e),
417        }
418    }
419
420    fn len(&self) -> usize {
421        PubPrivKey::len(&self.0)
422    }
423}
424
425impl RsaKey for RSA2048Keys {
426    fn map_modulus(&self, closure: &dyn Fn(&[u8])) -> Option<()> {
427        RsaKey::map_modulus(&self.0, closure)
428    }
429
430    fn take_modulus(&self) -> Option<&'static [u8]> {
431        RsaKey::take_modulus(&self.0)
432    }
433
434    fn public_exponent(&self) -> Option<u32> {
435        RsaKey::public_exponent(&self.0)
436    }
437}
438
439impl RsaPrivKey for RSA2048Keys {
440    fn map_exponent(&self, closure: &dyn Fn(&[u8])) -> Option<()> {
441        RsaPrivKey::map_exponent(&self.0, closure)
442    }
443
444    fn take_exponent(&self) -> Option<&'static [u8]> {
445        RsaPrivKey::take_exponent(&self.0)
446    }
447}
448
449pub struct RSA2048KeysMut(RSAKeys<256>);
450
451impl RSA2048KeysMut {
452    pub const fn new() -> RSA2048KeysMut {
453        RSA2048KeysMut(RSAKeys::<256>::new())
454    }
455}
456
457impl PubKeyMut for RSA2048KeysMut {
458    fn import_public_key(
459        &self,
460        public_key: &'static mut [u8],
461    ) -> Result<(), (kernel::ErrorCode, &'static mut [u8])> {
462        let key = self.0.import_public_key(MutImutBuffer::Mutable(public_key));
463
464        match key {
465            Err((e, buf)) => match buf {
466                MutImutBuffer::Mutable(ret) => Err((e, ret)),
467                MutImutBuffer::Immutable(_ret) => unreachable!(),
468            },
469            Ok(()) => Ok(()),
470        }
471    }
472
473    fn pub_key(&self) -> Result<&'static mut [u8], kernel::ErrorCode> {
474        match self.0.pub_key() {
475            Ok(buf) => match buf {
476                MutImutBuffer::Mutable(ret) => Ok(ret),
477                MutImutBuffer::Immutable(_ret) => unreachable!(),
478            },
479            Err(e) => Err(e),
480        }
481    }
482
483    fn len(&self) -> usize {
484        PubKey::len(&self.0)
485    }
486}
487
488impl PubPrivKeyMut for RSA2048KeysMut {
489    fn import_private_key(
490        &self,
491        private_key: &'static mut [u8],
492    ) -> Result<(), (kernel::ErrorCode, &'static mut [u8])> {
493        let key = self
494            .0
495            .import_private_key(MutImutBuffer::Mutable(private_key));
496
497        match key {
498            Err((e, buf)) => match buf {
499                MutImutBuffer::Mutable(ret) => Err((e, ret)),
500                MutImutBuffer::Immutable(_ret) => unreachable!(),
501            },
502            Ok(()) => Ok(()),
503        }
504    }
505
506    fn priv_key(&self) -> Result<&'static mut [u8], kernel::ErrorCode> {
507        match self.0.priv_key() {
508            Ok(buf) => match buf {
509                MutImutBuffer::Mutable(ret) => Ok(ret),
510                MutImutBuffer::Immutable(_ret) => unreachable!(),
511            },
512            Err(e) => Err(e),
513        }
514    }
515
516    fn len(&self) -> usize {
517        PubPrivKey::len(&self.0)
518    }
519}
520
521impl RsaKeyMut for RSA2048KeysMut {
522    fn map_modulus(&self, closure: &dyn Fn(&mut [u8])) -> Option<()> {
523        RsaKeyMut::map_modulus(&self.0, closure)
524    }
525
526    fn take_modulus(&self) -> Option<&'static mut [u8]> {
527        RsaKeyMut::take_modulus(&self.0)
528    }
529
530    fn public_exponent(&self) -> Option<u32> {
531        RsaKeyMut::public_exponent(&self.0)
532    }
533}
534
535impl RsaPrivKeyMut for RSA2048KeysMut {
536    fn map_exponent(&self, closure: &dyn Fn(&mut [u8])) -> Option<()> {
537        RsaPrivKeyMut::map_exponent(&self.0, closure)
538    }
539
540    fn take_exponent(&self) -> Option<&'static mut [u8]> {
541        RsaPrivKeyMut::take_exponent(&self.0)
542    }
543}
544
545pub struct RSA4096Keys(RSAKeys<512>);
546
547impl RSA4096Keys {
548    pub const fn new() -> RSA4096Keys {
549        RSA4096Keys(RSAKeys::<512>::new())
550    }
551}
552
553impl PubKey for RSA4096Keys {
554    fn import_public_key(
555        &self,
556        public_key: &'static [u8],
557    ) -> Result<(), (kernel::ErrorCode, &'static [u8])> {
558        let key = self
559            .0
560            .import_public_key(MutImutBuffer::Immutable(public_key));
561
562        match key {
563            Err((e, buf)) => match buf {
564                MutImutBuffer::Immutable(ret) => Err((e, ret)),
565                MutImutBuffer::Mutable(_ret) => unreachable!(),
566            },
567            Ok(()) => Ok(()),
568        }
569    }
570
571    fn pub_key(&self) -> Result<&'static [u8], kernel::ErrorCode> {
572        match self.0.pub_key() {
573            Ok(buf) => match buf {
574                MutImutBuffer::Immutable(ret) => Ok(ret),
575                MutImutBuffer::Mutable(_ret) => unreachable!(),
576            },
577            Err(e) => Err(e),
578        }
579    }
580
581    fn len(&self) -> usize {
582        PubKey::len(&self.0)
583    }
584}
585
586impl PubPrivKey for RSA4096Keys {
587    fn import_private_key(
588        &self,
589        private_key: &'static [u8],
590    ) -> Result<(), (kernel::ErrorCode, &'static [u8])> {
591        let key = self
592            .0
593            .import_private_key(MutImutBuffer::Immutable(private_key));
594
595        match key {
596            Err((e, buf)) => match buf {
597                MutImutBuffer::Immutable(ret) => Err((e, ret)),
598                MutImutBuffer::Mutable(_ret) => unreachable!(),
599            },
600            Ok(()) => Ok(()),
601        }
602    }
603
604    fn priv_key(&self) -> Result<&'static [u8], kernel::ErrorCode> {
605        match self.0.priv_key() {
606            Ok(buf) => match buf {
607                MutImutBuffer::Immutable(ret) => Ok(ret),
608                MutImutBuffer::Mutable(_ret) => unreachable!(),
609            },
610            Err(e) => Err(e),
611        }
612    }
613
614    fn len(&self) -> usize {
615        PubPrivKey::len(&self.0)
616    }
617}
618
619impl RsaKey for RSA4096Keys {
620    fn map_modulus(&self, closure: &dyn Fn(&[u8])) -> Option<()> {
621        RsaKey::map_modulus(&self.0, closure)
622    }
623
624    fn take_modulus(&self) -> Option<&'static [u8]> {
625        RsaKey::take_modulus(&self.0)
626    }
627
628    fn public_exponent(&self) -> Option<u32> {
629        RsaKey::public_exponent(&self.0)
630    }
631}
632
633impl RsaPrivKey for RSA4096Keys {
634    fn map_exponent(&self, closure: &dyn Fn(&[u8])) -> Option<()> {
635        RsaPrivKey::map_exponent(&self.0, closure)
636    }
637
638    fn take_exponent(&self) -> Option<&'static [u8]> {
639        RsaPrivKey::take_exponent(&self.0)
640    }
641}
642
643pub struct RSA4096KeysMut(RSAKeys<512>);
644
645impl RSA4096KeysMut {
646    pub const fn new() -> RSA4096KeysMut {
647        RSA4096KeysMut(RSAKeys::<512>::new())
648    }
649}
650
651impl PubKeyMut for RSA4096KeysMut {
652    fn import_public_key(
653        &self,
654        public_key: &'static mut [u8],
655    ) -> Result<(), (kernel::ErrorCode, &'static mut [u8])> {
656        let key = self.0.import_public_key(MutImutBuffer::Mutable(public_key));
657
658        match key {
659            Err((e, buf)) => match buf {
660                MutImutBuffer::Mutable(ret) => Err((e, ret)),
661                MutImutBuffer::Immutable(_ret) => unreachable!(),
662            },
663            Ok(()) => Ok(()),
664        }
665    }
666
667    fn pub_key(&self) -> Result<&'static mut [u8], kernel::ErrorCode> {
668        match self.0.pub_key() {
669            Ok(buf) => match buf {
670                MutImutBuffer::Mutable(ret) => Ok(ret),
671                MutImutBuffer::Immutable(_ret) => unreachable!(),
672            },
673            Err(e) => Err(e),
674        }
675    }
676
677    fn len(&self) -> usize {
678        PubKey::len(&self.0)
679    }
680}
681
682impl PubPrivKeyMut for RSA4096KeysMut {
683    fn import_private_key(
684        &self,
685        private_key: &'static mut [u8],
686    ) -> Result<(), (kernel::ErrorCode, &'static mut [u8])> {
687        let key = self
688            .0
689            .import_private_key(MutImutBuffer::Mutable(private_key));
690
691        match key {
692            Err((e, buf)) => match buf {
693                MutImutBuffer::Mutable(ret) => Err((e, ret)),
694                MutImutBuffer::Immutable(_ret) => unreachable!(),
695            },
696            Ok(()) => Ok(()),
697        }
698    }
699
700    fn priv_key(&self) -> Result<&'static mut [u8], kernel::ErrorCode> {
701        match self.0.priv_key() {
702            Ok(buf) => match buf {
703                MutImutBuffer::Mutable(ret) => Ok(ret),
704                MutImutBuffer::Immutable(_ret) => unreachable!(),
705            },
706            Err(e) => Err(e),
707        }
708    }
709
710    fn len(&self) -> usize {
711        PubPrivKey::len(&self.0)
712    }
713}
714
715impl RsaKeyMut for RSA4096KeysMut {
716    fn map_modulus(&self, closure: &dyn Fn(&mut [u8])) -> Option<()> {
717        RsaKeyMut::map_modulus(&self.0, closure)
718    }
719
720    fn take_modulus(&self) -> Option<&'static mut [u8]> {
721        RsaKeyMut::take_modulus(&self.0)
722    }
723
724    fn public_exponent(&self) -> Option<u32> {
725        RsaKeyMut::public_exponent(&self.0)
726    }
727}
728
729impl RsaPrivKeyMut for RSA4096KeysMut {
730    fn map_exponent(&self, closure: &dyn Fn(&mut [u8])) -> Option<()> {
731        RsaPrivKeyMut::map_exponent(&self.0, closure)
732    }
733
734    fn take_exponent(&self) -> Option<&'static mut [u8]> {
735        RsaPrivKeyMut::take_exponent(&self.0)
736    }
737}