test_mpi.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "esp_private/esp_crypto_lock_internal.h"
  9. #include "esp_log.h"
  10. #include "esp_heap_caps.h"
  11. #include "memory_checks.h"
  12. #include "unity_fixture.h"
  13. #if CONFIG_IDF_TARGET_ESP32
  14. #define ESP_MPI_USE_MONT_EXP
  15. #endif
  16. #include "hal/mpi_hal.h"
  17. #include "hal/mpi_ll.h"
  18. #include "mpi_params.h"
  19. #define _DEBUG_ 0
  20. static void esp_mpi_enable_hardware_hw_op( void )
  21. {
  22. /* Enable RSA hardware */
  23. MPI_RCC_ATOMIC() {
  24. mpi_ll_enable_bus_clock(true);
  25. mpi_ll_reset_register();
  26. }
  27. mpi_hal_enable_hardware_hw_op();
  28. }
  29. static void esp_mpi_disable_hardware_hw_op( void )
  30. {
  31. mpi_hal_disable_hardware_hw_op();
  32. /* Disable RSA hardware */
  33. MPI_RCC_ATOMIC() {
  34. mpi_ll_enable_bus_clock(false);
  35. }
  36. }
  37. static void mpi_mul_mpi_mod_hw_op(void)
  38. {
  39. esp_mpi_enable_hardware_hw_op();
  40. for(int i = 0; i < TEST_CASES_NUM; i++){
  41. #if CONFIG_IDF_TARGET_ESP32
  42. mpi_hal_set_mode((test_cases_num_words[i] / 16) - 1);
  43. #else
  44. mpi_hal_set_mode(test_cases_num_words[i] - 1);
  45. #endif
  46. /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */
  47. mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, test_cases_M_p[i], test_cases_M_n[i], test_cases_num_words[i]);
  48. mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, test_cases_X_p[i], test_cases_X_n[i], test_cases_num_words[i]);
  49. #if !CONFIG_IDF_TARGET_ESP32
  50. mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, test_cases_Y_p[i], test_cases_Y_n[i], test_cases_num_words[i]);
  51. #endif
  52. mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, test_cases_Rinv_p[i], test_cases_Rinv_n[i], test_cases_num_words[i]);
  53. mpi_hal_write_m_prime(test_cases_Mprime[i]);
  54. #if CONFIG_IDF_TARGET_ESP32
  55. mpi_hal_start_op(MPI_MULT);
  56. mpi_hal_wait_op_complete();
  57. /* execute second stage */
  58. /* Load Y to X input memory block, rerun */
  59. mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, test_cases_Y_p[i], test_cases_Y_n[i], test_cases_num_words[i]);
  60. mpi_hal_start_op(MPI_MULT);
  61. #else
  62. mpi_hal_start_op(MPI_MODMULT);
  63. #endif
  64. uint32_t* Z_p = (uint32_t*)heap_caps_calloc(test_cases_Z_words[i], sizeof(uint32_t), MALLOC_CAP_INTERNAL);
  65. mpi_hal_read_result_hw_op(Z_p, test_cases_Z_words[i], test_cases_Z_words[i]);
  66. printf("Test Case %d: ", i+1);
  67. #if _DEBUG_
  68. printf("\n");
  69. ESP_LOG_BUFFER_HEX("Expected Z:", test_cases_Z_p[i], test_cases_Z_words[i]*4);
  70. ESP_LOG_BUFFER_HEX("Got Z:", Z_p, test_cases_Z_words[i]*4);
  71. #endif
  72. TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(test_cases_Z_p[i], Z_p, test_cases_Z_words[i], "Result");
  73. printf("PASS\n");
  74. heap_caps_free(Z_p);
  75. }
  76. esp_mpi_disable_hardware_hw_op();
  77. }
  78. static void mpi_exp_mpi_mod_hw_op(void)
  79. {
  80. for (int i = 0; i < EXP_TEST_CASES_NUM; i++) {
  81. if (i == 14 || i == 16 || i == 18 || i == 22) // cases when Y == 0 (in Z = X ^ Y mod M) should be handled in the software level
  82. continue;
  83. #ifdef ESP_MPI_USE_MONT_EXP // CONFIG_IDF_TARGET_ESP32
  84. printf("Support for montgomery exponentiation to be added.\n");
  85. break;
  86. #else
  87. esp_mpi_enable_hardware_hw_op();
  88. mpi_hal_set_mode(exp_test_cases_num_words[i] - 1);
  89. mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, exp_test_cases_X_p[i], exp_test_cases_X_n[i], exp_test_cases_num_words[i]);
  90. mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, exp_test_cases_Y_p[i], exp_test_cases_Y_n[i], exp_test_cases_num_words[i]);
  91. mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, exp_test_cases_M_p[i], exp_test_cases_M_n[i], exp_test_cases_num_words[i]);
  92. mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, exp_test_cases_Rinv_p[i], exp_test_cases_Rinv_n[i], exp_test_cases_num_words[i]);
  93. mpi_hal_write_m_prime(exp_test_cases_Mprime[i]);
  94. /* Enable acceleration options */
  95. mpi_hal_enable_constant_time(false);
  96. mpi_hal_enable_search(true);
  97. mpi_hal_set_search_position(exp_test_cases_y_bits[i] - 1);
  98. /* Execute first stage montgomery multiplication */
  99. mpi_hal_start_op(MPI_MODEXP);
  100. mpi_hal_enable_search(false);
  101. #endif
  102. uint32_t* Z_p = (uint32_t*)heap_caps_calloc(exp_test_cases_m_words[i], sizeof(uint32_t), MALLOC_CAP_INTERNAL);
  103. /* Read back the result */
  104. mpi_hal_read_result_hw_op(Z_p, exp_test_cases_m_words[i], exp_test_cases_m_words[i]);
  105. esp_mpi_disable_hardware_hw_op();
  106. printf("Test Case %d: ", i+1);
  107. #if _DEBUG_
  108. printf("\n");
  109. ESP_LOG_BUFFER_HEX("Expected Z:", test_cases_Z_p[i], test_cases_Z_words[i]*4);
  110. ESP_LOG_BUFFER_HEX("Got Z:", Z_p, test_cases_Z_words[i]*4);
  111. #endif
  112. TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(exp_test_cases_Z_p[i], Z_p, exp_test_cases_m_words[i], "Result");
  113. printf("PASS\n");
  114. heap_caps_free(Z_p);
  115. }
  116. }
  117. TEST_GROUP(mpi);
  118. TEST_SETUP(mpi)
  119. {
  120. test_utils_record_free_mem();
  121. TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
  122. }
  123. TEST_TEAR_DOWN(mpi)
  124. {
  125. test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL),
  126. test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL));
  127. }
  128. TEST(mpi, mpi_multiplication)
  129. {
  130. mpi_mul_mpi_mod_hw_op();
  131. }
  132. TEST(mpi, mpi_exponentiation)
  133. {
  134. mpi_exp_mpi_mod_hw_op();
  135. }
  136. TEST_GROUP_RUNNER(mpi)
  137. {
  138. RUN_TEST_CASE(mpi, mpi_multiplication);
  139. RUN_TEST_CASE(mpi, mpi_exponentiation);
  140. }