diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 15fe1dd7..4a8543ce 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -298,6 +298,15 @@ last remaining passphrase from a LUKS container. Removing the last passphrase makes the LUKS container permanently inaccessible. .PP +\fIerase\fR +.br +\fIluksErase\fR +.IP +Erase all keyslots and make the LUKS container permanently inaccessible. +You do not need to provide any password for this operation. + +\fBWARNING:\fR This operation is irreversible. +.PP \fIluksUUID\fR .IP Print the UUID of a LUKS device. diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 3efbc703..22fe4a5f 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -1269,6 +1269,47 @@ args: return -EINVAL; } +static int action_luksErase(void) +{ + struct crypt_device *cd = NULL; + crypt_keyslot_info ki; + char *msg = NULL; + int i, r; + + if ((r = crypt_init(&cd, uuid_or_device(action_argv[0])))) + goto out; + + crypt_set_confirm_callback(cd, yesDialog, NULL); + + if ((r = crypt_load(cd, CRYPT_LUKS1, NULL))) + goto out; + + if(asprintf(&msg, _("This operation will erase all keyslots on device %s.\n" + "Device will become unusable after this operation."), + uuid_or_device(action_argv[0])) == -1) { + r = -ENOMEM; + goto out; + } + + if (!yesDialog(msg, NULL)) { + r = -EPERM; + goto out; + } + + for (i = 0; i < crypt_keyslot_max(CRYPT_LUKS1); i++) { + ki = crypt_keyslot_status(cd, i); + if (ki == CRYPT_SLOT_ACTIVE || ki == CRYPT_SLOT_ACTIVE_LAST) { + r = crypt_keyslot_destroy(cd, i); + if (r < 0) + goto out; + } + } +out: + free(msg); + crypt_free(cd); + return r; +} + static struct action_type { const char *type; int (*handler)(void); @@ -1283,6 +1324,7 @@ static struct action_type { { "status", action_status, 1, 0, N_(""), N_("show device status") }, { "benchmark", action_benchmark, 0, 0, N_(""), N_("benchmark cipher") }, { "repair", action_luksRepair, 1, 1, N_(""), N_("try to repair on-disk metadata") }, + { "erase", action_luksErase , 1, 1, N_(""), N_("erase all keyslots (remove encryption key)") }, { "luksFormat", action_luksFormat, 1, 1, N_(" []"), N_("formats a LUKS device") }, { "luksAddKey", action_luksAddKey, 1, 1, N_(" []"), N_("add key to LUKS device") }, { "luksRemoveKey",action_luksRemoveKey,1, 1, N_(" []"), N_("removes supplied key or key file from LUKS device") }, @@ -1534,6 +1576,9 @@ int main(int argc, const char **argv) !strcmp(aname, "loopaesClose") || !strcmp(aname, "tcryptClose")) { aname = "close"; + } else if (!strcmp(aname, "luksErase")) { + aname = "erase"; + opt_type = "luks"; } for(action = action_types; action->type; action++) diff --git a/tests/compat-test b/tests/compat-test index 80606728..86ec8e44 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -546,5 +546,14 @@ $CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail +prepare "[30] LUKS erase" wipe +$CRYPTSETUP -q luksFormat -i1 $LOOPDEV $KEY5 --key-slot 5 || fail +$CRYPTSETUP luksAddKey -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: ENABLED" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: ENABLED" || fail +$CRYPTSETUP luksErase -q $LOOPDEV || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: DISABLED" || fail + remove_mapping exit 0