linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs
@ 2018-10-18 14:36 Richard Weinberger
  2018-10-18 14:36 ` [PATCH 01/42] Import latest ubifs-media.h Richard Weinberger
                   ` (42 more replies)
  0 siblings, 43 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

This took a little longer than expected.
I had the PoC code for some time on my desk but never found the
time to bring it into upstream shape.
With David's help I've been able to make it finally happen.

With this series applied, mkfs.ubifs is able to produce an encrypted
UBIFS filesystem.
Currently it supports only encrypting the whole filesystem.
Supported ciphers are AES-128-CBC and AES-256-XES.

Example usage:
$ dd if=/dev/urandom of=key.data count=64 bs=1 # XTS needs a 512bit key
$ mkfs.ubifs --cipher AES-256-XTS --key key.data -r /rootfs -m 2048 -e 129024 -c 2048 ubifs.enc.img
$ ubiupdatevol /dev/ubi0_0 ubifs.enc.img
$ fscryptctl insert_key < key.data
$ mount -t ubifs /dev/ubi0_0 /new_root

Thanks,
//richard

David Oberhollenzer (15):
  mkfs.ubifs: Add crypto helper functions
  mkfs.ubifs: Implement UBIFS_FLG_DOUBLE_HASH
  mkfs.ubifs: Move symlink data encryption to helper function
  mkfs.ubifs: Seperate path encryption from symlink encryption helper
  mkfs.ubifs: Cleanup add_dent_node, user path encryption helper
  mkfs.ubifs: Replace constant values with parameters in
    init_fscrypt_context
  mkfs.ubifs: Make encryption dependend on (not-yet-existant) command
    line options
  mkfs.ubifs: Get key descriptor from command line and master key from
    file
  mkfs.ubifs: Specify padding policy via command line
  mkfs.ubifs: Initial support for encryption command lines
  mkfs.ubifs: Remove cipher implementations from public header
  mkfs.ubifs: Move fscrypt definitions and functions out of mkfs.ubifs.c
  mkfs.ubifs: Cleanup over-long lines
  mkfs.ubifs: Check length of master key
  mkfs.ubifs: Accept 0x prefix for key descriptor

Richard Weinberger (27):
  Import latest ubifs-media.h
  common: Add round functions
  mkfs.ubifs: Make r5 hash binary string aware
  mkfs.ubifs: Add fscrypto defines
  mkfs.ubifs: Add basic fscrypto functions
  mkfs.ubifs: Implement UBIFS_FLG_ENCRYPTION
  mkfs.ubifs: Implement basic fscrypto context passing
  mkfs.ubifs: Implement fscrypto context store as xattr
  mkfs.ubifs: Store directory name len in the temporary index
  mkfs.ubifs: Implement filename encryption
  mkfs.ubifs: Add dummy setup for crypto
  mkfs.ubifs: Pass source/dest key len to key derive function
  mkfs.ubifs: Add encrypted symlink support
  mkfs.ubifs: Implement file contents encryption
  mkfs.ubifs: Make sure we catch nodes that should or should not have
    name
  mkfs.ubifs: Free all index entry names
  mkfs.ubifs: Correctly use iv lengths in aes-cts mode
  mkfs.ubifs: Enable Cipher selection
  mkfs.ubifs: Use correct sizes for keys and hash lengths
  mkfs.ubifs: Fixup AES-XTS mode
  mkfs.ubifs: Compute encryption key descriptor automatically
  mkfs.ubifs: Fix key descriptor printing
  mkfs.ubifs: More fscryptctl compatibility
  mkfs.ubifs: Move RAND_poll to crypto.c
  mkfs.ubifs: Enable support for building without crypto
  mkfs.ubifs: Print key descriptor only when generated
  mkfs.ubifs: Use AES-256-XTS as default

 Makefile.am                         |   4 +
 configure.ac                        |  26 +-
 include/common.h                    |  10 +
 include/mtd/ubifs-media.h           |  67 ++++-
 ubifs-utils/Makemodule.am           |  10 +-
 ubifs-utils/mkfs.ubifs/crypto.c     | 362 ++++++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/crypto.h     |  58 ++++
 ubifs-utils/mkfs.ubifs/fscrypt.c    | 270 ++++++++++++++++++
 ubifs-utils/mkfs.ubifs/fscrypt.h    | 171 ++++++++++++
 ubifs-utils/mkfs.ubifs/key.h        |  17 +-
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 409 +++++++++++++++++++++++-----
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.h |   2 +
 ubifs-utils/mkfs.ubifs/ubifs.h      |   3 +
 13 files changed, 1321 insertions(+), 88 deletions(-)
 create mode 100644 ubifs-utils/mkfs.ubifs/crypto.c
 create mode 100644 ubifs-utils/mkfs.ubifs/crypto.h
 create mode 100644 ubifs-utils/mkfs.ubifs/fscrypt.c
 create mode 100644 ubifs-utils/mkfs.ubifs/fscrypt.h

-- 
2.19.1

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH 01/42] Import latest ubifs-media.h
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 02/42] common: Add round functions Richard Weinberger
                   ` (41 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 include/mtd/ubifs-media.h | 67 +++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 7 deletions(-)

diff --git a/include/mtd/ubifs-media.h b/include/mtd/ubifs-media.h
index a324e90a58d7..e69ba1687134 100644
--- a/include/mtd/ubifs-media.h
+++ b/include/mtd/ubifs-media.h
@@ -38,8 +38,30 @@
 /* UBIFS node magic number (must not have the padding byte first or last) */
 #define UBIFS_NODE_MAGIC  0x06101831
 
-/* UBIFS on-flash format version */
-#define UBIFS_FORMAT_VERSION 4
+/*
+ * UBIFS on-flash format version. This version is increased when the on-flash
+ * format is changing. If this happens, UBIFS is will support older versions as
+ * well. But older UBIFS code will not support newer formats. Format changes
+ * will be rare and only when absolutely necessary, e.g. to fix a bug or to add
+ * a new feature.
+ *
+ * UBIFS went into mainline kernel with format version 4. The older formats
+ * were development formats.
+ */
+#define UBIFS_FORMAT_VERSION 5
+
+/*
+ * Read-only compatibility version. If the UBIFS format is changed, older UBIFS
+ * implementations will not be able to mount newer formats in read-write mode.
+ * However, depending on the change, it may be possible to mount newer formats
+ * in R/O mode. This is indicated by the R/O compatibility version which is
+ * stored in the super-block.
+ *
+ * This is needed to support boot-loaders which only need R/O mounting. With
+ * this flag it is possible to do UBIFS format changes without a need to update
+ * boot-loaders.
+ */
+#define UBIFS_RO_COMPAT_VERSION 0
 
 /* Minimum logical eraseblock size in bytes */
 #define UBIFS_MIN_LEB_SZ (15*1024)
@@ -53,6 +75,13 @@
  */
 #define UBIFS_MIN_COMPR_LEN 128
 
+/*
+ * If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes
+ * shorter than uncompressed data length, UBIFS prefers to leave this data
+ * node uncompress, because it'll be read faster.
+ */
+#define UBIFS_MIN_COMPRESS_DIFF 64
+
 /* Root inode number */
 #define UBIFS_ROOT_INO 1
 
@@ -77,7 +106,6 @@
  */
 #define UBIFS_BLOCK_SIZE  4096
 #define UBIFS_BLOCK_SHIFT 12
-#define UBIFS_BLOCK_MASK  0x00000FFF
 
 /* UBIFS padding byte pattern (must not be first or last byte of node magic) */
 #define UBIFS_PADDING_BYTE 0xCE
@@ -109,6 +137,13 @@
 /* The key is always at the same position in all keyed nodes */
 #define UBIFS_KEY_OFFSET offsetof(struct ubifs_ino_node, key)
 
+/* Garbage collector journal head number */
+#define UBIFS_GC_HEAD   0
+/* Base journal head number */
+#define UBIFS_BASE_HEAD 1
+/* Data journal head number */
+#define UBIFS_DATA_HEAD 2
+
 /*
  * LEB Properties Tree node types.
  *
@@ -267,6 +302,13 @@ enum {
 /* The largest UBIFS node */
 #define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ
 
+/*
+ * xattr name of UBIFS encryption context, we don't use a prefix
+ * nor a long name to not waste space on the flash.
+ */
+#define UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT "c"
+
+
 /*
  * On-flash inode flags.
  *
@@ -276,6 +318,7 @@ enum {
  * UBIFS_APPEND_FL: writes to the inode may only append data
  * UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous
  * UBIFS_XATTR_FL: this inode is the inode for an extended attribute value
+ * UBIFS_CRYPT_FL: use encryption for this inode
  *
  * Note, these are on-flash flags which correspond to ioctl flags
  * (@FS_COMPR_FL, etc). They have the same values now, but generally, do not
@@ -288,6 +331,7 @@ enum {
 	UBIFS_APPEND_FL    = 0x08,
 	UBIFS_DIRSYNC_FL   = 0x10,
 	UBIFS_XATTR_FL     = 0x20,
+	UBIFS_CRYPT_FL     = 0x40,
 };
 
 /* Inode flag bits used by UBIFS */
@@ -376,12 +420,19 @@ enum {
  *
  * UBIFS_FLG_BIGLPT: if "big" LPT model is used if set
  * UBIFS_FLG_SPACE_FIXUP: first-mount "fixup" of free space within LEBs needed
+ * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to
+ *			  support 64bit cookies for lookups by hash
+ * UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files
  */
 enum {
 	UBIFS_FLG_BIGLPT = 0x02,
 	UBIFS_FLG_SPACE_FIXUP = 0x04,
+	UBIFS_FLG_DOUBLE_HASH = 0x08,
+	UBIFS_FLG_ENCRYPTION = 0x10,
 };
 
+#define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT|UBIFS_FLG_SPACE_FIXUP|UBIFS_FLG_DOUBLE_HASH|UBIFS_FLG_ENCRYPTION)
+
 /**
  * struct ubifs_ch - common header node.
  * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC)
@@ -488,7 +539,8 @@ struct ubifs_ino_node {
  * @padding1: reserved for future, zeroes
  * @type: type of the target inode (%UBIFS_ITYPE_REG, %UBIFS_ITYPE_DIR, etc)
  * @nlen: name length
- * @padding2: reserved for future, zeroes
+ * @cookie: A 32bits random number, used to construct a 64bits
+ *          identifier.
  * @name: zero-terminated name
  *
  * Note, do not forget to amend 'zero_dent_node_unused()' function when
@@ -501,7 +553,7 @@ struct ubifs_dent_node {
 	__u8 padding1;
 	__u8 type;
 	__le16 nlen;
-	__u8 padding2[4]; /* Watch 'zero_dent_node_unused()' if changing! */
+	__le32 cookie;
 	__u8 name[];
 } __attribute__ ((packed));
 
@@ -511,7 +563,7 @@ struct ubifs_dent_node {
  * @key: node key
  * @size: uncompressed data size in bytes
  * @compr_type: compression type (%UBIFS_COMPR_NONE, %UBIFS_COMPR_LZO, etc)
- * @padding: reserved for future, zeroes
+ * @compr_size: compressed data size in bytes, only valid when data is encrypted
  * @data: data
  *
  * Note, do not forget to amend 'zero_data_node_unused()' function when
@@ -522,7 +574,7 @@ struct ubifs_data_node {
 	__u8 key[UBIFS_MAX_KEY_LEN];
 	__le32 size;
 	__le16 compr_type;
-	__u8 padding[2]; /* Watch 'zero_data_node_unused()' if changing! */
+	__le16 compr_size;
 	__u8 data[];
 } __attribute__ ((packed));
 
@@ -584,6 +636,7 @@ struct ubifs_pad_node {
  * @padding2: reserved for future, zeroes
  * @time_gran: time granularity in nanoseconds
  * @uuid: UUID generated when the file system image was created
+ * @ro_compat_version: UBIFS R/O compatibility version
  */
 struct ubifs_sb_node {
 	struct ubifs_ch ch;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 02/42] common: Add round functions
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
  2018-10-18 14:36 ` [PATCH 01/42] Import latest ubifs-media.h Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 03/42] mkfs.ubifs: Add crypto helper functions Richard Weinberger
                   ` (40 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 include/common.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/common.h b/include/common.h
index 2f24645fe23b..72707697b170 100644
--- a/include/common.h
+++ b/include/common.h
@@ -65,6 +65,16 @@ extern "C" {
 	(_x > _y) ? _x : _y; \
 })
 
+/*
+ * This looks more complex than it should be. But we need to
+ * get the type for the ~ right in round_down (it needs to be
+ * as wide as the result!), and we want to evaluate the macro
+ * arguments just once each.
+ */
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
 #ifndef O_CLOEXEC
 #define O_CLOEXEC 0
 #endif
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 03/42] mkfs.ubifs: Add crypto helper functions
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
  2018-10-18 14:36 ` [PATCH 01/42] Import latest ubifs-media.h Richard Weinberger
  2018-10-18 14:36 ` [PATCH 02/42] common: Add round functions Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 04/42] mkfs.ubifs: Implement UBIFS_FLG_DOUBLE_HASH Richard Weinberger
                   ` (39 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 configure.ac                        |   1 +
 ubifs-utils/Makemodule.am           |   4 +-
 ubifs-utils/mkfs.ubifs/crypto.c     | 327 ++++++++++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/crypto.h     |  68 ++++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c |   6 +
 5 files changed, 405 insertions(+), 1 deletion(-)
 create mode 100644 ubifs-utils/mkfs.ubifs/crypto.c
 create mode 100644 ubifs-utils/mkfs.ubifs/crypto.h

diff --git a/configure.ac b/configure.ac
index c596eda4a797..346fcbd26328 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,6 +115,7 @@ AC_ARG_ENABLE([lsmtd],
 	esac],
 	[AM_CONDITIONAL([BUILD_LSMTD], [true])])
 
+AC_CHECK_HEADER(openssl/rand.h)
 
 AC_ARG_WITH([jffs],
 	[AS_HELP_STRING([--without-jffs], [Disable jffsX utilities])],
diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am
index 879f91a98045..3dd299dd20cc 100644
--- a/ubifs-utils/Makemodule.am
+++ b/ubifs-utils/Makemodule.am
@@ -10,13 +10,14 @@ mkfs_ubifs_SOURCES = \
 	ubifs-utils/mkfs.ubifs/crc16.c \
 	ubifs-utils/mkfs.ubifs/lpt.c \
 	ubifs-utils/mkfs.ubifs/compr.c \
+	ubifs-utils/mkfs.ubifs/crypto.c \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.c \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c \
 	ubifs-utils/mkfs.ubifs/devtable.c
-mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) -lm
+mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) -lm -lssl -lcrypto
 mkfs_ubifs_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) $(UUID_CFLAGS) $(LIBSELINUX_CFLAGS)\
 	-I$(top_srcdir)/ubi-utils/include -I$(top_srcdir)/ubifs-utils/mkfs.ubifs/
 
@@ -28,6 +29,7 @@ UBIFS_HEADER = \
 	ubifs-utils/mkfs.ubifs/defs.h ubifs-utils/mkfs.ubifs/key.h \
 	ubifs-utils/mkfs.ubifs/lpt.h ubifs-utils/mkfs.ubifs/mkfs.ubifs.h \
 	ubifs-utils/mkfs.ubifs/ubifs.h \
+	ubifs-utils/mkfs.ubifs/crypto.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h
diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
new file mode 100644
index 000000000000..a20bd56ba3db
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2017 sigma star gmbh
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
+ */
+
+#define PROGRAM_NAME "mkfs.ubifs"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include <assert.h>
+
+#include "crypto.h"
+#include "common.h"
+#include "mtd_swab.h"
+
+
+static struct cipher ciphers[] = {
+	{
+		.name = "AES-128-CBC",
+		.encrypt_block = encrypt_block_aes128_cbc,
+		.encrypt_fname = encrypt_aes128_cbc_cts,
+	}, {
+		.name = "AES-256-XTS",
+		.encrypt_block = encrypt_block_aes256_xts,
+		.encrypt_fname = encrypt_aes256_cbc_cts,
+	}
+};
+
+
+
+static int do_sha256(const unsigned char *in, size_t len, unsigned char *out)
+{
+	unsigned int out_len;
+	EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
+
+	if (!mdctx)
+		return -1;
+
+	if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1)
+		return -1;
+
+	if(EVP_DigestUpdate(mdctx, in, len) != 1)
+		return -1;
+
+	if(EVP_DigestFinal_ex(mdctx, out, &out_len) != 1)
+		return -1;
+
+	EVP_MD_CTX_destroy(mdctx);
+
+	return 0;
+}
+
+static int check_iv_key_size(const EVP_CIPHER *cipher, size_t key_len,
+				size_t iv_len)
+{
+	if ((size_t)EVP_CIPHER_key_length(cipher) != key_len) {
+		errmsg("Cipher key length mismatch. Expected %lu, got %d",
+			(unsigned long)key_len, EVP_CIPHER_key_length(cipher));
+		return -1;
+	}
+
+	if (iv_len && (size_t)EVP_CIPHER_iv_length(cipher) != iv_len) {
+		errmsg("Cipher IV length mismatch. Expected %lu, got %d",
+			(unsigned long)iv_len, EVP_CIPHER_key_length(cipher));
+		return -1;
+	}
+
+	return 0;
+}
+
+static ssize_t do_encrypt(const EVP_CIPHER *cipher,
+				const void *plaintext, size_t size,
+				const void *key, size_t key_len,
+				const void *iv, size_t iv_len,
+				void *ciphertext)
+{
+	int ciphertext_len, len;
+	EVP_CIPHER_CTX *ctx;
+
+	if (check_iv_key_size(cipher, key_len, iv_len))
+		return -1;
+
+	if (!(ctx = EVP_CIPHER_CTX_new()))
+		goto fail;
+
+	EVP_CIPHER_CTX_set_padding(ctx, 0);
+
+	if (EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv) != 1)
+		goto fail_ctx;
+
+	if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, size) != 1)
+		goto fail_ctx;
+
+	ciphertext_len = len;
+
+	EVP_CIPHER_CTX_free(ctx);
+	return ciphertext_len;
+fail_ctx:
+	ERR_print_errors_fp(stderr);
+	EVP_CIPHER_CTX_free(ctx);
+	return -1;
+fail:
+	ERR_print_errors_fp(stderr);
+	return -1;
+}
+
+static size_t gen_essiv_salt(const void *iv, size_t iv_len, const void *key, size_t key_len, void *salt)
+{
+	size_t ret;
+	const EVP_CIPHER *cipher;
+	void *sha256 = xzalloc(EVP_MD_size(EVP_sha256()));
+
+	cipher = EVP_aes_256_ecb();
+	if (!cipher) {
+		errmsg("OpenSSL: Cipher AES-256-ECB is not supported");
+		return -1;
+	}
+
+	if (do_sha256(key, key_len, sha256) != 0) {
+		errmsg("sha256 failed");
+		return -1;
+	}
+
+	ret = do_encrypt(cipher, iv, iv_len, sha256, EVP_CIPHER_key_length(cipher), NULL, 0, salt);
+	if (ret != iv_len)
+		errmsg("Unable to compute ESSIV salt, return value %zi instead of %zi", ret, iv_len);
+
+	free(sha256);
+
+	return ret;
+}
+
+
+static ssize_t encrypt_block(const void *plaintext, size_t size,
+			     const void *key, uint64_t block_index,
+			     void *ciphertext, const EVP_CIPHER *cipher)
+{
+	size_t key_len, ret, ivsize;
+	void *essiv_salt, *iv;
+
+	ivsize = EVP_CIPHER_iv_length(cipher);
+	key_len = EVP_CIPHER_key_length(cipher);
+
+	iv = alloca(ivsize);
+	essiv_salt = alloca(ivsize);
+
+	memset(iv, 0, ivsize);
+	*((uint64_t *)iv) = cpu_to_le64(block_index);
+
+	gen_essiv_salt(iv, ivsize, key, key_len, essiv_salt);
+
+	ret = do_encrypt(cipher, plaintext, size, key, key_len,
+			 essiv_salt, ivsize, ciphertext);
+	return ret;
+}
+
+ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
+				 const void *key, uint64_t block_index,
+				 void *ciphertext)
+{
+	const EVP_CIPHER *cipher = EVP_aes_128_cbc();
+
+	if (!cipher) {
+		errmsg("OpenSSL: Cipher AES-128-CBC is not supported");
+		return -1;
+	}
+	return encrypt_block(plaintext, size, key, block_index,
+			     ciphertext, cipher);
+}
+
+ssize_t encrypt_block_aes256_xts(const void *plaintext, size_t size,
+				 const void *key, uint64_t block_index,
+				 void *ciphertext)
+{
+	const EVP_CIPHER *cipher = EVP_aes_256_xts();
+
+	if (!cipher) {
+		errmsg("OpenSSL: Cipher AES-256-XTS is not supported");
+		return -1;
+	}
+	return encrypt_block(plaintext, size, key, block_index,
+			     ciphertext, cipher);
+}
+
+static void block_swap(uint8_t *ciphertext, size_t i0, size_t i1,
+			size_t size)
+{
+	uint8_t temp[size], *p0, *p1;
+
+	p0 = ciphertext + i0 * size;
+	p1 = ciphertext + i1 * size;
+
+	memcpy(temp, p0, size);
+	memcpy(p0, p1, size);
+	memcpy(p1, temp, size);
+}
+
+static ssize_t encrypt_cbc_cts(const void *plaintext, size_t size,
+			       const void *key, void *ciphertext,
+			       const EVP_CIPHER *cipher)
+{
+	size_t diff, padded_size, count, ivsize;
+	uint8_t iv[EVP_MAX_IV_LENGTH], *padded;
+	ssize_t ret, key_len;
+
+	key_len = EVP_CIPHER_key_length(cipher);
+	ivsize = EVP_CIPHER_iv_length(cipher);
+
+	memset(iv, 0, ivsize);
+
+	diff = size % key_len;
+
+	if (diff) {
+		padded_size = size - diff + key_len;
+		padded = size > 256 ? malloc(padded_size) : alloca(padded_size);
+
+		memcpy(padded, plaintext, size);
+		memset(padded + size, 0, padded_size - size);
+
+		ret = do_encrypt(cipher, padded, padded_size, key, key_len,
+				 iv, sizeof(iv), ciphertext);
+
+		if (size > 256)
+			free(padded);
+	} else {
+		ret = do_encrypt(cipher, plaintext, size, key, key_len,
+				 iv, sizeof(iv), ciphertext);
+	}
+
+	if (ret < 0)
+		return ret;
+
+	count = ret / key_len;
+
+	if (count > 1)
+		block_swap(ciphertext, count - 2, count - 1, key_len);
+
+	return size;
+}
+
+ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
+				const void *key, void *ciphertext)
+{
+	const EVP_CIPHER *cipher = EVP_aes_128_cbc();
+	if (!cipher) {
+		errmsg("OpenSSL: Cipher AES-128-CBC is not supported");
+		return -1;
+	}
+
+	return encrypt_cbc_cts(plaintext, size, key, ciphertext, cipher);
+}
+
+ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
+				const void *key, void *ciphertext)
+{
+	const EVP_CIPHER *cipher = EVP_aes_256_cbc();
+	if (!cipher) {
+		errmsg("OpenSSL: Cipher AES-256-CBC is not supported");
+		return -1;
+	}
+
+	return encrypt_cbc_cts(plaintext, size, key, ciphertext, cipher);
+}
+
+ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
+		       void *derived_key)
+{
+	const EVP_CIPHER *cipher;
+	size_t aes_key_len;
+
+	cipher = EVP_aes_128_ecb();
+	if (!cipher) {
+		errmsg("OpenSSL: Cipher AES-128-ECB is not supported");
+		return -1;
+	}
+	aes_key_len = EVP_CIPHER_key_length(cipher);
+
+	return do_encrypt(cipher, source_key, aes_key_len, deriving_key,
+			  aes_key_len, NULL, 0, derived_key);
+}
+
+int crypto_init(void)
+{
+	ERR_load_crypto_strings();
+	return 0;
+}
+
+void crypto_cleanup(void)
+{
+	EVP_cleanup();
+	ERR_free_strings();
+}
+
+struct cipher *get_cipher(const char *name)
+{
+	size_t i;
+
+	for (i = 0; i < sizeof(ciphers) / sizeof(ciphers[0]); ++i) {
+		if (!strcmp(ciphers[i].name, name))
+			return ciphers + i;
+	}
+
+	return NULL;
+}
+
+void list_ciphers(FILE *fp)
+{
+	size_t i;
+
+	for (i = 0; i < sizeof(ciphers) / sizeof(ciphers[0]); ++i) {
+		fprintf(fp, "\t%s\n", ciphers[i].name);
+	}
+}
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
new file mode 100644
index 000000000000..4e597004ec51
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 sigma star gmbh
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
+ */
+
+#ifndef UBIFS_CRYPTO_H
+#define UBIFS_CRYPTO_H
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+
+struct cipher {
+	const char *name;
+
+	ssize_t (*encrypt_block)(const void *plaintext, size_t size,
+				 const void *key, uint64_t block_index,
+				 void *ciphertext);
+
+	ssize_t (*encrypt_fname)(const void *plaintext, size_t size,
+				 const void *key, void *ciphertext);
+};
+
+
+int crypto_init(void);
+
+void crypto_cleanup(void);
+
+ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
+				 const void *key, uint64_t block_index,
+				 void *ciphertext);
+
+ssize_t encrypt_block_aes256_xts(const void *plaintext, size_t size,
+				 const void *key, uint64_t block_index,
+				 void *ciphertext);
+
+ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
+			       const void *key, void *ciphertext);
+
+ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
+			       const void *key, void *ciphertext);
+
+ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
+		       void *derived_key);
+
+
+struct cipher *get_cipher(const char *name);
+
+void list_ciphers(FILE *fp);
+
+#endif /* UBIFS_CRYPTO_H */
+
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index c764a237135f..fd6538c6d4e1 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -35,6 +35,8 @@
 #include <selinux/label.h>
 #endif
 
