summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/crypttab.xml24
-rw-r--r--src/cryptsetup/cryptsetup.c31
2 files changed, 52 insertions, 3 deletions
diff --git a/man/crypttab.xml b/man/crypttab.xml
index 3e249ad23e..d4ff760adc 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -146,6 +146,30 @@
</varlistentry>
<varlistentry>
+ <term><option>offset=</option></term>
+
+ <listitem><para>Start offset in the backend device, in 512-byte sectors.
+ This option is only relevant for plain devices.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>skip=</option></term>
+
+ <listitem><para>How many 512-byte sectors of the encrypted data to skip
+ at the beginning. This is different from the <option>--offset</option>
+ option with respect to the sector numbers used in initialization vector
+ (IV) calculation. Using <option>--offset</option> will shift the IV
+ calculation by the same negative amount. Hence, if <option>--offset n</option>,
+ sector n will get a sector number of 0 for the IV calculation.
+ Using <option>--skip</option> causes sector n to also be the first
+ sector of the mapped device, but with its number for IV generation is n.</para>
+
+ <para>This option is only relevant for plain devices.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>keyfile-offset=</option></term>
<listitem><para>Specifies the number of bytes to skip at the
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index ba0ef72d06..a5018f13ed 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -50,12 +50,12 @@ static bool arg_discards = false;
static bool arg_tcrypt_hidden = false;
static bool arg_tcrypt_system = false;
static char **arg_tcrypt_keyfiles = NULL;
+static uint64_t arg_offset = 0;
+static uint64_t arg_skip = 0;
static usec_t arg_timeout = 0;
/* Options Debian's crypttab knows we don't:
- offset=
- skip=
precheck=
check=
checkargs=
@@ -185,6 +185,20 @@ static int parse_one_option(const char *option) {
return 0;
}
+ } else if (startswith(option, "offset=")) {
+
+ if (safe_atou64(option+7, &arg_offset) < 0) {
+ log_error("offset= parse failure, refusing.");
+ return -EINVAL;
+ }
+
+ } else if (startswith(option, "skip=")) {
+
+ if (safe_atou64(option+5, &arg_skip) < 0) {
+ log_error("skip= parse failure, refusing.");
+ return -EINVAL;
+ }
+
} else if (!streq(option, "none"))
log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
@@ -209,6 +223,14 @@ static int parse_options(const char *options) {
return r;
}
+ /* sanity-check options */
+ if (arg_type != NULL && !streq(arg_type, CRYPT_PLAIN)) {
+ if (arg_offset)
+ log_warning("offset= ignored with type %s", arg_type);
+ if (arg_skip)
+ log_warning("skip= ignored with type %s", arg_type);
+ }
+
return 0;
}
@@ -410,7 +432,10 @@ static int attach_luks_or_plain(struct crypt_device *cd,
}
if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) {
- struct crypt_params_plain params = {};
+ struct crypt_params_plain params = {
+ .offset = arg_offset,
+ .skip = arg_skip,
+ };
const char *cipher, *cipher_mode;
_cleanup_free_ char *truncated_cipher = NULL;