@@ -12,9 +12,9 @@ use crate::{
1212        reserved_handles:: { Hierarchy ,  NvAuth } , 
1313    } , 
1414    structures:: { 
15-         Digest ,   EccParameter ,  EccPoint ,  EccScheme ,  KeyDerivationFunctionScheme ,  Public , 
16-         PublicBuilder ,   PublicEccParametersBuilder ,  PublicKeyRsa ,  PublicRsaParametersBuilder , 
17-         RsaExponent ,   RsaScheme ,  SymmetricDefinitionObject , 
15+         EccParameter ,  EccPoint ,  EccScheme ,  KeyDerivationFunctionScheme ,  Public ,   PublicBuilder , 
16+         PublicEccParametersBuilder ,  PublicKeyRsa ,  PublicRsaParametersBuilder ,   RsaExponent , 
17+         RsaScheme ,  SymmetricDefinitionObject , 
1818    } , 
1919    Context ,  Error ,  Result ,  WrapperErrorKind , 
2020} ; 
@@ -32,8 +32,32 @@ const ECC_P256_SM2_EK_CERTIFICATE_NV_INDEX: u32 = 0x01c0001a;
3232const  RSA_3072_EK_CERTIFICATE_NV_INDEX :  u32  = 0x01c0001c ; 
3333const  RSA_4096_EK_CERTIFICATE_NV_INDEX :  u32  = 0x01c0001e ; 
3434
35+ // Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.5 Revision 2 
36+ // Section B.3 and B.4 
37+ const  AUTHPOLICY_A_SHA256 :  [ u8 ;  32 ]  = [ 
38+     0x83 ,  0x71 ,  0x97 ,  0x67 ,  0x44 ,  0x84 ,  0xb3 ,  0xf8 ,  0x1a ,  0x90 ,  0xcc ,  0x8d ,  0x46 ,  0xa5 ,  0xd7 ,  0x24 , 
39+     0xfd ,  0x52 ,  0xd7 ,  0x6e ,  0x06 ,  0x52 ,  0x0b ,  0x64 ,  0xf2 ,  0xa1 ,  0xda ,  0x1b ,  0x33 ,  0x14 ,  0x69 ,  0xaa , 
40+ ] ; 
41+ const  AUTHPOLICY_B_SHA384 :  [ u8 ;  48 ]  = [ 
42+     0xb2 ,  0x6e ,  0x7d ,  0x28 ,  0xd1 ,  0x1a ,  0x50 ,  0xbc ,  0x53 ,  0xd8 ,  0x82 ,  0xbc ,  0xf5 ,  0xfd ,  0x3a ,  0x1a , 
43+     0x07 ,  0x41 ,  0x48 ,  0xbb ,  0x35 ,  0xd3 ,  0xb4 ,  0xe4 ,  0xcb ,  0x1c ,  0x0a ,  0xd9 ,  0xbd ,  0xe4 ,  0x19 ,  0xca , 
44+     0xcb ,  0x47 ,  0xba ,  0x09 ,  0x69 ,  0x96 ,  0x46 ,  0x15 ,  0x0f ,  0x9f ,  0xc0 ,  0x00 ,  0xf3 ,  0xf8 ,  0x0e ,  0x12 , 
45+ ] ; 
46+ const  AUTHPOLICY_B_SHA512 :  [ u8 ;  64 ]  = [ 
47+     0xb8 ,  0x22 ,  0x1c ,  0xa6 ,  0x9e ,  0x85 ,  0x50 ,  0xa4 ,  0x91 ,  0x4d ,  0xe3 ,  0xfa ,  0xa6 ,  0xa1 ,  0x8c ,  0x07 , 
48+     0x2c ,  0xc0 ,  0x12 ,  0x08 ,  0x07 ,  0x3a ,  0x92 ,  0x8d ,  0x5d ,  0x66 ,  0xd5 ,  0x9e ,  0xf7 ,  0x9e ,  0x49 ,  0xa4 , 
49+     0x29 ,  0xc4 ,  0x1a ,  0x6b ,  0x26 ,  0x95 ,  0x71 ,  0xd5 ,  0x7e ,  0xdb ,  0x25 ,  0xfb ,  0xdb ,  0x18 ,  0x38 ,  0x42 , 
50+     0x56 ,  0x08 ,  0xb4 ,  0x13 ,  0xcd ,  0x61 ,  0x6a ,  0x5f ,  0x6d ,  0xb5 ,  0xb6 ,  0x07 ,  0x1a ,  0xf9 ,  0x9b ,  0xea , 
51+ ] ; 
52+ const  AUTHPOLICY_B_SM3_256 :  [ u8 ;  32 ]  = [ 
53+     0x16 ,  0x78 ,  0x60 ,  0xa3 ,  0x5f ,  0x2c ,  0x5c ,  0x35 ,  0x67 ,  0xf9 ,  0xc9 ,  0x27 ,  0xac ,  0x56 ,  0xc0 ,  0x32 , 
54+     0xf3 ,  0xb3 ,  0xa6 ,  0x46 ,  0x2f ,  0x8d ,  0x03 ,  0x79 ,  0x98 ,  0xe7 ,  0xa1 ,  0x0f ,  0x77 ,  0xfa ,  0x45 ,  0x4a , 
55+ ] ; 
56+ 
3557/// Get the [`Public`] representing a default Endorsement Key 
3658/// 
59+ /// **Note**: This only works for key algorithms specified in TCG EK Credential Profile for TPM Family 2.0. 
60+ /// 
3761/// Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.3 Revision 2 
3862/// Appendix B.3.3 and B.3.4 
3963pub  fn  create_ek_public_from_default_template < IKC :  IntoKeyCustomization > ( 
@@ -42,12 +66,19 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
4266)  -> Result < Public >  { 
4367    let  key_customization = key_customization. into_key_customization ( ) ; 
4468
69+     // user_with_auth is not set for the lower profiles (RSA 20248 and ECC P256) 
70+     let  user_with_auth = !matches ! ( 
71+         alg, 
72+         AsymmetricAlgorithmSelection :: Rsa ( RsaKeyBits :: Rsa2048 ) 
73+             | AsymmetricAlgorithmSelection :: Ecc ( EccCurve :: NistP256 ) 
74+     ) ; 
75+ 
4576    let  obj_attrs_builder = ObjectAttributesBuilder :: new ( ) 
4677        . with_fixed_tpm ( true ) 
4778        . with_st_clear ( false ) 
4879        . with_fixed_parent ( true ) 
4980        . with_sensitive_data_origin ( true ) 
50-         . with_user_with_auth ( false ) 
81+         . with_user_with_auth ( user_with_auth ) 
5182        . with_admin_with_policy ( true ) 
5283        . with_no_da ( false ) 
5384        . with_encrypted_duplication ( false ) 
@@ -62,54 +93,93 @@ pub fn create_ek_public_from_default_template<IKC: IntoKeyCustomization>(
6293    } 
6394    . build ( ) ?; 
6495
65-     // TPM2_PolicySecret(TPM_RH_ENDORSEMENT) 
66-     // With 32 null-bytes attached, because of the type of with_auth_policy 
67-     let  authpolicy:  [ u8 ;  64 ]  = [ 
68-         0x83 ,  0x71 ,  0x97 ,  0x67 ,  0x44 ,  0x84 ,  0xb3 ,  0xf8 ,  0x1a ,  0x90 ,  0xcc ,  0x8d ,  0x46 ,  0xa5 ,  0xd7 , 
69-         0x24 ,  0xfd ,  0x52 ,  0xd7 ,  0x6e ,  0x06 ,  0x52 ,  0x0b ,  0x64 ,  0xf2 ,  0xa1 ,  0xda ,  0x1b ,  0x33 ,  0x14 , 
70-         0x69 ,  0xaa ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 , 
71-         0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 ,  0x00 , 
72-         0x00 ,  0x00 ,  0x00 ,  0x00 , 
73-     ] ; 
74- 
7596    let  key_builder = match  alg { 
76-         AsymmetricAlgorithmSelection :: Rsa ( key_bits)  => PublicBuilder :: new ( ) 
77-             . with_public_algorithm ( PublicAlgorithm :: Rsa ) 
78-             . with_name_hashing_algorithm ( HashingAlgorithm :: Sha256 ) 
79-             . with_object_attributes ( obj_attrs) 
80-             . with_auth_policy ( Digest :: try_from ( authpolicy[ 0 ..32 ] . to_vec ( ) ) ?) 
81-             . with_rsa_parameters ( 
82-                 PublicRsaParametersBuilder :: new ( ) 
83-                     . with_symmetric ( SymmetricDefinitionObject :: AES_128_CFB ) 
84-                     . with_scheme ( RsaScheme :: Null ) 
85-                     . with_key_bits ( key_bits) 
86-                     . with_exponent ( RsaExponent :: default ( ) ) 
87-                     . with_is_signing_key ( obj_attrs. sign_encrypt ( ) ) 
88-                     . with_is_decryption_key ( obj_attrs. decrypt ( ) ) 
89-                     . with_restricted ( obj_attrs. decrypt ( ) ) 
90-                     . build ( ) ?, 
91-             ) 
92-             . with_rsa_unique_identifier ( PublicKeyRsa :: new_empty_with_size ( RsaKeyBits :: Rsa2048 ) ) , 
93-         AsymmetricAlgorithmSelection :: Ecc ( ecc_curve)  => PublicBuilder :: new ( ) 
94-             . with_public_algorithm ( PublicAlgorithm :: Ecc ) 
95-             . with_name_hashing_algorithm ( HashingAlgorithm :: Sha256 ) 
96-             . with_object_attributes ( obj_attrs) 
97-             . with_auth_policy ( Digest :: try_from ( authpolicy[ 0 ..32 ] . to_vec ( ) ) ?) 
98-             . with_ecc_parameters ( 
99-                 PublicEccParametersBuilder :: new ( ) 
100-                     . with_symmetric ( SymmetricDefinitionObject :: AES_128_CFB ) 
101-                     . with_ecc_scheme ( EccScheme :: Null ) 
102-                     . with_curve ( ecc_curve) 
103-                     . with_key_derivation_function_scheme ( KeyDerivationFunctionScheme :: Null ) 
104-                     . with_is_signing_key ( obj_attrs. sign_encrypt ( ) ) 
105-                     . with_is_decryption_key ( obj_attrs. decrypt ( ) ) 
106-                     . with_restricted ( obj_attrs. decrypt ( ) ) 
107-                     . build ( ) ?, 
108-             ) 
109-             . with_ecc_unique_identifier ( EccPoint :: new ( 
110-                 EccParameter :: try_from ( vec ! [ 0u8 ;  32 ] ) ?, 
111-                 EccParameter :: try_from ( vec ! [ 0u8 ;  32 ] ) ?, 
112-             ) ) , 
97+         AsymmetricAlgorithmSelection :: Rsa ( key_bits)  => { 
98+             let  ( hash_alg,  authpolicy,  symmetric,  unique)  = match  key_bits { 
99+                 RsaKeyBits :: Rsa2048  => ( 
100+                     HashingAlgorithm :: Sha256 , 
101+                     AUTHPOLICY_A_SHA256 . into ( ) , 
102+                     SymmetricDefinitionObject :: AES_128_CFB , 
103+                     PublicKeyRsa :: new_empty_with_size ( RsaKeyBits :: Rsa2048 ) , 
104+                 ) , 
105+                 RsaKeyBits :: Rsa3072  | RsaKeyBits :: Rsa4096  => ( 
106+                     HashingAlgorithm :: Sha384 , 
107+                     AUTHPOLICY_B_SHA384 . into ( ) , 
108+                     SymmetricDefinitionObject :: AES_256_CFB , 
109+                     PublicKeyRsa :: new_empty ( ) , 
110+                 ) , 
111+                 // Other key sizes are not supported in the spec, so return a error 
112+                 _ => return  Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) , 
113+             } ; 
114+ 
115+             PublicBuilder :: new ( ) 
116+                 . with_public_algorithm ( PublicAlgorithm :: Rsa ) 
117+                 . with_name_hashing_algorithm ( hash_alg) 
118+                 . with_object_attributes ( obj_attrs) 
119+                 . with_auth_policy ( authpolicy) 
120+                 . with_rsa_parameters ( 
121+                     PublicRsaParametersBuilder :: new ( ) 
122+                         . with_symmetric ( symmetric) 
123+                         . with_scheme ( RsaScheme :: Null ) 
124+                         . with_key_bits ( key_bits) 
125+                         . with_exponent ( RsaExponent :: default ( ) ) 
126+                         . with_is_signing_key ( obj_attrs. sign_encrypt ( ) ) 
127+                         . with_is_decryption_key ( obj_attrs. decrypt ( ) ) 
128+                         . with_restricted ( obj_attrs. decrypt ( ) ) 
129+                         . build ( ) ?, 
130+                 ) 
131+                 . with_rsa_unique_identifier ( unique) 
132+         } 
133+         AsymmetricAlgorithmSelection :: Ecc ( ecc_curve)  => { 
134+             let  ( hash_alg,  authpolicy,  symmetric,  xy_size)  = match  ecc_curve { 
135+                 EccCurve :: NistP256  => ( 
136+                     HashingAlgorithm :: Sha256 , 
137+                     AUTHPOLICY_A_SHA256 . into ( ) , 
138+                     SymmetricDefinitionObject :: AES_128_CFB , 
139+                     32 , 
140+                 ) , 
141+                 EccCurve :: NistP384  => ( 
142+                     HashingAlgorithm :: Sha384 , 
143+                     AUTHPOLICY_B_SHA384 . into ( ) , 
144+                     SymmetricDefinitionObject :: AES_256_CFB , 
145+                     0 , 
146+                 ) , 
147+                 EccCurve :: NistP521  => ( 
148+                     HashingAlgorithm :: Sha512 , 
149+                     AUTHPOLICY_B_SHA512 . into ( ) , 
150+                     SymmetricDefinitionObject :: AES_256_CFB , 
151+                     0 , 
152+                 ) , 
153+                 EccCurve :: Sm2P256  => ( 
154+                     HashingAlgorithm :: Sm3_256 , 
155+                     AUTHPOLICY_B_SM3_256 . into ( ) , 
156+                     SymmetricDefinitionObject :: SM4_128_CFB , 
157+                     0 , 
158+                 ) , 
159+                 // Other curves are not supported in the spec, so return a error 
160+                 _ => return  Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) , 
161+             } ; 
162+             PublicBuilder :: new ( ) 
163+                 . with_public_algorithm ( PublicAlgorithm :: Ecc ) 
164+                 . with_name_hashing_algorithm ( hash_alg) 
165+                 . with_object_attributes ( obj_attrs) 
166+                 . with_auth_policy ( authpolicy) 
167+                 . with_ecc_parameters ( 
168+                     PublicEccParametersBuilder :: new ( ) 
169+                         . with_symmetric ( symmetric) 
170+                         . with_ecc_scheme ( EccScheme :: Null ) 
171+                         . with_curve ( ecc_curve) 
172+                         . with_key_derivation_function_scheme ( KeyDerivationFunctionScheme :: Null ) 
173+                         . with_is_signing_key ( obj_attrs. sign_encrypt ( ) ) 
174+                         . with_is_decryption_key ( obj_attrs. decrypt ( ) ) 
175+                         . with_restricted ( obj_attrs. decrypt ( ) ) 
176+                         . build ( ) ?, 
177+                 ) 
178+                 . with_ecc_unique_identifier ( EccPoint :: new ( 
179+                     EccParameter :: try_from ( vec ! [ 0u8 ;  xy_size] ) ?, 
180+                     EccParameter :: try_from ( vec ! [ 0u8 ;  xy_size] ) ?, 
181+                 ) ) 
182+         } 
113183    } ; 
114184
115185    let  key_builder = if  let  Some ( ref  k)  = key_customization { 
0 commit comments