From: Jan Kiszka <[email protected]> In contrast to real eMMCs, we are not (yet) persisting the full state of the device. This particularly includes the authentication key used for RPMB access, complicating testing of firmware images which do not support initial provisioning of the key.
One way to address this would be, e.g., extending the eMMC disk image with a special sector to store further state. A simpler approach is used here: Add another device property that allows to specify the authentication key, bringing up the eMMC as if the key has already been provisioned before. This is how to tell qemu to use the OP-TEE test key: -device emmc,[...],auth-key=D3EB3EC36E334C9F988CE2C0B85954610D2BCF8664844DF2AB56E6C61BB701E4 Or use this for machine-configured eMMCs: -global emmc.auth-key=D3EB3EC36E334C9F988CE2C0B85954610D2BCF8664844DF2AB56E6C61BB701E4 Signed-off-by: Jan Kiszka <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Acked-by: Ilias Apalodimas <[email protected]> Reviewed-by: Jerome Forissier <[email protected]> Message-ID: <9fab19ee4c755f9cb2abf55494541fcadff46cbd.1776231967.git.jan.kis...@siemens.com> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- docs/system/devices/emmc.rst | 23 +++++++++++++++++++++++ hw/sd/sd.c | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/docs/system/devices/emmc.rst b/docs/system/devices/emmc.rst index e62adfd68ed..e7d67c809d5 100644 --- a/docs/system/devices/emmc.rst +++ b/docs/system/devices/emmc.rst @@ -53,3 +53,26 @@ SDHCI controllers while assuming that the firmware needs a boot partitions of -drive file=emmc.img,if=none,format=raw,id=emmc-img -device sdhci-pci -device emmc,drive=emmc-img,boot-partition-size=1048576,rpmb-partition-size=2097152 + +RPMB Authentication Key +======================= + +A private shared key is used for authenticating requests of the host to the +RPMB. A real eMMC stores this persistently and permits no reprogramming once it +is set. QEMU emulates key programming but does not persist the key state +across restarts. To emulate the state "key is set", the eMMC can be created +with a user-provided key via the ``auth-key`` property: + +.. code-block:: console + + -device emmc,[...],auth-key=D3EB3EC36E334C9F988CE2C0B85954610D2BCF8664844DF2AB56E6C61BB701E4 + +This sets the well-known test key of OP-TEE on emmc device creation. In case an +eMMC is instantiated by the machine model already: + +.. code-block:: console + + -global emmc.auth-key=D3EB3EC36E334C9F988CE2C0B85954610D2BCF8664844DF2AB56E6C61BB701E4 + +A key always consists of 32 bytes that have to be encoded as hex numbers, +left-padding with zeros as needed. diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 58275e7fa19..ebe6e35b15e 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -205,6 +205,7 @@ struct SDState { QEMUTimer *ocr_power_timer; uint8_t dat_lines; bool cmd_line; + char *preset_auth_key; }; static void sd_realize(DeviceState *dev, Error **errp); @@ -3132,6 +3133,27 @@ static void sd_realize(DeviceState *dev, Error **errp) "The RPMB partition size must be multiples of 128K" "and not larger than 16384K.\n"); } + if (sd_is_emmc(sd) && sd->preset_auth_key) { + if (strlen(sd->preset_auth_key) != 64) { + error_setg(errp, + "Authentication key must be 32 bytes long, " + "encoded hexadecimally"); + return; + } + + char *pos = sd->preset_auth_key; + unsigned int n; + for (n = 0; n < RPMB_KEY_MAC_LEN; n++, pos += 2) { + int chrs; + if (sscanf(pos, "%02hhx%n", &sd->rpmb.key[n], &chrs) != 1 || + chrs != 2) { + error_setg(errp, + "Authentication key contains invalid characters"); + return; + } + } + sd->rpmb.key_set = 1; + } } static void emmc_realize(DeviceState *dev, Error **errp) @@ -3156,6 +3178,7 @@ static const Property emmc_properties[] = { DEFINE_PROP_UINT64("boot-partition-size", SDState, boot_part_size, 0), DEFINE_PROP_UINT8("boot-config", SDState, boot_config, 0x0), DEFINE_PROP_UINT64("rpmb-partition-size", SDState, rpmb_part_size, 0), + DEFINE_PROP_STRING("auth-key", SDState, preset_auth_key), }; static void sdmmc_common_class_init(ObjectClass *klass, const void *data) -- 2.53.0
