tpm.rs 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116
  1. // SPDX-License-Identifier: AGPL-3.0-or-later
  2. use crate::error::{DisplayErr, StringError};
  3. use super::*;
  4. use btserde::read_from;
  5. use log::error;
  6. use openssl::{
  7. bn::{BigNum, BigNumRef},
  8. nid::Nid,
  9. };
  10. use serde::ser;
  11. use std::{
  12. ffi::CStr,
  13. fs::OpenOptions,
  14. io::{BufReader, BufWriter, Read, Write},
  15. mem::size_of,
  16. ops::Deref,
  17. os::{raw::c_char, unix::fs::PermissionsExt},
  18. path::{Path, PathBuf},
  19. str::FromStr,
  20. sync::{Arc, RwLock, RwLockWriteGuard},
  21. time::Duration,
  22. };
  23. use tss_esapi::{
  24. attributes::{object::ObjectAttributes, SessionAttributesBuilder},
  25. constants::{
  26. response_code::Tss2ResponseCode,
  27. session_type::SessionType,
  28. tss::{TPM2_PERSISTENT_FIRST, TPM2_RH_NULL},
  29. CapabilityType, CommandCode, Tss2ResponseCodeKind,
  30. },
  31. handles::{KeyHandle, ObjectHandle, PersistentTpmHandle, TpmHandle},
  32. interface_types::{
  33. algorithm::HashingAlgorithm,
  34. dynamic_handles::Persistent,
  35. key_bits::RsaKeyBits,
  36. resource_handles::{Hierarchy, Provision},
  37. session_handles::{AuthSession, PolicySession},
  38. },
  39. structures::{
  40. Auth, CapabilityData, Data, Digest, EncryptedSecret, HashScheme, HashcheckTicket, Private,
  41. Public, PublicKeyRsa, PublicRsaParameters, RsaDecryptionScheme, RsaScheme, SignatureScheme,
  42. SymmetricDefinition, SymmetricDefinitionObject, Ticket,
  43. },
  44. tcti_ldr::{TabrmdConfig, TctiNameConf},
  45. traits::{Marshall, UnMarshall},
  46. Context,
  47. };
  48. use tss_esapi_sys::{TPM2_CAP, TPM2_HANDLE, TPM2_MAX_CAP_BUFFER, TPMT_TK_HASHCHECK, TSS2_RC};
  49. impl From<tss_esapi::Error> for Error {
  50. fn from(err: tss_esapi::Error) -> Self {
  51. match err {
  52. tss_esapi::Error::WrapperError(err) => Error::library(err),
  53. tss_esapi::Error::Tss2Error(err) => {
  54. let rc = err.tss2_rc();
  55. let text = tss2_rc_decode(err);
  56. let string = format!("response code: {rc}, response text: {text}");
  57. Error::library(StringError::new(string))
  58. }
  59. }
  60. }
  61. }
  62. /// Trait which extends the `tss_esapi::Context`.
  63. trait ContextExt {
  64. fn persistent_handles(&mut self) -> Result<Vec<PersistentTpmHandle>>;
  65. /// Returns the first free persistent handle available in the TPM.
  66. fn unused_persistent_primary_key(&mut self) -> Result<Persistent>;
  67. fn persist_key(&mut self, key_handle: KeyHandle) -> Result<TPM2_HANDLE>;
  68. fn evict_key(&mut self, tpm_handle: TPM2_HANDLE, key_handle: Option<KeyHandle>) -> Result<()>;
  69. fn key_handle(&mut self, tpm_handle: TpmHandle) -> Result<KeyHandle>;
  70. fn set_encrypt_decrypt(&mut self, session: AuthSession) -> Result<()>;
  71. fn start_default_auth_session(&mut self) -> Result<AuthSession>;
  72. fn start_policy_session(&mut self, is_trial: IsTrial) -> Result<PolicySession>;
  73. fn dup_with_password_policy(&mut self) -> Result<Digest>;
  74. fn export_key<S: Scheme>(
  75. &mut self,
  76. key_pair: &KeyPair<S>,
  77. new_parent: KeyHandle,
  78. key_auth: Auth,
  79. policy_session: PolicySession,
  80. encryption_key: &AeadKey,
  81. ) -> Result<ExportedKeyPair<S>>;
  82. fn import_key<S: Scheme>(
  83. &mut self,
  84. exported: ExportedKeyPair<S>,
  85. new_parent: KeyHandle,
  86. auth: Auth,
  87. encryption_key: &AeadKey,
  88. ) -> Result<KeyPair<S>>;
  89. fn set_auth(&mut self, cred_data: &CredData, password: &str) -> Result<()>;
  90. }
  91. impl ContextExt for Context {
  92. fn persistent_handles(&mut self) -> Result<Vec<PersistentTpmHandle>> {
  93. let capability = CapabilityType::Handles;
  94. let property = TPM2_PERSISTENT_FIRST;
  95. let max = usize::try_from(TPM2_MAX_CAP_BUFFER).unwrap();
  96. // This calculation was copied from tpm2_getcap.
  97. let count = (max - size_of::<TPM2_CAP>() - size_of::<u32>()) / size_of::<TPM2_HANDLE>();
  98. let property_count = u32::try_from(count).unwrap();
  99. let mut all_handles = Vec::new();
  100. let more = false;
  101. for _ in 0..255 {
  102. let (handles, more) = self.get_capability(capability, property, property_count)?;
  103. let list = match handles {
  104. CapabilityData::Handles(list) => list.into_inner(),
  105. _ => {
  106. return Err(bterr!(
  107. "Unexpected capability type returned by TPM: {:?}",
  108. handles
  109. ))
  110. }
  111. };
  112. all_handles.reserve(list.len());
  113. for handle in list {
  114. all_handles.push(PersistentTpmHandle::try_from(handle)?);
  115. }
  116. if !more {
  117. break;
  118. }
  119. }
  120. if more {
  121. return Err(bterr!(
  122. "hit iteration limit before retrieving all persistent handles from the TPM",
  123. ));
  124. }
  125. all_handles.sort_unstable_by_key(|handle| TPM2_HANDLE::from(*handle));
  126. Ok(all_handles)
  127. }
  128. fn unused_persistent_primary_key(&mut self) -> Result<Persistent> {
  129. let mut used_handles = self.persistent_handles()?.into_iter();
  130. // These address regions are defined in Registry of Reserved TPM 2.0 Handles and Localities
  131. // The first regions for both are for primary keys and the second is marked as "Available".
  132. let storage = (0x81_00_00_00..0x81_00_01_00u32).chain(0x81_00_80_00..0x81_01_00_00u32);
  133. let endorsement = (0x81_01_00_00..0x81_01_01_00u32).chain(0x81_01_80_00..0x81_02_00_00u32);
  134. let possible_handles = storage
  135. .chain(endorsement)
  136. .map(|handle| PersistentTpmHandle::new(handle).unwrap());
  137. let mut unused: Option<PersistentTpmHandle> = None;
  138. // We simultaneously iterate over the possible handles and the used handles, breaking when
  139. // we find a handle which is not equal to the current used handle, or when
  140. // there are no more used handles. This works because both `used_handles` and
  141. // `possible_handles` are sorted.
  142. for handle in possible_handles {
  143. let used = match used_handles.next() {
  144. Some(used) => used,
  145. None => {
  146. unused = Some(handle);
  147. break;
  148. }
  149. };
  150. if used != handle {
  151. unused = Some(handle);
  152. break;
  153. }
  154. }
  155. match unused {
  156. Some(unused) => Ok(Persistent::Persistent(unused)),
  157. None => Err(bterr!("failed to find an unused persistent handle")),
  158. }
  159. }
  160. fn persist_key(&mut self, key_handle: KeyHandle) -> Result<TPM2_HANDLE> {
  161. let mut persistent: Option<Persistent> = None;
  162. for _ in 0..255 {
  163. let handle =
  164. self.execute_with_session(None, |ctx| ctx.unused_persistent_primary_key())?;
  165. match self.evict_control(Provision::Owner, key_handle.into(), handle) {
  166. Ok(_) => {
  167. persistent = Some(handle);
  168. break;
  169. }
  170. Err(error) => {
  171. if let tss_esapi::Error::Tss2Error(rc) = error {
  172. if Some(Tss2ResponseCodeKind::NvDefined) == rc.kind() {
  173. // This type of error occurs if another application used the persistent
  174. // handle we found before we could, so we try again with a different
  175. // handle.
  176. continue;
  177. }
  178. }
  179. return Err(error.into());
  180. }
  181. }
  182. }
  183. match persistent {
  184. Some(Persistent::Persistent(inner)) => Ok(inner.into()),
  185. None => Err(bterr!("retry limit reached")),
  186. }
  187. }
  188. fn evict_key(&mut self, persistent: TPM2_HANDLE, key_handle: Option<KeyHandle>) -> Result<()> {
  189. let tpm_handle = TpmHandle::try_from(persistent)?;
  190. let key_handle = match key_handle {
  191. Some(key_handle) => key_handle,
  192. None => self.tr_from_tpm_public(tpm_handle)?.into(),
  193. };
  194. let persistent = Persistent::Persistent(tpm_handle.try_into()?);
  195. self.evict_control(Provision::Owner, key_handle.into(), persistent)?;
  196. Ok(())
  197. }
  198. fn set_encrypt_decrypt(&mut self, session: AuthSession) -> Result<()> {
  199. let (attributes, mask) = SessionAttributesBuilder::new()
  200. .with_decrypt(true)
  201. .with_encrypt(true)
  202. .build();
  203. self.tr_sess_set_attributes(session, attributes, mask)?;
  204. Ok(())
  205. }
  206. fn start_default_auth_session(&mut self) -> Result<AuthSession> {
  207. let session = self
  208. .start_auth_session(
  209. None,
  210. None,
  211. None,
  212. SessionType::Hmac,
  213. SymmetricDefinition::AES_256_CFB,
  214. HashingAlgorithm::Sha256,
  215. )?
  216. .ok_or_else(|| bterr!("empty session handle received from TPM"))?;
  217. self.set_encrypt_decrypt(session)?;
  218. Ok(session)
  219. }
  220. fn start_policy_session(&mut self, is_trial: IsTrial) -> Result<PolicySession> {
  221. let session = self
  222. .start_auth_session(
  223. None,
  224. None,
  225. None,
  226. is_trial.into(),
  227. SymmetricDefinition::AES_256_CFB,
  228. HashingAlgorithm::Sha256,
  229. )?
  230. .ok_or_else(|| bterr!("empty session handle received from TPM"))?;
  231. self.set_encrypt_decrypt(session)?;
  232. Ok(session.try_into()?)
  233. }
  234. /// Loads the public information from the persistent object stored in the TPM referred to by
  235. /// `tpm_handle` and returns the `KeyHandle` for this object. If the TPM handle refers to an
  236. /// object which is not actually a key, then an error is returned.
  237. fn key_handle(&mut self, tpm_handle: TpmHandle) -> Result<KeyHandle> {
  238. let obj_handle =
  239. self.execute_with_session(None, |ctx| ctx.tr_from_tpm_public(tpm_handle))?;
  240. Ok(obj_handle.into())
  241. }
  242. /// Returns the digest for the policy which allows a key to be duplicated provided that the
  243. /// caller supplies the correct password (authValue) for the key being duplicated.
  244. fn dup_with_password_policy(&mut self) -> Result<Digest> {
  245. let policy_session = self.start_policy_session(IsTrial::True)?;
  246. self.execute_with_session(None, |ctx| {
  247. ctx.policy_password(policy_session)?;
  248. ctx.policy_command_code(policy_session, CommandCode::Duplicate)?;
  249. Ok(ctx.policy_get_digest(policy_session)?)
  250. })
  251. }
  252. fn export_key<S: Scheme>(
  253. &mut self,
  254. key_pair: &KeyPair<S>,
  255. new_parent: KeyHandle,
  256. key_auth: Auth,
  257. policy_session: PolicySession,
  258. encryption_key: &AeadKey,
  259. ) -> Result<ExportedKeyPair<S>> {
  260. let (public, ..) = self.read_public(key_pair.private)?;
  261. let result: Result<()> = self.execute_with_session(None, |ctx| {
  262. ctx.policy_password(policy_session)?;
  263. ctx.policy_command_code(policy_session, CommandCode::Duplicate)?;
  264. Ok(())
  265. });
  266. result?;
  267. let result: Result<(tss_esapi::structures::Private, EncryptedSecret)> = self
  268. .execute_with_session(Some(policy_session.into()), |ctx| {
  269. let obj_handle = ObjectHandle::from(key_pair.private);
  270. ctx.tr_set_auth(obj_handle, key_auth)?;
  271. let (_, private, secret) = ctx.duplicate(
  272. obj_handle,
  273. new_parent.into(),
  274. None,
  275. SymmetricDefinitionObject::Null,
  276. )?;
  277. Ok((private, secret))
  278. });
  279. let (private, secret) = result?;
  280. let tagged_ct =
  281. encryption_key.encrypt(PublicWrapper(public), &TpmBlobs { private, secret })?;
  282. Ok(ExportedKeyPair {
  283. scheme: key_pair.public.scheme,
  284. tagged_ct,
  285. })
  286. }
  287. fn import_key<S: Scheme>(
  288. &mut self,
  289. exported: ExportedKeyPair<S>,
  290. new_parent: KeyHandle,
  291. auth: Auth,
  292. encryption_key: &AeadKey,
  293. ) -> Result<KeyPair<S>> {
  294. let blobs = encryption_key.decrypt(&exported.tagged_ct)?;
  295. let public = exported.tagged_ct.aad;
  296. let private = self.import(
  297. new_parent.into(),
  298. None,
  299. public.clone(),
  300. blobs.private,
  301. blobs.secret,
  302. SymmetricDefinitionObject::Null,
  303. )?;
  304. let key_handle = self.load(new_parent, private, public.clone())?;
  305. self.tr_set_auth(key_handle.into(), auth)?;
  306. let public = AsymKeyPub::try_from(public.0, exported.scheme)?;
  307. Ok(KeyPair {
  308. public,
  309. private: key_handle,
  310. })
  311. }
  312. fn set_auth(&mut self, creds: &CredData, password: &str) -> Result<()> {
  313. let auth = Auth::try_from(password.as_bytes())?;
  314. self.tr_set_auth(creds.sign.private.into(), auth.clone())?;
  315. self.tr_set_auth(creds.enc.private.into(), auth)?;
  316. Ok(())
  317. }
  318. }
  319. enum IsTrial {
  320. True,
  321. False,
  322. }
  323. impl From<IsTrial> for SessionType {
  324. fn from(is_trial: IsTrial) -> Self {
  325. match is_trial {
  326. IsTrial::True => SessionType::Trial,
  327. IsTrial::False => SessionType::Policy,
  328. }
  329. }
  330. }
  331. trait DigestExt {
  332. fn empty() -> Digest;
  333. }
  334. impl DigestExt for Digest {
  335. fn empty() -> Digest {
  336. let empty = [0u8; 0];
  337. Digest::try_from(empty.as_slice()).unwrap()
  338. }
  339. }
  340. /// An authentication cookie which grants access to a node's credentials.
  341. #[derive(Serialize, Deserialize, Clone)]
  342. struct Cookie(#[serde(with = "BigArray")] [u8; Self::LEN]);
  343. impl Cookie {
  344. const LEN: usize = TpmCredStore::SIGN_SCHEME.key_len_const() as usize;
  345. fn random() -> Result<Cookie> {
  346. Ok(Cookie(rand_array()?))
  347. }
  348. fn as_slice(&self) -> &[u8] {
  349. self.0.as_slice()
  350. }
  351. /// Returns the `Auth` value associated with this cookie.
  352. fn auth(&self) -> Auth {
  353. // This shouldn't fail because the given slice is only 64 bytes long.
  354. Auth::try_from(&self.as_slice()[..64]).unwrap()
  355. }
  356. }
  357. #[derive(Serialize, Deserialize)]
  358. struct PublicWrapper(
  359. #[serde(serialize_with = "serialize_marshall")]
  360. #[serde(deserialize_with = "deserialize_unmarshall")]
  361. Public,
  362. );
  363. impl Deref for PublicWrapper {
  364. type Target = Public;
  365. fn deref(&self) -> &Self::Target {
  366. &self.0
  367. }
  368. }
  369. fn serialize_marshall<S: Serializer, T: Marshall>(
  370. value: &T,
  371. ser: S,
  372. ) -> std::result::Result<S::Ok, S::Error> {
  373. let vec = value.marshall().map_err(ser::Error::custom)?;
  374. vec.as_slice().serialize(ser)
  375. }
  376. fn deserialize_unmarshall<'de, D: Deserializer<'de>, T: UnMarshall>(
  377. de: D,
  378. ) -> std::result::Result<T, D::Error> {
  379. let vec: Vec<u8> = Deserialize::deserialize(de)?;
  380. T::unmarshall(&vec).map_err(de::Error::custom)
  381. }
  382. #[derive(Serialize, Deserialize)]
  383. struct TpmBlobs {
  384. #[serde(serialize_with = "serialize_as_vec")]
  385. #[serde(deserialize_with = "deserialize_as_vec")]
  386. private: Private,
  387. #[serde(serialize_with = "serialize_as_vec")]
  388. #[serde(deserialize_with = "deserialize_as_vec")]
  389. secret: EncryptedSecret,
  390. }
  391. fn serialize_as_vec<S: Serializer, T: Deref<Target = Vec<u8>>>(
  392. value: &T,
  393. ser: S,
  394. ) -> std::result::Result<S::Ok, S::Error> {
  395. value.deref().serialize(ser)
  396. }
  397. fn deserialize_as_vec<'de, D: Deserializer<'de>, T: TryFrom<Vec<u8>>>(
  398. de: D,
  399. ) -> std::result::Result<T, D::Error> {
  400. T::try_from(Vec::deserialize(de)?)
  401. .map_err(|_| de::Error::custom("Unable to convert from vector"))
  402. }
  403. #[derive(Serialize, Deserialize)]
  404. pub struct ExportedKeyPair<S> {
  405. scheme: S,
  406. tagged_ct: TaggedCiphertext<TpmBlobs, PublicWrapper>,
  407. }
  408. #[derive(Serialize, Deserialize)]
  409. pub struct ExportedCreds {
  410. sign: ExportedKeyPair<Sign>,
  411. enc: ExportedKeyPair<Encrypt>,
  412. params: DerivationParams,
  413. writecap: Option<Writecap>,
  414. }
  415. /// A public/private key pair in a form which can be serialized and deserialized.
  416. #[derive(Serialize, Clone)]
  417. struct StoredKeyPair<S: Scheme> {
  418. public: AsymKeyPub<S>,
  419. private: TPM2_HANDLE,
  420. }
  421. impl<'de, S: Scheme> Deserialize<'de> for StoredKeyPair<S> {
  422. fn deserialize<D: Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
  423. const FIELDS: &[&str] = &["public", "private", "writecap"];
  424. struct StructVisitor<S: Scheme>(PhantomData<S>);
  425. impl<'de, S: Scheme> Visitor<'de> for StructVisitor<S> {
  426. type Value = StoredKeyPair<S>;
  427. fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
  428. formatter.write_fmt(format_args!("struct {}", stringify!(StoredKeyPair)))
  429. }
  430. fn visit_seq<A: SeqAccess<'de>>(
  431. self,
  432. mut seq: A,
  433. ) -> std::result::Result<Self::Value, A::Error> {
  434. let public: AsymKeyPub<S> = seq
  435. .next_element()?
  436. .ok_or_else(|| de::Error::missing_field(FIELDS[0]))?;
  437. let private: TPM2_HANDLE = seq
  438. .next_element()?
  439. .ok_or_else(|| de::Error::missing_field(FIELDS[1]))?;
  440. let pair = StoredKeyPair { public, private };
  441. Ok(pair)
  442. }
  443. }
  444. d.deserialize_struct(
  445. stringify!(StoredKeyPair),
  446. FIELDS,
  447. StructVisitor(PhantomData),
  448. )
  449. }
  450. }
  451. /// Credentials in a form which can be serialized and deserialized.
  452. #[derive(Serialize, Deserialize, Clone)]
  453. struct StoredCredData {
  454. sign: StoredKeyPair<Sign>,
  455. enc: StoredKeyPair<Encrypt>,
  456. writecap: Option<Writecap>,
  457. }
  458. impl StoredCredData {
  459. fn to_cred_data(&self, context: &mut Context) -> Result<CredData> {
  460. let sign = KeyPair::from_stored(context, &self.sign)?;
  461. let enc = KeyPair::from_stored(context, &self.enc)?;
  462. Ok(CredData {
  463. sign,
  464. enc,
  465. writecap: self.writecap.clone(),
  466. })
  467. }
  468. }
  469. #[derive(Serialize, Deserialize)]
  470. struct Storage {
  471. cookie: Cookie,
  472. node: Option<StoredCredData>,
  473. root: Option<StoredCredData>,
  474. storage_key: Option<StoredKeyPair<Encrypt>>,
  475. }
  476. impl Storage {
  477. fn new(cookie: Cookie) -> Storage {
  478. Storage {
  479. cookie,
  480. node: None,
  481. root: None,
  482. storage_key: None,
  483. }
  484. }
  485. fn save<W: Write>(&self, to: &mut W) -> Result<()> {
  486. Ok(write_to(self, to)?)
  487. }
  488. fn load<R: Read>(from: &mut R) -> Result<Storage> {
  489. Ok(read_from(from)?)
  490. }
  491. fn init<P: AsRef<Path>>(&self, path: P) -> Result<()> {
  492. let file = OpenOptions::new()
  493. .write(true)
  494. .create_new(true)
  495. .open(&path)?;
  496. // Only allow access from the current user.
  497. let metadata = file.metadata()?;
  498. let mut permissions = metadata.permissions();
  499. permissions.set_mode(0o600);
  500. file.set_permissions(permissions)?;
  501. let mut reader = BufWriter::new(file);
  502. self.save(&mut reader)?;
  503. reader.flush()?;
  504. Ok(())
  505. }
  506. fn load_or_init<P: AsRef<Path>>(path: P) -> Result<Storage> {
  507. match OpenOptions::new().read(true).open(&path) {
  508. Ok(file) => {
  509. let mut reader = BufReader::new(file);
  510. Self::load(&mut reader)
  511. }
  512. Err(error) => {
  513. if std::io::ErrorKind::NotFound != error.kind() {
  514. return Err(error.into());
  515. }
  516. let state = Self::new(Cookie::random()?);
  517. state.init(path)?;
  518. Ok(state)
  519. }
  520. }
  521. }
  522. }
  523. impl From<HashKind> for HashingAlgorithm {
  524. fn from(kind: HashKind) -> Self {
  525. match kind {
  526. HashKind::Sha2_256 => HashingAlgorithm::Sha256,
  527. HashKind::Sha2_512 => HashingAlgorithm::Sha512,
  528. }
  529. }
  530. }
  531. impl TryInto<RsaScheme> for SchemeKind {
  532. type Error = crate::Error;
  533. fn try_into(self) -> Result<RsaScheme> {
  534. match self {
  535. SchemeKind::Sign(sign) => match sign {
  536. Sign::RsaSsaPss(inner) => {
  537. Ok(RsaScheme::RsaPss(HashScheme::new(inner.hash_kind.into())))
  538. }
  539. },
  540. SchemeKind::Encrypt(encrypt) => match encrypt {
  541. Encrypt::RsaEsOaep(inner) => {
  542. Ok(RsaScheme::Oaep(HashScheme::new(inner.hash_kind.into())))
  543. }
  544. },
  545. }
  546. }
  547. }
  548. impl TryFrom<BitLen> for RsaKeyBits {
  549. type Error = crate::Error;
  550. fn try_from(len: BitLen) -> Result<RsaKeyBits> {
  551. match len {
  552. BitLen::Bits2048 => Ok(RsaKeyBits::Rsa2048),
  553. BitLen::Bits3072 => Ok(RsaKeyBits::Rsa3072),
  554. BitLen::Bits4096 => Ok(RsaKeyBits::Rsa4096),
  555. _ => Err(bterr!("unsupported key len: {len}")),
  556. }
  557. }
  558. }
  559. enum Parent {
  560. Seed(Hierarchy),
  561. Key(KeyHandle),
  562. }
  563. struct KeyBuilder<'a, S: Scheme> {
  564. scheme: S,
  565. allow_dup: bool,
  566. unique: &'a [u8],
  567. auth_value: Option<Auth>,
  568. name_hash: HashingAlgorithm,
  569. policy_digest: Digest,
  570. parent: Parent,
  571. restricted: bool,
  572. symmetric: SymmetricDefinitionObject,
  573. rsa_exponent: u32,
  574. }
  575. impl<'a, S: Scheme> KeyBuilder<'a, S> {
  576. fn new(scheme: S, unique: &'a [u8]) -> KeyBuilder<'a, S> {
  577. KeyBuilder {
  578. scheme,
  579. allow_dup: false,
  580. unique,
  581. auth_value: None,
  582. name_hash: HashingAlgorithm::Sha256,
  583. policy_digest: Digest::empty(),
  584. parent: Parent::Seed(Hierarchy::Owner),
  585. restricted: false,
  586. symmetric: SymmetricDefinitionObject::Null,
  587. rsa_exponent: Rsa::EXP,
  588. }
  589. }
  590. fn with_allow_dup(mut self, allow_dup: bool) -> Self {
  591. self.allow_dup = allow_dup;
  592. self
  593. }
  594. fn with_auth(mut self, auth: Auth) -> Self {
  595. self.auth_value = Some(auth);
  596. self
  597. }
  598. fn with_policy_digest(mut self, policy_digest: Digest) -> Self {
  599. self.policy_digest = policy_digest;
  600. self
  601. }
  602. fn with_parent(mut self, parent: Parent) -> Self {
  603. self.parent = parent;
  604. self
  605. }
  606. fn with_restricted(mut self, restricted: bool) -> Self {
  607. self.restricted = restricted;
  608. self
  609. }
  610. fn with_symmetric(mut self, symmetric: SymmetricDefinitionObject) -> Self {
  611. self.symmetric = symmetric;
  612. self
  613. }
  614. fn with_rsa_exponent(mut self, rsa_exponent: u32) -> Self {
  615. self.rsa_exponent = rsa_exponent;
  616. self
  617. }
  618. fn rsa_template(&self) -> Result<Public> {
  619. let scheme_enum = self.scheme.as_enum();
  620. let decrypt = match scheme_enum {
  621. SchemeKind::Sign(_) => false,
  622. SchemeKind::Encrypt(_) => true,
  623. };
  624. let object_attributes = ObjectAttributes::builder()
  625. .with_fixed_tpm(!self.allow_dup)
  626. .with_fixed_parent(!self.allow_dup)
  627. .with_sensitive_data_origin(true)
  628. .with_user_with_auth(true)
  629. .with_decrypt(decrypt)
  630. .with_sign_encrypt(!decrypt)
  631. .with_restricted(self.restricted)
  632. .build()?;
  633. let name_hashing_algorithm = self.name_hash;
  634. let parameters = PublicRsaParameters::new(
  635. self.symmetric,
  636. if self.restricted {
  637. RsaScheme::Null
  638. } else {
  639. scheme_enum.try_into()?
  640. },
  641. self.scheme.key_len().try_into()?,
  642. self.rsa_exponent.try_into()?,
  643. );
  644. let unique = PublicKeyRsa::try_from(self.unique)?;
  645. let public = Public::Rsa {
  646. object_attributes,
  647. name_hashing_algorithm,
  648. auth_policy: self.policy_digest.clone(),
  649. parameters,
  650. unique,
  651. };
  652. Ok(public)
  653. }
  654. fn template(&self) -> Result<Public> {
  655. match self.scheme.as_enum() {
  656. SchemeKind::Encrypt(encrypt) => match encrypt {
  657. Encrypt::RsaEsOaep(_) => self.rsa_template(),
  658. },
  659. SchemeKind::Sign(sign) => match sign {
  660. Sign::RsaSsaPss(_) => self.rsa_template(),
  661. },
  662. }
  663. }
  664. fn build(self, context: &mut Context) -> Result<KeyPair<S>> {
  665. let (public, private) = match self.parent {
  666. Parent::Seed(hierarchy) => {
  667. let result = context.create_primary(
  668. hierarchy,
  669. self.template()?,
  670. self.auth_value,
  671. None,
  672. None,
  673. None,
  674. )?;
  675. (result.out_public, result.key_handle)
  676. }
  677. Parent::Key(parent) => {
  678. let result =
  679. context.create(parent, self.template()?, self.auth_value, None, None, None)?;
  680. let private =
  681. context.load(parent, result.out_private, result.out_public.clone())?;
  682. (result.out_public, private)
  683. }
  684. };
  685. let public = AsymKey::try_from(public, self.scheme)?;
  686. Ok(KeyPair { public, private })
  687. }
  688. }
  689. impl<'a> KeyBuilder<'a, Encrypt> {
  690. fn for_storage_key(scheme: Encrypt, unique: &'a [u8]) -> KeyBuilder<'a, Encrypt> {
  691. KeyBuilder::new(scheme, unique)
  692. .with_allow_dup(false)
  693. .with_restricted(true)
  694. .with_symmetric(SymmetricDefinitionObject::AES_128_CFB)
  695. }
  696. }
  697. /// A public/private key pair.
  698. #[derive(Clone)]
  699. struct KeyPair<S: Scheme> {
  700. public: AsymKeyPub<S>,
  701. /// A rust struct which wraps an `ESYS_TR` from the ESAPI.
  702. private: KeyHandle,
  703. }
  704. impl<S: Scheme> KeyPair<S> {
  705. fn from_stored(context: &mut Context, stored: &StoredKeyPair<S>) -> Result<KeyPair<S>> {
  706. let tpm_handle = TpmHandle::try_from(stored.private)?;
  707. let key_handle = context.key_handle(tpm_handle)?;
  708. Ok(KeyPair {
  709. public: stored.public.clone(),
  710. private: key_handle,
  711. })
  712. }
  713. fn to_stored(&self, private: TPM2_HANDLE) -> StoredKeyPair<S> {
  714. let public = self.public.clone();
  715. StoredKeyPair { public, private }
  716. }
  717. }
  718. /// Credentials which can be used for signing and encrypting.
  719. struct CredData {
  720. sign: KeyPair<Sign>,
  721. enc: KeyPair<Encrypt>,
  722. writecap: Option<Writecap>,
  723. }
  724. struct State {
  725. context: Context,
  726. storage: Storage,
  727. node_creds: Option<TpmCreds>,
  728. storage_key: Option<KeyPair<Encrypt>>,
  729. }
  730. impl State {
  731. fn new(mut context: Context, storage: Storage) -> Result<State> {
  732. let storage_key = match &storage.storage_key {
  733. Some(storage_key) => Some(KeyPair::from_stored(&mut context, storage_key)?),
  734. None => None,
  735. };
  736. Ok(State {
  737. context,
  738. storage,
  739. node_creds: None,
  740. storage_key,
  741. })
  742. }
  743. fn init_node_creds(&mut self, state: &Arc<RwLock<State>>) -> Result<()> {
  744. let tpm_handles = match &self.storage.node {
  745. Some(handles) => handles,
  746. None => return Ok(()),
  747. };
  748. let key_handles = tpm_handles.to_cred_data(&mut self.context)?;
  749. let auth = self.storage.cookie.auth();
  750. self.context
  751. .tr_set_auth(key_handles.enc.private.into(), auth.clone())?;
  752. self.context
  753. .tr_set_auth(key_handles.sign.private.into(), auth)?;
  754. self.node_creds = Some(TpmCreds::new(key_handles, state));
  755. Ok(())
  756. }
  757. }
  758. pub struct TpmCredStore {
  759. state: Arc<RwLock<State>>,
  760. storage_path: PathBuf,
  761. cookie: Cookie,
  762. }
  763. impl TpmCredStore {
  764. const SIGN_SCHEME: Sign = Sign::RSA_PSS_2048_SHA_256;
  765. const ENCRYPT_SCHEME: Encrypt = Encrypt::RSA_OAEP_2048_SHA_256;
  766. const DEFAULT_WRITECAP_EXP: Duration = Duration::from_secs(60 * 60 * 24 * 365 * 10);
  767. /// Connects to the TPM via the TPM Access Broker Resource Manager Daemon (TABRMD), as
  768. /// specified by the provided configuration string.
  769. pub fn from_tabrmd(tabrmd_cfg: &str, state_path: PathBuf) -> Result<TpmCredStore> {
  770. let context = Context::new(TctiNameConf::Tabrmd(TabrmdConfig::from_str(tabrmd_cfg)?))?;
  771. Self::from_context(context, state_path)
  772. }
  773. pub fn from_context(mut context: Context, state_path: PathBuf) -> Result<TpmCredStore> {
  774. let storage = Storage::load_or_init(&state_path)?;
  775. let session = context.start_default_auth_session()?;
  776. context.set_sessions((Some(session), None, None));
  777. let cookie = storage.cookie.clone();
  778. let state = Arc::new(RwLock::new(State::new(context, storage)?));
  779. {
  780. let mut guard = state.write().display_err()?;
  781. guard.init_node_creds(&state)?;
  782. }
  783. Ok(TpmCredStore {
  784. state,
  785. storage_path: state_path,
  786. cookie,
  787. })
  788. }
  789. fn save_storage(&self, guard: &mut RwLockWriteGuard<State>) -> Result<()> {
  790. let file = OpenOptions::new().write(true).open(&self.storage_path)?;
  791. let mut writer = BufWriter::new(file);
  792. guard.storage.save(&mut writer)?;
  793. writer.flush()?;
  794. Ok(())
  795. }
  796. fn persist<F: FnOnce(&mut State, StoredCredData)>(
  797. &self,
  798. creds: &TpmCreds,
  799. update_storage: F,
  800. ) -> Result<()> {
  801. let mut guard = self.state.write().display_err()?;
  802. let sign_handle = guard.context.persist_key(creds.sign.private)?;
  803. let enc_handle = match guard.context.persist_key(creds.enc.private) {
  804. Ok(handle) => handle,
  805. Err(error) => {
  806. guard
  807. .context
  808. .evict_key(sign_handle, Some(creds.sign.private))?;
  809. return Err(error);
  810. }
  811. };
  812. let handles = StoredCredData {
  813. sign: creds.sign.to_stored(sign_handle),
  814. enc: creds.enc.to_stored(enc_handle),
  815. writecap: creds.writecap.clone(),
  816. };
  817. update_storage(&mut guard, handles);
  818. match self.save_storage(&mut guard) {
  819. Ok(_) => Ok(()),
  820. Err(error) => {
  821. let result = guard
  822. .context
  823. .evict_key(sign_handle, Some(creds.sign.private));
  824. if let Err(error) = result {
  825. error!("failed to evict signing key due to error: {:?}", error)
  826. }
  827. let result = guard.context.evict_key(enc_handle, Some(creds.enc.private));
  828. if let Err(error) = result {
  829. error!("failed to evict encryption key due to error: {:?}", error)
  830. }
  831. Err(error)
  832. }
  833. }
  834. }
  835. fn get_or_init_storage_key(&self) -> Result<KeyPair<Encrypt>> {
  836. {
  837. let guard = self.state.read().display_err()?;
  838. if let Some(storage_key) = &guard.storage_key {
  839. // We take this path if the storage key was generated and loaded.
  840. return Ok(storage_key.clone());
  841. }
  842. }
  843. {
  844. let mut guard = self.state.write().display_err()?;
  845. if let Some(storage_key) = guard.storage.storage_key.take() {
  846. let result = KeyPair::from_stored(&mut guard.context, &storage_key);
  847. guard.storage.storage_key = Some(storage_key);
  848. // We take this path if the storage key was generated but not loaded.
  849. return result;
  850. }
  851. }
  852. let params = KeyBuilder::for_storage_key(Self::ENCRYPT_SCHEME, self.cookie.as_slice())
  853. .with_parent(Parent::Seed(Hierarchy::Owner))
  854. .with_auth(self.cookie.auth());
  855. let mut guard = self.state.write().display_err()?;
  856. let storage_key = params.build(&mut guard.context)?;
  857. guard.storage_key = Some(storage_key.clone());
  858. let tpm_handle = guard.context.persist_key(storage_key.private)?;
  859. guard.storage.storage_key = Some(storage_key.to_stored(tpm_handle));
  860. if let Err(err) = self.save_storage(&mut guard) {
  861. guard.storage_key = None;
  862. guard.storage.storage_key = None;
  863. guard
  864. .context
  865. .evict_key(tpm_handle, Some(storage_key.private))?;
  866. return Err(err);
  867. }
  868. Ok(storage_key)
  869. }
  870. fn gen_key<S: Scheme>(&self, params: KeyBuilder<S>) -> Result<KeyPair<S>> {
  871. let mut guard = self.state.write().display_err()?;
  872. params.build(&mut guard.context)
  873. }
  874. fn gen_node_sign_key(&self) -> Result<KeyPair<Sign>> {
  875. let params = KeyBuilder::new(Self::SIGN_SCHEME, self.cookie.as_slice())
  876. .with_parent(Parent::Seed(Hierarchy::Owner))
  877. .with_allow_dup(false)
  878. .with_auth(self.cookie.auth());
  879. self.gen_key(params)
  880. }
  881. fn gen_node_enc_key(&self) -> Result<KeyPair<Encrypt>> {
  882. let params = KeyBuilder::new(Self::ENCRYPT_SCHEME, self.cookie.as_slice())
  883. .with_parent(Parent::Seed(Hierarchy::Owner))
  884. .with_allow_dup(false)
  885. .with_auth(self.cookie.auth());
  886. self.gen_key(params)
  887. }
  888. fn gen_node_creds(&self) -> Result<TpmCreds> {
  889. let sign = self.gen_node_sign_key()?;
  890. let enc = self.gen_node_enc_key()?;
  891. let cred_data = CredData {
  892. sign,
  893. enc,
  894. writecap: None,
  895. };
  896. let creds = TpmCreds::new(cred_data, &self.state);
  897. self.persist(&creds, |state, handles| {
  898. state.storage.node = Some(handles);
  899. state.node_creds = Some(creds.clone());
  900. })?;
  901. Ok(creds)
  902. }
  903. fn gen_root_sign_key(&self, password: &str, policy: Digest) -> Result<KeyPair<Sign>> {
  904. let scheme = Self::SIGN_SCHEME;
  905. let unique = rand_vec(scheme.key_len() as usize)?;
  906. let storage_key = self.get_or_init_storage_key()?;
  907. let params = KeyBuilder::new(scheme, unique.as_slice())
  908. .with_parent(Parent::Key(storage_key.private))
  909. .with_allow_dup(true)
  910. .with_auth(password.as_bytes().try_into()?)
  911. .with_policy_digest(policy);
  912. self.gen_key(params)
  913. }
  914. fn gen_root_enc_key(&self, password: &str, policy: Digest) -> Result<KeyPair<Encrypt>> {
  915. let scheme = Self::ENCRYPT_SCHEME;
  916. let unique = rand_vec(scheme.key_len() as usize)?;
  917. let storage_key = self.get_or_init_storage_key()?;
  918. let params = KeyBuilder::new(scheme, unique.as_slice())
  919. .with_parent(Parent::Key(storage_key.private))
  920. .with_allow_dup(true)
  921. .with_auth(password.as_bytes().try_into()?)
  922. .with_policy_digest(policy);
  923. self.gen_key(params)
  924. }
  925. }
  926. impl CredStore for TpmCredStore {
  927. type CredHandle = TpmCreds;
  928. type ExportedCreds = ExportedCreds;
  929. fn node_creds(&self) -> Result<TpmCreds> {
  930. {
  931. let guard = self.state.read().display_err()?;
  932. if let Some(creds) = &guard.node_creds {
  933. return Ok(creds.clone());
  934. }
  935. }
  936. self.gen_node_creds()
  937. }
  938. fn root_creds(&self, password: &str) -> Result<Self::CredHandle> {
  939. let root_handles = {
  940. let guard = self.state.read().display_err()?;
  941. guard
  942. .storage
  943. .root
  944. .as_ref()
  945. .ok_or_else(|| bterr!("root creds have not yet been generated"))?
  946. .clone()
  947. };
  948. let mut guard = self.state.write().display_err()?;
  949. let key_handles = root_handles.to_cred_data(&mut guard.context)?;
  950. guard.context.set_auth(&key_handles, password)?;
  951. Ok(TpmCreds::new(key_handles, &self.state))
  952. }
  953. fn gen_root_creds(&self, password: &str) -> Result<Self::CredHandle> {
  954. {
  955. let guard = self.state.read().display_err()?;
  956. if guard.storage.root.is_some() {
  957. return Err(bterr!("root creds have already been generated"));
  958. }
  959. }
  960. let policy = {
  961. let mut guard = self.state.write().display_err()?;
  962. guard.context.dup_with_password_policy()?
  963. };
  964. let sign = self.gen_root_sign_key(password, policy.clone())?;
  965. let enc = self.gen_root_enc_key(password, policy)?;
  966. let cred_data = CredData {
  967. sign,
  968. enc,
  969. writecap: None,
  970. };
  971. {
  972. let mut guard = self.state.write().display_err()?;
  973. guard.context.set_auth(&cred_data, password)?;
  974. }
  975. let mut creds = TpmCreds::new(cred_data, &self.state);
  976. creds.init_root_writecap(Epoch::now() + Self::DEFAULT_WRITECAP_EXP)?;
  977. self.persist(&creds, |state, handles| state.storage.root = Some(handles))?;
  978. Ok(creds)
  979. }
  980. fn storage_key(&self) -> Result<AsymKeyPub<Encrypt>> {
  981. let pair = self.get_or_init_storage_key()?;
  982. Ok(pair.public)
  983. }
  984. fn export_root_creds(
  985. &self,
  986. root_creds: &TpmCreds,
  987. password: &str,
  988. new_parent: &AsymKeyPub<Encrypt>,
  989. ) -> Result<ExportedCreds> {
  990. let params = DerivationParams::new()?;
  991. let aead_key = params.derive_key(password)?;
  992. let new_parent = new_parent.storage_key_public()?;
  993. let mut guard = self.state.write().display_err()?;
  994. if let Some(storage_key) = guard.storage_key.take() {
  995. // Save memory by flushing the storage key from the TPM's RAM.
  996. guard.context.flush_context(storage_key.private.into())?;
  997. }
  998. let new_parent_handle = guard
  999. .context
  1000. .load_external_public(new_parent, Hierarchy::Null)?;
  1001. let policy_session = guard.context.start_policy_session(IsTrial::False)?;
  1002. let auth = Auth::try_from(password.as_bytes())?;
  1003. let sign = guard.context.export_key(
  1004. &root_creds.sign,
  1005. new_parent_handle,
  1006. auth.clone(),
  1007. policy_session,
  1008. &aead_key,
  1009. )?;
  1010. let enc = guard.context.export_key(
  1011. &root_creds.enc,
  1012. new_parent_handle,
  1013. auth,
  1014. policy_session,
  1015. &aead_key,
  1016. )?;
  1017. Ok(ExportedCreds {
  1018. sign,
  1019. enc,
  1020. params,
  1021. writecap: root_creds.writecap.clone(),
  1022. })
  1023. }
  1024. fn import_root_creds(&self, password: &str, exported: ExportedCreds) -> Result<TpmCreds> {
  1025. let aead_key = exported.params.derive_key(password)?;
  1026. let auth = Auth::try_from(password.as_bytes())?;
  1027. let storage_key = self.get_or_init_storage_key()?;
  1028. let creds = {
  1029. let mut guard = self.state.write().display_err()?;
  1030. let sign = guard.context.import_key(
  1031. exported.sign,
  1032. storage_key.private,
  1033. auth.clone(),
  1034. &aead_key,
  1035. )?;
  1036. let enc =
  1037. guard
  1038. .context
  1039. .import_key(exported.enc, storage_key.private, auth, &aead_key)?;
  1040. let cred_data = CredData {
  1041. sign,
  1042. enc,
  1043. writecap: exported.writecap,
  1044. };
  1045. TpmCreds::new(cred_data, &self.state)
  1046. };
  1047. self.persist(&creds, |state, handles| state.storage.root = Some(handles))?;
  1048. Ok(creds)
  1049. }
  1050. fn assign_node_writecap(
  1051. &self,
  1052. handle: &mut Self::CredHandle,
  1053. writecap: Writecap,
  1054. ) -> Result<()> {
  1055. handle.set_writecap(writecap.clone())?;
  1056. let mut state = self.state.write().display_err()?;
  1057. if let Some(creds) = state.node_creds.as_mut() {
  1058. creds.writecap = Some(writecap.clone());
  1059. }
  1060. if let Some(creds) = state.storage.node.as_mut() {
  1061. creds.writecap = Some(writecap);
  1062. }
  1063. self.save_storage(&mut state)
  1064. }
  1065. fn assign_root_writecap(
  1066. &self,
  1067. handle: &mut Self::CredHandle,
  1068. writecap: Writecap,
  1069. ) -> Result<()> {
  1070. handle.set_writecap(writecap.clone())?;
  1071. let mut state = self.state.write().display_err()?;
  1072. if let Some(creds) = state.storage.root.as_mut() {
  1073. creds.writecap = Some(writecap);
  1074. }
  1075. self.save_storage(&mut state)
  1076. }
  1077. }
  1078. impl<S: Scheme> AsymKeyPub<S> {
  1079. fn try_from(public: Public, scheme: S) -> Result<AsymKeyPub<S>> {
  1080. match public {
  1081. Public::Rsa {
  1082. parameters, unique, ..
  1083. } => {
  1084. let exponent_value = parameters.exponent().value();
  1085. let exponent = BigNum::from_u32(exponent_value)?;
  1086. let modulus = BigNum::from_slice(unique.as_slice())?;
  1087. let rsa = OsslRsa::from_public_components(modulus, exponent)?;
  1088. let pkey = PKey::from_rsa(rsa)?.conv_pub();
  1089. Ok(AsymKey { pkey, scheme })
  1090. }
  1091. key => Err(bterr!("Unsupported key type returned by TPM: {:?}", key)),
  1092. }
  1093. }
  1094. }
  1095. impl AsymKeyPub<Encrypt> {
  1096. fn storage_key_public(&self) -> Result<Public> {
  1097. fn from_rsa(scheme: Encrypt, rsa: openssl::rsa::Rsa<super::Public>) -> Result<Public> {
  1098. let exponent = rsa.e().try_into_u32()?;
  1099. let modulus = rsa.n().to_vec();
  1100. let builder = KeyBuilder::for_storage_key(scheme, &modulus).with_rsa_exponent(exponent);
  1101. builder.rsa_template()
  1102. }
  1103. match self.scheme {
  1104. Encrypt::RsaEsOaep(_) => from_rsa(self.scheme, self.pkey.rsa()?),
  1105. }
  1106. }
  1107. }
  1108. trait NidExt {
  1109. fn sha3_256() -> Nid {
  1110. Nid::from_raw(1097)
  1111. }
  1112. fn sha3_384() -> Nid {
  1113. Nid::from_raw(1098)
  1114. }
  1115. fn sha3_512() -> Nid {
  1116. Nid::from_raw(1099)
  1117. }
  1118. }
  1119. impl NidExt for Nid {}
  1120. trait BigNumRefExt {
  1121. fn try_into_u32(self) -> Result<u32>;
  1122. }
  1123. impl BigNumRefExt for &BigNumRef {
  1124. fn try_into_u32(self) -> Result<u32> {
  1125. let data = self.to_vec();
  1126. if data.len() > 4 {
  1127. return Err(bterr!("data was too long: {}", data.len()));
  1128. }
  1129. let mut buf = [0u8; 4];
  1130. // Note that BigNum data is stored in big endian format, so padding zeros go at the
  1131. // beginning of the buffer.
  1132. let subslice = &mut buf[4 - data.len()..];
  1133. subslice.copy_from_slice(data.as_slice());
  1134. let int = u32::from_be_bytes(buf);
  1135. Ok(int)
  1136. }
  1137. }
  1138. trait MessageDigestExt {
  1139. fn hash_algo(&self) -> Result<HashingAlgorithm>;
  1140. fn hash_scheme(&self) -> Result<HashScheme> {
  1141. Ok(HashScheme::new(self.hash_algo()?))
  1142. }
  1143. }
  1144. impl MessageDigestExt for MessageDigest {
  1145. fn hash_algo(&self) -> Result<HashingAlgorithm> {
  1146. let nid = self.type_();
  1147. let algo = if Nid::SHA1 == nid {
  1148. HashingAlgorithm::Sha1
  1149. } else if Nid::SHA256 == nid {
  1150. HashingAlgorithm::Sha256
  1151. } else if Nid::SHA384 == nid {
  1152. HashingAlgorithm::Sha384
  1153. } else if Nid::SHA512 == nid {
  1154. HashingAlgorithm::Sha512
  1155. } else if Nid::sha3_256() == nid {
  1156. HashingAlgorithm::Sha3_256
  1157. } else if Nid::sha3_384() == nid {
  1158. HashingAlgorithm::Sha3_384
  1159. } else if Nid::sha3_512() == nid {
  1160. HashingAlgorithm::Sha3_512
  1161. } else {
  1162. return Err(bterr!("Unsupported hash algorithm with NID: {:?}", nid));
  1163. };
  1164. Ok(algo)
  1165. }
  1166. }
  1167. trait HashcheckTicketExt {
  1168. fn null() -> HashcheckTicket;
  1169. }
  1170. impl HashcheckTicketExt for HashcheckTicket {
  1171. /// Returns the NULL Ticket of the hashcheck type, as defined in part 1 of the TPM spec,
  1172. /// clause 4.47.
  1173. fn null() -> HashcheckTicket {
  1174. TPMT_TK_HASHCHECK {
  1175. tag: HashcheckTicket::POSSIBLE_TAGS[0].into(),
  1176. digest: Default::default(),
  1177. hierarchy: TPM2_RH_NULL,
  1178. }
  1179. .try_into()
  1180. .unwrap()
  1181. }
  1182. }
  1183. #[derive(Clone)]
  1184. pub struct TpmCreds {
  1185. state: Arc<RwLock<State>>,
  1186. sign: KeyPair<Sign>,
  1187. enc: KeyPair<Encrypt>,
  1188. writecap: Option<Writecap>,
  1189. }
  1190. impl TpmCreds {
  1191. fn new(key_handles: CredData, state: &Arc<RwLock<State>>) -> TpmCreds {
  1192. TpmCreds {
  1193. sign: key_handles.sign,
  1194. enc: key_handles.enc,
  1195. state: state.clone(),
  1196. writecap: key_handles.writecap,
  1197. }
  1198. }
  1199. fn init_root_writecap(&mut self, expires: Epoch) -> Result<()> {
  1200. let writecap = self.issue_writecap(self.principal(), Vec::new(), expires)?;
  1201. self.writecap = Some(writecap);
  1202. Ok(())
  1203. }
  1204. fn set_writecap(&mut self, writecap: Writecap) -> Result<()> {
  1205. writecap.assert_issued_to(&self.principal())?;
  1206. self.writecap = Some(writecap);
  1207. Ok(())
  1208. }
  1209. }
  1210. impl Principaled for TpmCreds {
  1211. fn principal_of_kind(&self, kind: HashKind) -> Principal {
  1212. self.sign.public.principal_of_kind(kind)
  1213. }
  1214. }
  1215. impl Verifier for TpmCreds {
  1216. fn init_verify(&self) -> Result<Box<dyn '_ + VerifyOp>> {
  1217. self.sign.public.init_verify()
  1218. }
  1219. fn verify(&self, parts: &mut dyn Iterator<Item = &[u8]>, signature: &[u8]) -> Result<()> {
  1220. self.sign.public.verify(parts, signature)
  1221. }
  1222. fn kind(&self) -> Sign {
  1223. self.sign.public.kind()
  1224. }
  1225. }
  1226. impl Encrypter for TpmCreds {
  1227. fn encrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
  1228. self.enc.public.encrypt(slice)
  1229. }
  1230. }
  1231. impl CredsPub for TpmCreds {
  1232. fn public_sign(&self) -> &AsymKeyPub<Sign> {
  1233. &self.sign.public
  1234. }
  1235. fn concrete_pub(&self) -> ConcretePub {
  1236. ConcretePub {
  1237. sign: self.sign.public.clone(),
  1238. enc: self.enc.public.clone(),
  1239. }
  1240. }
  1241. }
  1242. pub struct TpmSignOp<'a> {
  1243. op: VarHashOp,
  1244. creds: &'a TpmCreds,
  1245. }
  1246. impl<'a> TpmSignOp<'a> {
  1247. pub fn new(arg: &'a TpmCreds) -> Result<Self> {
  1248. let op = VarHashOp::new(arg.sign.public.scheme.hash_kind())?;
  1249. Ok(TpmSignOp { op, creds: arg })
  1250. }
  1251. }
  1252. impl<'a> Op for TpmSignOp<'a> {
  1253. fn update(&mut self, data: &[u8]) -> Result<()> {
  1254. self.op.update(data)
  1255. }
  1256. fn finish_into(&mut self, buf: &mut [u8]) -> Result<usize> {
  1257. let hash = self.op.finish()?;
  1258. let digest = Digest::try_from(hash.as_ref())?;
  1259. let validation = HashcheckTicket::null();
  1260. // Null means the scheme used during key creation will be used.
  1261. let scheme = SignatureScheme::Null;
  1262. let sig = {
  1263. let mut guard = self.creds.state.write().display_err()?;
  1264. guard
  1265. .context
  1266. .sign(self.creds.sign.private, digest, scheme, validation)?
  1267. };
  1268. let slice: &[u8] = match &sig {
  1269. tss_esapi::structures::Signature::RsaSsa(inner) => inner.signature(),
  1270. tss_esapi::structures::Signature::RsaPss(inner) => inner.signature(),
  1271. _ => return Err(bterr!("Unexpected signature type: {:?}", sig.algorithm())),
  1272. };
  1273. if buf.len() < slice.len() {
  1274. return Err(bterr!(Error::IncorrectSize {
  1275. expected: slice.len(),
  1276. actual: buf.len(),
  1277. }));
  1278. }
  1279. buf.copy_from_slice(slice);
  1280. Ok(slice.len())
  1281. }
  1282. }
  1283. impl<'a> SignOp for TpmSignOp<'a> {
  1284. fn scheme(&self) -> Sign {
  1285. self.creds.sign.public.scheme
  1286. }
  1287. }
  1288. impl Signer for TpmCreds {
  1289. fn init_sign(&self) -> Result<Box<dyn '_ + SignOp>> {
  1290. Ok(Box::new(TpmSignOp::new(self)?))
  1291. }
  1292. fn sign(&self, parts: &mut dyn Iterator<Item = &[u8]>) -> Result<Signature> {
  1293. let mut op = self.init_sign()?;
  1294. for part in parts {
  1295. op.update(part)?;
  1296. }
  1297. op.finish()
  1298. }
  1299. fn kind(&self) -> Sign {
  1300. self.sign.public.kind()
  1301. }
  1302. }
  1303. impl Decrypter for TpmCreds {
  1304. fn decrypt(&self, slice: &[u8]) -> Result<Vec<u8>> {
  1305. let cipher_text = PublicKeyRsa::try_from(slice)?;
  1306. // Null means the scheme used during key creation will be used.
  1307. let in_scheme = RsaDecryptionScheme::Null;
  1308. let empty = [0u8; 0];
  1309. let label = Data::try_from(empty.as_slice())?;
  1310. let plain_text = {
  1311. let mut guard = self.state.write().display_err()?;
  1312. guard
  1313. .context
  1314. .rsa_decrypt(self.enc.private, cipher_text, in_scheme, label)?
  1315. };
  1316. Ok(Vec::from(plain_text.value()))
  1317. }
  1318. }
  1319. impl CredsPriv for TpmCreds {
  1320. fn writecap(&self) -> Option<&Writecap> {
  1321. self.writecap.as_ref()
  1322. }
  1323. }
  1324. trait TctiNameConfExt {
  1325. fn default() -> TctiNameConf;
  1326. }
  1327. impl TctiNameConfExt for TctiNameConf {
  1328. /// Returns a configuration which specifies that Tabrmd should be connected to using the system
  1329. /// DBus.
  1330. fn default() -> TctiNameConf {
  1331. TctiNameConf::Tabrmd(TabrmdConfig::default())
  1332. }
  1333. }
  1334. #[link(name = "tss2-rc")]
  1335. extern "C" {
  1336. fn Tss2_RC_Decode(rc: TSS2_RC) -> *const c_char;
  1337. }
  1338. /// Interface for types which can be converted to TSS2 response codes.
  1339. trait HasResponseCode {
  1340. /// Returns the TSS2 response code associated with this instance.
  1341. fn tss2_rc(&self) -> TSS2_RC;
  1342. }
  1343. /// Returns the error message associated with the given TSS2 response code.
  1344. fn tss2_rc_decode<E: HasResponseCode>(err: E) -> &'static str {
  1345. let c_str = unsafe {
  1346. let ptr = Tss2_RC_Decode(err.tss2_rc());
  1347. CStr::from_ptr(ptr)
  1348. };
  1349. // We're relying on Tss2_RC_Decode to return valid C strings.
  1350. c_str.to_str().unwrap()
  1351. }
  1352. impl HasResponseCode for Tss2ResponseCode {
  1353. fn tss2_rc(&self) -> TSS2_RC {
  1354. match self {
  1355. Tss2ResponseCode::Success => 0,
  1356. Tss2ResponseCode::FormatZero(code) => code.0,
  1357. Tss2ResponseCode::FormatOne(code) => code.0,
  1358. }
  1359. }
  1360. }
  1361. impl HasResponseCode for TSS2_RC {
  1362. fn tss2_rc(&self) -> TSS2_RC {
  1363. *self
  1364. }
  1365. }
  1366. #[cfg(test)]
  1367. mod test {
  1368. use super::*;
  1369. use crate::{error::AnyhowErrorExt, test_helpers::BtCursor};
  1370. use ctor::ctor;
  1371. use std::{fs::File, io::SeekFrom};
  1372. use swtpm_harness::SwtpmHarness;
  1373. use tss_esapi::{
  1374. interface_types::ecc::EccCurve,
  1375. structures::{EccPoint, EccScheme, KeyDerivationFunctionScheme, PublicEccParameters},
  1376. };
  1377. #[ctor]
  1378. fn ctor() {
  1379. env_logger::init();
  1380. }
  1381. /// Displays the message associated with a TSS2 return code.
  1382. //#[test]
  1383. #[allow(dead_code)]
  1384. fn print_error_message() {
  1385. const RC: TSS2_RC = 2461;
  1386. let msg = tss2_rc_decode(RC);
  1387. println!("{}", msg);
  1388. }
  1389. #[test]
  1390. fn create_context() {
  1391. let harness = SwtpmHarness::new().unwrap();
  1392. harness.context().unwrap().self_test(true).unwrap();
  1393. }
  1394. #[test]
  1395. fn create_primary_key() {
  1396. let harness = SwtpmHarness::new().unwrap();
  1397. let mut context = harness.context().unwrap();
  1398. let public = {
  1399. let object_attributes = ObjectAttributes::builder()
  1400. .with_fixed_tpm(true)
  1401. .with_fixed_parent(true)
  1402. .with_sensitive_data_origin(true)
  1403. .with_user_with_auth(true)
  1404. .with_decrypt(false)
  1405. .with_sign_encrypt(true)
  1406. .with_restricted(false)
  1407. .build()
  1408. .expect("ObjectAttributesBuilder failed");
  1409. let name_hashing_algorithm = HashingAlgorithm::Sha256;
  1410. let empty = [0u8; 0];
  1411. let auth_policy = Digest::try_from(empty.as_slice()).unwrap();
  1412. let parameters = PublicEccParameters::new(
  1413. SymmetricDefinitionObject::Null,
  1414. EccScheme::EcDsa(HashScheme::new(HashingAlgorithm::Sha256)),
  1415. EccCurve::NistP256,
  1416. KeyDerivationFunctionScheme::Null,
  1417. );
  1418. Public::Ecc {
  1419. object_attributes,
  1420. name_hashing_algorithm,
  1421. auth_policy,
  1422. parameters,
  1423. unique: EccPoint::default(),
  1424. }
  1425. };
  1426. let session = context
  1427. .start_auth_session(
  1428. None,
  1429. None,
  1430. None,
  1431. SessionType::Hmac,
  1432. SymmetricDefinition::AES_256_CFB,
  1433. HashingAlgorithm::Sha256,
  1434. )
  1435. .expect("Failed to create session")
  1436. .expect("Received invalid handle");
  1437. context.execute_with_session(Some(session), |ctx| {
  1438. let primary = ctx
  1439. .create_primary(Hierarchy::Null, public, None, None, None, None)
  1440. .expect("create_primary failed")
  1441. .key_handle;
  1442. ctx.flush_context(primary.into())
  1443. .expect("flush_context failed");
  1444. });
  1445. }
  1446. /// Tests that a TPM Credential Store can be created when a cookie does not already exist.
  1447. #[test]
  1448. fn tpm_cred_store_new() -> Result<()> {
  1449. let harness = SwtpmHarness::new().bterr()?;
  1450. let cookie_path = harness.dir_path().join("cookie.bin");
  1451. let store = TpmCredStore::from_context(harness.context()?, cookie_path.to_owned())?;
  1452. let cookie = File::open(&cookie_path)?;
  1453. let metadata = cookie.metadata()?;
  1454. let actual = metadata.permissions().mode();
  1455. // Assert that the cookie can only be read by its owner.
  1456. assert_eq!(0o600, 0o777 & actual);
  1457. drop(store);
  1458. Ok(())
  1459. }
  1460. #[test]
  1461. fn gen_creds() -> Result<()> {
  1462. let harness = SwtpmHarness::new().bterr()?;
  1463. let cookie_path = harness.dir_path().join("cookie.bin");
  1464. let store = TpmCredStore::from_context(harness.context()?, cookie_path)?;
  1465. store.gen_node_creds()?;
  1466. Ok(())
  1467. }
  1468. /// Displays the numeric identifiers used by the supported hash algorithms.
  1469. //#[test]
  1470. #[allow(dead_code)]
  1471. fn show_nids() {
  1472. fn show_nid(digest: MessageDigest) {
  1473. let nid = digest.type_();
  1474. println!("{}: {:?}", nid.long_name().unwrap(), nid);
  1475. }
  1476. show_nid(MessageDigest::sha1());
  1477. show_nid(MessageDigest::sha256());
  1478. show_nid(MessageDigest::sha384());
  1479. show_nid(MessageDigest::sha512());
  1480. show_nid(MessageDigest::sha3_256());
  1481. show_nid(MessageDigest::sha3_384());
  1482. show_nid(MessageDigest::sha3_512());
  1483. }
  1484. /// Verifies that the NIDs returned by the supported hash algorithms are as expected.
  1485. #[test]
  1486. fn verify_expected_nids() {
  1487. fn assert_eq(digest: MessageDigest, nid: Nid) {
  1488. assert_eq!(digest.type_(), nid);
  1489. }
  1490. assert_eq(MessageDigest::sha1(), Nid::SHA1);
  1491. assert_eq(MessageDigest::sha256(), Nid::SHA256);
  1492. assert_eq(MessageDigest::sha384(), Nid::SHA384);
  1493. assert_eq(MessageDigest::sha512(), Nid::SHA512);
  1494. assert_eq(MessageDigest::sha3_256(), Nid::sha3_256());
  1495. assert_eq(MessageDigest::sha3_384(), Nid::sha3_384());
  1496. assert_eq(MessageDigest::sha3_512(), Nid::sha3_512());
  1497. }
  1498. /// Returns a SwtpmHarness and a TpmCredStore that uses it. Note that the order of the entries
  1499. /// in the returned tuple is significant, as TpmCredStore must be dropped _before_ SwtpmHarness.
  1500. fn test_store() -> Result<(SwtpmHarness, TpmCredStore)> {
  1501. let harness = SwtpmHarness::new().bterr()?;
  1502. let store =
  1503. TpmCredStore::from_context(harness.context()?, harness.state_path().to_owned())?;
  1504. Ok((harness, store))
  1505. }
  1506. fn sign_verify_test(creds: &TpmCreds) -> Result<()> {
  1507. let data: [u8; 1024] = rand_array()?;
  1508. let parts = [data.as_slice()];
  1509. let sig = creds.sign(&mut parts.into_iter())?;
  1510. return creds.verify(&mut parts.into_iter(), sig.as_slice());
  1511. }
  1512. #[test]
  1513. fn tpm_sign_verify() -> Result<()> {
  1514. let (_harness, store) = test_store()?;
  1515. let creds = store.gen_node_creds()?;
  1516. sign_verify_test(&creds)
  1517. }
  1518. fn encrypt_decrypt_test(creds: &TpmCreds) -> Result<()> {
  1519. let expected: [u8; Cookie::LEN / 2] = rand_array()?;
  1520. let ct = creds.encrypt(expected.as_slice())?;
  1521. let actual = creds.decrypt(&ct)?;
  1522. if expected.as_slice() == actual {
  1523. Ok(())
  1524. } else {
  1525. Err(bterr!("decrypted data did not match input"))
  1526. }
  1527. }
  1528. #[test]
  1529. fn tpm_encrypt_decrypt() -> Result<()> {
  1530. let (_harness, store) = test_store()?;
  1531. let creds = store.gen_node_creds()?;
  1532. encrypt_decrypt_test(&creds)
  1533. }
  1534. /// Tests that `HashcheckTicket::null` doesn't panic.
  1535. #[test]
  1536. fn hashcheck_null() {
  1537. HashcheckTicket::null();
  1538. }
  1539. #[test]
  1540. fn persistent_handles() -> Result<()> {
  1541. let harness = SwtpmHarness::new().bterr()?;
  1542. let mut context = harness.context()?;
  1543. context.persistent_handles()?;
  1544. Ok(())
  1545. }
  1546. #[test]
  1547. fn first_free_persistent() -> Result<()> {
  1548. let harness = SwtpmHarness::new().bterr()?;
  1549. let mut context = harness.context()?;
  1550. context.unused_persistent_primary_key()?;
  1551. Ok(())
  1552. }
  1553. #[test]
  1554. fn persist_key() -> Result<()> {
  1555. let (_harness, store) = test_store()?;
  1556. let cookie = Cookie::random()?;
  1557. let params = KeyBuilder::new(Sign::RSA_PSS_3072_SHA_256, cookie.as_slice());
  1558. let pair = store.gen_key(params)?;
  1559. let mut guard = store.state.write().display_err()?;
  1560. guard.context.persist_key(pair.private)?;
  1561. Ok(())
  1562. }
  1563. /// Tests that the same node key is returned by after a cred store is dropped and recreated.
  1564. #[test]
  1565. fn node_key_persisted() -> Result<()> {
  1566. let (harness, store) = test_store()?;
  1567. let expected = {
  1568. let creds = store.node_creds()?;
  1569. creds.principal()
  1570. };
  1571. drop(store);
  1572. let store =
  1573. TpmCredStore::from_context(harness.context()?, harness.state_path().to_owned())?;
  1574. let creds = store.node_creds()?;
  1575. let actual = creds.principal();
  1576. assert_eq!(expected, actual);
  1577. sign_verify_test(&creds)?;
  1578. encrypt_decrypt_test(&creds)?;
  1579. Ok(())
  1580. }
  1581. #[test]
  1582. fn root_key_can_be_used_after_generation() {
  1583. let (_harness, store) = test_store().expect("failed to make test store");
  1584. let creds = store
  1585. .gen_root_creds(&"TimeInvariant")
  1586. .expect("failed to gen root creds");
  1587. let data = [1u8; 32];
  1588. creds
  1589. .sign(&mut std::iter::once(data.as_slice()))
  1590. .expect("sign failed");
  1591. }
  1592. #[test]
  1593. fn root_and_node_keys_generated() {
  1594. let (_harness, store) = test_store().expect("failed to make test store");
  1595. let _root_creds = store
  1596. .gen_root_creds(&"TranslationInvariant")
  1597. .expect("failed to gen root creds");
  1598. let _node_creds = store.node_creds().expect("failed to gen node creds");
  1599. }
  1600. #[test]
  1601. fn verify_root_writecap() {
  1602. let (_harness, store) = test_store().expect("failed to make test store");
  1603. let root_creds = store
  1604. .gen_root_creds(&"TranslationInvariant")
  1605. .expect("failed to gen root creds");
  1606. let writecap = root_creds.writecap().expect("no root writecap was present");
  1607. let path = crate::BlockPath::new(root_creds.principal(), Vec::new());
  1608. writecap
  1609. .assert_valid_for(&path)
  1610. .expect("failed to verify root writecap");
  1611. }
  1612. #[test]
  1613. fn issue_writecap_to_node() {
  1614. let (_harness, store) = test_store().expect("failed to make test store");
  1615. let root_creds = store
  1616. .gen_root_creds(&"TranslationInvariant")
  1617. .expect("failed to gen root creds");
  1618. let path = crate::BlockPath::new(
  1619. root_creds.principal(),
  1620. vec!["apps".to_string(), "comms".to_string()],
  1621. );
  1622. let node_creds = store.node_creds().expect("failed to gen node creds");
  1623. let writecap = root_creds
  1624. .issue_writecap(
  1625. node_creds.principal(),
  1626. path.components().map(|e| e.to_string()).collect(),
  1627. Epoch::now() + Duration::from_secs(3600),
  1628. )
  1629. .expect("failed to issue writecap");
  1630. writecap
  1631. .assert_valid_for(&path)
  1632. .expect("failed to verify writecap");
  1633. }
  1634. #[test]
  1635. fn root_key_persisted() -> Result<()> {
  1636. const PASSWORD: &str = "Scaramouch";
  1637. let (harness, store) = test_store()?;
  1638. let expected = {
  1639. let creds = store.gen_root_creds(PASSWORD)?;
  1640. creds.principal()
  1641. };
  1642. drop(store);
  1643. let store =
  1644. TpmCredStore::from_context(harness.context()?, harness.state_path().to_owned())?;
  1645. let creds = store.root_creds(PASSWORD)?;
  1646. let actual = creds.principal();
  1647. assert_eq!(expected, actual);
  1648. sign_verify_test(&creds)?;
  1649. encrypt_decrypt_test(&creds)?;
  1650. Ok(())
  1651. }
  1652. #[test]
  1653. fn root_key_unusable_when_password_wrong() -> Result<()> {
  1654. let (harness, store) = test_store()?;
  1655. store.gen_root_creds("Galileo")?;
  1656. drop(store);
  1657. let store =
  1658. TpmCredStore::from_context(harness.context()?, harness.state_path().to_owned())?;
  1659. let creds = store.root_creds("Figaro")?;
  1660. assert!(sign_verify_test(&creds).is_err());
  1661. assert!(encrypt_decrypt_test(&creds).is_err());
  1662. Ok(())
  1663. }
  1664. #[test]
  1665. fn root_key_export_import() {
  1666. const PASSWORD: &str = "Frobinate";
  1667. let (_src_harness, src_store) = test_store().unwrap();
  1668. let src_root_creds = src_store.gen_root_creds(PASSWORD).unwrap();
  1669. let (_dest_harness, dest_store) = test_store().unwrap();
  1670. let dest_storage_key = dest_store.storage_key().unwrap();
  1671. let exported = src_store
  1672. .export_root_creds(&src_root_creds, PASSWORD, &dest_storage_key)
  1673. .unwrap();
  1674. let vec = to_vec(&exported).unwrap();
  1675. let mut slice = vec.as_slice();
  1676. let exported = read_from(&mut slice).unwrap();
  1677. let dest_root_creds = dest_store.import_root_creds(PASSWORD, exported).unwrap();
  1678. let message = rand_vec(TpmCredStore::ENCRYPT_SCHEME.key_len() as usize / 2).unwrap();
  1679. let sig = dest_root_creds
  1680. .sign(&mut [message.as_slice()].into_iter())
  1681. .unwrap();
  1682. src_root_creds
  1683. .verify(&mut [message.as_slice()].into_iter(), sig.as_slice())
  1684. .unwrap();
  1685. let ct = src_root_creds.encrypt(message.as_slice()).unwrap();
  1686. let pt = dest_root_creds.decrypt(ct.as_slice()).unwrap();
  1687. assert_eq!(message.as_slice(), pt.as_slice());
  1688. }
  1689. /// Tests that a signature computed using a `TpmSignOp` can be verified.
  1690. #[test]
  1691. fn sign_write_can_be_verified() {
  1692. const LEN: usize = 512;
  1693. let cursor = BtCursor::new([0u8; LEN]);
  1694. let (_harness, store) = test_store().unwrap();
  1695. let creds = store.gen_node_creds().expect("gen_node_creds failed");
  1696. let sign_op = creds.init_sign().expect("init_sign failed");
  1697. let mut sign_wrap = SignWrite::new(cursor, sign_op);
  1698. let part_values = (1..9u8).map(|k| [k; LEN / 8]).collect::<Vec<_>>();
  1699. let get_parts = || part_values.iter().map(|arr| arr.as_slice());
  1700. for part in get_parts() {
  1701. sign_wrap.write(part).expect("write failed");
  1702. }
  1703. let (sig, ..) = sign_wrap.finish().expect("finish failed");
  1704. creds
  1705. .verify(&mut get_parts(), sig.as_ref())
  1706. .expect("verify failed");
  1707. }
  1708. /// Tests that data written into a `SignWrite` using a `TpmSignOp` and later read from a
  1709. /// `VerifyRead` using a `OsslVerifyOp` can be successfully verified.
  1710. #[test]
  1711. fn sign_write_then_verify_read() {
  1712. use std::io::Seek;
  1713. const LEN: usize = 512;
  1714. let cursor = BtCursor::new([0u8; LEN]);
  1715. let (_harness, store) = test_store().unwrap();
  1716. let creds = store.gen_node_creds().expect("gen_node_creds failed");
  1717. let sign_op = creds.init_sign().expect("init_sign failed");
  1718. let mut sign_wrap = SignWrite::new(cursor, sign_op);
  1719. for part in (1..9u8).map(|k| [k; LEN / 8]) {
  1720. sign_wrap.write(part.as_slice()).expect("write failed");
  1721. }
  1722. let (sig, mut cursor) = sign_wrap.finish().expect("finish failed");
  1723. cursor.seek(SeekFrom::Start(0)).expect("seek failed");
  1724. let verify_op = creds.init_verify().expect("init_verify failed");
  1725. let mut verify_read = VerifyRead::new(cursor, verify_op);
  1726. let mut buf = Vec::with_capacity(LEN);
  1727. verify_read
  1728. .read_to_end(&mut buf)
  1729. .expect("read_to_end failed");
  1730. verify_read
  1731. .finish(sig.as_ref())
  1732. .expect("failed to verify signature");
  1733. }
  1734. /// This test is broken for unknown reasons. It passes if no inner encryption key is supplied.
  1735. /// To work-around this issue I've chosen to wrap the data returned by `duplicate` with a
  1736. /// symmetric key in software.
  1737. //#[test]
  1738. #[allow(dead_code)]
  1739. fn key_export_import() -> Result<()> {
  1740. let auth = Auth::try_from(vec![0u8; 32])?;
  1741. let src_harness = SwtpmHarness::new().bterr()?;
  1742. let mut src_ctx = src_harness.context()?;
  1743. {
  1744. let session = src_ctx.start_default_auth_session()?;
  1745. src_ctx.set_sessions((Some(session), None, None));
  1746. }
  1747. let src_storage = {
  1748. let unique = [0u8; 0];
  1749. KeyBuilder::for_storage_key(Encrypt::RSA_OAEP_2048_SHA_256, unique.as_slice())
  1750. .with_parent(Parent::Seed(Hierarchy::Owner))
  1751. .with_auth(auth.clone())
  1752. .build(&mut src_ctx)?
  1753. .private
  1754. };
  1755. let dest_harness = SwtpmHarness::new().bterr()?;
  1756. let mut dest_ctx = dest_harness.context()?;
  1757. {
  1758. let session = dest_ctx.start_default_auth_session()?;
  1759. dest_ctx.set_sessions((Some(session), None, None));
  1760. }
  1761. let dest_storage = {
  1762. let unique = [0u8; 0];
  1763. KeyBuilder::for_storage_key(Encrypt::RSA_OAEP_2048_SHA_256, unique.as_slice())
  1764. .with_parent(Parent::Seed(Hierarchy::Owner))
  1765. .with_auth(auth.clone())
  1766. .build(&mut dest_ctx)?
  1767. .private
  1768. };
  1769. let key_handle = {
  1770. let policy = src_ctx.dup_with_password_policy()?;
  1771. let unique = rand_array::<256>()?;
  1772. KeyBuilder::new(Sign::RSA_PSS_2048_SHA_256, unique.as_slice())
  1773. .with_parent(Parent::Key(src_storage))
  1774. .with_allow_dup(true)
  1775. .with_policy_digest(policy)
  1776. .build(&mut src_ctx)?
  1777. .private
  1778. };
  1779. let new_parent = {
  1780. let (public, ..) = dest_ctx.read_public(dest_storage)?;
  1781. src_ctx.load_external_public(public, Hierarchy::Owner)?
  1782. };
  1783. let (public, ..) = src_ctx.read_public(key_handle)?;
  1784. let encryption_key = Data::try_from(vec![7u8; 16])?;
  1785. let (_, private, secret) = {
  1786. let session = src_ctx.start_policy_session(IsTrial::False)?;
  1787. let result: Result<()> = src_ctx.execute_with_session(None, |ctx| {
  1788. ctx.policy_password(session)?;
  1789. ctx.policy_command_code(session, CommandCode::Duplicate)?;
  1790. Ok(())
  1791. });
  1792. result?;
  1793. src_ctx
  1794. .execute_with_session(Some(session.into()), |ctx| {
  1795. ctx.duplicate(
  1796. key_handle.into(),
  1797. new_parent.into(),
  1798. Some(encryption_key.clone()),
  1799. SymmetricDefinitionObject::AES_128_CFB,
  1800. )
  1801. })
  1802. .unwrap()
  1803. };
  1804. dest_ctx
  1805. .import(
  1806. dest_storage.into(),
  1807. Some(encryption_key),
  1808. public,
  1809. private,
  1810. secret,
  1811. SymmetricDefinitionObject::AES_128_CFB,
  1812. )
  1813. .unwrap();
  1814. Ok(())
  1815. }
  1816. /// Ensures that the [Writecap] assigned to the node credentials using one instance of
  1817. /// [TpmCredStore] is available from another.
  1818. #[test]
  1819. fn node_writecap_persisted() {
  1820. let (harness, store) = test_store().unwrap();
  1821. let expected = {
  1822. let root_creds = store.gen_root_creds("TURTLES").unwrap();
  1823. let mut node_creds = store.node_creds().unwrap();
  1824. let expires = Epoch::now() + Duration::from_secs(3600);
  1825. let expected = root_creds
  1826. .issue_writecap(node_creds.principal(), vec![], expires)
  1827. .unwrap();
  1828. store
  1829. .assign_node_writecap(&mut node_creds, expected.clone())
  1830. .unwrap();
  1831. assert_eq!(&expected, node_creds.writecap().unwrap());
  1832. expected
  1833. };
  1834. let store =
  1835. TpmCredStore::from_tabrmd(harness.tabrmd_config(), harness.state_path().to_owned())
  1836. .unwrap();
  1837. let node_creds = store.node_creds().unwrap();
  1838. let actual = node_creds.writecap().unwrap();
  1839. assert_eq!(&expected, actual);
  1840. }
  1841. /// Tests that the [Writecap] for the root credentials is persisted across different instances
  1842. /// of [TpmCredStore].
  1843. #[test]
  1844. fn root_writecap_persisted() {
  1845. const PASSWORD: &str = "SuddenUnscheduledDisassembly";
  1846. let (harness, store) = test_store().unwrap();
  1847. let expected = {
  1848. let mut root_creds = store.gen_root_creds(PASSWORD).unwrap();
  1849. let expires = Epoch::now() + Duration::from_secs(3600);
  1850. let expected = root_creds
  1851. .issue_writecap(root_creds.principal(), vec![], expires)
  1852. .unwrap();
  1853. store
  1854. .assign_root_writecap(&mut root_creds, expected.clone())
  1855. .unwrap();
  1856. assert_eq!(&expected, root_creds.writecap().unwrap());
  1857. expected
  1858. };
  1859. let store =
  1860. TpmCredStore::from_context(harness.context().unwrap(), harness.state_path().to_owned())
  1861. .unwrap();
  1862. let root_creds = store.root_creds(PASSWORD).unwrap();
  1863. let actual = root_creds.writecap().unwrap();
  1864. assert_eq!(&expected, actual);
  1865. }
  1866. /// Checks that when a writecap is assigned to the node creds it is present in a subsequently
  1867. /// returned instance of the node creds.
  1868. #[test]
  1869. fn writecap_present_in_subsequent_node_creds() {
  1870. let (_harness, store) = test_store().unwrap();
  1871. let expected = {
  1872. let root_creds = store.gen_root_creds("POWER").unwrap();
  1873. let mut node_creds = store.node_creds().unwrap();
  1874. let expires = Epoch::now() + Duration::from_secs(3600);
  1875. let writecap = root_creds
  1876. .issue_writecap(node_creds.principal(), vec![], expires)
  1877. .unwrap();
  1878. store
  1879. .assign_node_writecap(&mut node_creds, writecap.clone())
  1880. .unwrap();
  1881. writecap
  1882. };
  1883. let node_creds = store.node_creds().unwrap();
  1884. let actual = node_creds.writecap().unwrap();
  1885. assert_eq!(&expected, actual);
  1886. }
  1887. /// Tests that multiple instance of the node creds can be requested from the [TpmCredStore] with
  1888. /// overlapping lifetimes.
  1889. #[test]
  1890. fn multiple_node_creds_can_coexist() {
  1891. let (_harness, store) = test_store().unwrap();
  1892. let first = store.node_creds().unwrap();
  1893. let second = store.node_creds().unwrap();
  1894. assert_eq!(first.concrete_pub(), second.concrete_pub());
  1895. }
  1896. }