Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/cgdconfig cgdconfig(8): Add support for generating shar...



details:   https://anonhg.NetBSD.org/src/rev/fe810e68006c
branches:  trunk
changeset: 368892:fe810e68006c
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Fri Aug 12 10:49:35 2022 +0000

description:
cgdconfig(8): Add support for generating shared-key parameters files.

Usage model:

- Generate a parameters file that supports sharing its main key:

        cgdconfig -g -S -o /etc/cgd/wd0e -V gpt adiantum

- Make another parameters file that uses the same shared main key but
  derives an independent subkey from it:

        cgdconfig -g -S -P /etc/cgd/wd0e -o /etc/cgd/ld1e \
            -V disklabel aes-cbc 256

diffstat:

 sbin/cgdconfig/cgdconfig.8 |   34 +++++++++++-
 sbin/cgdconfig/cgdconfig.c |   82 +++++++++++++++++++++++++-----
 sbin/cgdconfig/params.c    |  121 ++++++++++++++++++++++++++++++++++++++++++++-
 sbin/cgdconfig/params.h    |    5 +-
 4 files changed, 223 insertions(+), 19 deletions(-)

diffs (truncated from 410 to 300 lines):

diff -r 8b4e7542c555 -r fe810e68006c sbin/cgdconfig/cgdconfig.8
--- a/sbin/cgdconfig/cgdconfig.8        Fri Aug 12 10:49:17 2022 +0000
+++ b/sbin/cgdconfig/cgdconfig.8        Fri Aug 12 10:49:35 2022 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: cgdconfig.8,v 1.55 2022/08/12 10:49:17 riastradh Exp $
+.\" $NetBSD: cgdconfig.8,v 1.56 2022/08/12 10:49:35 riastradh Exp $
 .\"
 .\" Copyright (c) 2002, The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -52,11 +52,12 @@
 .Ar paramsfile
 .Nm
 .Fl g
-.Op Fl v
+.Op Fl Sv
 .Op Fl V Ar vmeth
 .Op Fl i Ar ivmeth
 .Op Fl k Ar kgmeth
 .Op Fl o Ar outfile
+.Op Fl P Ar paramsfile
 .Ar alg
 .Op Ar keylen
 .Nm
@@ -138,6 +139,13 @@
 If
 .Fl o
 is not given, any paramsfile content is written to standard output.
+.It Fl P Ar paramsfile
+With the
+.Fl S
+option for the
+.Fl g
+action, specify a parameters file with a shared key to reuse for
+deriving this one as a subkey.
 .It Fl p
 Read all passphrases from stdin rather than
 .Pa /dev/tty .
@@ -147,6 +155,15 @@
 If this flag is specified then verification errors will cause the device
 in question to be unconfigured rather than prompting for the passphrase
 again.
+.It Fl S
+When generating a parameters file with
+.Fl g ,
+arrange to use a subkey of a shared key.
+If
+.Fl P Ar paramsfile
+is also specified, reuse the shared key of
+.Ar paramsfile ;
+otherwise a new one will be generated.
 .It Fl s
 Read the key (nb: not the passphrase) from stdin.
 .It Fl T
@@ -485,6 +502,19 @@
        new file's passphrase:
 .Ed
 .Pp
+To create parameters files for three disks with subkeys derived from a
+shared password-based key:
+.Bd -literal
+       # cgdconfig -g -S -k argon2id -o /etc/cgd/wd0 -V gpt adiantum
+       # cgdconfig -g -S -P /etc/cgd/wd0 -o /etc/cgd/ld1 \e
+             -V disklabel aes-cbc 256
+.Ed
+.Pp
+Listing these in the same
+.Pa /etc/cgd/cgd.conf
+will allow you to enter a password once to decrypt both disks with
+.Cm cgdconfig -C .
+.Pp
 To configure a cgd that uses aes-cbc with a 192 bit key that it
 reads from stdin:
 .Bd -literal
