From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1nH5zj-00080P-63 for mharc-grub-devel@gnu.org; Mon, 07 Feb 2022 10:31:59 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49484) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nH5zg-0007wS-M2 for grub-devel@gnu.org; Mon, 07 Feb 2022 10:31:57 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:11804) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nH5zd-0001FP-OE for grub-devel@gnu.org; Mon, 07 Feb 2022 10:31:55 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 217DtwxB003797; Mon, 7 Feb 2022 15:31:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=KZxJ7tUoHBflwSwwrfTUbXPAECm7dO9EpNUXEhZqPGs=; b=HbWsMhK9v67jfhuk9/jmg47TCDBkTQ+5EeulmnR9C6ZwGiLYp1uJyxWmVXxVmDTuwnz5 nCF8xjhLXAUYElQw+Ktnu9SNDjVdoPiH7ui7baFZ/FNVR13qhJlodT/m59ykEPOK1gnI dzTVeG3OKcfkrtUGDTTcOoaM5xzYCn1LhUJHphWpYf0F3Hqkf53qdsu5/e4zpA+MVfOD kdV5od2azu4G5f/U17fjT8WEknpWKKJyIL6To5D3TE/glcKzuJf3pbabFm/V+9fgQBvw R3NqPokP7Cnxe8H8iMrEfp0Nt9zxLbk1qtIKbkgvMHkg1f/YbmJ9Ql/rjipv1svHK+xI qw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3e22qeqq54-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 07 Feb 2022 15:31:48 +0000 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 217DCmZq020584; Mon, 7 Feb 2022 15:31:47 GMT Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 3e22qeqq4s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 07 Feb 2022 15:31:47 +0000 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 217FDpu9017533; Mon, 7 Feb 2022 15:31:46 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma04dal.us.ibm.com with ESMTP id 3e1gvafksk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 07 Feb 2022 15:31:46 +0000 Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 217FVfUf33227112 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 7 Feb 2022 15:31:41 GMT Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7CD5F6E050; Mon, 7 Feb 2022 15:31:41 +0000 (GMT) Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 90D1F6E05E; Mon, 7 Feb 2022 15:31:39 +0000 (GMT) Received: from jarvis.int.hansenpartnership.com (unknown [9.211.78.81]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 7 Feb 2022 15:31:39 +0000 (GMT) From: James Bottomley To: grub-devel@gnu.org Cc: thomas.lendacky@amd.com, ashish.kalra@amd.com, brijesh.singh@amd.com, david.kaplan@amd.com, jon.grimm@amd.com, tobin@ibm.com, frankeh@us.ibm.com, Dr David Alan Gilbert , dovmurik@linux.vnet.ibm.com, Dov.Murik1@il.ibm.com, Javier Martinez Canillas , GNUtoo@cyberdimension.org, ps@pks.im, development@efficientek.com, Daniel Kiper Subject: [PATCH v4 1/2] cryptodisk: add OS provided secret support Date: Mon, 7 Feb 2022 10:29:43 -0500 Message-Id: <20220207152944.27183-2-jejb@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207152944.27183-1-jejb@linux.ibm.com> References: <20220207152944.27183-1-jejb@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: amj9SipVONe-jCJkkldMK35X6d3-dv2_ X-Proofpoint-GUID: TyXgF7unCsRFAwpv-g-4sa6H7O8YQn8L X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-02-07_05,2022-02-07_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 mlxscore=0 adultscore=0 malwarescore=0 clxscore=1015 suspectscore=0 bulkscore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2202070097 Received-SPF: pass client-ip=148.163.156.1; envelope-from=jejb@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham 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: Mon, 07 Feb 2022 15:31:57 -0000 Make use of the new OS provided secrets API so that if the new '-s' option is passed in we try to extract the secret from the API rather than prompting for it. The primary consumer of this is AMD SEV, which has been programmed to provide an injectable secret to the encrypted virtual machine. OVMF provides the secret area and passes it into the EFI Configuration Tables. The grub EFI layer pulls the secret out and primes the secrets API with it. The upshot of all of this is that a SEV protected VM can do an encrypted boot with a protected boot secret. Signed-off-by: James Bottomley --- v2: add callback for after secret use v3: update to use named module mechanism for secret loading v4: update for new secret passing API --- grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++++++++++++++-- include/grub/cryptodisk.h | 14 ++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 497097394..f9c86f958 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -42,6 +42,7 @@ static const struct grub_arg_option options[] = {"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}, + {"secret", 's', 0, N_("Get secret passphrase from named module and optional identifier"), 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -984,6 +985,9 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) #endif +/* variable to hold the list of secret providers */ +static struct grub_secret_entry *secret_providers; + static void cryptodisk_close (grub_cryptodisk_t dev) { @@ -1064,6 +1068,18 @@ grub_cryptodisk_scan_device_real (const char *name, return dev; } +void +grub_cryptodisk_add_secret_provider (struct grub_secret_entry *e) +{ + grub_list_push(GRUB_AS_LIST_P (&secret_providers), GRUB_AS_LIST (e)); +} + +void +grub_cryptodisk_remove_secret_provider (struct grub_secret_entry *e) +{ + grub_list_remove (GRUB_AS_LIST (e)); +} + #ifdef GRUB_UTIL #include grub_err_t @@ -1160,10 +1176,14 @@ 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}; + struct grub_secret_entry *se = NULL; - if (argc < 1 && !state[1].set && !state[2].set) + if (argc < 1 && !state[1].set && !state[2].set && !state[3].set) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + if (state[3].set && state[4].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "-p and -s are exclusive options"); + if (grub_cryptodisk_list == NULL) return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); @@ -1172,6 +1192,24 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) cargs.key_data = (grub_uint8_t *) state[3].arg; cargs.key_len = grub_strlen (state[3].arg); } + else if (state[4].set) /* secret module */ + { + grub_err_t rc; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "secret module must be specified"); +#ifndef GRUB_UTIL + grub_dl_load (args[0]); +#endif + se = grub_named_list_find (GRUB_AS_NAMED_LIST (secret_providers), args[0]); + if (se == NULL) + return grub_error (GRUB_ERR_INVALID_COMMAND, "No secret provider is found"); + + rc = se->get (args[1], &cargs.key_data); + if (rc) + return rc; + cargs.key_len = grub_strlen((char *) cargs.key_data); + } if (state[0].set) /* uuid */ { @@ -1190,6 +1228,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) cargs.search_uuid = args[0]; found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); + if (state[4].set) + { + se->put (args[1], found_uuid, &cargs.key_data); + } + if (found_uuid) return GRUB_ERR_NONE; else if (grub_errno == GRUB_ERR_NONE) @@ -1208,6 +1251,10 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) { cargs.check_boot = state[2].set; grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); + if (state[4].set) + { + se->put (args[1], 1, &cargs.key_data); + } return GRUB_ERR_NONE; } else @@ -1252,6 +1299,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) if (disklast) *disklast = ')'; + if (state[4].set) + { + se->put (args[1], dev != NULL, &cargs.key_data); + } + return (dev == NULL) ? grub_errno : GRUB_ERR_NONE; } } @@ -1385,7 +1437,7 @@ GRUB_MOD_INIT (cryptodisk) { grub_disk_dev_register (&grub_cryptodisk_dev); cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, - N_("[-p password] "), + N_("[-p password] "), N_("Mount a crypto device."), options); grub_procfs_register ("luks_script", &luks_script); } diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index c6524c9ea..60249f1fc 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -183,4 +183,18 @@ grub_util_get_geli_uuid (const char *dev); grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk); +struct grub_secret_entry { + /* as named list */ + struct grub_secret_entry *next; + struct grub_secret_entry **prev; + const char *name; + + /* additional entries */ + grub_err_t (*get) (const char *arg, grub_uint8_t **secret); + grub_err_t (*put) (const char *arg, int have_it, grub_uint8_t **secret); +}; + +void grub_cryptodisk_add_secret_provider (struct grub_secret_entry *e); +void grub_cryptodisk_remove_secret_provider (struct grub_secret_entry *e); + #endif -- 2.34.1