From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1mvN19-0002ZI-U4 for mharc-grub-devel@gnu.org; Thu, 09 Dec 2021 12:15:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:44926) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mvN11-0002Oa-Ai for grub-devel@gnu.org; Thu, 09 Dec 2021 12:15:31 -0500 Received: from [2607:f8b0:4864:20::f29] (port=46005 helo=mail-qv1-xf29.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mvN0z-0005Bo-8j for grub-devel@gnu.org; Thu, 09 Dec 2021 12:15:30 -0500 Received: by mail-qv1-xf29.google.com with SMTP id s9so5646597qvk.12 for ; Thu, 09 Dec 2021 09:15:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficientek-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=u+Cug+k9A/CvUN5v9tvaVJnAarhRsQTBblLKClQUoJE=; b=3X3UA0CWVYGihDzju93qhZUG1qJKDKY8dobrekFPZH7LhCxDBMy2E/Gbm4myzJ9wqg pCn8BS93wc7c6JY7ZPqpHvisf570i8wkPkw3OLeXQz1D5vvc4u9zZYzhgxs++L5wXWaU v10Pl/CIgkXtaXk/H6FCVQD38a2b4NPec9n9nlgQU9jRJ+ZeF1Ihepvr4ne/lIhlYiZv EWLgXNCq6vSpIIJuRKBGd8xP2aDWCsAR+B7B70a5pfJAPZuutMI+Zdn2LJZqont6TImS +j0sjLmhI7+IsvNKpEqcYpAaG4f9N8+LmL1ztj8s9i0bNR52jnTYmtkuQyaXDEcaLtrL BSCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=u+Cug+k9A/CvUN5v9tvaVJnAarhRsQTBblLKClQUoJE=; b=sKDeBXCsmopuQvX+/t4nQRS6f2Rh4+r4Nvvm//PLGUAbrXMB2PLs/9k9faTU5bvjpP nB3izAgHjp/xEe4+2WLHRvVIEnu2N771yMSWxjG+/J24aWRrYq/Ss2ZvATvuK372G5qI VeScgJC4QhhccXHhok7JVGzIdVc0y2qJa547w2m+dGu66fXbrWdQpFiAn/NQlEt6ksgJ 2p9rJYRIEliLihXRmMShUYlxNPF+Fj1wGe3GpafeySlGzRmyz8R/FsYNoAGxbPqrN8Er WcFKw2u0oPhkMW8EYRqSd+dRcU3dma9dRkeUJvL5Y0RWjo0T+AqEGHeKf03FB3GRgHVX T5sg== X-Gm-Message-State: AOAM5337lcHEdij/F+4UljimHC0jgCBZxR4FR0aSQpf04NxqU5prfc2j Dy5fp9lSQ4EbkVncBC4IzhooEg== X-Google-Smtp-Source: ABdhPJxERU74TqMNQZY4O6eYo3kizI3bkQJM8TPRHtr3kLXgN9yQ8Vfb12zTE7Q8yTzozyZX0zYduA== X-Received: by 2002:a05:6214:262e:: with SMTP id gv14mr18844503qvb.107.1639070127211; Thu, 09 Dec 2021 09:15:27 -0800 (PST) Received: from localhost.localdomain ([37.218.244.251]) by smtp.gmail.com with ESMTPSA id m9sm151839qkn.59.2021.12.09.09.15.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Dec 2021 09:15:26 -0800 (PST) From: Glenn Washburn To: Daniel Kiper , grub-devel@gnu.org Cc: Denis 'GNUtoo' Carikli , Patrick Steinhardt , James Bottomley , Glenn Washburn Subject: [PATCH v5 6/9] cryptodisk: Add infrastructure to pass data from cryptomount to cryptodisk modules Date: Thu, 9 Dec 2021 11:14:55 -0600 Message-Id: <9ab7601bd412dacf75fa419fdbaec2a90ce44695.1639069499.git.development@efficientek.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::f29 (failed) Received-SPF: pass client-ip=2607:f8b0:4864:20::f29; envelope-from=development@efficientek.com; helo=mail-qv1-xf29.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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: Thu, 09 Dec 2021 17:15:32 -0000 Previously, the cryptomount arguments were passed by global variable and function call argument, neither of which are ideal. This change passes data via a grub_cryptomount_args struct, which can be added to over time as opposed to continually adding arguments to the cryptodisk scan and recover_key. As an example, passing a password as a cryptomount argument is implemented. However, the backends are not implemented, so testing this will return a not implemented error. Also, add comments to cryptomount argument parsing to make it more obvious which argument states are being handled. Signed-off-by: Glenn Washburn --- grub-core/disk/cryptodisk.c | 31 +++++++++++++++++++++---------- grub-core/disk/geli.c | 6 +++++- grub-core/disk/luks.c | 7 ++++++- grub-core/disk/luks2.c | 7 ++++++- include/grub/cryptodisk.h | 9 ++++++++- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index a5f1b0978..f1ccfbee3 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -41,6 +41,7 @@ static const struct grub_arg_option options[] = /* TRANSLATORS: It's still restricted to cryptodisks only. */ {"all", 'a', 0, N_("Mount all."), 0, 0}, {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, + {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -996,7 +997,9 @@ cryptodisk_close (grub_cryptodisk_t dev) } static grub_cryptodisk_t -grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) +grub_cryptodisk_scan_device_real (const char *name, + grub_disk_t source, + grub_cryptomount_args_t cargs) { grub_err_t err; grub_cryptodisk_t dev; @@ -1015,7 +1018,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) if (!dev) continue; - err = cr->recover_key (source, dev); + err = cr->recover_key (source, dev, cargs); if (err) { cryptodisk_close (dev); @@ -1080,11 +1083,12 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) static int grub_cryptodisk_scan_device (const char *name, - void *data __attribute__ ((unused))) + void *data) { int ret = 0; grub_disk_t source; grub_cryptodisk_t dev; + grub_cryptomount_args_t cargs = data; grub_errno = GRUB_ERR_NONE; /* Try to open disk. */ @@ -1095,7 +1099,7 @@ grub_cryptodisk_scan_device (const char *name, return 0; } - dev = grub_cryptodisk_scan_device_real (name, source); + dev = grub_cryptodisk_scan_device_real (name, source, cargs); if (dev) { ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0); @@ -1124,6 +1128,7 @@ static grub_err_t grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; + struct grub_cryptomount_args cargs = {0}; if (argc < 1 && !state[1].set && !state[2].set) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); @@ -1131,7 +1136,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) if (grub_cryptodisk_list == NULL) return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); - if (state[0].set) + if (state[3].set) /* password */ + { + cargs.key_data = (grub_uint8_t *) state[3].arg; + cargs.key_len = grub_strlen (state[3].arg); + } + + if (state[0].set) /* uuid */ { int found_uuid; grub_cryptodisk_t dev; @@ -1146,7 +1157,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) check_boot = state[2].set; search_uuid = args[0]; - found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); search_uuid = NULL; if (found_uuid) @@ -1163,11 +1174,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) } return grub_errno; } - else if (state[1].set || (argc == 0 && state[2].set)) + else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */ { search_uuid = NULL; check_boot = state[2].set; - grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); search_uuid = NULL; return GRUB_ERR_NONE; } @@ -1208,7 +1219,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) return GRUB_ERR_NONE; } - dev = grub_cryptodisk_scan_device_real (diskname, disk); + dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); grub_disk_close (disk); if (disklast) @@ -1347,7 +1358,7 @@ GRUB_MOD_INIT (cryptodisk) { grub_disk_dev_register (&grub_cryptodisk_dev); cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, - N_("SOURCE|-u UUID|-a|-b"), + N_("[-p password] "), N_("Mount a crypto device."), options); grub_procfs_register ("luks_script", &luks_script); } diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 2f34a35e6..777da3a05 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -398,7 +398,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, } static grub_err_t -recover_key (grub_disk_t source, grub_cryptodisk_t dev) +recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs) { grub_size_t keysize; grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN]; @@ -414,6 +414,10 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) grub_disk_addr_t sector; grub_err_t err; + /* Keyfiles are not implemented yet */ + if (cargs->key_data != NULL || cargs->key_len) + return GRUB_ERR_NOT_IMPLEMENTED_YET; + if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) return grub_error (GRUB_ERR_BUG, "cipher block is too long"); diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 13103ea6a..c5858fcf8 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -152,7 +152,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, static grub_err_t luks_recover_key (grub_disk_t source, - grub_cryptodisk_t dev) + grub_cryptodisk_t dev, + grub_cryptomount_args_t cargs) { struct grub_luks_phdr header; grub_size_t keysize; @@ -165,6 +166,10 @@ luks_recover_key (grub_disk_t source, grub_size_t max_stripes = 1; char *tmp; + /* Keyfiles are not implemented yet */ + if (cargs->key_data != NULL || cargs->key_len) + return GRUB_ERR_NOT_IMPLEMENTED_YET; + err = grub_disk_read (source, 0, 0, sizeof (header), &header); if (err) return err; diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c index fea196dd4..2cbec8acc 100644 --- a/grub-core/disk/luks2.c +++ b/grub-core/disk/luks2.c @@ -545,7 +545,8 @@ luks2_decrypt_key (grub_uint8_t *out_key, static grub_err_t luks2_recover_key (grub_disk_t source, - grub_cryptodisk_t crypt) + grub_cryptodisk_t crypt, + grub_cryptomount_args_t cargs) { grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; char passphrase[MAX_PASSPHRASE], cipher[32]; @@ -559,6 +560,10 @@ luks2_recover_key (grub_disk_t source, grub_json_t *json = NULL, keyslots; grub_err_t ret; + /* Keyfiles are not implemented yet */ + if (cargs->key_data != NULL || cargs->key_len) + return GRUB_ERR_NOT_IMPLEMENTED_YET; + ret = luks2_read_header (source, &header); if (ret) return ret; diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index dcf17fbb3..282f8ac45 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -66,6 +66,13 @@ typedef gcry_err_code_t (*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, grub_uint64_t zoneno); +struct grub_cryptomount_args +{ + grub_uint8_t *key_data; + grub_size_t key_len; +}; +typedef struct grub_cryptomount_args *grub_cryptomount_args_t; + struct grub_cryptodisk { struct grub_cryptodisk *next; @@ -119,7 +126,7 @@ struct grub_cryptodisk_dev grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, int boot_only); - grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev); + grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs); }; typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; -- 2.27.0