sec-common.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. *
  3. * Common security related functions for OMAP devices
  4. *
  5. * (C) Copyright 2016
  6. * Texas Instruments, <www.ti.com>
  7. *
  8. * Daniel Allred <d-allred@ti.com>
  9. * Andreas Dannenberg <dannenberg@ti.com>
  10. *
  11. * SPDX-License-Identifier: GPL-2.0+
  12. */
  13. #include <common.h>
  14. #include <stdarg.h>
  15. #include <asm/arch/sys_proto.h>
  16. #include <asm/omap_common.h>
  17. #include <asm/omap_sec_common.h>
  18. #include <asm/spl.h>
  19. #include <spl.h>
  20. /* Index for signature verify ROM API */
  21. #ifdef CONFIG_AM33XX
  22. #define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000C)
  23. #else
  24. #define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000E)
  25. #endif
  26. static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
  27. u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
  28. {
  29. int i;
  30. u32 num_args;
  31. va_list ap;
  32. va_start(ap, flag);
  33. num_args = va_arg(ap, u32);
  34. if (num_args > 4)
  35. return 1;
  36. /* Copy args to aligned args structure */
  37. for (i = 0; i < num_args; i++)
  38. secure_rom_call_args[i + 1] = va_arg(ap, u32);
  39. secure_rom_call_args[0] = num_args;
  40. va_end(ap);
  41. /* if data cache is enabled, flush the aligned args structure */
  42. flush_dcache_range(
  43. (unsigned int)&secure_rom_call_args[0],
  44. (unsigned int)&secure_rom_call_args[0] +
  45. roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN));
  46. return omap_smc_sec(service, proc_id, flag, secure_rom_call_args);
  47. }
  48. static u32 find_sig_start(char *image, size_t size)
  49. {
  50. char *image_end = image + size;
  51. char *sig_start_magic = "CERT_";
  52. int magic_str_len = strlen(sig_start_magic);
  53. char *ch;
  54. while (--image_end > image) {
  55. if (*image_end == '_') {
  56. ch = image_end - magic_str_len + 1;
  57. if (!strncmp(ch, sig_start_magic, magic_str_len))
  58. return (u32)ch;
  59. }
  60. }
  61. return 0;
  62. }
  63. int secure_boot_verify_image(void **image, size_t *size)
  64. {
  65. int result = 1;
  66. u32 cert_addr, sig_addr;
  67. size_t cert_size;
  68. /* Perform cache writeback on input buffer */
  69. flush_dcache_range(
  70. (u32)*image,
  71. (u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
  72. cert_addr = (uint32_t)*image;
  73. sig_addr = find_sig_start((char *)*image, *size);
  74. if (sig_addr == 0) {
  75. printf("No signature found in image!\n");
  76. result = 1;
  77. goto auth_exit;
  78. }
  79. *size = sig_addr - cert_addr; /* Subtract out the signature size */
  80. cert_size = *size;
  81. /* Check if image load address is 32-bit aligned */
  82. if (!IS_ALIGNED(cert_addr, 4)) {
  83. printf("Image is not 4-byte aligned!\n");
  84. result = 1;
  85. goto auth_exit;
  86. }
  87. /* Image size also should be multiple of 4 */
  88. if (!IS_ALIGNED(cert_size, 4)) {
  89. printf("Image size is not 4-byte aligned!\n");
  90. result = 1;
  91. goto auth_exit;
  92. }
  93. /* Call ROM HAL API to verify certificate signature */
  94. debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__,
  95. cert_addr, cert_size, sig_addr);
  96. result = secure_rom_call(
  97. API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0,
  98. 4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF);
  99. /* Perform cache writeback on output buffer */
  100. flush_dcache_range(
  101. (u32)*image,
  102. (u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
  103. auth_exit:
  104. if (result != 0) {
  105. printf("Authentication failed!\n");
  106. printf("Return Value = %08X\n", result);
  107. hang();
  108. }
  109. /*
  110. * Output notification of successful authentication as well the name of
  111. * the signing certificate used to re-assure the user that the secure
  112. * code is being processed as expected. However suppress any such log
  113. * output in case of building for SPL and booting via YMODEM. This is
  114. * done to avoid disturbing the YMODEM serial protocol transactions.
  115. */
  116. if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
  117. IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
  118. spl_boot_device() == BOOT_DEVICE_UART))
  119. printf("Authentication passed: %s\n", (char *)sig_addr);
  120. return result;
  121. }