tpm.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. use std::{
  2. os::raw::c_char,
  3. ffi::CStr,
  4. };
  5. use tss_esapi::constants::response_code::Tss2ResponseCode;
  6. use tss_esapi_sys::TSS2_RC;
  7. #[link(name = "tss2-rc")]
  8. extern {
  9. fn Tss2_RC_Decode(rc: TSS2_RC) -> *const c_char;
  10. }
  11. trait HasResponseCode {
  12. fn response_code(&self) -> TSS2_RC;
  13. }
  14. fn tss2_rc_decode<E: HasResponseCode>(err: E) -> &'static str {
  15. let c_str = unsafe {
  16. let ptr = Tss2_RC_Decode(err.response_code());
  17. CStr::from_ptr(ptr)
  18. };
  19. // We're relying on Tss2_RC_Decode to return valid C strings.
  20. c_str.to_str().unwrap()
  21. }
  22. impl HasResponseCode for Tss2ResponseCode {
  23. fn response_code(&self) -> TSS2_RC {
  24. match self {
  25. Tss2ResponseCode::Success => 0,
  26. Tss2ResponseCode::FormatZero(code) => code.0,
  27. Tss2ResponseCode::FormatOne(code) => code.0,
  28. }
  29. }
  30. }
  31. trait Tss2Expect<T> {
  32. /// Provides an enhanced error message for types which contain TSS2 response codes.
  33. fn tss2_expect(self, err_msg: &str) -> T;
  34. }
  35. impl<T> Tss2Expect<T> for tss_esapi::Result<T> {
  36. fn tss2_expect(self, err_msg: &str) -> T {
  37. match self {
  38. tss_esapi::Result::Ok(val) => val,
  39. tss_esapi::Result::Err(err) => {
  40. match err {
  41. tss_esapi::Error::WrapperError(err) => panic!("{}: {}", err_msg, err),
  42. tss_esapi::Error::Tss2Error(err) => {
  43. let rc = err.response_code();
  44. let text = tss2_rc_decode(err);
  45. panic!("{}, response code: {}, response text: {}", err_msg, rc, text);
  46. }
  47. }
  48. },
  49. }
  50. }
  51. }
  52. #[cfg(test)]
  53. mod test {
  54. use super::*;
  55. use tss_esapi::{
  56. Context,
  57. constants::{
  58. session_type::{SessionType},
  59. },
  60. tcti_ldr::{TabrmdConfig},
  61. interface_types::{
  62. resource_handles::{Hierarchy},
  63. algorithm::{HashingAlgorithm},
  64. ecc::{EccCurve},
  65. },
  66. structures::{
  67. Digest,
  68. EccPoint,
  69. EccScheme,
  70. KeyDerivationFunctionScheme,
  71. HashScheme,
  72. Public,
  73. PublicEccParameters,
  74. SymmetricDefinition,
  75. SymmetricDefinitionObject,
  76. },
  77. attributes::{
  78. object::{ObjectAttributes},
  79. },
  80. };
  81. #[test]
  82. fn create_context() {
  83. let config = TabrmdConfig::default();
  84. let mut context = Context::new_with_tabrmd(config).unwrap();
  85. context.self_test(true).unwrap();
  86. }
  87. #[test]
  88. fn create_primary_key() {
  89. let config = TabrmdConfig::default();
  90. let mut context = Context::new_with_tabrmd(config)
  91. .expect("Failed to connect to tabrmd. Ensure that tpm2-abrmd is running");
  92. let public = {
  93. let object_attributes = ObjectAttributes::builder()
  94. .with_fixed_tpm(true)
  95. .with_fixed_parent(true)
  96. .with_sensitive_data_origin(true)
  97. .with_user_with_auth(true)
  98. .with_decrypt(false)
  99. .with_sign_encrypt(true)
  100. .with_restricted(false)
  101. .build()
  102. .expect("ObjectAttributesBuilder failed");
  103. let name_hashing_algorithm = HashingAlgorithm::Sha256;
  104. let empty = [0u8; 0];
  105. let auth_policy = Digest::try_from(empty.as_slice()).unwrap();
  106. let parameters = PublicEccParameters::new(
  107. SymmetricDefinitionObject::Null,
  108. EccScheme::EcDsa(HashScheme::new(HashingAlgorithm::Sha256)),
  109. EccCurve::NistP256,
  110. KeyDerivationFunctionScheme::Null
  111. );
  112. Public::Ecc {
  113. object_attributes,
  114. name_hashing_algorithm,
  115. auth_policy,
  116. parameters,
  117. unique: EccPoint::default(),
  118. }
  119. };
  120. let session = context.start_auth_session(
  121. None,
  122. None,
  123. None,
  124. SessionType::Hmac,
  125. SymmetricDefinition::AES_256_CFB,
  126. HashingAlgorithm::Sha256,
  127. )
  128. .expect("Failed to create session")
  129. .expect("Received invalid handle");
  130. context.execute_with_session(Some(session), |ctx| {
  131. let primary = ctx.create_primary(
  132. Hierarchy::Null,
  133. public,
  134. None,
  135. None,
  136. None,
  137. None,
  138. )
  139. .tss2_expect("create_primary failed")
  140. .key_handle;
  141. ctx.flush_context(primary.into()).expect("flush_context failed");
  142. });
  143. }
  144. }