• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! TPM command encoding/decoding library.
6 
7 use cxx::{let_cxx_string, UniquePtr};
8 use std::fmt::{self, Display, Formatter, Write};
9 use std::num::NonZeroU32;
10 
11 pub use trunks::*;
12 
13 #[allow(clippy::too_many_arguments)]
14 #[cxx::bridge(namespace = "trunks")]
15 pub mod trunks {
16     unsafe extern "C++" {
17         include!("authorization_delegate.h");
18 
19         type AuthorizationDelegate;
20 
21         include!("tpm_generated.h");
22 
23         type TPM2B_CREATION_DATA;
24         type TPM2B_DATA;
25         type TPM2B_DIGEST;
26         type TPM2B_PUBLIC;
27         type TPM2B_SENSITIVE_CREATE;
28         type TPMT_SIG_SCHEME;
29         type TPML_PCR_SELECTION;
30         type TPMT_TK_CREATION;
31 
32         include!("ffi.h");
33 
34         /// Encrypts data for an attestation CA. The CA's public key is passed
35         /// in as an input. The output values correspond to the EncryptedData
36         /// protobuf in attestation_ca.proto. Returns true on success and false
37         /// on failure.
EncryptDataForCa( data: &CxxString, public_key_hex: &CxxString, key_id: &CxxString, wrapped_key: Pin<&mut CxxString>, iv: Pin<&mut CxxString>, mac: Pin<&mut CxxString>, encrypted_data: Pin<&mut CxxString>, wrapping_key_id: Pin<&mut CxxString>, ) -> bool38         fn EncryptDataForCa(
39             data: &CxxString,
40             public_key_hex: &CxxString,
41             key_id: &CxxString,
42             wrapped_key: Pin<&mut CxxString>,
43             iv: Pin<&mut CxxString>,
44             mac: Pin<&mut CxxString>,
45             encrypted_data: Pin<&mut CxxString>,
46             wrapping_key_id: Pin<&mut CxxString>,
47         ) -> bool;
48 
49         /// Constructs a new PasswordAuthorizationDelegate with the given
50         /// password.
PasswordAuthorizationDelegate_New( password: &CxxString, ) -> UniquePtr<AuthorizationDelegate>51         fn PasswordAuthorizationDelegate_New(
52             password: &CxxString,
53         ) -> UniquePtr<AuthorizationDelegate>;
54 
55         /// See Tpm::SerializeCommand_Create for docs.
SerializeCommand_Create( parent_handle: &u32, parent_handle_name: &CxxString, in_sensitive: &TPM2B_SENSITIVE_CREATE, in_public: &TPM2B_PUBLIC, outside_info: &TPM2B_DATA, creation_pcr: &TPML_PCR_SELECTION, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u3256         fn SerializeCommand_Create(
57             parent_handle: &u32,
58             parent_handle_name: &CxxString,
59             in_sensitive: &TPM2B_SENSITIVE_CREATE,
60             in_public: &TPM2B_PUBLIC,
61             outside_info: &TPM2B_DATA,
62             creation_pcr: &TPML_PCR_SELECTION,
63             serialized_command: Pin<&mut CxxString>,
64             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
65         ) -> u32;
66 
67         /// See Tpm::ParseResponse_Create for docs.
ParseResponse_Create( response: &CxxString, out_private: Pin<&mut CxxString>, out_public: Pin<&mut CxxString>, creation_data: Pin<&mut TPM2B_CREATION_DATA>, creation_hash: Pin<&mut TPM2B_DIGEST>, creation_ticket: Pin<&mut TPMT_TK_CREATION>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u3268         fn ParseResponse_Create(
69             response: &CxxString,
70             out_private: Pin<&mut CxxString>,
71             out_public: Pin<&mut CxxString>,
72             creation_data: Pin<&mut TPM2B_CREATION_DATA>,
73             creation_hash: Pin<&mut TPM2B_DIGEST>,
74             creation_ticket: Pin<&mut TPMT_TK_CREATION>,
75             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
76         ) -> u32;
77 
78         /// See Tpm::SerializeCommand_CreatePrimary for docs.
SerializeCommand_CreatePrimary( primary_handle: &u32, primary_handle_name: &CxxString, in_sensitive: &TPM2B_SENSITIVE_CREATE, in_public: &TPM2B_PUBLIC, outside_info: &TPM2B_DATA, creation_pcr: &TPML_PCR_SELECTION, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u3279         fn SerializeCommand_CreatePrimary(
80             primary_handle: &u32,
81             primary_handle_name: &CxxString,
82             in_sensitive: &TPM2B_SENSITIVE_CREATE,
83             in_public: &TPM2B_PUBLIC,
84             outside_info: &TPM2B_DATA,
85             creation_pcr: &TPML_PCR_SELECTION,
86             serialized_command: Pin<&mut CxxString>,
87             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
88         ) -> u32;
89 
90         /// See Tpm::ParseResponse_CreatePrimary for docs.
ParseResponse_CreatePrimary( response: &CxxString, object_handle: Pin<&mut u32>, out_public: Pin<&mut TPM2B_PUBLIC>, creation_data: Pin<&mut TPM2B_CREATION_DATA>, creation_hash: Pin<&mut TPM2B_DIGEST>, creation_ticket: Pin<&mut TPMT_TK_CREATION>, name: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u3291         fn ParseResponse_CreatePrimary(
92             response: &CxxString,
93             object_handle: Pin<&mut u32>,
94             out_public: Pin<&mut TPM2B_PUBLIC>,
95             creation_data: Pin<&mut TPM2B_CREATION_DATA>,
96             creation_hash: Pin<&mut TPM2B_DIGEST>,
97             creation_ticket: Pin<&mut TPMT_TK_CREATION>,
98             name: Pin<&mut CxxString>,
99             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
100         ) -> u32;
101 
102         /// See Tpm::SerializeCommand_Load for docs.
SerializeCommand_Load( parent_handle: &u32, parent_handle_name: &CxxString, in_private: &CxxString, in_public: &CxxString, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32103         fn SerializeCommand_Load(
104             parent_handle: &u32,
105             parent_handle_name: &CxxString,
106             in_private: &CxxString,
107             in_public: &CxxString,
108             serialized_command: Pin<&mut CxxString>,
109             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
110         ) -> u32;
111 
112         /// See Tpm::ParseResponse_Load for docs.
ParseResponse_Load( response: &CxxString, object_handle: Pin<&mut u32>, name: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32113         fn ParseResponse_Load(
114             response: &CxxString,
115             object_handle: Pin<&mut u32>,
116             name: Pin<&mut CxxString>,
117             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
118         ) -> u32;
119 
120         /// See Tpm::SerializeCommand_NV_Certify for docs.
SerializeCommand_NV_Certify( sign_handle: &u32, sign_handle_name: &CxxString, auth_handle: &u32, auth_handle_name: &CxxString, nv_index: &u32, nv_index_name: &CxxString, qualifying_data: &TPM2B_DATA, in_scheme: &TPMT_SIG_SCHEME, size: &u16, offset: &u16, serialized_command: Pin<&mut CxxString>, ) -> u32121         fn SerializeCommand_NV_Certify(
122             sign_handle: &u32,
123             sign_handle_name: &CxxString,
124             auth_handle: &u32,
125             auth_handle_name: &CxxString,
126             nv_index: &u32,
127             nv_index_name: &CxxString,
128             qualifying_data: &TPM2B_DATA,
129             in_scheme: &TPMT_SIG_SCHEME,
130             size: &u16,
131             offset: &u16,
132             serialized_command: Pin<&mut CxxString>,
133         ) -> u32;
134 
135         /// See Tpm::ParseResponse_NV_Certify for docs.
ParseResponse_NV_Certify( response: &CxxString, certify_info: Pin<&mut CxxString>, signature: Pin<&mut CxxString>, ) -> u32136         fn ParseResponse_NV_Certify(
137             response: &CxxString,
138             certify_info: Pin<&mut CxxString>,
139             signature: Pin<&mut CxxString>,
140         ) -> u32;
141 
142         /// See Tpm::SerializeCommand_NV_Read for docs.
SerializeCommand_NV_Read( auth_handle: &u32, auth_handle_name: &CxxString, nv_index: &u32, nv_index_name: &CxxString, size: &u16, offset: &u16, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32143         fn SerializeCommand_NV_Read(
144             auth_handle: &u32,
145             auth_handle_name: &CxxString,
146             nv_index: &u32,
147             nv_index_name: &CxxString,
148             size: &u16,
149             offset: &u16,
150             serialized_command: Pin<&mut CxxString>,
151             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
152         ) -> u32;
153 
154         /// See Tpm::ParseResponse_NV_Read for docs.
ParseResponse_NV_Read( response: &CxxString, data: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32155         fn ParseResponse_NV_Read(
156             response: &CxxString,
157             data: Pin<&mut CxxString>,
158             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
159         ) -> u32;
160 
161         /// See Tpm::SerializeCommand_NV_ReadPublic for docs.
SerializeCommand_NV_ReadPublic( nv_index: &u32, nv_index_name: &CxxString, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32162         fn SerializeCommand_NV_ReadPublic(
163             nv_index: &u32,
164             nv_index_name: &CxxString,
165             serialized_command: Pin<&mut CxxString>,
166             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
167         ) -> u32;
168 
169         /// See Tpm::ParseResponse_NV_ReadPublic for docs.
ParseResponse_NV_ReadPublic( response: &CxxString, nv_public_data_size: &mut u16, nv_name: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32170         fn ParseResponse_NV_ReadPublic(
171             response: &CxxString,
172             nv_public_data_size: &mut u16,
173             nv_name: Pin<&mut CxxString>,
174             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
175         ) -> u32;
176 
177         /// See Tpm::SerializeCommand_Quote for docs.
SerializeCommand_Quote( sign_handle: &u32, sign_handle_name: &CxxString, qualifying_data: &TPM2B_DATA, in_scheme: &TPMT_SIG_SCHEME, pcrselect: &TPML_PCR_SELECTION, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32178         fn SerializeCommand_Quote(
179             sign_handle: &u32,
180             sign_handle_name: &CxxString,
181             qualifying_data: &TPM2B_DATA,
182             in_scheme: &TPMT_SIG_SCHEME,
183             pcrselect: &TPML_PCR_SELECTION,
184             serialized_command: Pin<&mut CxxString>,
185             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
186         ) -> u32;
187 
188         /// See Tpm::ParseResponse_Quote for docs.
ParseResponse_Quote( response: &CxxString, quoted: Pin<&mut CxxString>, signature: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32189         fn ParseResponse_Quote(
190             response: &CxxString,
191             quoted: Pin<&mut CxxString>,
192             signature: Pin<&mut CxxString>,
193             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
194         ) -> u32;
195 
196         /// See Tpm::SerializeCommand_PCR_Read for docs.
SerializeCommand_PCR_Read( pcr_selection_id: &TPML_PCR_SELECTION, serialized_command: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32197         fn SerializeCommand_PCR_Read(
198             pcr_selection_id: &TPML_PCR_SELECTION,
199             serialized_command: Pin<&mut CxxString>,
200             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
201         ) -> u32;
202 
203         /// See Tpm::ParseResponse_PCR_Read for docs.
ParseResponse_PCR_Read( response: &CxxString, pcr_update_counter: &mut u32, pcr_selection_out: Pin<&mut TPML_PCR_SELECTION>, pcr_values: Pin<&mut CxxString>, authorization_delegate: &UniquePtr<AuthorizationDelegate>, ) -> u32204         fn ParseResponse_PCR_Read(
205             response: &CxxString,
206             pcr_update_counter: &mut u32,
207             pcr_selection_out: Pin<&mut TPML_PCR_SELECTION>,
208             pcr_values: Pin<&mut CxxString>,
209             authorization_delegate: &UniquePtr<AuthorizationDelegate>,
210         ) -> u32;
211 
212         /// Returns a serialized representation of the unmodified handle. This
213         /// is useful for predefined handle values, like TPM_RH_OWNER. For
214         /// details on what types of handles use this name formula see Table 3
215         /// in the TPM 2.0 Library Spec Part 1 (Section 16 - Names).
NameFromHandle(handle: &u32) -> UniquePtr<CxxString>216         fn NameFromHandle(handle: &u32) -> UniquePtr<CxxString>;
217 
218         /// Creates a new empty TPM2B_CREATION_DATA.
TPM2B_CREATION_DATA_New() -> UniquePtr<TPM2B_CREATION_DATA>219         fn TPM2B_CREATION_DATA_New() -> UniquePtr<TPM2B_CREATION_DATA>;
220 
221         /// Creates a TPM2B_DATA with the given data.
TPM2B_DATA_New(bytes: &CxxString) -> UniquePtr<TPM2B_DATA>222         fn TPM2B_DATA_New(bytes: &CxxString) -> UniquePtr<TPM2B_DATA>;
223 
224         /// Creates a new empty TPM2B_DIGEST.
TPM2B_DIGEST_New() -> UniquePtr<TPM2B_DIGEST>225         fn TPM2B_DIGEST_New() -> UniquePtr<TPM2B_DIGEST>;
226 
227         /// Returns the public area template for the Attestation Identity Key.
AttestationIdentityKeyTemplate() -> UniquePtr<TPM2B_PUBLIC>228         fn AttestationIdentityKeyTemplate() -> UniquePtr<TPM2B_PUBLIC>;
229 
230         /// Returns the public area template for the Storage Root Key.
StorageRootKeyTemplate() -> UniquePtr<TPM2B_PUBLIC>231         fn StorageRootKeyTemplate() -> UniquePtr<TPM2B_PUBLIC>;
232 
233         /// Converts a serialized TPM2B_PUBLIC (as returned by
234         /// ParseResponse_Create) into a serialized TPMT_PUBLIC (as required by
235         /// the attestation CA).
Tpm2bPublicToTpmtPublic( tpm2b_public: &CxxString, tpmt_public: Pin<&mut CxxString>, ) -> u32236         fn Tpm2bPublicToTpmtPublic(
237             tpm2b_public: &CxxString,
238             tpmt_public: Pin<&mut CxxString>,
239         ) -> u32;
240 
241         /// Creates a new TPM2B_SENSITIVE_CREATE with the given auth and data
242         /// values.
TPM2B_SENSITIVE_CREATE_New( user_auth: &CxxString, data: &CxxString, ) -> UniquePtr<TPM2B_SENSITIVE_CREATE>243         fn TPM2B_SENSITIVE_CREATE_New(
244             user_auth: &CxxString,
245             data: &CxxString,
246         ) -> UniquePtr<TPM2B_SENSITIVE_CREATE>;
247 
248         /// Returns an empty PCR selection list.
EmptyPcrSelection() -> UniquePtr<TPML_PCR_SELECTION>249         fn EmptyPcrSelection() -> UniquePtr<TPML_PCR_SELECTION>;
250 
251         /// Returns a PCR selection list that selects a single PCR.
SinglePcrSelection(pcr: u8) -> UniquePtr<TPML_PCR_SELECTION>252         fn SinglePcrSelection(pcr: u8) -> UniquePtr<TPML_PCR_SELECTION>;
253 
254         /// Creates a TPMT_SIGN_SCHEME with hash algorithm SHA-256 and signature
255         /// algorithm ECDSA.
Sha256EcdsaSigScheme() -> UniquePtr<TPMT_SIG_SCHEME>256         fn Sha256EcdsaSigScheme() -> UniquePtr<TPMT_SIG_SCHEME>;
257 
258         /// Makes an empty TPMT_TK_CREATION;
TPMT_TK_CREATION_New() -> UniquePtr<TPMT_TK_CREATION>259         fn TPMT_TK_CREATION_New() -> UniquePtr<TPMT_TK_CREATION>;
260     }
261 }
262 
263 /// An error code returned by a Tpm method.
264 #[derive(Debug)]
265 pub struct TpmError {
266     return_code: NonZeroU32,
267 }
268 
269 impl TpmError {
270     /// Creates a TpmError for the given return code, or None if this is a
271     /// successful code.
from_tpm_return_code(return_code: u32) -> Option<TpmError>272     pub fn from_tpm_return_code(return_code: u32) -> Option<TpmError> {
273         Some(TpmError { return_code: NonZeroU32::new(return_code)? })
274     }
275 }
276 
277 impl Display for TpmError {
fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error>278     fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
279         write!(f, "{:#x}", self.return_code)
280     }
281 }
282 
283 /// Converts the given byte array into a hex string (intended for debug prints).
bytes_to_hex(bytes: &[u8]) -> String284 pub fn bytes_to_hex(bytes: &[u8]) -> String {
285     let expected_len = 2 * bytes.len();
286     let mut out = String::with_capacity(expected_len);
287     for b in bytes {
288         write!(out, "{:02x}", b).unwrap();
289     }
290     out
291 }
292