+#include "crypto.h"
+
 /* Size (prime number) of hash table for link counting */
 #define HASH_TABLE_SIZE 10099
 
@@ -2625,6 +2627,9 @@ int main(int argc, char *argv[])
 {
 	int err;
 
+	if (crypto_init())
+		return -1;
+
 	err = get_options(argc, argv);
 	if (err)
 		return err;
@@ -2646,5 +2651,6 @@ int main(int argc, char *argv[])
 	if (verbose)
 		printf("Success!\n");
 
+	crypto_cleanup();
 	return 0;
 }
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 04/42] mkfs.ubifs: Implement UBIFS_FLG_DOUBLE_HASH
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (2 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 03/42] mkfs.ubifs: Add crypto helper functions Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 05/42] mkfs.ubifs: Make r5 hash binary string aware Richard Weinberger
                   ` (38 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 13 +++++++++++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.h |  2 ++
 ubifs-utils/mkfs.ubifs/ubifs.h      |  2 ++
 3 files changed, 17 insertions(+)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index fd6538c6d4e1..e7acf17f6c96 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1436,6 +1436,14 @@ static int add_symlink_inode(const char *path_name, struct stat *st, ino_t inum,
 	return add_inode(st, inum, buf, len, flags, path_name);
 }
 
+static void set_dent_cookie(struct ubifs_dent_node *dent)
+{
+	if (c->double_hash)
+		RAND_bytes((void *)&dent->cookie, sizeof(dent->cookie));
+	else
+		dent->cookie = 0;
+}
+
 /**
  * add_dent_node - write a directory entry node.
  * @dir_inum: target inode number of directory
@@ -1469,6 +1477,7 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 	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;
 
@@ -2268,6 +2277,8 @@ static int write_super(void)
 		sup.flags |= cpu_to_le32(UBIFS_FLG_BIGLPT);
 	if (c->space_fixup)
 		sup.flags |= cpu_to_le32(UBIFS_FLG_SPACE_FIXUP);
+	if (c->double_hash)
+		sup.flags |= cpu_to_le32(UBIFS_FLG_DOUBLE_HASH);
 
 	return write_node(&sup, UBIFS_SB_NODE_SZ, UBIFS_SB_LNUM);
 }
@@ -2630,6 +2641,8 @@ int main(int argc, char *argv[])
 	if (crypto_init())
 		return -1;
 
+	RAND_poll();
+
 	err = get_options(argc, argv);
 	if (err)
 		return err;
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
index 132119167fa5..aa032392155b 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
@@ -46,6 +46,8 @@
 #include <uuid.h>
 #include <sys/file.h>
 
+#include <openssl/rand.h>
+
 #include <mtd/ubifs-media.h>
 
 /* common.h requires the PROGRAM_NAME macro */
diff --git a/ubifs-utils/mkfs.ubifs/ubifs.h b/ubifs-utils/mkfs.ubifs/ubifs.h
index 2f080a8ce708..5a4af997e7bd 100644
--- a/ubifs-utils/mkfs.ubifs/ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/ubifs.h
@@ -330,6 +330,7 @@ struct ubifs_znode
  * @nhead_offs: offset of LPT head
  * @big_lpt: flag that LPT is too big to write whole during commit
  * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up
+ * @double_hash: flag indicating that we can do lookups by hash
  * @lpt_sz: LPT size
  *
  * @ltab_lnum: LEB number of LPT's own lprops table
@@ -408,6 +409,7 @@ struct ubifs_info
 	int nhead_offs;
 	int big_lpt;
 	int space_fixup;
+	int double_hash;
 	long long lpt_sz;
 
 	int ltab_lnum;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 05/42] mkfs.ubifs: Make r5 hash binary string aware
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (3 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 04/42] mkfs.ubifs: Implement UBIFS_FLG_DOUBLE_HASH Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 06/42] mkfs.ubifs: Add fscrypto defines Richard Weinberger
                   ` (37 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

As of now all filenames known by UBIFS are strings with a NUL
terminator. With encrypted filenames a filename can be any binary
string and the r5 function cannot search for the NUL terminator.
UBIFS always knows how long a filename is, therefore we can change
the hash function to iterate over the filename length to work
correctly with binary strings.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/key.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/key.h b/ubifs-utils/mkfs.ubifs/key.h
index c16d0a85418e..0c7922b67687 100644
--- a/ubifs-utils/mkfs.ubifs/key.h
+++ b/ubifs-utils/mkfs.ubifs/key.h
@@ -64,9 +64,8 @@ static inline uint32_t key_r5_hash(const char *s, int len)
 {
 	uint32_t a = 0;
 	const signed char *str = (const signed char *)s;
-	(void)len;
 
-	while (*str) {
+	while (len--) {
 		a += *str << 4;
 		a += *str >> 4;
 		a *= 11;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 06/42] mkfs.ubifs: Add fscrypto defines
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (4 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 05/42] mkfs.ubifs: Make r5 hash binary string aware Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 07/42] mkfs.ubifs: Add basic fscrypto functions Richard Weinberger
                   ` (36 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

most of them should be UAPI, therefore check using #ifndef

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 50 +++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index e7acf17f6c96..2649c34cdd68 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -109,6 +109,56 @@ struct inum_mapping {
 	struct stat st;
 };
 
+#ifndef FS_KEY_DESCRIPTOR_SIZE
+#define FS_KEY_DESCRIPTOR_SIZE  8
+#endif
+#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
+#define FS_KEY_DERIVATION_NONCE_SIZE	16
+
+#ifndef FS_ENCRYPTION_MODE_AES_128_CBC
+#define FS_ENCRYPTION_MODE_AES_128_CBC 5
+#endif
+
+#ifndef FS_ENCRYPTION_MODE_AES_128_CTS
+#define FS_ENCRYPTION_MODE_AES_128_CTS 6
+#endif
+
+#ifndef FS_POLICY_FLAGS_VALID
+#define FS_POLICY_FLAGS_PAD_4		0x00
+#define FS_POLICY_FLAGS_PAD_8		0x01
+#define FS_POLICY_FLAGS_PAD_16		0x02
+#define FS_POLICY_FLAGS_PAD_32		0x03
+#define FS_POLICY_FLAGS_PAD_MASK	0x03
+#define FS_POLICY_FLAGS_VALID		0x03
+#endif
+
+#define FS_CRYPTO_BLOCK_SIZE	16
+
+/**
+ * Encryption context for inode
+ *
+ * Protector format:
+ *  1 byte: Protector format (1 = this version)
+ *  1 byte: File contents encryption mode
+ *  1 byte: File names encryption mode
+ *  1 byte: Flags
+ *  8 bytes: Master Key descriptor
+ *  16 bytes: Encryption Key derivation nonce
+ */
+struct fscrypt_context {
+	__u8 format;
+	__u8 contents_encryption_mode;
+	__u8 filenames_encryption_mode;
+	__u8 flags;
+	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
+} __attribute__((packed));
+
+#ifndef FS_MAX_KEY_SIZE
+#define FS_MAX_KEY_SIZE	64
+#endif
+static __u8 fscrypt_masterkey[FS_MAX_KEY_SIZE];
+
 /*
  * Because we copy functions from the kernel, we use a subset of the UBIFS
  * file-system description object struct ubifs_info.
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 07/42] mkfs.ubifs: Add basic fscrypto functions
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (5 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 06/42] mkfs.ubifs: Add fscrypto defines Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 08/42] mkfs.ubifs: Implement UBIFS_FLG_ENCRYPTION Richard Weinberger
                   ` (35 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

...maybe we should add them to crypto.c?

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 67 +++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 2649c34cdd68..fc1b0cb1f6cc 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -518,6 +518,73 @@ static long long get_bytes(const char *str)
 
 	return bytes;
 }
+
+static unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx)
+{
+	int ret;
+	unsigned char *new_key = xmalloc(FS_MAX_KEY_SIZE);
+
+	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, new_key);
+	if (ret < 0) {
+		err_msg("derive_key_aes failed: %i\n", ret);
+
+		free(new_key);
+		new_key = NULL;
+	}
+
+	return new_key;
+}
+
+static struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx)
+{
+	struct fscrypt_context *new_fctx = NULL;
+
+	if (fctx) {
+		new_fctx = xmalloc(sizeof(*new_fctx));
+		new_fctx->format = fctx->format;
+		new_fctx->contents_encryption_mode = fctx->contents_encryption_mode;
+		new_fctx->filenames_encryption_mode = fctx->filenames_encryption_mode;
+		new_fctx->flags = fctx->flags;
+		memcpy(new_fctx->master_key_descriptor, fctx->master_key_descriptor,
+		       FS_KEY_DESCRIPTOR_SIZE);
+		RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+	}
+
+	return new_fctx;
+}
+
+static void free_fscrypt_context(struct fscrypt_context *fctx)
+{
+	free(fctx);
+}
+
+static void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
+{
+	int i;
+
+	normsg_cont("fscrypt master key descriptor: ");
+	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
+		normsg_cont("%02x", fctx->master_key_descriptor[i]);
+	}
+	normsg("");
+}
+
+static struct fscrypt_context *init_fscrypt_context(void)
+{
+	struct fscrypt_context *new_fctx = xmalloc(sizeof(*new_fctx));
+
+	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
+	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
+	new_fctx->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CTS;
+	//TODO  accept padding via a parameter
+	new_fctx->flags = FS_POLICY_FLAGS_PAD_4;
+	//TODO  accept descriptor via a parameter
+	RAND_bytes((void *)&new_fctx->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
+	RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+
+	return new_fctx;
+}
+
 /**
  * open_ubi - open the UBI volume.
  * @node: name of the UBI volume character device to fetch information about
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 08/42] mkfs.ubifs: Implement UBIFS_FLG_ENCRYPTION
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (6 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 07/42] mkfs.ubifs: Add basic fscrypto functions Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 09/42] mkfs.ubifs: Implement basic fscrypto context passing Richard Weinberger
                   ` (34 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

...and set UBIFS format version

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 13 ++++++++++++-
 ubifs-utils/mkfs.ubifs/ubifs.h      |  1 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index fc1b0cb1f6cc..09c28ab0b6bd 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -2357,6 +2357,15 @@ static int finalize_leb_cnt(void)
 	return 0;
 }
 
+static int ubifs_format_version(void)
+{
+	if (c->double_hash || c->encrypted)
+		return 5;
+
+	/* Default */
+	return 4;
+}
+
 /**
  * write_super - write the super block.
  */
@@ -2379,7 +2388,7 @@ static int write_super(void)
 	sup.jhead_cnt     = cpu_to_le32(c->jhead_cnt);
 	sup.fanout        = cpu_to_le32(c->fanout);
 	sup.lsave_cnt     = cpu_to_le32(c->lsave_cnt);
-	sup.fmt_version   = cpu_to_le32(UBIFS_FORMAT_VERSION);
+	sup.fmt_version   = cpu_to_le32(ubifs_format_version());
 	sup.default_compr = cpu_to_le16(c->default_compr);
 	sup.rp_size       = cpu_to_le64(c->rp_size);
 	sup.time_gran     = cpu_to_le32(DEFAULT_TIME_GRAN);
@@ -2396,6 +2405,8 @@ static int write_super(void)
 		sup.flags |= cpu_to_le32(UBIFS_FLG_SPACE_FIXUP);
 	if (c->double_hash)
 		sup.flags |= cpu_to_le32(UBIFS_FLG_DOUBLE_HASH);
+	if (c->encrypted)
+		sup.flags |= cpu_to_le32(UBIFS_FLG_ENCRYPTION);
 
 	return write_node(&sup, UBIFS_SB_NODE_SZ, UBIFS_SB_LNUM);
 }
diff --git a/ubifs-utils/mkfs.ubifs/ubifs.h b/ubifs-utils/mkfs.ubifs/ubifs.h
index 5a4af997e7bd..c26d0944ac50 100644
--- a/ubifs-utils/mkfs.ubifs/ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/ubifs.h
@@ -410,6 +410,7 @@ struct ubifs_info
 	int big_lpt;
 	int space_fixup;
 	int double_hash;
