From patchwork Mon Apr 30 22:51:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 906925 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=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Oflw9jqW"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="nc+QaGGw"; 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 40ZgBZ56pKz9s0n for ; Tue, 1 May 2018 09:05:58 +1000 (AEST) 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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=n696kw6l5o0Oc4s/Q0MjFLH0IJLenZXreRirXRBJgT0=; b=Oflw9jqW/cz3FX0hnHNYTMvkdW E4wPMB4IBEar05Jv3KVvChmC61931gyedItI7K3Kx6wBuOL1nVph9KID/bWGr1z0RND50SFgNkStt O159Y3g6dWO9/8sLSMj4Q0KGDh1tdGqHY3TyzCTv0Lnis88jmugzy9jVIxBREAOfVq4E7kZI/TCef SL9zqLqBZ38CXUb61LgBEdVAuQ21q7u6zsktFKFfWKGIAZc6AGzdB+vCajDhKrsPsEao6KgIqCk4/ Gz8T43JLm1S5lEJR9LpBWBdmr10wUDoYKMXhMNoDILbc0/gBWMvzsQsEMb9FHHEnUJ5Xuke5cHUnd FgTFZIMA==; 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 1fDHrg-0001zy-8B; Mon, 30 Apr 2018 23:05:48 +0000 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fDHj6-0003qH-Vx for linux-mtd@lists.infradead.org; Mon, 30 Apr 2018 22:57:00 +0000 Received: by mail-pf0-x241.google.com with SMTP id j11so7866033pff.10 for ; Mon, 30 Apr 2018 15:56:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6FJK5fX6Xy34m8X70gLUAwyLpubC/LkpvQQIN9+cN18=; b=nc+QaGGwfKkQIdYEA4J+WKPM3EYIRliTwUb7DkA9HOI6ChdWYHlo1fXmP38wFOdu4t jk+hKMVh6vIBMGcg1SjDnuMOLmRV7dobT1wqa8Az8svs4Nfs7urbegH+uS+L3LD8RG0j e/1nhSHzP7n3knPI5kGxOaBEMOqAPJ6EPYf5sDZzALdmxrfHER+XTq7PH6mtc7M3+N7R QFOa5O0DSy+SDl0VFNb1bhWmBuX6sGwKol9TzeD9Ic1LyOROk0opaNavMaAfHedc/rhd SO98v8fcNI8zBReoIOi75V6e3UFLjMmdYUzfSSU9d9nAk05JBEjRQcsv0CsNL1skP5Tc XaDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6FJK5fX6Xy34m8X70gLUAwyLpubC/LkpvQQIN9+cN18=; b=pSRv+Bt7WxB3lPacL9Nzw65PD0cd72bbbb38wUu3eehZp1z9kWZ/A49dGqDDj2DZy7 Tj8pOKA1NlCXI/kiGQnkYTIj6qGAEZ5x8idmQ2OQ6DMCBIscBDbnDZI0ZZZzgrw4YVhB rjJrU5zsfszqwDBYmkEhL1N+PlNoRkBVQ7+dTulgbsZwninLwnRYlacYDnA07TA8b/pW HmtPhj0EPIA1/lAyDX5uAjIARhKDYjGpblr4DTLuxJkpmkWCHPAMMuGKoTdpaZTVauH6 NjS5MdtPM7y/wtPhYymaEPzP2uLsb9oR6LFR6wf5HRn2ppzeyX1xhLSxgFj6ERpNboJr wqkw== X-Gm-Message-State: ALQs6tCgk0/T6VwqGbGxwyqrbGUN3y45j9aH2ABF9PjRmq3UakkDUb3q xN1Ye/3JUazsalCqyKcm3AIRcAWy X-Google-Smtp-Source: AB8JxZrbEZADLIPieDij4VBAiT1ncSAJTqVZvitaof6IITCk8FbFzeq4Msh2trjuQtXKEmI1wY8Ofw== X-Received: by 2002:a17:902:bb8c:: with SMTP id m12-v6mr14255407pls.53.1525129012623; Mon, 30 Apr 2018 15:56:52 -0700 (PDT) Received: from ebiggers-linuxstation.kir.corp.google.com ([2620:15c:17:3:dc28:5c82:b905:e8a8]) by smtp.gmail.com with ESMTPSA id b15sm12969305pfi.111.2018.04.30.15.56.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 30 Apr 2018 15:56:51 -0700 (PDT) From: Eric Biggers To: linux-fscrypt@vger.kernel.org, "Theodore Y . Ts'o" Subject: [PATCH 15/15] fscrypt: only derive the needed portion of the key Date: Mon, 30 Apr 2018 15:51:49 -0700 Message-Id: <20180430225149.183514-16-ebiggers3@gmail.com> X-Mailer: git-send-email 2.17.0.441.gb46fe60e1d-goog In-Reply-To: <20180430225149.183514-1-ebiggers3@gmail.com> References: <20180430225149.183514-1-ebiggers3@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180430_155657_236919_3982F5D5 X-CRM114-Status: GOOD ( 15.59 ) X-Spam-Score: 0.1 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c00:0:0:0:241 listed in] [list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (ebiggers3[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (ebiggers3[at]gmail.com) -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 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: Jaegeuk Kim , linux-ext4@vger.kernel.org, linux-mtd@lists.infradead.org, Eric Biggers , linux-f2fs-devel@lists.sourceforge.net MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Eric Biggers Currently the key derivation function in fscrypt uses the master key length as the amount of output key material to derive. This works, but it means we can waste time deriving more key material than is actually used, e.g. most commonly, deriving 64 bytes for directories which only take a 32-byte AES-256-CTS-CBC key. It also forces us to validate that the master key length is a multiple of AES_BLOCK_SIZE, which wouldn't otherwise be necessary. Fix it to only derive the needed length key. Signed-off-by: Eric Biggers --- fs/crypto/keyinfo.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index f248ee9974fa..c4d1388fc9b4 100644 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -19,17 +19,16 @@ static struct crypto_shash *essiv_hash_tfm; -/** - * derive_key_aes() - Derive a key using AES-128-ECB - * @deriving_key: Encryption key used for derivation. - * @source_key: Source key to which to apply derivation. - * @derived_raw_key: Derived raw key. +/* + * Key derivation function. This generates the derived key by encrypting the + * master key with AES-128-ECB using the inode's nonce as the AES key. * - * Return: Zero on success; non-zero otherwise. + * The master key must be at least as long as the derived key. If the master + * key is longer, then only the first 'derived_keysize' bytes are used. */ -static int derive_key_aes(const u8 deriving_key[FS_KEY_DERIVATION_NONCE_SIZE], - const struct fscrypt_key *source_key, - u8 derived_raw_key[FS_MAX_KEY_SIZE]) +static int derive_key_aes(const u8 *master_key, + const struct fscrypt_context *ctx, + u8 *derived_key, unsigned int derived_keysize) { int res = 0; struct skcipher_request *req = NULL; @@ -51,14 +50,13 @@ static int derive_key_aes(const u8 deriving_key[FS_KEY_DERIVATION_NONCE_SIZE], skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, &wait); - res = crypto_skcipher_setkey(tfm, deriving_key, - FS_KEY_DERIVATION_NONCE_SIZE); + res = crypto_skcipher_setkey(tfm, ctx->nonce, sizeof(ctx->nonce)); if (res < 0) goto out; - sg_init_one(&src_sg, source_key->raw, source_key->size); - sg_init_one(&dst_sg, derived_raw_key, source_key->size); - skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size, + sg_init_one(&src_sg, master_key, derived_keysize); + sg_init_one(&dst_sg, derived_key, derived_keysize); + skcipher_request_set_crypt(req, &src_sg, &dst_sg, derived_keysize, NULL); res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); out: @@ -109,10 +107,9 @@ find_and_lock_process_key(const char *prefix, goto invalid; } - if (payload->size < min_keysize || - payload->size % AES_BLOCK_SIZE != 0) { + if (payload->size < min_keysize) { fscrypt_warn(NULL, - "key with description '%s' is too short or is misaligned (got %u bytes, need %u+ bytes)", + "key with description '%s' is too short (got %u bytes, need %u+ bytes)", key->description, payload->size, min_keysize); goto invalid; } @@ -145,7 +142,7 @@ static int find_and_derive_key(const struct inode *inode, } if (IS_ERR(key)) return PTR_ERR(key); - err = derive_key_aes(ctx->nonce, payload, derived_key); + err = derive_key_aes(payload->raw, ctx, derived_key, derived_keysize); up_read(&key->sem); key_put(key); return err; @@ -325,7 +322,7 @@ int fscrypt_get_encryption_info(struct inode *inode) * crypto API as part of key derivation. */ res = -ENOMEM; - raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS); + raw_key = kmalloc(keysize, GFP_NOFS); if (!raw_key) goto out; @@ -343,10 +340,6 @@ int fscrypt_get_encryption_info(struct inode *inode) } crypt_info->ci_ctfm = ctfm; crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_REQ_WEAK_KEY); - /* - * if the provided key is longer than keysize, we use the first - * keysize bytes of the derived key only - */ res = crypto_skcipher_setkey(ctfm, raw_key, keysize); if (res) goto out;