From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1o16tX-0005yu-Mq for mharc-grub-devel@gnu.org; Tue, 14 Jun 2022 09:47:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42280) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o16tU-0005sz-9o for grub-devel@gnu.org; Tue, 14 Jun 2022 09:47:44 -0400 Received: from jpoiret.xyz ([206.189.101.64]:35154) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o16tO-0008Su-RP for grub-devel@gnu.org; Tue, 14 Jun 2022 09:47:43 -0400 Received: from authenticated-user (jpoiret.xyz [206.189.101.64]) by jpoiret.xyz (Postfix) with ESMTPA id 1ECBE185300; Tue, 14 Jun 2022 13:47:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jpoiret.xyz; s=dkim; t=1655214456; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WB1Gl89UlBOLxDnZSHcQVv63pyc2pDlZzOBCYV5if00=; b=PATc6EX6lUxyYBdiIplS6D8ygPF4z6rxVqqGlJJ1BRN6HQK8ht4oMc+1GOYtIMhzxtKS6t FMSmisapVJZKhEV+Z/dxGSgZQQQM6IAxN7bumx7CWUM5kIbMctsWDbrYQgmx5uw6msXKiV 3uFuMAztvj28ys9CfEacjVr8+lwlgPrecmG2qd+bkGPb14cOFWmTpxP5Fih7b1+ov5s9e8 vQcqghicifY+psgCKDFvBZLChIp2BJFJjKhiAl0ZLK6D+N27E09/AZvG7jtEwdvY0xTuj7 0WJ8VFP3MSCweL6PS5KWppdQ6gSo6sypLj8spr+u+tbyrSdG/l82u7cA/6+vuQ== From: Josselin Poiret To: Glenn Washburn Cc: grub-devel@gnu.org, Josselin Poiret Subject: [PATCH v4 2/2] devmapper/getroot: Set up cheated LUKS2 cryptodisk mount from DM parameters Date: Tue, 14 Jun 2022 15:47:30 +0200 Message-Id: <20220614134730.7439-3-dev@jpoiret.xyz> In-Reply-To: <20220614134730.7439-1-dev@jpoiret.xyz> References: <20220520192035.313b5ede@crass-HP-ZBook-15-G2> <20220614134730.7439-1-dev@jpoiret.xyz> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Authentication-Results: jpoiret.xyz; auth=pass smtp.auth=jpoiret@jpoiret.xyz smtp.mailfrom=dev@jpoiret.xyz X-Spamd-Bar: / Received-SPF: pass client-ip=206.189.101.64; envelope-from=dev@jpoiret.xyz; helo=jpoiret.xyz X-Spam_score_int: 4 X-Spam_score: 0.4 X-Spam_bar: / X-Spam_report: (0.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FROM_SUSPICIOUS_NTLD=0.499, PDS_OTHER_BAD_TLD=1.997, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jun 2022 13:47:44 -0000 This lets a LUKS2 cryptodisk have its cipher and hash filled out, otherwise they wouldn't be initialized if cheat mounted. --- grub-core/osdep/devmapper/getroot.c | 91 ++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c index 2bf4264cf..ac90761ea 100644 --- a/grub-core/osdep/devmapper/getroot.c +++ b/grub-core/osdep/devmapper/getroot.c @@ -51,6 +51,8 @@ #include #include +#include + static int grub_util_open_dm (const char *os_dev, struct dm_tree **tree, struct dm_tree_node **node) @@ -186,7 +188,6 @@ grub_util_pull_devmapper (const char *os_dev) && lastsubdev) { char *grdev = grub_util_get_grub_dev (lastsubdev); - dm_tree_free (tree); if (grdev) { grub_err_t err; @@ -194,7 +195,95 @@ grub_util_pull_devmapper (const char *os_dev) if (err) grub_util_error (_("can't mount encrypted volume `%s': %s"), lastsubdev, grub_errmsg); + if (strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) + { + /* set LUKS2 cipher from dm parameters, since it is not + * possible to determine the correct one without + * unlocking, as there might be multiple segments. + */ + grub_disk_t source; + grub_cryptodisk_t cryptodisk; + grub_addr_t start, length; + char *target_type; + char *params; + const char *name; + char *cipher, *cipher_mode; + struct dm_task *dmt; + char *seek_head, *c; + unsigned int remaining; + + source = grub_disk_open (grdev); + cryptodisk = grub_cryptodisk_get_by_source_disk (source); + grub_disk_close (source); + + name = dm_tree_node_get_name (node); + + grub_util_info ("populating parameters of cryptomount `%s' from DM device `%s'", + uuid, name); + + dmt = dm_task_create (DM_DEVICE_TABLE); + if (dmt == 0) + grub_util_error (_("can't create dm task DM_DEVICE_TABLE")); + if (dm_task_set_name (dmt, name) == 0) + grub_util_error (_("can't set dm task name to `%s'"), name); + if (dm_task_run (dmt) == 0) + grub_util_error (_("can't run dm task for `%s'"), name); + /* dm_get_next_target doesn't have any error modes, everything has + * been handled by dm_task_run. + */ + dm_get_next_target (dmt, NULL, &start, &length, + &target_type, ¶ms); + if (strncmp (target_type, "crypt", sizeof ("crypt")) != 0) + grub_util_error (_("dm target of type `%s' is not `crypt'"), + target_type); + + /* dm target parameters for dm-crypt is + * [<#opt_params> ...] + */ + c = params; + remaining = grub_strlen (c); + + /* first, get the cipher name from the cipher */ + if (!(seek_head = grub_memchr (c, '-', remaining))) + grub_util_error (_("can't get cipher from dm-crypt parameters `%s'"), + params); + cipher = grub_strndup (c, seek_head - c); + remaining -= seek_head - c + 1; + c = seek_head + 1; + + /* now, the cipher mode */ + if (!(seek_head = grub_memchr (c, ' ', remaining))) + grub_util_error (_("can't get cipher mode from dm-crypt parameters `%s'"), + params); + cipher_mode = grub_strndup (c, seek_head - c); + remaining -= seek_head - c + 1; + c = seek_head + 1; + + err = grub_cryptodisk_setcipher (cryptodisk, cipher, cipher_mode); + if (err) + { + grub_util_error (_("can't set cipher of cryptodisk `%s' to `%s' with mode `%s'"), + uuid, cipher, cipher_mode); + } + + grub_free (cipher); + grub_free (cipher_mode); + + /* This is the only hash usable by PBKDF2, and we don't + * have Argon2 support yet, so set it by default, + * otherwise grub-probe would miss the required + * abstraction + */ + cryptodisk->hash = grub_crypto_lookup_md_by_name ("sha256"); + if (cryptodisk->hash == 0) + { + grub_util_error (_("can't lookup hash sha256 by name")); + } + + dm_task_destroy (dmt); + } } + dm_tree_free (tree); grub_free (grdev); } else -- 2.36.1