+	int encrypted;
 	long long lpt_sz;
 
 	int ltab_lnum;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 09/42] mkfs.ubifs: Implement basic fscrypto context passing
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (7 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 08/42] mkfs.ubifs: Implement UBIFS_FLG_ENCRYPTION Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 10/42] mkfs.ubifs: Implement fscrypto context store as xattr Richard Weinberger
                   ` (33 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 64 ++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 09c28ab0b6bd..349f68ab8797 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -174,6 +174,7 @@ int yes;
 
 static char *root;
 static int root_len;
+static struct fscrypt_context *root_fctx;
 static struct stat root_st;
 static char *output;
 static int out_fd;
@@ -1423,7 +1424,8 @@ static inline int inode_add_selinux_xattr(struct ubifs_ino_node *host_ino,
  * @flags: source inode flags
  */
 static int add_inode(struct stat *st, ino_t inum, void *data,
-		     unsigned int data_len, int flags, const char *xattr_path)
+		     unsigned int data_len, int flags, const char *xattr_path,
+		     struct fscrypt_context *fctx)
 {
 	struct ubifs_ino_node *ino = node_buf;
 	union ubifs_key key;
@@ -1441,7 +1443,8 @@ static int add_inode(struct stat *st, ino_t inum, void *data,
 		use_flags |= UBIFS_APPEND_FL;
 	if (flags & FS_DIRSYNC_FL && S_ISDIR(st->st_mode))
 		use_flags |= UBIFS_DIRSYNC_FL;
-
+	if (fctx)
+		use_flags |= UBIFS_CRYPT_FL;
 	memset(ino, 0, UBIFS_INO_NODE_SZ);
 
 	ino_key_init(&key, inum);
@@ -1498,7 +1501,8 @@ static int add_inode(struct stat *st, ino_t inum, void *data,
  * the device table.
  */
 static int add_dir_inode(const char *path_name, DIR *dir, ino_t inum, loff_t size,
-			 unsigned int nlink, struct stat *st)
+			 unsigned int nlink, struct stat *st,
+			 struct fscrypt_context *fctx)
 {
 	int fd, flags = 0;
 
@@ -1513,7 +1517,7 @@ static int add_dir_inode(const char *path_name, DIR *dir, ino_t inum, loff_t siz
 			flags = 0;
 	}
 
-	return add_inode(st, inum, NULL, 0, flags, path_name);
+	return add_inode(st, inum, NULL, 0, flags, path_name, fctx);
 }
 
 /**
@@ -1527,7 +1531,7 @@ static int add_dev_inode(const char *path_name, struct stat *st, ino_t inum, int
 	union ubifs_dev_desc dev;
 
 	dev.huge = cpu_to_le64(makedev(major(st->st_rdev), minor(st->st_rdev)));
-	return add_inode(st, inum, &dev, 8, flags, path_name);
+	return add_inode(st, inum, &dev, 8, flags, path_name, NULL);
 }
 
 /**
@@ -1538,7 +1542,7 @@ static int add_dev_inode(const char *path_name, struct stat *st, ino_t inum, int
  * @flags: source inode flags
  */
 static int add_symlink_inode(const char *path_name, struct stat *st, ino_t inum,
-			     int flags)
+			     int flags, struct fscrypt_context *fctx)
 {
 	char buf[UBIFS_MAX_INO_DATA + 2];
 	ssize_t len;
@@ -1550,7 +1554,7 @@ static int add_symlink_inode(const char *path_name, struct stat *st, ino_t inum,
 	if (len > UBIFS_MAX_INO_DATA)
 		return err_msg("symlink too long for %s", path_name);
 
-	return add_inode(st, inum, buf, len, flags, path_name);
+	return add_inode(st, inum, buf, len, flags, path_name, fctx);
 }
 
 static void set_dent_cookie(struct ubifs_dent_node *dent)
@@ -1569,7 +1573,7 @@ static void set_dent_cookie(struct ubifs_dent_node *dent)
  * @type: type of the target inode
  */
 static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
-			 unsigned char type)
+			 unsigned char type, struct fscrypt_context *fctx)
 {
 	struct ubifs_dent_node *dent = node_buf;
 	union ubifs_key key;
@@ -1658,7 +1662,7 @@ static int all_zero(void *buf, int len)
  * @flags: source inode flags
  */
 static int add_file(const char *path_name, struct stat *st, ino_t inum,
-		    int flags)
+		    int flags, struct fscrypt_context *fctx)
 {
 	struct ubifs_data_node *dn = node_buf;
 	void *buf = block_buf;
@@ -1728,7 +1732,7 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 		return err_msg("file size changed during writing file '%s'",
 			       path_name);
 
-	return add_inode(st, inum, NULL, 0, flags, path_name);
+	return add_inode(st, inum, NULL, 0, flags, path_name, fctx);
 }
 
 /**
@@ -1741,7 +1745,8 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
  *      creating the UBIFS inode
  */
 static int add_non_dir(const char *path_name, ino_t *inum, unsigned int nlink,
-		       unsigned char *type, struct stat *st)
+		       unsigned char *type, struct stat *st,
+		       struct fscrypt_context *fctx)
 {
 	int fd, flags = 0;
 
@@ -1806,17 +1811,17 @@ static int add_non_dir(const char *path_name, ino_t *inum, unsigned int nlink,
 	creat_sqnum = ++c->max_sqnum;
 
 	if (S_ISREG(st->st_mode))
-		return add_file(path_name, st, *inum, flags);
+		return add_file(path_name, st, *inum, flags, fctx);
 	if (S_ISCHR(st->st_mode))
 		return add_dev_inode(path_name, st, *inum, flags);
 	if (S_ISBLK(st->st_mode))
 		return add_dev_inode(path_name, st, *inum, flags);
 	if (S_ISLNK(st->st_mode))
-		return add_symlink_inode(path_name, st, *inum, flags);
+		return add_symlink_inode(path_name, st, *inum, flags, fctx);
 	if (S_ISSOCK(st->st_mode))
-		return add_inode(st, *inum, NULL, 0, flags, NULL);
+		return add_inode(st, *inum, NULL, 0, flags, NULL, NULL);
 	if (S_ISFIFO(st->st_mode))
-		return add_inode(st, *inum, NULL, 0, flags, NULL);
+		return add_inode(st, *inum, NULL, 0, flags, NULL, NULL);
 
 	return err_msg("file '%s' has unknown inode type", path_name);
 }
@@ -1831,7 +1836,7 @@ static int add_non_dir(const char *path_name, ino_t *inum, unsigned int nlink,
  *            created because it is defined in the device table file.
  */
 static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
-			 int existing)
+			 int existing, struct fscrypt_context *fctx)
 {
 	struct dirent *entry;
 	DIR *dir = NULL;
@@ -1867,6 +1872,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 	 */
 	for (; existing;) {
 		struct stat dent_st;
+		struct fscrypt_context *new_fctx = NULL;
 
 		errno = 0;
 		entry = readdir(dir);
@@ -1922,14 +1928,16 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 
 		inum = ++c->highest_inum;
 
+		new_fctx = inherit_fscrypt_context(fctx);
+
 		if (S_ISDIR(dent_st.st_mode)) {
-			err = add_directory(name, inum, &dent_st, 1);
+			err = add_directory(name, inum, &dent_st, 1, new_fctx);
 			if (err)
 				goto out_free;
 			nlink += 1;
 			type = UBIFS_ITYPE_DIR;
 		} else {
-			err = add_non_dir(name, &inum, 0, &type, &dent_st);
+			err = add_non_dir(name, &inum, 0, &type, &dent_st, new_fctx);
 			if (err)
 				goto out_free;
 		}
@@ -1938,11 +1946,13 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		if (err)
 			goto out_free;
 
-		err = add_dent_node(dir_inum, entry->d_name, inum, type);
+		err = add_dent_node(dir_inum, entry->d_name, inum, type, fctx);
 		if (err)
 			goto out_free;
 		size += ALIGN(UBIFS_DENT_NODE_SZ + strlen(entry->d_name) + 1,
 			      8);
+
+		free_fscrypt_context(new_fctx);
 	}
 
 	/*
@@ -1952,6 +1962,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 	nh_elt = first_name_htbl_element(ph_elt, &itr);
 	while (nh_elt) {
 		struct stat fake_st;
+		struct fscrypt_context *new_fctx = NULL;
 
 		/*
 		 * We prohibit creating regular files using the device table,
@@ -1978,14 +1989,16 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		name = make_path(dir_name, nh_elt->name);
 		inum = ++c->highest_inum;
 
+		new_fctx = inherit_fscrypt_context(fctx);
+
 		if (S_ISDIR(nh_elt->mode)) {
-			err = add_directory(name, inum, &fake_st, 0);
+			err = add_directory(name, inum, &fake_st, 0, new_fctx);
 			if (err)
 				goto out_free;
 			nlink += 1;
 			type = UBIFS_ITYPE_DIR;
 		} else {
-			err = add_non_dir(name, &inum, 0, &type, &fake_st);
+			err = add_non_dir(name, &inum, 0, &type, &fake_st, new_fctx);
 			if (err)
 				goto out_free;
 		}
@@ -1994,17 +2007,18 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		if (err)
 			goto out_free;
 
-		err = add_dent_node(dir_inum, nh_elt->name, inum, type);
+		err = add_dent_node(dir_inum, nh_elt->name, inum, type, fctx);
 		if (err)
 			goto out_free;
 		size += ALIGN(UBIFS_DENT_NODE_SZ + strlen(nh_elt->name) + 1, 8);
 
 		nh_elt = next_name_htbl_element(ph_elt, &itr);
+		free_fscrypt_context(new_fctx);
 	}
 
 	creat_sqnum = dir_creat_sqnum;
 
-	err = add_dir_inode(dir ? dir_name : NULL, dir, dir_inum, size, nlink, st);
+	err = add_dir_inode(dir ? dir_name : NULL, dir, dir_inum, size, nlink, st, fctx);
 	if (err)
 		goto out_free;
 
@@ -2035,7 +2049,7 @@ static int add_multi_linked_files(void)
 		for (im = hash_table[i]; im; im = im->next) {
 			dbg_msg(2, "%s", im->path_name);
 			err = add_non_dir(im->path_name, &im->use_inum,
-					  im->use_nlink, &type, &im->st);
+					  im->use_nlink, &type, &im->st, NULL);
 			if (err)
 				return err;
 		}
@@ -2083,7 +2097,7 @@ static int write_data(void)
 	if (err)
 		return err;
 
-	err = add_directory(root, UBIFS_ROOT_INO, &root_st, !!root);
+	err = add_directory(root, UBIFS_ROOT_INO, &root_st, !!root, root_fctx);
 	if (err)
 		return err;
 	err = add_multi_linked_files();
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 10/42] mkfs.ubifs: Implement fscrypto context store as xattr
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (8 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 09/42] mkfs.ubifs: Implement basic fscrypto context passing Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 11/42] mkfs.ubifs: Store directory name len in the temporary index Richard Weinberger
                   ` (32 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 53 ++++++++++++++++++-----------
 1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 349f68ab8797..e391cdaae35f 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1156,36 +1156,45 @@ static int add_node(union ubifs_key *key, char *name, void *node, int len)
 	return 0;
 }
 
-static int add_xattr(struct stat *st, ino_t inum, const void *data,
-		     unsigned int data_len, struct qstr *nm)
+static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, ino_t inum,
+		     char *name, const void *data, unsigned int data_len)
 {
 	struct ubifs_ino_node *ino;
 	struct ubifs_dent_node *xent;
+	struct qstr nm;
 	union ubifs_key xkey, nkey;
 	int len, ret;
 
-	xent = xzalloc(sizeof(*xent) + nm->len + 1);
+	nm.name = name;
+	nm.len = strlen(name);
+
+	host_ino->xattr_cnt++;
+	host_ino->xattr_size += CALC_DENT_SIZE(nm.len);
+	host_ino->xattr_size += CALC_XATTR_BYTES(data_len);
+	host_ino->xattr_names += nm.len;
+
+	xent = xzalloc(sizeof(*xent) + nm.len + 1);
 	ino = xzalloc(sizeof(*ino) + data_len);
 
-	xent_key_init(c, &xkey, inum, nm);
+	xent_key_init(c, &xkey, inum, &nm);
 	xent->ch.node_type = UBIFS_XENT_NODE;
 	key_write(&xkey, &xent->key);
 
-	len = UBIFS_XENT_NODE_SZ + nm->len + 1;
+	len = UBIFS_XENT_NODE_SZ + nm.len + 1;
 
 	xent->ch.len = len;
 	xent->padding1 = 0;
 	xent->type = UBIFS_ITYPE_DIR;
-	xent->nlen = cpu_to_le16(nm->len);
+	xent->nlen = cpu_to_le16(nm.len);
 
-	memcpy(xent->name, nm->name, nm->len + 1);
+	memcpy(xent->name, nm.name, nm.len + 1);
 
 	inum = ++c->highest_inum;
 	creat_sqnum = ++c->max_sqnum;
 
 	xent->inum = cpu_to_le64(inum);
 
-	ret = add_node(&xkey, nm->name, xent, len);
+	ret = add_node(&xkey, nm.name, xent, len);
 	if (ret)
 		goto out;
 
@@ -1217,7 +1226,7 @@ static int add_xattr(struct stat *st, ino_t inum, const void *data,
 	if (data_len)
 		memcpy(&ino->data, data, data_len);
 
-	ret = add_node(&nkey, nm->name, ino, UBIFS_INO_NODE_SZ + data_len) ;
+	ret = add_node(&nkey, nm.name, ino, UBIFS_INO_NODE_SZ + data_len) ;
 
 out:
 	free(xent);
@@ -1270,7 +1279,6 @@ static int inode_add_xattr(struct ubifs_ino_node *host_ino,
 			   const char *path_name, struct stat *st, ino_t inum)
 {
 	int ret;
-	struct qstr nm;
 	void *buf = NULL;
 	ssize_t len;
 	ssize_t pos = 0;
@@ -1327,15 +1335,7 @@ static int inode_add_xattr(struct ubifs_ino_node *host_ino,
 			continue;
 		}
 
-		nm.name = name;
-		nm.len = strlen(name);
-
-		host_ino->xattr_cnt++;
-		host_ino->xattr_size += CALC_DENT_SIZE(nm.len);
-		host_ino->xattr_size += CALC_XATTR_BYTES(attrsize);
-		host_ino->xattr_names += nm.len;
-
-		ret = add_xattr(st, inum, attrbuf, attrsize, &nm);
+		ret = add_xattr(host_ino, st, inum, name, attrbuf, attrsize);
 		if (ret < 0)
 			goto out_free;
 	}
@@ -1415,6 +1415,15 @@ static inline int inode_add_selinux_xattr(struct ubifs_ino_node *host_ino,
 }
 #endif
 
+static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
+			       struct stat *host_st,
+			       struct fscrypt_context *fctx)
+{
+	return add_xattr(host_ino, host_st, inum,
+			 UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+			 fctx, sizeof(*fctx));
+}
+
 /**
  * add_inode - write an inode.
  * @st: stat information of source inode
@@ -1484,6 +1493,12 @@ static int add_inode(struct stat *st, ino_t inum, void *data,
 			return ret;
 	}
 
+	if (fctx) {
+		ret = set_fscrypt_context(ino, inum, st, fctx);
+		if (ret < 0)
+			return ret;
+	}
+
 	return add_node(&key, NULL, ino, len);
 }
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 11/42] mkfs.ubifs: Store directory name len in the temporary index
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (9 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 10/42] mkfs.ubifs: Implement fscrypto context store as xattr Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 12/42] mkfs.ubifs: Implement filename encryption Richard Weinberger
                   ` (31 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

since names are no longer strings, we need to know the length.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index e391cdaae35f..469d5874eaa2 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -73,6 +73,7 @@ struct idx_entry {
 	struct idx_entry *prev;
 	union ubifs_key key;
 	char *name;
+	int name_len;
 	int lnum;
 	int offs;
 	int len;
@@ -1069,7 +1070,7 @@ static void set_lprops(int lnum, int offs, int flags)
  * @offs: node offset
  * @len: node length
  */
-static int add_to_index(union ubifs_key *key, char *name, int lnum, int offs,
+static int add_to_index(union ubifs_key *key, char *name, int name_len, int lnum, int offs,
 			int len)
 {
 	struct idx_entry *e;
@@ -1080,6 +1081,7 @@ static int add_to_index(union ubifs_key *key, char *name, int lnum, int offs,
 	e->prev = idx_list_last;
 	e->key = *key;
 	e->name = name;
+	e->name_len = name_len;
 	e->lnum = lnum;
 	e->offs = offs;
 	e->len = len;
@@ -1138,7 +1140,7 @@ static int reserve_space(int len, int *lnum, int *offs)
  * @node: node
  * @len: node length
  */
-static int add_node(union ubifs_key *key, char *name, void *node, int len)
+static int add_node(union ubifs_key *key, char *name, int name_len, void *node, int len)
 {
 	int err, lnum, offs;
 
@@ -1151,7 +1153,7 @@ static int add_node(union ubifs_key *key, char *name, void *node, int len)
 	memcpy(leb_buf + offs, node, len);
 	memset(leb_buf + offs + len, 0xff, ALIGN(len, 8) - len);
 
-	add_to_index(key, name, lnum, offs, len);
+	add_to_index(key, name, name_len, lnum, offs, len);
 
 	return 0;
 }
@@ -1194,7 +1196,7 @@ static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, ino_t inu
 
 	xent->inum = cpu_to_le64(inum);
 
-	ret = add_node(&xkey, nm.name, xent, len);
+	ret = add_node(&xkey, nm.name, nm.len, xent, len);
 	if (ret)
 		goto out;
 
@@ -1226,7 +1228,7 @@ static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, ino_t inu
 	if (data_len)
 		memcpy(&ino->data, data, data_len);
 
-	ret = add_node(&nkey, nm.name, ino, UBIFS_INO_NODE_SZ + data_len) ;
+	ret = add_node(&nkey, nm.name, nm.len, ino, UBIFS_INO_NODE_SZ + data_len) ;
 
 out:
 	free(xent);
@@ -1499,7 +1501,7 @@ static int add_inode(struct stat *st, ino_t inum, void *data,
 			return ret;
 	}
 
-	return add_node(&key, NULL, ino, len);
+	return add_node(&key, NULL, 0, ino, len);
 }
 
 /**
@@ -1621,7 +1623,7 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 	if (!kname)
 		return err_msg("cannot allocate memory");
 
-	return add_node(&key, kname, dent, len);
+	return add_node(&key, kname, dname.len, dent, len);
 }
 
 /**
@@ -1732,9 +1734,10 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 		compr_type = compress_data(buf, bytes_read, &dn->data,
 					   &out_len, use_compr);
 		dn->compr_type = cpu_to_le16(compr_type);
+		//TODO: encrypt
 		dn_len = UBIFS_DATA_NODE_SZ + out_len;
 		/* Add data node to file system */
-		err = add_node(&key, NULL, dn, dn_len);
+		err = add_node(&key, NULL, 0, dn, dn_len);
 		if (err) {
 			close(fd);
 			return err;
@@ -2121,13 +2124,13 @@ static int write_data(void)
 	return flush_nodes();
 }
 
-static int namecmp(const char *name1, const char *name2)
+static int namecmp(const struct idx_entry *e1, const struct idx_entry *e2)
 {
-	size_t len1 = strlen(name1), len2 = strlen(name2);
+	size_t len1 = e1->name_len, len2 = e2->name_len;
 	size_t clen = (len1 < len2) ? len1 : len2;
 	int cmp;
 
-	cmp = memcmp(name1, name2, clen);
+	cmp = memcmp(e1->name, e2->name, clen);
 	if (cmp)
 		return cmp;
 	return (len1 < len2) ? -1 : 1;
@@ -2142,7 +2145,7 @@ static int cmp_idx(const void *a, const void *b)
 	cmp = keys_cmp(&e1->key, &e2->key);
 	if (cmp)
 		return cmp;
-	return namecmp(e1->name, e2->name);
+	return namecmp(e1, e2);
 }
 
 /**
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 12/42] mkfs.ubifs: Implement filename encryption
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (10 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 11/42] mkfs.ubifs: Store directory name len in the temporary index Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 13/42] mkfs.ubifs: Add dummy setup for crypto Richard Weinberger
                   ` (30 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

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 --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);
 }
 
 /**
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 13/42] mkfs.ubifs: Add dummy setup for crypto
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (11 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 12/42] mkfs.ubifs: Implement filename encryption Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 14/42] mkfs.ubifs: Pass source/dest key len to key derive function Richard Weinberger
                   ` (29 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 7deca96e7953..a43b2a1620b1 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -2720,6 +2720,12 @@ static int init(void)
 	sz = sizeof(struct inum_mapping *) * HASH_TABLE_SIZE;
 	hash_table = xzalloc(sz);
 
+	//TODO make this a parameter
+	root_fctx = init_fscrypt_context();
+	print_fscrypt_master_key_descriptor(root_fctx);
+	c->double_hash = 1;
+	c->encrypted = 1;
+
 	err = init_compression();
 	if (err)
 		return err;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 14/42] mkfs.ubifs: Pass source/dest key len to key derive function
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (12 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 13/42] mkfs.ubifs: Add dummy setup for crypto Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 15/42] mkfs.ubifs: Add encrypted symlink support Richard Weinberger
                   ` (28 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

fscrypto is using the max key lenth (64), so we cannot use the
AES-128-ECB len.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c     | 4 ++--
 ubifs-utils/mkfs.ubifs/crypto.h     | 2 +-
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index a20bd56ba3db..f249b49b5b59 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -277,7 +277,7 @@ ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
 }
 
 ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
-		       void *derived_key)
+		       size_t source_key_len, void *derived_key)
 {
 	const EVP_CIPHER *cipher;
 	size_t aes_key_len;
@@ -289,7 +289,7 @@ ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 	}
 	aes_key_len = EVP_CIPHER_key_length(cipher);
 
-	return do_encrypt(cipher, source_key, aes_key_len, deriving_key,
+	return do_encrypt(cipher, source_key, source_key_len, deriving_key,
 			  aes_key_len, NULL, 0, derived_key);
 }
 
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
index 4e597004ec51..5bff70fea29e 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.h
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -57,7 +57,7 @@ ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
 			       const void *key, void *ciphertext);
 
 ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
-		       void *derived_key);
+		       size_t source_key_len, void *derived_key);
 
 
 struct cipher *get_cipher(const char *name);
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index a43b2a1620b1..c315e36dd3d3 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -526,7 +526,7 @@ static unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx)
 	int ret;
 	unsigned char *new_key = xmalloc(FS_MAX_KEY_SIZE);
 
-	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, new_key);
+	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, FS_MAX_KEY_SIZE, new_key);
 	if (ret < 0) {
 		err_msg("derive_key_aes failed: %i\n", ret);
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 15/42] mkfs.ubifs: Add encrypted symlink support
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (13 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 14/42] mkfs.ubifs: Pass source/dest key len to key derive function Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 16/42] mkfs.ubifs: Implement file contents encryption Richard Weinberger
                   ` (27 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 75 ++++++++++++++++++++++++++---
 1 file changed, 68 insertions(+), 7 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index c315e36dd3d3..4ffd8fd51e41 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -155,6 +155,16 @@ struct fscrypt_context {
 	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
 } __attribute__((packed));
 
+/**
+ * For encrypted symlinks, the ciphertext length is stored at the beginning
+ * of the string in little-endian format.
+ */
+struct fscrypt_symlink_data {
+	__le16 len;
+	char encrypted_path[1];
+} __attribute__((packed));
+
+
 #ifndef FS_MAX_KEY_SIZE
 #define FS_MAX_KEY_SIZE	64
 #endif
@@ -578,15 +588,22 @@ static struct fscrypt_context *init_fscrypt_context(void)
 	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
 	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
 	new_fctx->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CTS;
-	//TODO  accept padding via a parameter
 	new_fctx->flags = FS_POLICY_FLAGS_PAD_4;
-	//TODO  accept descriptor via a parameter
-	RAND_bytes((void *)&new_fctx->master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
 	RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
 
 	return new_fctx;
 }
 
+unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx, unsigned int ilen)
+{
+	int padding;
+
+	padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
+	ilen = max_t(unsigned int, ilen, FS_CRYPTO_BLOCK_SIZE);
+	return round_up(ilen, padding);
+}
+
+
 /**
  * open_ubi - open the UBI volume.
  * @node: name of the UBI volume character device to fetch information about
@@ -1478,11 +1495,54 @@ static int add_inode(struct stat *st, ino_t inum, void *data,
 	ino->gid        = cpu_to_le32(st->st_gid);
 	ino->mode       = cpu_to_le32(st->st_mode);
 	ino->flags      = cpu_to_le32(use_flags);
-	ino->data_len   = cpu_to_le32(data_len);
 	ino->compr_type = cpu_to_le16(c->default_compr);
-	if (data_len)
-		memcpy(&ino->data, data, data_len);
+	if (data_len) {
+		if (!S_ISLNK(st->st_mode))
+			return err_msg("Expected symlink");
 
+		if (!fctx) {
+			memcpy(&ino->data, data, data_len);
+		} else {
+			//TODO turn this into a common helper
+			struct fscrypt_symlink_data *sd;
+			void *inbuf, *outbuf, *crypt_key;
+			unsigned int max_namelen = UBIFS_MAX_INO_DATA;
+			unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
+			unsigned int cryptlen;
+			unsigned int link_disk_len = fscrypt_fname_encrypted_size(fctx, data_len) + sizeof(struct fscrypt_symlink_data);
+
+			cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
+			cryptlen = round_up(cryptlen, padding);
+			cryptlen = min(cryptlen, max_namelen);
+
+			sd = xzalloc(link_disk_len);
+			inbuf = xmalloc(cryptlen);
+			/* CTS mode needs a block size aligned buffer */
+			outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
+
+			memset(inbuf, 0, cryptlen);
+			memcpy(inbuf, data, data_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");
+
+			memcpy(sd->encrypted_path, outbuf, cryptlen);
+			sd->len = cpu_to_le16(cryptlen);
+			memcpy(&ino->data, sd, link_disk_len);
+			((char *)&ino->data)[link_disk_len - 1] = '\0';
+
+			data_len = link_disk_len;
+
+			free(crypt_key);
+			free(inbuf);
+			free(outbuf);
+			free(sd);
+		}
+	}
+	ino->data_len   = cpu_to_le32(data_len);
 	len = UBIFS_INO_NODE_SZ + data_len;
 
 	if (xattr_path) {
@@ -1635,7 +1695,8 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 		cryptlen = min(cryptlen, max_namelen);
 
 		inbuf = xmalloc(cryptlen);
-		outbuf = xmalloc(cryptlen + 32);
+		/* CTS mode needs a block size aligned buffer */
+		outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
 
 		memset(inbuf, 0, cryptlen);
 		memcpy(inbuf, dname.name, dname.len);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 16/42] mkfs.ubifs: Implement file contents encryption
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (14 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 15/42] mkfs.ubifs: Add encrypted symlink support Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 17/42] mkfs.ubifs: Move symlink data encryption to helper function Richard Weinberger
                   ` (26 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 39 ++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 4ffd8fd51e41..b7d68c60d481 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1817,10 +1817,9 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 		}
 		/* Make data node */
 		memset(dn, 0, UBIFS_DATA_NODE_SZ);
-		data_key_init(&key, inum, block_no++);
+		data_key_init(&key, inum, block_no);
 		dn->ch.node_type = UBIFS_DATA_NODE;
 		key_write(&key, &dn->key);
-		dn->size = cpu_to_le32(bytes_read);
 		out_len = NODE_BUFFER_SIZE - UBIFS_DATA_NODE_SZ;
 		if (c->default_compr == UBIFS_COMPR_NONE &&
 		    (flags & FS_COMPR_FL))
@@ -1834,7 +1833,39 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 		compr_type = compress_data(buf, bytes_read, &dn->data,
 					   &out_len, use_compr);
 		dn->compr_type = cpu_to_le16(compr_type);
-		//TODO: encrypt
+		dn->size = cpu_to_le32(bytes_read);
+
+		if (!fctx) {
+			dn->compr_size = 0;
+		} else {
+			void *inbuf, *outbuf, *crypt_key;
+			size_t ret, pad_len = round_up(out_len, FS_CRYPTO_BLOCK_SIZE);
+
+			dn->compr_size = out_len;
+
+			inbuf = xzalloc(pad_len);
+			outbuf = xzalloc(pad_len);
+
+			memcpy(inbuf, &dn->data, out_len);
+
+			crypt_key = calc_fscrypt_subkey(fctx);
+			if (!crypt_key)
+				return err_msg("could not compute subkey");
+
+			ret = encrypt_block_aes128_cbc(inbuf, pad_len, crypt_key, block_no,
+						       outbuf);
+			if (ret != pad_len)
+				return err_msg("encrypt_block_aes128_cbc returned %zi instead of %zi", ret, pad_len);
+
+			memcpy(&dn->data, outbuf, pad_len);
+
+			out_len = pad_len;
+
+			free(inbuf);
+			free(outbuf);
+			free(crypt_key);
+		}
+
 		dn_len = UBIFS_DATA_NODE_SZ + out_len;
 		/* Add data node to file system */
 		err = add_node(&key, NULL, 0, dn, dn_len);
@@ -1842,6 +1873,8 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 			close(fd);
 			return err;
 		}
+
+		block_no++;
 	} while (ret != 0);
 
 	if (close(fd) == -1)
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 17/42] mkfs.ubifs: Move symlink data encryption to helper function
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (15 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 16/42] mkfs.ubifs: Implement file contents encryption Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 18/42] mkfs.ubifs: Make sure we catch nodes that should or should not have name Richard Weinberger
                   ` (25 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 81 ++++++++++++++++-------------
 1 file changed, 44 insertions(+), 37 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index b7d68c60d481..b402945924ac 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1443,6 +1443,46 @@ static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
 			 fctx, sizeof(*fctx));
 }
 
