diff --git a/cryptsetup_1.7.1+nuke_keys.diff b/cryptsetup_1.7.1+nuke_keys.diff new file mode 100644 index 0000000..937149e --- /dev/null +++ b/cryptsetup_1.7.1+nuke_keys.diff @@ -0,0 +1,146 @@ +diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h +index 80bbf5c..7bf2503 100644 +--- a/lib/libcryptsetup.h ++++ b/lib/libcryptsetup.h +@@ -663,6 +663,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot); + #define CRYPT_ACTIVATE_PRIVATE (1 << 4) + /** corruption detected (verity), output only */ + #define CRYPT_ACTIVATE_CORRUPTED (1 << 5) ++/** key slot is a nuke, will wipe all keyslots */ ++#define CRYPT_ACTIVATE_NUKE (1 << 30) + /** use same_cpu_crypt option for dm-crypt */ + #define CRYPT_ACTIVATE_SAME_CPU_CRYPT (1 << 6) + /** use submit_from_crypt_cpus for dm-crypt */ +diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c +index 40117b2..087938d 100644 +--- a/lib/luks1/keymanage.c ++++ b/lib/luks1/keymanage.c +@@ -964,6 +964,24 @@ static int LUKS_open_key(unsigned int keyIndex, + + if (!r) + log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex); ++ ++ /* check whether key in key slot is a NUKE (then wipe all keyslots) */ ++ if(vk->key[0] == 0) { ++ int i=1; ++ ++ while(ikeylength && vk->key[i]==0) { ++ i++; ++ } ++ if(i == vk->keylength) { ++ /* vk is all 0's: WIPE ALL KEYSLOTS and log a fake error message */ ++ log_err(ctx, _("Failed to read from key storage.\n")); ++ for(i=0; i 0) && ((keyslot & CRYPT_ACTIVATE_NUKE) != 0) ) { ++ nuke = 1; ++ keyslot ^= CRYPT_ACTIVATE_NUKE; ++ } ++ if( (keyslot < 0) && ((keyslot & CRYPT_ACTIVATE_NUKE) == 0) ) { ++ nuke = 1; ++ keyslot ^= CRYPT_ACTIVATE_NUKE; ++ } + +- if (!passphrase || !new_passphrase) +- return -EINVAL; ++ r = onlyLUKS(cd); ++ if (r < 0) ++ return r; ++ ++ if (!passphrase || !new_passphrase) ++ return -EINVAL; ++ ++ r = keyslot_verify_or_find_empty(cd, &keyslot); ++ if (r) ++ return r; + +- r = keyslot_verify_or_find_empty(cd, &keyslot); +- if (r) +- return r; + + if (!LUKS_keyslot_active_count(&cd->u.luks1.hdr)) { + /* No slots used, try to use pre-generated key in header */ +@@ -1567,6 +1578,10 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd, + if(r < 0) + goto out; + ++ if(nuke) { ++ memset(vk->key, '\0', vk->keylength); ++ } ++ + r = LUKS_set_key(keyslot, CONST_CAST(char*)new_passphrase, new_passphrase_size, + &cd->u.luks1.hdr, vk, cd->iteration_time, &cd->u.luks1.PBKDF2_per_sec, cd); + if(r < 0) +diff --git a/src/cryptsetup.c b/src/cryptsetup.c +index bc484e0..88b6ede 100644 +--- a/src/cryptsetup.c ++++ b/src/cryptsetup.c +@@ -37,6 +37,7 @@ static const char *opt_header_backup_file = NULL; + static const char *opt_uuid = NULL; + static const char *opt_header_device = NULL; + static const char *opt_type = "luks"; ++static int currentlyNuking = 0; + static int opt_key_size = 0; + static long opt_keyfile_size = 0; + static long opt_new_keyfile_size = 0; +@@ -1028,6 +1029,10 @@ static int action_luksAddKey(void) + if (r < 0) + goto out; + ++ if(currentlyNuking == 1) { ++ opt_key_slot ^= CRYPT_ACTIVATE_NUKE; ++ } ++ + r = crypt_keyslot_add_by_passphrase(cd, opt_key_slot, + password, password_size, + password_new, password_new_size); +@@ -1040,6 +1045,15 @@ out: + return r; + } + ++static int action_luksAddNuke(void) ++{ ++ int results; ++ currentlyNuking = 1; ++ results = action_luksAddKey(); ++ currentlyNuking = 0; ++ return(results); ++} ++ + static int action_luksChangeKey(void) + { + const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL); +@@ -1381,6 +1395,7 @@ static struct action_type { + { "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") }, ++ { "luksAddNuke", action_luksAddNuke, 1, 1, N_(" []"), N_("add NUKE to LUKS device") }, + { "luksRemoveKey",action_luksRemoveKey,1, 1, N_(" []"), N_("removes supplied key or key file from LUKS device") }, + { "luksChangeKey",action_luksChangeKey,1, 1, N_(" []"), N_("changes supplied key or key file of LUKS device") }, + { "luksKillSlot", action_luksKillSlot, 2, 1, N_(" "), N_("wipes key with number from LUKS device") },