From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1kdNp5-0002CU-Ki for mharc-grub-devel@gnu.org; Thu, 12 Nov 2020 20:24:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45318) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kdNp3-0002Bp-VZ for grub-devel@gnu.org; Thu, 12 Nov 2020 20:24:18 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:47234) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kdNp1-0004J6-UA for grub-devel@gnu.org; Thu, 12 Nov 2020 20:24:17 -0500 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0AD13g0N117451; Thu, 12 Nov 2020 20:24:12 -0500 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=z5PKEbkyXe8fgr7Q/rMktACnNHEuYXgqepLXG3SSa3A=; b=fP6bM50zMrnDKrj8KSwMRWPoUtF9RtcSjJNsdLjm0FnFfVjsVuVcEZLrIZX9QB2RcdQd fJ6mKBG1r7gUoSOvj1nDQvQY0wjOlCjTQ213Zj8LRKJGSnu53zehWdFtRjrPCVyW9tMT 0m3Lh7Bu06OJn4Eq14GMVg04yw+6SHc/fGQW+9DDjxeGtwYyuWpSf20EP/xuURy+iTvZ RNgzlmzjCOQEmHYxb74hiow/sq1pd6yaid2EznuG044EZwvjzPoiAAmGhe3F5RNWH/Gj dm7LN3Y3Q69dWlhPz8TVtu0l3ulGeQscMNkDdnUDZl++bDaAGstHEBoXX/E9nig02K6H Kg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 34se78kbh1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Nov 2020 20:24:11 -0500 Received: from m0098396.ppops.net (m0098396.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 0AD14FGL120045; Thu, 12 Nov 2020 20:24:11 -0500 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 34se78kbg5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Nov 2020 20:24:11 -0500 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 0AD1MATU006649; Fri, 13 Nov 2020 01:24:10 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma04dal.us.ibm.com with ESMTP id 34nk7atvb3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 13 Nov 2020 01:24:10 +0000 Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 0AD1O6kx12387006 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 13 Nov 2020 01:24:06 GMT Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 96B9578064; Fri, 13 Nov 2020 01:24:06 +0000 (GMT) Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 636127805E; Fri, 13 Nov 2020 01:24:04 +0000 (GMT) Received: from jarvis.int.hansenpartnership.com (unknown [9.85.145.64]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP; Fri, 13 Nov 2020 01:24:04 +0000 (GMT) From: James Bottomley To: grub-devel@gnu.org Cc: dovmurik@linux.vnet.ibm.com, Dov.Murik1@il.ibm.com, ashish.kalra@amd.com, brijesh.singh@amd.com, tobin@ibm.com, david.kaplan@amd.com, jon.grimm@amd.com, thomas.lendacky@amd.com, jejb@linux.ibm.com, frankeh@us.ibm.com, "Dr . David Alan Gilbert" Subject: [PATCH 2/3] cryptodisk: add OS provided secret support Date: Thu, 12 Nov 2020 17:22:05 -0800 Message-Id: <20201113012206.24246-3-jejb@linux.ibm.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201113012206.24246-1-jejb@linux.ibm.com> References: <20201113012206.24246-1-jejb@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.312, 18.0.737 definitions=2020-11-12_16:2020-11-12, 2020-11-12 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 impostorscore=0 phishscore=0 bulkscore=0 mlxscore=0 priorityscore=1501 spamscore=0 clxscore=1015 lowpriorityscore=0 suspectscore=3 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2011130001 Received-SPF: pass client-ip=148.163.156.1; envelope-from=jejb@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/11/12 20:24:14 X-ACL-Warn: Detected OS = Linux 3.x [generic] [fuzzy] 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_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Nov 2020 01:24:18 -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 --- grub-core/disk/cryptodisk.c | 60 ++++++++++++++++++++++++++++++++++--- include/grub/cryptodisk.h | 2 ++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 682f5a55d..02104aad4 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}, + {"secret", 's', 0, N_("Get OS provisioned secret and mount all volumes encrypted with that secret"), 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -967,6 +968,10 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) static int check_boot, have_it; static char *search_uuid; +static char *os_passwd; + +/* variable to hold the passed in secret area. */ +static char *os_secret_area; static void cryptodisk_close (grub_cryptodisk_t dev) @@ -977,6 +982,17 @@ cryptodisk_close (grub_cryptodisk_t dev) grub_free (dev); } +static int +os_password_get(char buf[], unsigned len) +{ + /* os_passwd should be null terminated, so just copy everything */ + grub_strncpy(buf, os_passwd, len); + /* and add a terminator just in case */ + buf[len - 1] = 0; + + return 1; +} + static grub_err_t grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) { @@ -996,8 +1012,17 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) return grub_errno; if (!dev) continue; - - err = cr->recover_key (source, dev, grub_password_get); + + if (os_passwd) + { + err = cr->recover_key (source, dev, os_password_get); + if (err) + /* if the key doesn't work ignore the access denied error */ + grub_error_pop(); + } + else + err = cr->recover_key (source, dev, grub_password_get); + if (err) { cryptodisk_close (dev); @@ -1013,6 +1038,14 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) return GRUB_ERR_NONE; } +grub_err_t +grub_cryptodisk_set_secret (char *secret) +{ + os_secret_area = secret; + + return GRUB_ERR_NONE; +} + #ifdef GRUB_UTIL #include grub_err_t @@ -1089,7 +1122,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; - 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"); have_it = 0; @@ -1107,6 +1140,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) check_boot = state[2].set; search_uuid = args[0]; + os_passwd = NULL; grub_device_iterate (&grub_cryptodisk_scan_device, NULL); search_uuid = NULL; @@ -1117,11 +1151,28 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) else if (state[1].set || (argc == 0 && state[2].set)) { search_uuid = NULL; + os_passwd = NULL; check_boot = state[2].set; grub_device_iterate (&grub_cryptodisk_scan_device, NULL); search_uuid = NULL; return GRUB_ERR_NONE; } + else if (state[3].set) + { + /* do we have a secret? */ + if (os_secret_area == NULL) + return grub_error (GRUB_ERR_INVALID_COMMAND, "No OS secret is provisioned"); + + os_passwd = os_secret_area; + search_uuid = NULL; + grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + os_passwd = NULL; + + if (!have_it) + return grub_error (GRUB_ERR_ACCESS_DENIED, "SEV password failed to unlock any volumes"); + + return GRUB_ERR_NONE; + } else { grub_err_t err; @@ -1132,6 +1183,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) grub_size_t len; search_uuid = NULL; + os_passwd = NULL; check_boot = state[2].set; diskname = args[0]; len = grub_strlen (diskname); @@ -1299,7 +1351,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_("SOURCE|-u UUID|-a|-b|-s"), 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 45dae5483..55c411754 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -163,4 +163,6 @@ 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); +grub_err_t grub_cryptodisk_set_secret(char *secret); + #endif -- 2.26.2