+static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
+			   struct fscrypt_context *fctx)
+{
+	struct fscrypt_symlink_data *sd;
+	void *inbuf, *outbuf, *crypt_key;
+	unsigned int max_namelen = UBIFS_MAX_INO_DATA;
+	unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
+	unsigned int cryptlen;
+	unsigned int link_disk_len = fscrypt_fname_encrypted_size(fctx, data_len) + sizeof(struct fscrypt_symlink_data);
+
+	cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
+	cryptlen = round_up(cryptlen, padding);
+	cryptlen = min(cryptlen, max_namelen);
+
+	sd = xzalloc(link_disk_len);
+	inbuf = xmalloc(cryptlen);
+	/* CTS mode needs a block size aligned buffer */
+	outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
+
+	memset(inbuf, 0, cryptlen);
+	memcpy(inbuf, data, data_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");
+
+	memcpy(sd->encrypted_path, outbuf, cryptlen);
+	sd->len = cpu_to_le16(cryptlen);
+	memcpy(dst, sd, link_disk_len);
+	((char *)dst)[link_disk_len - 1] = '\0';
+
+	free(crypt_key);
+	free(inbuf);
+	free(outbuf);
+	free(sd);
+	return link_disk_len;
+}
+
 /**
  * add_inode - write an inode.
  * @st: stat information of source inode
@@ -1503,43 +1543,10 @@ static int add_inode(struct stat *st, ino_t inum, void *data,
 		if (!fctx) {
 			memcpy(&ino->data, data, data_len);
 		} else {
-			//TODO turn this into a common helper
-			struct fscrypt_symlink_data *sd;
-			void *inbuf, *outbuf, *crypt_key;
-			unsigned int max_namelen = UBIFS_MAX_INO_DATA;
-			unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
-			unsigned int cryptlen;
-			unsigned int link_disk_len = fscrypt_fname_encrypted_size(fctx, data_len) + sizeof(struct fscrypt_symlink_data);
-
-			cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
-			cryptlen = round_up(cryptlen, padding);
-			cryptlen = min(cryptlen, max_namelen);
-
-			sd = xzalloc(link_disk_len);
-			inbuf = xmalloc(cryptlen);
-			/* CTS mode needs a block size aligned buffer */
-			outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
-
-			memset(inbuf, 0, cryptlen);
-			memcpy(inbuf, data, data_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");
-
-			memcpy(sd->encrypted_path, outbuf, cryptlen);
-			sd->len = cpu_to_le16(cryptlen);
-			memcpy(&ino->data, sd, link_disk_len);
-			((char *)&ino->data)[link_disk_len - 1] = '\0';
-
-			data_len = link_disk_len;
-
-			free(crypt_key);
-			free(inbuf);
-			free(outbuf);
-			free(sd);
+			ret = encrypt_symlink(&ino->data, data, data_len, fctx);
+			if (ret < 0)
+				return ret;
+			data_len = ret;
 		}
 	}
 	ino->data_len   = cpu_to_le32(data_len);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 18/42] mkfs.ubifs: Make sure we catch nodes that should or should not have name
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (16 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 17/42] mkfs.ubifs: Move symlink data encryption to helper function Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 19/42] mkfs.ubifs: Free all index entry names Richard Weinberger
                   ` (24 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/key.h        | 10 ++++++++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c |  8 ++++++++
 2 files changed, 18 insertions(+)

diff --git a/ubifs-utils/mkfs.ubifs/key.h b/ubifs-utils/mkfs.ubifs/key.h
index c18e35e8f0a3..2de530b813a2 100644
--- a/ubifs-utils/mkfs.ubifs/key.h
+++ b/ubifs-utils/mkfs.ubifs/key.h
@@ -209,4 +209,14 @@ static inline int keys_cmp(const union ubifs_key *key1,
 	return 0;
 }
 
+/**
+ * key_type - get key type.
+ * @c: UBIFS file-system description object
+ * @key: key to get type of
+ */
+static inline int key_type(const union ubifs_key *key)
+{
+	return key->u32[1] >> UBIFS_S_KEY_BLOCK_BITS;
+}
+
 #endif /* !__UBIFS_KEY_H__ */
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index b402945924ac..8aba668f8e28 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1161,6 +1161,14 @@ static int add_node(union ubifs_key *key, char *name, int name_len, void *node,
 {
 	int err, lnum, offs;
 
+	if (key_type(key) == UBIFS_DENT_KEY || key_type(key) == UBIFS_XENT_KEY) {
+		if (!name)
+			return err_msg("Directory entry or xattr without name!");
+	} else {
+		if (name)
+			return err_msg("Name given for non dir/xattr node!");
+	}
+
 	prepare_node(node, len);
 
 	err = reserve_space(len, &lnum, &offs);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 19/42] mkfs.ubifs: Free all index entry names
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (17 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 18/42] mkfs.ubifs: Make sure we catch nodes that should or should not have name Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 20/42] mkfs.ubifs: Seperate path encryption from symlink encryption helper Richard Weinberger
                   ` (23 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

...and make valgrind memcheck happy

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 8aba668f8e28..66ca061cc225 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1253,7 +1253,7 @@ static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, ino_t inu
 	if (data_len)
 		memcpy(&ino->data, data, data_len);
 
-	ret = add_node(&nkey, nm.name, nm.len, ino, UBIFS_INO_NODE_SZ + data_len) ;
+	ret = add_node(&nkey, NULL, 0, ino, UBIFS_INO_NODE_SZ + data_len);
 
 out:
 	free(xent);
@@ -1447,7 +1447,7 @@ static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
 			       struct fscrypt_context *fctx)
 {
 	return add_xattr(host_ino, host_st, inum,
-			 UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+			 xstrdup(UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT),
 			 fctx, sizeof(*fctx));
 }
 
@@ -2470,8 +2470,10 @@ static int write_index(void)
 	}
 
 	/* Free stuff */
-	for (i = 0; i < idx_cnt; i++)
+	for (i = 0; i < idx_cnt; i++) {
+		free(idx_ptr[i]->name);
 		free(idx_ptr[i]);
+	}
 	free(idx_ptr);
 	free(idx);
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 20/42] mkfs.ubifs: Seperate path encryption from symlink encryption helper
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (18 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 19/42] mkfs.ubifs: Free all index entry names Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 21/42] mkfs.ubifs: Cleanup add_dent_node, user path " Richard Weinberger
                   ` (22 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 36 ++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 66ca061cc225..49a895ae3682 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1451,24 +1451,20 @@ static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
 			 fctx, sizeof(*fctx));
 }
 
-static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
-			   struct fscrypt_context *fctx)
+static int encrypt_path(void **outbuf, void *data, unsigned int data_len,
+			unsigned int max_namelen, struct fscrypt_context *fctx)
 {
-	struct fscrypt_symlink_data *sd;
-	void *inbuf, *outbuf, *crypt_key;
-	unsigned int max_namelen = UBIFS_MAX_INO_DATA;
+	void *inbuf, *crypt_key;
 	unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
 	unsigned int cryptlen;
-	unsigned int link_disk_len = fscrypt_fname_encrypted_size(fctx, data_len) + sizeof(struct fscrypt_symlink_data);
 
 	cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
 	cryptlen = round_up(cryptlen, padding);
 	cryptlen = min(cryptlen, max_namelen);
 
-	sd = xzalloc(link_disk_len);
 	inbuf = xmalloc(cryptlen);
 	/* CTS mode needs a block size aligned buffer */
-	outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
+	*outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
 
 	memset(inbuf, 0, cryptlen);
 	memcpy(inbuf, data, data_len);
@@ -1476,16 +1472,34 @@ static int encrypt_symlink(void *dst, void *data, unsigned int data_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)
+	if (encrypt_aes128_cbc_cts(inbuf, cryptlen, crypt_key, *outbuf) < 0)
 		return err_msg("could not encrypt filename");
 
+	free(crypt_key);
+	free(inbuf);
+	return cryptlen;
+}
+
+static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
+			   struct fscrypt_context *fctx)
+{
+	struct fscrypt_symlink_data *sd;
+	void *outbuf;
+	unsigned int link_disk_len = fscrypt_fname_encrypted_size(fctx, data_len) + sizeof(struct fscrypt_symlink_data);
+	unsigned int cryptlen;
+	int ret;
+
+	ret = encrypt_path(&outbuf, data, data_len, UBIFS_MAX_INO_DATA, fctx);
+	if (ret < 0)
+		return ret;
+	cryptlen = ret;
+
+	sd = xzalloc(link_disk_len);
 	memcpy(sd->encrypted_path, outbuf, cryptlen);
 	sd->len = cpu_to_le16(cryptlen);
 	memcpy(dst, sd, link_disk_len);
 	((char *)dst)[link_disk_len - 1] = '\0';
 
-	free(crypt_key);
-	free(inbuf);
 	free(outbuf);
 	free(sd);
 	return link_disk_len;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 21/42] mkfs.ubifs: Cleanup add_dent_node, user path encryption helper
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (19 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 20/42] mkfs.ubifs: Seperate path encryption from symlink encryption helper Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 22/42] mkfs.ubifs: Replace constant values with parameters in init_fscrypt_context Richard Weinberger
                   ` (21 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 55 ++++++++---------------------
 1 file changed, 15 insertions(+), 40 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 49a895ae3682..ae1d26726deb 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1703,53 +1703,28 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 	set_dent_cookie(dent);
 
 	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);
-		/* CTS mode needs a block size aligned buffer */
-		outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
-
-		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);
+		int ret;
+
+		ret = encrypt_path((void **)&kname, dname.name, dname.len,
+				   max_namelen, fctx);
+		if (ret < 0)
+			return ret;
+
+		kname_len = ret;
 	}
