Skip to main content

trussed_rsa_types/
lib.rs

1// Copyright (C) Nitrokey GmbH
2// SPDX-License-Identifier: Apache-2.0 or MIT
3
4#![no_std]
5
6use heapless_bytes::Bytes;
7use serde::{Deserialize, Serialize};
8use trussed_core::types::SerializedKey;
9
10/// Error type
11#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
12#[non_exhaustive]
13pub enum ErrorKind {
14    /// Error occured during serialization
15    SerializeBufferFull,
16    /// Serialization failed. This indicates an internal error.
17    /// If encountered, please report
18    SerializeCustom,
19    /// The structure failed to deserialize
20    Deseralization,
21}
22
23/// Error during serialization.
24/// This means that the serialization failed, likely
25#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
26pub struct Error {
27    kind: ErrorKind,
28}
29
30pub(crate) fn postcard_serialize_bytes<T: serde::Serialize, const N: usize>(
31    object: &T,
32) -> postcard::Result<Bytes<N>> {
33    let mut vec = Bytes::new();
34    vec.resize_to_capacity();
35    let serialized = postcard::to_slice(object, &mut vec)?.len();
36    vec.resize(serialized, 0).unwrap();
37    Ok(vec)
38}
39
40/// Structure containing the public part of an RSA key
41///
42/// Given how Trussed extensions are implemented, this structure cannot be sent as-is to the backend,
43/// and is instead sent as a byte array.
44/// You can use [`serialize`](RsaPublicParts::serialize) and [`deserialize`](RsaPublicParts::deserialize) functions
45/// to convert to and from tha byte array format
46#[derive(Serialize, Deserialize)]
47pub struct RsaPublicParts<'d> {
48    /// big-endian integer representing the modulus of an RSA key
49    pub n: &'d [u8],
50    /// big-endian integer representing the public exponent of an RSA key
51    pub e: &'d [u8],
52}
53
54impl<'d> RsaPublicParts<'d> {
55    pub fn serialize(&self) -> Result<SerializedKey, Error> {
56        use postcard::Error as PError;
57        postcard_serialize_bytes(self).map_err(|err| match err {
58            PError::SerializeBufferFull => Error {
59                kind: ErrorKind::SerializeBufferFull,
60            },
61            _ => Error {
62                kind: ErrorKind::SerializeCustom,
63            },
64        })
65    }
66
67    pub fn deserialize(data: &'d [u8]) -> Result<Self, Error> {
68        postcard::from_bytes(data).map_err(|_err| Error {
69            kind: ErrorKind::Deseralization,
70        })
71    }
72}
73
74/// Format for private RSA key import
75///
76/// Given how Trussed extensions are implemented, this structure cannot be sent as-is to the backend,
77/// and is instead sent as a byte array.
78/// You can use [`serialize`](RsaImportFormat::serialize) and [`deserialize`](RsaImportFormat::deserialize) functions
79/// to convert to and from tha byte array format
80#[derive(Debug, Deserialize, Serialize)]
81pub struct RsaImportFormat<'d> {
82    /// big-endian integer representing the exponent of the public part of the RSA key
83    pub e: &'d [u8],
84    /// big-endian integer representing the first prime of a private RSA key
85    pub p: &'d [u8],
86    /// big-endian integer representing the second prime of a private RSA key
87    pub q: &'d [u8],
88}
89
90impl<'d> RsaImportFormat<'d> {
91    pub fn serialize(&self) -> Result<SerializedKey, Error> {
92        use postcard::Error as PError;
93        postcard_serialize_bytes(self).map_err(|err| match err {
94            PError::SerializeBufferFull => Error {
95                kind: ErrorKind::SerializeBufferFull,
96            },
97            _ => Error {
98                kind: ErrorKind::SerializeCustom,
99            },
100        })
101    }
102
103    pub fn deserialize(data: &'d [u8]) -> Result<Self, Error> {
104        postcard::from_bytes(data).map_err(|_err| Error {
105            kind: ErrorKind::Deseralization,
106        })
107    }
108}