Skip to main content

tss_esapi/context/tpm_commands/
signing_and_signature_verification.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    handles::KeyHandle,
5    structures::{Digest, HashcheckTicket, Signature, SignatureScheme, VerifiedTicket},
6    tss2_esys::{Esys_Sign, Esys_VerifySignature},
7    Context, Error, Result,
8};
9use log::error;
10use std::convert::{TryFrom, TryInto};
11use std::ptr::null_mut;
12
13impl Context {
14    /// Verify if a signature was generated by signing a given digest with a key in the TPM.
15    pub fn verify_signature(
16        &mut self,
17        key_handle: KeyHandle,
18        digest: Digest,
19        signature: Signature,
20    ) -> Result<VerifiedTicket> {
21        let mut validation_ptr = null_mut();
22        let ret = unsafe {
23            Esys_VerifySignature(
24                self.mut_context(),
25                key_handle.into(),
26                self.optional_session_1(),
27                self.optional_session_2(),
28                self.optional_session_3(),
29                &digest.into(),
30                &signature.try_into()?,
31                &mut validation_ptr,
32            )
33        };
34        let ret = Error::from_tss_rc(ret);
35
36        if ret.is_success() {
37            VerifiedTicket::try_from(Context::ffi_data_to_owned(validation_ptr))
38        } else {
39            error!("Error when verifying signature: {}", ret);
40            Err(ret)
41        }
42    }
43
44    /// Sign a digest with a key present in the TPM and return the signature.
45    pub fn sign(
46        &mut self,
47        key_handle: KeyHandle,
48        digest: Digest,
49        scheme: SignatureScheme,
50        validation: HashcheckTicket,
51    ) -> Result<Signature> {
52        let mut signature_ptr = null_mut();
53        let ret = unsafe {
54            Esys_Sign(
55                self.mut_context(),
56                key_handle.into(),
57                self.required_session_1()?,
58                self.optional_session_2(),
59                self.optional_session_3(),
60                &digest.into(),
61                &scheme.into(),
62                &validation.try_into()?,
63                &mut signature_ptr,
64            )
65        };
66        let ret = Error::from_tss_rc(ret);
67
68        if ret.is_success() {
69            Signature::try_from(Context::ffi_data_to_owned(signature_ptr))
70        } else {
71            error!("Error when signing: {}", ret);
72            Err(ret)
73        }
74    }
75}