@@ -12,6 +12,7 @@ use cryptoki::mechanism::kbkdf::{
1212 DerivedKey , Endianness , KbkdfCounterFormat , KbkdfDkmLengthFormat , KbkdfDkmLengthMethod ,
1313 KbkdfFeedbackParams , KbkdfParams , PrfDataParam , PrfDataParamType ,
1414} ;
15+ use cryptoki:: mechanism:: misc:: { ExtractParams , KeyDerivationStringData } ;
1516use cryptoki:: mechanism:: rsa:: { PkcsMgfType , PkcsOaepParams , PkcsOaepSource } ;
1617use cryptoki:: mechanism:: { Mechanism , MechanismType , MessageParam } ;
1718use cryptoki:: object:: {
@@ -772,6 +773,257 @@ fn derive_key_sp800() -> TestResult {
772773 Ok ( ( ) )
773774}
774775
776+ #[ test]
777+ #[ serial]
778+ #[ ignore = "unsupported by both SoftHSM and Kryoptic for the moment. See latchset/kryoptic#323 to track support" ]
779+ fn derive_key_concatenation_two_keys ( ) -> TestResult {
780+ let ( pkcs11, slot) = init_pins ( ) ;
781+
782+ // Open a session and log in
783+ let session = pkcs11. open_rw_session ( slot) ?;
784+ session. login ( UserType :: User , Some ( & AuthPin :: new ( USER_PIN . into ( ) ) ) ) ?;
785+
786+ // Define keys to concatenate
787+ let key_value = [ 0x12 , 0x34 , 0x56 , 0x78 , 0x90 , 0x01 ] ;
788+
789+ let key1_template = [
790+ Attribute :: Token ( true ) ,
791+ Attribute :: Private ( false ) ,
792+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
793+ Attribute :: KeyType ( KeyType :: GENERIC_SECRET ) ,
794+ Attribute :: Value ( key_value[ ..3 ] . to_vec ( ) ) ,
795+ Attribute :: Derive ( true ) ,
796+ ] ;
797+ let key2_template = [
798+ Attribute :: Token ( true ) ,
799+ Attribute :: Private ( false ) ,
800+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
801+ Attribute :: KeyType ( KeyType :: GENERIC_SECRET ) ,
802+ Attribute :: Value ( key_value[ 3 ..] . to_vec ( ) ) ,
803+ Attribute :: Derive ( true ) ,
804+ ] ;
805+
806+ let key1 = session. create_object ( & key1_template) ?;
807+ let key2 = session. create_object ( & key2_template) ?;
808+
809+ // Derive key from two input keys
810+ let derived_key_template = [
811+ Attribute :: Token ( true ) ,
812+ Attribute :: Private ( false ) ,
813+ Attribute :: Sensitive ( false ) ,
814+ Attribute :: Extractable ( true ) ,
815+ ] ;
816+ let derived_key = session. derive_key (
817+ & Mechanism :: ConcatenateBaseAndKey ( key2) ,
818+ key1,
819+ & derived_key_template,
820+ ) ?;
821+
822+ let derived_key_value = session
823+ . get_attributes ( derived_key, & [ AttributeType :: Value ] ) ?
824+ . remove ( 0 ) ;
825+ let derived_key_value = if let Attribute :: Value ( value) = derived_key_value {
826+ value
827+ } else {
828+ panic ! ( "Expected value attribute." ) ;
829+ } ;
830+
831+ assert_eq ! ( & derived_key_value, & key_value) ;
832+
833+ // Delete keys
834+ session. destroy_object ( key1) ?;
835+ session. destroy_object ( key2) ?;
836+ session. destroy_object ( derived_key) ?;
837+
838+ Ok ( ( ) )
839+ }
840+
841+ #[ test]
842+ #[ serial]
843+ #[ ignore = "unsupported by both SoftHSM and Kryoptic for the moment. See latchset/kryoptic#323 to track support" ]
844+ fn derive_key_concatenation_key_and_data ( ) -> TestResult {
845+ let ( pkcs11, slot) = init_pins ( ) ;
846+
847+ // Open a session and log in
848+ let session = pkcs11. open_rw_session ( slot) ?;
849+ session. login ( UserType :: User , Some ( & AuthPin :: new ( USER_PIN . into ( ) ) ) ) ?;
850+
851+ // Define key/data to concatenate
852+ let mut data_value = [ 0x12 , 0x34 , 0x56 , 0x78 , 0x90 , 0x01 ] ;
853+
854+ let key_template = [
855+ Attribute :: Token ( true ) ,
856+ Attribute :: Private ( false ) ,
857+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
858+ Attribute :: KeyType ( KeyType :: GENERIC_SECRET ) ,
859+ Attribute :: Value ( data_value[ ..3 ] . to_vec ( ) ) ,
860+ Attribute :: Derive ( true ) ,
861+ ] ;
862+
863+ let key = session. create_object ( & key_template) ?;
864+
865+ // Derive keys from input key and data, both appended and prepended
866+ let derived_key_template = [
867+ Attribute :: Token ( true ) ,
868+ Attribute :: Private ( false ) ,
869+ Attribute :: Sensitive ( false ) ,
870+ Attribute :: Extractable ( true ) ,
871+ ] ;
872+ let data = KeyDerivationStringData :: new ( & data_value[ 3 ..] ) ;
873+ let derived_key1 = session. derive_key (
874+ & Mechanism :: ConcatenateBaseAndData ( data) ,
875+ key,
876+ & derived_key_template,
877+ ) ?;
878+ let derived_key2 = session. derive_key (
879+ & Mechanism :: ConcatenateDataAndBase ( data) ,
880+ key,
881+ & derived_key_template,
882+ ) ?;
883+
884+ let derived_key1_value = session
885+ . get_attributes ( derived_key1, & [ AttributeType :: Value ] ) ?
886+ . remove ( 0 ) ;
887+ let derived_key1_value = if let Attribute :: Value ( value) = derived_key1_value {
888+ value
889+ } else {
890+ panic ! ( "Expected value attribute." ) ;
891+ } ;
892+ let derived_key2_value = session
893+ . get_attributes ( derived_key2, & [ AttributeType :: Value ] ) ?
894+ . remove ( 0 ) ;
895+ let derived_key2_value = if let Attribute :: Value ( value) = derived_key2_value {
896+ value
897+ } else {
898+ panic ! ( "Expected value attribute." ) ;
899+ } ;
900+
901+ assert_eq ! ( & derived_key1_value, & data_value) ;
902+ // Swap halves of the data_value in-place
903+ let ( first_half, second_half) = data_value. split_at_mut ( 3 ) ;
904+ first_half. swap_with_slice ( second_half) ;
905+ assert_eq ! ( & derived_key2_value, & data_value) ;
906+
907+ // Delete keys
908+ session. destroy_object ( key) ?;
909+ session. destroy_object ( derived_key1) ?;
910+ session. destroy_object ( derived_key2) ?;
911+
912+ Ok ( ( ) )
913+ }
914+
915+ #[ test]
916+ #[ serial]
917+ #[ ignore = "unsupported by both SoftHSM and Kryoptic for the moment. See latchset/kryoptic#323 to track support" ]
918+ fn derive_key_xor_key_and_data ( ) -> TestResult {
919+ let ( pkcs11, slot) = init_pins ( ) ;
920+
921+ // Open a session and log in
922+ let session = pkcs11. open_rw_session ( slot) ?;
923+ session. login ( UserType :: User , Some ( & AuthPin :: new ( USER_PIN . into ( ) ) ) ) ?;
924+
925+ // Define key/data to xor
926+ let data_value = [ 0x12 , 0x34 , 0x56 , 0x78 , 0x90 , 0x01 ] ;
927+
928+ let key_template = [
929+ Attribute :: Token ( true ) ,
930+ Attribute :: Private ( false ) ,
931+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
932+ Attribute :: KeyType ( KeyType :: GENERIC_SECRET ) ,
933+ Attribute :: Value ( data_value. to_vec ( ) ) ,
934+ Attribute :: Derive ( true ) ,
935+ ] ;
936+
937+ let key = session. create_object ( & key_template) ?;
938+
939+ // Derive key by xor-ing input key and data
940+ let derived_key_template = [
941+ Attribute :: Token ( true ) ,
942+ Attribute :: Private ( false ) ,
943+ Attribute :: Sensitive ( false ) ,
944+ Attribute :: Extractable ( true ) ,
945+ ] ;
946+ let data = KeyDerivationStringData :: new ( & data_value) ;
947+ let derived_key = session. derive_key (
948+ & Mechanism :: XorBaseAndData ( data) ,
949+ key,
950+ & derived_key_template,
951+ ) ?;
952+
953+ let derived_key_value = session
954+ . get_attributes ( derived_key, & [ AttributeType :: Value ] ) ?
955+ . remove ( 0 ) ;
956+ let derived_key_value = if let Attribute :: Value ( value) = derived_key_value {
957+ value
958+ } else {
959+ panic ! ( "Expected value attribute." ) ;
960+ } ;
961+
962+ assert_eq ! ( & derived_key_value, & [ 0 ; 6 ] ) ;
963+
964+ // Delete keys
965+ session. destroy_object ( key) ?;
966+ session. destroy_object ( derived_key) ?;
967+
968+ Ok ( ( ) )
969+ }
970+
971+ #[ test]
972+ #[ serial]
973+ #[ ignore = "unsupported by both SoftHSM and Kryoptic for the moment. See latchset/kryoptic#323 to track support" ]
974+ fn derive_key_extract_from_key ( ) -> TestResult {
975+ let ( pkcs11, slot) = init_pins ( ) ;
976+
977+ // Open a session and log in
978+ let session = pkcs11. open_rw_session ( slot) ?;
979+ session. login ( UserType :: User , Some ( & AuthPin :: new ( USER_PIN . into ( ) ) ) ) ?;
980+
981+ // Define key to extract from
982+ let data_value = [ 0x12 , 0x34 , 0x56 , 0x78 , 0x90 , 0x01 ] ;
983+
984+ let key_template = [
985+ Attribute :: Token ( true ) ,
986+ Attribute :: Private ( false ) ,
987+ Attribute :: Class ( ObjectClass :: SECRET_KEY ) ,
988+ Attribute :: KeyType ( KeyType :: GENERIC_SECRET ) ,
989+ Attribute :: Value ( data_value. to_vec ( ) ) ,
990+ Attribute :: Derive ( true ) ,
991+ ] ;
992+
993+ let key = session. create_object ( & key_template) ?;
994+
995+ // Derive key by extracting subset of base key
996+ let derived_key_template = [
997+ Attribute :: Token ( true ) ,
998+ Attribute :: Private ( false ) ,
999+ Attribute :: Sensitive ( false ) ,
1000+ Attribute :: Extractable ( true ) ,
1001+ ] ;
1002+ let params = ExtractParams :: new ( 3 ) ;
1003+ let derived_key = session. derive_key (
1004+ & Mechanism :: ExtractKeyFromKey ( params) ,
1005+ key,
1006+ & derived_key_template,
1007+ ) ?;
1008+
1009+ let derived_key_value = session
1010+ . get_attributes ( derived_key, & [ AttributeType :: Value ] ) ?
1011+ . remove ( 0 ) ;
1012+ let derived_key_value = if let Attribute :: Value ( value) = derived_key_value {
1013+ value
1014+ } else {
1015+ panic ! ( "Expected value attribute." ) ;
1016+ } ;
1017+
1018+ assert_eq ! ( & derived_key_value, & data_value[ 3 ..] ) ;
1019+
1020+ // Delete keys
1021+ session. destroy_object ( key) ?;
1022+ session. destroy_object ( derived_key) ?;
1023+
1024+ Ok ( ( ) )
1025+ }
1026+
7751027#[ test]
7761028#[ serial]
7771029fn import_export ( ) -> TestResult {
0 commit comments