From 4c55918dd747df4b81e5fde56dba699858ac1ad0 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Thu, 18 Oct 2018 16:36:48 +0200 Subject: mkfs.ubifs: Implement filename encryption Signed-off-by: Richard Weinberger Signed-off-by: David Oberhollenzer --- ubifs-utils/mkfs.ubifs/key.h | 4 +-- ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 61 ++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/ubifs-utils/mkfs.ubifs/key.h b/ubifs-utils/mkfs.ubifs/key.h index 0c7922b..c18e35e 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 469d587..7deca96 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); } /** -- cgit v1.2.3