test_aes_perf.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* mbedTLS AES performance test
  2. */
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stdbool.h>
  6. #include <esp_system.h>
  7. #include "mbedtls/aes.h"
  8. #include "mbedtls/gcm.h"
  9. #include "unity.h"
  10. #include "sdkconfig.h"
  11. #include "esp_heap_caps.h"
  12. #include "test_utils.h"
  13. #include "ccomp_timer.h"
  14. TEST_CASE("mbedtls AES performance", "[aes][timeout=60]")
  15. {
  16. const unsigned CALLS = 256;
  17. const unsigned CALL_SZ = 32 * 1024;
  18. mbedtls_aes_context ctx;
  19. float elapsed_usec;
  20. uint8_t iv[16];
  21. uint8_t key[16];
  22. memset(iv, 0xEE, 16);
  23. memset(key, 0x44, 16);
  24. // allocate internal memory
  25. uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
  26. TEST_ASSERT_NOT_NULL(buf);
  27. mbedtls_aes_init(&ctx);
  28. mbedtls_aes_setkey_enc(&ctx, key, 128);
  29. ccomp_timer_start();
  30. for (int c = 0; c < CALLS; c++) {
  31. memset(buf, 0xAA, CALL_SZ);
  32. mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, buf, buf);
  33. }
  34. elapsed_usec = ccomp_timer_stop();
  35. /* Sanity check: make sure the last ciphertext block matches
  36. what we expect to see.
  37. Last block produced via this Python:
  38. import os, binascii
  39. from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
  40. from cryptography.hazmat.backends import default_backend
  41. key = b'\x44' * 16
  42. iv = b'\xee' * 16
  43. cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
  44. encryptor = cipher.encryptor()
  45. ct = encryptor.update(b'\xaa' * 256 * 32 * 1024) + encryptor.finalize()
  46. print(binascii.hexlify(ct[-16:]))
  47. */
  48. const uint8_t expected_last_block[] = {
  49. 0x50, 0x81, 0xe0, 0xe1, 0x15, 0x2f, 0x14, 0xe9,
  50. 0x97, 0xa0, 0xc6, 0xe6, 0x36, 0xf3, 0x5c, 0x25,
  51. };
  52. TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16);
  53. free(buf);
  54. // bytes/usec = MB/sec
  55. float mb_sec = (CALL_SZ * CALLS) / elapsed_usec;
  56. printf("Encryption rate %.3fMB/sec\n", mb_sec);
  57. #ifdef CONFIG_MBEDTLS_HARDWARE_AES
  58. // Don't put a hard limit on software AES performance
  59. TEST_PERFORMANCE_GREATER_THAN(AES_CBC_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
  60. #endif
  61. }
  62. TEST_CASE("mbedtls AES GCM performance", "[aes]")
  63. {
  64. const unsigned CALL_SZ = 32 * 1024;
  65. mbedtls_gcm_context ctx;
  66. float elapsed_usec;
  67. unsigned char tag_buf[16];
  68. mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
  69. uint8_t iv[16];
  70. uint8_t key[16];
  71. memset(iv, 0xEE, 16);
  72. memset(key, 0x44, 16);
  73. // allocate internal memory
  74. uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
  75. TEST_ASSERT_NOT_NULL(buf);
  76. uint8_t aad[16];
  77. memset(aad, 0x22, 16);
  78. mbedtls_gcm_init(&ctx);
  79. mbedtls_gcm_setkey( &ctx, cipher, key, 128);
  80. ccomp_timer_start();
  81. memset(buf, 0xAA, CALL_SZ);
  82. mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, sizeof(iv), aad, sizeof(aad), buf, buf, 16, tag_buf);
  83. elapsed_usec = ccomp_timer_stop();
  84. /* Sanity check: make sure the last ciphertext block matches
  85. what we expect to see.
  86. Last block and tag produced via this Python:
  87. import os, binascii
  88. from cryptography.hazmat.primitives.ciphers.aead import AESGCM
  89. key = b'\x44' * 16
  90. iv = b'\xEE' * 16
  91. data = b'\xAA' * 100
  92. aad = b'\x22 * 16
  93. aesgcm = AESGCM(key)
  94. ct = aesgcm.encrypt(iv, data, aad)
  95. */
  96. const uint8_t expected_last_block[] = {
  97. 0x7d, 0x3d, 0x16, 0x84, 0xd0, 0xb4, 0x38, 0x30,
  98. 0xd1, 0x24, 0x6f, 0x7e, 0x9a, 0x9c, 0x81, 0x58,
  99. };
  100. const uint8_t expected_tag[] = {
  101. 0x7e, 0x16, 0x04, 0x07, 0x4b, 0x7e, 0x6b, 0xf7,
  102. 0x5d, 0xce, 0x9e, 0x7d, 0x3f, 0x85, 0xc5, 0xa5,
  103. };
  104. TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16 , 16);
  105. TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag_buf, 16);
  106. free(buf);
  107. // bytes/usec = MB/sec
  108. float mb_sec = CALL_SZ / elapsed_usec;
  109. printf("GCM encryption rate %.3fMB/sec\n", mb_sec);
  110. #ifdef CONFIG_MBEDTLS_HARDWARE_GCM
  111. // Don't put a hard limit on software AES performance
  112. TEST_PERFORMANCE_GREATER_THAN(AES_GCM_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec);
  113. #endif
  114. }