+
+	dent_key_init(c, &key, dir_inum, kname, kname_len);
+	dent->nlen = cpu_to_le16(kname_len);
+	memcpy(dent->name, kname, kname_len);
+	dent->name[kname_len] = '\0';
+	len = UBIFS_DENT_NODE_SZ + kname_len + 1;
+
 	key_write(&key, dent->key);
 
 	return add_node(&key, kname, kname_len, dent, len);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 22/42] mkfs.ubifs: Replace constant values with parameters in init_fscrypt_context
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (20 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 21/42] mkfs.ubifs: Cleanup add_dent_node, user path " Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:36 ` [PATCH 23/42] mkfs.ubifs: Make encryption dependend on (not-yet-existant) command line options Richard Weinberger
                   ` (20 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index ae1d26726deb..8be84ca1e99c 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -581,16 +581,20 @@ static void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
 	normsg("");
 }
 
-static struct fscrypt_context *init_fscrypt_context(void)
+static struct fscrypt_context *init_fscrypt_context(unsigned int flags,
+						void *master_key_descriptor,
+						void *nonce)
 {
 	struct fscrypt_context *new_fctx = xmalloc(sizeof(*new_fctx));
 
 	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
 	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
 	new_fctx->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CTS;
-	new_fctx->flags = FS_POLICY_FLAGS_PAD_4;
-	RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+	new_fctx->flags = flags;
 
+	memcpy(&new_fctx->nonce, nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+	memcpy(&new_fctx->master_key_descriptor, master_key_descriptor,
+		FS_KEY_DESCRIPTOR_SIZE);
 	return new_fctx;
 }
 
@@ -2779,6 +2783,8 @@ static int close_target(void)
  */
 static int init(void)
 {
+	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
 	int err, i, main_lebs, big_lpt = 0, sz;
 
 	c->highest_inum = UBIFS_FIRST_INO;
@@ -2821,7 +2827,11 @@ static int init(void)
 	hash_table = xzalloc(sz);
 
 	//TODO make this a parameter
-	root_fctx = init_fscrypt_context();
+	RAND_bytes((void *)master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
+	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+
+	root_fctx = init_fscrypt_context(FS_POLICY_FLAGS_PAD_4,
+					master_key_descriptor, nonce);
 	print_fscrypt_master_key_descriptor(root_fctx);
 	c->double_hash = 1;
 	c->encrypted = 1;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 23/42] mkfs.ubifs: Make encryption dependend on (not-yet-existant) command line options
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (21 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 22/42] mkfs.ubifs: Replace constant values with parameters in init_fscrypt_context Richard Weinberger
@ 2018-10-18 14:36 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 24/42] mkfs.ubifs: Get key descriptor from command line and master key from file Richard Weinberger
                   ` (19 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:36 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 8be84ca1e99c..5be390e93da9 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -217,6 +217,7 @@ static struct inum_mapping **hash_table;
 /* Inode creation sequence number */
 static unsigned long long creat_sqnum;
 
+//TODO: add options for double hash and encryption
 static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqa";
 
 static const struct option longopts[] = {
@@ -654,6 +655,8 @@ static int get_options(int argc, char**argv)
 	c->max_leb_cnt = -1;
 	c->max_bud_bytes = -1;
 	c->log_lebs = -1;
+	c->double_hash = 0;
+	c->encrypted = 0;
 
 	while (1) {
 		opt = getopt_long(argc, argv, optstring, longopts, &i);
@@ -2826,15 +2829,16 @@ static int init(void)
 	sz = sizeof(struct inum_mapping *) * HASH_TABLE_SIZE;
 	hash_table = xzalloc(sz);
 
-	//TODO make this a parameter
-	RAND_bytes((void *)master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
-	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+	if (c->encrypted) {
+		RAND_bytes((void *)master_key_descriptor,
+				FS_KEY_DESCRIPTOR_SIZE);
+		RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
 
-	root_fctx = init_fscrypt_context(FS_POLICY_FLAGS_PAD_4,
-					master_key_descriptor, nonce);
-	print_fscrypt_master_key_descriptor(root_fctx);
-	c->double_hash = 1;
-	c->encrypted = 1;
+		root_fctx = init_fscrypt_context(FS_POLICY_FLAGS_PAD_4,
+						master_key_descriptor, nonce);
+		print_fscrypt_master_key_descriptor(root_fctx);
+		c->double_hash = 1;
+	}
 
 	err = init_compression();
 	if (err)
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 24/42] mkfs.ubifs: Get key descriptor from command line and master key from file
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (22 preceding siblings ...)
  2018-10-18 14:36 ` [PATCH 23/42] mkfs.ubifs: Make encryption dependend on (not-yet-existant) command line options Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 25/42] mkfs.ubifs: Specify padding policy via command line Richard Weinberger
                   ` (18 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 131 ++++++++++++++++++++++++----
 1 file changed, 113 insertions(+), 18 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 5be390e93da9..70c306bdf94e 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -217,8 +217,7 @@ static struct inum_mapping **hash_table;
 /* Inode creation sequence number */
 static unsigned long long creat_sqnum;
 
-//TODO: add options for double hash and encryption
-static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqa";
+static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:";
 
 static const struct option longopts[] = {
 	{"root",               1, NULL, 'r'},
@@ -244,6 +243,8 @@ static const struct option longopts[] = {
 	{"squash-uids" ,       0, NULL, 'U'},
 	{"set-inode-attr",     0, NULL, 'a'},
 	{"selinux",            1, NULL, 's'},
+	{"key",                1, NULL, 'K'},
+	{"key-descriptor",     1, NULL, 'b'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -288,6 +289,8 @@ static const char *helptext =
 "                         added to the image. The attribute will contain the inode\n"
 "                         number the file has in the generated image.\n"
 "-s, --selinux=FILE       Selinux context file\n"
+"-K, --key=FILE           load an encryption key from a specified file.\n"
+"-b, --key-descriptor=HEX specify the key descriptor as a hex string.\n"
 "-h, --help               display this help text\n\n"
 "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n"
 "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n"
@@ -582,11 +585,87 @@ static void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
 	normsg("");
 }
 
+static int xdigit(int x)
+{
+	if (isupper(x))
+		return x - 'A' + 0x0A;
+	if (islower(x))
+		return x - 'a' + 0x0A;
+	return x - '0';
+}
+
+static int parse_key_descriptor(const char *desc, __u8 *dst)
+{
+	int i, hi, lo;
+
+	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; ++i) {
+		if (!desc[i * 2] || !desc[i * 2 + 1]) {
+			err_msg("key descriptor '%s' is too short", desc);
+			return -1;
+		}
+		if (!isxdigit(desc[i * 2]) || !isxdigit(desc[i * 2 + 1])) {
+			err_msg("invalid key descriptor '%s'", desc);
+			return -1;
+		}
+
+		hi = xdigit(desc[i * 2]);
+		lo = xdigit(desc[i * 2 + 1]);
+
+		dst[i] = (hi << 4) | lo;
+	}
+
+	if (desc[i * 2]) {
+		err_msg("key descriptor '%s' is too long", desc);
+		return -1;
+	}
+	return 0;
+}
+
+static int load_master_key(const char *key_file)
+{
+	int kf;
+	ssize_t keysize;
+
+	kf = open(key_file, O_RDONLY);
+	if (kf < 0) {
+		sys_errmsg("open '%s'", key_file);
+		return -1;
+	}
+
+	keysize = read(kf, fscrypt_masterkey, sizeof(fscrypt_masterkey));
+	if (keysize < 0) {
+		sys_errmsg("read '%s'", key_file);
+		goto fail;
+	}
+	if (keysize == 0) {
+		err_msg("loading key from '%s': file is empty", key_file);
+		goto fail;
+	}
+
+	close(kf);
+	return 0;
+fail:
+	close(kf);
+	return -1;
+}
+
 static struct fscrypt_context *init_fscrypt_context(unsigned int flags,
-						void *master_key_descriptor,
-						void *nonce)
+						const char *key_file,
+						const char *key_descriptor)
 {
-	struct fscrypt_context *new_fctx = xmalloc(sizeof(*new_fctx));
+	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
+	struct fscrypt_context *new_fctx;
+
+	if (parse_key_descriptor(key_descriptor, master_key_descriptor))
+		return NULL;
+
+	if (load_master_key(key_file))
+		return NULL;
+
+	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+
+	new_fctx = xmalloc(sizeof(*new_fctx));
 
 	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
 	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
@@ -635,6 +714,7 @@ static int open_ubi(const char *node)
 static int get_options(int argc, char**argv)
 {
 	int opt, i;
+	const char *key_file = NULL, *key_desc = NULL;
 	const char *tbl_file = NULL;
 	struct stat st;
 	char *endp;
@@ -812,6 +892,18 @@ static int get_options(int argc, char**argv)
 				return sys_err_msg("bad file context %s\n",
 								   context);
 			break;
+		case 'K':
+			if (key_file) {
+				return err_msg("key file specified more than once");
+			}
+			key_file = optarg;
+			break;
+		case 'b':
+			if (key_desc) {
+				return err_msg("key descriptor specified more than once");
+			}
+			key_desc = optarg;
+			break;
 		}
 	}
 
@@ -830,6 +922,22 @@ static int get_options(int argc, char**argv)
 			c->max_leb_cnt = c->vi.rsvd_lebs;
 	}
 
+	if (key_file || key_desc) {
+		if (!key_file)
+			return err_msg("no key file specified");
+		if (!key_desc)
+			return err_msg("no key descriptor specified");
+
+		c->double_hash = 1;
+		c->encrypted = 1;
+
+		root_fctx = init_fscrypt_context(FS_POLICY_FLAGS_PAD_4,
+						key_file, key_desc);
+		if (!root_fctx)
+			return -1;
+		print_fscrypt_master_key_descriptor(root_fctx);
+	}
+
 	if (c->min_io_size == -1)
 		return err_msg("min. I/O unit was not specified "
 			       "(use -h for help)");
@@ -2786,8 +2894,6 @@ static int close_target(void)
  */
 static int init(void)
 {
-	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
-	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
 	int err, i, main_lebs, big_lpt = 0, sz;
 
 	c->highest_inum = UBIFS_FIRST_INO;
@@ -2829,17 +2935,6 @@ static int init(void)
 	sz = sizeof(struct inum_mapping *) * HASH_TABLE_SIZE;
 	hash_table = xzalloc(sz);
 
-	if (c->encrypted) {
-		RAND_bytes((void *)master_key_descriptor,
-				FS_KEY_DESCRIPTOR_SIZE);
-		RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
-
-		root_fctx = init_fscrypt_context(FS_POLICY_FLAGS_PAD_4,
-						master_key_descriptor, nonce);
-		print_fscrypt_master_key_descriptor(root_fctx);
-		c->double_hash = 1;
-	}
-
 	err = init_compression();
 	if (err)
 		return err;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 25/42] mkfs.ubifs: Specify padding policy via command line
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (23 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 24/42] mkfs.ubifs: Get key descriptor from command line and master key from file Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 26/42] mkfs.ubifs: Initial support for encryption command lines Richard Weinberger
                   ` (17 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 38 ++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 70c306bdf94e..9935fceafb77 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -217,7 +217,7 @@ static struct inum_mapping **hash_table;
 /* Inode creation sequence number */
 static unsigned long long creat_sqnum;
 
-static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:";
+static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:P:";
 
 static const struct option longopts[] = {
 	{"root",               1, NULL, 'r'},
@@ -245,6 +245,7 @@ static const struct option longopts[] = {
 	{"selinux",            1, NULL, 's'},
 	{"key",                1, NULL, 'K'},
 	{"key-descriptor",     1, NULL, 'b'},
+	{"padding",            1, NULL, 'P'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -291,6 +292,8 @@ static const char *helptext =
 "-s, --selinux=FILE       Selinux context file\n"
 "-K, --key=FILE           load an encryption key from a specified file.\n"
 "-b, --key-descriptor=HEX specify the key descriptor as a hex string.\n"
+"-P, --padding=NUM        specify padding policy for encrypting filenames\n"
+"                         (default = 4).\n"
 "-h, --help               display this help text\n\n"
 "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n"
 "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n"
@@ -713,7 +716,7 @@ static int open_ubi(const char *node)
 
 static int get_options(int argc, char**argv)
 {
-	int opt, i;
+	int opt, i, fscrypt_flags = FS_POLICY_FLAGS_PAD_4;
 	const char *key_file = NULL, *key_desc = NULL;
 	const char *tbl_file = NULL;
 	struct stat st;
@@ -904,6 +907,35 @@ static int get_options(int argc, char**argv)
 			}
 			key_desc = optarg;
 			break;
+		case 'P': {
+			int error = 0;
+			unsigned long num;
+
+			num = simple_strtoul(optarg, &error);
+			if (error)
+				num = -1;
+
+			fscrypt_flags &= ~FS_POLICY_FLAGS_PAD_MASK;
+
+			switch (num) {
+			case 4:
+				fscrypt_flags |= FS_POLICY_FLAGS_PAD_4;
+				break;
+			case 8:
+				fscrypt_flags |= FS_POLICY_FLAGS_PAD_8;
+				break;
+			case 16:
+				fscrypt_flags |= FS_POLICY_FLAGS_PAD_16;
+				break;
+			case 32:
+				fscrypt_flags |= FS_POLICY_FLAGS_PAD_32;
+				break;
+			default:
+				return errmsg("invalid padding policy '%s'",
+						optarg);
+			}
+			break;
+		}
 		}
 	}
 
@@ -931,7 +963,7 @@ static int get_options(int argc, char**argv)
 		c->double_hash = 1;
 		c->encrypted = 1;
 
-		root_fctx = init_fscrypt_context(FS_POLICY_FLAGS_PAD_4,
+		root_fctx = init_fscrypt_context(fscrypt_flags,
 						key_file, key_desc);
 		if (!root_fctx)
 			return -1;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 26/42] mkfs.ubifs: Initial support for encryption command lines
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (24 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 25/42] mkfs.ubifs: Specify padding policy via command line Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 27/42] mkfs.ubifs: Remove cipher implementations from public header Richard Weinberger
                   ` (16 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 39 +++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 9935fceafb77..707758a42f4f 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -186,6 +186,7 @@ int yes;
 static char *root;
 static int root_len;
 static struct fscrypt_context *root_fctx;
+static struct cipher *fscrypt_cipher;
 static struct stat root_st;
 static char *output;
 static int out_fd;
@@ -217,7 +218,7 @@ static struct inum_mapping **hash_table;
 /* Inode creation sequence number */
 static unsigned long long creat_sqnum;
 
-static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:P:";
+static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:P:C:";
 
 static const struct option longopts[] = {
 	{"root",               1, NULL, 'r'},
@@ -246,6 +247,7 @@ static const struct option longopts[] = {
 	{"key",                1, NULL, 'K'},
 	{"key-descriptor",     1, NULL, 'b'},
 	{"padding",            1, NULL, 'P'},
+	{"cipher",             1, NULL, 'C'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -294,6 +296,8 @@ static const char *helptext =
 "-b, --key-descriptor=HEX specify the key descriptor as a hex string.\n"
 "-P, --padding=NUM        specify padding policy for encrypting filenames\n"
 "                         (default = 4).\n"
+"-C, --cipher=NAME        Specify cipher to use for file level encryption\n"
+"                         (default is \"AES-128-CBC\").\n"
 "-h, --help               display this help text\n\n"
 "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n"
 "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n"
@@ -718,7 +722,7 @@ static int get_options(int argc, char**argv)
 {
 	int opt, i, fscrypt_flags = FS_POLICY_FLAGS_PAD_4;
 	const char *key_file = NULL, *key_desc = NULL;
-	const char *tbl_file = NULL;
+	const char *tbl_file = NULL, *cipher_name = "AES-128-CBC";
 	struct stat st;
 	char *endp;
 
@@ -797,6 +801,8 @@ static int get_options(int argc, char**argv)
 			exit(EXIT_SUCCESS);
 		case '?':
 			printf("%s", helptext);
+			printf("\n\nSupported ciphers:\n");
+			list_ciphers(stdout);
 			exit(-1);
 		case 'v':
 			verbose = 1;
@@ -936,6 +942,9 @@ static int get_options(int argc, char**argv)
 			}
 			break;
 		}
+		case 'C':
+			cipher_name = optarg;
+			break;
 		}
 	}
 
@@ -967,6 +976,15 @@ static int get_options(int argc, char**argv)
 						key_file, key_desc);
 		if (!root_fctx)
 			return -1;
+
+		fscrypt_cipher = get_cipher(cipher_name);
+		if (!fscrypt_cipher) {
+			fprintf(stderr, "Cannot find cipher '%s'\n"
+				"Try `%s --help' for more information\n",
+				cipher_name, PROGRAM_NAME);
+			return -1;
+		}
+
 		print_fscrypt_master_key_descriptor(root_fctx);
 	}
 
@@ -1604,6 +1622,7 @@ static int encrypt_path(void **outbuf, void *data, unsigned int data_len,
 	void *inbuf, *crypt_key;
 	unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
 	unsigned int cryptlen;
+	int ret;
 
 	cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
 	cryptlen = round_up(cryptlen, padding);
@@ -1619,7 +1638,10 @@ static int encrypt_path(void **outbuf, void *data, unsigned int data_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)
+
+	ret = fscrypt_cipher->encrypt_fname(inbuf, cryptlen,
+					    crypt_key, *outbuf);
+	if (ret < 0)
 		return err_msg("could not encrypt filename");
 
 	free(crypt_key);
@@ -2003,10 +2025,13 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 			if (!crypt_key)
 				return err_msg("could not compute subkey");
 
-			ret = encrypt_block_aes128_cbc(inbuf, pad_len, crypt_key, block_no,
-						       outbuf);
-			if (ret != pad_len)
-				return err_msg("encrypt_block_aes128_cbc returned %zi instead of %zi", ret, pad_len);
+			ret = fscrypt_cipher->encrypt_block(inbuf, pad_len,
+							    crypt_key, block_no,
+							    outbuf);
+			if (ret != pad_len) {
+				return err_msg("encrypt_block returned %zi "
+						"instead of %zi", ret, pad_len);
+			}
 
 			memcpy(&dn->data, outbuf, pad_len);
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 27/42] mkfs.ubifs: Remove cipher implementations from public header
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (25 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 26/42] mkfs.ubifs: Initial support for encryption command lines Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 28/42] mkfs.ubifs: Move fscrypt definitions and functions out of mkfs.ubifs.c Richard Weinberger
                   ` (15 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c | 47 +++++++++++++++------------------
 ubifs-utils/mkfs.ubifs/crypto.h | 14 ----------
 2 files changed, 22 insertions(+), 39 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index f249b49b5b59..f7b51357c04a 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -27,21 +27,6 @@
 #include "common.h"
 #include "mtd_swab.h"
 
-
-static struct cipher ciphers[] = {
-	{
-		.name = "AES-128-CBC",
-		.encrypt_block = encrypt_block_aes128_cbc,
-		.encrypt_fname = encrypt_aes128_cbc_cts,
-	}, {
-		.name = "AES-256-XTS",
-		.encrypt_block = encrypt_block_aes256_xts,
-		.encrypt_fname = encrypt_aes256_cbc_cts,
-	}
-};
-
-
-
 static int do_sha256(const unsigned char *in, size_t len, unsigned char *out)
 {
 	unsigned int out_len;
@@ -168,9 +153,9 @@ static ssize_t encrypt_block(const void *plaintext, size_t size,
 	return ret;
 }
 
-ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
-				 const void *key, uint64_t block_index,
-				 void *ciphertext)
+static ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
+					const void *key, uint64_t block_index,
+					void *ciphertext)
 {
 	const EVP_CIPHER *cipher = EVP_aes_128_cbc();
 
@@ -182,9 +167,9 @@ ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
 			     ciphertext, cipher);
 }
 
-ssize_t encrypt_block_aes256_xts(const void *plaintext, size_t size,
-				 const void *key, uint64_t block_index,
-				 void *ciphertext)
+static ssize_t encrypt_block_aes256_xts(const void *plaintext, size_t size,
+					const void *key, uint64_t block_index,
+					void *ciphertext)
 {
 	const EVP_CIPHER *cipher = EVP_aes_256_xts();
 
@@ -252,8 +237,8 @@ static ssize_t encrypt_cbc_cts(const void *plaintext, size_t size,
 	return size;
 }
 
-ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
-				const void *key, void *ciphertext)
+static ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
+				      const void *key, void *ciphertext)
 {
 	const EVP_CIPHER *cipher = EVP_aes_128_cbc();
 	if (!cipher) {
@@ -264,8 +249,8 @@ ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
 	return encrypt_cbc_cts(plaintext, size, key, ciphertext, cipher);
 }
 
-ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
-				const void *key, void *ciphertext)
+static ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
+				      const void *key, void *ciphertext)
 {
 	const EVP_CIPHER *cipher = EVP_aes_256_cbc();
 	if (!cipher) {
@@ -293,6 +278,18 @@ ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 			  aes_key_len, NULL, 0, derived_key);
 }
 
+static struct cipher ciphers[] = {
+	{
+		.name = "AES-128-CBC",
+		.encrypt_block = encrypt_block_aes128_cbc,
+		.encrypt_fname = encrypt_aes128_cbc_cts,
+	}, {
+		.name = "AES-256-XTS",
+		.encrypt_block = encrypt_block_aes256_xts,
+		.encrypt_fname = encrypt_aes256_cbc_cts,
+	}
+};
+
 int crypto_init(void)
 {
 	ERR_load_crypto_strings();
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
index 5bff70fea29e..b6a1e004f46d 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.h
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -42,20 +42,6 @@ int crypto_init(void);
 
 void crypto_cleanup(void);
 
-ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
-				 const void *key, uint64_t block_index,
-				 void *ciphertext);
-
-ssize_t encrypt_block_aes256_xts(const void *plaintext, size_t size,
-				 const void *key, uint64_t block_index,
-				 void *ciphertext);
-
-ssize_t encrypt_aes128_cbc_cts(const void *plaintext, size_t size,
-			       const void *key, void *ciphertext);
-
-ssize_t encrypt_aes256_cbc_cts(const void *plaintext, size_t size,
-			       const void *key, void *ciphertext);
-
 ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 		       size_t source_key_len, void *derived_key);
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 28/42] mkfs.ubifs: Move fscrypt definitions and functions out of mkfs.ubifs.c
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (26 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 27/42] mkfs.ubifs: Remove cipher implementations from public header Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 29/42] mkfs.ubifs: Cleanup over-long lines Richard Weinberger
                   ` (14 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/Makemodule.am           |   2 +
 ubifs-utils/mkfs.ubifs/fscrypt.c    | 256 ++++++++++++++++++++++++
 ubifs-utils/mkfs.ubifs/fscrypt.h    | 112 +++++++++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 292 +---------------------------
 4 files changed, 376 insertions(+), 286 deletions(-)
 create mode 100644 ubifs-utils/mkfs.ubifs/fscrypt.c
 create mode 100644 ubifs-utils/mkfs.ubifs/fscrypt.h

diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am
index 3dd299dd20cc..5905a2badbb6 100644
--- a/ubifs-utils/Makemodule.am
+++ b/ubifs-utils/Makemodule.am
@@ -11,6 +11,7 @@ mkfs_ubifs_SOURCES = \
 	ubifs-utils/mkfs.ubifs/lpt.c \
 	ubifs-utils/mkfs.ubifs/compr.c \
 	ubifs-utils/mkfs.ubifs/crypto.c \
+	ubifs-utils/mkfs.ubifs/fscrypt.c \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h \
@@ -30,6 +31,7 @@ UBIFS_HEADER = \
 	ubifs-utils/mkfs.ubifs/lpt.h ubifs-utils/mkfs.ubifs/mkfs.ubifs.h \
 	ubifs-utils/mkfs.ubifs/ubifs.h \
 	ubifs-utils/mkfs.ubifs/crypto.h \
+	ubifs-utils/mkfs.ubifs/fscrypt.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
new file mode 100644
index 000000000000..68001e1d88f4
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2017 sigma star gmbh
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Richard Weinberger <richard@sigma-star.at>
+ *          David Oberhollenzer <david.oberhollenzer@sigma-star.at>
+ */
+
+#define PROGRAM_NAME "mkfs.ubifs"
+#include "fscrypt.h"
+
+
+static __u8 fscrypt_masterkey[FS_MAX_KEY_SIZE];
+static struct cipher *fscrypt_cipher;
+
+
+unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx)
+{
+	int ret;
+	unsigned char *new_key = xmalloc(FS_MAX_KEY_SIZE);
+
+	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, FS_MAX_KEY_SIZE, new_key);
+	if (ret < 0) {
+		err_msg("derive_key_aes failed: %i\n", ret);
+
+		free(new_key);
+		new_key = NULL;
+	}
+
+	return new_key;
+}
+
+struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx)
+{
+	struct fscrypt_context *new_fctx = NULL;
+
+	if (fctx) {
+		new_fctx = xmalloc(sizeof(*new_fctx));
+		new_fctx->format = fctx->format;
+		new_fctx->contents_encryption_mode = fctx->contents_encryption_mode;
+		new_fctx->filenames_encryption_mode = fctx->filenames_encryption_mode;
+		new_fctx->flags = fctx->flags;
+		memcpy(new_fctx->master_key_descriptor, fctx->master_key_descriptor,
+		       FS_KEY_DESCRIPTOR_SIZE);
+		RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+	}
+
+	return new_fctx;
+}
+
+void free_fscrypt_context(struct fscrypt_context *fctx)
+{
+	free(fctx);
+}
+
+void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
+{
+	int i;
+
+	normsg_cont("fscrypt master key descriptor: ");
+	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
+		normsg_cont("%02x", fctx->master_key_descriptor[i]);
+	}
+	normsg("");
+}
+
+unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx,
+					  unsigned int ilen)
+{
+	int padding;
+
+	padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
+	ilen = max_t(unsigned int, ilen, FS_CRYPTO_BLOCK_SIZE);
+	return round_up(ilen, padding);
+}
+
+int encrypt_path(void **outbuf, void *data, unsigned int data_len,
+		unsigned int max_namelen, struct fscrypt_context *fctx)
+{
+	void *inbuf, *crypt_key;
+	unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
+	unsigned int cryptlen;
+	int ret;
+
+	cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
+	cryptlen = round_up(cryptlen, padding);
+	cryptlen = min(cryptlen, max_namelen);
+
+	inbuf = xmalloc(cryptlen);
+	/* CTS mode needs a block size aligned buffer */
+	*outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
+
+	memset(inbuf, 0, cryptlen);
+	memcpy(inbuf, data, data_len);
+
+	crypt_key = calc_fscrypt_subkey(fctx);
+	if (!crypt_key)
+		return err_msg("could not compute subkey");
+
+	ret = fscrypt_cipher->encrypt_fname(inbuf, cryptlen,
+					    crypt_key, *outbuf);
+	if (ret < 0)
+		return err_msg("could not encrypt filename");
+
+	free(crypt_key);
+	free(inbuf);
+	return cryptlen;
+}
+
+int encrypt_data_node(struct fscrypt_context *fctx, unsigned int block_no,
+		      struct ubifs_data_node *dn, size_t length)
+{
+	void *inbuf, *outbuf, *crypt_key;
+	size_t ret, pad_len = round_up(length, FS_CRYPTO_BLOCK_SIZE);
+
+	dn->compr_size = length;
+
+	inbuf = xzalloc(pad_len);
+	outbuf = xzalloc(pad_len);
+
+	memcpy(inbuf, &dn->data, length);
+
+	crypt_key = calc_fscrypt_subkey(fctx);
+	if (!crypt_key)
+		return err_msg("could not compute subkey");
+
+	ret = fscrypt_cipher->encrypt_block(inbuf, pad_len,
+					    crypt_key, block_no,
+					    outbuf);
+	if (ret != pad_len) {
+		return err_msg("encrypt_block returned %zi "
+				"instead of %zi", ret, pad_len);
+	}
+
+	memcpy(&dn->data, outbuf, pad_len);
+
+	free(inbuf);
+	free(outbuf);
+	free(crypt_key);
+	return pad_len;
+}
+
+static int xdigit(int x)
+{
+	if (isupper(x))
+		return x - 'A' + 0x0A;
+	if (islower(x))
+		return x - 'a' + 0x0A;
+	return x - '0';
+}
+
+static int parse_key_descriptor(const char *desc, __u8 *dst)
+{
+	int i, hi, lo;
+
+	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; ++i) {
+		if (!desc[i * 2] || !desc[i * 2 + 1]) {
+			err_msg("key descriptor '%s' is too short", desc);
+			return -1;
+		}
+		if (!isxdigit(desc[i * 2]) || !isxdigit(desc[i * 2 + 1])) {
+			err_msg("invalid key descriptor '%s'", desc);
+			return -1;
+		}
+
+		hi = xdigit(desc[i * 2]);
+		lo = xdigit(desc[i * 2 + 1]);
+
+		dst[i] = (hi << 4) | lo;
+	}
+
+	if (desc[i * 2]) {
+		err_msg("key descriptor '%s' is too long", desc);
+		return -1;
+	}
+	return 0;
+}
+
+static int load_master_key(const char *key_file)
+{
+	int kf;
+	ssize_t keysize;
+
+	kf = open(key_file, O_RDONLY);
+	if (kf < 0) {
+		sys_errmsg("open '%s'", key_file);
+		return -1;
+	}
+
+	keysize = read(kf, fscrypt_masterkey, sizeof(fscrypt_masterkey));
+	if (keysize < 0) {
+		sys_errmsg("read '%s'", key_file);
+		goto fail;
+	}
+	if (keysize == 0) {
+		err_msg("loading key from '%s': file is empty", key_file);
+		goto fail;
+	}
+
+	close(kf);
+	return 0;
+fail:
+	close(kf);
+	return -1;
+}
+
+struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
+					     unsigned int flags,
+					     const char *key_file,
+					     const char *key_descriptor)
+{
+	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
+	struct fscrypt_context *new_fctx;
+
+	fscrypt_cipher = get_cipher(cipher_name);
+
+	if (!fscrypt_cipher) {
+		fprintf(stderr, "Cannot find cipher '%s'\n"
+			"Try `%s --help' for more information\n",
+			cipher_name, PROGRAM_NAME);
+		return NULL;
+	}
+
+	if (parse_key_descriptor(key_descriptor, master_key_descriptor))
+		return NULL;
+
+	if (load_master_key(key_file))
+		return NULL;
+
+	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+
+	new_fctx = xmalloc(sizeof(*new_fctx));
+
+	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
+	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
+	new_fctx->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CTS;
+	new_fctx->flags = flags;
+
+	memcpy(&new_fctx->nonce, nonce, FS_KEY_DERIVATION_NONCE_SIZE);
+	memcpy(&new_fctx->master_key_descriptor, master_key_descriptor,
+		FS_KEY_DESCRIPTOR_SIZE);
+	return new_fctx;
+}
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.h b/ubifs-utils/mkfs.ubifs/fscrypt.h
new file mode 100644
index 000000000000..b6fb6d136e58
--- /dev/null
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 sigma star gmbh
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Richard Weinberger <richard@sigma-star.at>
+ *          David Oberhollenzer <david.oberhollenzer@sigma-star.at>
+ */
+
+#ifndef FSCRYPT_H
+#define FSCRYPT_H
+
+
+#include "mkfs.ubifs.h"
+#include <sys/types.h>
+#include "crypto.h"
+
+
+#ifndef FS_KEY_DESCRIPTOR_SIZE
+#define FS_KEY_DESCRIPTOR_SIZE  8
+#endif
+#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
+#define FS_KEY_DERIVATION_NONCE_SIZE	16
+
+#ifndef FS_ENCRYPTION_MODE_AES_128_CBC
+#define FS_ENCRYPTION_MODE_AES_128_CBC 5
+#endif
+
+#ifndef FS_ENCRYPTION_MODE_AES_128_CTS
+#define FS_ENCRYPTION_MODE_AES_128_CTS 6
+#endif
+
+#ifndef FS_POLICY_FLAGS_VALID
+#define FS_POLICY_FLAGS_PAD_4		0x00
+#define FS_POLICY_FLAGS_PAD_8		0x01
+#define FS_POLICY_FLAGS_PAD_16		0x02
+#define FS_POLICY_FLAGS_PAD_32		0x03
+#define FS_POLICY_FLAGS_PAD_MASK	0x03
+#define FS_POLICY_FLAGS_VALID		0x03
+#endif
+
+#define FS_CRYPTO_BLOCK_SIZE	16
+
+/**
+ * Encryption context for inode
+ *
+ * Protector format:
+ *  1 byte: Protector format (1 = this version)
+ *  1 byte: File contents encryption mode
+ *  1 byte: File names encryption mode
+ *  1 byte: Flags
+ *  8 bytes: Master Key descriptor
+ *  16 bytes: Encryption Key derivation nonce
+ */
+struct fscrypt_context {
+	__u8 format;
+	__u8 contents_encryption_mode;
+	__u8 filenames_encryption_mode;
+	__u8 flags;
+	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
+	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
+} __attribute__((packed));
+
+/**
+ * For encrypted symlinks, the ciphertext length is stored at the beginning
+ * of the string in little-endian format.
+ */
+struct fscrypt_symlink_data {
+	__le16 len;
+	char encrypted_path[1];
+} __attribute__((packed));
+
+
+#ifndef FS_MAX_KEY_SIZE
+#define FS_MAX_KEY_SIZE	64
+#endif
+
+unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx);
+
+struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx);
+
+void free_fscrypt_context(struct fscrypt_context *fctx);
+
+void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx);
+
+unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx,
+					  unsigned int ilen);
+
+int encrypt_path(void **outbuf, void *data, unsigned int data_len,
+		 unsigned int max_namelen, struct fscrypt_context *fctx);
+
+int encrypt_data_node(struct fscrypt_context *fctx, unsigned int block_no,
+		      struct ubifs_data_node *dn, size_t length);
+
+struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
+					     unsigned int flags,
+					     const char *key_file,
+					     const char *key_descriptor);
+
+#endif /* FSCRYPT_H */
+
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 707758a42f4f..1710e25b88ee 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -36,6 +36,7 @@
 #endif
 
 #include "crypto.h"
