blob: 635f51a04277d5622efdd4f1fc37701ca2fd7672 [file]
/** @file
Library that implements the Arm CCA Realm Service Interface calls.
Copyright (c) 2022 - 2024, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
- Rsi or RSI - Realm Service Interface
- IPA - Intermediate Physical Address
- RIPAS - Realm IPA state
- RIM - Realm Initial Measurement
- REM - Realm Extensible Measurement
@par Reference(s):
- Realm Management Monitor (RMM) Specification, version 1.0-rel0
(https://developer.arm.com/documentation/den0137/)
**/
#pragma once
#include <Base.h>
/**
A macro defining the size of a Realm Granule.
See Section A2.2, RMM Specification, version 1.0-rel0
DNBXXX A Granule is a unit of physical memory whose size is 4KB.
*/
#define ARM_CCA_REALM_GRANULE_SIZE SIZE_4KB
/**
A macro defining the mask for the RSI RIPAS type.
See Section B4.4.7 RsiRipas type, RMM Specification, version 1.0-rel0.
*/
#define ARM_CCA_RIPAS_TYPE_MASK 0xFF
/* Maximum challenge data size in bits.
*/
#define ARM_CCA_MAX_CHALLENGE_DATA_SIZE_BITS 512
/* Minimum recommended challenge data size in bits.
*/
#define ARM_CCA_MIN_CHALLENGE_DATA_SIZE_BITS 256
/* Maximum measurement data size in bytes.
See Section C1.17 RmmRealmMeasurement type, RMM Specification, version 1.0-rel0
The width of the RmmRealmMeasurement type is 512 bits.
*/
#define ARM_CCA_MAX_MEASUREMENT_DATA_SIZE_BYTES 64
/* Minimum and Maximum indices for REMs
See Section A2.1.3 Realm attributes, RMM Specification, version 1.0-rel0
IFMPYL - Attributes of a Realm include an array of measurement values. The
first entry in this array is a RIM. The remaining entries in this array are
REMs.
*/
#define ARM_CCA_MIN_REM_INDEX 1
#define ARM_CCA_MAX_REM_INDEX 4
/* The values of the RsiHashAlgorithm enumeration.
SHA-256 (Secure Hash Standard (SHS))
*/
#define ARM_CCA_RSI_HASH_SHA_256 0
/* The values of the RsiHashAlgorithm enumeration.
SHA-512 (Secure Hash Standard (SHS))
*/
#define ARM_CCA_RSI_HASH_SHA_512 1
/* The RsiRipasChangeFlags fieldset contains flags provided by
the Realm when requesting a RIPAS change.
See section B5.4.9 RsiRipasChangeFlags type in the
RMM Specification, version 1.0-rel0.
The following macros prefixed RIPAS_CHANGE_FLAGS_xxx
define the values of the RsiRipasChangeFlags fieldset.
*/
/* A RIPAS change from DESTROYED should not be permitted.
See section B4.4.8 RsiRipasChangeDestroyed type in the
RMM Specification, version 1.0-rel0
*/
#define ARM_CCA_RIPAS_CHANGE_FLAGS_RSI_NO_CHANGE_DESTROYED 0
/* A RIPAS change from DESTROYED should be permitted.
See section B4.4.8 RsiRipasChangeDestroyed type in the
RMM Specification, version 1.0-rel0
*/
#define ARM_CCA_RIPAS_CHANGE_FLAGS_RSI_CHANGE_DESTROYED 1
/* The RsiResponse type is a value returned by the
RSI_IPA_STATE_SET command and represents whether
the Host accepted or rejected a Realm request.
See section B5.4.6 RsiResponse type in the
RMM Specification, version 1.0-rel0.
The width of the RsiResponse enumeration is 1 bit
and the following macros prefixed RIPAS_CHANGE_RESPONSE_xxx
define the values of the RsiResponse type.
*/
/* The RIPAS change request to RAM was accepted
by the host.
*/
#define ARM_CCA_RIPAS_CHANGE_RESPONSE_ACCEPT 0
/* The RIPAS change request to RAM was rejected
by the host.
*/
#define ARM_CCA_RIPAS_CHANGE_RESPONSE_REJECT 1
/* A mask for the RSI Response bit */
#define ARM_CCA_RSI_RESPONSE_MASK BIT0
/** An enum describing the RSI RIPAS.
See Section A5.2.2 Realm IPA state, RMM Specification, version 1.0-rel0
*/
typedef enum ArmCcaRipas {
RipasEmpty, ///< Unused IPA location.
RipasRam, ///< Private code or data owned by the Realm.
RipasDestroyed, ///< An address which is inaccessible to the Realm.
RipasDev, ///< MMIO address where an assigned Realm device is mapped.
RipasMax ///< A valid RIPAS type value is less than RipasMax.
} ARM_CCA_RIPAS;
/* The maximum length of the Realm Personalisation Value (RPV).
*/
#define ARM_CCA_REALM_CFG_RPV_SIZE 64
/* The size of the Realm Config is 4KB.
*/
#define ARM_CCA_REALM_CFG_SIZE SIZE_4KB
/* Helper macros to define the RealmConfig structure.
*/
#define ARM_CCA_REALM_CFG_OFFSET_IPA_WIDTH 0
#define ARM_CCA_REALM_CFG_OFFSET_HASH_ALGO (ARM_CCA_REALM_CFG_OFFSET_IPA_WIDTH + sizeof (UINT64))
#define ARM_CCA_REALM_CFG_OFFSET_RESERVED (ARM_CCA_REALM_CFG_OFFSET_HASH_ALGO + sizeof (UINT8))
#define ARM_CCA_REALM_CFG_OFFSET_RPV 0x200
#define ARM_CCA_REALM_CFG_OFFSET_RESERVED1 (ARM_CCA_REALM_CFG_OFFSET_RPV + ARM_CCA_REALM_CFG_RPV_SIZE)
/* The maximum size of the RsiHostCallArgs structure.
*/
#define ARM_CCA_RSI_HOST_CALL_ARGS_SIZE 0x100
#pragma pack(1)
/** A structure describing the Realm Configuration.
See Section B5.4.5 RsiRealmConfig type, RMM Specification, version 1.0-rel0
The width of the RsiRealmConfig structure is 4096 (0x1000) bytes.
*/
typedef struct ArmCcaRealmConfig {
/// Width of IPA in bits.
UINT64 IpaWidth;
/// Width of the RsiHashAlgorithm enumeration is 8 bits.
UINT8 HashAlgorithm;
/// Reserved
UINT8 Reserved[ARM_CCA_REALM_CFG_OFFSET_RPV - ARM_CCA_REALM_CFG_OFFSET_RESERVED];
/// Realm Personalisation Value
UINT8 Rpv[ARM_CCA_REALM_CFG_RPV_SIZE];
/// Unused bits of the RsiRealmConfig structure should be zero.
UINT8 Reserved1[ARM_CCA_REALM_CFG_SIZE - ARM_CCA_REALM_CFG_OFFSET_RESERVED1];
} ARM_CCA_REALM_CONFIG;
/** A structure describing the Host Call arguments
See Section 5.4.3 RsiHostCall type, RMM Specification, version 1.0-rel0
*/
typedef struct ArmCcaRsiHostCallArgs {
UINT16 Imm;
UINT8 Reserved1[6];
UINT64 Gprs0;
UINT64 Gprs1;
UINT64 Gprs2;
UINT64 Gprs3;
UINT64 Gprs4;
UINT64 Gprs5;
UINT64 Gprs6;
UINT64 Gprs7;
UINT64 Gprs8;
UINT64 Gprs9;
UINT64 Gprs10;
UINT64 Gprs11;
UINT64 Gprs12;
UINT64 Gprs13;
UINT64 Gprs14;
UINT64 Gprs15;
UINT64 Gprs16;
UINT64 Gprs17;
UINT64 Gprs18;
UINT64 Gprs19;
UINT64 Gprs20;
UINT64 Gprs21;
UINT64 Gprs22;
UINT64 Gprs23;
UINT64 Gprs24;
UINT64 Gprs25;
UINT64 Gprs26;
UINT64 Gprs27;
UINT64 Gprs28;
UINT64 Gprs29;
UINT64 Gprs30;
} ARM_CCA_RSI_HOST_CALL_ARGS;
#pragma pack()
/**
Retrieve an attestation token from the RMM.
@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 [out] TokenBuffer Pointer to a buffer to store the
retrieved attestation token.
@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.
@retval RETURN_OUT_OF_RESOURCES Out of resources.
@retval RETURN_ABORTED The operation was aborted as the state
of the Realm or REC does not match the
state expected by the command.
Or the Token generation failed for an
unknown or IMPDEF reason.
@retval RETURN_NOT_READY The operation requested by the command
is not complete.
@retval RETURN_BAD_BUFFER_SIZE The token buffer size returned in an
earlier call to RSI_ATTESTATION_TOKEN_INIT
was insufficient to complete the operation.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiGetAttestationToken (
IN CONST UINT8 *CONST ChallengeData,
IN UINT64 ChallengeDataSizeBits,
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
ArmCcaRsiFreeAttestationToken (
IN UINT8 *CONST TokenBuffer,
IN UINT64 CONST TokenBufferSize
);
/**
Returns the IPA state for the page pointed by the address.
@param [in] Base Base of target IPA region.
@param [in, out] Top End of target IPA region on input.
Top of IPA region which has the
reported RIPAS value on return.
@param [out] State The RIPAS state for the address specified.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiGetIpaState (
IN UINT64 *Base,
IN OUT UINT64 **Top,
OUT ARM_CCA_RIPAS *State
);
/**
Sets the IPA state for the pages pointed by the memory range.
@param [in] Address Address to the start of the memory range.
@param [in] Size Length of the memory range.
@param [in] State The RIPAS state to be configured.
@param [in] Flags The RIPAS change flags.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
@retval RETURN_ACCESS_DENIED RIPAS change request was rejected.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiSetIpaState (
IN UINT64 *Address,
IN UINT64 Size,
IN ARM_CCA_RIPAS State,
IN UINT64 Flags
);
/**
Extends a measurement to a REM.
@param [in] MeasurementIndex Index of the REM.
@param [in] Measurement Pointer to the measurement buffer.
@param [in] MeasurementSize Size of the measurement data.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiExtendMeasurement (
IN UINTN MeasurementIndex,
IN CONST UINT8 *CONST Measurement,
IN UINTN MeasurementSize
);
/**
Read the measurement value from a REM.
@param [in] MeasurementIndex Index of the REM.
@param [out] MeasurementBuffer Pointer to store the measurement data.
@param [in] MeasurementBufferSize Size of the measurement buffer.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiReadMeasurement (
IN UINTN MeasurementIndex,
OUT UINT8 *CONST MeasurementBuffer,
IN UINTN MeasurementBufferSize
);
/**
Read the Realm Configuration.
@param [out] Config Pointer to the address of the buffer to retrieve
the Realm configuration.
Note: The buffer to retrieve the Realm configuration must be aligned to the
Realm granule size.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiGetRealmConfig (
IN ARM_CCA_REALM_CONFIG *Config
);
/**
Make a Host Call.
A Host call can be used by a Realm to make a hypercall.
On Realm execution of HVC, an Unknown exception is taken to the Realm.
@param [in] Args Pointer to the IPA of the Host call data
structure.
Note: The IPA of the Host call arguments data structure must be aligned
to the Realm granule size.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiHostCall (
IN ARM_CCA_RSI_HOST_CALL_ARGS *Args
);
/**
Get the version of the RSI implementation.
@param [out] UefiImpl The version of the RSI specification
implemented by the UEFI firmware.
@param [out] RmmImplLow The low version of the RSI specification
implemented by the RMM.
@param [out] RmmImplHigh The high version of the RSI specification
implemented by the RMM.
@retval RETURN_SUCCESS Success.
@retval RETURN_UNSUPPORTED The execution context is not a Realm.
@retval RETURN_INCOMPATIBLE_VERSION The Firmware and RMM specification
revisions are not compatible.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiGetVersion (
OUT UINT32 *CONST UefiImpl,
OUT UINT32 *CONST RmmImplLow,
OUT UINT32 *CONST RmmImplHigh
);
/**
Get the features supported by the RSI implementation.
RMM implementations across different CCA platforms may support
disparate features and may offer disparate configuration options
for Realms. The features supported by an RSI implementation are
discovered by reading feature pseudo-register values using the
RSI_FEATURES command.
@param [in] FeatureRegIndex The Feature Register Index.
@param [out] FeatureRegValue The Feature Register Value.
@retval RETURN_SUCCESS Success.
@retval RETURN_INVALID_PARAMETER A parameter is invalid.
**/
RETURN_STATUS
EFIAPI
ArmCcaRsiGetFeatures (
IN UINT64 FeatureRegIndex,
OUT UINT64 *FeatureRegValue
);