[U-Boot] [PATCH] ARMv8/sec_firmware : Update chosen/kaslr-seed

Peter Robinson pbrobinson at gmail.com
Mon May 15 12:48:05 UTC 2017


On Sat, May 13, 2017 at 1:07 AM, Ruchika Gupta <ruchika.gupta at nxp.com> wrote:
> kASLR support in kernel requires a random number to be passed via
> chosen/kaslr-seed propert. sec_firmware generates this random seed
> which can then be passed in the device tree node

Is that functionality generic that it can be consumed by other devices?

> sec_firmware reserves JR3 for it's own usage. Node for JR3 is
> removed from device-tree.
>
> Signed-off-by: Ruchika Gupta <ruchika.gupta at nxp.com>
> ---
>  arch/arm/cpu/armv8/fsl-layerscape/fdt.c   | 73 +++++++++++++++++++++++++++++++
>  arch/arm/cpu/armv8/sec_firmware.c         | 53 ++++++++++++++++++++++
>  arch/arm/include/asm/armv8/sec_firmware.h |  9 ++++
>  3 files changed, 135 insertions(+)
>
> diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
> index 05c4577..d4ca129 100644
> --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
> +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
> @@ -345,6 +345,75 @@ static void fdt_fixup_msi(void *blob)
>  }
>  #endif
>
> +
> +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: could not get 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: could not set kaslr-seed %s.\n",
> +                      fdt_strerror(err));
> +               return 0;
> +       }
> +       ret = 1;
> +#endif
> +
> +       return ret;
> +}
> +
> +/* Remove JR node used by SEC firmware */
> +void fdt_fixup_remove_jr(void *blob)
> +{
> +       int jr_node, addr_cells, len;
> +       int crypto_node = fdt_path_offset(blob, "crypto");
> +       u64 jr_offset, used_jr;
> +       fdt32_t *reg;
> +
> +       used_jr = sec_firmware_used_jobring_offset();
> +       of_bus_default_count_cells(blob, crypto_node, &addr_cells, NULL);
> +
> +       jr_node = fdt_node_offset_by_compatible(blob, crypto_node,
> +                                               "fsl,sec-v4.0-job-ring");
> +
> +       while (jr_node != -FDT_ERR_NOTFOUND) {
> +               reg = (fdt32_t *)fdt_getprop(blob, jr_node, "reg", &len);
> +               jr_offset = of_read_number(reg, addr_cells);
> +               if (jr_offset == used_jr) {
> +                       fdt_del_node(blob, jr_node);
> +                       break;
> +               }
> +               jr_node = fdt_node_offset_by_compatible(blob, jr_node,
> +                                                       "fsl,sec-v4.0-job-ring");
> +       }
> +}
> +
>  void ft_cpu_setup(void *blob, bd_t *bd)
>  {
>  #ifdef CONFIG_FSL_LSCH2
> @@ -358,6 +427,9 @@ void ft_cpu_setup(void *blob, bd_t *bd)
>         else {
>                 ccsr_sec_t __iomem *sec;
>
> +               if (fdt_fixup_kaslr(blob))
> +                       fdt_fixup_remove_jr(blob);
> +
>                 sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
>                 fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms));
>         }
> @@ -396,4 +468,5 @@ void ft_cpu_setup(void *blob, bd_t *bd)
>  #ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
>         fdt_fixup_msi(blob);
>  #endif
> +
>  }
> diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c
> index 4afa3ad..f460cca 100644
> --- a/arch/arm/cpu/armv8/sec_firmware.c
> +++ b/arch/arm/cpu/armv8/sec_firmware.c
> @@ -232,6 +232,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 - Initialize the 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(&regs);
> +
> +       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
>   * @eret_hold_l:       the address to hold exception return address low
> diff --git a/arch/arm/include/asm/armv8/sec_firmware.h b/arch/arm/include/asm/armv8/sec_firmware.h
> index bc1d97d..1dc547a 100644
> --- a/arch/arm/include/asm/armv8/sec_firmware.h
> +++ b/arch/arm/include/asm/armv8/sec_firmware.h
> @@ -8,10 +8,13 @@
>  #define __SEC_FIRMWARE_H_
>
>  #define PSCI_INVALID_VER               0xffffffff
> +#define SEC_JR3_OFFSET                 0x40000
>
>  int sec_firmware_init(const void *, u32 *, u32 *);
>  int _sec_firmware_entry(const void *, u32 *, u32 *);
>  bool sec_firmware_is_valid(const void *);
> +bool sec_firmware_support_hwrng(void);
> +int sec_firmware_get_random(uint8_t *rand, int bytes);
>  #ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI
>  unsigned int sec_firmware_support_psci_version(void);
>  unsigned int _sec_firmware_support_psci_version(void);
> @@ -22,4 +25,10 @@ static inline unsigned int sec_firmware_support_psci_version(void)
>  }
>  #endif
>
> +static inline unsigned int sec_firmware_used_jobring_offset(void)
> +{
> +       return SEC_JR3_OFFSET;
> +}
> +
> +
>  #endif /* __SEC_FIRMWARE_H_ */
> --
> 2.7.4
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list