twizzler_security/keys/
sig.rs

1use alloc::format;
2use core::fmt::Display;
3
4use heapless::Vec;
5#[cfg(feature = "log")]
6use log::error;
7use p256::ecdsa::Signature as EcdsaSignature;
8
9use crate::{SecurityError, SigningScheme};
10
11/// The maximum signature size supported by the security system.
12/// NOTE: can be increased while preserving backwards compatibility.
13const MAX_SIG_SIZE: usize = 128;
14
15#[derive(Clone, Debug, PartialEq, Eq)]
16/// Represents a Scheme agnostic Signature;
17pub struct Signature {
18    /// Buffer to store the bytes
19    buf: Vec<u8, MAX_SIG_SIZE>,
20    /// The scheme used to generate this signature
21    scheme: SigningScheme,
22}
23
24impl Signature {
25    fn as_bytes(&self) -> &[u8] {
26        self.buf.as_slice()
27    }
28}
29
30impl Display for Signature {
31    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32        write!(
33            f,
34            "Signature(scheme: {:?}, len: {}, bytes: ",
35            self.scheme,
36            self.buf.len()
37        )?;
38        for byte in self.buf.iter() {
39            write!(f, "{:02x}", byte)?;
40        }
41        write!(f, ")")
42    }
43}
44
45impl From<EcdsaSignature> for Signature {
46    fn from(value: EcdsaSignature) -> Self {
47        let mut buf = Vec::<u8, MAX_SIG_SIZE>::new();
48        let binding = value.to_bytes();
49        let slice = binding.as_slice();
50
51        buf.extend_from_slice(slice).expect(
52            format!("ECDSA signature longer than {MAX_SIG_SIZE}, invariant broken...").as_str(),
53        );
54
55        Self {
56            buf,
57            scheme: SigningScheme::Ecdsa,
58        }
59    }
60}
61
62impl TryFrom<&Signature> for EcdsaSignature {
63    type Error = SecurityError;
64    fn try_from(value: &Signature) -> Result<Self, Self::Error> {
65        if value.scheme != SigningScheme::Ecdsa {
66            #[cfg(feature = "log")]
67            error!("Cannot convert Signature to EcdsaSignature due to scheme mismatch. SigningScheme: {:?}", value.scheme);
68            return Err(SecurityError::InvalidScheme);
69        }
70
71        Ok(EcdsaSignature::from_slice(value.as_bytes()).map_err(|_e| {
72            #[cfg(feature = "log")]
73            error!("Failed to construct a EcdsaSignature due to: {:?}", _e);
74            SecurityError::SignatureMismatch
75        })?)
76    }
77}