From patchwork Thu Oct 18 14:36:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 985957 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="iXGxniY0"; 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 42bX4Q5gTxz9sCT for ; Fri, 19 Oct 2018 01:49:10 +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=mwNSLqexKyZIi98FXswY3nsd13rgb2ps9fYzPuNwZu4=; b=iXGxniY0lr/bea KBnuTBNMQYXmX4l8Gs0/WLstTNUx8am3P6tX2zTyFr/qr3JTHoWATLWgLkXWpV7ZOwiINeIQxB8j5 Xoivj5x0R9f+GSTpW9tlEV76dTOnhW4XaFYDdY2OviOhQI7rNKGXM1oPlcBlIC4zm/gzlGYYCYp5N CxJ7G/lOePED/vhv9RMOk6mNyhiqvniG6qUY6C6TY2VzVo4m8EGWSxgGrmDr0L2a+AbNT2TmlwWR3 wdWIe7qEly8VL3fgEOBs3ZOfWqcGjLDMH9bZ/SUaKO6tle/nwiSGXY5BHmJRIbn9gZla/hmg9R2wj CLKLPqO6V1V4Nz7285uw==; 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 1gD9bc-0002k2-RZ; Thu, 18 Oct 2018 14:48:56 +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 1gD9Rj-0004Dr-BO for linux-mtd@lists.infradead.org; Thu, 18 Oct 2018 14:39:46 +0000 Received: from localhost (localhost [127.0.0.1]) by lilium.sigma-star.at (Postfix) with ESMTP id 521A818011B6E; Thu, 18 Oct 2018 16:38:18 +0200 (CEST) From: Richard Weinberger To: linux-mtd@lists.infradead.org Subject: [PATCH 15/42] mkfs.ubifs: Add encrypted symlink support Date: Thu, 18 Oct 2018 16:36:51 +0200 Message-Id: <20181018143718.26298-16-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_073843_706858_F570BC56 X-CRM114-Status: GOOD ( 15.67 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 T_SPF_PERMERROR SPF: test of record failed (permerror) 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 Signed-off-by: Richard Weinberger --- 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);