4141#define VERSION "v1.2.0"
4242#endif
4343
44+ #ifndef BLKCRYPTOIMPORTKEY
45+
46+ struct blk_crypto_import_key_arg {
47+ __u64 raw_key_ptr ;
48+ __u64 raw_key_size ;
49+ __u64 lt_key_ptr ;
50+ __u64 lt_key_size ;
51+ __u64 reserved [4 ];
52+ };
53+
54+ struct blk_crypto_generate_key_arg {
55+ __u64 lt_key_ptr ;
56+ __u64 lt_key_size ;
57+ __u64 reserved [4 ];
58+ };
59+
60+ struct blk_crypto_prepare_key_arg {
61+ __u64 lt_key_ptr ;
62+ __u64 lt_key_size ;
63+ __u64 eph_key_ptr ;
64+ __u64 eph_key_size ;
65+ __u64 reserved [4 ];
66+ };
67+
68+ #define BLKCRYPTOIMPORTKEY _IOWR(0x12, 137, struct blk_crypto_import_key_arg)
69+ #define BLKCRYPTOGENERATEKEY \
70+ _IOWR(0x12, 138, struct blk_crypto_generate_key_arg)
71+ #define BLKCRYPTOPREPAREKEY _IOWR(0x12, 139, struct blk_crypto_prepare_key_arg)
72+
73+ #endif /* BLKCRYPTOIMPORTKEY */
74+
4475#define MAX_WRAPPED_KEY_SIZE 128
4576
4677#define ARRAY_SIZE (array ) (sizeof(array) / sizeof((array)[0]))
@@ -133,6 +164,13 @@ static void __attribute__((__noreturn__)) usage(FILE *out) {
133164 " fscryptctl set_policy <key identifier> <directory>\n"
134165 " Set up an encryption policy on the specified directory with the\n"
135166 " specified key identifier.\n"
167+ " fscryptctl import_hw_wrapped_key <block device>\n"
168+ " Create a hardware-wrapped key by importing a raw key.\n"
169+ " fscryptctl generate_hw_wrapped_key <block device>\n"
170+ " Create a hardware-wrapped key by generating one in hardware.\n"
171+ " fscryptctl prepare_hw_wrapped_key <block device>\n"
172+ " Prepare a hardware-wrapped key to be used by converting it from\n"
173+ " long-term wrapped form to ephemerally-wrapped form.\n"
136174 "\nOptions:\n"
137175 " -h, --help\n"
138176 " print this help screen\n"
@@ -778,6 +816,125 @@ static int cmd_set_policy(int argc, char *const argv[]) {
778816 return EXIT_SUCCESS ;
779817}
780818
819+ static int cmd_import_hw_wrapped_key (int argc , char * const argv []) {
820+ handle_no_options (& argc , & argv );
821+ if (argc != 1 ) {
822+ fputs ("error: must specify a block device\n" , stderr );
823+ return EXIT_FAILURE ;
824+ }
825+ const char * blkdev = argv [0 ];
826+ int status = EXIT_FAILURE ;
827+
828+ struct blk_crypto_import_key_arg arg = {0 };
829+ uint8_t * raw_key = xzalloc (FSCRYPT_MAX_KEY_SIZE );
830+ uint8_t * lt_key = xzalloc (MAX_WRAPPED_KEY_SIZE );
831+ arg .raw_key_ptr = (uintptr_t )raw_key ;
832+ arg .raw_key_size = read_key (raw_key , FSCRYPT_MAX_KEY_SIZE );
833+ if (arg .raw_key_size == 0 ) {
834+ goto cleanup ;
835+ }
836+ arg .lt_key_ptr = (uintptr_t )lt_key ;
837+ arg .lt_key_size = MAX_WRAPPED_KEY_SIZE ;
838+
839+ int fd = open (blkdev , O_RDONLY | O_CLOEXEC );
840+ if (fd < 0 ) {
841+ fprintf (stderr , "error: opening %s: %s\n" , blkdev , strerror (errno ));
842+ goto cleanup ;
843+ }
844+ if (ioctl (fd , BLKCRYPTOIMPORTKEY , & arg ) != 0 ) {
845+ fprintf (stderr , "error: importing hardware-wrapped key: %s\n" ,
846+ strerror (errno ));
847+ close (fd );
848+ goto cleanup ;
849+ }
850+ close (fd );
851+ if (!full_write (STDOUT_FILENO , lt_key , arg .lt_key_size )) {
852+ goto cleanup ;
853+ }
854+ status = EXIT_SUCCESS ;
855+ cleanup :
856+ wipe_and_free (raw_key , FSCRYPT_MAX_KEY_SIZE );
857+ wipe_and_free (lt_key , MAX_WRAPPED_KEY_SIZE );
858+ return status ;
859+ }
860+
861+ static int cmd_generate_hw_wrapped_key (int argc , char * const argv []) {
862+ handle_no_options (& argc , & argv );
863+ if (argc != 1 ) {
864+ fputs ("error: must specify a block device\n" , stderr );
865+ return EXIT_FAILURE ;
866+ }
867+ const char * blkdev = argv [0 ];
868+ int status = EXIT_FAILURE ;
869+
870+ struct blk_crypto_generate_key_arg arg = {0 };
871+ uint8_t * lt_key = xzalloc (MAX_WRAPPED_KEY_SIZE );
872+ arg .lt_key_ptr = (uintptr_t )lt_key ;
873+ arg .lt_key_size = MAX_WRAPPED_KEY_SIZE ;
874+
875+ int fd = open (blkdev , O_RDONLY | O_CLOEXEC );
876+ if (fd < 0 ) {
877+ fprintf (stderr , "error: opening %s: %s\n" , blkdev , strerror (errno ));
878+ goto cleanup ;
879+ }
880+ if (ioctl (fd , BLKCRYPTOGENERATEKEY , & arg ) != 0 ) {
881+ fprintf (stderr , "error: generating hardware-wrapped key: %s\n" ,
882+ strerror (errno ));
883+ close (fd );
884+ goto cleanup ;
885+ }
886+ close (fd );
887+ if (!full_write (STDOUT_FILENO , lt_key , arg .lt_key_size )) {
888+ goto cleanup ;
889+ }
890+ status = EXIT_SUCCESS ;
891+ cleanup :
892+ wipe_and_free (lt_key , MAX_WRAPPED_KEY_SIZE );
893+ return status ;
894+ }
895+
896+ static int cmd_prepare_hw_wrapped_key (int argc , char * const argv []) {
897+ handle_no_options (& argc , & argv );
898+ if (argc != 1 ) {
899+ fputs ("error: must specify a block device\n" , stderr );
900+ return EXIT_FAILURE ;
901+ }
902+ const char * blkdev = argv [0 ];
903+ int status = EXIT_FAILURE ;
904+
905+ struct blk_crypto_prepare_key_arg arg = {0 };
906+ uint8_t * lt_key = xzalloc (MAX_WRAPPED_KEY_SIZE );
907+ uint8_t * eph_key = xzalloc (MAX_WRAPPED_KEY_SIZE );
908+ arg .lt_key_ptr = (uintptr_t )lt_key ;
909+ arg .lt_key_size = read_key (lt_key , MAX_WRAPPED_KEY_SIZE );
910+ if (arg .lt_key_size == 0 ) {
911+ goto cleanup ;
912+ }
913+ arg .eph_key_ptr = (uintptr_t )eph_key ;
914+ arg .eph_key_size = MAX_WRAPPED_KEY_SIZE ;
915+
916+ int fd = open (blkdev , O_RDONLY | O_CLOEXEC );
917+ if (fd < 0 ) {
918+ fprintf (stderr , "error: opening %s: %s\n" , blkdev , strerror (errno ));
919+ goto cleanup ;
920+ }
921+ if (ioctl (fd , BLKCRYPTOPREPAREKEY , & arg ) != 0 ) {
922+ fprintf (stderr , "error: preparing hardware-wrapped key: %s\n" ,
923+ strerror (errno ));
924+ close (fd );
925+ goto cleanup ;
926+ }
927+ close (fd );
928+ if (!full_write (STDOUT_FILENO , eph_key , arg .eph_key_size )) {
929+ goto cleanup ;
930+ }
931+ status = EXIT_SUCCESS ;
932+ cleanup :
933+ wipe_and_free (lt_key , FSCRYPT_MAX_KEY_SIZE );
934+ wipe_and_free (eph_key , MAX_WRAPPED_KEY_SIZE );
935+ return status ;
936+ }
937+
781938// -----------------------------------------------------------------------------
782939// The main() function
783940// -----------------------------------------------------------------------------
@@ -786,9 +943,14 @@ static const struct {
786943 const char * name ;
787944 int (* func )(int argc , char * const argv []);
788945} commands [] = {
789- {"add_key" , cmd_add_key }, {"remove_key" , cmd_remove_key },
790- {"key_status" , cmd_key_status }, {"get_policy" , cmd_get_policy },
946+ {"add_key" , cmd_add_key },
947+ {"remove_key" , cmd_remove_key },
948+ {"key_status" , cmd_key_status },
949+ {"get_policy" , cmd_get_policy },
791950 {"set_policy" , cmd_set_policy },
951+ {"import_hw_wrapped_key" , cmd_import_hw_wrapped_key },
952+ {"generate_hw_wrapped_key" , cmd_generate_hw_wrapped_key },
953+ {"prepare_hw_wrapped_key" , cmd_prepare_hw_wrapped_key },
792954};
793955
794956int main (int argc , char * const argv []) {
0 commit comments