|
@@ -231,6 +231,59 @@ unsigned int sec_firmware_support_psci_version(void)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ * Check with sec_firmware if it supports random number generation
|
|
|
+ * via HW RNG
|
|
|
+ *
|
|
|
+ * The return value will be true if it is supported
|
|
|
+ */
|
|
|
+bool sec_firmware_support_hwrng(void)
|
|
|
+{
|
|
|
+ uint8_t rand[8];
|
|
|
+ if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) {
|
|
|
+ if (!sec_firmware_get_random(rand, 8))
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * sec_firmware_get_random - Get a random number from SEC Firmware
|
|
|
+ * @rand: random number buffer to be filled
|
|
|
+ * @bytes: Number of bytes of random number to be supported
|
|
|
+ * @eret: -1 in case of error, 0 for success
|
|
|
+ */
|
|
|
+int sec_firmware_get_random(uint8_t *rand, int bytes)
|
|
|
+{
|
|
|
+ unsigned long long num;
|
|
|
+ struct pt_regs regs;
|
|
|
+ int param1;
|
|
|
+
|
|
|
+ if (!bytes || bytes > 8) {
|
|
|
+ printf("Max Random bytes genration supported is 8\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+#define SIP_RNG_64 0xC200FF11
|
|
|
+ regs.regs[0] = SIP_RNG_64;
|
|
|
+
|
|
|
+ if (bytes <= 4)
|
|
|
+ param1 = 0;
|
|
|
+ else
|
|
|
+ param1 = 1;
|
|
|
+ regs.regs[1] = param1;
|
|
|
+
|
|
|
+ smc_call(®s);
|
|
|
+
|
|
|
+ if (regs.regs[0])
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ num = regs.regs[1];
|
|
|
+ memcpy(rand, &num, bytes);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* sec_firmware_init - Initialize the SEC Firmware
|
|
|
* @sec_firmware_img: the SEC Firmware image address
|
|
@@ -278,3 +331,49 @@ int sec_firmware_init(const void *sec_firmware_img,
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+/*
|
|
|
+ * fdt_fix_kaslr - Add kalsr-seed node in Device tree
|
|
|
+ * @fdt: Device tree
|
|
|
+ * @eret: 0 in case of error, 1 for success
|
|
|
+ */
|
|
|
+int fdt_fixup_kaslr(void *fdt)
|
|
|
+{
|
|
|
+ int nodeoffset;
|
|
|
+ int err, ret = 0;
|
|
|
+ u8 rand[8];
|
|
|
+
|
|
|
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
|
|
|
+ /* Check if random seed generation is supported */
|
|
|
+ if (sec_firmware_support_hwrng() == false)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ ret = sec_firmware_get_random(rand, 8);
|
|
|
+ if (ret < 0) {
|
|
|
+ printf("WARNING: No random number to set kaslr-seed\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ err = fdt_check_header(fdt);
|
|
|
+ if (err < 0) {
|
|
|
+ printf("fdt_chosen: %s\n", fdt_strerror(err));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* find or create "/chosen" node. */
|
|
|
+ nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
|
|
|
+ if (nodeoffset < 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand,
|
|
|
+ sizeof(rand));
|
|
|
+ if (err < 0) {
|
|
|
+ printf("WARNING: can't set kaslr-seed %s.\n",
|
|
|
+ fdt_strerror(err));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ ret = 1;
|
|
|
+#endif
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|