diff mbox series

[12/42] mkfs.ubifs: Implement filename encryption

Message ID 20181018143718.26298-13-richard@nod.at
State Accepted
Delegated to: David Oberhollenzer
Headers show
Series mtd-utils: Add fscrypt support to mkfs.ubifs | expand

Commit Message

Richard Weinberger Oct. 18, 2018, 2:36 p.m. UTC
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/key.h        |  4 +-
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 61 +++++++++++++++++++++++------
 2 files changed, 52 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/ubifs-utils/mkfs.ubifs/key.h b/ubifs-utils/mkfs.ubifs/key.h
index 0c7922b67687..c18e35e8f0a3 100644
--- a/ubifs-utils/mkfs.ubifs/key.h
+++ b/ubifs-utils/mkfs.ubifs/key.h
@@ -110,9 +110,9 @@  static inline void ino_key_init(union ubifs_key *key, ino_t inum)
  */
 static inline void dent_key_init(const struct ubifs_info *c,
 				 union ubifs_key *key, ino_t inum,
-				 const struct qstr *nm)
+				 const void *name, int name_len)
 {
-	uint32_t hash = c->key_hash(nm->name, nm->len);
+	uint32_t hash = c->key_hash(name, name_len);
 
 	assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
 	key->u32[0] = inum;
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 469d5874eaa2..7deca96e7953 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1596,6 +1596,7 @@  static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 	union ubifs_key key;
 	struct qstr dname;
 	char *kname;
+	int kname_len;
 	int len;
 
 	dbg_msg(3, "%s ino %lu type %u dir ino %lu", name, (unsigned long)inum,
@@ -1607,23 +1608,61 @@  static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 
 	dent->ch.node_type = UBIFS_DENT_NODE;
 
-	dent_key_init(c, &key, dir_inum, &dname);
-	key_write(&key, dent->key);
 	dent->inum = cpu_to_le64(inum);
 	dent->padding1 = 0;
 	dent->type = type;
-	dent->nlen = cpu_to_le16(dname.len);
-	memcpy(dent->name, dname.name, dname.len);
-	dent->name[dname.len] = '\0';
 	set_dent_cookie(dent);
 
-	len = UBIFS_DENT_NODE_SZ + dname.len + 1;
-
-	kname = strdup(name);
-	if (!kname)
-		return err_msg("cannot allocate memory");
+	if (!fctx) {
+		dent_key_init(c, &key, dir_inum, dname.name, dname.len);
+		dent->nlen = cpu_to_le16(dname.len);
+		memcpy(dent->name, dname.name, dname.len);
+		dent->name[dname.len] = '\0';
+		len = UBIFS_DENT_NODE_SZ + dname.len + 1;
+
+		kname_len = dname.len;
+		kname = strdup(name);
+		if (!kname)
+			return err_msg("cannot allocate memory");
+	} else {
+		void *inbuf, *outbuf, *crypt_key;
+		unsigned int max_namelen = type == UBIFS_ITYPE_LNK ? UBIFS_MAX_INO_DATA : UBIFS_MAX_NLEN;
+		unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
+		unsigned int cryptlen;
+
+		cryptlen = max_t(unsigned int, dname.len, FS_CRYPTO_BLOCK_SIZE);
+		cryptlen = round_up(cryptlen, padding);
+		cryptlen = min(cryptlen, max_namelen);
+
+		inbuf = xmalloc(cryptlen);
+		outbuf = xmalloc(cryptlen + 32);
+
+		memset(inbuf, 0, cryptlen);
+		memcpy(inbuf, dname.name, dname.len);
+
+		crypt_key = calc_fscrypt_subkey(fctx);
+		if (!crypt_key)
+			return err_msg("could not compute subkey");
+		if (encrypt_aes128_cbc_cts(inbuf, cryptlen, crypt_key, outbuf) < 0)
+			return err_msg("could not encrypt filename");
+
+		dent->nlen = cpu_to_le16(cryptlen);
+		memcpy(dent->name, outbuf, cryptlen);
+		dent->name[cryptlen] = '\0';
+		len = UBIFS_DENT_NODE_SZ + cryptlen + 1;
+
+		dent_key_init(c, &key, dir_inum, outbuf, cryptlen);
+
+		kname_len = cryptlen;
+		kname = xmalloc(cryptlen);
+		memcpy(kname, outbuf, cryptlen);
+		free(crypt_key);
+		free(inbuf);
+		free(outbuf);
+	}
+	key_write(&key, dent->key);
 
-	return add_node(&key, kname, dname.len, dent, len);
+	return add_node(&key, kname, kname_len, dent, len);
 }
 
 /**