@@ -35,24 +35,6 @@ static void _set_reencryption_flags(uint32_t *flags)
3535 * flags |= CRYPT_REENCRYPT_RESUME_ONLY ;
3636}
3737
38- static int reencrypt_check_passphrase (struct crypt_device * cd ,
39- int keyslot ,
40- const char * passphrase ,
41- size_t passphrase_len )
42- {
43- int r ;
44-
45- assert (cd );
46-
47- r = crypt_activate_by_passphrase (cd , NULL , keyslot ,
48- passphrase , passphrase_len , 0 );
49- check_signal (& r );
50- tools_passphrase_msg (r );
51- tools_keyslot_msg (r , UNLOCKED );
52-
53- return r ;
54- }
55-
5638static int set_keyslot_params (struct crypt_device * cd , int keyslot )
5739{
5840 const char * cipher ;
@@ -266,6 +248,114 @@ static int reencrypt_hint_force_offline_reencrypt(const char *data_device)
266248 return 0 ;
267249}
268250
251+ /* libcryptsetup API does not provide function to get old volume key size directly */
252+ static int reencrypt_get_decrypt_volume_key_size (struct crypt_device * cd , int keyslot )
253+ {
254+ int i ;
255+ crypt_keyslot_info ki ;
256+
257+ if (keyslot != CRYPT_ANY_SLOT ) {
258+ ki = crypt_keyslot_status (cd , keyslot );
259+ if (ki == CRYPT_SLOT_INVALID )
260+ return - EINVAL ;
261+ if (ki != CRYPT_SLOT_ACTIVE && ki != CRYPT_SLOT_ACTIVE_LAST )
262+ return - ENOENT ;
263+
264+ return crypt_keyslot_get_key_size (cd , keyslot );
265+ }
266+
267+ for (i = 0 ; i < crypt_keyslot_max (CRYPT_LUKS2 ); i ++ ) {
268+ switch (crypt_keyslot_status (cd , keyslot )) {
269+ case CRYPT_SLOT_INACTIVE :
270+ case CRYPT_SLOT_UNBOUND :
271+ break ;
272+ case CRYPT_SLOT_ACTIVE :
273+ case CRYPT_SLOT_ACTIVE_LAST :
274+ return crypt_keyslot_get_key_size (cd , keyslot );
275+ default :
276+ return - EINVAL ;
277+ }
278+ }
279+
280+ return - ENOENT ;
281+ }
282+
283+ static int reencrypt_single_key_unlock (struct crypt_device * cd ,
284+ const struct crypt_params_reencrypt * params ,
285+ struct crypt_keyslot_context * * r_kc )
286+ {
287+ int r , tries , keysize = 0 ;
288+ struct crypt_keyslot_context * kc = NULL , * dummy = NULL ;
289+
290+ assert (params );
291+ assert (r_kc );
292+
293+ if (ARG_SET (OPT_KEY_SIZE_ID ))
294+ keysize = ARG_UINT32 (OPT_KEY_SIZE_ID ) / 8 ;
295+
296+ if (ARG_SET (OPT_VOLUME_KEY_FILE_ID ) || ARG_SET (OPT_VOLUME_KEY_KEYRING_ID )) {
297+ if (!keysize && params -> mode == CRYPT_REENCRYPT_DECRYPT )
298+ keysize = reencrypt_get_decrypt_volume_key_size (cd , ARG_INT32 (OPT_KEY_SLOT_ID ));
299+ else if (!keysize && params -> mode == CRYPT_REENCRYPT_ENCRYPT )
300+ keysize = crypt_get_volume_key_size (cd );
301+
302+ if (keysize <= 0 && !ARG_SET (OPT_VOLUME_KEY_KEYRING_ID )) {
303+ log_err (_ ("Cannot determine volume key size for LUKS without keyslots, please use --key-size option." ));
304+ return - EINVAL ;
305+ }
306+
307+ r = luks_init_keyslot_contexts_by_volume_keys (cd , ARG_STR (OPT_VOLUME_KEY_FILE_ID ),
308+ NULL /* unused */ ,
309+ keysize ,
310+ 0 /* unused */ ,
311+ ARG_STR (OPT_VOLUME_KEY_KEYRING_ID ),
312+ NULL /* unused */ ,
313+ & kc , & dummy );
314+ if (r < 0 )
315+ goto out ;
316+ r = crypt_activate_by_keyslot_context (cd , NULL , ARG_INT32 (OPT_KEY_SLOT_ID ),
317+ kc , CRYPT_ANY_SLOT , NULL , 0 );
318+ } else {
319+ r = luks_try_token_unlock (cd , ARG_INT32 (OPT_KEY_SLOT_ID ),
320+ ARG_INT32 (OPT_TOKEN_ID_ID ), NULL ,
321+ ARG_STR (OPT_TOKEN_TYPE_ID ), 0 ,
322+ set_tries_tty (false), true,
323+ ARG_SET (OPT_TOKEN_ONLY_ID ) || ARG_SET (OPT_TOKEN_ID_ID ) || ARG_SET (OPT_TOKEN_TYPE_ID ),
324+ & kc );
325+
326+ if (r >= 0 || quit || ARG_SET (OPT_TOKEN_ONLY_ID ))
327+ goto out ;
328+
329+ r = - ENOENT ;
330+
331+ tries = set_tries_tty (true);
332+ do {
333+ crypt_keyslot_context_free (kc );
334+ kc = NULL ;
335+ r = luks_init_keyslot_context (cd , NULL , verify_passphrase (0 ), false, & kc );
336+ if (r < 0 )
337+ goto out ;
338+
339+ r = crypt_activate_by_keyslot_context (cd , NULL , ARG_INT32 (OPT_KEY_SLOT_ID ),
340+ kc , CRYPT_ANY_SLOT , NULL , 0 );
341+
342+ tools_keyslot_msg (r , UNLOCKED );
343+ tools_passphrase_msg (r );
344+ check_signal (& r );
345+ } while ((r == - EPERM || r == - ERANGE ) && (-- tries > 0 ));
346+ }
347+
348+ out :
349+ if (r >= 0 )
350+ * r_kc = kc ;
351+ else
352+ crypt_keyslot_context_free (kc );
353+
354+ crypt_keyslot_context_free (dummy ); /* unused */
355+
356+ return r ;
357+ }
358+
269359static int reencrypt_luks2_load (struct crypt_device * cd , const char * data_device )
270360{
271361 char * msg ;
@@ -732,9 +822,8 @@ static int decrypt_luks2_datashift_init(struct crypt_device **cd,
732822 const char * expheader )
733823{
734824 int fd , r ;
735- size_t passwordLen ;
736825 struct stat hdr_st ;
737- char * msg , * data_device , * active_name = NULL , * password = NULL ;
826+ char * msg , * data_device , * active_name = NULL ;
738827 bool remove_header = false;
739828 struct crypt_params_reencrypt params = {
740829 .mode = CRYPT_REENCRYPT_DECRYPT ,
@@ -745,6 +834,7 @@ static int decrypt_luks2_datashift_init(struct crypt_device **cd,
745834 .max_hotzone_size = ARG_UINT64 (OPT_HOTZONE_SIZE_ID ) / SECTOR_SIZE ,
746835 .flags = CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT
747836 };
837+ struct crypt_keyslot_context * kc = NULL ;
748838
749839 assert (expheader );
750840 assert (cd && * cd );
@@ -775,14 +865,7 @@ static int decrypt_luks2_datashift_init(struct crypt_device **cd,
775865 if (r < 0 )
776866 goto out ;
777867
778- r = tools_get_key (NULL , & password , & passwordLen ,
779- ARG_UINT64 (OPT_KEYFILE_OFFSET_ID ), ARG_UINT32 (OPT_KEYFILE_SIZE_ID ),
780- ARG_STR (OPT_KEY_FILE_ID ), ARG_UINT32 (OPT_TIMEOUT_ID ),
781- verify_passphrase (0 ), 0 , * cd );
782- if (r < 0 )
783- goto out ;
784-
785- r = reencrypt_check_passphrase (* cd , ARG_INT32 (OPT_KEY_SLOT_ID ), password , passwordLen );
868+ r = reencrypt_single_key_unlock (* cd , & params , & kc );
786869 if (r < 0 )
787870 goto out ;
788871
@@ -844,9 +927,9 @@ static int decrypt_luks2_datashift_init(struct crypt_device **cd,
844927
845928 remove_header = false;
846929
847- r = crypt_reencrypt_init_by_passphrase (* cd , active_name , password ,
848- passwordLen , ARG_INT32 (OPT_KEY_SLOT_ID ), CRYPT_ANY_SLOT ,
849- NULL , NULL , & params );
930+ r = crypt_reencrypt_init_by_keyslot_context (* cd , active_name , kc , NULL ,
931+ ARG_INT32 (OPT_KEY_SLOT_ID ),
932+ CRYPT_ANY_SLOT , NULL , NULL , & params );
850933
851934 if (r < 0 && crypt_reencrypt_status (* cd , NULL ) == CRYPT_REENCRYPT_NONE ) {
852935 /* if restore is successful we can remove header backup */
@@ -856,7 +939,7 @@ static int decrypt_luks2_datashift_init(struct crypt_device **cd,
856939out :
857940 free (active_name );
858941 free (data_device );
859- crypt_safe_free ( password );
942+ crypt_keyslot_context_free ( kc );
860943
861944 if (r < 0 && !remove_header && !stat (expheader , & hdr_st ) && S_ISREG (hdr_st .st_mode ))
862945 log_err (_ ("Reencryption initialization failed. Header backup is available in %s." ),
@@ -870,8 +953,7 @@ static int decrypt_luks2_datashift_init(struct crypt_device **cd,
870953static int decrypt_luks2_init (struct crypt_device * cd , const char * data_device )
871954{
872955 int r ;
873- size_t passwordLen ;
874- char * active_name = NULL , * password = NULL ;
956+ char * active_name = NULL ;
875957 struct crypt_params_reencrypt params = {
876958 .mode = CRYPT_REENCRYPT_DECRYPT ,
877959 .direction = data_shift > 0 ? CRYPT_REENCRYPT_FORWARD : CRYPT_REENCRYPT_BACKWARD ,
@@ -881,6 +963,7 @@ static int decrypt_luks2_init(struct crypt_device *cd, const char *data_device)
881963 .device_size = ARG_UINT64 (OPT_DEVICE_SIZE_ID ) / SECTOR_SIZE ,
882964 .max_hotzone_size = ARG_UINT64 (OPT_HOTZONE_SIZE_ID ) / SECTOR_SIZE ,
883965 };
966+ struct crypt_keyslot_context * kc = NULL ;
884967
885968 if (!luks2_reencrypt_eligible (cd ))
886969 return - EINVAL ;
@@ -897,25 +980,21 @@ static int decrypt_luks2_init(struct crypt_device *cd, const char *data_device)
897980
898981 _set_reencryption_flags (& params .flags );
899982
900- r = tools_get_key (NULL , & password , & passwordLen ,
901- ARG_UINT64 (OPT_KEYFILE_OFFSET_ID ), ARG_UINT32 (OPT_KEYFILE_SIZE_ID ), ARG_STR (OPT_KEY_FILE_ID ),
902- ARG_UINT32 (OPT_TIMEOUT_ID ), verify_passphrase (0 ), 0 , cd );
903- if (r < 0 )
904- return r ;
905-
906- r = reencrypt_check_passphrase (cd , ARG_INT32 (OPT_KEY_SLOT_ID ), password , passwordLen );
983+ r = reencrypt_single_key_unlock (cd , & params , & kc );
907984 if (r < 0 )
908985 goto out ;
909986
910987 if (!ARG_SET (OPT_FORCE_OFFLINE_REENCRYPT_ID ))
911988 r = reencrypt_get_active_name (cd , data_device , & active_name );
912989 if (r >= 0 )
913- r = crypt_reencrypt_init_by_passphrase (cd , active_name , password ,
914- passwordLen , ARG_INT32 (OPT_KEY_SLOT_ID ), CRYPT_ANY_SLOT , NULL , NULL , & params );
990+ r = crypt_reencrypt_init_by_keyslot_context (cd , active_name , kc , NULL ,
991+ ARG_INT32 (OPT_KEY_SLOT_ID ),
992+ CRYPT_ANY_SLOT , NULL , NULL ,
993+ & params );
915994
916995out :
917996 free (active_name );
918- crypt_safe_free ( password );
997+ crypt_keyslot_context_free ( kc );
919998 return r ;
920999}
9211000
0 commit comments