+#include "fscrypt.h"
 
 /* Size (prime number) of hash table for link counting */
 #define HASH_TABLE_SIZE 10099
@@ -110,66 +111,6 @@ struct inum_mapping {
 	struct stat st;
 };
 
-#ifndef FS_KEY_DESCRIPTOR_SIZE
-#define FS_KEY_DESCRIPTOR_SIZE  8
-#endif
-#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
-#define FS_KEY_DERIVATION_NONCE_SIZE	16
-
-#ifndef FS_ENCRYPTION_MODE_AES_128_CBC
-#define FS_ENCRYPTION_MODE_AES_128_CBC 5
-#endif
-
-#ifndef FS_ENCRYPTION_MODE_AES_128_CTS
-#define FS_ENCRYPTION_MODE_AES_128_CTS 6
-#endif
-
-#ifndef FS_POLICY_FLAGS_VALID
-#define FS_POLICY_FLAGS_PAD_4		0x00
-#define FS_POLICY_FLAGS_PAD_8		0x01
-#define FS_POLICY_FLAGS_PAD_16		0x02
-#define FS_POLICY_FLAGS_PAD_32		0x03
-#define FS_POLICY_FLAGS_PAD_MASK	0x03
-#define FS_POLICY_FLAGS_VALID		0x03
-#endif
-
-#define FS_CRYPTO_BLOCK_SIZE	16
-
-/**
- * Encryption context for inode
- *
- * Protector format:
- *  1 byte: Protector format (1 = this version)
- *  1 byte: File contents encryption mode
- *  1 byte: File names encryption mode
- *  1 byte: Flags
- *  8 bytes: Master Key descriptor
- *  16 bytes: Encryption Key derivation nonce
- */
-struct fscrypt_context {
-	__u8 format;
-	__u8 contents_encryption_mode;
-	__u8 filenames_encryption_mode;
-	__u8 flags;
-	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
-	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
-} __attribute__((packed));
-
-/**
- * For encrypted symlinks, the ciphertext length is stored at the beginning
- * of the string in little-endian format.
- */
-struct fscrypt_symlink_data {
-	__le16 len;
-	char encrypted_path[1];
-} __attribute__((packed));
-
-
-#ifndef FS_MAX_KEY_SIZE
-#define FS_MAX_KEY_SIZE	64
-#endif
-static __u8 fscrypt_masterkey[FS_MAX_KEY_SIZE];
-
 /*
  * Because we copy functions from the kernel, we use a subset of the UBIFS
  * file-system description object struct ubifs_info.
@@ -186,7 +127,6 @@ int yes;
 static char *root;
 static int root_len;
 static struct fscrypt_context *root_fctx;
-static struct cipher *fscrypt_cipher;
 static struct stat root_st;
 static char *output;
 static int out_fd;
@@ -541,160 +481,6 @@ static long long get_bytes(const char *str)
 
 	return bytes;
 }
-
-static unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx)
-{
-	int ret;
-	unsigned char *new_key = xmalloc(FS_MAX_KEY_SIZE);
-
-	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, FS_MAX_KEY_SIZE, new_key);
-	if (ret < 0) {
-		err_msg("derive_key_aes failed: %i\n", ret);
-
-		free(new_key);
-		new_key = NULL;
-	}
-
-	return new_key;
-}
-
-static struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx)
-{
-	struct fscrypt_context *new_fctx = NULL;
-
-	if (fctx) {
-		new_fctx = xmalloc(sizeof(*new_fctx));
-		new_fctx->format = fctx->format;
-		new_fctx->contents_encryption_mode = fctx->contents_encryption_mode;
-		new_fctx->filenames_encryption_mode = fctx->filenames_encryption_mode;
-		new_fctx->flags = fctx->flags;
-		memcpy(new_fctx->master_key_descriptor, fctx->master_key_descriptor,
-		       FS_KEY_DESCRIPTOR_SIZE);
-		RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
-	}
-
-	return new_fctx;
-}
-
-static void free_fscrypt_context(struct fscrypt_context *fctx)
-{
-	free(fctx);
-}
-
-static void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
-{
-	int i;
-
-	normsg_cont("fscrypt master key descriptor: ");
-	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
-		normsg_cont("%02x", fctx->master_key_descriptor[i]);
-	}
-	normsg("");
-}
-
-static int xdigit(int x)
-{
-	if (isupper(x))
-		return x - 'A' + 0x0A;
-	if (islower(x))
-		return x - 'a' + 0x0A;
-	return x - '0';
-}
-
-static int parse_key_descriptor(const char *desc, __u8 *dst)
-{
-	int i, hi, lo;
-
-	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; ++i) {
-		if (!desc[i * 2] || !desc[i * 2 + 1]) {
-			err_msg("key descriptor '%s' is too short", desc);
-			return -1;
-		}
-		if (!isxdigit(desc[i * 2]) || !isxdigit(desc[i * 2 + 1])) {
-			err_msg("invalid key descriptor '%s'", desc);
-			return -1;
-		}
-
-		hi = xdigit(desc[i * 2]);
-		lo = xdigit(desc[i * 2 + 1]);
-
-		dst[i] = (hi << 4) | lo;
-	}
-
-	if (desc[i * 2]) {
-		err_msg("key descriptor '%s' is too long", desc);
-		return -1;
-	}
-	return 0;
-}
-
-static int load_master_key(const char *key_file)
-{
-	int kf;
-	ssize_t keysize;
-
-	kf = open(key_file, O_RDONLY);
-	if (kf < 0) {
-		sys_errmsg("open '%s'", key_file);
-		return -1;
-	}
-
-	keysize = read(kf, fscrypt_masterkey, sizeof(fscrypt_masterkey));
-	if (keysize < 0) {
-		sys_errmsg("read '%s'", key_file);
-		goto fail;
-	}
-	if (keysize == 0) {
-		err_msg("loading key from '%s': file is empty", key_file);
-		goto fail;
-	}
-
-	close(kf);
-	return 0;
-fail:
-	close(kf);
-	return -1;
-}
-
-static struct fscrypt_context *init_fscrypt_context(unsigned int flags,
-						const char *key_file,
-						const char *key_descriptor)
-{
-	__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
-	__u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
-	struct fscrypt_context *new_fctx;
-
-	if (parse_key_descriptor(key_descriptor, master_key_descriptor))
-		return NULL;
-
-	if (load_master_key(key_file))
-		return NULL;
-
-	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
-
-	new_fctx = xmalloc(sizeof(*new_fctx));
-
-	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
-	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
-	new_fctx->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CTS;
-	new_fctx->flags = flags;
-
-	memcpy(&new_fctx->nonce, nonce, FS_KEY_DERIVATION_NONCE_SIZE);
-	memcpy(&new_fctx->master_key_descriptor, master_key_descriptor,
-		FS_KEY_DESCRIPTOR_SIZE);
-	return new_fctx;
-}
-
-unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx, unsigned int ilen)
-{
-	int padding;
-
-	padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
-	ilen = max_t(unsigned int, ilen, FS_CRYPTO_BLOCK_SIZE);
-	return round_up(ilen, padding);
-}
-
-
 /**
  * open_ubi - open the UBI volume.
  * @node: name of the UBI volume character device to fetch information about
@@ -972,19 +758,11 @@ static int get_options(int argc, char**argv)
 		c->double_hash = 1;
 		c->encrypted = 1;
 
-		root_fctx = init_fscrypt_context(fscrypt_flags,
+		root_fctx = init_fscrypt_context(cipher_name, fscrypt_flags,
 						key_file, key_desc);
 		if (!root_fctx)
 			return -1;
 
-		fscrypt_cipher = get_cipher(cipher_name);
-		if (!fscrypt_cipher) {
-			fprintf(stderr, "Cannot find cipher '%s'\n"
-				"Try `%s --help' for more information\n",
-				cipher_name, PROGRAM_NAME);
-			return -1;
-		}
-
 		print_fscrypt_master_key_descriptor(root_fctx);
 	}
 
@@ -1616,39 +1394,6 @@ static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
 			 fctx, sizeof(*fctx));
 }
 
-static int encrypt_path(void **outbuf, void *data, unsigned int data_len,
-			unsigned int max_namelen, struct fscrypt_context *fctx)
-{
-	void *inbuf, *crypt_key;
-	unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
-	unsigned int cryptlen;
-	int ret;
-
-	cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
-	cryptlen = round_up(cryptlen, padding);
-	cryptlen = min(cryptlen, max_namelen);
-
-	inbuf = xmalloc(cryptlen);
-	/* CTS mode needs a block size aligned buffer */
-	*outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
-
-	memset(inbuf, 0, cryptlen);
-	memcpy(inbuf, data, data_len);
-
-	crypt_key = calc_fscrypt_subkey(fctx);
-	if (!crypt_key)
-		return err_msg("could not compute subkey");
-
-	ret = fscrypt_cipher->encrypt_fname(inbuf, cryptlen,
-					    crypt_key, *outbuf);
-	if (ret < 0)
-		return err_msg("could not encrypt filename");
-
-	free(crypt_key);
-	free(inbuf);
-	return cryptlen;
-}
-
 static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
 			   struct fscrypt_context *fctx)
 {
@@ -2011,35 +1756,10 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 		if (!fctx) {
 			dn->compr_size = 0;
 		} else {
-			void *inbuf, *outbuf, *crypt_key;
-			size_t ret, pad_len = round_up(out_len, FS_CRYPTO_BLOCK_SIZE);
-
-			dn->compr_size = out_len;
-
-			inbuf = xzalloc(pad_len);
-			outbuf = xzalloc(pad_len);
-
-			memcpy(inbuf, &dn->data, out_len);
-
-			crypt_key = calc_fscrypt_subkey(fctx);
-			if (!crypt_key)
-				return err_msg("could not compute subkey");
-
-			ret = fscrypt_cipher->encrypt_block(inbuf, pad_len,
-							    crypt_key, block_no,
-							    outbuf);
-			if (ret != pad_len) {
-				return err_msg("encrypt_block returned %zi "
-						"instead of %zi", ret, pad_len);
-			}
-
-			memcpy(&dn->data, outbuf, pad_len);
-
-			out_len = pad_len;
-
-			free(inbuf);
-			free(outbuf);
-			free(crypt_key);
+			ret = encrypt_data_node(fctx, block_no, dn, out_len);
+			if (ret < 0)
+				return ret;
+			out_len = ret;
 		}
 
 		dn_len = UBIFS_DATA_NODE_SZ + out_len;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 29/42] mkfs.ubifs: Cleanup over-long lines
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (27 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 28/42] mkfs.ubifs: Move fscrypt definitions and functions out of mkfs.ubifs.c Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 30/42] mkfs.ubifs: Check length of master key Richard Weinberger
                   ` (13 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 35 +++++++++++++++++++----------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 1710e25b88ee..9bd15a2f047a 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1030,8 +1030,8 @@ static void set_lprops(int lnum, int offs, int flags)
  * @offs: node offset
  * @len: node length
  */
-static int add_to_index(union ubifs_key *key, char *name, int name_len, int lnum, int offs,
-			int len)
+static int add_to_index(union ubifs_key *key, char *name, int name_len,
+			int lnum, int offs, int len)
 {
 	struct idx_entry *e;
 
@@ -1102,11 +1102,12 @@ static int reserve_space(int len, int *lnum, int *offs)
  */
 static int add_node(union ubifs_key *key, char *name, int name_len, void *node, int len)
 {
-	int err, lnum, offs;
+	int err, lnum, offs, type = key_type(key);
 
-	if (key_type(key) == UBIFS_DENT_KEY || key_type(key) == UBIFS_XENT_KEY) {
+	if (type == UBIFS_DENT_KEY || type == UBIFS_XENT_KEY) {
 		if (!name)
-			return err_msg("Directory entry or xattr without name!");
+			return err_msg("Directory entry or xattr "
+					"without name!");
 	} else {
 		if (name)
 			return err_msg("Name given for non dir/xattr node!");
@@ -1126,8 +1127,9 @@ static int add_node(union ubifs_key *key, char *name, int name_len, void *node,
 	return 0;
 }
 
-static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st, ino_t inum,
-		     char *name, const void *data, unsigned int data_len)
+static int add_xattr(struct ubifs_ino_node *host_ino, struct stat *st,
+		     ino_t inum, char *name, const void *data,
+		     unsigned int data_len)
 {
 	struct ubifs_ino_node *ino;
 	struct ubifs_dent_node *xent;
@@ -1399,10 +1401,13 @@ static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
 {
 	struct fscrypt_symlink_data *sd;
 	void *outbuf;
-	unsigned int link_disk_len = fscrypt_fname_encrypted_size(fctx, data_len) + sizeof(struct fscrypt_symlink_data);
+	unsigned int link_disk_len;
 	unsigned int cryptlen;
 	int ret;
 
+	link_disk_len = sizeof(struct fscrypt_symlink_data);
+	link_disk_len += fscrypt_fname_encrypted_size(fctx, data_len);
+
 	ret = encrypt_path(&outbuf, data, data_len, UBIFS_MAX_INO_DATA, fctx);
 	if (ret < 0)
 		return ret;
@@ -1622,9 +1627,12 @@ static int add_dent_node(ino_t dir_inum, const char *name, ino_t inum,
 		if (!kname)
 			return err_msg("cannot allocate memory");
 	} else {
-		unsigned int max_namelen = type == UBIFS_ITYPE_LNK ? UBIFS_MAX_INO_DATA : UBIFS_MAX_NLEN;
+		unsigned int max_namelen = UBIFS_MAX_NLEN;
 		int ret;
 
+		if (type == UBIFS_ITYPE_LNK)
+			max_namelen = UBIFS_MAX_INO_DATA;
+
 		ret = encrypt_path((void **)&kname, dname.name, dname.len,
 				   max_namelen, fctx);
 		if (ret < 0)
@@ -1984,7 +1992,8 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 			nlink += 1;
 			type = UBIFS_ITYPE_DIR;
 		} else {
-			err = add_non_dir(name, &inum, 0, &type, &dent_st, new_fctx);
+			err = add_non_dir(name, &inum, 0, &type,
+					  &dent_st, new_fctx);
 			if (err)
 				goto out_free;
 		}
@@ -2045,7 +2054,8 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 			nlink += 1;
 			type = UBIFS_ITYPE_DIR;
 		} else {
-			err = add_non_dir(name, &inum, 0, &type, &fake_st, new_fctx);
+			err = add_non_dir(name, &inum, 0, &type,
+					  &fake_st, new_fctx);
 			if (err)
 				goto out_free;
 		}
@@ -2065,7 +2075,8 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 
 	creat_sqnum = dir_creat_sqnum;
 
-	err = add_dir_inode(dir ? dir_name : NULL, dir, dir_inum, size, nlink, st, fctx);
+	err = add_dir_inode(dir ? dir_name : NULL, dir, dir_inum, size,
+			    nlink, st, fctx);
 	if (err)
 		goto out_free;
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 30/42] mkfs.ubifs: Check length of master key
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (28 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 29/42] mkfs.ubifs: Cleanup over-long lines Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 31/42] mkfs.ubifs: Accept 0x prefix for key descriptor Richard Weinberger
                   ` (12 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c  | 2 ++
 ubifs-utils/mkfs.ubifs/crypto.h  | 1 +
 ubifs-utils/mkfs.ubifs/fscrypt.c | 9 +++++++--
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index f7b51357c04a..bd3273767a5b 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -281,10 +281,12 @@ ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 static struct cipher ciphers[] = {
 	{
 		.name = "AES-128-CBC",
+		.key_length = 16,
 		.encrypt_block = encrypt_block_aes128_cbc,
 		.encrypt_fname = encrypt_aes128_cbc_cts,
 	}, {
 		.name = "AES-256-XTS",
+		.key_length = 64,
 		.encrypt_block = encrypt_block_aes256_xts,
 		.encrypt_fname = encrypt_aes256_cbc_cts,
 	}
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
index b6a1e004f46d..7fb2d3b8d005 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.h
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -28,6 +28,7 @@
 
 struct cipher {
 	const char *name;
+	unsigned int key_length;
 
 	ssize_t (*encrypt_block)(const void *plaintext, size_t size,
 				 const void *key, uint64_t block_index,
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index 68001e1d88f4..6d1fa4ba9d3f 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -188,7 +188,7 @@ static int parse_key_descriptor(const char *desc, __u8 *dst)
 	return 0;
 }
 
-static int load_master_key(const char *key_file)
+static int load_master_key(const char *key_file, struct cipher *fsc)
 {
 	int kf;
 	ssize_t keysize;
@@ -208,6 +208,11 @@ static int load_master_key(const char *key_file)
 		err_msg("loading key from '%s': file is empty", key_file);
 		goto fail;
 	}
+	if (keysize < fsc->key_length) {
+		err_msg("key '%s' is too short (at least %u bytes required)",
+			key_file, fsc->key_length);
+		goto fail;
+	}
 
 	close(kf);
 	return 0;
@@ -237,7 +242,7 @@ struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
 	if (parse_key_descriptor(key_descriptor, master_key_descriptor))
 		return NULL;
 
-	if (load_master_key(key_file))
+	if (load_master_key(key_file, fscrypt_cipher))
 		return NULL;
 
 	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 31/42] mkfs.ubifs: Accept 0x prefix for key descriptor
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (29 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 30/42] mkfs.ubifs: Check length of master key Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 32/42] mkfs.ubifs: Correctly use iv lengths in aes-cts mode Richard Weinberger
                   ` (11 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/fscrypt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index 6d1fa4ba9d3f..02132e205a35 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -165,6 +165,9 @@ static int parse_key_descriptor(const char *desc, __u8 *dst)
 {
 	int i, hi, lo;
 
+	if (desc[0] == '0' && (desc[1] == 'x' || desc[1] == 'X'))
+		desc += 2;
+
 	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; ++i) {
 		if (!desc[i * 2] || !desc[i * 2 + 1]) {
 			err_msg("key descriptor '%s' is too short", desc);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 32/42] mkfs.ubifs: Correctly use iv lengths in aes-cts mode
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (30 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 31/42] mkfs.ubifs: Accept 0x prefix for key descriptor Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 33/42] mkfs.ubifs: Enable Cipher selection Richard Weinberger
                   ` (10 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

The key length can be very long, for example in xts mode.
So we have to use the right sizes for block and iv lengths.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index bd3273767a5b..8d113f198bb2 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -207,32 +207,32 @@ static ssize_t encrypt_cbc_cts(const void *plaintext, size_t size,
 
 	memset(iv, 0, ivsize);
 
-	diff = size % key_len;
+	diff = size % ivsize;
 
 	if (diff) {
-		padded_size = size - diff + key_len;
+		padded_size = size - diff + ivsize;
 		padded = size > 256 ? malloc(padded_size) : alloca(padded_size);
 
 		memcpy(padded, plaintext, size);
 		memset(padded + size, 0, padded_size - size);
 
 		ret = do_encrypt(cipher, padded, padded_size, key, key_len,
-				 iv, sizeof(iv), ciphertext);
+				 iv, ivsize, ciphertext);
 
 		if (size > 256)
 			free(padded);
 	} else {
 		ret = do_encrypt(cipher, plaintext, size, key, key_len,
-				 iv, sizeof(iv), ciphertext);
+				 iv, ivsize, ciphertext);
 	}
 
 	if (ret < 0)
 		return ret;
 
-	count = ret / key_len;
+	count = ret / ivsize;
 
 	if (count > 1)
-		block_swap(ciphertext, count - 2, count - 1, key_len);
+		block_swap(ciphertext, count - 2, count - 1, ivsize);
 
 	return size;
 }
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 33/42] mkfs.ubifs: Enable Cipher selection
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (31 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 32/42] mkfs.ubifs: Correctly use iv lengths in aes-cts mode Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 34/42] mkfs.ubifs: Use correct sizes for keys and hash lengths Richard Weinberger
                   ` (9 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

No longer hard code AES-128-CBC, we support AES-256-XTS too.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c  | 7 +++++--
 ubifs-utils/mkfs.ubifs/crypto.h  | 3 +++
 ubifs-utils/mkfs.ubifs/fscrypt.c | 4 ++--
 ubifs-utils/mkfs.ubifs/fscrypt.h | 9 ++++++++-
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index 8d113f198bb2..ec414531e94a 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -23,9 +23,8 @@
 #include <string.h>
 #include <assert.h>
 
-#include "crypto.h"
+#include "fscrypt.h"
 #include "common.h"
-#include "mtd_swab.h"
 
 static int do_sha256(const unsigned char *in, size_t len, unsigned char *out)
 {
@@ -284,11 +283,15 @@ static struct cipher ciphers[] = {
 		.key_length = 16,
 		.encrypt_block = encrypt_block_aes128_cbc,
 		.encrypt_fname = encrypt_aes128_cbc_cts,
+		.fscrypt_block_mode = FS_ENCRYPTION_MODE_AES_128_CBC,
+		.fscrypt_fname_mode = FS_ENCRYPTION_MODE_AES_128_CTS,
 	}, {
 		.name = "AES-256-XTS",
 		.key_length = 64,
 		.encrypt_block = encrypt_block_aes256_xts,
 		.encrypt_fname = encrypt_aes256_cbc_cts,
+		.fscrypt_block_mode = FS_ENCRYPTION_MODE_AES_256_XTS,
+		.fscrypt_fname_mode = FS_ENCRYPTION_MODE_AES_256_CTS,
 	}
 };
 
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
index 7fb2d3b8d005..c2631dd0fd89 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.h
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -36,6 +36,9 @@ struct cipher {
 
 	ssize_t (*encrypt_fname)(const void *plaintext, size_t size,
 				 const void *key, void *ciphertext);
+
+	unsigned int fscrypt_block_mode;
+	unsigned int fscrypt_fname_mode;
 };
 
 
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index 02132e205a35..2fc0ae8b3509 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -253,8 +253,8 @@ struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
 	new_fctx = xmalloc(sizeof(*new_fctx));
 
 	new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
-	new_fctx->contents_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CBC;
-	new_fctx->filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_128_CTS;
+	new_fctx->contents_encryption_mode = fscrypt_cipher->fscrypt_block_mode;
+	new_fctx->filenames_encryption_mode = fscrypt_cipher->fscrypt_fname_mode;
 	new_fctx->flags = flags;
 
 	memcpy(&new_fctx->nonce, nonce, FS_KEY_DERIVATION_NONCE_SIZE);
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.h b/ubifs-utils/mkfs.ubifs/fscrypt.h
index b6fb6d136e58..e39d7e105fda 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.h
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.h
@@ -26,13 +26,20 @@
 #include <sys/types.h>
 #include "crypto.h"
 
-
 #ifndef FS_KEY_DESCRIPTOR_SIZE
 #define FS_KEY_DESCRIPTOR_SIZE  8
 #endif
 #define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
 #define FS_KEY_DERIVATION_NONCE_SIZE	16
 
+#ifndef FS_ENCRYPTION_MODE_AES_256_XTS
+#define FS_ENCRYPTION_MODE_AES_256_XTS 1
+#endif
+
+#ifndef FS_ENCRYPTION_MODE_AES_256_CTS
+#define FS_ENCRYPTION_MODE_AES_256_CTS 4
+#endif
+
 #ifndef FS_ENCRYPTION_MODE_AES_128_CBC
 #define FS_ENCRYPTION_MODE_AES_128_CBC 5
 #endif
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 34/42] mkfs.ubifs: Use correct sizes for keys and hash lengths
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (32 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 33/42] mkfs.ubifs: Enable Cipher selection Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 35/42] mkfs.ubifs: Fixup AES-XTS mode Richard Weinberger
                   ` (8 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

This works currently by chance since the sizes match, but
that might change with different cipher setups.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c  | 2 +-
 ubifs-utils/mkfs.ubifs/fscrypt.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index ec414531e94a..7d35ae7473ba 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -119,7 +119,7 @@ static size_t gen_essiv_salt(const void *iv, size_t iv_len, const void *key, siz
 		return -1;
 	}
 
-	ret = do_encrypt(cipher, iv, iv_len, sha256, EVP_CIPHER_key_length(cipher), NULL, 0, salt);
+	ret = do_encrypt(cipher, iv, iv_len, sha256, EVP_MD_size(EVP_sha256()), NULL, 0, salt);
 	if (ret != iv_len)
 		errmsg("Unable to compute ESSIV salt, return value %zi instead of %zi", ret, iv_len);
 
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index 2fc0ae8b3509..b9f9acc17c17 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -31,7 +31,7 @@ unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx)
 	int ret;
 	unsigned char *new_key = xmalloc(FS_MAX_KEY_SIZE);
 
