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