From patchwork Tue Aug 16 19:32:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacky Li X-Patchwork-Id: 12945238 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D046C25B0E for ; Tue, 16 Aug 2022 19:32:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236768AbiHPTcj (ORCPT ); Tue, 16 Aug 2022 15:32:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237134AbiHPTci (ORCPT ); Tue, 16 Aug 2022 15:32:38 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42E0D876B5 for ; Tue, 16 Aug 2022 12:32:37 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id c11-20020a170902d48b00b0016f093907e0so7129568plg.20 for ; Tue, 16 Aug 2022 12:32:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=cLOSl1l8YNAWhxNFx3o73beB8xM+qrlqaIO5EXRLvFo=; b=tgMI8er7FzLZlU+19DplrLR9MN+MPGczyrzjaZD2fVzo6thDafHrq6GbW4E8PpqeGs i+y9D4fPpx99JIX6ZT5p+Lozzp0CRsZldMdDop6K1Aoav9maSeUliXdub5vlMkJvyrkO oasQGw7n6J+jS4wb4Npsw1C2aEAsnchQZ1zbzBiTpYWJXXJ2SDznV1piFewvrhkeusMF vSpF6BG2XgbeLrYhOVYPy8aep67MWYNm6erJixGm11bh5mw/wiPpQ1BbaZFvvRft+l4t YEKWwfe0/XdF47dWpvYt51rArd0xrZ4LyY5azxWVQdp9D46h86S0aJjDOECgMf1tHmcc FVvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=cLOSl1l8YNAWhxNFx3o73beB8xM+qrlqaIO5EXRLvFo=; b=utCU1xW0VW7B1+mfpa4Fv1RC+f8xhXWi9rHizuvunv1fHryXFKy64Pgzr+B7gITSEM oMiDzFzCryfg+w95dkHXv5yXXNj3A8sxm19BKOoZS5SvkpPHXpFSCBAvia4KqU4KevFc eQX6eZDvRw+MyQYwOHSG3yQCg1BH0z20kvTogHUi8Xe4D1J+UHT14EW0EUTng1tAZoGL 9AKL+vnXVaj2/3lajjeofj5TpfFlCYSoycT1hNC2jFA773U4oN9mPkFxlbn6YX0+mZk2 JxtC0whwO+Oh3JWaZ+GbD43ZBO368uS6bBtYtxaXdiB8jZMZXxJrQ+t7Goqj9Y+aLISq 99hA== X-Gm-Message-State: ACgBeo1A+U9ohyWB0hnBLH/isMTaNh5CnSSjQGDoKDEFroWlqi3MeI20 SG+I356U6bYaOUHekTO7kL9htCAWbTM= X-Google-Smtp-Source: AA6agR5JWvYnZnpqmFocIBolS4RXEXDNzFu8iVfVPJ8x2ZIecuDgEzoSyOU1TzPcs0oySmP1CDP49LPY0+ws X-Received: from jackyli.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3b51]) (user=jackyli job=sendgmr) by 2002:a05:6a00:850:b0:52e:d1c1:df48 with SMTP id q16-20020a056a00085000b0052ed1c1df48mr22198771pfk.75.1660678356759; Tue, 16 Aug 2022 12:32:36 -0700 (PDT) Date: Tue, 16 Aug 2022 19:32:08 +0000 In-Reply-To: <20220816193209.4057566-1-jackyli@google.com> Message-Id: <20220816193209.4057566-2-jackyli@google.com> Mime-Version: 1.0 References: <20220816193209.4057566-1-jackyli@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v2 1/2] crypto: ccp - Initialize PSP when reading psp data file failed From: Jacky Li To: Brijesh Singh , Tom Lendacky , John Allen Cc: Herbert Xu , "David S. Miller" , Marc Orr , Alper Gun , Peter Gonda , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Jacky Li Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Currently the OS fails the PSP initialization when the file specified at 'init_ex_path' does not exist or has invalid content. However the SEV spec just requires users to allocate 32KB of 0xFF in the file, which can be taken care of by the OS easily. To improve the robustness during the PSP init, leverage the retry mechanism and continue the init process: Before the first INIT_EX call, if the content is invalid or missing, continue the process by feeding those contents into PSP instead of aborting. PSP will then override it with 32KB 0xFF and return SEV_RET_SECURE_DATA_INVALID status code. In the second INIT_EX call, this 32KB 0xFF content will then be fed and PSP will write the valid data to the file. In order to do this, sev_read_init_ex_file should only be called once for the first INIT_EX call. Calling it again for the second INIT_EX call will cause the invalid file content overwriting the valid 32KB 0xFF data provided by PSP in the first INIT_EX call. Co-developed-by: Peter Gonda Signed-off-by: Peter Gonda Signed-off-by: Jacky Li Reported-by: Alper Gun Acked-by: David Rientjes Acked-by: Tom Lendacky --- Changelog since v1: - Add the message to indicate the possible file creation. - Return 0 when the file does not exist in sev_read_init_ex_file(). - Move sev_read_init_ex_file() before the first call to INIT_EX. - Rephrase the last paragraph of the commit message. .../virt/kvm/x86/amd-memory-encryption.rst | 5 ++- drivers/crypto/ccp/sev-dev.c | 36 +++++++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Documentation/virt/kvm/x86/amd-memory-encryption.rst index 2d307811978c..935aaeb97fe6 100644 --- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst +++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst @@ -89,9 +89,8 @@ context. In a typical workflow, this command should be the first command issued. The firmware can be initialized either by using its own non-volatile storage or the OS can manage the NV storage for the firmware using the module parameter -``init_ex_path``. The file specified by ``init_ex_path`` must exist. To create -a new NV storage file allocate the file with 32KB bytes of 0xFF as required by -the SEV spec. +``init_ex_path``. If the file specified by ``init_ex_path`` does not exist or +is invalid, the OS will create or override the file with output from PSP. Returns: 0 on success, -negative on error diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 9f588c9728f8..fb7ca45a2f0d 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -211,18 +211,24 @@ static int sev_read_init_ex_file(void) if (IS_ERR(fp)) { int ret = PTR_ERR(fp); - dev_err(sev->dev, - "SEV: could not open %s for read, error %d\n", - init_ex_path, ret); + if (ret == -ENOENT) { + dev_info(sev->dev, + "SEV: %s does not exist and will be created later.\n", + init_ex_path); + ret = 0; + } else { + dev_err(sev->dev, + "SEV: could not open %s for read, error %d\n", + init_ex_path, ret); + } return ret; } nread = kernel_read(fp, sev_init_ex_buffer, NV_LENGTH, NULL); if (nread != NV_LENGTH) { - dev_err(sev->dev, - "SEV: failed to read %u bytes to non volatile memory area, ret %ld\n", + dev_info(sev->dev, + "SEV: could not read %u bytes to non volatile memory area, ret %ld\n", NV_LENGTH, nread); - return -EIO; } dev_dbg(sev->dev, "SEV: read %ld bytes from NV file\n", nread); @@ -410,17 +416,12 @@ static int __sev_init_locked(int *error) static int __sev_init_ex_locked(int *error) { struct sev_data_init_ex data; - int ret; memset(&data, 0, sizeof(data)); data.length = sizeof(data); data.nv_address = __psp_pa(sev_init_ex_buffer); data.nv_len = NV_LENGTH; - ret = sev_read_init_ex_file(); - if (ret) - return ret; - if (sev_es_tmr) { /* * Do not include the encryption mask on the physical @@ -439,7 +440,7 @@ static int __sev_platform_init_locked(int *error) { struct psp_device *psp = psp_master; struct sev_device *sev; - int rc, psp_ret = -1; + int rc = 0, psp_ret = -1; int (*init_function)(int *error); if (!psp || !psp->sev_data) @@ -450,8 +451,15 @@ static int __sev_platform_init_locked(int *error) if (sev->state == SEV_STATE_INIT) return 0; - init_function = sev_init_ex_buffer ? __sev_init_ex_locked : - __sev_init_locked; + if (sev_init_ex_buffer) { + init_function = __sev_init_ex_locked; + rc = sev_read_init_ex_file(); + if (rc) + return rc; + } else { + init_function = __sev_init_locked; + } + rc = init_function(&psp_ret); if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) { /* From patchwork Tue Aug 16 19:32:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacky Li X-Patchwork-Id: 12945239 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EC079C25B0E for ; Tue, 16 Aug 2022 19:32:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236836AbiHPTco (ORCPT ); Tue, 16 Aug 2022 15:32:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237144AbiHPTcm (ORCPT ); Tue, 16 Aug 2022 15:32:42 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FC2F883CC for ; Tue, 16 Aug 2022 12:32:41 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id x3-20020a17090ab00300b001f731f28b82so10204375pjq.3 for ; Tue, 16 Aug 2022 12:32:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=zO5It9jW5Ab8pMtnbQERYyQvcLS9G329Zpg9klZy+fY=; b=T+3wMLEHCjZORIJaiQyb/vbWxoih9ExTmT/iYy0VeOAbdfsRLuvrYSTToE4xC395Hb 8rtiLr/+bk6o8eQJWJqlWeDY5kax4JvF31lxyhd8HZB+xu8X6tANByp/V74LKpJ0REPD 6pLIMWC6xQGG71NDBv5ZWed7vN5606apgAYXZgIMfucBRHWmDlTKIux54nivTe7/R14K zicKMMKXy34dlA/oMRiGtPBB/1rwKdXe2THDcBjz9UaLiUjPVULA/h5gQ/EEZbaHca+z 3+RK9IaXnsXtmt5VnfhFKdq61kcj1ZTSSuzevnFV5FV1qj1ZmkDSVgWCvmUol77mWgog 2raw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=zO5It9jW5Ab8pMtnbQERYyQvcLS9G329Zpg9klZy+fY=; b=Nmm4cMbTNh4KdvDyZ/uirwlkKCyVqAZ+cjgmGDkpFClUIORCkvuA96BbD9KaJv+LB/ Ln/5x5shrH0pztStVxWD503QrD+Of6+DvRgwqFklkdU7uxhfkg5tC840v1WEq0YmlENj up90e15RGu2ybFwlJbIpr+nCv6Ei//hDnytczk48ZXAoV/PdUp1gyy7wxKmeYX48tW7c d8taznZIhh2RQDtHxOPTdbYn0psUeAe8tVUaNs1bYhOC14cWQYSZC4s0rM189msDxzwA t5J/supN+XHP3NHHf9nN4Jlobav15jKNsvvoSo3fHJ4MpIARRq0VNp2Ime4HbzUI3p3J +QjA== X-Gm-Message-State: ACgBeo08eVsUUl9Cc2VSa4UMUliRc09CVx+IEXZ9qBD1yJ0O/GqV+/UQ 1Wj3kyQYGYKsRLMSFrmsN64+AUnLMos= X-Google-Smtp-Source: AA6agR7ycAIiMu1up33hj1Do+MnhhxCC9G7VF8Bgz2C0/MM+g+7+nG81BtOwC2Vzz+Xgbz2jLrFMQzBB+fc/ X-Received: from jackyli.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3b51]) (user=jackyli job=sendgmr) by 2002:a17:902:710e:b0:170:8d34:9447 with SMTP id a14-20020a170902710e00b001708d349447mr23167541pll.126.1660678361168; Tue, 16 Aug 2022 12:32:41 -0700 (PDT) Date: Tue, 16 Aug 2022 19:32:09 +0000 In-Reply-To: <20220816193209.4057566-1-jackyli@google.com> Message-Id: <20220816193209.4057566-3-jackyli@google.com> Mime-Version: 1.0 References: <20220816193209.4057566-1-jackyli@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v2 2/2] crypto: ccp - Fail the PSP initialization when writing psp data file failed From: Jacky Li To: Brijesh Singh , Tom Lendacky , John Allen Cc: Herbert Xu , "David S. Miller" , Marc Orr , Alper Gun , Peter Gonda , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Jacky Li , kernel test robot Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Currently the OS continues the PSP initialization when there is a write failure to the init_ex_file. Therefore, the userspace would be told that SEV is properly INIT'd even though the psp data file is not updated. This is problematic because later when asked for the SEV data, the OS won't be able to provide it. Fixes: 3d725965f836 ("crypto: ccp - Add SEV_INIT_EX support") Reported-by: Peter Gonda Reported-by: kernel test robot Signed-off-by: Jacky Li Acked-by: David Rientjes Acked-by: Tom Lendacky --- Changelog since v1: - Add a blank line after the variable declaration. - Fix the string format of the error code. drivers/crypto/ccp/sev-dev.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index fb7ca45a2f0d..ab1f76549ef8 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -237,7 +237,7 @@ static int sev_read_init_ex_file(void) return 0; } -static void sev_write_init_ex_file(void) +static int sev_write_init_ex_file(void) { struct sev_device *sev = psp_master->sev_data; struct file *fp; @@ -247,14 +247,16 @@ static void sev_write_init_ex_file(void) lockdep_assert_held(&sev_cmd_mutex); if (!sev_init_ex_buffer) - return; + return 0; fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600); if (IS_ERR(fp)) { + int ret = PTR_ERR(fp); + dev_err(sev->dev, - "SEV: could not open file for write, error %ld\n", - PTR_ERR(fp)); - return; + "SEV: could not open file for write, error %d\n", + ret); + return ret; } nwrite = kernel_write(fp, sev_init_ex_buffer, NV_LENGTH, &offset); @@ -265,18 +267,20 @@ static void sev_write_init_ex_file(void) dev_err(sev->dev, "SEV: failed to write %u bytes to non volatile memory area, ret %ld\n", NV_LENGTH, nwrite); - return; + return -EIO; } dev_dbg(sev->dev, "SEV: write successful to NV file\n"); + + return 0; } -static void sev_write_init_ex_file_if_required(int cmd_id) +static int sev_write_init_ex_file_if_required(int cmd_id) { lockdep_assert_held(&sev_cmd_mutex); if (!sev_init_ex_buffer) - return; + return 0; /* * Only a few platform commands modify the SPI/NV area, but none of the @@ -291,10 +295,10 @@ static void sev_write_init_ex_file_if_required(int cmd_id) case SEV_CMD_PEK_GEN: break; default: - return; + return 0; } - sev_write_init_ex_file(); + return sev_write_init_ex_file(); } static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) @@ -367,7 +371,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) cmd, reg & PSP_CMDRESP_ERR_MASK); ret = -EIO; } else { - sev_write_init_ex_file_if_required(cmd); + ret = sev_write_init_ex_file_if_required(cmd); } print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,