Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159855970
D25605.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D25605.diff
View Options
Index: head/stand/i386/gptboot/gptboot.c
===================================================================
--- head/stand/i386/gptboot/gptboot.c
+++ head/stand/i386/gptboot/gptboot.c
@@ -610,7 +610,7 @@
#ifdef LOADER_GELI_SUPPORT
if (err == 0 && gdsk.gdev != NULL) {
/* Decrypt */
- if (geli_read(gdsk.gdev, lba * DEV_BSIZE, buf,
+ if (geli_io(gdsk.gdev, GELI_DECRYPT, lba * DEV_BSIZE, buf,
nblk * DEV_BSIZE))
return (err);
}
Index: head/stand/libsa/geli/geliboot.h
===================================================================
--- head/stand/libsa/geli/geliboot.h
+++ head/stand/libsa/geli/geliboot.h
@@ -50,6 +50,11 @@
#define GELI_KEYBUF_SIZE (sizeof(struct keybuf) + \
(GELI_MAX_KEYS * sizeof(struct keybuf_ent)))
+typedef enum geli_op {
+ GELI_DECRYPT,
+ GELI_ENCRYPT
+} geli_op_t;
+
extern void pwgets(char *buf, int n, int hide);
typedef u_char geli_ukey[G_ELI_USERKEYLEN];
@@ -73,9 +78,10 @@
typedef int (*geli_readfunc)(void *vdev, void *readpriv, off_t offbytes,
void *buf, size_t sizebytes);
-struct geli_dev * geli_taste(geli_readfunc readfunc, void *readpriv,
+struct geli_dev *geli_taste(geli_readfunc readfunc, void *readpriv,
daddr_t lastsector, const char *namefmt, ...);
-int geli_read(struct geli_dev *gdev, off_t offset, u_char *buf, size_t bytes);
+int geli_io(struct geli_dev *gdev, geli_op_t, off_t offset, u_char *buf,
+ size_t bytes);
int geli_havekey(struct geli_dev *gdev);
int geli_passphrase(struct geli_dev *gdev, char *pw);
Index: head/stand/libsa/geli/geliboot.c
===================================================================
--- head/stand/libsa/geli/geliboot.c
+++ head/stand/libsa/geli/geliboot.c
@@ -310,7 +310,8 @@
}
int
-geli_read(struct geli_dev *gdev, off_t offset, u_char *buf, size_t bytes)
+geli_io(struct geli_dev *gdev, geli_op_t enc, off_t offset, u_char *buf,
+ size_t bytes)
{
u_char iv[G_ELI_IVKEYLEN];
u_char *pbuf;
@@ -343,12 +344,13 @@
keyno = (dstoff >> G_ELI_KEY_SHIFT) / secsize;
g_eli_key_fill(&gdev->sc, &gkey, keyno);
- error = geliboot_crypt(gdev->sc.sc_ealgo, 0, pbuf, secsize,
+ error = geliboot_crypt(gdev->sc.sc_ealgo, enc, pbuf, secsize,
gkey.gek_key, gdev->sc.sc_ekeylen, iv);
if (error != 0) {
explicit_bzero(&gkey, sizeof(gkey));
- printf("Failed to decrypt in geli_read()!");
+ printf("%s: Failed to %s!", __func__,
+ enc ? "encrypt" : "decrypt");
return (error);
}
pbuf += secsize;
Index: head/stand/libsa/geli/geliboot_crypto.c
===================================================================
--- head/stand/libsa/geli/geliboot_crypto.c
+++ head/stand/libsa/geli/geliboot_crypto.c
@@ -35,7 +35,7 @@
#include "geliboot.h"
int
-geliboot_crypt(u_int algo, int enc, u_char *data, size_t datasize,
+geliboot_crypt(u_int algo, geli_op_t enc, u_char *data, size_t datasize,
const u_char *key, size_t keysize, u_char *iv)
{
keyInstance aeskey;
@@ -49,7 +49,7 @@
err = rijndael_makeKey(&aeskey, !enc, keysize,
(const char *)key);
if (err < 0) {
- printf("Failed to setup decryption keys: %d\n", err);
+ printf("Failed to setup crypo keys: %d\n", err);
return (err);
}
@@ -59,18 +59,20 @@
return (err);
}
- if (enc == 0) {
- /* decrypt */
+ switch (enc) {
+ case GELI_DECRYPT:
blks = rijndael_blockDecrypt(&cipher, &aeskey, data,
datasize * 8, data);
- } else {
- /* encrypt */
+ break;
+ case GELI_ENCRYPT:
blks = rijndael_blockEncrypt(&cipher, &aeskey, data,
datasize * 8, data);
+ break;
}
if (datasize != (blks / 8)) {
- printf("Failed to decrypt the entire input: "
- "%u != %zu\n", blks, datasize);
+ printf("Failed to %s the entire input: %u != %zu\n",
+ enc ? "decrypt" : "encrypt",
+ blks, datasize);
return (1);
}
break;
@@ -82,16 +84,16 @@
enc_xform_aes_xts.reinit(ctxp, iv);
switch (enc) {
- case 0: /* decrypt */
+ case GELI_DECRYPT:
for (i = 0; i < datasize; i += AES_XTS_BLOCKSIZE) {
enc_xform_aes_xts.decrypt(ctxp, data + i,
data + i);
}
break;
- case 1: /* encrypt */
+ case GELI_ENCRYPT:
for (i = 0; i < datasize; i += AES_XTS_BLOCKSIZE) {
enc_xform_aes_xts.encrypt(ctxp, data + i,
- data + 1);
+ data + i);
}
break;
}
@@ -105,7 +107,7 @@
}
static int
-g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
+g_eli_crypto_cipher(u_int algo, geli_op_t enc, u_char *data, size_t datasize,
const u_char *key, size_t keysize)
{
u_char iv[keysize];
@@ -123,7 +125,8 @@
if (algo == CRYPTO_AES_XTS)
algo = CRYPTO_AES_CBC;
- return (g_eli_crypto_cipher(algo, 1, data, datasize, key, keysize));
+ return (g_eli_crypto_cipher(algo, GELI_ENCRYPT, data, datasize, key,
+ keysize));
}
int
@@ -135,5 +138,6 @@
if (algo == CRYPTO_AES_XTS)
algo = CRYPTO_AES_CBC;
- return (g_eli_crypto_cipher(algo, 0, data, datasize, key, keysize));
+ return (g_eli_crypto_cipher(algo, GELI_DECRYPT, data, datasize, key,
+ keysize));
}
Index: head/stand/libsa/geli/geliboot_internal.h
===================================================================
--- head/stand/libsa/geli/geliboot_internal.h
+++ head/stand/libsa/geli/geliboot_internal.h
@@ -55,6 +55,8 @@
#define STAND_H /* We don't want stand.h in {gpt,zfs,gptzfs}boot */
#include <opencrypto/xform_enc.h>
+#include "geliboot.h"
+
#define GELIDEV_NAMELEN 32
struct geli_dev {
@@ -65,7 +67,7 @@
char *name; /* for prompting; it ends in ':' */
};
-int geliboot_crypt(u_int algo, int enc, u_char *data, size_t datasize,
+int geliboot_crypt(u_int algo, geli_op_t enc, u_char *data, size_t datasize,
const u_char *key, size_t keysize, u_char *iv);
#endif /* _GELIBOOT_INTERNAL_H_ */
Index: head/stand/libsa/geli/gelidev.c
===================================================================
--- head/stand/libsa/geli/gelidev.c
+++ head/stand/libsa/geli/gelidev.c
@@ -115,10 +115,6 @@
char *iobuf;
int rc;
- /* We only handle reading; no write support. */
- if ((rw & F_MASK) != F_READ)
- return (EOPNOTSUPP);
-
gdesc = (struct geli_devdesc *)devdata;
/*
@@ -139,34 +135,63 @@
alnsize = alnend - alnstart;
/*
- * If alignment requires us to read more than the size of the provided
- * buffer, allocate a temporary buffer.
+ * If alignment requires us to read/write more than the size of the
+ * provided buffer, allocate a temporary buffer.
+ * The writes will always get temporary buffer because of encryption.
*/
- if (alnsize <= size)
+ if (alnsize <= size && (rw & F_MASK) == F_READ)
iobuf = buf;
else if ((iobuf = malloc(alnsize)) == NULL)
return (ENOMEM);
- /*
- * Read the encrypted data using the host provider, then decrypt it.
- */
- rc = gdesc->hdesc->dd.d_dev->dv_strategy(gdesc->hdesc, rw,
- alnstart / DEV_BSIZE, alnsize, iobuf, NULL);
- if (rc != 0)
- goto out;
- rc = geli_read(gdesc->gdev, alnstart, iobuf, alnsize);
- if (rc != 0)
- goto out;
+ switch (rw & F_MASK) {
+ case F_READ:
+ /*
+ * Read the encrypted data using the host provider,
+ * then decrypt it.
+ */
+ rc = gdesc->hdesc->dd.d_dev->dv_strategy(gdesc->hdesc, rw,
+ alnstart / DEV_BSIZE, alnsize, iobuf, NULL);
+ if (rc != 0)
+ goto out;
+ rc = geli_io(gdesc->gdev, GELI_DECRYPT, alnstart, iobuf,
+ alnsize);
+ if (rc != 0)
+ goto out;
- /*
- * If we had to use a temporary buffer, copy the requested part of the
- * data to the caller's buffer.
- */
- if (iobuf != buf)
- memcpy(buf, iobuf + (reqstart - alnstart), size);
+ /*
+ * If we had to use a temporary buffer, copy the requested
+ * part of the data to the caller's buffer.
+ */
+ if (iobuf != buf)
+ memcpy(buf, iobuf + (reqstart - alnstart), size);
- if (rsize != NULL)
- *rsize = size;
+ if (rsize != NULL)
+ *rsize = size;
+ break;
+ case F_WRITE:
+ if (iobuf != buf) {
+ /* Read, decrypt, then modify. */
+ rc = gdesc->hdesc->dd.d_dev->dv_strategy(gdesc->hdesc,
+ F_READ, alnstart / DEV_BSIZE, alnsize, iobuf, NULL);
+ if (rc != 0)
+ goto out;
+ rc = geli_io(gdesc->gdev, GELI_DECRYPT, alnstart, iobuf,
+ alnsize);
+ if (rc != 0)
+ goto out;
+ /* Copy data to iobuf */
+ memcpy(iobuf + (reqstart - alnstart), buf, size);
+ }
+
+ /* Encrypt and write it. */
+ rc = geli_io(gdesc->gdev, GELI_ENCRYPT, alnstart, iobuf,
+ alnsize);
+ if (rc != 0)
+ goto out;
+ rc = gdesc->hdesc->dd.d_dev->dv_strategy(gdesc->hdesc,
+ rw, alnstart / DEV_BSIZE, alnsize, iobuf, NULL);
+ }
out:
if (iobuf != buf)
free(iobuf);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jun 19, 8:28 PM (13 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34096570
Default Alt Text
D25605.diff (8 KB)
Attached To
Mode
D25605: loader: GELI writes are not yet implemented
Attached
Detach File
Event Timeline
Log In to Comment