22// SPDX-License-Identifier: Apache-2.0 
33
44use  crate :: { 
5-     abstraction:: { cipher :: Cipher ,  IntoKeyCustomization ,  KeyCustomization } , 
5+     abstraction:: { AsymmetricAlgorithmSelection ,  IntoKeyCustomization ,  KeyCustomization } , 
66    attributes:: { ObjectAttributesBuilder ,  SessionAttributesBuilder } , 
77    constants:: { AlgorithmIdentifier ,  SessionType } , 
88    handles:: { AuthHandle ,  KeyHandle ,  SessionHandle } , 
99    interface_types:: { 
1010        algorithm:: { 
11-             AsymmetricAlgorithm ,   EccSchemeAlgorithm ,  HashingAlgorithm ,  PublicAlgorithm , 
12-             RsaSchemeAlgorithm ,   SignatureSchemeAlgorithm , 
11+             EccSchemeAlgorithm ,  HashingAlgorithm ,  PublicAlgorithm ,   RsaSchemeAlgorithm , 
12+             SignatureSchemeAlgorithm , 
1313        } , 
14-         ecc:: EccCurve , 
15-         key_bits:: RsaKeyBits , 
1614        session_handles:: PolicySession , 
1715    } , 
1816    structures:: { 
19-         Auth ,  CreateKeyResult ,  EccScheme ,  KeyDerivationFunctionScheme ,  Private ,  Public , 
20-         PublicBuilder ,  PublicEccParametersBuilder ,  PublicKeyRsa ,  PublicRsaParametersBuilder , 
21-         RsaExponent ,  RsaScheme ,  SymmetricDefinitionObject , 
17+         Auth ,  CreateKeyResult ,  Digest ,  DigestList ,  EccPoint ,  EccScheme , 
18+         KeyDerivationFunctionScheme ,  Private ,  Public ,  PublicBuilder ,  PublicEccParametersBuilder , 
19+         PublicKeyRsa ,  PublicRsaParametersBuilder ,  RsaExponent ,  RsaScheme , 
20+         SymmetricDefinitionObject , 
2221    } , 
2322    Context ,  Error ,  Result ,  WrapperErrorKind , 
2423} ; 
25- use  log:: error; 
26- use  std:: convert:: { TryFrom ,  TryInto } ; 
24+ use  std:: convert:: TryFrom ; 
25+ 
26+ // Source: TCG EK Credential Profile for TPM Family 2.0; Level 0 Version 2.5 Revision 2 
27+ // Section B.6 
28+ const  POLICY_A_SHA384 :  [ u8 ;  48 ]  = [ 
29+     0x8b ,  0xbf ,  0x22 ,  0x66 ,  0x53 ,  0x7c ,  0x17 ,  0x1c ,  0xb5 ,  0x6e ,  0x40 ,  0x3c ,  0x4d ,  0xc1 ,  0xd4 ,  0xb6 , 
30+     0x4f ,  0x43 ,  0x26 ,  0x11 ,  0xdc ,  0x38 ,  0x6e ,  0x6f ,  0x53 ,  0x20 ,  0x50 ,  0xc3 ,  0x27 ,  0x8c ,  0x93 ,  0x0e , 
31+     0x14 ,  0x3e ,  0x8b ,  0xb1 ,  0x13 ,  0x38 ,  0x24 ,  0xcc ,  0xb4 ,  0x31 ,  0x05 ,  0x38 ,  0x71 ,  0xc6 ,  0xdb ,  0x53 , 
32+ ] ; 
33+ const  POLICY_A_SHA512 :  [ u8 ;  64 ]  = [ 
34+     0x1e ,  0x3b ,  0x76 ,  0x50 ,  0x2c ,  0x8a ,  0x14 ,  0x25 ,  0xaa ,  0x0b ,  0x7b ,  0x3f ,  0xc6 ,  0x46 ,  0xa1 ,  0xb0 , 
35+     0xfa ,  0xe0 ,  0x63 ,  0xb0 ,  0x3b ,  0x53 ,  0x68 ,  0xf9 ,  0xc4 ,  0xcd ,  0xde ,  0xca ,  0xff ,  0x08 ,  0x91 ,  0xdd , 
36+     0x68 ,  0x2b ,  0xac ,  0x1a ,  0x85 ,  0xd4 ,  0xd8 ,  0x32 ,  0xb7 ,  0x81 ,  0xea ,  0x45 ,  0x19 ,  0x15 ,  0xde ,  0x5f , 
37+     0xc5 ,  0xbf ,  0x0d ,  0xc4 ,  0xa1 ,  0x91 ,  0x7c ,  0xd4 ,  0x2f ,  0xa0 ,  0x41 ,  0xe3 ,  0xf9 ,  0x98 ,  0xe0 ,  0xee , 
38+ ] ; 
39+ const  POLICY_A_SM3_256 :  [ u8 ;  32 ]  = [ 
40+     0xc6 ,  0x7f ,  0x7d ,  0x35 ,  0xf6 ,  0x6f ,  0x3b ,  0xec ,  0x13 ,  0xc8 ,  0x9f ,  0xe8 ,  0x98 ,  0x92 ,  0x1c ,  0x65 , 
41+     0x1b ,  0x0c ,  0xb5 ,  0xa3 ,  0x8a ,  0x92 ,  0x69 ,  0x0a ,  0x62 ,  0xa4 ,  0x3c ,  0x00 ,  0x12 ,  0xe4 ,  0xfb ,  0x8b , 
42+ ] ; 
43+ const  POLICY_C_SHA384 :  [ u8 ;  48 ]  = [ 
44+     0xd6 ,  0x03 ,  0x2c ,  0xe6 ,  0x1f ,  0x2f ,  0xb3 ,  0xc2 ,  0x40 ,  0xeb ,  0x3c ,  0xf6 ,  0xa3 ,  0x32 ,  0x37 ,  0xef , 
45+     0x2b ,  0x6a ,  0x16 ,  0xf4 ,  0x29 ,  0x3c ,  0x22 ,  0xb4 ,  0x55 ,  0xe2 ,  0x61 ,  0xcf ,  0xfd ,  0x21 ,  0x7a ,  0xd5 , 
46+     0xb4 ,  0x94 ,  0x7c ,  0x2d ,  0x73 ,  0xe6 ,  0x30 ,  0x05 ,  0xee ,  0xd2 ,  0xdc ,  0x2b ,  0x35 ,  0x93 ,  0xd1 ,  0x65 , 
47+ ] ; 
48+ const  POLICY_C_SHA512 :  [ u8 ;  64 ]  = [ 
49+     0x58 ,  0x9e ,  0xe1 ,  0xe1 ,  0x46 ,  0x54 ,  0x47 ,  0x16 ,  0xe8 ,  0xde ,  0xaf ,  0xe6 ,  0xdb ,  0x24 ,  0x7b ,  0x01 , 
50+     0xb8 ,  0x1e ,  0x9f ,  0x9c ,  0x7d ,  0xd1 ,  0x6b ,  0x81 ,  0x4a ,  0xa1 ,  0x59 ,  0x13 ,  0x87 ,  0x49 ,  0x10 ,  0x5f , 
51+     0xba ,  0x53 ,  0x88 ,  0xdd ,  0x1d ,  0xea ,  0x70 ,  0x2f ,  0x35 ,  0x24 ,  0x0c ,  0x18 ,  0x49 ,  0x33 ,  0x12 ,  0x1e , 
52+     0x2c ,  0x61 ,  0xb8 ,  0xf5 ,  0x0d ,  0x3e ,  0xf9 ,  0x13 ,  0x93 ,  0xa4 ,  0x9a ,  0x38 ,  0xc3 ,  0xf7 ,  0x3f ,  0xc8 , 
53+ ] ; 
54+ const  POLICY_C_SM3_256 :  [ u8 ;  32 ]  = [ 
55+     0x2d ,  0x4e ,  0x81 ,  0x57 ,  0x8c ,  0x35 ,  0x31 ,  0xd9 ,  0xbd ,  0x1c ,  0xdd ,  0x7d ,  0x02 ,  0xba ,  0x29 ,  0x8d , 
56+     0x56 ,  0x99 ,  0xa3 ,  0xe3 ,  0x9f ,  0xc3 ,  0x55 ,  0x1b ,  0xfe ,  0xff ,  0xcf ,  0x13 ,  0x2b ,  0x49 ,  0xe1 ,  0x1d , 
57+ ] ; 
2758
2859fn  create_ak_public < IKC :  IntoKeyCustomization > ( 
29-     key_alg :  AsymmetricAlgorithm , 
60+     key_alg :  AsymmetricAlgorithmSelection , 
3061    hash_alg :  HashingAlgorithm , 
3162    sign_alg :  SignatureSchemeAlgorithm , 
3263    key_customization :  IKC , 
@@ -50,7 +81,7 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
5081    . build ( ) ?; 
5182
5283    let  key_builder = match  key_alg { 
53-         AsymmetricAlgorithm :: Rsa  => PublicBuilder :: new ( ) 
84+         AsymmetricAlgorithmSelection :: Rsa ( key_bits )  => PublicBuilder :: new ( ) 
5485            . with_public_algorithm ( PublicAlgorithm :: Rsa ) 
5586            . with_name_hashing_algorithm ( hash_alg) 
5687            . with_object_attributes ( obj_attrs) 
@@ -60,15 +91,15 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
6091                        RsaSchemeAlgorithm :: try_from ( AlgorithmIdentifier :: from ( sign_alg) ) ?, 
6192                        Some ( hash_alg) , 
6293                    ) ?) 
63-                     . with_key_bits ( RsaKeyBits :: Rsa2048 ) 
94+                     . with_key_bits ( key_bits ) 
6495                    . with_exponent ( RsaExponent :: default ( ) ) 
6596                    . with_is_signing_key ( obj_attrs. sign_encrypt ( ) ) 
6697                    . with_is_decryption_key ( obj_attrs. decrypt ( ) ) 
6798                    . with_restricted ( obj_attrs. restricted ( ) ) 
6899                    . build ( ) ?, 
69100            ) 
70101            . with_rsa_unique_identifier ( PublicKeyRsa :: default ( ) ) , 
71-         AsymmetricAlgorithm :: Ecc  => PublicBuilder :: new ( ) 
102+         AsymmetricAlgorithmSelection :: Ecc ( ecc_curve )  => PublicBuilder :: new ( ) 
72103            . with_public_algorithm ( PublicAlgorithm :: Ecc ) 
73104            . with_name_hashing_algorithm ( hash_alg) 
74105            . with_object_attributes ( obj_attrs) 
@@ -78,16 +109,17 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
78109                    . with_ecc_scheme ( EccScheme :: create ( 
79110                        EccSchemeAlgorithm :: try_from ( AlgorithmIdentifier :: from ( sign_alg) ) ?, 
80111                        Some ( hash_alg) , 
81-                         Some ( 0 ) , 
112+                         if  sign_alg == SignatureSchemeAlgorithm :: EcDaa  { 
113+                             Some ( 0 ) 
114+                         }  else  { 
115+                             None 
116+                         } , 
82117                    ) ?) 
83-                     . with_curve ( EccCurve :: NistP192 ) 
118+                     . with_curve ( ecc_curve ) 
84119                    . with_key_derivation_function_scheme ( KeyDerivationFunctionScheme :: Null ) 
85120                    . build ( ) ?, 
86-             ) , 
87-         AsymmetricAlgorithm :: Null  => { 
88-             // TODO: Figure out what to with Null. 
89-             return  Err ( Error :: local_error ( WrapperErrorKind :: UnsupportedParam ) ) ; 
90-         } 
121+             ) 
122+             . with_ecc_unique_identifier ( EccPoint :: default ( ) ) , 
91123    } ; 
92124
93125    let  key_builder = if  let  Some ( ref  k)  = key_customization { 
@@ -99,6 +131,38 @@ fn create_ak_public<IKC: IntoKeyCustomization>(
99131    key_builder. build ( ) 
100132} 
101133
134+ // extracts the hashing and sysmmetric algorithm from parent and constructs the correct DigestList for OR policy 
135+ fn  session_config ( 
136+     context :  & mut  Context , 
137+     parent :  KeyHandle , 
138+ )  -> Result < ( HashingAlgorithm ,  SymmetricDefinitionObject ,  DigestList ) >  { 
139+     let  ( parent_public,  _,  _)  = context. read_public ( parent) ?; 
140+     let  parent_hash_alg = parent_public. name_hashing_algorithm ( ) ; 
141+     let  parent_symmetric = parent_public
142+         . symmetric_algorithm ( ) 
143+         . ok_or_else ( || Error :: local_error ( WrapperErrorKind :: InvalidParam ) ) ?; 
144+ 
145+     let  mut  policy_digests = DigestList :: new ( ) ; 
146+ 
147+     match  parent_hash_alg { 
148+         HashingAlgorithm :: Sha384  => { 
149+             policy_digests. add ( Digest :: try_from ( POLICY_A_SHA384 . as_slice ( ) ) ?) ?; 
150+             policy_digests. add ( Digest :: try_from ( POLICY_C_SHA384 . as_slice ( ) ) ?) ?; 
151+         } 
152+         HashingAlgorithm :: Sha512  => { 
153+             policy_digests. add ( Digest :: try_from ( POLICY_A_SHA512 . as_slice ( ) ) ?) ?; 
154+             policy_digests. add ( Digest :: try_from ( POLICY_C_SHA512 . as_slice ( ) ) ?) ?; 
155+         } 
156+         HashingAlgorithm :: Sm3_256  => { 
157+             policy_digests. add ( Digest :: try_from ( POLICY_A_SM3_256 . as_slice ( ) ) ?) ?; 
158+             policy_digests. add ( Digest :: try_from ( POLICY_C_SM3_256 . as_slice ( ) ) ?) ?; 
159+         } 
160+         _ => ( ) , 
161+     } ; 
162+ 
163+     Ok ( ( parent_hash_alg,  parent_symmetric,  policy_digests) ) 
164+ } 
165+ 
102166/// This loads an Attestation Key previously generated under the Endorsement hierarchy 
103167pub  fn  load_ak ( 
104168    context :  & mut  Context , 
@@ -107,14 +171,16 @@ pub fn load_ak(
107171    private :  Private , 
108172    public :  Public , 
109173)  -> Result < KeyHandle >  { 
174+     let  ( parent_hash_alg,  parent_symmetric,  policy_digests)  = session_config ( context,  parent) ?; 
175+ 
110176    let  policy_auth_session = context
111177        . start_auth_session ( 
112178            None , 
113179            None , 
114180            None , 
115181            SessionType :: Policy , 
116-             Cipher :: aes_128_cfb ( ) . try_into ( ) ? , 
117-             HashingAlgorithm :: Sha256 , 
182+             parent_symmetric . into ( ) , 
183+             parent_hash_alg , 
118184        ) ?
119185        . ok_or_else ( || Error :: local_error ( WrapperErrorKind :: WrongValueFromTpm ) ) ?; 
120186
@@ -142,6 +208,13 @@ pub fn load_ak(
142208                ) 
143209            } ) ?; 
144210
211+             if  !policy_digests. is_empty ( )  { 
212+                 ctx. policy_or ( 
213+                     PolicySession :: try_from ( policy_auth_session) ?, 
214+                     policy_digests, 
215+                 ) ?
216+             } 
217+ 
145218            ctx. execute_with_session ( Some ( policy_auth_session) ,  |ctx| { 
146219                ctx. load ( parent,  private,  public) 
147220            } ) 
@@ -160,26 +233,22 @@ pub fn create_ak<IKC: IntoKeyCustomization>(
160233    context :  & mut  Context , 
161234    parent :  KeyHandle , 
162235    hash_alg :  HashingAlgorithm , 
236+     key_alg :  AsymmetricAlgorithmSelection , 
163237    sign_alg :  SignatureSchemeAlgorithm , 
164238    ak_auth_value :  Option < Auth > , 
165239    key_customization :  IKC , 
166240)  -> Result < CreateKeyResult >  { 
167-     let  key_alg = AsymmetricAlgorithm :: try_from ( sign_alg) . map_err ( |e| { 
168-         // sign_alg is either HMAC or Null. 
169-         error ! ( "Could not retrieve asymmetric algorithm for provided signature scheme" ) ; 
170-         e
171-     } ) ?; 
172- 
173241    let  ak_pub = create_ak_public ( key_alg,  hash_alg,  sign_alg,  key_customization) ?; 
242+     let  ( parent_hash_alg,  parent_symmetric,  policy_digests)  = session_config ( context,  parent) ?; 
174243
175244    let  policy_auth_session = context
176245        . start_auth_session ( 
177246            None , 
178247            None , 
179248            None , 
180249            SessionType :: Policy , 
181-             Cipher :: aes_128_cfb ( ) . try_into ( ) ? , 
182-             HashingAlgorithm :: Sha256 , 
250+             parent_symmetric . into ( ) , 
251+             parent_hash_alg , 
183252        ) ?
184253        . ok_or_else ( || Error :: local_error ( WrapperErrorKind :: WrongValueFromTpm ) ) ?; 
185254
@@ -207,6 +276,13 @@ pub fn create_ak<IKC: IntoKeyCustomization>(
207276                ) 
208277            } ) ?; 
209278
279+             if  !policy_digests. is_empty ( )  { 
280+                 ctx. policy_or ( 
281+                     PolicySession :: try_from ( policy_auth_session) ?, 
282+                     policy_digests, 
283+                 ) ?
284+             } ; 
285+ 
210286            ctx. execute_with_session ( Some ( policy_auth_session) ,  |ctx| { 
211287                ctx. create ( parent,  ak_pub,  ak_auth_value,  None ,  None ,  None ) 
212288            } ) 
0 commit comments