-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.
QEMUTimer *ocr_power_timer;
uint8_t dat_lines;
bool cmd_line;
+ char *preset_auth_key;
};
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)
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)