@@ -15,6 +15,7 @@ use serial_test::serial;
15
15
use std:: collections:: HashMap ;
16
16
use std:: thread;
17
17
18
+ use cryptoki:: mechanism:: ekdf:: AesCbcDeriveParams ;
18
19
use testresult:: TestResult ;
19
20
20
21
#[ test]
@@ -1105,3 +1106,84 @@ fn wait_for_slot_event() {
1105
1106
res
1106
1107
) ;
1107
1108
}
1109
+
1110
+ #[ test]
1111
+ #[ serial]
1112
+ fn generate_generic_secret_key ( ) -> TestResult {
1113
+ let ( pkcs11, slot) = init_pins ( ) ;
1114
+ let session = pkcs11. open_rw_session ( slot) ?;
1115
+ session. login ( UserType :: User , Some ( & AuthPin :: new ( USER_PIN . into ( ) ) ) ) ?;
1116
+
1117
+ let key_label = Attribute :: Label ( b"test_generic_secret_key_gen" . to_vec ( ) ) ;
1118
+ let key_template = vec ! [
1119
+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
1120
+ Attribute :: KeyType ( KeyType :: GENERIC_SECRET ) ,
1121
+ Attribute :: Token ( true ) ,
1122
+ Attribute :: Sensitive ( true ) ,
1123
+ Attribute :: Private ( true ) ,
1124
+ Attribute :: ValueLen ( 512 . into( ) ) ,
1125
+ key_label. clone( ) ,
1126
+ ] ;
1127
+
1128
+ let key = session. generate_key ( & Mechanism :: GenericSecretKeyGen , & key_template) ?;
1129
+ let attributes_result = session. find_objects ( & [ key_label] ) ?. remove ( 0 ) ;
1130
+ assert_eq ! ( key, attributes_result) ;
1131
+
1132
+ Ok ( ( ) )
1133
+ }
1134
+
1135
+ #[ test]
1136
+ #[ serial]
1137
+ fn ekdf_aes_cbc_encrypt_data ( ) -> TestResult {
1138
+ let ( pkcs11, slot) = init_pins ( ) ;
1139
+ let session = pkcs11. open_rw_session ( slot) ?;
1140
+ session. login ( UserType :: User , Some ( & AuthPin :: new ( USER_PIN . into ( ) ) ) ) ?;
1141
+
1142
+ // key template
1143
+ let key_template = vec ! [
1144
+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
1145
+ Attribute :: KeyType ( KeyType :: AES ) ,
1146
+ Attribute :: Token ( true ) ,
1147
+ Attribute :: Sensitive ( true ) ,
1148
+ Attribute :: Private ( true ) ,
1149
+ Attribute :: ValueLen ( 32 . into( ) ) ,
1150
+ Attribute :: Derive ( true ) ,
1151
+ ] ;
1152
+
1153
+ // generate master key
1154
+ let master_key_label = Attribute :: Label ( b"test_aes_cbc_encrypt_data_master_key" . to_vec ( ) ) ;
1155
+ let mut master_key_template = key_template. clone ( ) ;
1156
+ master_key_template. insert ( 0 , master_key_label. clone ( ) ) ;
1157
+
1158
+ let master_key = session. generate_key ( & Mechanism :: AesKeyGen , & master_key_template) ?;
1159
+ assert_eq ! (
1160
+ master_key,
1161
+ session. find_objects( & [ master_key_label] ) ?. remove( 0 )
1162
+ ) ;
1163
+
1164
+ // generate a derived pair
1165
+ let derived_key_label = Attribute :: Label ( b"test_aes_cbc_encrypt_data_child_key" . to_vec ( ) ) ;
1166
+ let mut derived_key_template = key_template. clone ( ) ;
1167
+ derived_key_template. insert ( 0 , derived_key_label. clone ( ) ) ;
1168
+
1169
+ // ============================================== IMPORTANT ==============================================
1170
+ // When using this derivation method in production, be aware that it's better to keep first bytes of data
1171
+ // filled with actual data (e.g., derivation path) - this shall cause CBC mode to propagate randomness to
1172
+ // remaining 128 bit-wide AES blocks.
1173
+ // Otherwise, if filling only last bytes, you are risking to keep first N of 128 bit-wide chunks of your
1174
+ // derived private key the same for all child keys. If deriving a key for 256-bit AES, this means half of
1175
+ // the key to be static.
1176
+ // =======================================================================================================
1177
+ let aes_cbc_derive_params = AesCbcDeriveParams :: new ( [ 0u8 ; 16 ] , [ 1u8 ; 32 ] . as_slice ( ) ) ;
1178
+ let derived_key = session. derive_key (
1179
+ & Mechanism :: AesCbcEncryptData ( aes_cbc_derive_params) ,
1180
+ master_key,
1181
+ & derived_key_template,
1182
+ ) ?;
1183
+ assert_eq ! (
1184
+ derived_key,
1185
+ session. find_objects( & [ derived_key_label] ) ?. remove( 0 )
1186
+ ) ;
1187
+
1188
+ Ok ( ( ) )
1189
+ }
0 commit comments