diff -r 8b4e7542c555 -r fe810e68006c sbin/cgdconfig/cgdconfig.c
--- a/sbin/cgdconfig/cgdconfig.c        Fri Aug 12 10:49:17 2022 +0000
+++ b/sbin/cgdconfig/cgdconfig.c        Fri Aug 12 10:49:35 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cgdconfig.c,v 1.56 2022/08/12 10:49:17 riastradh Exp $ */
+/* $NetBSD: cgdconfig.c,v 1.57 2022/08/12 10:49:35 riastradh 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.56 2022/08/12 10:49:17 riastradh Exp $");
+__RCSID("$NetBSD: cgdconfig.c,v 1.57 2022/08/12 10:49:35 riastradh Exp $");
 #endif
 
 #ifdef HAVE_ARGON2
@@ -100,6 +100,10 @@
 
 int    nflag = 0;
 
+/* if Sflag is set, generate shared keys */
+
+int    Sflag = 0;
+
 /* if pflag is set to PFLAG_STDIN read from stdin rather than getpass(3) */
 
 #define        PFLAG_GETPASS           0x01
@@ -123,7 +127,8 @@
 
 static int     configure(int, char **, struct params *, int);
 static int     configure_stdin(struct params *, int argc, char **);
-static int     generate(struct params *, int, char **, const char *);
+static int     generate(struct params *, int, char **, const char *,
+                   const char *);
 static int     generate_convert(struct params *, int, char **, const char *);
 static int     unconfigure(int, char **, struct params *, int);
 static int     do_all(const char *, int, char **,
@@ -177,8 +182,8 @@
            getprogname());
        (void)fprintf(stderr, "       %s -G [-enpv] [-i ivmeth] [-k kgmeth] "
            "[-o outfile] paramsfile\n", getprogname());
-       (void)fprintf(stderr, "       %s -g [-v] [-i ivmeth] [-k kgmeth] "
-           "[-o outfile] alg [keylen]\n", getprogname());
+       (void)fprintf(stderr, "       %s -g [-Sv] [-i ivmeth] [-k kgmeth] "
+           "[-P paramsfile] [-o outfile] alg [keylen]\n", getprogname());
        (void)fprintf(stderr, "       %s -l [-v[v]] [cgd]\n", getprogname());
        (void)fprintf(stderr, "       %s -s [-nv] [-i ivmeth] cgd dev alg "
            "[keylen]\n", getprogname());
@@ -230,6 +235,7 @@
        int     ch;
        const char      *cfile = NULL;
        const char      *outfile = NULL;
+       const char      *Pfile = NULL;
 
        setprogname(*argv);
        if (hkdf_hmac_sha256_selftest())
@@ -240,7 +246,7 @@
        p = params_new();
        kg = NULL;
 
