tss_esapi/structures/tagged/
signature.rs1use crate::{
4 interface_types::algorithm::SignatureSchemeAlgorithm,
5 structures::{EccSignature, HashAgile, RsaSignature},
6 traits::{Marshall, UnMarshall},
7 tss2_esys::{TPMT_SIGNATURE, TPMU_SIGNATURE},
8 Error, Result, WrapperErrorKind,
9};
10use log::error;
11use std::{
12 convert::{TryFrom, TryInto},
13 mem::size_of,
14};
15use tss_esapi_sys::{Tss2_MU_TPMT_SIGNATURE_Marshal, Tss2_MU_TPMT_SIGNATURE_Unmarshal};
16
17#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum Signature {
23 RsaSsa(RsaSignature),
24 RsaPss(RsaSignature),
25 EcDsa(EccSignature),
26 EcDaa(EccSignature),
27 Sm2(EccSignature),
28 EcSchnorr(EccSignature),
29 Hmac(HashAgile),
30 Null,
31}
32
33impl Signature {
34 pub fn algorithm(&self) -> SignatureSchemeAlgorithm {
35 match self {
36 Signature::RsaSsa(_) => SignatureSchemeAlgorithm::RsaSsa,
37 Signature::RsaPss(_) => SignatureSchemeAlgorithm::RsaPss,
38 Signature::EcDsa(_) => SignatureSchemeAlgorithm::EcDsa,
39 Signature::EcDaa(_) => SignatureSchemeAlgorithm::EcDaa,
40 Signature::Sm2(_) => SignatureSchemeAlgorithm::Sm2,
41 Signature::EcSchnorr(_) => SignatureSchemeAlgorithm::EcSchnorr,
42 Signature::Hmac(_) => SignatureSchemeAlgorithm::Hmac,
43 Signature::Null => SignatureSchemeAlgorithm::Null,
44 }
45 }
46}
47
48impl TryFrom<Signature> for TPMT_SIGNATURE {
49 type Error = Error;
50
51 fn try_from(signature: Signature) -> Result<Self> {
52 let signature_algorithm = signature.algorithm().into();
53 match signature {
54 Signature::RsaSsa(rsa_signature) => Ok(TPMT_SIGNATURE {
55 sigAlg: signature_algorithm,
56 signature: TPMU_SIGNATURE {
57 rsassa: rsa_signature.into(),
58 },
59 }),
60 Signature::RsaPss(rsa_signature) => Ok(TPMT_SIGNATURE {
61 sigAlg: signature_algorithm,
62 signature: TPMU_SIGNATURE {
63 rsapss: rsa_signature.into(),
64 },
65 }),
66 Signature::EcDsa(ecc_signature) => Ok(TPMT_SIGNATURE {
67 sigAlg: signature_algorithm,
68 signature: TPMU_SIGNATURE {
69 ecdsa: ecc_signature.into(),
70 },
71 }),
72 Signature::EcDaa(ecc_signature) => Ok(TPMT_SIGNATURE {
73 sigAlg: signature_algorithm,
74 signature: TPMU_SIGNATURE {
75 ecdaa: ecc_signature.into(),
76 },
77 }),
78 Signature::Sm2(ecc_signature) => Ok(TPMT_SIGNATURE {
79 sigAlg: signature_algorithm,
80 signature: TPMU_SIGNATURE {
81 sm2: ecc_signature.into(),
82 },
83 }),
84 Signature::EcSchnorr(ecc_signature) => Ok(TPMT_SIGNATURE {
85 sigAlg: signature_algorithm,
86 signature: TPMU_SIGNATURE {
87 ecschnorr: ecc_signature.into(),
88 },
89 }),
90 Signature::Hmac(hash_agile) => Ok(TPMT_SIGNATURE {
91 sigAlg: signature_algorithm,
92 signature: TPMU_SIGNATURE {
93 hmac: hash_agile.try_into()?,
94 },
95 }),
96 Signature::Null => Ok(TPMT_SIGNATURE {
97 sigAlg: signature_algorithm,
98 signature: Default::default(),
99 }),
100 }
101 }
102}
103
104impl TryFrom<TPMT_SIGNATURE> for Signature {
105 type Error = Error;
106
107 fn try_from(tpmt_signature: TPMT_SIGNATURE) -> Result<Self> {
108 match SignatureSchemeAlgorithm::try_from(tpmt_signature.sigAlg)? {
109 SignatureSchemeAlgorithm::RsaSsa => Ok(Signature::RsaSsa(
110 unsafe { tpmt_signature.signature.rsassa }.try_into()?,
111 )),
112 SignatureSchemeAlgorithm::RsaPss => Ok(Signature::RsaPss(
113 unsafe { tpmt_signature.signature.rsapss }.try_into()?,
114 )),
115 SignatureSchemeAlgorithm::EcDsa => Ok(Signature::EcDsa(
116 unsafe { tpmt_signature.signature.ecdsa }.try_into()?,
117 )),
118 SignatureSchemeAlgorithm::EcDaa => Ok(Signature::EcDaa(
119 unsafe { tpmt_signature.signature.ecdaa }.try_into()?,
120 )),
121 SignatureSchemeAlgorithm::Sm2 => Ok(Signature::Sm2(
122 unsafe { tpmt_signature.signature.sm2 }.try_into()?,
123 )),
124 SignatureSchemeAlgorithm::EcSchnorr => Ok(Signature::EcSchnorr(
125 unsafe { tpmt_signature.signature.ecschnorr }.try_into()?,
126 )),
127 SignatureSchemeAlgorithm::Hmac => Ok(Signature::Hmac(
128 unsafe { tpmt_signature.signature.hmac }.try_into()?,
129 )),
130 SignatureSchemeAlgorithm::Null => Ok(Signature::Null),
131 }
132 }
133}
134
135impl Marshall for Signature {
136 #[allow(unused_qualifications)]
137 const BUFFER_SIZE: usize = size_of::<TPMT_SIGNATURE>();
138
139 fn marshall(&self) -> Result<Vec<u8>> {
141 let tpmt_sig = TPMT_SIGNATURE::try_from(self.clone())?;
142 let mut offset = 0;
143 let mut buffer = vec![0; Self::BUFFER_SIZE];
144
145 let ret = unsafe {
146 Tss2_MU_TPMT_SIGNATURE_Marshal(
147 &tpmt_sig,
148 buffer.as_mut_ptr(),
149 buffer.capacity().try_into().map_err(|e| {
150 error!("Failed to convert size of buffer to TSS size_t type: {}", e);
151 Error::local_error(WrapperErrorKind::InvalidParam)
152 })?,
153 &mut offset,
154 )
155 };
156 let ret = Error::from_tss_rc(ret);
157 if ret.is_success() {
158 let checked_offset = usize::try_from(offset).map_err(|e| {
159 error!("Failed to parse offset as usize: {}", e);
160 Error::local_error(WrapperErrorKind::InvalidParam)
161 })?;
162
163 buffer.truncate(checked_offset);
164 Ok(buffer)
165 } else {
166 Err(ret)
167 }
168 }
169}
170
171impl UnMarshall for Signature {
172 fn unmarshall(public_buffer: &[u8]) -> Result<Self> {
174 let mut tpmt_sig = TPMT_SIGNATURE::default();
175 let mut offset = 0;
176
177 let ret = unsafe {
178 Tss2_MU_TPMT_SIGNATURE_Unmarshal(
179 public_buffer.as_ptr(),
180 public_buffer.len().try_into().map_err(|e| {
181 error!("Failed to convert length of marshalled data: {}", e);
182 Error::local_error(WrapperErrorKind::InvalidParam)
183 })?,
184 &mut offset,
185 &mut tpmt_sig,
186 )
187 };
188 let ret = Error::from_tss_rc(ret);
189 if ret.is_success() {
190 Ok(tpmt_sig.try_into()?)
191 } else {
192 Err(ret)
193 }
194 }
195}