diff --git a/man/crypttab.xml b/man/crypttab.xml
index 3e249ad23e..d4ff760adc 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -145,6 +145,30 @@
option.
+
+
+
+ Start offset in the backend device, in 512-byte sectors.
+ This option is only relevant for plain devices.
+
+
+
+
+
+
+ How many 512-byte sectors of the encrypted data to skip
+ at the beginning. This is different from the
+ option with respect to the sector numbers used in initialization vector
+ (IV) calculation. Using will shift the IV
+ calculation by the same negative amount. Hence, if ,
+ sector n will get a sector number of 0 for the IV calculation.
+ Using causes sector n to also be the first
+ sector of the mapped device, but with its number for IV generation is n.
+
+ This option is only relevant for plain devices.
+
+
+
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;