[patch] Add encryption key parameter to compress/decompress functions

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

 



This patch extends to interface for compression and decompression of data nodes to take a cryptographic key as a parameter. If it is set to NULL, then the current behaviour persists. If it is non-null, then it is taken as a pointer to an array of length UBIFSEC_KEYSIZE (=16 bytes) which contains the key to use to encrypt the data node. Each data node should be encrypted with a separate key as it uses the same initialization vector (of 0).

In all places where the compress/decompress are called, a NULL parameter is used, so it will have no effect on deployed systems. It will be needed when adding secure deletion to UBIFS using individually encrypted data nodes.

It was tested by with hundred runs of integck along with power cut tests.

------

Signed-off-by: Joel Reardon<reardonj@xxxxxxxxxxx>
diff -uprN -X linux-3.2.1-vanilla/Documentation/dontdiff linux-3.2.1-vanilla/fs/ubifs/compress.c linux-3.2.1-ubifsec/fs/ubifs/compress.c --- linux-3.2.1-vanilla/fs/ubifs/compress.c 2012-01-12 20:42:45.000000000 +0100 +++ linux-3.2.1-ubifsec/fs/ubifs/compress.c 2012-02-23 16:07:44.287023169 +0100
@@ -27,9 +27,11 @@
  * decompression.
  */

-#include <linux/crypto.h>
 #include "ubifs.h"

+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+
 /* Fake description object for the "none" compressor */
 static struct ubifs_compressor none_compr = {
 	.compr_type = UBIFS_COMPR_NONE,
@@ -74,6 +76,40 @@ static struct ubifs_compressor zlib_comp
 /* All UBIFS compressors */
 struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];

+int ubifs_aes_crypt(u8 *str, int len, u8 *key, int keylen, u8 *iv, int ivlen)
+{
+	struct crypto_blkcipher *tfm;
+	struct blkcipher_desc desc;
+	struct scatterlist sg;
+	int err = 0;
+	tfm = crypto_alloc_blkcipher(UBIFSEC_CRYPTO_ALGORITHM, 0, 0);
+
+	if (IS_ERR(tfm)) {
+		ubifs_err("failed to load transform for aes: %ld",
+			  PTR_ERR(tfm));
+		return err;
+	}
+
+	err = crypto_blkcipher_setkey(tfm, key, keylen);
+	desc.tfm = tfm;
+	desc.flags = 0;
+	if (err) {
+		ubifs_err("setkey() failed  flags=%x",
+			  crypto_blkcipher_get_flags(tfm));
+		return err;
+	}
+	memset(&sg, 0, sizeof(struct scatterlist));
+
+	sg_set_buf(&sg, str, len);
+	desc.info = iv;
+	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, len);
+	crypto_free_blkcipher(tfm);
+	if (err)
+		return err;
+	return 0;
+}
+
+
 /**
  * ubifs_compress - compress data.
  * @in_buf: data to compress
@@ -93,7 +129,7 @@ struct ubifs_compressor *ubifs_compresso
  * buffer and %UBIFS_COMPR_NONE is returned in @compr_type.
  */
void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
-		    int *compr_type)
+		    int *compr_type, u8* key)
 {
 	int err;
 	struct ubifs_compressor *compr = ubifs_compressors[*compr_type];
@@ -115,7 +151,7 @@ void ubifs_compress(const void *in_buf,
 		ubifs_warn("cannot compress %d bytes, compressor %s, "
 			   "error %d, leave data uncompressed",
 			   in_len, compr->name, err);
-		 goto no_compr;
+		goto no_compr;
 	}

 	/*
@@ -124,13 +160,20 @@ void ubifs_compress(const void *in_buf,
 	 */
 	if (in_len - *out_len < UBIFS_MIN_COMPRESS_DIFF)
 		goto no_compr;
-
-	return;
+	goto encrypt;

 no_compr:
 	memcpy(out_buf, in_buf, in_len);
 	*out_len = in_len;
 	*compr_type = UBIFS_COMPR_NONE;
+	goto encrypt;
+encrypt:
+	if (key) {
+		u8 iv[AES_KEYSIZE_128];
+		memset(iv, 0, AES_KEYSIZE_128);
+		ubifs_aes_crypt(out_buf, *out_len, key, AES_KEYSIZE_128,
+				iv, AES_KEYSIZE_128);
+	}
 }

 /**
@@ -145,8 +188,9 @@ no_compr:
* The length of the uncompressed data is returned in @out_len. This functions
  * returns %0 on success or a negative error code on failure.
  */
