Skip to content

Commit 65258c9

Browse files
committed
Fixes issue wrong max size in some sized buffer types.
Some of the sized buffers had their buffer sizes set as numbers. Even though this in some cases were the correct numbers they were a little hard to determine if they actually followed the size specified in the standard. So this PR fixes #548 in the main branch by using the the calculations specified in the standard for the buffer sizes. Signed-off-by: Jesper Brynolf <[email protected]>
1 parent 97ccc11 commit 65258c9

File tree

13 files changed

+362
-200
lines changed

13 files changed

+362
-200
lines changed

tss-esapi/src/structures/buffers.rs

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,30 @@ pub mod sensitive;
103103
pub mod sensitive_create;
104104

105105
pub mod auth {
106-
buffer_type!(Auth, 64, TPM2B_AUTH);
106+
// Same size as TPM2B_DIGEST according to the specification.
107+
use crate::tss2_esys::TPMU_HA;
108+
use std::mem::size_of;
109+
const TPM2B_AUTH_BUFFER_SIZE: usize = size_of::<TPMU_HA>();
110+
buffer_type!(Auth, TPM2B_AUTH_BUFFER_SIZE, TPM2B_AUTH);
107111
}
108112

109113
pub mod data {
110-
buffer_type!(Data, 64, TPM2B_DATA);
114+
// This should, according to the specification, be
115+
// size_of::<TPMT_HA>() but due to a bug in tpm2-tss
116+
// (https://github.com/tpm2-software/tpm2-tss/issues/2888)
117+
// it is the size of TPMU_HA
118+
use crate::tss2_esys::TPMU_HA;
119+
use std::mem::size_of;
120+
const TPM2B_DATA_BUFFER_SIZE: usize = size_of::<TPMU_HA>();
121+
buffer_type!(Data, TPM2B_DATA_BUFFER_SIZE, TPM2B_DATA);
111122
}
112123