-	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, FS_MAX_KEY_SIZE, new_key);
+	ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, fscrypt_cipher->key_length, new_key);
 	if (ret < 0) {
 		err_msg("derive_key_aes failed: %i\n", ret);
 
@@ -202,7 +202,7 @@ static int load_master_key(const char *key_file, struct cipher *fsc)
 		return -1;
 	}
 
-	keysize = read(kf, fscrypt_masterkey, sizeof(fscrypt_masterkey));
+	keysize = read(kf, fscrypt_masterkey, fsc->key_length);
 	if (keysize < 0) {
 		sys_errmsg("read '%s'", key_file);
 		goto fail;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 35/42] mkfs.ubifs: Fixup AES-XTS mode
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (33 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 34/42] mkfs.ubifs: Use correct sizes for keys and hash lengths Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 36/42] mkfs.ubifs: Compute encryption key descriptor automatically Richard Weinberger
                   ` (7 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

In XTS mode we don't need ESSIV, just use the block number
as tweak.
Also apply EVP_EncryptFinal().

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c  | 35 +++++++++++++++++++++-----------
 ubifs-utils/mkfs.ubifs/fscrypt.h |  4 ++++
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index 7d35ae7473ba..d0f24e1a5f6f 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -91,6 +91,13 @@ static ssize_t do_encrypt(const EVP_CIPHER *cipher,
 
 	ciphertext_len = len;
 
+	if (cipher == EVP_aes_256_xts()) {
+		if (EVP_EncryptFinal(ctx, ciphertext + ciphertext_len, &len) != 1)
+			goto fail_ctx;
+
+		ciphertext_len += len;
+	}
+
 	EVP_CIPHER_CTX_free(ctx);
 	return ciphertext_len;
 fail_ctx:
@@ -128,28 +135,32 @@ static size_t gen_essiv_salt(const void *iv, size_t iv_len, const void *key, siz
 	return ret;
 }
 
-
 static ssize_t encrypt_block(const void *plaintext, size_t size,
 			     const void *key, uint64_t block_index,
 			     void *ciphertext, const EVP_CIPHER *cipher)
 {
-	size_t key_len, ret, ivsize;
-	void *essiv_salt, *iv;
+	size_t key_len, ivsize;
+	void *tweak;
+	struct {
+		uint64_t index;
+		uint8_t padding[FS_IV_SIZE - sizeof(uint64_t)];
+	} iv;
 
 	ivsize = EVP_CIPHER_iv_length(cipher);
 	key_len = EVP_CIPHER_key_length(cipher);
 
-	iv = alloca(ivsize);
-	essiv_salt = alloca(ivsize);
+	iv.index = cpu_to_le64(block_index);
+	memset(iv.padding, 0, sizeof(iv.padding));
 
-	memset(iv, 0, ivsize);
-	*((uint64_t *)iv) = cpu_to_le64(block_index);
-
-	gen_essiv_salt(iv, ivsize, key, key_len, essiv_salt);
+	if (cipher == EVP_aes_256_cbc()) {
+		tweak = alloca(ivsize);
+		gen_essiv_salt(&iv, FS_IV_SIZE, key, key_len, tweak);
+	} else {
+		tweak = &iv;
+	}
 
-	ret = do_encrypt(cipher, plaintext, size, key, key_len,
-			 essiv_salt, ivsize, ciphertext);
-	return ret;
+	return do_encrypt(cipher, plaintext, size, key, key_len, tweak,
+			  ivsize, ciphertext);
 }
 
 static ssize_t encrypt_block_aes128_cbc(const void *plaintext, size_t size,
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.h b/ubifs-utils/mkfs.ubifs/fscrypt.h
index e39d7e105fda..e3cfee50290a 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.h
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.h
@@ -93,6 +93,10 @@ struct fscrypt_symlink_data {
 #define FS_MAX_KEY_SIZE	64
 #endif
 
+#ifndef FS_IV_SIZE
+#define FS_IV_SIZE 16
+#endif
+
 unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx);
 
 struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 36/42] mkfs.ubifs: Compute encryption key descriptor automatically
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (34 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 35/42] mkfs.ubifs: Fixup AES-XTS mode Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 37/42] mkfs.ubifs: Fix key descriptor printing Richard Weinberger
                   ` (6 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

...if none is given. To be compatible with fscryptctl.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c     | 27 ++++++++++++++++++++++++---
 ubifs-utils/mkfs.ubifs/crypto.h     |  1 +
 ubifs-utils/mkfs.ubifs/fscrypt.c    | 11 ++++++++---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c |  2 --
 4 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index d0f24e1a5f6f..50a09b53ebfe 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -26,7 +26,7 @@
 #include "fscrypt.h"
 #include "common.h"
 
-static int do_sha256(const unsigned char *in, size_t len, unsigned char *out)
+static int do_hash(const EVP_MD *md, const unsigned char *in, size_t len, unsigned char *out)
 {
 	unsigned int out_len;
 	EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
@@ -34,7 +34,7 @@ static int do_sha256(const unsigned char *in, size_t len, unsigned char *out)
 	if (!mdctx)
 		return -1;
 
-	if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1)
+	if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
 		return -1;
 
 	if(EVP_DigestUpdate(mdctx, in, len) != 1)
@@ -121,7 +121,7 @@ static size_t gen_essiv_salt(const void *iv, size_t iv_len, const void *key, siz
 		return -1;
 	}
 
-	if (do_sha256(key, key_len, sha256) != 0) {
+	if (do_hash(EVP_sha256(), key, key_len, sha256) != 0) {
 		errmsg("sha256 failed");
 		return -1;
 	}
@@ -288,6 +288,27 @@ ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 			  aes_key_len, NULL, 0, derived_key);
 }
 
+int derive_key_descriptor(const void *source_key, void *descriptor)
+{
+	int ret = -1;
+	void *hash1 = xzalloc(EVP_MD_size(EVP_sha512()));
+	void *hash2 = xzalloc(EVP_MD_size(EVP_sha512()));
+
+	if (do_hash(EVP_sha512(), source_key, FS_MAX_KEY_SIZE, hash1) != 0)
+		goto out;
+
+	if (do_hash(EVP_sha512(), hash1, EVP_MD_size(EVP_sha512()), hash2) != 0)
+		goto out;
+
+	memcpy(descriptor, hash2, FS_KEY_DESCRIPTOR_SIZE);
+
+	ret = 0;
+out:
+	free(hash1);
+	free(hash2);
+	return ret;
+}
+
 static struct cipher ciphers[] = {
 	{
 		.name = "AES-128-CBC",
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
index c2631dd0fd89..f275839aa77d 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.h
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -49,6 +49,7 @@ void crypto_cleanup(void);
 ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 		       size_t source_key_len, void *derived_key);
 
+int derive_key_descriptor(const void *source_key, void *descriptor);
 
 struct cipher *get_cipher(const char *name);
 
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index b9f9acc17c17..ce6e2fc29ce0 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -242,12 +242,17 @@ struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
 		return NULL;
 	}
 
-	if (parse_key_descriptor(key_descriptor, master_key_descriptor))
-		return NULL;
-
 	if (load_master_key(key_file, fscrypt_cipher))
 		return NULL;
 
+	if (!key_descriptor) {
+		if (derive_key_descriptor(fscrypt_masterkey, master_key_descriptor))
+			return NULL;
+	} else {
+		if (parse_key_descriptor(key_descriptor, master_key_descriptor))
+			return NULL;
+	}
+
 	RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
 
 	new_fctx = xmalloc(sizeof(*new_fctx));
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 9bd15a2f047a..f8d8e52f1bae 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -752,8 +752,6 @@ static int get_options(int argc, char**argv)
 	if (key_file || key_desc) {
 		if (!key_file)
 			return err_msg("no key file specified");
-		if (!key_desc)
-			return err_msg("no key descriptor specified");
 
 		c->double_hash = 1;
 		c->encrypted = 1;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 37/42] mkfs.ubifs: Fix key descriptor printing
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (35 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 36/42] mkfs.ubifs: Compute encryption key descriptor automatically Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 38/42] mkfs.ubifs: More fscryptctl compatibility Richard Weinberger
                   ` (5 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

normsg() sucks.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/fscrypt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index ce6e2fc29ce0..29dad1b039e7 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -69,11 +69,11 @@ void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
 {
 	int i;
 
-	normsg_cont("fscrypt master key descriptor: ");
+	normsg_cont("fscrypt master key descriptor: 0x");
 	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
-		normsg_cont("%02x", fctx->master_key_descriptor[i]);
+		printf("%02x", fctx->master_key_descriptor[i]);
 	}
-	normsg("");
+	printf("\n");
 }
 
 unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx,
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 38/42] mkfs.ubifs: More fscryptctl compatibility
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (36 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 37/42] mkfs.ubifs: Fix key descriptor printing Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 39/42] mkfs.ubifs: Move RAND_poll to crypto.c Richard Weinberger
                   ` (4 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

fscryptctl reads up to FS_MAX_KEY_SIZE bytes from the source key
to compute the descriptor.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/fscrypt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index 29dad1b039e7..3d4bff618050 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -202,7 +202,7 @@ static int load_master_key(const char *key_file, struct cipher *fsc)
 		return -1;
 	}
 
-	keysize = read(kf, fscrypt_masterkey, fsc->key_length);
+	keysize = read(kf, fscrypt_masterkey, FS_MAX_KEY_SIZE);
 	if (keysize < 0) {
 		sys_errmsg("read '%s'", key_file);
 		goto fail;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 39/42] mkfs.ubifs: Move RAND_poll to crypto.c
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (37 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 38/42] mkfs.ubifs: More fscryptctl compatibility Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 40/42] mkfs.ubifs: Enable support for building without crypto Richard Weinberger
                   ` (3 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/crypto.c     | 1 +
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/crypto.c b/ubifs-utils/mkfs.ubifs/crypto.c
index 50a09b53ebfe..9c6073ec00f9 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.c
+++ b/ubifs-utils/mkfs.ubifs/crypto.c
@@ -330,6 +330,7 @@ static struct cipher ciphers[] = {
 int crypto_init(void)
 {
 	ERR_load_crypto_strings();
+	RAND_poll();
 	return 0;
 }
 
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index f8d8e52f1bae..e4204dae07cb 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -2841,8 +2841,6 @@ int main(int argc, char *argv[])
 	if (crypto_init())
 		return -1;
 
-	RAND_poll();
-
 	err = get_options(argc, argv);
 	if (err)
 		return err;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 40/42] mkfs.ubifs: Enable support for building without crypto
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (38 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 39/42] mkfs.ubifs: Move RAND_poll to crypto.c Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 41/42] mkfs.ubifs: Print key descriptor only when generated Richard Weinberger
                   ` (2 subsequent siblings)
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 Makefile.am                         |  4 ++
 configure.ac                        | 27 ++++++++++--
 ubifs-utils/Makemodule.am           | 10 +++--
 ubifs-utils/mkfs.ubifs/crypto.h     | 11 +++--
 ubifs-utils/mkfs.ubifs/fscrypt.h    | 65 +++++++++++++++++++++++++----
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 56 ++++++++++++++++++++++---
 6 files changed, 148 insertions(+), 25 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 391edef4ee31..1bc4684b191d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,10 @@ if WITH_SELINUX
 AM_CPPFLAGS += -DWITH_SELINUX
 endif
 
+if WITH_CRYPTO
+AM_CPPFLAGS += -DWITH_CRYPTO
+endif
+
 sbin_PROGRAMS =
 sbin_SCRIPTS =
 check_PROGRAMS =
diff --git a/configure.ac b/configure.ac
index 346fcbd26328..d5abb14263b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,7 +69,7 @@ need_lzo="no"
 need_xattr="no"
 need_cmocka="no"
 need_selinux="no"
-
+need_openssl="no"
 
 AM_COND_IF([UNIT_TESTS], [
 	need_cmocka="yes"
@@ -115,8 +115,6 @@ AC_ARG_ENABLE([lsmtd],
 	esac],
 	[AM_CONDITIONAL([BUILD_LSMTD], [true])])
 
-AC_CHECK_HEADER(openssl/rand.h)
-
 AC_ARG_WITH([jffs],
 	[AS_HELP_STRING([--without-jffs], [Disable jffsX utilities])],
 	[case "${withval}" in
@@ -140,6 +138,7 @@ AM_COND_IF([BUILD_UBIFS], [
 	need_xattr="yes"
 	need_zlib="yes"
 	need_lzo="yes"
+	need_openssl="yes"
 ])
 
 AM_COND_IF([BUILD_JFFSX], [
@@ -174,6 +173,15 @@ AC_ARG_WITH([selinux],
 	*) AC_MSG_ERROR([bad value ${withval} for --with-selinux]) ;;
 	esac])
 
+AC_ARG_WITH([crypto],
+	[AS_HELP_STRING([--without-crypto],
+		[Disable support for UBIFS crypto features])],
+	[case "${withval}" in
+	yes) ;;
+	no) need_openssl="no";;
+	*) AC_MSG_ERROR([bad value ${withval} for --without-crypto]) ;;
+	esac])
+
 ##### search for dependencies #####
 
 clock_gettime_missing="no"
@@ -184,6 +192,7 @@ lzo_missing="no"
 xattr_missing="no"
 cmocka_missing="no"
 selinux_missing="no"
+openssl_missing="no"
 
 if test "x$need_zlib" = "xyes"; then
 	PKG_CHECK_MODULES(ZLIB, [zlib], [], [zlib_missing="yes"])
@@ -226,6 +235,11 @@ if test "x$need_selinux" = "xyes"; then
 	AC_CHECK_HEADERS([selinux/label.h], [], [selinux_missing="yes"])
 fi
 
+if test "x$need_openssl" = "xyes"; then
+	AC_CHECK_HEADER(openssl/rand.h)
+	PKG_CHECK_MODULES(OPENSSL, [openssl], [], [openssl_missing="yes"])
+fi
+
 if test "x$need_cmocka" = "xyes"; then
 	PKG_CHECK_MODULES(CMOCKA, [cmocka], [], [cmocka_missing="yes"])
 fi
@@ -281,6 +295,12 @@ if test "x$selinux_missing" = "xyes"; then
 	need_selinux="no"
 fi
 