-int ubifs_decompress(const void *in_buf, int in_len, void *out_buf,
-		     int *out_len, int compr_type)
+int ubifs_decompress(void *in_buf, int in_len, void *out_buf,
+		     int *out_len, int compr_type, u8* key)
+
 {
 	int err;
 	struct ubifs_compressor *compr;
@@ -163,6 +207,12 @@ int ubifs_decompress(const void *in_buf,
 		return -EINVAL;
 	}

+	if (key) {
+		u8 iv[AES_KEYSIZE_128];
+		memset(iv, 0, AES_KEYSIZE_128);
+		ubifs_aes_crypt(in_buf, in_len, key, AES_KEYSIZE_128,
+				iv, AES_KEYSIZE_128);
+	}
 	if (compr_type == UBIFS_COMPR_NONE) {
 		memcpy(out_buf, in_buf, in_len);
 		*out_len = in_len;
diff -uprN -X linux-3.2.1-vanilla/Documentation/dontdiff linux-3.2.1-vanilla/fs/ubifs/file.c linux-3.2.1-ubifsec/fs/ubifs/file.c --- linux-3.2.1-vanilla/fs/ubifs/file.c 2012-01-12 20:42:45.000000000 +0100 +++ linux-3.2.1-ubifsec/fs/ubifs/file.c 2012-02-23 16:15:48.607046613 +0100
@@ -80,7 +80,7 @@ static int read_block(struct inode *inod
 	dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
 	out_len = UBIFS_BLOCK_SIZE;
 	err = ubifs_decompress(&dn->data, dlen, addr, &out_len,
-			       le16_to_cpu(dn->compr_type));
+			       le16_to_cpu(dn->compr_type), NULL);
 	if (err || len != out_len)
 		goto dump;

@@ -649,7 +649,8 @@ static int populate_page(struct ubifs_in
dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
 			out_len = UBIFS_BLOCK_SIZE;
err = ubifs_decompress(&dn->data, dlen, addr, &out_len, - le16_to_cpu(dn->compr_type)); + le16_to_cpu(dn->compr_type),
+					       NULL);
 			if (err || len != out_len)
 				goto out_err;

diff -uprN -X linux-3.2.1-vanilla/Documentation/dontdiff linux-3.2.1-vanilla/fs/ubifs/journal.c linux-3.2.1-ubifsec/fs/ubifs/journal.c --- linux-3.2.1-vanilla/fs/ubifs/journal.c 2012-01-12 20:42:45.000000000 +0100 +++ linux-3.2.1-ubifsec/fs/ubifs/journal.c 2012-02-23 16:15:05.415044519 +0100
@@ -728,7 +728,7 @@ int ubifs_jnl_write_data(struct ubifs_in
 		compr_type = ui->compr_type;

 	out_len = dlen - UBIFS_DATA_NODE_SZ;
-	ubifs_compress(buf, len, &data->data, &out_len, &compr_type);
+ ubifs_compress(buf, len, &data->data, &out_len, &compr_type, NULL);
 	ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);

 	dlen = UBIFS_DATA_NODE_SZ + out_len;
@@ -1111,11 +1111,12 @@ static int recomp_data_node(struct ubifs

 	len = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
 	compr_type = le16_to_cpu(dn->compr_type);
-	err = ubifs_decompress(&dn->data, len, buf, &out_len, compr_type);
+	err = ubifs_decompress(
+		&dn->data, len, buf, &out_len, compr_type, NULL);
 	if (err)
 		goto out;

-	ubifs_compress(buf, *new_len, &dn->data, &out_len, &compr_type);
+ ubifs_compress(buf, *new_len, &dn->data, &out_len, &compr_type, NULL);
 	ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);
 	dn->compr_type = cpu_to_le16(compr_type);
 	dn->size = cpu_to_le32(*new_len);
diff -uprN -X linux-3.2.1-vanilla/Documentation/dontdiff linux-3.2.1-vanilla/fs/ubifs/ubifs.h linux-3.2.1-ubifsec/fs/ubifs/ubifs.h --- linux-3.2.1-vanilla/fs/ubifs/ubifs.h 2012-01-12 20:42:45.000000000 +0100 +++ linux-3.2.1-ubifsec/fs/ubifs/ubifs.h 2012-02-23 16:09:03.071026982 +0100
@@ -163,6 +163,14 @@
 /* Maximum number of data nodes to bulk-read */
 #define UBIFS_MAX_BULK_READ 32

+/* Size of 128 bits in bytes */
+#define AES_KEYSIZE_128 16
+
+/* Key size in bytes for UBIFSEC */
+#define UBIFSEC_KEYSIZE AES_KEYSIZE_128
+#define UBIFSEC_CRYPTO_ALGORITHM "ctr(aes)"
+#define POISON_KEY(p) memset(p, 0xff, UBIFSEC_KEYSIZE)
+
 /*
  * Lockdep classes for UBIFS inode @ui_mutex.
  */
@@ -1775,9 +1783,10 @@ long ubifs_compat_ioctl(struct file *fil
 int __init ubifs_compressors_init(void);
 void ubifs_compressors_exit(void);
void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
-		    int *compr_type);
-int ubifs_decompress(const void *buf, int len, void *out, int *out_len,
-		     int compr_type);
+		    int *compr_type, u8* key);
+int ubifs_decompress(void *buf, int len, void *out, int *out_len,
+		     int compr_type, u8 *key);
+int ubifs_aes_crypt(u8 *str, int len, u8 *key, int keylen, u8 *iv, int ivlen);

 #include "debug.h"
 #include "misc.h"


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux