Skip to content

Commit a980623

Browse files
committed
tpm: add policy auth for EK to activate crendential
Signed-off-by: Thore Sommer <[email protected]>
1 parent f053cfc commit a980623

File tree

1 file changed

+118
-33
lines changed

1 file changed

+118
-33
lines changed

keylime/src/tpm.rs

+118-33
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use std::{
1616
sync::{Arc, Mutex, OnceLock},
1717
};
1818
use thiserror::Error;
19+
use tss_esapi::handles::SessionHandle;
20+
use tss_esapi::interface_types::session_handles::PolicySession;
21+
use tss_esapi::structures::{DigestList, SymmetricDefinition};
1922

2023
use openssl::{
2124
hash::{Hasher, MessageDigest},
@@ -26,9 +29,7 @@ use openssl::{
2629

2730
use tss_esapi::{
2831
abstraction::{
29-
ak,
30-
cipher::Cipher,
31-
ek,
32+
ak, ek,
3233
pcr::{read_all, PcrData},
3334
DefaultKey,
3435
},
@@ -40,7 +41,7 @@ use tss_esapi::{
4041
},
4142
handles::{
4243
AuthHandle, KeyHandle, ObjectHandle, PcrHandle, PersistentTpmHandle,
43-
SessionHandle, TpmHandle,
44+
TpmHandle,
4445
},
4546
interface_types::{
4647
algorithm::{AsymmetricAlgorithm, HashingAlgorithm, PublicAlgorithm},
@@ -116,6 +117,47 @@ const IAK_AUTH_POLICY_SHA256: [u8; 32] = [
116117
];
117118
const UNIQUE_IAK: [u8; 3] = [0x49, 0x41, 0x4b];
118119

120+
// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.5 Revision 2
121+
// Section B.6
122+
const POLICY_A_SHA384: [u8; 48] = [
123+
0x8b, 0xbf, 0x22, 0x66, 0x53, 0x7c, 0x17, 0x1c, 0xb5, 0x6e, 0x40, 0x3c,
124+
0x4d, 0xc1, 0xd4, 0xb6, 0x4f, 0x43, 0x26, 0x11, 0xdc, 0x38, 0x6e, 0x6f,
125+
0x53, 0x20, 0x50, 0xc3, 0x27, 0x8c, 0x93, 0x0e, 0x14, 0x3e, 0x8b, 0xb1,
126+
0x13, 0x38, 0x24, 0xcc, 0xb4, 0x31, 0x05, 0x38, 0x71, 0xc6, 0xdb, 0x53,
127+
];
128+
const POLICY_A_SHA512: [u8; 64] = [
129+
0x1e, 0x3b, 0x76, 0x50, 0x2c, 0x8a, 0x14, 0x25, 0xaa, 0x0b, 0x7b, 0x3f,
130+
0xc6, 0x46, 0xa1, 0xb0, 0xfa, 0xe0, 0x63, 0xb0, 0x3b, 0x53, 0x68, 0xf9,
131+
0xc4, 0xcd, 0xde, 0xca, 0xff, 0x08, 0x91, 0xdd, 0x68, 0x2b, 0xac, 0x1a,
132+
0x85, 0xd4, 0xd8, 0x32, 0xb7, 0x81, 0xea, 0x45, 0x19, 0x15, 0xde, 0x5f,
133+
0xc5, 0xbf, 0x0d, 0xc4, 0xa1, 0x91, 0x7c, 0xd4, 0x2f, 0xa0, 0x41, 0xe3,
134+
0xf9, 0x98, 0xe0, 0xee,
135+
];
136+
const POLICY_A_SM3_256: [u8; 32] = [
137+
0xc6, 0x7f, 0x7d, 0x35, 0xf6, 0x6f, 0x3b, 0xec, 0x13, 0xc8, 0x9f, 0xe8,
138+
0x98, 0x92, 0x1c, 0x65, 0x1b, 0x0c, 0xb5, 0xa3, 0x8a, 0x92, 0x69, 0x0a,
139+
0x62, 0xa4, 0x3c, 0x00, 0x12, 0xe4, 0xfb, 0x8b,
140+
];
141+
const POLICY_C_SHA384: [u8; 48] = [
142+
0xd6, 0x03, 0x2c, 0xe6, 0x1f, 0x2f, 0xb3, 0xc2, 0x40, 0xeb, 0x3c, 0xf6,
143+
0xa3, 0x32, 0x37, 0xef, 0x2b, 0x6a, 0x16, 0xf4, 0x29, 0x3c, 0x22, 0xb4,
144+
0x55, 0xe2, 0x61, 0xcf, 0xfd, 0x21, 0x7a, 0xd5, 0xb4, 0x94, 0x7c, 0x2d,
145+
0x73, 0xe6, 0x30, 0x05, 0xee, 0xd2, 0xdc, 0x2b, 0x35, 0x93, 0xd1, 0x65,
146+
];
147+
const POLICY_C_SHA512: [u8; 64] = [
148+
0x58, 0x9e, 0xe1, 0xe1, 0x46, 0x54, 0x47, 0x16, 0xe8, 0xde, 0xaf, 0xe6,
149+
0xdb, 0x24, 0x7b, 0x01, 0xb8, 0x1e, 0x9f, 0x9c, 0x7d, 0xd1, 0x6b, 0x81,
150+
0x4a, 0xa1, 0x59, 0x13, 0x87, 0x49, 0x10, 0x5f, 0xba, 0x53, 0x88, 0xdd,
151+
0x1d, 0xea, 0x70, 0x2f, 0x35, 0x24, 0x0c, 0x18, 0x49, 0x33, 0x12, 0x1e,
152+
0x2c, 0x61, 0xb8, 0xf5, 0x0d, 0x3e, 0xf9, 0x13, 0x93, 0xa4, 0x9a, 0x38,
153+
0xc3, 0xf7, 0x3f, 0xc8,
154+
];
155+
const POLICY_C_SM3_256: [u8; 32] = [
156+
0x2d, 0x4e, 0x81, 0x57, 0x8c, 0x35, 0x31, 0xd9, 0xbd, 0x1c, 0xdd, 0x7d,
157+
0x02, 0xba, 0x29, 0x8d, 0x56, 0x99, 0xa3, 0xe3, 0x9f, 0xc3, 0x55, 0x1b,
158+
0xfe, 0xff, 0xcf, 0x13, 0x2b, 0x49, 0xe1, 0x1d,
159+
];
160+
119161
/// TpmError wraps all possible errors raised in tpm.rs
120162
#[derive(Error, Debug)]
121163
pub enum TpmError {
@@ -1215,19 +1257,14 @@ impl Context<'_> {
12151257
/// Creates an empty authentication session
12161258
fn create_empty_session(
12171259
&mut self,
1260+
ctx: &mut tss_esapi::Context,
12181261
ses_type: SessionType,
1262+
symmetric: SymmetricDefinition,
1263+
hash_alg: HashingAlgorithm,
12191264
) -> Result<AuthSession> {
1220-
let mut ctx = self.inner.lock().unwrap(); //#[allow_ci]
12211265
let Some(session) = ctx
12221266
.start_auth_session(
1223-
None,
1224-
None,
1225-
None,
1226-
ses_type,
1227-
Cipher::aes_128_cfb().try_into().map_err(|source| {
1228-
TpmError::TSSSymmetricDefinitionFromCipher { source }
1229-
})?,
1230-
HashingAlgorithm::Sha256,
1267+
None, None, None, ses_type, symmetric, hash_alg,
12311268
)
12321269
.map_err(|source| {
12331270
TpmError::TSSStartAuthenticationSessionError { source }
@@ -1255,35 +1292,83 @@ impl Context<'_> {
12551292
ak: KeyHandle,
12561293
ek: KeyHandle,
12571294
) -> Result<Digest> {
1258-
let (credential, secret) = parse_cred_and_secret(keyblob)?;
1259-
1260-
let ek_auth = self.create_empty_session(SessionType::Policy)?;
1261-
12621295
let mut ctx = self.inner.lock().unwrap(); //#[allow_ci]
12631296

1264-
// We authorize ses2 with PolicySecret(ENDORSEMENT) as per PolicyA
1265-
let _ = ctx.execute_with_nullauth_session(|context| {
1266-
context.policy_secret(
1267-
ek_auth.try_into()?,
1268-
AuthHandle::Endorsement,
1269-
Default::default(),
1270-
Default::default(),
1271-
Default::default(),
1272-
None,
1273-
)
1274-
})?;
1297+
let (credential, secret) = parse_cred_and_secret(keyblob)?;
1298+
let mut policy_digests = DigestList::new();
1299+
let (parent_public, _, _) = ctx.read_public(ek)?;
1300+
let ek_hash_alg = parent_public.name_hashing_algorithm();
1301+
let ek_symmetric =
1302+
parent_public.symmetric_algorithm().ok_or_else(|| {
1303+
TpmError::TSSReadPublicError {
1304+
source: tss_esapi::Error::WrapperError(
1305+
tss_esapi::WrapperErrorKind::InvalidParam,
1306+
),
1307+
}
1308+
})?;
1309+
match ek_hash_alg {
1310+
HashingAlgorithm::Sha384 => {
1311+
policy_digests
1312+
.add(Digest::try_from(POLICY_A_SHA384.as_slice())?)?;
1313+
policy_digests
1314+
.add(Digest::try_from(POLICY_C_SHA384.as_slice())?)?;
1315+
}
1316+
HashingAlgorithm::Sha512 => {
1317+
policy_digests
1318+
.add(Digest::try_from(POLICY_A_SHA512.as_slice())?)?;
1319+
policy_digests
1320+
.add(Digest::try_from(POLICY_C_SHA512.as_slice())?)?;
1321+
}
1322+
HashingAlgorithm::Sm3_256 => {
1323+
policy_digests
1324+
.add(Digest::try_from(POLICY_A_SM3_256.as_slice())?)?;
1325+
policy_digests
1326+
.add(Digest::try_from(POLICY_C_SM3_256.as_slice())?)?;
1327+
}
1328+
_ => (),
1329+
};
1330+
1331+
let ek_auth = self.create_empty_session(
1332+
&mut ctx,
1333+
SessionType::Policy,
1334+
ek_symmetric.into(),
1335+
ek_hash_alg,
1336+
)?;
12751337

1338+
// We authorize session according to the EK profile spec
12761339
let result = ctx
1277-
.execute_with_sessions(
1278-
(Some(AuthSession::Password), Some(ek_auth), None),
1279-
|context| {
1280-
context.activate_credential(ak, ek, credential, secret)
1340+
.execute_with_temporary_object(
1341+
SessionHandle::from(ek_auth).into(),
1342+
|ctx, _| {
1343+
let _ = ctx.execute_with_nullauth_session(|ctx| {
1344+
ctx.policy_secret(
1345+
PolicySession::try_from(ek_auth)?,
1346+
AuthHandle::Endorsement,
1347+
Default::default(),
1348+
Default::default(),
1349+
Default::default(),
1350+
None,
1351+
)
1352+
})?;
1353+
if !policy_digests.is_empty() {
1354+
ctx.policy_or(
1355+
PolicySession::try_from(ek_auth)?,
1356+
policy_digests,
1357+
)?
1358+
}
1359+
ctx.execute_with_sessions(
1360+
(Some(AuthSession::Password), Some(ek_auth), None),
1361+
|ctx| {
1362+
ctx.activate_credential(
1363+
ak, ek, credential, secret,
1364+
)
1365+
},
1366+
)
12811367
},
12821368
)
12831369
.map_err(TpmError::from);
12841370

12851371
// Clear sessions after use
1286-
ctx.flush_context(SessionHandle::from(ek_auth).into())?;
12871372
ctx.clear_sessions();
12881373

12891374
result

0 commit comments

Comments
 (0)