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