tss_esapi/structures/
signatures.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    interface_types::algorithm::HashingAlgorithm,
5    structures::{EccParameter, PublicKeyRsa},
6    tss2_esys::{TPMS_SIGNATURE_ECC, TPMS_SIGNATURE_RSA},
7    Error, Result, WrapperErrorKind,
8};
9use log::error;
10use std::convert::{TryFrom, TryInto};
11
12/// Type holding RSA signature information.
13///
14/// For more information about the contents of `signature` see Annex B
15/// in the Architecture spec.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct RsaSignature {
18    hashing_algorithm: HashingAlgorithm,
19    signature: PublicKeyRsa,
20}
21
22impl RsaSignature {
23    /// Creates new RSA signature
24    ///
25    /// # Errors
26    /// Using [Null][`HashingAlgorithm::Null`] will cause an error.
27    pub fn create(hashing_algorithm: HashingAlgorithm, signature: PublicKeyRsa) -> Result<Self> {
28        if hashing_algorithm == HashingAlgorithm::Null {
29            error!("Hashing algorithm Null is not allowed in RsaSignature");
30            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
31        }
32        Ok(RsaSignature {
33            hashing_algorithm,
34            signature,
35        })
36    }
37
38    /// Returns the hashing algorithm
39    pub const fn hashing_algorithm(&self) -> HashingAlgorithm {
40        self.hashing_algorithm
41    }
42
43    /// Returns the signature
44    pub const fn signature(&self) -> &PublicKeyRsa {
45        &self.signature
46    }
47}
48
49impl From<RsaSignature> for TPMS_SIGNATURE_RSA {
50    fn from(rsa_signature: RsaSignature) -> Self {
51        TPMS_SIGNATURE_RSA {
52            hash: rsa_signature.hashing_algorithm.into(),
53            sig: rsa_signature.signature.into(),
54        }
55    }
56}
57
58impl TryFrom<TPMS_SIGNATURE_RSA> for RsaSignature {
59    type Error = Error;
60
61    fn try_from(tpms_signature_rsa: TPMS_SIGNATURE_RSA) -> Result<Self> {
62        let hashing_algorithm = tpms_signature_rsa.hash.try_into()?;
63        if hashing_algorithm == HashingAlgorithm::Null {
64            error!("Received invalid hashing algorithm Null from the tpm in the RSA signature.");
65            return Err(Error::local_error(WrapperErrorKind::WrongValueFromTpm));
66        }
67
68        Ok(RsaSignature {
69            hashing_algorithm,
70            signature: tpms_signature_rsa.sig.try_into()?,
71        })
72    }
73}
74
75/// Type holding ECC signature information.
76///
77/// For more information about the contents of `signature_r` and `signature_s`
78/// see Annex B in the Architecture spec (or Annex D for SM2 signatures).
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct EccSignature {
81    hashing_algorithm: HashingAlgorithm,
82    signature_r: EccParameter,
83    signature_s: EccParameter,
84}
85
86impl EccSignature {
87    /// Creates new ECC signature
88    pub fn create(
89        hashing_algorithm: HashingAlgorithm,
90        signature_r: EccParameter,
91        signature_s: EccParameter,
92    ) -> Result<Self> {
93        if hashing_algorithm == HashingAlgorithm::Null {
94            error!("Hashing algorithm Null is not allowed in RsaSignature");
95            return Err(Error::local_error(WrapperErrorKind::InvalidParam));
96        }
97        Ok(EccSignature {
98            hashing_algorithm,
99            signature_r,
100            signature_s,
101        })
102    }
103
104    /// Returns the hashing algorithm
105    pub const fn hashing_algorithm(&self) -> HashingAlgorithm {
106        self.hashing_algorithm
107    }
108
109    /// Returns signature r
110    pub const fn signature_r(&self) -> &EccParameter {
111        &self.signature_r
112    }
113
114    /// Returns signature s
115    pub const fn signature_s(&self) -> &EccParameter {
116        &self.signature_s
117    }
118}
119
120impl From<EccSignature> for TPMS_SIGNATURE_ECC {
121    fn from(ecc_signature: EccSignature) -> Self {
122        TPMS_SIGNATURE_ECC {
123            hash: ecc_signature.hashing_algorithm.into(),
124            signatureR: ecc_signature.signature_r.into(),
125            signatureS: ecc_signature.signature_s.into(),
126        }
127    }
128}
129
130impl TryFrom<TPMS_SIGNATURE_ECC> for EccSignature {
131    type Error = Error;
132
133    fn try_from(tpms_signature_ecc: TPMS_SIGNATURE_ECC) -> Result<Self> {
134        let hashing_algorithm = tpms_signature_ecc.hash.try_into()?;
135        if hashing_algorithm == HashingAlgorithm::Null {
136            error!("Received invalid hashing algorithm Null from the tpm in the ECC signature.");
137            return Err(Error::local_error(WrapperErrorKind::WrongValueFromTpm));
138        }
139        Ok(EccSignature {
140            hashing_algorithm,
141            signature_r: tpms_signature_ecc.signatureR.try_into()?,
142            signature_s: tpms_signature_ecc.signatureS.try_into()?,
143        })
144    }
145}