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;
+}