From: "Sami Mujawar" <sami.mujawar@arm.com>
To: <devel@edk2.groups.io>
Cc: Sami Mujawar <sami.mujawar@arm.com>, <ardb+tianocore@kernel.org>,
<quic_llindhol@quicinc.com>, <kraxel@redhat.com>,
<Matteo.Carlini@arm.com>, <Akanksha.Jain2@arm.com>,
<Sibel.Allinson@arm.com>, <nd@arm.com>
Subject: [edk2-devel] [PATCH v2 42/45] ArmVirtPkg: RMM 1.0-eac5 - Attestation token API updates
Date: Fri, 12 Apr 2024 15:33:19 +0100 [thread overview]
Message-ID: <20240412143322.5244-43-sami.mujawar@arm.com> (raw)
In-Reply-To: <20240412143322.5244-1-sami.mujawar@arm.com>
The RMM 1.0-eac3 specification removed the restriction that
attestation token size must not exceed 4KB. Further it also
extended the RSI_ATTESTATION_TOKEN_CONTINUE command so as to
return up to a granule worth of the attestation token data.
The RMM 1.0-eac5 specification simplified the attestation
token interfaces such that, the RSI_ATTESTATION_TOKEN_INIT
command returns the upper bound of the attestation token
size. This eliminates the need for relocation of token data
buffers during attestation token retrieval.
Therefore, implement the attestation token API updates
from RMM 1.0-eac3 through to RMM 1.0-eac5 specification.
Note: The RsiGetAttestationToken() API has been modified
such that ArmCcaRsiLib allocates memory for the returned
attestation token buffer. The caller is therefore required
to call RsiFreeAttestationToken() to free the memory that
was allocated for the attestation token buffer.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
ArmVirtPkg/Include/Library/ArmCcaRsiLib.h | 31 ++--
ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c | 160 +++++++++++++++-----
2 files changed, 146 insertions(+), 45 deletions(-)
diff --git a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
index 8c1c0d5bc19d14fa640464c8d0d44e3ef522ba79..b768f3498314a2ea61762af65bf2668d463909a6 100644
--- a/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
+++ b/ArmVirtPkg/Include/Library/ArmCcaRsiLib.h
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac4
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac5
(https://developer.arm.com/documentation/den0137/)
**/
@@ -33,11 +33,6 @@
*/
#define RIPAS_TYPE_MASK 0xFF
-/* Maximum attestation token size
- RBXKKY The size of an attestation token is no larger than 4KB.
-*/
-#define MAX_ATTESTATION_TOKEN_SIZE SIZE_4KB
-
/* Maximum challenge data size in bits.
*/
#define MAX_CHALLENGE_DATA_SIZE_BITS 512
@@ -185,9 +180,10 @@ typedef struct HostCallArgs {
@param [in] ChallengeDataSizeBits Size of the challenge data in bits.
@param [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
- @param [in, out] TokenBufferSize Size of the token buffer on input and
- number of bytes stored in token buffer
- on return.
+ @param [out] TokenBufferSize Length of token data returned.
+
+ Note: The TokenBuffer allocated must be freed by the caller
+ using RsiFreeAttestationToken().
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -202,8 +198,21 @@ EFIAPI
RsiGetAttestationToken (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
- OUT UINT8 *CONST TokenBuffer,
- IN OUT UINT64 *CONST TokenBufferSize
+ OUT UINT8 **CONST TokenBuffer,
+ OUT UINT64 *CONST TokenBufferSize
+ );
+
+/**
+ Free the attestation token buffer.
+
+ @param [in] TokenBuffer Pointer to the retrieved
+ attestation token.
+ @param [in] TokenBufferSize Size of the token buffer.
+**/
+VOID
+RsiFreeAttestationToken (
+ IN UINT8 *CONST TokenBuffer,
+ IN UINT64 CONST TokenBufferSize
);
/**
diff --git a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
index edd2e11f786d11191f13dd9b087cdeec4127b375..b861b2e79d5d659a0eb16206d329a0cb039eda0d 100644
--- a/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
+++ b/ArmVirtPkg/Library/ArmCcaRsiLib/ArmCcaRsiLib.c
@@ -11,7 +11,7 @@
- REM - Realm Extensible Measurement
@par Reference(s):
- - Realm Management Monitor (RMM) Specification, version 1.0-eac4
+ - Realm Management Monitor (RMM) Specification, version 1.0-eac5
(https://developer.arm.com/documentation/den0137/)
**/
@@ -22,6 +22,7 @@
#include <Library/ArmSmcLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
#include "ArmCcaRsi.h"
/**
@@ -88,6 +89,8 @@ AddrIsGranuleAligned (
@param [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
+ @param [in] Offset Offset within Token buffer granule
+ to start of buffer in bytes.
@param [in,out] TokenSize On input size of the token buffer,
and on output size of the token
returned if operation is successful,
@@ -106,6 +109,7 @@ RETURN_STATUS
EFIAPI
RsiAttestationTokenContinue (
OUT UINT8 *CONST TokenBuffer,
+ IN UINT64 CONST Offset,
IN OUT UINT64 *CONST TokenSize
)
{
@@ -116,6 +120,10 @@ RsiAttestationTokenContinue (
SmcCmd.Arg0 = FID_RSI_ATTESTATION_TOKEN_CONTINUE;
// Set the IPA of the Granule to which the token will be written.
SmcCmd.Arg1 = (UINTN)TokenBuffer;
+ // Set the Offset within Granule to start of buffer in bytes
+ SmcCmd.Arg2 = (UINTN)Offset;
+ // Set the size of the buffer in bytes
+ SmcCmd.Arg3 = (UINTN)*TokenSize;
ArmCallSmc (&SmcCmd);
Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
@@ -137,8 +145,8 @@ RsiAttestationTokenContinue (
@param [in] ChallengeData Pointer to the challenge data to be
included in the attestation token.
@param [in] ChallengeDataSizeBits Size of the challenge data in bits.
- @param [in] TokenBuffer Pointer to a buffer to store the
- retrieved attestation token.
+ @param [out] MaxTokenSize Pointer to an integer to retrieve
+ the maximum attestation token size.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -149,14 +157,15 @@ EFIAPI
RsiAttestationTokenInit (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
- IN UINT8 *CONST TokenBuffer
+ OUT UINT64 *CONST MaxTokenSize
)
{
- ARM_SMC_ARGS SmcCmd;
- UINT8 *Buffer8;
- CONST UINT8 *Data8;
- UINT64 Count;
- UINT8 TailBits;
+ RETURN_STATUS Status;
+ ARM_SMC_ARGS SmcCmd;
+ UINT8 *Buffer8;
+ CONST UINT8 *Data8;
+ UINT64 Count;
+ UINT8 TailBits;
/* See A7.2.2 Attestation token generation, RMM Specification, version A-bet0
IWTKDD - If the size of the challenge provided by the relying party is less
@@ -168,11 +177,8 @@ RsiAttestationTokenInit (
*/
ZeroMem (&SmcCmd, sizeof (SmcCmd));
SmcCmd.Arg0 = FID_RSI_ATTESTATION_TOKEN_INIT;
- // Set the IPA of the Granule to which the token will be written.
- SmcCmd.Arg1 = (UINTN)TokenBuffer;
-
// Copy challenge data.
- Buffer8 = (UINT8 *)&SmcCmd.Arg2;
+ Buffer8 = (UINT8 *)&SmcCmd.Arg1;
Data8 = ChallengeData;
// First copy whole bytes
@@ -194,7 +200,38 @@ RsiAttestationTokenInit (
}
ArmCallSmc (&SmcCmd);
- return RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+ Status = RsiCmdStatusToEfiStatus (SmcCmd.Arg0);
+ if (RETURN_ERROR (Status)) {
+ // Set the max token size to zero
+ *MaxTokenSize = 0;
+ } else {
+ *MaxTokenSize = SmcCmd.Arg1;
+ }
+
+ return Status;
+}
+
+/**
+ Free the attestation token buffer.
+
+ @param [in] TokenBuffer Pointer to the retrieved
+ attestation token.
+ @param [in] TokenBufferSize Size of the token buffer.
+**/
+VOID
+RsiFreeAttestationToken (
+ IN UINT8 *CONST TokenBuffer,
+ IN UINT64 CONST TokenBufferSize
+ )
+{
+ if (TokenBuffer != NULL) {
+ if (TokenBufferSize > 0) {
+ // Scrub the token buffer
+ ZeroMem (TokenBuffer, TokenBufferSize);
+ }
+
+ FreePool (TokenBuffer);
+ }
}
/**
@@ -205,9 +242,10 @@ RsiAttestationTokenInit (
@param [in] ChallengeDataSizeBits Size of the challenge data in bits.
@param [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
- @param [in, out] TokenBufferSize Size of the token buffer on input and
- number of bytes stored in token buffer
- on return.
+ @param [out] TokenBufferSize Length of token data returned.
+
+ Note: The TokenBuffer allocated must be freed by the caller
+ using RsiFreeAttestationToken().
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@@ -222,11 +260,17 @@ EFIAPI
RsiGetAttestationToken (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
- OUT UINT8 *CONST TokenBuffer,
- IN OUT UINT64 *CONST TokenBufferSize
+ OUT UINT8 **CONST TokenBuffer,
+ OUT UINT64 *CONST TokenBufferSize
)
{
RETURN_STATUS Status;
+ UINT8 *Granule;
+ UINT64 GranuleSize;
+ UINT64 Offset;
+ UINT8 *Token;
+ UINT64 TokenSize;
+ UINT64 MaxTokenSize;
if ((TokenBuffer == NULL) ||
(TokenBufferSize == NULL) ||
@@ -235,16 +279,6 @@ RsiGetAttestationToken (
return RETURN_INVALID_PARAMETER;
}
- if (*TokenBufferSize < MAX_ATTESTATION_TOKEN_SIZE) {
- *TokenBufferSize = MAX_ATTESTATION_TOKEN_SIZE;
- return RETURN_BAD_BUFFER_SIZE;
- }
-
- if (!AddrIsGranuleAligned ((UINT64 *)TokenBuffer)) {
- DEBUG ((DEBUG_ERROR, "ERROR : Token buffer not granule aligned\n"));
- return RETURN_INVALID_PARAMETER;
- }
-
if (ChallengeDataSizeBits > MAX_CHALLENGE_DATA_SIZE_BITS) {
return RETURN_INVALID_PARAMETER;
}
@@ -260,18 +294,76 @@ RsiGetAttestationToken (
Status = RsiAttestationTokenInit (
ChallengeData,
ChallengeDataSizeBits,
- TokenBuffer
+ &MaxTokenSize
);
if (RETURN_ERROR (Status)) {
ASSERT (0);
return Status;
}
- /* Loop until the token is ready or there is an error.
- */
+ // Allocate a granule to retrieve the attestation token chunk.
+ Granule = (UINT8 *)AllocateAlignedPages (
+ EFI_SIZE_TO_PAGES (REALM_GRANULE_SIZE),
+ REALM_GRANULE_SIZE
+ );
+ if (Granule == NULL) {
+ ASSERT (0);
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ // Alloate a buffer to store the retrieved attestation token.
+ Token = AllocateZeroPool (MaxTokenSize);
+ if (Token == NULL) {
+ ASSERT (0);
+ Status = RETURN_OUT_OF_RESOURCES;
+ goto exit_handler;
+ }
+
+ TokenSize = 0;
do {
- Status = RsiAttestationTokenContinue (TokenBuffer, TokenBufferSize);
- } while (Status == RETURN_NOT_READY);
+ // Retrieve one Granule of data per loop iteration
+ ZeroMem (Granule, REALM_GRANULE_SIZE);
+ Offset = 0;
+ do {
+ // Retrieve sub-Granule chunk of data per loop iteration
+ GranuleSize = REALM_GRANULE_SIZE - Offset;
+ Status = RsiAttestationTokenContinue (
+ Granule,
+ Offset,
+ &GranuleSize
+ );
+ Offset += GranuleSize;
+ } while ((Status == RETURN_NOT_READY) && (Offset < REALM_GRANULE_SIZE));
+
+ if (RETURN_ERROR (Status) && (Status != RETURN_NOT_READY)) {
+ ASSERT (0);
+ goto exit_handler1;
+ }
+
+ // "Offset" bytes of data are now ready for consumption from "Granule"
+ // Copy the new token data from the Granule.
+ CopyMem (&Token[TokenSize], Granule, Offset);
+ TokenSize += Offset;
+ } while ((Status == RETURN_NOT_READY) && (TokenSize < MaxTokenSize));
+
+ *TokenBuffer = Token;
+ *TokenBufferSize = TokenSize;
+ goto exit_handler;
+
+exit_handler1:
+ if (Token != NULL) {
+ // Scrub the old Token
+ ZeroMem (Token, TokenSize);
+ FreePool (Token);
+ }
+
+ *TokenBuffer = NULL;
+ *TokenBufferSize = 0;
+
+exit_handler:
+ // Scrub the Granule buffer
+ ZeroMem (Granule, REALM_GRANULE_SIZE);
+ FreePages (Granule, EFI_SIZE_TO_PAGES (REALM_GRANULE_SIZE));
return Status;
}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117706): https://edk2.groups.io/g/devel/message/117706
Mute This Topic: https://groups.io/mt/105483450/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
prev parent reply other threads:[~2024-04-12 14:34 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20240412143322.5244-1-sami.mujawar@arm.com>
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 01/45] ArmPkg: Add helper function to detect RME Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 02/45] ArmPkg: Introduce SetMemoryProtectionAttribute() for Realms Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 03/45] ArmPkg: Extend number of parameter registers in SMC call Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 04/45] ArmVirtPkg: Add Arm CCA Realm Service Interface Library Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 05/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to manage the Realm IPA state Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 06/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to get an attestation token Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 07/45] ArmVirtPkg: ArmCcaRsiLib: Add interfaces to get/extend REMs Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 08/45] ArmVirtPkg: ArmCcaRsiLib: Add an interface to make a RSI Host Call Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 09/45] ArmVirtPkg: Define a GUID HOB for IPA width of a Realm Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 10/45] ArmVirtPkg: Add library for Arm CCA initialisation in PEI Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 11/45] ArmVirtPkg: Add NULL instance of ArmCcaInitPeiLib Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 12/45] ArmVirtPkg: Add library for Arm CCA helper functions Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 13/45] ArmVirtPkg: Add Null instance of ArmCcaLib Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 14/45] ArmVirtPkg: Define an interface to configure MMIO regions for Arm CCA Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 15/45] ArmVirtPkg: CloudHv: Add a NULL implementation of ArmCcaConfigureMmio Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 16/45] ArmVirtPkg: Qemu: " Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 17/45] ArmVirtPkg: Xen: " Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 18/45] ArmVirtPkg: Configure the MMIO regions for Arm CCA Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 19/45] ArmVirtPkg: Kvmtool: Use Null version of DebugLib in PrePi Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 20/45] ArmVirtPkg: Introduce ArmVirtMonitorLib library Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 21/45] ArmVirtPkg: Kvmtool: Use ArmVirt instance of ArmMonitorLib Sami Mujawar
2024-04-12 14:32 ` [edk2-devel] [PATCH v2 22/45] ArmVirtPkg: Add Arm CCA libraries for Kvmtool guest firmware Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 23/45] ArmVirtPkg: Arm CCA configure system memory in early Pei Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 24/45] ArmVirtPkg: Perform Arm CCA initialisation in the Pei phase Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 25/45] ArmVirtPkg: Introduce Realm Aperture Management Protocol Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 26/45] ArmVirtPkg: IoMMU driver to DMA from Realms Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 27/45] ArmVirtPkg: Enable Virtio communication for Arm CCA Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 28/45] MdePkg: Warn if AArch64 RNDR instruction is not supported Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 29/45] ArmVirtPkg: Kvmtool: Switch to use BaseRng for AArch64 Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 31/45] ArmVirtPkg: ArmCcaRsiLib: Fix size of Imm field in HostCallArgs Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 32/45] ArmVirtPkg: RMM 1.0-bet1 - Update width of RSI host call struct Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 33/45] ArmVirtPkg: RMM 1.0-bet2 - Increase number of RSI host call args Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 34/45] ArmVirtPkg: RMM 1.0-eac0 - Update RsiSetIpaState parameter usage Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 35/45] ArmVirtPkg: RMM 1.0-eac1 - Relax alignment of RSI host call arg Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 36/45] ArmVirtPkg: RMM 1.0-eac2 - Update RsiRealmConfig structure Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 37/45] ArmVirtPkg: RMM 1.0-eac2 - Add RIPAS DESTROYED state Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 38/45] ArmVirtPkg: RMM 1.0-eac2 - Add RsiRipasChangeFlags definitions Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 39/45] ArmVirtPkg: RMM 1.0-eac2 - Add Flags to RsiSetIpaState() Sami Mujawar
2024-04-12 14:33 ` [edk2-devel] [PATCH v2 40/45] ArmVirtPkg: RMM 1.0-eac3 - Handle RsiSetIpaState() response Sami Mujawar
2024-04-12 14:33 ` Sami Mujawar [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240412143322.5244-43-sami.mujawar@arm.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox