platform: msm_shared: add secure random value for canary
Add scm call for secure random value in lk.
Use secure random value for canary.
CRs-Fixed: 671500
Change-Id: Iafd3a89d7051ee44b02fba8de77e6c38d52210d0
diff --git a/include/platform/debug.h b/include/platform/debug.h
index e99aed7..e4ab0b6 100644
--- a/include/platform/debug.h
+++ b/include/platform/debug.h
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <stdarg.h>
#include <compiler.h>
+#include <scm.h>
#if defined(__cplusplus)
extern "C" {
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
index 6c8f7ef..18f8d78 100644
--- a/platform/msm_shared/include/scm.h
+++ b/platform/msm_shared/include/scm.h
@@ -116,11 +116,17 @@
uint64_t el1_elr;
} el1_system_param;
+struct tz_prng_data {
+ uint8_t *out_buf;
+ uint32_t out_buf_size;
+}__packed;
+
/* Service IDs */
#define SCM_SVC_BOOT 0x01
#define TZBSP_SVC_INFO 0x06
#define SCM_SVC_SSD 0x07
#define SVC_MEMORY_PROTECTION 0x0C
+#define TZ_SVC_CRYPTO 0x0A
/*Service specific command IDs */
#define SSD_DECRYPT_ID 0x01
@@ -137,6 +143,8 @@
#define TZ_INFO_GET_FEATURE_ID 0x03
+#define PRNG_CMD_ID 0x01
+
/* Download Mode specific arguments to be passed to TZ */
#define SCM_EDLOAD_MODE 0x02
#define SCM_DLOAD_MODE 0x10
@@ -216,6 +224,7 @@
int scm_call_atomic2(uint32_t svc, uint32_t cmd, uint32_t arg1, uint32_t arg2);
void scm_elexec_call(paddr_t kernel_entry, paddr_t dtb_offset);
+void *get_canary();
/**
* struct scm_command - one SCM command buffer
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index dc41587..66db6f1 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -672,3 +672,39 @@
dprintf(CRITICAL, "Failed to jump to kernel\n");
ASSERT(0);
}
+
+/* SCM Random Command */
+int scm_random(uint32_t * rbuf, uint32_t r_len)
+{
+ int ret;
+ struct tz_prng_data data;
+
+ data.out_buf = (uint8_t*) rbuf;
+ data.out_buf_size = r_len;
+
+ /*
+ * random buffer must be flushed/invalidated before and after TZ call.
+ */
+ arch_clean_invalidate_cache_range((addr_t) rbuf, r_len);
+
+ ret = scm_call(TZ_SVC_CRYPTO, PRNG_CMD_ID, &data, sizeof(data), NULL, 0);
+
+ /* Invalidate the updated random buffer */
+ arch_clean_invalidate_cache_range((addr_t) rbuf, r_len);
+
+ return ret;
+}
+
+void * get_canary()
+{
+ void * canary;
+ if(scm_random(&canary, sizeof(canary))) {
+ dprintf(CRITICAL,"scm_call for random failed !!!");
+ /*
+ * fall back to use lib rand API if scm call failed.
+ */
+ canary = (void *)rand();
+ }
+
+ return canary;
+}