aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2018-10-18 16:36:48 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2018-11-01 12:38:33 +0100
commit4c55918dd747df4b81e5fde56dba699858ac1ad0 (patch)
tree382c1358b19781eb80518a881114e3fa325eaeeb
parent35b6f36c9bee7492ed6303a6604f450963f7f8f5 (diff)
mkfs.ubifs: Implement filename encryption
Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--ubifs-utils/mkfs.ubifs/key.h4
-rw-r--r--ubifs-utils/mkfs.ubifs/mkfs.ubifs.c61
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);
}
/**