PR/58212: Malte Dehling: Add zfs verification method
This commit is contained in:
parent
91e71a2ef4
commit
c162bcc0ed
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.22 2022/08/12 10:49:17 riastradh Exp $
|
||||
# $NetBSD: Makefile,v 1.23 2024/05/12 18:02:16 christos Exp $
|
||||
|
||||
RUMPPRG=cgdconfig
|
||||
MAN= cgdconfig.8
|
||||
|
@ -29,4 +29,19 @@ ARGON2_NO_THREADS=1
|
|||
.include "${NETBSDSRCDIR}/external/apache2/argon2/lib/libargon2/Makefile.inc"
|
||||
.endif
|
||||
|
||||
.if ${MKZFS} != "no"
|
||||
CPPFLAGS+= -DHAVE_ZFS
|
||||
|
||||
OSNET=${NETBSDSRCDIR}/external/cddl/osnet
|
||||
CPPFLAGS.cgdconfig.c+= -I${OSNET}/include
|
||||
CPPFLAGS.cgdconfig.c+= -I${OSNET}/sys
|
||||
CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/head
|
||||
CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/lib/libzpool/common
|
||||
CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/uts/common
|
||||
CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/uts/common/fs/zfs
|
||||
|
||||
COPTS.cgdconfig.c+= -Wno-unknown-pragmas
|
||||
COPTS.cgdconfig.c+= -Wno-strict-prototypes
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: cgdconfig.8,v 1.57 2022/08/12 10:49:47 riastradh Exp $
|
||||
.\" $NetBSD: cgdconfig.8,v 1.58 2024/05/12 18:02:16 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002, The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -27,7 +27,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 4, 2021
|
||||
.Dd May 12, 2024
|
||||
.Dt CGDCONFIG 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -270,6 +270,8 @@ scan for a valid Master Boot Record.
|
|||
scan for a valid GUID partition table.
|
||||
.It ffs
|
||||
scan for a valid FFS file system.
|
||||
.It zfs
|
||||
scan for a valid ZFS vdev label (if compiled with MKZFS).
|
||||
.It re-enter
|
||||
prompt for passphrase twice, and ensure entered passphrases are
|
||||
identical.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cgdconfig.c,v 1.62 2024/04/29 00:28:18 riastradh Exp $ */
|
||||
/* $NetBSD: cgdconfig.c,v 1.63 2024/05/12 18:02:16 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -33,7 +33,7 @@
|
|||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 2002, 2003\
|
||||
The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: cgdconfig.c,v 1.62 2024/04/29 00:28:18 riastradh Exp $");
|
||||
__RCSID("$NetBSD: cgdconfig.c,v 1.63 2024/05/12 18:02:16 christos Exp $");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARGON2
|
||||
|
@ -73,6 +73,11 @@ __RCSID("$NetBSD: cgdconfig.c,v 1.62 2024/04/29 00:28:18 riastradh Exp $");
|
|||
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#ifdef HAVE_ZFS
|
||||
#include <sys/vdev_impl.h>
|
||||
#include <sha2.h>
|
||||
#endif
|
||||
|
||||
#include "params.h"
|
||||
#include "pkcs5_pbkdf2.h"
|
||||
#include "utils.h"
|
||||
|
@ -98,11 +103,11 @@ enum action {
|
|||
|
||||
/* if nflag is set, do not configure/unconfigure the cgd's */
|
||||
|
||||
int nflag = 0;
|
||||
static int nflag = 0;
|
||||
|
||||
/* if Sflag is set, generate shared keys */
|
||||
|
||||
int Sflag = 0;
|
||||
static int Sflag = 0;
|
||||
|
||||
/* if pflag is set to PFLAG_STDIN read from stdin rather than getpass(3) */
|
||||
|
||||
|
@ -110,7 +115,7 @@ int Sflag = 0;
|
|||
#define PFLAG_GETPASS_ECHO 0x02
|
||||
#define PFLAG_GETPASS_MASK 0x03
|
||||
#define PFLAG_STDIN 0x04
|
||||
int pflag = PFLAG_GETPASS;
|
||||
static int pflag = PFLAG_GETPASS;
|
||||
|
||||
/*
|
||||
* When configuring all cgds, save a cache of shared keys for key
|
||||
|
@ -127,7 +132,7 @@ struct sharedkey {
|
|||
SLIST_ENTRY(sharedkey) used;
|
||||
int verified;
|
||||
};
|
||||
LIST_HEAD(, sharedkey) sharedkeys;
|
||||
static LIST_HEAD(, sharedkey) sharedkeys;
|
||||
SLIST_HEAD(sharedkeyhits, sharedkey);
|
||||
|
||||
static int configure(int, char **, struct params *, int);
|
||||
|
@ -170,11 +175,14 @@ static int verify_ffs(int);
|
|||
static int verify_reenter(struct params *);
|
||||
static int verify_mbr(int);
|
||||
static int verify_gpt(int);
|
||||
#ifdef HAVE_ZFS
|
||||
static int verify_zfs(int);
|
||||
#endif
|
||||
|
||||
__dead static void usage(void);
|
||||
|
||||
/* Verbose Framework */
|
||||
unsigned verbose = 0;
|
||||
static unsigned verbose = 0;
|
||||
|
||||
#define VERBOSE(x,y) if (verbose >= x) y
|
||||
#define VPRINTF(x,y) if (verbose >= x) (void)printf y
|
||||
|
@ -636,12 +644,12 @@ getkey_argon2id(const char *target, struct keygen *kg, size_t keylen)
|
|||
char *passp;
|
||||
char buf[1024];
|
||||
uint8_t raw[256];
|
||||
int err;
|
||||
int error;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s's passphrase%s:", target,
|
||||
pflag & PFLAG_GETPASS_ECHO ? " (echo)" : "");
|
||||
passp = maybe_getpass(buf);
|
||||
if ((err = argon2_hash(kg->kg_iterations, kg->kg_memory,
|
||||
if ((error = argon2_hash(kg->kg_iterations, kg->kg_memory,
|
||||
kg->kg_parallelism,
|
||||
passp, strlen(passp),
|
||||
bits_getbuf(kg->kg_salt),
|
||||
|
@ -649,7 +657,7 @@ getkey_argon2id(const char *target, struct keygen *kg, size_t keylen)
|
|||
raw, sizeof(raw),
|
||||
NULL, 0,
|
||||
Argon2_id, kg->kg_version)) != ARGON2_OK) {
|
||||
warnx("failed to generate Argon2id key, error code %d", err);
|
||||
warnx("failed to generate Argon2id key, error code %d", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1024,6 +1032,10 @@ verify(struct params *p, int fd)
|
|||
return verify_mbr(fd);
|
||||
case VERIFY_GPT:
|
||||
return verify_gpt(fd);
|
||||
#ifdef HAVE_ZFS
|
||||
case VERIFY_ZFS:
|
||||
return verify_zfs(fd);
|
||||
#endif
|
||||
default:
|
||||
warnx("unimplemented verification method");
|
||||
return -1;
|
||||
|
@ -1161,7 +1173,6 @@ verify_gpt(int fd)
|
|||
return -1;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
for (blksize = DEV_BSIZE;
|
||||
(off = (blksize * GPT_HDR_BLKNO)) <= SCANSIZE - sizeof(hdr);
|
||||
blksize <<= 1) {
|
||||
|
@ -1173,15 +1184,114 @@ verify_gpt(int fd)
|
|||
|
||||
hdr.hdr_crc_self = 0;
|
||||
if (crc32(&hdr, sizeof(hdr))) {
|
||||
ret = 0;
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZFS
|
||||
|
||||
#define ZIO_CHECKSUM_BE(zcp) \
|
||||
{ \
|
||||
(zcp)->zc_word[0] = BE_64((zcp)->zc_word[0]); \
|
||||
(zcp)->zc_word[1] = BE_64((zcp)->zc_word[1]); \
|
||||
(zcp)->zc_word[2] = BE_64((zcp)->zc_word[2]); \
|
||||
(zcp)->zc_word[3] = BE_64((zcp)->zc_word[3]); \
|
||||
}
|
||||
|
||||
static int
|
||||
verify_zfs(int fd)
|
||||
{
|
||||
off_t vdev_size;
|
||||
int rv = 1;
|
||||
|
||||
if (prog_ioctl(fd, DIOCGMEDIASIZE, &vdev_size) == -1) {
|
||||
warn("%s: ioctl", __func__);
|
||||
return rv;
|
||||
}
|
||||
|
||||
vdev_phys_t *vdev_phys = emalloc(sizeof(*vdev_phys));
|
||||
for (size_t i = 0; i < VDEV_LABELS; i++) {
|
||||
off_t vdev_phys_off = (i < VDEV_LABELS / 2 ?
|
||||
i * sizeof(vdev_label_t) :
|
||||
vdev_size - (VDEV_LABELS - i) * sizeof(vdev_label_t))
|
||||
+ offsetof(vdev_label_t, vl_vdev_phys);
|
||||
|
||||
ssize_t ret = prog_pread(fd, vdev_phys, sizeof(*vdev_phys),
|
||||
vdev_phys_off);
|
||||
if (ret == -1) {
|
||||
warn("%s: read failed", __func__);
|
||||
goto out;
|
||||
}
|
||||
if ((size_t)ret < sizeof(*vdev_phys)) {
|
||||
warnx("%s: incomplete block", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bool byteswap;
|
||||
switch (vdev_phys->vp_zbt.zec_magic) {
|
||||
case BSWAP_64(ZEC_MAGIC):
|
||||
byteswap = true;
|
||||
break;
|
||||
case ZEC_MAGIC:
|
||||
byteswap = false;
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
|
||||
zio_cksum_t cksum_found = vdev_phys->vp_zbt.zec_cksum;
|
||||
if (byteswap) {
|
||||
ZIO_CHECKSUM_BSWAP(&cksum_found);
|
||||
}
|
||||
|
||||
ZIO_SET_CHECKSUM(&vdev_phys->vp_zbt.zec_cksum,
|
||||
vdev_phys_off, 0, 0, 0);
|
||||
if (byteswap) {
|
||||
ZIO_CHECKSUM_BSWAP(&vdev_phys->vp_zbt.zec_cksum);
|
||||
}
|
||||
|
||||
SHA256_CTX ctx;
|
||||
zio_cksum_t cksum_real;
|
||||
|
||||
SHA256Init(&ctx);
|
||||
SHA256Update(&ctx, (uint8_t *)vdev_phys, sizeof *vdev_phys);
|
||||
SHA256Final(&cksum_real, &ctx);
|
||||
|
||||
/*
|
||||
* For historical reasons the on-disk sha256 checksums are
|
||||
* always in big endian format.
|
||||
* (see cddl/osnet/dist/uts/common/fs/zfs/sha256.c)
|
||||
*/
|
||||
ZIO_CHECKSUM_BE(&cksum_real);
|
||||
|
||||
if (!ZIO_CHECKSUM_EQUAL(cksum_found, cksum_real)) {
|
||||
warnx("%s: checksum mismatch on vdev label %zu",
|
||||
__func__, i);
|
||||
warnx("%s: found %#jx, %#jx, %#jx, %#jx", __func__,
|
||||
(uintmax_t)cksum_found.zc_word[0],
|
||||
(uintmax_t)cksum_found.zc_word[1],
|
||||
(uintmax_t)cksum_found.zc_word[2],
|
||||
(uintmax_t)cksum_found.zc_word[3]);
|
||||
warnx("%s: expected %#jx, %#jx, %#jx, %#jx", __func__,
|
||||
(uintmax_t)cksum_real.zc_word[0],
|
||||
(uintmax_t)cksum_real.zc_word[1],
|
||||
(uintmax_t)cksum_real.zc_word[2],
|
||||
(uintmax_t)cksum_real.zc_word[3]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
rv = 0;
|
||||
out:
|
||||
free(vdev_phys);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static off_t sblock_try[] = SBLOCKSEARCH;
|
||||
|
||||
static int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: params.c,v 1.34 2022/08/12 10:49:35 riastradh Exp $ */
|
||||
/* $NetBSD: params.c,v 1.35 2024/05/12 18:02:16 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: params.c,v 1.34 2022/08/12 10:49:35 riastradh Exp $");
|
||||
__RCSID("$NetBSD: params.c,v 1.35 2024/05/12 18:02:16 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -287,6 +287,10 @@ params_verify_method(string_t *in)
|
|||
p->verify_method = VERIFY_MBR;
|
||||
if (!strcmp("gpt", vm))
|
||||
p->verify_method = VERIFY_GPT;
|
||||
#ifdef HAVE_ZFS
|
||||
if (!strcmp("zfs", vm))
|
||||
p->verify_method = VERIFY_ZFS;
|
||||
#endif
|
||||
|
||||
string_free(in);
|
||||
|
||||
|
@ -1065,6 +1069,11 @@ params_fput(struct params *p, FILE *f)
|
|||
case VERIFY_GPT:
|
||||
print_kvpair_cstr(f, ts, "verify_method", "gpt");
|
||||
break;
|
||||
#ifdef HAVE_ZFS
|
||||
case VERIFY_ZFS:
|
||||
print_kvpair_cstr(f, ts, "verify_method", "zfs");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
warnx("unsupported verify_method (%d)", p->verify_method);
|
||||
return -1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: params.h,v 1.14 2022/08/12 10:49:35 riastradh Exp $ */
|
||||
/* $NetBSD: params.h,v 1.15 2024/05/12 18:02:16 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -81,6 +81,7 @@ struct params {
|
|||
#define VERIFY_REENTER 0x4
|
||||
#define VERIFY_MBR 0x5
|
||||
#define VERIFY_GPT 0x6
|
||||
#define VERIFY_ZFS 0x7
|
||||
|
||||
/* shared key derivation methods */
|
||||
|
||||
|
|
Loading…
Reference in New Issue