mirror of
https://github.com/systemd/systemd
synced 2024-10-06 16:21:34 +00:00
veritysetup: add support for fec options
The verity fec_* parameters allows to use Forward Error Correction to recover from corruption if hash verification fails. This adds the options fec_device, fec_offset and fec_roots (sixth argument) which are the equivalent of the options --fec-device, --fec-offset and --fec-roots in the veritysetup world. - fec-device=FILE - fec-offset=BYTES - fec-roots=UINT64 See `veritysetup(8)` for more details.
This commit is contained in:
parent
0bbf7a842a
commit
21c60c76e1
|
@ -94,7 +94,8 @@
|
||||||
<option>salt=<replaceable>HEX</replaceable></option>, <option>uuid=<replaceable>UUID</replaceable></option>,
|
<option>salt=<replaceable>HEX</replaceable></option>, <option>uuid=<replaceable>UUID</replaceable></option>,
|
||||||
<option>ignore-corruption</option>, <option>restart-on-corruption</option>, <option>ignore-zero-blocks</option>,
|
<option>ignore-corruption</option>, <option>restart-on-corruption</option>, <option>ignore-zero-blocks</option>,
|
||||||
<option>check-at-most-once</option>, <option>panic-on-corruption</option>,
|
<option>check-at-most-once</option>, <option>panic-on-corruption</option>,
|
||||||
<option>hash=<replaceable>HASH</replaceable></option> and
|
<option>hash=<replaceable>HASH</replaceable></option>, <option>fec-device=<replaceable>PATH</replaceable></option>,
|
||||||
|
<option>fec-offset=<replaceable>BYTES</replaceable></option>, <option>fec-roots=<replaceable>NUM</replaceable></option> and
|
||||||
<option>root-hash-signature=<replaceable>PATH</replaceable>|base64:<replaceable>HEX</replaceable></option>. See
|
<option>root-hash-signature=<replaceable>PATH</replaceable>|base64:<replaceable>HEX</replaceable></option>. See
|
||||||
<citerefentry project='die-net'><refentrytitle>veritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry> for more
|
<citerefentry project='die-net'><refentrytitle>veritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry> for more
|
||||||
details.</para></listitem>
|
details.</para></listitem>
|
||||||
|
|
|
@ -157,6 +157,30 @@ This is based on crypttab(5).
|
||||||
see <command>veritysetup --help</command>.</para></listitem>
|
see <command>veritysetup --help</command>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>fec-device=<replaceable>PATH</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>Use forward error correction (FEC) to recover from corruption if hash verification fails. Use
|
||||||
|
encoding data from the specified device. The fec device argument can be block device or file image. For format,
|
||||||
|
if fec device path doesn't exist, it will be created as file. Note: block sizes for data and hash devices must
|
||||||
|
match. Also, if the verity data_device is encrypted the fec_device should be too.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>fec-offset=<replaceable>BYTES</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>This is the offset, in bytes, from the start of the FEC device to the beginning of the encoding
|
||||||
|
data. (Aligned on 512 bytes.)</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>fec-roots=<replaceable>NUM</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>Number of generator roots. This equals to the number of parity bytes in the encoding data. In
|
||||||
|
RS(M, N) encoding, the number of roots is M-N. M is 255 and M-N is between 2 and 24 (including).</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>root-hash-signature=<replaceable>PATH</replaceable>|base64:<replaceable>HEX</replaceable></option></term>
|
<term><option>root-hash-signature=<replaceable>PATH</replaceable>|base64:<replaceable>HEX</replaceable></option></term>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "cryptsetup-util.h"
|
#include "cryptsetup-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
#include "fstab-util.h"
|
||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
|
@ -28,11 +29,15 @@ static void *arg_salt = NULL;
|
||||||
static uint64_t arg_salt_size = 32;
|
static uint64_t arg_salt_size = 32;
|
||||||
static char *arg_uuid = NULL;
|
static char *arg_uuid = NULL;
|
||||||
static uint32_t arg_activate_flags = CRYPT_ACTIVATE_READONLY;
|
static uint32_t arg_activate_flags = CRYPT_ACTIVATE_READONLY;
|
||||||
|
static char *arg_fec_what = NULL;
|
||||||
|
static uint64_t arg_fec_offset = 0;
|
||||||
|
static uint64_t arg_fec_roots = 2;
|
||||||
static char *arg_root_hash_signature = NULL;
|
static char *arg_root_hash_signature = NULL;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_hash, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_hash, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_salt, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_salt, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_uuid, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_uuid, freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_fec_what, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_root_hash_signature, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root_hash_signature, freep);
|
||||||
|
|
||||||
static int help(void) {
|
static int help(void) {
|
||||||
|
@ -221,6 +226,42 @@ static int parse_options(const char *options) {
|
||||||
r = free_and_strdup(&arg_hash, val);
|
r = free_and_strdup(&arg_hash, val);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
} else if ((val = startswith(word, "fec-device="))) {
|
||||||
|
_cleanup_free_ char *what = NULL;
|
||||||
|
|
||||||
|
what = fstab_node_to_udev_node(val);
|
||||||
|
if (!what)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
if (!path_is_absolute(what))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "fec-device= expects an absolute path.");
|
||||||
|
|
||||||
|
if (!path_is_normalized(what))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "fec-device= expects an normalized path.");
|
||||||
|
|
||||||
|
r = free_and_strdup(&arg_fec_what, what);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
} else if ((val = startswith(word, "fec-offset="))) {
|
||||||
|
uint64_t off;
|
||||||
|
|
||||||
|
r = parse_size(val, 1024, &off);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse offset '%s': %m", word);
|
||||||
|
if (off % 512 != 0)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "fec-offset= expects a 512-byte aligned value.");
|
||||||
|
|
||||||
|
arg_fec_offset = off;
|
||||||
|
} else if ((val = startswith(word, "fec-roots="))) {
|
||||||
|
uint64_t u;
|
||||||
|
|
||||||
|
r = safe_atou64(val, &u);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse number '%s', ignoring: %m", word);
|
||||||
|
if (u < 2 || u > 24)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "fec-rootfs= expects a value between 2 and 24 (including).");
|
||||||
|
|
||||||
|
arg_fec_roots = u;
|
||||||
} else if ((val = startswith(word, "root-hash-signature="))) {
|
} else if ((val = startswith(word, "root-hash-signature="))) {
|
||||||
r = save_roothashsig_option(val, /* strict= */ true);
|
r = save_roothashsig_option(val, /* strict= */ true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -295,7 +336,10 @@ static int run(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (arg_superblock) {
|
if (arg_superblock) {
|
||||||
p = (struct crypt_params_verity) {
|
p = (struct crypt_params_verity) {
|
||||||
|
.fec_device = arg_fec_what,
|
||||||
.hash_area_offset = arg_hash_offset,
|
.hash_area_offset = arg_hash_offset,
|
||||||
|
.fec_area_offset = arg_fec_offset,
|
||||||
|
.fec_roots = arg_fec_roots,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = crypt_load(cd, CRYPT_VERITY, &p);
|
r = crypt_load(cd, CRYPT_VERITY, &p);
|
||||||
|
@ -305,6 +349,7 @@ static int run(int argc, char *argv[]) {
|
||||||
p = (struct crypt_params_verity) {
|
p = (struct crypt_params_verity) {
|
||||||
.hash_name = arg_hash,
|
.hash_name = arg_hash,
|
||||||
.data_device = data_device,
|
.data_device = data_device,
|
||||||
|
.fec_device = arg_fec_what,
|
||||||
.salt = arg_salt,
|
.salt = arg_salt,
|
||||||
.salt_size = arg_salt_size,
|
.salt_size = arg_salt_size,
|
||||||
.hash_type = arg_format,
|
.hash_type = arg_format,
|
||||||
|
@ -312,6 +357,8 @@ static int run(int argc, char *argv[]) {
|
||||||
.hash_block_size = arg_hash_block_size,
|
.hash_block_size = arg_hash_block_size,
|
||||||
.data_size = arg_data_blocks,
|
.data_size = arg_data_blocks,
|
||||||
.hash_area_offset = arg_hash_offset,
|
.hash_area_offset = arg_hash_offset,
|
||||||
|
.fec_area_offset = arg_fec_offset,
|
||||||
|
.fec_roots = arg_fec_roots,
|
||||||
.flags = CRYPT_VERITY_NO_HEADER,
|
.flags = CRYPT_VERITY_NO_HEADER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue