diff --git a/components/esp_rom/esp32/ld/esp32.rom.newlib-reent-funcs.ld b/components/esp_rom/esp32/ld/esp32.rom.newlib-reent-funcs.ld index aa4f48f359..56c55188ae 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.newlib-reent-funcs.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.newlib-reent-funcs.ld @@ -72,3 +72,5 @@ strcoll = 0x40001398; strlwr = 0x40001524; strncasecmp = 0x40001550; strupr = 0x4000174c; +PROVIDE ( hmac_md5 = 0x4005d264 ); +PROVIDE ( hmac_md5_vector = 0x4005d17c ); diff --git a/components/esp_rom/esp32/ld/esp32.rom.redefined.ld b/components/esp_rom/esp32/ld/esp32.rom.redefined.ld index a7f62b8676..6cc166ed66 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.redefined.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.redefined.ld @@ -19,8 +19,6 @@ PROVIDE ( ets_timer_done = 0x40008428 ); PROVIDE ( ets_timer_init = 0x400084e8 ); PROVIDE ( ets_timer_handler_isr = 0x40008454 ); PROVIDE ( ets_timer_setfn = 0x40008350 ); -PROVIDE ( hmac_md5 = 0x4005d264 ); -PROVIDE ( hmac_md5_vector = 0x4005d17c ); PROVIDE ( hmac_sha1 = 0x40060acc ); PROVIDE ( hmac_sha1_vector = 0x400609e4 ); PROVIDE ( hmac_sha256 = 0x40060d58 ); diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 3f7198e10b..6ad741688b 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -410,8 +410,6 @@ md5_vector = 0x40000610; MD5Init = 0x40000614; MD5Update = 0x40000618; MD5Final = 0x4000061c; -hmac_md5_vector = 0x40000620; -hmac_md5 = 0x40000624; crc32_le = 0x40000628; crc32_be = 0x4000062c; crc16_le = 0x40000630; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld index 2f3662e60c..40c5529153 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld @@ -48,3 +48,5 @@ strcoll = 0x400003e8; strlwr = 0x400003f4; strncasecmp = 0x400003f8; strupr = 0x40000418; +hmac_md5_vector = 0x40000620; +hmac_md5 = 0x40000624; diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.ld index 5f2116099e..fba68198a7 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.ld @@ -359,8 +359,6 @@ PROVIDE ( rom_gpio_pin_wakeup_disable = 0x40019404 ); PROVIDE ( rom_gpio_pin_wakeup_enable = 0x400193c8 ); PROVIDE ( g_shared_buffers = 0x3ffeab04 ); PROVIDE ( g_ticks_per_us = 0x3ffffd70 ); -PROVIDE ( hmac_md5 = 0x40005490 ); -PROVIDE ( hmac_md5_vector = 0x400053a0 ); PROVIDE ( ibus_baseaddrs = 0x3ffaf03c ); PROVIDE ( intr_matrix_set = 0x4000f1d0 ); PROVIDE ( _iram0_text_end = 0x40000540 ); diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-reent-funcs.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-reent-funcs.ld index dc4ef563ab..c75f24e48e 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-reent-funcs.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-reent-funcs.ld @@ -62,3 +62,5 @@ strcoll = 0x40007ce8; strlwr = 0x40007e68; strncasecmp = 0x40007e94; strupr = 0x40008084; +PROVIDE ( hmac_md5 = 0x40005490 ); +PROVIDE ( hmac_md5_vector = 0x400053a0 ); diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 31ef47b830..f573448e7a 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -518,8 +518,6 @@ md5_vector = 0x40001c50; MD5Init = 0x40001c5c; MD5Update = 0x40001c68; MD5Final = 0x40001c74; -hmac_md5_vector = 0x40001c80; -hmac_md5 = 0x40001c8c; crc32_le = 0x40001c98; crc32_be = 0x40001ca4; crc16_le = 0x40001cb0; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld index f964e305f8..ccdf4c0f74 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld @@ -42,3 +42,5 @@ strcoll = 0x400013a4; strlwr = 0x400013c8; strncasecmp = 0x400013d4; strupr = 0x40001434; +hmac_md5_vector = 0x40001c80; +hmac_md5 = 0x40001c8c; diff --git a/components/wpa_supplicant/test_apps/main/CMakeLists.txt b/components/wpa_supplicant/test_apps/main/CMakeLists.txt index d9528030ae..5f2fc90cc2 100644 --- a/components/wpa_supplicant/test_apps/main/CMakeLists.txt +++ b/components/wpa_supplicant/test_apps/main/CMakeLists.txt @@ -4,6 +4,7 @@ idf_component_register(SRCS "test_eloop.c" "test_fast_pbkdf2.c" "test_offchannel.c" + "test_rom_md5.c" "test_sae.c" "test_sae_h2e.c" "test_wpa_supplicant_main.c" diff --git a/components/wpa_supplicant/test_apps/main/test_rom_md5.c b/components/wpa_supplicant/test_apps/main/test_rom_md5.c new file mode 100644 index 0000000000..c7b45d0949 --- /dev/null +++ b/components/wpa_supplicant/test_apps/main/test_rom_md5.c @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Tests for MD5 and HMAC-MD5 functions. + * + * These tests verify the basic functionality of md5_vector, hmac_md5, and + * hmac_md5_vector APIs. On ESP32-C3 and ESP32-S3, these may use ROM implementations + * which need verification after PSA migration changes. + */ + +#include +#include +#include "unity.h" +#include "crypto/crypto.h" +#include "crypto/md5.h" +#include "test_wpa_supplicant_common.h" + +/* MD5 output length */ +#define MD5_DIGEST_LEN 16 + +/* + * RFC 1321 MD5 Test Vectors + */ + +/* MD5("") = d41d8cd98f00b204e9800998ecf8427e */ +static const uint8_t md5_empty_expected[MD5_DIGEST_LEN] = { + 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e +}; + +/* MD5("abc") = 900150983cd24fb0d6963f7d28e17f72 */ +static const uint8_t md5_abc_input[] = "abc"; +static const uint8_t md5_abc_expected[MD5_DIGEST_LEN] = { + 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 +}; + +/* + * RFC 2104 HMAC-MD5 Test Vectors + */ + +/* Test case 1: key = 0x0b repeated 16 times, data = "Hi There" */ +static const uint8_t hmac_md5_key1[16] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b +}; +static const uint8_t hmac_md5_data1[] = "Hi There"; +static const uint8_t hmac_md5_expected1[MD5_DIGEST_LEN] = { + 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d +}; + +/* Test case 2: key = "Jefe", data = "what do ya want for nothing?" */ +static const uint8_t hmac_md5_key2[] = "Jefe"; +static const uint8_t hmac_md5_data2[] = "what do ya want for nothing?"; +static const uint8_t hmac_md5_expected2[MD5_DIGEST_LEN] = { + 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 +}; + +TEST_CASE("Test md5_vector function", "[wpa_crypto][rom_md5]") +{ + set_leak_threshold(100); + + uint8_t digest[MD5_DIGEST_LEN]; + int ret; + + /* Test 1: MD5 of empty string */ + { + const uint8_t *addr[1] = { (const uint8_t *)"" }; + size_t len[1] = { 0 }; + + memset(digest, 0, sizeof(digest)); + ret = md5_vector(1, addr, len, digest); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(md5_empty_expected, digest, MD5_DIGEST_LEN); + } + + /* Test 2: MD5 of "abc" */ + { + const uint8_t *addr[1] = { md5_abc_input }; + size_t len[1] = { 3 }; + + memset(digest, 0, sizeof(digest)); + ret = md5_vector(1, addr, len, digest); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(md5_abc_expected, digest, MD5_DIGEST_LEN); + } + + /* Test 3: MD5 with multiple elements (should produce same result as concatenated) */ + { + /* "abc" split into "a" + "bc" */ + const uint8_t *addr[2] = { (const uint8_t *)"a", (const uint8_t *)"bc" }; + size_t len[2] = { 1, 2 }; + + memset(digest, 0, sizeof(digest)); + ret = md5_vector(2, addr, len, digest); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(md5_abc_expected, digest, MD5_DIGEST_LEN); + } +} + +TEST_CASE("Test hmac_md5 function", "[wpa_crypto][rom_md5]") +{ + set_leak_threshold(100); + + uint8_t mac[MD5_DIGEST_LEN]; + int ret; + + /* Test 1: RFC 2104 test vector - key=0x0b*16, data="Hi There" */ + { + memset(mac, 0, sizeof(mac)); + ret = hmac_md5(hmac_md5_key1, sizeof(hmac_md5_key1), + hmac_md5_data1, strlen((const char *)hmac_md5_data1), + mac); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(hmac_md5_expected1, mac, MD5_DIGEST_LEN); + } + + /* Test 2: RFC 2104 test vector - key="Jefe", data="what do ya want..." */ + { + memset(mac, 0, sizeof(mac)); + ret = hmac_md5(hmac_md5_key2, strlen((const char *)hmac_md5_key2), + hmac_md5_data2, strlen((const char *)hmac_md5_data2), + mac); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(hmac_md5_expected2, mac, MD5_DIGEST_LEN); + } +} + +TEST_CASE("Test hmac_md5_vector function", "[wpa_crypto][rom_md5]") +{ + set_leak_threshold(100); + + uint8_t mac[MD5_DIGEST_LEN]; + int ret; + + /* Test 1: Single element (should match hmac_md5 result) */ + { + const uint8_t *addr[1] = { hmac_md5_data1 }; + size_t len[1] = { strlen((const char *)hmac_md5_data1) }; + + memset(mac, 0, sizeof(mac)); + ret = hmac_md5_vector(hmac_md5_key1, sizeof(hmac_md5_key1), + 1, addr, len, mac); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(hmac_md5_expected1, mac, MD5_DIGEST_LEN); + } + + /* Test 2: Multiple elements (data split into parts) */ + { + /* "Hi There" split into "Hi " + "There" */ + const uint8_t *addr[2] = { (const uint8_t *)"Hi ", (const uint8_t *)"There" }; + size_t len[2] = { 3, 5 }; + + memset(mac, 0, sizeof(mac)); + ret = hmac_md5_vector(hmac_md5_key1, sizeof(hmac_md5_key1), + 2, addr, len, mac); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(hmac_md5_expected1, mac, MD5_DIGEST_LEN); + } + + /* Test 3: Three elements */ + { + /* "Hi There" split into "Hi" + " " + "There" */ + const uint8_t *addr[3] = { (const uint8_t *)"Hi", (const uint8_t *)" ", (const uint8_t *)"There" }; + size_t len[3] = { 2, 1, 5 }; + + memset(mac, 0, sizeof(mac)); + ret = hmac_md5_vector(hmac_md5_key1, sizeof(hmac_md5_key1), + 3, addr, len, mac); + TEST_ASSERT_EQUAL_INT(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(hmac_md5_expected1, mac, MD5_DIGEST_LEN); + } +}