summaryrefslogtreecommitdiffstats
path: root/drivers/hab
diff options
context:
space:
mode:
authorRoland Hieber <r.hieber@pengutronix.de>2018-11-29 14:42:07 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-12-05 08:47:50 +0100
commit620cd45ac1b97fb0f5cf68be309c6f45cc53cc6a (patch)
tree62d159c318076839ef2f7c2833e87210c73af947 /drivers/hab
parent5a1a5ed2537d7d12f851f3778707681d6c08d6e8 (diff)
downloadbarebox-620cd45ac1b97fb0f5cf68be309c6f45cc53cc6a.tar.gz
barebox-620cd45ac1b97fb0f5cf68be309c6f45cc53cc6a.tar.xz
drivers: caam: add RNG software self-test
This patch is based on a vendor patch in U-Boot, taken from https://portland.source.codeaurora.org/patches/external/imxsupport/uboot-imx/imx_v2016.03_4.1.15_2.0.0_ga/HAB-238-Run-RNG-self-test-for-impacted-i.MX-chips.zip | HAB-238 Run RNG self test for impacted i.MX chips | | Patch is only applicable to imx_v2016.03_4.1.15_2.0.0_ga branch of u-boot. | Please adapt the patch for your respective release version. | | Background: | Few i.MX chips which have HAB 4.2.3 or beyond, have oberserved following | warning message generated by HAB due to incorrect implementation of drng | self test in boot ROM. | | Event |0xdb|0x0024|0x42| SRCE Field: 69 30 e1 1d | | | | | STS = HAB_WARNING (0x69) | | | | | RSN = HAB_ENG_FAIL (0x30) | | | | | CTX = HAB_CTX_ENTRY (0xE1) | | | | | ENG = HAB_ENG_CAAM (0x1D) | | | | | Evt Data (hex): | | | | | 00 08 00 02 40 00 36 06 55 55 00 03 00 00 00 00 | | | | | 00 00 00 00 00 00 00 00 00 00 00 01 | | It is recommended to run this rng self test before any RNG related crypto | implementations are done. | [...] | | Signed-off-by: Utkarsh Gupta <utkarsh.gupta@nxp.com> Currently known impacted chips, as determined by NXP, include: * i.MX6DQ+ silicon revision 1.1 * i.MX6DQ silicon revision 1.6 * i.MX6DLS silicon revision 1.4 * i.MX6SX silicon revision 1.4 * i.MX6UL silicon revision 1.2 * i.MX67SD silicon revision 1.3 Port the RNG software self-test from this patch to barebox. It can be enabled by selecting CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST in Kconfig. The original patch included a command line utility to run the self-test, but we choose a different approach here, and run the software self-test automatically when the respective HAB events indicating a RNG ROM self-test failure are found when running habv4_get_status(). Note that habv4_get_status() must be called by the board code before the CAAM device driver is probed for this mechanism to work. Until now there are at least two such known events. The first event was observed on an i.MX6Solo, silicon revision 1.4; the second event is mentioned in the original patch description given above. When an event occured, habv4_get_status() tests if it is one of those known events, and if so, indicates to the CAAM driver to run the software self-test. In this case, printing the respective HAB warning is suppressed to prevent confusion; the software self-test itself will error out in case of recurring RNG self-test failure. Signed-off-by: Roland Hieber <r.hieber@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/hab')
-rw-r--r--drivers/hab/habv4.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/hab/habv4.c b/drivers/hab/habv4.c
index 28fd42ecd7..aa9506c022 100644
--- a/drivers/hab/habv4.c
+++ b/drivers/hab/habv4.c
@@ -387,6 +387,39 @@ static void habv4_display_event(uint8_t *data, uint32_t len)
habv4_display_event_record((struct hab_event_record *)data);
}
+/* Some chips with HAB >= 4.2.3 have an incorrect implementation of the RNG
+ * self-test in ROM code. In this case, an HAB event is generated, and a
+ * software self-test should be run. This variable is set to @c true by
+ * habv4_get_status() when this occurs. */
+bool habv4_need_rng_software_self_test = false;
+EXPORT_SYMBOL(habv4_need_rng_software_self_test);
+
+#define RNG_FAIL_EVENT_SIZE 36
+static uint8_t habv4_known_rng_fail_events[][RNG_FAIL_EVENT_SIZE] = {
+ { 0xdb, 0x00, 0x24, 0x42, 0x69, 0x30, 0xe1, 0x1d,
+ 0x00, 0x80, 0x00, 0x02, 0x40, 0x00, 0x36, 0x06,
+ 0x55, 0x55, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01 },
+ { 0xdb, 0x00, 0x24, 0x42, 0x69, 0x30, 0xe1, 0x1d,
+ 0x00, 0x04, 0x00, 0x02, 0x40, 0x00, 0x36, 0x06,
+ 0x55, 0x55, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01 },
+};
+
+static bool is_known_rng_fail_event(const uint8_t *data, size_t len)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(habv4_known_rng_fail_events); i++) {
+ if (memcmp(data, habv4_known_rng_fail_events[i],
+ min(len, (uint32_t)RNG_FAIL_EVENT_SIZE)) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
static int habv4_get_status(const struct habv4_rvt *rvt)
{
uint8_t data[256];
@@ -413,10 +446,18 @@ static int habv4_get_status(const struct habv4_rvt *rvt)
len = sizeof(data);
while (rvt->report_event(HAB_STATUS_WARNING, index, data, &len) == HAB_STATUS_SUCCESS) {
- pr_err("-------- HAB warning Event %d --------\n", index);
- pr_err("event data:\n");
- habv4_display_event(data, len);
+ /* suppress RNG self-test fail events if they can be handled in software */
+ if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST) &&
+ is_known_rng_fail_event(data, len)) {
+ pr_debug("RNG self-test failure detected, will run software self-test\n");
+ habv4_need_rng_software_self_test = true;
+ } else {
+ pr_err("-------- HAB warning Event %d --------\n", index);
+ pr_err("event data:\n");
+ habv4_display_event(data, len);
+ }
+
len = sizeof(data);
index++;
}