Hi,

Here is a patch I've made to select the algorithm used for a softraid
encryption. I added an extra field to the kdfinfo structure to
retrieve the algorithm type from userland. I modified bioctl to allow
this extra option. (And updated the man page as well).

Finally, I added the ioctl discipline SR_IOCTL_GET_ALGORITHM to
retrieve the encryption algorithm name from userland. Now, bioctl -i
returns something like:
# bioctl -i sd2
Volume      Status               Size Device
softraid0 2 Online           16180224 sd2     CRYPTO AES_XTS_256
         0 Online           16180224 2:0.0   noencl <sd1b>

Comments are welcomed.

Thanks
Thiébaud Weksteen

Index: softraid_crypto.c
===================================================================
RCS file: /cvs/src/sys/dev/softraid_crypto.c,v
retrieving revision 1.82
diff -u -p -u -r1.82 softraid_crypto.c
--- softraid_crypto.c   9 Oct 2012 11:57:33 -0000       1.82
+++ softraid_crypto.c   27 Oct 2012 09:38:39 -0000
@@ -151,6 +151,7 @@ sr_crypto_create(struct sr_discipline *s
        omi->omi_som->som_length = sizeof(struct sr_meta_crypto);
        SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link);
        sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)omi->omi_som;
+       sd->mds.mdd_crypto.scr_meta->scm_flags = 0;
        sd->sd_meta->ssdi.ssd_opt_no++;

        sd->mds.mdd_crypto.key_disk = NULL;
@@ -397,6 +398,20 @@ sr_crypto_get_kdf(struct bioc_createraid
                bcopy(&kdfinfo->maskkey, sd->mds.mdd_crypto.scr_maskkey,
                    sizeof(kdfinfo->maskkey));
        }
+
+       /* copy the requested algorithm, if applicable */
+       if ((kdfinfo->flags & SR_CRYPTOKDF_ALG) &&
+            !sd->mds.mdd_crypto.scr_meta->scm_alg) {
+               switch (kdfinfo->alg) {
+               case SR_CRYPTOA_AES_XTS_128:
+               case SR_CRYPTOA_AES_XTS_256:
+                       sd->mds.mdd_crypto.scr_meta->scm_alg = kdfinfo->alg;
+                       sd->mds.mdd_crypto.scr_meta->scm_flags |= 
SR_CRYPTOF_ALG;
+                       break;
+               default:
+                       goto out;
+               }
+       }

        bc->bc_opaque_status = BIOC_SOINOUT_OK;
        rv = 0;