113124
pub mod digest {
114-
buffer_type!(Digest, 64, TPM2B_DIGEST);
125+
use crate::tss2_esys::TPMU_HA;
126+
use std::mem::size_of;
127+
const TPM2B_DIGEST_BUFFER_SIZE: usize = size_of::<TPMU_HA>();
128+
129+
buffer_type!(Digest, TPM2B_DIGEST_BUFFER_SIZE, TPM2B_DIGEST);
115130

116131
// Some implementations to get from Digest to [u8; N] for common values of N (sha* primarily)
117132
// This is used to work around the fact that Rust does not allow custom functions for general values of N in [T; N],
@@ -216,11 +231,27 @@ pub mod ecc_parameter {
216231
}
217232

218233
pub mod encrypted_secret {
219-
named_field_buffer_type!(EncryptedSecret, 256, TPM2B_ENCRYPTED_SECRET, secret);
234+
use crate::tss2_esys::TPMU_ENCRYPTED_SECRET;
235+
use std::mem::size_of;
236+
const TPMU_ENCRYPTED_SECRET_MEM_SIZE: usize = size_of::<TPMU_ENCRYPTED_SECRET>();
237+
named_field_buffer_type!(
238+
EncryptedSecret,
239+
TPMU_ENCRYPTED_SECRET_MEM_SIZE,
240+
TPM2B_ENCRYPTED_SECRET,
241+
secret
242+
);
220243
}
221244

222245
pub mod id_object {
223-
named_field_buffer_type!(IdObject, 256, TPM2B_ID_OBJECT, credential);
246+
use crate::tss2_esys::TPMS_ID_OBJECT;
247+
use std::mem::size_of;
248+
const TPMS_ID_OBJECT_MEM_SIZE: usize = size_of::<TPMS_ID_OBJECT>();
249+
named_field_buffer_type!(
250+
IdObject,
251+
TPMS_ID_OBJECT_MEM_SIZE,
252+
TPM2B_ID_OBJECT,
253+
credential
254+
);
224255
}
225256

226257
pub mod initial_value {
@@ -246,42 +277,45 @@ pub mod max_nv_buffer {
246277
}
247278

248279
pub mod nonce {
249-
buffer_type!(Nonce, 64, TPM2B_NONCE);
280+
// Same size as TPM2B_DIGEST according to the specification.
281+
use crate::tss2_esys::TPMU_HA;
282+
use std::mem::size_of;
283+
const TPM2B_NONCE_BUFFER_SIZE: usize = size_of::<TPMU_HA>();
284+
285+
buffer_type!(Nonce, TPM2B_NONCE_BUFFER_SIZE, TPM2B_NONCE);
250286
}
251287

252288
pub mod private_key_rsa {
253289
use crate::tss2_esys::TPM2_MAX_RSA_KEY_BYTES;
290+
const TPM2B_PRIVATE_KEY_RSA_BUFFER_SIZE: usize = (TPM2_MAX_RSA_KEY_BYTES as usize) * 5 / 2;
254291

255-
// The maximum size is given in the spec as:
256-
// "RSA_PRIVATE_SIZE is a vendor specific value that can be (MAX_RSA_KEY_BYTES / 2) or
257-
// ((MAX_RSA_KEY_BYTES * 5) ./ 2. The larger size would only apply to keys that have fixedTPM parents.
258-
// The larger size was added in revision 01.53."
259-
// The TSS stack we use only accepts the smaller of the two sizes described above (for now).
260292
buffer_type!(
261293
PrivateKeyRsa,
262-
(TPM2_MAX_RSA_KEY_BYTES / 2) as usize,
294+
TPM2B_PRIVATE_KEY_RSA_BUFFER_SIZE,
263295
TPM2B_PRIVATE_KEY_RSA
264296
);
265297
}
266298

267299
pub mod private_vendor_specific {
268300
use crate::tss2_esys::TPM2_PRIVATE_VENDOR_SPECIFIC_BYTES;
269-
301+
const TPM2B_PRIVATE_VENDOR_SPECIFIC_BUFFER_SIZE: usize =
302+
TPM2_PRIVATE_VENDOR_SPECIFIC_BYTES as usize;
270303
// The spec states the maximum size as:
271304
// "The value for PRIVATE_VENDOR_SPECIFIC_BYTES is determined by the vendor."
272305
// Not very helpful, but the TSS exposes a generic value that we can use.
273306
buffer_type!(
274307
PrivateVendorSpecific,
275-
TPM2_PRIVATE_VENDOR_SPECIFIC_BYTES as usize,
308+
TPM2B_PRIVATE_VENDOR_SPECIFIC_BUFFER_SIZE,
276309
TPM2B_PRIVATE_VENDOR_SPECIFIC
277310
);
278311
}
279312

280313
pub mod public_key_rsa {
281314
use crate::{interface_types::key_bits::RsaKeyBits, tss2_esys::TPM2_MAX_RSA_KEY_BYTES};
315+
const TPM2B_PUBLIC_KEY_RSA_BUFFER_SIZE: usize = TPM2_MAX_RSA_KEY_BYTES as usize;
282316
buffer_type!(
283317
PublicKeyRsa,
284-
TPM2_MAX_RSA_KEY_BYTES as usize,
318+
TPM2B_PUBLIC_KEY_RSA_BUFFER_SIZE,
285319
TPM2B_PUBLIC_KEY_RSA
286320
);
287321

@@ -359,45 +393,47 @@ pub mod sensitive_data {
359393
// versions of tpm2-tss supported by the crate so the fall back is to
360394
// calculate the max size by removing the size of the size parameter(UINT16)
361395
// from the total size of the buffer type.
396+
use std::mem::size_of;
362397
cfg_if::cfg_if! {
363398
if #[cfg(has_tpmu_sensitive_create)] {
364399
use crate::tss2_esys::TPMU_SENSITIVE_CREATE;
365-
#[allow(unused_qualifications)]
366-
const TPMU_SENSITIVE_CREATE_MEM_SIZE: usize = std::mem::size_of::<TPMU_SENSITIVE_CREATE>();
400+
const TPM2B_SENSITIVE_DATA_BUFFER_SIZE: usize = size_of::<TPMU_SENSITIVE_CREATE>();
367401
} else {
368402
use crate::tss2_esys::UINT16;
369-
#[allow(unused_qualifications)]
370-
const TPMU_SENSITIVE_CREATE_MEM_SIZE: usize = std::mem::size_of::<TPM2B_SENSITIVE_DATA>() - std::mem::size_of::<UINT16>();
403+
const TPM2B_SENSITIVE_DATA_BUFFER_SIZE: usize = size_of::<TPM2B_SENSITIVE_DATA>() - size_of::<UINT16>();
371404
}
372405
}
373406
buffer_type!(
374407
SensitiveData,
375-
TPMU_SENSITIVE_CREATE_MEM_SIZE,
408+
TPM2B_SENSITIVE_DATA_BUFFER_SIZE,
376409
TPM2B_SENSITIVE_DATA
377410
);
378411
}
379412

380413
pub mod symmetric_key {
381414
use crate::tss2_esys::TPM2_MAX_SYM_KEY_BYTES;
382-
415+
const TPM2B_SYM_KEY_BUFFER_SIZE: usize = TPM2_MAX_SYM_KEY_BYTES as usize;
383416
// The spec states the maximum size as:
384417
// "MAX_SYM_KEY_BYTES will be the larger of the largest symmetric key supported by the TPM and the
385418
// largest digest produced by any hashing algorithm implemented on the TPM"
386-
buffer_type!(SymmetricKey, TPM2_MAX_SYM_KEY_BYTES as usize, TPM2B_SYM_KEY);
419+
buffer_type!(SymmetricKey, TPM2B_SYM_KEY_BUFFER_SIZE, TPM2B_SYM_KEY);
387420
}
388421

389422
pub mod timeout {
390-
buffer_type!(Timeout, 8, TPM2B_TIMEOUT);
423+
use crate::tss2_esys::UINT64;
424+
use std::mem::size_of;
425+
const TPM2B_TIMEOUT_BUFFER_SIZE: usize = size_of::<UINT64>();
426+
buffer_type!(Timeout, TPM2B_TIMEOUT_BUFFER_SIZE, TPM2B_TIMEOUT);
391427
}
392428

393429
pub mod tpm_context_data {
394430
use crate::tss2_esys::TPMS_CONTEXT_DATA;
431+
use std::mem::size_of;
395432

396-
#[allow(unused_qualifications)]
397-
const TPMS_CONTEXT_DATA_MEM_SIZE: usize = std::mem::size_of::<TPMS_CONTEXT_DATA>();
433+
const TPM2B_CONTEXT_DATA_BUFFER_SIZE: usize = size_of::<TPMS_CONTEXT_DATA>();
398434
buffer_type!(
399435
TpmContextData,
400-
TPMS_CONTEXT_DATA_MEM_SIZE,
436+
TPM2B_CONTEXT_DATA_BUFFER_SIZE,
401437
TPM2B_CONTEXT_DATA
402438
);
403439
}

tss-esapi/src/structures/buffers/public.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
use log::error;
1111
use std::{
1212
convert::{TryFrom, TryInto},
13+
mem::size_of,
1314
ops::Deref,
1415
};
1516
use zeroize::{Zeroize, ZeroizeOnDrop};
@@ -24,8 +25,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
2425
pub struct PublicBuffer(Vec<u8>);
2526

2627
impl PublicBuffer {
27-
#[allow(unused_qualifications)]
28-
pub const MAX_SIZE: usize = std::mem::size_of::<TPMT_PUBLIC>();
28+
pub const MAX_SIZE: usize = size_of::<TPMT_PUBLIC>();
2929

3030
pub fn value(&self) -> &[u8] {
3131
&self.0

tss-esapi/tests/integration_tests/structures_tests/buffers_tests/attest_buffer_tests.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,17 @@ fn test_default() {
5151
assert_eq!(expected, actual);
5252
}
5353
}
54+
55+
#[test]
56+
fn test_max_sized_attest_buffer_conversions() {
57+
let expected_attestation_data = [0xffu8; AttestBuffer::MAX_SIZE];
58+
let native = AttestBuffer::try_from(expected_attestation_data.as_slice().to_vec()).expect(
59+
"It should be possible to convert an array of MAX size into a AttestBuffer object.",
60+
);
61+
let tss = TPM2B_ATTEST::try_from(native).expect(
62+
"It should be possible to convert a valid AttestBuffer object into a TPM2B_ATTEST.",
63+
);
64+
assert_eq!(AttestBuffer::MAX_SIZE, tss.size as usize);
65+
// This will be a compiler error if the max size does not match the TSS buffer size.
66+
assert_eq!(expected_attestation_data, tss.attestationData);
67+
}

tss-esapi/tests/integration_tests/structures_tests/buffers_tests/auth_tests.rs

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,60 @@ use tss_esapi::tss2_esys::TPM2B_AUTH;
88
// in it being just a type alias for TPM2B_DIGEST
99
// in the rust code. So the same size restrictions that
1010
// TPM2B_DIGEST have will apply here as well.
11-
mod test_auth {
12-
use super::*;
1311

14-
#[test]
15-
fn test_max_sized_data() {
16-
let _ = Auth::try_from([0xff; 64].to_vec()).unwrap();
17-
}
12+
#[test]
13+
fn test_max_sized_data() {
14+
let _ = Auth::try_from([0xff; 64].to_vec()).unwrap();
15+
}
1816

19-
#[test]
20-
fn test_to_large_data() {
21-
// Removed:
22-
// - test_handle_auth::test_set_large_handle
23-
// - test_create::test_long_auth_create
24-
// - test_create_primary::test_long_auth_create_primary
25-
// from the context tests and put here instead.
17+
#[test]
18+
fn test_to_large_data() {
19+
// Removed:
20+
// - test_handle_auth::test_set_large_handle
21+
// - test_create::test_long_auth_create
22+
// - test_create_primary::test_long_auth_create_primary
23+
// from the context tests and put here instead.
2624

27-
let _ = Auth::try_from([0xff; 100].to_vec()).unwrap_err();
28-
}
25+
let _ = Auth::try_from([0xff; 100].to_vec()).unwrap_err();
26+
}
2927

30-
#[test]
31-
fn test_default() {
32-
{
33-
let auth: Auth = Default::default();
34-
let expected: TPM2B_AUTH = Default::default();
35-
let actual = TPM2B_AUTH::from(auth);
36-
assert_eq!(expected.size, actual.size);
37-
assert_eq!(
38-
expected.buffer.len(),
39-
actual.buffer.len(),
40-
"Buffers don't have the same length"
41-
);
42-
assert!(
43-
expected
44-
.buffer
45-
.iter()
46-
.zip(actual.buffer.iter())
47-
.all(|(a, b)| a == b),
48-
"Buffers are not equal"
49-
);
50-
}
51-
{
52-
let tss_auth: TPM2B_AUTH = Default::default();
53-
let expected: Auth = Default::default();
54-
let actual = Auth::try_from(tss_auth).unwrap();
55-
assert_eq!(expected, actual);
56-
}
28+
#[test]
29+
fn test_default() {
30+
{
31+
let auth: Auth = Default::default();
32+
let expected: TPM2B_AUTH = Default::default();
33+
let actual = TPM2B_AUTH::from(auth);
34+
assert_eq!(expected.size, actual.size);
35+
assert_eq!(
36+
expected.buffer.len(),
37+
actual.buffer.len(),
38+
"Buffers don't have the same length"
39+
);
40+
assert!(
41+
expected
42+
.buffer
43+
.iter()
44+
.zip(actual.buffer.iter())
45+
.all(|(a, b)| a == b),
46+
"Buffers are not equal"
47+
);
5748
}
49+
{
50+
let tss_auth: TPM2B_AUTH = Default::default();
51+
let expected: Auth = Default::default();
52+
let actual = Auth::try_from(tss_auth).unwrap();
53+
assert_eq!(expected, actual);
54+
}
55+
}
56+
57+
#[test]
58+
fn test_max_sized_auth_conversions() {
59+
let expected_buffer = [0xffu8; Auth::MAX_SIZE];
60+
let native = Auth::try_from(expected_buffer.as_slice().to_vec())
61+
.expect("It should be possible to convert an array of MAX size into a Auth object.");
62+
let tss = TPM2B_AUTH::try_from(native)
63+
.expect("It should be possible to convert a valid Auth object into a TPM2B_AUTH.");
64+
assert_eq!(Auth::MAX_SIZE, tss.size as usize);
65+
// This will be a compiler error if the max size does not match the TSS buffer size.
66+
assert_eq!(expected_buffer, tss.buffer);
5867
}

0 commit comments

Comments
 (0)