From patchwork Thu Oct 18 14:37:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 985994 X-Patchwork-Delegate: david.oberhollenzer@sigma-star.at Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nod.at Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="TJxAssi0"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42bXL368G3z9sCm for ; Fri, 19 Oct 2018 02:00:59 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=HIsxdKC4AaWksN8djEHf+dPd0TY1eAe/5RoTwfBOdtg=; b=TJxAssi0HO597/ oNQiKQIybSFz0QRyfU41nyYg+7oJc3aVAmc8HJShQhhvujJ33/YUKJhiBSd7OJvUSoPzLU6pUVAdg sUlt5w6T1zEEQ3F+AmpHc4oulryMu2dx7Wov6U/BcXMV/hd3l77XdWNOvLTSMOPxQ6/A+zy1GEt2g IRXB6SGWR8c5WW76TrE3SCnox8nKKrq4JH51S2Li/Ci55AW3vdcOtdB6HIYApXCS87MJB9aAA83zx iWrW5QgCFlMqTS+dFWhM7dBhnr149Cuwj6KxOAT/oi+gxx0kDb0PRYiotwI+zabrHw3fzoYthhODS gP6o/hj+aRKXcmAMDmQw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gD9n3-0002m4-JD; Thu, 18 Oct 2018 15:00:45 +0000 Received: from lilium.sigma-star.at ([109.75.188.150]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gD9Rv-0004Mn-8c for linux-mtd@lists.infradead.org; Thu, 18 Oct 2018 14:40:56 +0000 Received: from localhost (localhost [127.0.0.1]) by lilium.sigma-star.at (Postfix) with ESMTP id 6C2C318011B66; Thu, 18 Oct 2018 16:38:43 +0200 (CEST) From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 24/42] mkfs.ubifs: Get key descriptor from command line and master key from file Date: Thu, 18 Oct 2018 16:37:00 +0200 Message-Id: <20181018143718.26298-25-richard@nod.at> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181018143718.26298-1-richard@nod.at> References: <20181018143718.26298-1-richard@nod.at> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181018_073855_699134_78415669 X-CRM114-Status: GOOD ( 18.72 ) X-Spam-Note: SpamAssassin invocation failed X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Weinberger , david.oberhollenzer@sigma-star.at Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: David Oberhollenzer Signed-off-by: David Oberhollenzer Signed-off-by: Richard Weinberger --- 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;