From patchwork Thu Oct 27 15:05:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Gonda X-Patchwork-Id: 11815 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp285003wru; Thu, 27 Oct 2022 08:08:44 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4reLqpDUXce/wbjzb4FAJNfUIBAiZo6r3wX2x+6ev0dAQhWpruH1+eLJxLJg+xRZfEeuy4 X-Received: by 2002:a17:90b:3847:b0:20d:c41f:de7a with SMTP id nl7-20020a17090b384700b0020dc41fde7amr10924597pjb.85.1666883324379; Thu, 27 Oct 2022 08:08:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666883324; cv=none; d=google.com; s=arc-20160816; b=0VAhB2ZKF/Wz2yCTYcDNzj1u+o6rMPrFCqQO6aXyj9KKhjAaG0UBod2HfDZ31PbBsw kdJINJ+v0EyP2wgE6Eoh+sqWjdGYni52XA29r9GJtg7FG8sfGWXLWZaiwQsLy+sg+tHY kPe6R8zcT38QMUmVv/QTOUSYtboV7tS93HDn+/Zx+hiEThbkkFQDWAyCEQg/eMiOJokR QQSzpgprecT74maHAxBP4M5P48hgjakEErK1hjgKnwpj+IuXPsKnPsXXCnYFC7rFRlMz Ih5Iq9213EMw3g9O3avUGS0GOK4fqIRyy3jYCATbBqPt0YYgu0LBJYjWq+/S1iD8V8ix eSjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=Rm31qAFaq+M5EgnK0auSpdF+G0fRaJUMCym7D7tYLvw=; b=S73c164y7bC6Lqh1HvcYA19qvBSLoxLTtx6FtzdKSiyo1FOISv+1SDbiq429gRHou9 r5IF1RaC9gq1KjnEeG4bye1YK87h8uRk4xNBzOpXD6gwXjQU948/JwxEcLJYUcmJuoJK XWfXIaTWoW3RnHOMfpyuMrLADStfsmaRKjyZTQTW807ttYoVpMkOQjEz56h+X607SKiR EtVwyZx2DlMkK3TvXqKJJiwgxQA4JG7WPSgeZVJKWVPNgb0VqwwlKFdUuy73aL4U+Kmw xVmsKKr+flPNo0Kbzshm2uIYMbPSSWcVsL4j0M2pyt4IZ7DHOuZ7g2f5NnpDclB9v0cU dgpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=Iw874OKP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id lk14-20020a17090b33ce00b002129a8204d2si2211339pjb.44.2022.10.27.08.08.11; Thu, 27 Oct 2022 08:08:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=Iw874OKP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234035AbiJ0PGI (ORCPT + 99 others); Thu, 27 Oct 2022 11:06:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235382AbiJ0PGF (ORCPT ); Thu, 27 Oct 2022 11:06:05 -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 47CB7D77EF for ; Thu, 27 Oct 2022 08:06:04 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id l16-20020a170902f69000b001865f863784so1225746plg.2 for ; Thu, 27 Oct 2022 08:06:04 -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:subject:date:message-id:reply-to; bh=Rm31qAFaq+M5EgnK0auSpdF+G0fRaJUMCym7D7tYLvw=; b=Iw874OKP9XyuWJmrG1OHfXWZrOxXcb2jULJ6j4+HS40QEL25Wc6OtiLxK0KnUavx5B ZFH2ffHBIiZFHOtg6b/LHMy5TBSFbULVIUYQVUaFQxPtKihrmHSAoFjOUf5uK5joyf3x w7uxADbDL8eqDwO3IkhUHnYJO2Yfbx07Px4a+ozuf+iA9Z25iwjMQijYBGD0m/ovUQYD rR1mEnY5ZBTVTJg4b4W9NLf4y7JOmvlAzhXu+OuWKRPN6rRzrTTw6duo4lSJ9r+g/2Ct TDx0kuIfi5wBEMtGaBIzCh+QVsvK9W12adB/3UHf81UbbC6bKWHjHNJuJI3dfLJhxfN1 ujEg== 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:subject:date:message-id:reply-to; bh=Rm31qAFaq+M5EgnK0auSpdF+G0fRaJUMCym7D7tYLvw=; b=rrkxTmBRdzbdnPo2rDmGPRWkoru9q7vnwc5bTmVCaduU2xA0krSUsl0Q0kiH2JMU9R fH591tUuZYfe8I34orIqGDrqJFY5bv3YOsrUy7dBxiqouT0YFDHNanHGjMa199L/WYbz XdcdWBCMwihfx6NkG7M2ptWDDsL6Qv4VwX8aNSbSEwTV+QaksQ2lSZKiBhwadfSYT8lL knJlyyj8Mfzp06XpVdV4EgvnMUbaVNS1oi1dP+F0jjksao30Yfe2DQ1VA/05LMcKbOlf gbDictXNum9XdfbUy21qrAAwSvcVZSXCMF2XwJK1Y0Q3+lqgVxy0fihKgfXLjKA/HhbZ zP5A== X-Gm-Message-State: ACrzQf3sUC/3fuPZDu/HyC04qIxHsJGGBNComRSbDObGBqg0E+cVkpdP L4qq/1m29HbAaTZ1h0kzoQEAsIHbqD8= X-Received: from pgonda1.kir.corp.google.com ([2620:0:1008:11:da0c:de35:6ecf:7c48]) (user=pgonda job=sendgmr) by 2002:a05:6a00:1a4d:b0:563:a7c4:f521 with SMTP id h13-20020a056a001a4d00b00563a7c4f521mr49813630pfv.61.1666883163776; Thu, 27 Oct 2022 08:06:03 -0700 (PDT) Date: Thu, 27 Oct 2022 08:05:57 -0700 In-Reply-To: <20221027150558.722062-1-pgonda@google.com> Message-Id: <20221027150558.722062-2-pgonda@google.com> Mime-Version: 1.0 References: <20221027150558.722062-1-pgonda@google.com> X-Mailer: git-send-email 2.38.0.135.g90850a2211-goog Subject: [PATCH V3 1/2] virt: sev: Prevent IV reuse in SNP guest driver From: Peter Gonda To: thomas.lendacky@amd.com Cc: Peter Gonda , Dionna Glaze , Borislav Petkov , Michael Roth , Haowen Bai , Yang Yingliang , Marc Orr , David Rientjes , Ashish Kalra , linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747853848452050542?= X-GMAIL-MSGID: =?utf-8?q?1747853848452050542?= The ASP and an SNP guest use a series of AES-GCM keys called VMPCKs to communicate securely with each other. The IV to this scheme is a sequence number that both the ASP and the guest track. Currently this sequence number in a guest request must exactly match the sequence number tracked by the ASP. This means that if the guest sees an error from the host during a request it can only retry that exact request or disable the VMPCK to prevent an IV reuse. AES-GCM cannot tolerate IV reuse see: https://csrc.nist.gov/csrc/media/projects/block-cipher-techniques/documents/bcm/comments/800-38-series-drafts/gcm/joux_comments.pdf To handle userspace querying the cert_data length. Instead of requesting the cert length from userspace use the size of the drivers allocated shared buffer. Then copy that buffer to userspace, or give userspace an error depending on the size of the buffer given by userspace. Fixes: fce96cf044308 ("virt: Add SEV-SNP guest driver") Signed-off-by: Peter Gonda Reported-by: Peter Gonda Reviewed-by: Dionna Glaze Cc: Borislav Petkov Cc: Tom Lendacky Cc: Michael Roth Cc: Haowen Bai Cc: Yang Yingliang Cc: Marc Orr Cc: David Rientjes Cc: Ashish Kalra Cc: linux-kernel@vger.kernel.org Cc: kvm@vger.kernel.org --- drivers/virt/coco/sev-guest/sev-guest.c | 93 ++++++++++++++++--------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index f422f9c58ba7..8c54ea84bc57 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -41,7 +41,7 @@ struct snp_guest_dev { struct device *dev; struct miscdevice misc; - void *certs_data; + u8 (*certs_data)[SEV_FW_BLOB_MAX_SIZE]; struct snp_guest_crypto *crypto; struct snp_guest_msg *request, *response; struct snp_secrets_page_layout *layout; @@ -67,8 +67,27 @@ static bool is_vmpck_empty(struct snp_guest_dev *snp_dev) return true; } +/* + * If we receive an error from the host or ASP we have two options. We can + * either retry the exact same encrypted request or we can discontinue using the + * VMPCK. + * + * This is because in the current encryption scheme GHCB v2 uses AES-GCM to + * encrypt the requests. The IV for this scheme is the sequence number. GCM + * cannot tolerate IV reuse. + * + * The ASP FW v1.51 only increments the sequence numbers on a successful + * guest<->ASP back and forth and only accepts messages at its exact sequence + * number. + * + * So if we were to reuse the sequence number the encryption scheme is + * vulnerable. If we encrypt the sequence number for a fresh IV the ASP will + * reject our request. + */ static void snp_disable_vmpck(struct snp_guest_dev *snp_dev) { + dev_alert(snp_dev->dev, "Disabling vmpck_id: %d to prevent IV reuse.\n", + vmpck_id); memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN); snp_dev->vmpck = NULL; } @@ -326,29 +345,29 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in if (fw_err) *fw_err = err; - if (rc) - return rc; + if (rc) { + dev_alert(snp_dev->dev, + "Detected error from ASP request. rc: %d, fw_err: %llu\n", + rc, *fw_err); + goto disable_vmpck; + } - /* - * The verify_and_dec_payload() will fail only if the hypervisor is - * actively modifying the message header or corrupting the encrypted payload. - * This hints that hypervisor is acting in a bad faith. Disable the VMPCK so that - * the key cannot be used for any communication. The key is disabled to ensure - * that AES-GCM does not use the same IV while encrypting the request payload. - */ rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz); if (rc) { dev_alert(snp_dev->dev, - "Detected unexpected decode failure, disabling the vmpck_id %d\n", - vmpck_id); - snp_disable_vmpck(snp_dev); - return rc; + "Detected unexpected decode failure from ASP. rc: %d\n", + rc); + goto disable_vmpck; } /* Increment to new message sequence after payload decryption was successful. */ snp_inc_msg_seqno(snp_dev); return 0; + +disable_vmpck: + snp_disable_vmpck(snp_dev); + return rc; } static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) @@ -437,7 +456,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques struct snp_guest_crypto *crypto = snp_dev->crypto; struct snp_ext_report_req req; struct snp_report_resp *resp; - int ret, npages = 0, resp_len; + int ret, resp_len, req_cert_len, resp_cert_len; lockdep_assert_held(&snp_cmd_mutex); @@ -448,14 +467,15 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques return -EFAULT; /* userspace does not want certificate data */ - if (!req.certs_len || !req.certs_address) + req_cert_len = req.certs_len; + if (!req_cert_len || !req.certs_address) goto cmd; - if (req.certs_len > SEV_FW_BLOB_MAX_SIZE || - !IS_ALIGNED(req.certs_len, PAGE_SIZE)) + if (req_cert_len > sizeof(*snp_dev->certs_data) || + !IS_ALIGNED(req_cert_len, PAGE_SIZE)) return -EINVAL; - if (!access_ok((const void __user *)req.certs_address, req.certs_len)) + if (!access_ok((const void __user *)req.certs_address, req_cert_len)) return -EFAULT; /* @@ -464,8 +484,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques * the host. If host does not supply any certs in it, then copy * zeros to indicate that certificate data was not provided. */ - memset(snp_dev->certs_data, 0, req.certs_len); - npages = req.certs_len >> PAGE_SHIFT; + memset(snp_dev->certs_data, 0, sizeof(*snp_dev->certs_data)); cmd: /* * The intermediate response buffer is used while decrypting the @@ -477,25 +496,37 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques if (!resp) return -ENOMEM; - snp_dev->input.data_npages = npages; + snp_dev->input.data_npages = sizeof(*snp_dev->certs_data) >> PAGE_SHIFT; ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg->msg_version, SNP_MSG_REPORT_REQ, &req.data, sizeof(req.data), resp->data, resp_len, &arg->fw_err); + resp_cert_len = snp_dev->input.data_npages << PAGE_SHIFT; + /* If certs length is invalid then copy the returned length */ if (arg->fw_err == SNP_GUEST_REQ_INVALID_LEN) { - req.certs_len = snp_dev->input.data_npages << PAGE_SHIFT; + dev_alert(snp_dev->dev, + "Certificate data from host: %d, Max size allocated by driver: %lu.\n", + resp_cert_len, sizeof(*snp_dev->certs_data)); + ret = -EFAULT; + } + + if (ret) + goto e_free; + + /* Pass the actual certificate data size back to userspace */ + req.certs_len = resp_cert_len; + if (resp_cert_len > req_cert_len) { + arg->fw_err = SNP_GUEST_REQ_INVALID_LEN; if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req))) ret = -EFAULT; - } - if (ret) goto e_free; + } - if (npages && - copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, - req.certs_len)) { + if (copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, + resp_cert_len)) { ret = -EFAULT; goto e_free; } @@ -676,7 +707,7 @@ static int __init sev_guest_probe(struct platform_device *pdev) if (!snp_dev->response) goto e_free_request; - snp_dev->certs_data = alloc_shared_pages(dev, SEV_FW_BLOB_MAX_SIZE); + snp_dev->certs_data = alloc_shared_pages(dev, sizeof(*snp_dev->certs_data)); if (!snp_dev->certs_data) goto e_free_response; @@ -703,7 +734,7 @@ static int __init sev_guest_probe(struct platform_device *pdev) return 0; e_free_cert_data: - free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE); + free_shared_pages(snp_dev->certs_data, sizeof(*snp_dev->certs_data)); e_free_response: free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg)); e_free_request: @@ -717,7 +748,7 @@ static int __exit sev_guest_remove(struct platform_device *pdev) { struct snp_guest_dev *snp_dev = platform_get_drvdata(pdev); - free_shared_pages(snp_dev->certs_data, SEV_FW_BLOB_MAX_SIZE); + free_shared_pages(snp_dev->certs_data, sizeof(*snp_dev->certs_data)); free_shared_pages(snp_dev->response, sizeof(struct snp_guest_msg)); free_shared_pages(snp_dev->request, sizeof(struct snp_guest_msg)); deinit_crypto(snp_dev->crypto); From patchwork Thu Oct 27 15:05:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Gonda X-Patchwork-Id: 11816 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp285340wru; Thu, 27 Oct 2022 08:09:14 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6uKW5igkrpBzOvAZU61ThiX1RyH45raFFSSe3Rr90zxDu2oVpl+4/AdF+6rYyUB2j8+7f2 X-Received: by 2002:a17:907:708:b0:77e:ff47:34b1 with SMTP id xb8-20020a170907070800b0077eff4734b1mr40680828ejb.493.1666883354294; Thu, 27 Oct 2022 08:09:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666883354; cv=none; d=google.com; s=arc-20160816; b=DA9KF/J1d8RezqUKa7/WvqSnCKHKKEprJioA/JPCmQv1jOQaexZNKm48CYqCk55jFd J3Mkhxdky6Edc+W4gPgyl0e36Jb/2H/KElpAFj3UQq/qa3G/AP28pD8BpYGb+vVBcQ7P KkylU5ZEayEadBsZSVnc4j/tM8SrSAb9swU2VVGdnNBLB+NsHNNg1uqPLg1k+cT8fWcu Q1xRJNwIW+BAS78vC33l/wrA64S3Ule3SNjgZPkwf2Fl1POtO/Zls4DO2dnYeoJ2RHGo z1l3A8jYveaYR9NS8WIkVpV2yN1alvuolgJl34eMK4MstVCZxqLJ2pckxVGDBDyUfv2D XDRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=co6QgImvBY6rg4iltv5GQDLPg23wAqLBYYMlaysrcLQ=; b=GU3cgBUwrb5y8H4cewCwPFjjVmcl2ioDOiQD/treZWNDyf+A2JvfNyfY90okg/l2j/ KhgRkEqwrwNKiHhnyykrMBFoTc3yR6Xt/1oy9/5hTxZZv6HTOaD1aplfoWTtY5M+1JMb 2j9+hMh+9/M5SlbpfmpIDOa4xVoGKDbHYWe7UhrVWPkV7kN03gg2dryqfvCWe546rESH JW691lnZMYLsIoWSWvAl5wVQaUWhlPSxMyzjm0EYUQkQUFNIq9s2eUMZMrMuUzNPNWNU TNWrzZ/eqRjkqGeG9o9vpsIk2YkJdYY01/KY0x8hW2MJRoSaVHQq/ko/gzawBdZIdueK nHww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=RKr2mNOD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 27-20020a50875b000000b0045d2c253a61si1759907edv.351.2022.10.27.08.08.43; Thu, 27 Oct 2022 08:09:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=RKr2mNOD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235703AbiJ0PGT (ORCPT + 99 others); Thu, 27 Oct 2022 11:06:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235650AbiJ0PGH (ORCPT ); Thu, 27 Oct 2022 11:06:07 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FBEBDCEB9 for ; Thu, 27 Oct 2022 08:06:06 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-36fc0644f51so15175647b3.17 for ; Thu, 27 Oct 2022 08:06:06 -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:subject:date:message-id:reply-to; bh=co6QgImvBY6rg4iltv5GQDLPg23wAqLBYYMlaysrcLQ=; b=RKr2mNODlbVwgZbH8QfPexb80BB0KK62G47Vn4P9JLluupGBH+f9mnrZWxTXWE+8EQ 6W2sgp5Je3yj/2tgVl/WulUUZTGUx27d7Kkhf74NeinxvMQNG6a9fD+8Ded7sxkFqj39 02sboYXwqP5ihDu2EZum47cC30JOM56VEBtwWCaG6qB4lyVYhMcR2v6WSctPyd5Hkcdw xa9YrtTEhKUl+UJOL462AsY3y2urK/U1cF3g6+JXQDyG1iNXPCYf15h8E9OuMT0kE7+N glt3+SDD5dM++vBlIsdM1rMfcKxND/joOkoFZAYfJJoH0kvdj5H8pGxWJAT1eVFh3Lfa z8rg== 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:subject:date:message-id:reply-to; bh=co6QgImvBY6rg4iltv5GQDLPg23wAqLBYYMlaysrcLQ=; b=Ieus2oAOWAOmZm0jr/OL5EsYPLwc/I2RN48y6aCxzSLqM+7wdbOnOXIzBRAxRz4pKj SYFFG0+HQraNhXacEO4rfeUaeNBKL3AsAmIp4BRfdDmRj6sk6psNjbT/7WDLKWTpk4Hc LEyL+ImYqkSsO9YLHtrZGVVg8p1JsMg1UHmAsHiL2A61tWfgabOAPrtKtcoLsb8M48eE 29l9qmuDCiZMQtZCGSMpVfOEwi2F8mUpeRN70mc73QwtKvUIhNh6lbjPNGr9reWbT1QG Jy5a5rZHtLtE3odGUGiL8g6u8MMgtHOV4xz5nzMjXVs+K535FJJIx8U2iAE6rSmJMh8W RsCQ== X-Gm-Message-State: ACrzQf0rjXGAAoQSjhi5nb2N10KDJdOkPhwDfe9cJyjbAWEuw/QIUuaw eI9gTIN+NMgYPcv+3uewugekFgoev3U= X-Received: from pgonda1.kir.corp.google.com ([2620:0:1008:11:da0c:de35:6ecf:7c48]) (user=pgonda job=sendgmr) by 2002:a25:9885:0:b0:6b3:e9a7:4952 with SMTP id l5-20020a259885000000b006b3e9a74952mr48322400ybo.294.1666883165611; Thu, 27 Oct 2022 08:06:05 -0700 (PDT) Date: Thu, 27 Oct 2022 08:05:58 -0700 In-Reply-To: <20221027150558.722062-1-pgonda@google.com> Message-Id: <20221027150558.722062-3-pgonda@google.com> Mime-Version: 1.0 References: <20221027150558.722062-1-pgonda@google.com> X-Mailer: git-send-email 2.38.0.135.g90850a2211-goog Subject: [PATCH V3 2/2] virt: sev: Allow for retrying SNP extended requests From: Peter Gonda To: thomas.lendacky@amd.com Cc: Peter Gonda , Borislav Petkov , Michael Roth , Haowen Bai , Yang Yingliang , Marc Orr , David Rientjes , Ashish Kalra , linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747853880298897837?= X-GMAIL-MSGID: =?utf-8?q?1747853880298897837?= If an SNP Extended Request is placed without enough data pages the host will return an error to the guest and tell it the number of required data pages. If we place an extended request without enogh data page we can retry the command portion of the request using an SNP Request. This allows us to keep our command sequence numbers with the ASP in sync while also supporting the SNP Extended Request's data size querying capability. This happens inside of snp_issue_guest_request() to keep the safety of the sequence numbers easy. Any failure snp_issue_guest_request() should result in no further of the VMCPK due to issues with the sequence number being the IV in the AES-GCM communication channel. IV reuse, meaning sequence number reuse in this driver, can result in the secure channel being compromised. Signed-off-by: Peter Gonda Cc: Borislav Petkov Cc: Tom Lendacky Cc: Michael Roth Cc: Haowen Bai Cc: Yang Yingliang Cc: Marc Orr Cc: David Rientjes Cc: Ashish Kalra Cc: linux-kernel@vger.kernel.org Cc: kvm@vger.kernel.org --- arch/x86/include/asm/svm.h | 6 ++++++ arch/x86/kernel/sev.c | 28 ++++++++++++++++++++----- drivers/virt/coco/sev-guest/sev-guest.c | 2 +- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 0361626841bc..3886b8ea18ae 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -585,6 +585,12 @@ struct vmcb { (unsigned long *)&ghcb->save.valid_bitmap); \ } \ \ + static __always_inline void ghcb_clear_##field(const struct ghcb *ghcb) \ + { \ + clear_bit(GHCB_BITMAP_IDX(field), \ + (unsigned long *)&ghcb->save.valid_bitmap); \ + } \ + \ static __always_inline u64 ghcb_get_##field(struct ghcb *ghcb) \ { \ return ghcb->save.field; \ diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index a428c62330d3..3f7e2105ef97 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -2213,12 +2213,30 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned goto e_put; if (ghcb->save.sw_exit_info_2) { - /* Number of expected pages are returned in RBX */ + /* For a SNP Extended Request, if the request was placed with + * insufficient data pages. The host will return the number of + * pages required using RBX in the GHCB. We can than retry the + * call as an SNP Request to fulfill the command without getting + * the extended request data. + */ if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST && - ghcb->save.sw_exit_info_2 == SNP_GUEST_REQ_INVALID_LEN) - input->data_npages = ghcb_get_rbx(ghcb); - - *fw_err = ghcb->save.sw_exit_info_2; + ghcb->save.sw_exit_info_2 == SNP_GUEST_REQ_INVALID_LEN) { + int npages = ghcb_get_rbx(ghcb); + + ghcb_clear_rax(ghcb); + ghcb_clear_rbx(ghcb); + + ret = sev_es_ghcb_hv_call(ghcb, &ctxt, + SVM_VMGEXIT_GUEST_REQUEST, + input->req_gpa, + input->resp_gpa); + if (ret) + goto e_put; + + input->data_npages = npages; + *fw_err = SNP_GUEST_REQ_INVALID_LEN; + } else + *fw_err = ghcb->save.sw_exit_info_2; ret = -EIO; } diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index 8c54ea84bc57..ede07c0ec0c3 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -496,7 +496,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques if (!resp) return -ENOMEM; - snp_dev->input.data_npages = sizeof(*snp_dev->certs_data) >> PAGE_SHIFT; + snp_dev->input.data_npages = req_cert_len >> PAGE_SHIFT; ret = handle_guest_request(snp_dev, SVM_VMGEXIT_EXT_GUEST_REQUEST, arg->msg_version, SNP_MSG_REPORT_REQ, &req.data, sizeof(req.data), resp->data, resp_len, &arg->fw_err);