+if test "x$openssl_missing" = "xyes"; then
+	AC_MSG_WARN([cannot find headers for OpenSSL library])
+	AC_MSG_WARN([disabling OpenSSL support])
+	need_openssl="no"
+fi
+
 if test "x$cmocka_missing" = "xyes"; then
 	AC_MSG_WARN([cannot find CMocka library required for unit tests])
 	AC_MSG_NOTICE([unit tests can optionally be disabled])
@@ -296,6 +316,7 @@ fi
 AM_CONDITIONAL([WITHOUT_LZO], [test "x$need_lzo" != "xyes"])
 AM_CONDITIONAL([WITHOUT_XATTR], [test "x$need_xattr" != "xyes"])
 AM_CONDITIONAL([WITH_SELINUX], [test "x$need_selinux" == "xyes"])
+AM_CONDITIONAL([WITH_CRYPTO], [test "x$need_openssl" == "xyes"])
 
 AC_CHECK_SIZEOF([off_t])
 AC_CHECK_SIZEOF([loff_t])
diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am
index 5905a2badbb6..b8e4075c9d2a 100644
--- a/ubifs-utils/Makemodule.am
+++ b/ubifs-utils/Makemodule.am
@@ -10,15 +10,19 @@ mkfs_ubifs_SOURCES = \
 	ubifs-utils/mkfs.ubifs/crc16.c \
 	ubifs-utils/mkfs.ubifs/lpt.c \
 	ubifs-utils/mkfs.ubifs/compr.c \
-	ubifs-utils/mkfs.ubifs/crypto.c \
-	ubifs-utils/mkfs.ubifs/fscrypt.c \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_private.h \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable.c \
 	ubifs-utils/mkfs.ubifs/hashtable/hashtable_itr.c \
 	ubifs-utils/mkfs.ubifs/devtable.c
-mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) -lm -lssl -lcrypto
+
+if WITH_CRYPTO
+mkfs_ubifs_SOURCES += ubifs-utils/mkfs.ubifs/crypto.c \
+		ubifs-utils/mkfs.ubifs/fscrypt.c
+endif
+
+mkfs_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) $(OPENSSL_LIBS) -lm
 mkfs_ubifs_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) $(UUID_CFLAGS) $(LIBSELINUX_CFLAGS)\
 	-I$(top_srcdir)/ubi-utils/include -I$(top_srcdir)/ubifs-utils/mkfs.ubifs/
 
diff --git a/ubifs-utils/mkfs.ubifs/crypto.h b/ubifs-utils/mkfs.ubifs/crypto.h
index f275839aa77d..b6ffad19b72d 100644
--- a/ubifs-utils/mkfs.ubifs/crypto.h
+++ b/ubifs-utils/mkfs.ubifs/crypto.h
@@ -41,19 +41,18 @@ struct cipher {
 	unsigned int fscrypt_fname_mode;
 };
 
-
+#ifdef WITH_CRYPTO
 int crypto_init(void);
-
 void crypto_cleanup(void);
-
 ssize_t derive_key_aes(const void *deriving_key, const void *source_key,
 		       size_t source_key_len, void *derived_key);
-
 int derive_key_descriptor(const void *source_key, void *descriptor);
-
 struct cipher *get_cipher(const char *name);
-
 void list_ciphers(FILE *fp);
+#else
+static inline int crypto_init(void) { return 0;}
+static inline void crypto_cleanup(void) {}
+#endif /* WITH_CRYPTO */
 
 #endif /* UBIFS_CRYPTO_H */
 
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.h b/ubifs-utils/mkfs.ubifs/fscrypt.h
index e3cfee50290a..3b717b4359c6 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.h
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.h
@@ -97,27 +97,76 @@ struct fscrypt_symlink_data {
 #define FS_IV_SIZE 16
 #endif
 
+#ifdef WITH_CRYPTO
 unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx);
-
 struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx);
-
 void free_fscrypt_context(struct fscrypt_context *fctx);
-
 void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx);
-
 unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx,
 					  unsigned int ilen);
-
 int encrypt_path(void **outbuf, void *data, unsigned int data_len,
 		 unsigned int max_namelen, struct fscrypt_context *fctx);
-
 int encrypt_data_node(struct fscrypt_context *fctx, unsigned int block_no,
 		      struct ubifs_data_node *dn, size_t length);
-
 struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
 					     unsigned int flags,
 					     const char *key_file,
 					     const char *key_descriptor);
-
+#else
+static inline struct fscrypt_context *init_fscrypt_context(
+					const char *cipher_name,
+					unsigned int flags,
+					const char *key_file,
+					const char *key_descriptor)
+{
+	(void)cipher_name;
+	(void)flags;
+	(void)key_file;
+	(void)key_descriptor;
+
+	assert(0);
+	return NULL;
+}
+
+static inline void free_fscrypt_context(struct fscrypt_context *fctx)
+{
+	(void)fctx;
+
+	assert(0);
+}
+
+static inline int encrypt_path(void **outbuf, void *data, unsigned int data_len,
+		 unsigned int max_namelen, struct fscrypt_context *fctx)
+{
+	(void)outbuf;
+	(void)data;
+	(void)data_len;
+	(void)max_namelen;
+	(void)fctx;
+
+	assert(0);
+	return -1;
+}
+
+static inline int encrypt_data_node(struct fscrypt_context *fctx, unsigned int block_no,
+		      struct ubifs_data_node *dn, size_t length)
+{
+	(void)fctx;
+	(void)block_no;
+	(void)dn;
+	(void)length;
+
+	assert(0);
+	return -1;
+}
+
+static inline struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx)
+{
+	(void)fctx;
+
+	assert(0);
+	return NULL;
+}
+#endif /* WITH_CRYPTO */
 #endif /* FSCRYPT_H */
 
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index e4204dae07cb..7073bf052688 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -508,9 +508,12 @@ static int get_options(int argc, char**argv)
 {
 	int opt, i, fscrypt_flags = FS_POLICY_FLAGS_PAD_4;
 	const char *key_file = NULL, *key_desc = NULL;
-	const char *tbl_file = NULL, *cipher_name = "AES-128-CBC";
+	const char *tbl_file = NULL;
 	struct stat st;
 	char *endp;
+#ifdef WITH_CRYPTO
+	const char *cipher_name;
+#endif
 
 	c->fanout = 8;
 	c->orph_lebs = 1;
@@ -587,8 +590,10 @@ static int get_options(int argc, char**argv)
 			exit(EXIT_SUCCESS);
 		case '?':
 			printf("%s", helptext);
+#ifdef WITH_CRYPTO
 			printf("\n\nSupported ciphers:\n");
 			list_ciphers(stdout);
+#endif
 			exit(-1);
 		case 'v':
 			verbose = 1;
@@ -729,7 +734,11 @@ static int get_options(int argc, char**argv)
 			break;
 		}
 		case 'C':
+#ifdef WITH_CRYPTO
 			cipher_name = optarg;
+#else
+			return err_msg("mkfs.ubifs was built without crypto support.");
+#endif
 			break;
 		}
 	}
@@ -748,20 +757,26 @@ static int get_options(int argc, char**argv)
 		if (c->max_leb_cnt == -1)
 			c->max_leb_cnt = c->vi.rsvd_lebs;
 	}
-
 	if (key_file || key_desc) {
+#ifdef WITH_CRYPTO
 		if (!key_file)
 			return err_msg("no key file specified");
 
 		c->double_hash = 1;
 		c->encrypted = 1;
 
+		if (cipher_name == NULL)
+			cipher_name = "AES-128-CBC";
+
 		root_fctx = init_fscrypt_context(cipher_name, fscrypt_flags,
 						key_file, key_desc);
 		if (!root_fctx)
 			return -1;
 
 		print_fscrypt_master_key_descriptor(root_fctx);
+#else
+		return err_msg("mkfs.ubifs was built without crypto support.");
+#endif
 	}
 
 	if (c->min_io_size == -1)
@@ -1385,6 +1400,7 @@ static inline int inode_add_selinux_xattr(struct ubifs_ino_node *host_ino,
 }
 #endif
 
+#ifdef WITH_CRYPTO
 static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
 			       struct stat *host_st,
 			       struct fscrypt_context *fctx)
@@ -1421,6 +1437,31 @@ static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
 	free(sd);
 	return link_disk_len;
 }
+#else
+static int set_fscrypt_context(struct ubifs_ino_node *host_ino, ino_t inum,
+			       struct stat *host_st,
+			       struct fscrypt_context *fctx)
+{
+	(void)host_ino;
+	(void)inum;
+	(void)host_st;
+	(void)fctx;
+
+	assert(0);
+	return -1;
+}
+static int encrypt_symlink(void *dst, void *data, unsigned int data_len,
+			   struct fscrypt_context *fctx)
+{
+	(void)dst;
+	(void)data;
+	(void)data_len;
+	(void)fctx;
+
+	assert(0);
+	return -1;
+}
+#endif
 
 /**
  * add_inode - write an inode.
@@ -1582,9 +1623,11 @@ static int add_symlink_inode(const char *path_name, struct stat *st, ino_t inum,
 
 static void set_dent_cookie(struct ubifs_dent_node *dent)
 {
+#ifdef WITH_CRYPTO
 	if (c->double_hash)
 		RAND_bytes((void *)&dent->cookie, sizeof(dent->cookie));
 	else
+#endif
 		dent->cookie = 0;
 }
 
@@ -1981,7 +2024,8 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 
 		inum = ++c->highest_inum;
 
-		new_fctx = inherit_fscrypt_context(fctx);
+		if (fctx)
+			new_fctx = inherit_fscrypt_context(fctx);
 
 		if (S_ISDIR(dent_st.st_mode)) {
 			err = add_directory(name, inum, &dent_st, 1, new_fctx);
@@ -2006,7 +2050,8 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		size += ALIGN(UBIFS_DENT_NODE_SZ + strlen(entry->d_name) + 1,
 			      8);
 
-		free_fscrypt_context(new_fctx);
+		if (new_fctx)
+			free_fscrypt_context(new_fctx);
 	}
 
 	/*
@@ -2068,7 +2113,8 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		size += ALIGN(UBIFS_DENT_NODE_SZ + strlen(nh_elt->name) + 1, 8);
 
 		nh_elt = next_name_htbl_element(ph_elt, &itr);
-		free_fscrypt_context(new_fctx);
+		if (new_fctx)
+			free_fscrypt_context(new_fctx);
 	}
 
 	creat_sqnum = dir_creat_sqnum;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 41/42] mkfs.ubifs: Print key descriptor only when generated
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (39 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 40/42] mkfs.ubifs: Enable support for building without crypto Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-10-18 14:37 ` [PATCH 42/42] mkfs.ubifs: Use AES-256-XTS as default Richard Weinberger
  2018-11-02 16:41 ` [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs David Oberhollenzer
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/fscrypt.c    | 5 +++--
 ubifs-utils/mkfs.ubifs/fscrypt.h    | 1 -
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 2 --
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
index 3d4bff618050..6d2b650d626d 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.c
@@ -65,13 +65,13 @@ void free_fscrypt_context(struct fscrypt_context *fctx)
 	free(fctx);
 }
 
-void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx)
+static void print_fscrypt_master_key_descriptor(__u8 *master_key_descriptor)
 {
 	int i;
 
 	normsg_cont("fscrypt master key descriptor: 0x");
 	for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
-		printf("%02x", fctx->master_key_descriptor[i]);
+		printf("%02x", master_key_descriptor[i]);
 	}
 	printf("\n");
 }
@@ -248,6 +248,7 @@ struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
 	if (!key_descriptor) {
 		if (derive_key_descriptor(fscrypt_masterkey, master_key_descriptor))
 			return NULL;
+		print_fscrypt_master_key_descriptor(master_key_descriptor);
 	} else {
 		if (parse_key_descriptor(key_descriptor, master_key_descriptor))
 			return NULL;
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.h b/ubifs-utils/mkfs.ubifs/fscrypt.h
index 3b717b4359c6..34b799c94c2b 100644
--- a/ubifs-utils/mkfs.ubifs/fscrypt.h
+++ b/ubifs-utils/mkfs.ubifs/fscrypt.h
@@ -101,7 +101,6 @@ struct fscrypt_symlink_data {
 unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx);
 struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx);
 void free_fscrypt_context(struct fscrypt_context *fctx);
-void print_fscrypt_master_key_descriptor(struct fscrypt_context *fctx);
 unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx,
 					  unsigned int ilen);
 int encrypt_path(void **outbuf, void *data, unsigned int data_len,
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 7073bf052688..a60d392bbc81 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -772,8 +772,6 @@ static int get_options(int argc, char**argv)
 						key_file, key_desc);
 		if (!root_fctx)
 			return -1;
-
-		print_fscrypt_master_key_descriptor(root_fctx);
 #else
 		return err_msg("mkfs.ubifs was built without crypto support.");
 #endif
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 42/42] mkfs.ubifs: Use AES-256-XTS as default
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (40 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 41/42] mkfs.ubifs: Print key descriptor only when generated Richard Weinberger
@ 2018-10-18 14:37 ` Richard Weinberger
  2018-11-02 16:41 ` [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs David Oberhollenzer
  42 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-10-18 14:37 UTC (permalink / raw)
  To: linux-mtd; +Cc: david.oberhollenzer, Richard Weinberger

AES-128-CBC should only being used when 256-XTS is too slow
on low end hardware.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index a60d392bbc81..5847b352038a 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -766,7 +766,7 @@ static int get_options(int argc, char**argv)
 		c->encrypted = 1;
 
 		if (cipher_name == NULL)
-			cipher_name = "AES-128-CBC";
+			cipher_name = "AES-256-XTS";
 
 		root_fctx = init_fscrypt_context(cipher_name, fscrypt_flags,
 						key_file, key_desc);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs
  2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
                   ` (41 preceding siblings ...)
  2018-10-18 14:37 ` [PATCH 42/42] mkfs.ubifs: Use AES-256-XTS as default Richard Weinberger
@ 2018-11-02 16:41 ` David Oberhollenzer
  2018-11-02 16:43   ` Richard Weinberger
  42 siblings, 1 reply; 45+ messages in thread
From: David Oberhollenzer @ 2018-11-02 16:41 UTC (permalink / raw)
  To: Richard Weinberger, linux-mtd

Hi!

This patch set has been sitting on the ML for more than two weeks now, with no
one commenting/complaining/nit-picking/bike-shedding/etc, so I'll push it to
mtd-utils.git master.

Since I authored some of those commits and already stared at the whole patch
set for quite some time before it's been submitted, I'm not sure how helpful
it is for me to try and review it now. Nevertheless, I've looked through the
patch set again over the last few days, compared it against the latest version
I have locally and did some quick tests and it still looks good to me.

Thanks,

David

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs
  2018-11-02 16:41 ` [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs David Oberhollenzer
@ 2018-11-02 16:43   ` Richard Weinberger
  0 siblings, 0 replies; 45+ messages in thread
From: Richard Weinberger @ 2018-11-02 16:43 UTC (permalink / raw)
  To: David Oberhollenzer; +Cc: linux-mtd

David,

Am Freitag, 2. November 2018, 17:41:44 CET schrieb David Oberhollenzer:
> Hi!
> 
> This patch set has been sitting on the ML for more than two weeks now, with no
> one commenting/complaining/nit-picking/bike-shedding/etc, so I'll push it to
> mtd-utils.git master.
> 
> Since I authored some of those commits and already stared at the whole patch
> set for quite some time before it's been submitted, I'm not sure how helpful
> it is for me to try and review it now. Nevertheless, I've looked through the
> patch set again over the last few days, compared it against the latest version
> I have locally and did some quick tests and it still looks good to me.

one thing is to consider, Sascha's UBIFS auth patches for mkfs.ubifs.
Not that there are some subtle merge issues.

Thanks,
//richard 

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2018-11-02 16:43 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-18 14:36 [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs Richard Weinberger
2018-10-18 14:36 ` [PATCH 01/42] Import latest ubifs-media.h Richard Weinberger
2018-10-18 14:36 ` [PATCH 02/42] common: Add round functions Richard Weinberger
2018-10-18 14:36 ` [PATCH 03/42] mkfs.ubifs: Add crypto helper functions Richard Weinberger
2018-10-18 14:36 ` [PATCH 04/42] mkfs.ubifs: Implement UBIFS_FLG_DOUBLE_HASH Richard Weinberger
2018-10-18 14:36 ` [PATCH 05/42] mkfs.ubifs: Make r5 hash binary string aware Richard Weinberger
2018-10-18 14:36 ` [PATCH 06/42] mkfs.ubifs: Add fscrypto defines Richard Weinberger
2018-10-18 14:36 ` [PATCH 07/42] mkfs.ubifs: Add basic fscrypto functions Richard Weinberger
2018-10-18 14:36 ` [PATCH 08/42] mkfs.ubifs: Implement UBIFS_FLG_ENCRYPTION Richard Weinberger
2018-10-18 14:36 ` [PATCH 09/42] mkfs.ubifs: Implement basic fscrypto context passing Richard Weinberger
2018-10-18 14:36 ` [PATCH 10/42] mkfs.ubifs: Implement fscrypto context store as xattr Richard Weinberger
2018-10-18 14:36 ` [PATCH 11/42] mkfs.ubifs: Store directory name len in the temporary index Richard Weinberger
2018-10-18 14:36 ` [PATCH 12/42] mkfs.ubifs: Implement filename encryption Richard Weinberger
2018-10-18 14:36 ` [PATCH 13/42] mkfs.ubifs: Add dummy setup for crypto Richard Weinberger
2018-10-18 14:36 ` [PATCH 14/42] mkfs.ubifs: Pass source/dest key len to key derive function Richard Weinberger
2018-10-18 14:36 ` [PATCH 15/42] mkfs.ubifs: Add encrypted symlink support Richard Weinberger
2018-10-18 14:36 ` [PATCH 16/42] mkfs.ubifs: Implement file contents encryption Richard Weinberger
2018-10-18 14:36 ` [PATCH 17/42] mkfs.ubifs: Move symlink data encryption to helper function Richard Weinberger
2018-10-18 14:36 ` [PATCH 18/42] mkfs.ubifs: Make sure we catch nodes that should or should not have name Richard Weinberger
2018-10-18 14:36 ` [PATCH 19/42] mkfs.ubifs: Free all index entry names Richard Weinberger
2018-10-18 14:36 ` [PATCH 20/42] mkfs.ubifs: Seperate path encryption from symlink encryption helper Richard Weinberger
2018-10-18 14:36 ` [PATCH 21/42] mkfs.ubifs: Cleanup add_dent_node, user path " Richard Weinberger
2018-10-18 14:36 ` [PATCH 22/42] mkfs.ubifs: Replace constant values with parameters in init_fscrypt_context Richard Weinberger
2018-10-18 14:36 ` [PATCH 23/42] mkfs.ubifs: Make encryption dependend on (not-yet-existant) command line options Richard Weinberger
2018-10-18 14:37 ` [PATCH 24/42] mkfs.ubifs: Get key descriptor from command line and master key from file Richard Weinberger
2018-10-18 14:37 ` [PATCH 25/42] mkfs.ubifs: Specify padding policy via command line Richard Weinberger
2018-10-18 14:37 ` [PATCH 26/42] mkfs.ubifs: Initial support for encryption command lines Richard Weinberger
2018-10-18 14:37 ` [PATCH 27/42] mkfs.ubifs: Remove cipher implementations from public header Richard Weinberger
2018-10-18 14:37 ` [PATCH 28/42] mkfs.ubifs: Move fscrypt definitions and functions out of mkfs.ubifs.c Richard Weinberger
2018-10-18 14:37 ` [PATCH 29/42] mkfs.ubifs: Cleanup over-long lines Richard Weinberger
2018-10-18 14:37 ` [PATCH 30/42] mkfs.ubifs: Check length of master key Richard Weinberger
2018-10-18 14:37 ` [PATCH 31/42] mkfs.ubifs: Accept 0x prefix for key descriptor Richard Weinberger
2018-10-18 14:37 ` [PATCH 32/42] mkfs.ubifs: Correctly use iv lengths in aes-cts mode Richard Weinberger
2018-10-18 14:37 ` [PATCH 33/42] mkfs.ubifs: Enable Cipher selection Richard Weinberger
2018-10-18 14:37 ` [PATCH 34/42] mkfs.ubifs: Use correct sizes for keys and hash lengths Richard Weinberger
2018-10-18 14:37 ` [PATCH 35/42] mkfs.ubifs: Fixup AES-XTS mode Richard Weinberger
2018-10-18 14:37 ` [PATCH 36/42] mkfs.ubifs: Compute encryption key descriptor automatically Richard Weinberger
2018-10-18 14:37 ` [PATCH 37/42] mkfs.ubifs: Fix key descriptor printing Richard Weinberger
2018-10-18 14:37 ` [PATCH 38/42] mkfs.ubifs: More fscryptctl compatibility Richard Weinberger
2018-10-18 14:37 ` [PATCH 39/42] mkfs.ubifs: Move RAND_poll to crypto.c Richard Weinberger
2018-10-18 14:37 ` [PATCH 40/42] mkfs.ubifs: Enable support for building without crypto Richard Weinberger
2018-10-18 14:37 ` [PATCH 41/42] mkfs.ubifs: Print key descriptor only when generated Richard Weinberger
2018-10-18 14:37 ` [PATCH 42/42] mkfs.ubifs: Use AES-256-XTS as default Richard Weinberger
2018-11-02 16:41 ` [PATCH 00/42] mtd-utils: Add fscrypt support to mkfs.ubifs David Oberhollenzer
2018-11-02 16:43   ` Richard Weinberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).