mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-15 04:40:05 +01:00
* Add --master-key-file option for luksFormat and luksAddKey.
Signed-off-by: Milan Broz <mbroz@redhat.com> git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@99 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
* Add new libcryptsetup API (documented in libcryptsetup.h).
|
* Add new libcryptsetup API (documented in libcryptsetup.h).
|
||||||
* Implement old API calls using new functions.
|
* Implement old API calls using new functions.
|
||||||
* Remove old API code helper functions.
|
* Remove old API code helper functions.
|
||||||
|
* Add --master-key-file option for luksFormat and luksAddKey.
|
||||||
|
|
||||||
2009-08-17 Milan Broz <mbroz@redhat.com>
|
2009-08-17 Milan Broz <mbroz@redhat.com>
|
||||||
* Fix PBKDF2 speed calculation for large passhrases.
|
* Fix PBKDF2 speed calculation for large passhrases.
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ use file as key material. With LUKS, key material supplied in key files via \-d
|
|||||||
|
|
||||||
If the key file is "-", stdin will be used. This is different from how cryptsetup usually reads from stdin. See section \fBNOTES ON PASSWORD PROCESSING\fR for more information.
|
If the key file is "-", stdin will be used. This is different from how cryptsetup usually reads from stdin. See section \fBNOTES ON PASSWORD PROCESSING\fR for more information.
|
||||||
.TP
|
.TP
|
||||||
|
.B "\-\-master-key-file"
|
||||||
|
Use pre-generated master key stored in file. For \fIluksFormat\fR it allows LUKS header reformatting with the same master key (if all other parameters are the same existing encrypted data remains intact).
|
||||||
|
|
||||||
|
For \fIluksAddKey\fR it allows adding new passphrase with only master key knowledge.
|
||||||
|
.TP
|
||||||
.B "\-\-key-slot, \-S"
|
.B "\-\-key-slot, \-S"
|
||||||
For LUKS operations that add key material, this options allows to you specify which key slot is selected for the new key. This option can be used for \fIluksFormat\fR and \fIluksAddKey\fR.
|
For LUKS operations that add key material, this options allows to you specify which key slot is selected for the new key. This option can be used for \fIluksFormat\fR and \fIluksAddKey\fR.
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
129
src/cryptsetup.c
129
src/cryptsetup.c
@@ -21,8 +21,9 @@ static char *opt_cipher = NULL;
|
|||||||
static char *opt_hash = NULL;
|
static char *opt_hash = NULL;
|
||||||
static int opt_verify_passphrase = 0;
|
static int opt_verify_passphrase = 0;
|
||||||
static char *opt_key_file = NULL;
|
static char *opt_key_file = NULL;
|
||||||
|
static char *opt_master_key_file = NULL;
|
||||||
static unsigned int opt_key_size = 0;
|
static unsigned int opt_key_size = 0;
|
||||||
static int opt_key_slot = -1;
|
static int opt_key_slot = CRYPT_ANY_SLOT;
|
||||||
static uint64_t opt_size = 0;
|
static uint64_t opt_size = 0;
|
||||||
static uint64_t opt_offset = 0;
|
static uint64_t opt_offset = 0;
|
||||||
static uint64_t opt_skip = 0;
|
static uint64_t opt_skip = 0;
|
||||||
@@ -163,7 +164,6 @@ static int action_create(int reload)
|
|||||||
.key_file = opt_key_file,
|
.key_file = opt_key_file,
|
||||||
.key_size = ((opt_key_size)?opt_key_size:DEFAULT_KEY_SIZE)/8,
|
.key_size = ((opt_key_size)?opt_key_size:DEFAULT_KEY_SIZE)/8,
|
||||||
.key_slot = opt_key_slot,
|
.key_slot = opt_key_slot,
|
||||||
.passphrase_fd = 0, /* stdin */
|
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = opt_size,
|
.size = opt_size,
|
||||||
.offset = opt_offset,
|
.offset = opt_offset,
|
||||||
@@ -247,7 +247,7 @@ static int action_status(int arg)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int action_luksFormat(int arg)
|
static int _action_luksFormat_generateMK()
|
||||||
{
|
{
|
||||||
struct crypt_options options = {
|
struct crypt_options options = {
|
||||||
.key_size = (opt_key_size ?: DEFAULT_LUKS_KEY_SIZE) / 8,
|
.key_size = (opt_key_size ?: DEFAULT_LUKS_KEY_SIZE) / 8,
|
||||||
@@ -262,16 +262,87 @@ static int action_luksFormat(int arg)
|
|||||||
.align_payload = opt_align_payload,
|
.align_payload = opt_align_payload,
|
||||||
.icb = &cmd_icb,
|
.icb = &cmd_icb,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return crypt_luksFormat(&options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _read_mk(const char *file, char **key, int keysize)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
*key = malloc(keysize);
|
||||||
|
if (!*key)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
fd = open(file, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
log_err("Cannot read keyfile %s.\n", file);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if ((read(fd, *key, keysize) != keysize)) {
|
||||||
|
log_err("Cannot read %d bytes from keyfile %s.\n", keysize, file);
|
||||||
|
close(fd);
|
||||||
|
memset(*key, 0, keysize);
|
||||||
|
free(*key);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _action_luksFormat_useMK()
|
||||||
|
{
|
||||||
|
int r = -EINVAL, keysize;
|
||||||
|
char *key = NULL, cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||||
|
struct crypt_device *cd = NULL;
|
||||||
|
struct crypt_params_luks1 params = {
|
||||||
|
.hash = opt_hash ?: DEFAULT_LUKS_HASH,
|
||||||
|
.data_alignment = opt_align_payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (parse_into_name_and_mode(opt_cipher ?: DEFAULT_LUKS_CIPHER, cipher, cipher_mode)) {
|
||||||
|
log_err("No known cipher specification pattern detected.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
keysize = (opt_key_size ?: DEFAULT_LUKS_KEY_SIZE) / 8;
|
||||||
|
if (_read_mk(opt_master_key_file, &key, keysize) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if ((r = crypt_init(&cd, action_argv[0])))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
crypt_set_password_verify(cd, 1);
|
||||||
|
crypt_set_timeout(cd, opt_timeout);
|
||||||
|
if (opt_iteration_time)
|
||||||
|
crypt_set_iterarion_time(cd, opt_iteration_time);
|
||||||
|
|
||||||
|
if ((r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, keysize, ¶ms)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot, key, keysize, NULL, 0);
|
||||||
|
out:
|
||||||
|
|
||||||
|
crypt_free(cd);
|
||||||
|
if (key) {
|
||||||
|
memset(key, 0, keysize);
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_luksFormat(int arg)
|
||||||
|
{
|
||||||
int r = 0; char *msg = NULL;
|
int r = 0; char *msg = NULL;
|
||||||
|
|
||||||
/* Avoid overwriting possibly wrong part of device than user requested by rejecting these options */
|
/* Avoid overwriting possibly wrong part of device than user requested by rejecting these options */
|
||||||
if (opt_offset || opt_skip) {
|
if (opt_offset || opt_skip) {
|
||||||
fprintf(stderr,"Options --offset and --skip are not supported for luksFormat.\n");
|
log_err("Options --offset and --skip are not supported for luksFormat.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."), options.device) == -1) {
|
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]) == -1) {
|
||||||
fputs(_("memory allocation error in action_luksFormat"), stderr);
|
log_err(_("memory allocation error in action_luksFormat"));
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
r = yesDialog(msg);
|
r = yesDialog(msg);
|
||||||
@@ -280,7 +351,10 @@ static int action_luksFormat(int arg)
|
|||||||
if (!r)
|
if (!r)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return crypt_luksFormat(&options);
|
if (opt_master_key_file)
|
||||||
|
return _action_luksFormat_useMK();
|
||||||
|
else
|
||||||
|
return _action_luksFormat_generateMK();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int action_luksOpen(int arg)
|
static int action_luksOpen(int arg)
|
||||||
@@ -304,7 +378,7 @@ static int action_luksOpen(int arg)
|
|||||||
|
|
||||||
static int action_luksDelKey(int arg)
|
static int action_luksDelKey(int arg)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"luksDelKey is a deprecated action name.\nPlease use luksKillSlot.\n");
|
log_err("luksDelKey is a deprecated action name.\nPlease use luksKillSlot.\n");
|
||||||
return action_luksKillSlot(arg);
|
return action_luksKillSlot(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,6 +410,37 @@ static int action_luksRemoveKey(int arg)
|
|||||||
return crypt_luksRemoveKey(&options);
|
return crypt_luksRemoveKey(&options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _action_luksAddKey_useMK()
|
||||||
|
{
|
||||||
|
int r = -EINVAL, keysize;
|
||||||
|
char *key = NULL;
|
||||||
|
struct crypt_device *cd = NULL;
|
||||||
|
|
||||||
|
if ((r = crypt_init(&cd, action_argv[0])))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
keysize = crypt_get_volume_key_size(cd);
|
||||||
|
crypt_set_password_verify(cd, 1);
|
||||||
|
crypt_set_timeout(cd, opt_timeout);
|
||||||
|
if (opt_iteration_time)
|
||||||
|
crypt_set_iterarion_time(cd, opt_iteration_time);
|
||||||
|
|
||||||
|
if (_read_mk(opt_master_key_file, &key, keysize) < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot, key, keysize, NULL, 0);
|
||||||
|
out:
|
||||||
|
crypt_free(cd);
|
||||||
|
if (key) {
|
||||||
|
memset(key, 0, keysize);
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_luksAddKey(int arg)
|
static int action_luksAddKey(int arg)
|
||||||
{
|
{
|
||||||
struct crypt_options options = {
|
struct crypt_options options = {
|
||||||
@@ -349,6 +454,9 @@ static int action_luksAddKey(int arg)
|
|||||||
.icb = &cmd_icb,
|
.icb = &cmd_icb,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (opt_master_key_file)
|
||||||
|
return _action_luksAddKey_useMK();
|
||||||
|
else
|
||||||
return crypt_luksAddKey(&options);
|
return crypt_luksAddKey(&options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,12 +551,12 @@ static int run_action(struct action_type *action)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action->required_memlock)
|
if (action->required_memlock)
|
||||||
memlock_inc(NULL);
|
crypt_memory_lock(NULL, 1);
|
||||||
|
|
||||||
r = action->handler(action->arg);
|
r = action->handler(action->arg);
|
||||||
|
|
||||||
if (action->required_memlock)
|
if (action->required_memlock)
|
||||||
memlock_dec(NULL);
|
crypt_memory_lock(NULL, 0);
|
||||||
|
|
||||||
if (action->required_dm_backend)
|
if (action->required_dm_backend)
|
||||||
dm_exit();
|
dm_exit();
|
||||||
@@ -476,6 +584,7 @@ int main(int argc, char **argv)
|
|||||||
{ "hash", 'h', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL },
|
{ "hash", 'h', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL },
|
||||||
{ "verify-passphrase", 'y', POPT_ARG_NONE, &opt_verify_passphrase, 0, N_("Verifies the passphrase by asking for it twice"), NULL },
|
{ "verify-passphrase", 'y', POPT_ARG_NONE, &opt_verify_passphrase, 0, N_("Verifies the passphrase by asking for it twice"), NULL },
|
||||||
{ "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 0, N_("Read the key from a file (can be /dev/random)"), NULL },
|
{ "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 0, N_("Read the key from a file (can be /dev/random)"), NULL },
|
||||||
|
{ "master-key-file", '\0', POPT_ARG_STRING, &opt_master_key_file, 0, N_("Read the volume (master) key from file."), NULL },
|
||||||
{ "key-size", 's', POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") },
|
{ "key-size", 's', POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") },
|
||||||
{ "key-slot", 'S', POPT_ARG_INT, &opt_key_slot, 0, N_("Slot number for new key (default is first free)"), NULL },
|
{ "key-slot", 'S', POPT_ARG_INT, &opt_key_slot, 0, N_("Slot number for new key (default is first free)"), NULL },
|
||||||
{ "size", 'b', POPT_ARG_STRING, &popt_tmp, 1, N_("The size of the device"), N_("SECTORS") },
|
{ "size", 'b', POPT_ARG_STRING, &popt_tmp, 1, N_("The size of the device"), N_("SECTORS") },
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
#define MAX_CIPHER_LEN 32
|
#define MAX_CIPHER_LEN 32
|
||||||
|
|
||||||
/* Helper funcions provided by internal libcryptsetup objects */
|
/* Helper funcions provided by internal libcryptsetup objects */
|
||||||
struct crypt_device;
|
|
||||||
void crypt_set_debug_level(int level);
|
|
||||||
void set_default_log(void (*log)(int class, char *msg));
|
void set_default_log(void (*log)(int class, char *msg));
|
||||||
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
||||||
#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
|
#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
|
||||||
|
|||||||
Reference in New Issue
Block a user