@@ -541,9 +556,6 @@ sr_crypto_create_keys(struct sr_discipli
        if (AES_MAXKEYBYTES < sizeof(sd->mds.mdd_crypto.scr_maskkey))
                return (1);

-       /* XXX allow user to specify */
-       sd->mds.mdd_crypto.scr_meta->scm_alg = SR_CRYPTOA_AES_XTS_256;
-
        /* generate crypto keys */
        arc4random_buf(sd->mds.mdd_crypto.scr_key,
            sizeof(sd->mds.mdd_crypto.scr_key));
@@ -571,7 +583,7 @@ sr_crypto_create_keys(struct sr_discipli
        sr_crypto_dumpkeys(sd);
#endif

-       sd->mds.mdd_crypto.scr_meta->scm_flags = SR_CRYPTOF_KEY |
+       sd->mds.mdd_crypto.scr_meta->scm_flags |= SR_CRYPTOF_KEY |
            SR_CRYPTOF_KDFHINT;

        return (0);
@@ -1103,6 +1115,26 @@ sr_crypto_ioctl(struct sr_discipline *sd
            DEVNAME(sd->sd_sc), bd->bd_cmd);

        switch (bd->bd_cmd) {
+       case SR_IOCTL_GET_ALGORITHM:
+               if(bd->bd_data == NULL)
+                       goto bad;
+               switch(sd->mds.mdd_crypto.scr_meta->scm_alg){
+                       case SR_CRYPTOA_AES_XTS_128:
+                               copyout(SR_CRYPTOA_AES_XTS_128_S, bd->bd_data,
+                                       sizeof(SR_CRYPTOA_AES_XTS_128_S));
+                               break;
+                       case SR_CRYPTOA_AES_XTS_256:
+                               copyout(SR_CRYPTOA_AES_XTS_256_S, bd->bd_data,
+                                       sizeof(SR_CRYPTOA_AES_XTS_256_S));
+                               break;
+                       default:
+                               break;
+               }
+
+               rv = 0;
+
+               break;
+
        case SR_IOCTL_GET_KDFHINT:

                /* Get KDF hint for userland. */
Index: softraidvar.h
===================================================================
RCS file: /cvs/src/sys/dev/softraidvar.h,v
retrieving revision 1.119
diff -u -p -u -r1.119 softraidvar.h
--- softraidvar.h       9 Oct 2012 13:55:36 -0000       1.119
+++ softraidvar.h       27 Oct 2012 09:38:40 -0000
@@ -149,11 +149,14 @@ struct sr_meta_crypto {
        struct sr_meta_opt_hdr  scm_hdr;
        u_int32_t               scm_alg;        /* vol crypto algorithm */
#define SR_CRYPTOA_AES_XTS_128  1
+#define SR_CRYPTOA_AES_XTS_128_S  "AES_XTS_128"
#define SR_CRYPTOA_AES_XTS_256  2
+#define SR_CRYPTOA_AES_XTS_256_S  "AES_XTS_256"
        u_int32_t               scm_flags;      /* key & kdfhint valid */
#define SR_CRYPTOF_INVALID      (0)
#define SR_CRYPTOF_KEY          (1<<0)
#define SR_CRYPTOF_KDFHINT      (1<<1)
+#define SR_CRYPTOF_ALG         (1<<2)
        u_int32_t               scm_mask_alg;   /* disk key masking crypt alg */
#define SR_CRYPTOM_AES_ECB_256  1
        u_int32_t               scm_pad1;
@@ -221,11 +224,13 @@ struct sr_crypto_kdf_pbkdf2 {
 * the embedded hint structures are not interpreted by the kernel.
 */
struct sr_crypto_kdfinfo {
-       u_int32_t       len;
-       u_int32_t       flags;
+       u_int32_t               len;
+       u_int32_t               flags;
#define SR_CRYPTOKDF_INVALID    (0)
#define SR_CRYPTOKDF_KEY        (1<<0)
#define SR_CRYPTOKDF_HINT       (1<<1)
+#define SR_CRYPTOKDF_ALG       (1<<2)
+       u_int32_t               alg;    /* vol crypto algorithm */
        u_int8_t        maskkey[SR_CRYPTO_MAXKEYBYTES];
        union {
                struct sr_crypto_genkdf         generic;
@@ -237,6 +242,7 @@ struct sr_crypto_kdfinfo {

#define SR_IOCTL_GET_KDFHINT            0x01    /* Get KDF hint. */
#define SR_IOCTL_CHANGE_PASSPHRASE      0x02    /* Change passphase. */
+#define SR_IOCTL_GET_ALGORITHM 0x03 /* Get encryption algorithm info. */

struct sr_crypto_kdfpair {
        void            *kdfinfo1;
Index: bioctl.c
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.c,v
retrieving revision 1.112
diff -u -p -u -r1.112 bioctl.c
--- bioctl.c    10 Sep 2012 11:28:47 -0000      1.112
+++ bioctl.c    27 Oct 2012 09:37:58 -0000
@@ -59,6 +59,7 @@ void                  bio_status(struct bio_status *);
int                     bio_parse_devlist(char *, dev_t *);
void                    bio_kdf_derive(struct sr_crypto_kdfinfo *,
                            struct sr_crypto_kdf_pbkdf2 *, char *, int);
+void                   bio_kdf_set_alg(struct sr_crypto_kdfinfo *);
void                    bio_kdf_generate(struct sr_crypto_kdfinfo *);
void                    derive_key_pkcs(int, u_int8_t *, size_t, u_int8_t *,
                            size_t, char *, int);
@@ -73,6 +74,7 @@ struct sr_aoe_config  *create_aoe(u_int1
void                    bio_createraid(u_int16_t, char *, char *);
void                    bio_deleteraid(char *);
void                    bio_changepass(char *);
+void                   bio_getcryptoinfo(char *, char *);
u_int32_t               bio_createflags(char *);
char                    *bio_vis(char *);
void                    bio_diskinq(char *);
@@ -83,6 +85,7 @@ int                   verbose;
u_int32_t               cflags = 0;
int                     rflag = 8192;
char                    *password;
+u_int32_t              enc_algorithm = SR_CRYPTOA_AES_XTS_256;

void                    *bio_cookie;

@@ -107,7 +110,7 @@ main(int argc, char *argv[])
        if (argc < 2)
                usage();

- while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:O:Pp:qr:R:svu:")) != + while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:O:Pp:qr:R:st:vu:")) !=
            -1) {
                switch (ch) {
                case 'a': /* alarm */
@@ -186,6 +189,12 @@ main(int argc, char *argv[])
                case 's':
                        rpp_flag = RPP_STDIN;
                        break;
+               case 't':
+                       enc_algorithm = strtonum(optarg, 0, 5, &errstr);
+                       if (errstr != NULL)
+                               errx(1, "Encryption algorithm is %s: %s",
+                                   errstr, optarg);
+                       break;
                case 'v':
                        verbose = 1;
                        break;
@@ -272,7 +281,7 @@ usage(void)
                "\t[-l special[,special,...]] "
                "[-O device | channel:target[.lun]]\n"
                "\t[-p passfile] [-R device | channel:target[.lun]]\n"
-               "\t[-r rounds] "
+               "\t[-r rounds] [-t encryption-type] "
                "device\n", __progname, __progname);

        exit(1);
@@ -338,11 +347,13 @@ bio_inq(char *name)
        char                    percent[10], seconds[20];
        int                     i, d, volheader, hotspare, unused;
        char                    encname[16], serial[32];
+       char                    algname[64];
        struct bioc_inq         bi;
        struct bioc_vol         bv;
        struct bioc_disk        bd;

        memset(&bi, 0, sizeof(bi));
+       memset(&algname, 0, sizeof(algname));

        bi.bi_bio.bio_cookie = bio_cookie;

@@ -427,9 +438,11 @@ bio_inq(char *name)
                                    bv.bv_size);
                        switch (bv.bv_level) {
                        case 'C':
-                               printf("%11s %-10s %14s %-7s CRYPTO%s%s\n",
+
+                               bio_getcryptoinfo(name, algname);
+                               printf("%11s %-10s %14s %-7s CRYPTO%s%s %s\n",
                                    volname, status, size, bv.bv_dev,
-                                   percent, seconds);
+                                   percent, seconds, algname);
                                break;
                        case 'c':
                                printf("%11s %-10s %14s %-7s CONCAT%s%s\n",
@@ -884,7 +897,8 @@ bio_createraid(u_int16_t level, char *de
                } else {
                        bio_kdf_generate(&kdfinfo);
                }
-
+
+               bio_kdf_set_alg(&kdfinfo);
                create.bc_opaque = &kdfinfo;
                create.bc_opaque_size = sizeof(kdfinfo);
                create.bc_opaque_flags = BIOC_SOIN;
@@ -950,6 +964,14 @@ bio_kdf_derive(struct sr_crypto_kdfinfo
}

void
+bio_kdf_set_alg(struct sr_crypto_kdfinfo *kdfinfo)
+{
+       kdfinfo->flags |= SR_CRYPTOKDF_ALG;
+       kdfinfo->alg = enc_algorithm;
+}
+
+
+void
bio_kdf_generate(struct sr_crypto_kdfinfo *kdfinfo)
{
        if (!kdfinfo)
@@ -1063,6 +1085,23 @@ bio_deleteraid(char *dev)
        strlcpy(bd.bd_dev, dev, sizeof bd.bd_dev);
        if (ioctl(devh, BIOCDELETERAID, &bd))
                err(1, "BIOCDELETERAID");
+
+       bio_status(&bd.bd_bio.bio_status);
+}
+
+void
+bio_getcryptoinfo(char *dev, char *alg_name)
+{
+       struct bioc_discipline bd;
+       memset(&bd, 0, sizeof(bd));
+
+       strlcpy(bd.bd_dev, dev, sizeof(bd.bd_dev));
+       bd.bd_cmd = SR_IOCTL_GET_ALGORITHM;
+       bd.bd_size = sizeof(alg_name);
+       bd.bd_data = alg_name;
+
+       if (ioctl(devh, BIOCDISCIPLINE, &bd))
+               err(1, "BIOCDISCIPLINE");

        bio_status(&bd.bd_bio.bio_status);
}
Index: bioctl.8
===================================================================
RCS file: /cvs/src/sbin/bioctl/bioctl.8,v
retrieving revision 1.90
diff -u -p -u -r1.90 bioctl.8
--- bioctl.8    22 Sep 2012 20:09:43 -0000      1.90
+++ bioctl.8    27 Oct 2012 09:37:58 -0000
@@ -52,6 +52,7 @@
.Op Fl p Ar passfile
.Op Fl R Ar device \*(Ba channel:target[.lun]
.Op Fl r Ar rounds
+.Op Fl t Ar encryption-type
.Ar device
.Ek
.Sh DESCRIPTION
@@ -250,6 +251,16 @@ the PBKDF2 algorithm used to convert a p
Higher iteration counts take more time, but offer more resistance to key
guessing attacks.
The minimum is 1000 rounds and the default is 8192.
+.It Fl t Ar encryption-type
+Specify the algorithm to use for the disk encryption. Accepted values are:
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It 1
+AES_XTS_128
+.It 2
+AES_XTS_256 (default)
+.El
+.Pp
.It Fl s
Read the passphrase for the selected crypto volume from
.Pa /dev/stdin

Reply via email to