--- a/src/cryptsetup/cryptsetup.c 2014-08-01 07:30:31.382931869 +0300 +++ b/src/cryptsetup/cryptsetup.c 2014-08-01 07:31:08.258990394 +0300 @@ -43,6 +43,7 @@ static unsigned arg_keyfile_size = 0; static unsigned arg_keyfile_offset = 0; static char *arg_hash = NULL; +static char *arg_header = NULL; static unsigned arg_tries = 3; static bool arg_readonly = false; static bool arg_verify = false; @@ -136,6 +137,17 @@ free(arg_hash); arg_hash = t; + } else if (startswith(option, "header=")) { + arg_type = CRYPT_LUKS1; + + if(!path_is_absolute(option+7)) + log_error("Header path '%s' is not absolute. Ignoring.", option+7); + + free(arg_header); + arg_header = strdup(option+7); + if (!arg_header) + return log_oom(); + } else if (startswith(option, "tries=")) { if (safe_atou(option+6, &arg_tries) < 0) { @@ -379,6 +391,7 @@ static int attach_luks_or_plain(struct crypt_device *cd, const char *name, const char *key_file, + const char *data_device, char **passwords, uint32_t flags) { int r = 0; @@ -388,9 +401,13 @@ assert(name); assert(key_file || passwords); - if (!arg_type || streq(arg_type, CRYPT_LUKS1)) + if (!arg_type || streq(arg_type, CRYPT_LUKS1)) { r = crypt_load(cd, CRYPT_LUKS1, NULL); + if (data_device) + r = crypt_set_data_device(cd, data_device); + } + if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) { struct crypt_params_plain params = {}; const char *cipher, *cipher_mode; @@ -559,6 +576,14 @@ name = name_buffer ? name_buffer : argv[2]; k = crypt_init(&cd, argv[3]); + + if(arg_header) { + log_info("LUKS header: %s", arg_header); + k = crypt_init(&cd, arg_header); + } else { + k = crypt_init(&cd, argv[3]); + } + if (k) { log_error("crypt_init() failed: %s", strerror(-k)); goto finish; @@ -609,7 +634,7 @@ if (streq_ptr(arg_type, CRYPT_TCRYPT)) k = attach_tcrypt(cd, argv[2], key_file, passwords, flags); else - k = attach_luks_or_plain(cd, argv[2], key_file, passwords, flags); + k = attach_luks_or_plain(cd, argv[2], key_file, ( arg_header ? argv[3] : NULL), passwords, flags); if (k >= 0) break; else if (k == -EAGAIN) { @@ -660,6 +685,7 @@ free(arg_cipher); free(arg_hash); + free(arg_header); strv_free(arg_tcrypt_keyfiles); return r;