From patchwork Thu May 11 07:23:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khalid Elmously X-Patchwork-Id: 1779793 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=OPpyD1WE; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QH3Lw3LYFz20fn for ; Thu, 11 May 2023 17:24:55 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1px0fN-0002Iy-6p; Thu, 11 May 2023 07:24:45 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1px0fK-0002II-5S for kernel-team@lists.ubuntu.com; Thu, 11 May 2023 07:24:42 +0000 Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 608AA3F32E for ; Thu, 11 May 2023 07:24:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1683789881; bh=CnzFRZeV5WJTv9BPHZhWAA89kqp3s7xwlB76w56phVc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OPpyD1WEoWB/toTk0Vy42DWRMsJ6RAWMHyMoxqMjg78nW2ITd1+fZNmF/4u/VIbCP H65arfJ0Q2PoMKTa+/M8P8LLa0HhJ86Irn2S028X3ndS/7Ky666xHe2Y5/FNbJqP9G 7PqIwKHBk63zRi55FhyNSNOJI8pjiri3/NF3L9nI0F2vosGDcXWfF46CrwcnmhyeVS Pb0dn1bVuCQvw0gOsuhWEeQz9+msjhtocfN39kk0Nu0dZ+Vn+E+DmcCxRiwAfZfY5n koq+EBG/HrmyvAZ7HNetjnJPmBkaAj3btlejTPxP4SIPNX3XhB3ujRw9iPCF/cjEnD FOn8S5Yn/yvGA== Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-3f3c9860201so13951601cf.0 for ; Thu, 11 May 2023 00:24:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683789880; x=1686381880; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CnzFRZeV5WJTv9BPHZhWAA89kqp3s7xwlB76w56phVc=; b=fsjYlJweChb5f4h5SAHI58x8LeNJhnLvE3t14vYdB3vQQAyhA6QVECZEZ1gMjifePZ L3Fmj8mt5c/yDeHinyMFzF55gBeokM+RJB7rlXQYeatXIIS84/Xly+r7nKdqMsBfY+69 10qg+pnmfVM21MTjTqn0+QQFTMfG8Z7cMDgyeKhV+cHYy2R6HllIhvLunXKlSkOr2oJ8 tYXoy5ykndXJR2/eVLK9m247MpVs7rBG4BA5oAGhfFvRJ92sY2rzzQYb23z2eMsnZ3/+ zJwGUWKYmiADdruaVBWXloI5EIFdylEh/FxarLVuOeUIkblNfrDOS/dpq2VFRTnKhemp smrA== X-Gm-Message-State: AC+VfDxUCTMCe7kF58fV6yPn/TBD4JcoKt5K2QSNj1sQn2ervQuSbeFO M6yxqIrdTkvj0DWdB4l7vhcYc9XZV4SdjHGXPBhjxKCo0XJg4mVKK76/OwWKBoq1zmtokGY2vAi yfm+T2pwoqDM14oTfN6dYz6guhAbQUniyYPJoF5WHjS/7F/HByhF8 X-Received: by 2002:ac8:5dcd:0:b0:3f4:c236:2eac with SMTP id e13-20020ac85dcd000000b003f4c2362eacmr6747321qtx.3.1683789880091; Thu, 11 May 2023 00:24:40 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7dZ6emIvZmN/nugvbFZZ1D7cJDndt0wFBaaI9xW+dyY7iOjAm1rY5CLHHHJ/FJxegf4nCF2w== X-Received: by 2002:ac8:5dcd:0:b0:3f4:c236:2eac with SMTP id e13-20020ac85dcd000000b003f4c2362eacmr6747310qtx.3.1683789879771; Thu, 11 May 2023 00:24:39 -0700 (PDT) Received: from k2.fuzzbuzz.org ([38.147.253.170]) by smtp.gmail.com with ESMTPSA id x27-20020ac8701b000000b003ef5ba0702fsm2053475qtm.7.2023.05.11.00.24.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 May 2023 00:24:39 -0700 (PDT) From: Khalid Elmously To: kernel-team@lists.ubuntu.com Subject: [SRU][v2][j/gcp][PATCH 1/2] virt/sev-guest: Prevent IV reuse in the SNP guest driver Date: Thu, 11 May 2023 03:23:55 -0400 Message-Id: <20230511072357.1165970-2-khalid.elmously@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230511072357.1165970-1-khalid.elmously@canonical.com> References: <20230511072357.1165970-1-khalid.elmously@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Peter Gonda BugLink: https://bugs.launchpad.net/bugs/2013198 The AMD Secure Processor (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: "Authentication Failures in NIST version of GCM" - Antoine Joux et al. In order to address this, make handle_guest_request() delete the VMPCK on any non successful return. To allow userspace querying the cert_data length make handle_guest_request() save the number of pages required by the host, then have handle_guest_request() retry the request without requesting the extended data, then return the number of pages required back to userspace. [ bp: Massage, incorporate Tom's review comments. ] Fixes: fce96cf044308 ("virt: Add SEV-SNP guest driver") Reported-by: Peter Gonda Signed-off-by: Peter Gonda Signed-off-by: Borislav Petkov Reviewed-by: Tom Lendacky Cc: stable@kernel.org Link: https://lore.kernel.org/r/20221116175558.2373112-1-pgonda@google.com (cherry picked from commit 47894e0fa6a56a42be6a47c767e79cce8125489d) Signed-off-by: Khalid Elmously --- drivers/virt/coco/sevguest/sevguest.c | 84 ++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/drivers/virt/coco/sevguest/sevguest.c b/drivers/virt/coco/sevguest/sevguest.c index b840cf426f38a..f7991bc920e4d 100644 --- a/drivers/virt/coco/sevguest/sevguest.c +++ b/drivers/virt/coco/sevguest/sevguest.c @@ -67,8 +67,27 @@ static bool is_vmpck_empty(struct snp_guest_dev *snp_dev) return true; } +/* + * If an error is received from the host or AMD Secure Processor (ASP) there + * are two options. Either retry the exact same encrypted request or 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 the sequence number were to be reused the encryption scheme is + * vulnerable. If the sequence number were incremented for a fresh IV the ASP + * will reject the 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; } @@ -321,34 +340,71 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in if (rc) return rc; - /* Call firmware to process the request */ + /* + * Call firmware to process the request. In this function the encrypted + * message enters shared memory with the host. So after this call the + * sequence number must be incremented or the VMPCK must be deleted to + * prevent reuse of the IV. + */ rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); + + /* + * If the extended guest request fails due to having too small of a + * certificate data buffer, retry the same guest request without the + * extended data request in order to increment the sequence number + * and thus avoid IV reuse. + */ + if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST && + err == SNP_GUEST_REQ_INVALID_LEN) { + const unsigned int certs_npages = snp_dev->input.data_npages; + + exit_code = SVM_VMGEXIT_GUEST_REQUEST; + + /* + * If this call to the firmware succeeds, the sequence number can + * be incremented allowing for continued use of the VMPCK. If + * there is an error reflected in the return value, this value + * is checked further down and the result will be the deletion + * of the VMPCK and the error code being propagated back to the + * user as an ioctl() return code. + */ + rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err); + + /* + * Override the error to inform callers the given extended + * request buffer size was too small and give the caller the + * required buffer size. + */ + err = SNP_GUEST_REQ_INVALID_LEN; + snp_dev->input.data_npages = certs_npages; + } + 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)