-       while ((ch = getopt(argc, argv, "CGTUV:b:ef:gi:k:lno:sptuv")) != -1)
+       while ((ch = getopt(argc, argv, "CGP:STUV:b:ef:gi:k:lno:sptuv")) != -1)
                switch (ch) {
                case 'C':
                        set_action(&action, ACTION_CONFIGALL);
@@ -248,6 +254,14 @@
                case 'G':
                        set_action(&action, ACTION_GENERATE_CONVERT);
                        break;
+               case 'P':
+                       if (Pfile)
+                               usage();
+                       Pfile = estrdup(optarg);
+                       break;
+               case 'S':
+                       Sflag = 1;
+                       break;
                case 'T':
                        set_action(&action, ACTION_PRINTALLKEYS);
                        break;
@@ -336,6 +350,17 @@
                err(1, "init failed");
 
        /* validate the consistency of the arguments */
+       if (Pfile != NULL && action != ACTION_GENERATE) {
+               warnx("-P is only for use with -g action");
+               usage();
+       }
+       if (Pfile != NULL && !Sflag) {
+               warnx("-P only makes sense with -S flag");
+       }
+       if (Sflag && action != ACTION_GENERATE) {
+               warnx("-S is only for use with -g action");
+               usage();
+       }
 
        switch (action) {
        case ACTION_DEFAULT:    /* ACTION_CONFIGURE is the default */
@@ -344,7 +369,7 @@
        case ACTION_UNCONFIGURE:
                return unconfigure(argc, argv, NULL, CONFIG_FLAGS_FROMMAIN);
        case ACTION_GENERATE:
-               return generate(p, argc, argv, outfile);
+               return generate(p, argc, argv, outfile, Pfile);
        case ACTION_GENERATE_CONVERT:
                return generate_convert(p, argc, argv, outfile);
        case ACTION_CONFIGALL:
@@ -1197,7 +1222,8 @@
 }
 
 static int
-generate(struct params *p, int argc, char **argv, const char *outfile)
+generate(struct params *p, int argc, char **argv, const char *outfile,
+    const char *Pfile)
 {
        int      ret;
 
@@ -1219,15 +1245,43 @@
        if (ret)
                return ret;
 
-       if (!p->keygen) {
-               p->keygen = keygen_generate(KEYGEN_PKCS5_PBKDF2_SHA1);
-               if (!p->keygen)
+       if (Pfile) {
+               struct params *pp;
+
+               pp = params_cget(Pfile);
+               if (pp == NULL)
+                       return -1;
+               if (!params_verify(pp)) {
+                       params_free(pp);
+                       warnx("invalid parameters file \"%s\"", Pfile);
                        return -1;
+               }
+               p = params_combine(pp, p);
+               keygen_stripstored(&p->keygen);
+               if (!p->keygen) {
+                       warnx("no keygen in parameters file \"%s\"", Pfile);
+                       return -1;
+               }
+       } else {
+               if (!p->keygen) {
+                       p->keygen = keygen_generate(KEYGEN_PKCS5_PBKDF2_SHA1);
+                       if (!p->keygen)
+                               return -1;
+               }
+
+               if (keygen_filldefaults(p->keygen, p->keylen)) {
+                       warnx("Failed to generate defaults for keygen");
+                       return -1;
+               }
        }
 
-       if (keygen_filldefaults(p->keygen, p->keylen)) {
-               warnx("Failed to generate defaults for keygen");
-               return -1;
+       if (Sflag) {
+               if (Pfile)
+                       ret = keygen_tweakshared(p->keygen);
+               else
+                       ret = keygen_makeshared(p->keygen);
+               if (ret)
+                       return ret;
        }
 
        if (!params_verify(p)) {
diff -r 8b4e7542c555 -r fe810e68006c sbin/cgdconfig/params.c
--- a/sbin/cgdconfig/params.c   Fri Aug 12 10:49:17 2022 +0000
+++ b/sbin/cgdconfig/params.c   Fri Aug 12 10:49:35 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: params.c,v 1.33 2022/08/12 10:49:17 riastradh Exp $ */
+/* $NetBSD: params.c,v 1.34 2022/08/12 10:49:35 riastradh 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.33 2022/08/12 10:49:17 riastradh Exp $");
+__RCSID("$NetBSD: params.c,v 1.34 2022/08/12 10:49:35 riastradh Exp $");
 #endif
 
 #include <sys/types.h>
@@ -46,6 +46,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <util.h>
+#include <uuid.h>
 
 #ifdef HAVE_ARGON2
 #include <argon2.h>
@@ -524,6 +525,122 @@
        return keygen_filldefaults(kg->next, keylen);
 }
 
+/*
+ * Strip the storedkey entries in preparation for inserting a shared
+ * clause with a newly generated info string to derive this key from
+ * KDF.  The result is that the key generated here is independent of
+ * whatever storedkeys were involved in the old one, so there is no
+ * need to keep them around,
+ */
+void
+keygen_stripstored(struct keygen **kgp)
+{
+       struct keygen *kg, *to_free = NULL;
+
+       while ((kg = *kgp) != NULL) {
+               if (kg->kg_method == KEYGEN_STOREDKEY) {
+                       *kgp = kg->next;
+                       kg->next = to_free;
+                       to_free = kg;
+               } else {
+                       kgp = &kg->next;
+               }
+       }
+       keygen_free(to_free);
+}
+
+int
+keygen_makeshared(struct keygen *kg0)
+{
+       struct keygen *kg;



Home | Main Index | Thread Index | Old Index