From a902e2a9ded6cdebc797b36b18361f2a97e3f224 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 25 Nov 2016 19:15:39 +1100 Subject: [PATCH 1/2] mbedtls tests: Add additional MPI (bignum), SHA tests --- components/mbedtls/test/test_mbedtls.c | 120 +--------- components/mbedtls/test/test_mbedtls_mpi.c | 168 ++++++++++++++ components/mbedtls/test/test_mbedtls_sha.c | 250 +++++++++++++++++++++ tools/unit-test-app/sdkconfig | 70 +++++- 4 files changed, 489 insertions(+), 119 deletions(-) create mode 100644 components/mbedtls/test/test_mbedtls_mpi.c create mode 100644 components/mbedtls/test/test_mbedtls_sha.c diff --git a/components/mbedtls/test/test_mbedtls.c b/components/mbedtls/test/test_mbedtls.c index 797c107ef..acde6e9dd 100644 --- a/components/mbedtls/test/test_mbedtls.c +++ b/components/mbedtls/test/test_mbedtls.c @@ -1,27 +1,25 @@ -/* mbedTLS internal tests wrapped into Unity +/* mbedTLS self-tests as unit tests Focus on testing functionality where we use ESP32 hardware accelerated crypto features. - See also test_hwcrypto.c + See also test_hwcrypto.c in esp32 component, which tests hardware crypto without mbedTLS. */ #include #include +#include +#include #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" #include "mbedtls/aes.h" #include "mbedtls/bignum.h" +#include "mbedtls/rsa.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" #include "unity.h" - -static int mbedtls_alt_sha256_self_test( int verbose ); - -TEST_CASE("mbedtls SHA self-tests", "[mbedtls]") -{ - TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass."); - TEST_ASSERT_FALSE_MESSAGE(mbedtls_alt_sha256_self_test(1), "SHA256 self-tests should pass."); - TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass."); -} +#include "sdkconfig.h" TEST_CASE("mbedtls AES self-tests", "[aes]") { @@ -33,102 +31,8 @@ TEST_CASE("mbedtls MPI self-tests", "[bignum]") TEST_ASSERT_FALSE_MESSAGE(mbedtls_mpi_self_test(1), "MPI self-tests should pass."); } - -/* Following code is a copy of the mbedtls_sha256 test vectors, - with the SHA-224 support removed as we don't currently support this hash. -*/ - -/* - * FIPS-180-2 test vectors - */ -static const unsigned char sha256_test_buf[3][57] = { - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const int sha256_test_buflen[3] = { - 3, 56, 1000 -}; - -static const unsigned char sha256_test_sum[6][32] = { - /* - * SHA-256 test vectors - */ - { - 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, - 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, - 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, - 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD - }, - { - 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 - }, - { - 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, - 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, - 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, - 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 - } -}; - -/* - * Checkup routine - */ -static int mbedtls_alt_sha256_self_test( int verbose ) +TEST_CASE("mbedtls RSA self-tests", "[bignum]") { - int j, n, buflen, ret = 0; - unsigned char buf[1024]; - unsigned char sha256sum[32]; - mbedtls_sha256_context ctx; - - for ( j = 0; j < 3; j++ ) { - mbedtls_sha256_init( &ctx ); - - if ( verbose != 0 ) { - printf( " SHA-%d test #%d: ", 256, j + 1 ); - } - - mbedtls_sha256_starts( &ctx, 0 ); - - if ( j == 2 ) { - memset( buf, 'a', buflen = 1000 ); - - for ( n = 0; n < 1000; n++ ) { - mbedtls_sha256_update( &ctx, buf, buflen ); - } - } else - mbedtls_sha256_update( &ctx, sha256_test_buf[j], - sha256_test_buflen[j] ); - - mbedtls_sha256_finish( &ctx, sha256sum ); - - if ( memcmp( sha256sum, sha256_test_sum[j], 32 ) != 0 ) { - if ( verbose != 0 ) { - printf( "failed\n" ); - } - - mbedtls_sha256_free( &ctx ); - - ret = 1; - goto exit; - } - - if ( verbose != 0 ) { - printf( "passed\n" ); - } - - mbedtls_sha256_free( &ctx ); - } - - if ( verbose != 0 ) { - printf( "\n" ); - } - -exit: - - return ( ret ); + TEST_ASSERT_FALSE_MESSAGE(mbedtls_rsa_self_test(1), "RSA self-tests should pass."); } + diff --git a/components/mbedtls/test/test_mbedtls_mpi.c b/components/mbedtls/test/test_mbedtls_mpi.c new file mode 100644 index 000000000..515f9d305 --- /dev/null +++ b/components/mbedtls/test/test_mbedtls_mpi.c @@ -0,0 +1,168 @@ +/* mbedTLS bignum (MPI) self-tests as unit tests +*/ +#include +#include +#include +#include +#include "mbedtls/bignum.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "unity.h" +#include "sdkconfig.h" + + +/* Debugging function to print an MPI number to stdout. Happens to + print output that can be copy-pasted directly into a Python shell. +*/ +void mbedtls_mpi_printf(const char *name, const mbedtls_mpi *X) +{ + static char buf[1024]; + size_t n; + memset(buf, 0, sizeof(buf)); + mbedtls_mpi_write_string(X, 16, buf, sizeof(buf)-1, &n); + if(n) { + printf("%s = 0x%s\n", name, buf); + } else { + printf("%s = TOOLONG\n", name); + } +} + +/* Assert E = A * B */ +static void test_bignum_mult(const char *a_str, const char *b_str, const char *e_str, size_t mod_bits) +{ + mbedtls_mpi A, B, X, E, M; + char x_buf[1024] = { 0 }; + size_t x_buf_len = 0; + + mbedtls_mpi_init(&A); + mbedtls_mpi_init(&B); + mbedtls_mpi_init(&X); + mbedtls_mpi_init(&E); + + TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&A, 16, a_str)); + TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&B, 16, b_str)); + + /* E = A * B */ + TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&E, 16, e_str)); + TEST_ASSERT_FALSE(mbedtls_mpi_mul_mpi(&X, &A, &B)); + + mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len); + TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "mbedtls_mpi_mul_mpi result wrong"); + + /* if mod_bits arg is set, also do a esp_mpi_mul_mod() call */ + if (mod_bits > 0) { + mbedtls_mpi_init(&M); + for(int i = 0; i < mod_bits; i++) { + mbedtls_mpi_set_bit(&M, i, 1); + } + + TEST_ASSERT_FALSE(esp_mpi_mul_mpi_mod(&X, &A, &B, &M)); + + mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len); + TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "esp_mpi_mul_mpi_mod result wrong"); + + mbedtls_mpi_free(&M); + } + + + mbedtls_mpi_free(&A); + mbedtls_mpi_free(&B); + mbedtls_mpi_free(&X); + mbedtls_mpi_free(&E); +} + +TEST_CASE("test MPI multiplication", "[bignum]") +{ + /* Run some trivial numbers tests w/ various high modulo bit counts, + should make no difference to the result + */ + for(int i = 512; i <= 4096; i+= 512) { + test_bignum_mult("10", "100", "1000", + i); + } + + test_bignum_mult("60006FA8D3E3BD746BE39B860FFAADB4F108E15CF2ED8F685FB0E86CC4CB107A488720B41C3F1E18550F00619CD3CA8442296ECB54D2F52ECEE5346D310195700000000", + "BF474CA7", + "047BB102CAF58A48D3D97E4231BC0B753051D8232B9B939A2A4E310F88E65FEFD7762FC2DE0E2BAD6AA51A391DFFABD120653A312E4998F42E2C03AA404EE63B67275BC100000000", + 1024); + + test_bignum_mult("49493AC229831EC01EEB01EAF3BBEBC44768EADF9ABC30C87D1791F5E04245756ED4965361EC0599626884DF079B6B5738985CE76BD66FAA67E3AAAD60775D5C9D44C09FDF9E27C033696C007BE1C540D718CA148BA01FFA4A358541E9E9F02F72BE37AFAB037DAEA5E3669A770400D2F4A5DBBD83A83919D05E3DD64787BC80000000", + "B878CC29", + "34CF37013066D5BDA2C86CF1FE7BDA66604E0D55DAFF9864B6E727BFF5871012B0AB73D28D4E100BA1E4607AA2A247C912FDBC435C6BF7C5F8E00278AE1381B1E5F6E3D52D2CBE819F0D65CB37370666D156E7A7B1FD4698D8C9D3165FC8A83F9293C839521993619CCF8180E521300C4306206C9121D629754F1FCC7839BF6DFAF33080000000", + 3072); + + test_bignum_mult("24BF6185468786FDD303083D25E64EFC66CA472BC44D253102F8B4A9D3BFA75091386C0077937FE33FA3252D28855837AE1B484A8A9A45F7EE8C0C634F9E8CDDF79C5CE07EE72C7F123142198164234CABB724CF78B8173B9F880FC86322407AF1FEDFDDE2BEB674CA15F3E81A1521E071513A1E85B5DFA031F21ECAE9A34D", + "010001", + "24BF8644A80CCD855A00DB402E2374E2B5C6ADF60B78E97E2829B7A288697B103888FD38E393F776BF8664D04DB280BD0652F665D2E4D0923483FAEF5C01DC7C847A547CDBC7AB663EB0544AC37DA4B0CF03D0869D878FF3B6C3AF5072EAA39D3279D1DCC29C9933808ABDFE0DFD3BF59331AB6FBFD46556119250BD086E36A34D", + 1536); + + test_bignum_mult("-5D88B669C417EDD02213723546A906B7E9DA7683780E9B54856A2147467ADA316F8819D69486FC8056FE1E8EA7DEC5D5EF12340B95C4FC966F4B348D35893620", + "9AE7FBC99546432DF71896FC239EADAEF38D18D2B2F0E2DD275AA977E2BF4411F5A3B2A5D33605AEBBCCBA7FEB9F2D2FA74206CEC169D74BF5A8C50D6F48EA08", + "-38990016EB21810E3B5E6AEE339AEE72BB7CD629C4C9270A3D832701A2949BC82B2BE5A7F900C0C9937464699862821976095187D646884E8FBF01DE8C3442F3BC97B670AF573EFB74A9BBEBE4432EE74B0A83BBCDF59485D332B1FF49EB461A3A8B12C38FD72C7772D75EC6EBA5633199540C47678BD2F4ADEEA40830C2F100", + 2048); + + + /* 1 << 2050 * 0X1234 */ + test_bignum_mult("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "1234", + "48D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 3072); + + /* multiply a 1178 bit number by a 2050 bit number */ + test_bignum_mult("AAAAAAAAAA75124938ABBECD0EEEEE333333333333333333333FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAABBBBBBBBBBBBBBBBBBBB000000000000000000000000000000000004988A5293848932948872398400000000000FFFFFFFFFFF0000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238", + "390587293875124938ABBECD0EEEEE3333333333333333333333333333333399999888000AAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238478327400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003012111111111111111100000000000000000000000111111111111111111111111", + "02603AF70D0421C1AD82CE623F28F70B128118D06D00C27D433EC25BA86E6105C3890A0B1973B8BE068CA68E159A21078785DDB37F94216FBF4AEC939958AF4B8CEA2A48895CECA87562FC846EAAE0C866AF9D41EEABFB1D579F5828E9666A15E2AF946F16A189B5C645872FDCA247D309AB0BCAFB0D112881186FCFFEDC87061B4AE4A375E9BBCF579A7BC87A8EAC8C6F66E107986FC603F920F5E1A0FD8C619D88D90066FFFC8F4DB77437EBD7E3BD7E398C4C01F93426E347E039DCA7B0A73C0C90A9C4271BB761ADFF88971D190CE5DA98EFC5D7390D33BC034908AF81D784A4D7F32D0902E0C5DABC706635D5A28FC0E3A364EDEB21E8E117041D0E4B51CA6F9684F434057E7FCF2AF6BD050334B1D11E043B0967154E57354B681161D3C618974D5A7E0385755B80B931AE9B59DD4402BAEC206F04B8440741B3C4CA6D9F7DAF0AE6B3BF1B24B76C2F12B9E9A7C50D32E2093608FC9A30CBD852329E64A9AE0BC3F513899EBFA28629C1DF38081FB8C6630408F70D7B9A37701ABA4176C8B7DCB8CC78BD7783B861A7FC50862E75191DB8", + 4096); +} + +static void test_bignum_modexp(const char *z_str, const char *x_str, const char *y_str, const char *m_str) +{ + mbedtls_mpi Z, X, Y, M; + char z_buf[400] = { 0 }; + size_t z_buf_len = 0; + + mbedtls_mpi_init(&Z); + mbedtls_mpi_init(&X); + mbedtls_mpi_init(&Y); + mbedtls_mpi_init(&M); + + TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&X, 16, x_str)); + TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&Y, 16, y_str)); + TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&M, 16, m_str)); + + //mbedtls_mpi_printf("X", &X); + //mbedtls_mpi_printf("X", &Y); + //mbedtls_mpi_printf("M", &M); + + /* Z = (X ^ Y) mod M */ + TEST_ASSERT_FALSE(mbedtls_mpi_exp_mod(&Z, &X, &Y, &M, NULL)); + + mbedtls_mpi_write_string(&Z, 16, z_buf, sizeof(z_buf)-1, &z_buf_len); + TEST_ASSERT_EQUAL_STRING_MESSAGE(z_str, z_buf, "mbedtls_mpi_exp_mod incorrect"); +} + +TEST_CASE("test MPI modexp", "[bignum]") +{ + test_bignum_modexp("01000000", "1000", "2", "FFFFFFFF"); + test_bignum_modexp("014B5A90", "1234", "2", "FFFFFFF"); + test_bignum_modexp("01234321", "1111", "2", "FFFFFFFF"); + test_bignum_modexp("02", "5", "1", "3"); + test_bignum_modexp("22", "55", "1", "33"); + test_bignum_modexp("0222", "555", "1", "333"); + test_bignum_modexp("2222", "5555", "1", "3333"); + test_bignum_modexp("11", "5555", "1", "33"); + + test_bignum_modexp("55", "1111", "1", "77"); + test_bignum_modexp("88", "1111", "2", "BB"); + + test_bignum_modexp("01000000", "2", "128", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + + /* failures below here... */ + test_bignum_modexp("0ABCDEF12345", "ABCDEF12345", "1", "FFFFFFFFFFFF"); + test_bignum_modexp("0ABCDE", "ABCDE", "1", "FFFFF"); + + test_bignum_modexp("04", "2", "2", "9"); +} + diff --git a/components/mbedtls/test/test_mbedtls_sha.c b/components/mbedtls/test/test_mbedtls_sha.c new file mode 100644 index 000000000..721c59b76 --- /dev/null +++ b/components/mbedtls/test/test_mbedtls_sha.c @@ -0,0 +1,250 @@ +/* mbedTLS SHA unit tests + */ + +#include +#include +#include +#include +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "unity.h" +#include "sdkconfig.h" + +TEST_CASE("mbedtls SHA self-tests", "[mbedtls]") +{ + TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass."); + TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass."); + TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass."); + TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass."); +} + +static const unsigned char *one_hundred_as = (unsigned char *) + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + +static const unsigned char *one_hundred_bs = (unsigned char *) + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; + +static const uint8_t sha256_thousand_as[32] = { + 0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c, + 0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3 }; + +static const uint8_t sha256_thousand_bs[32] = { + 0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b +}; + +static const uint8_t sha512_thousand_bs[64] = { + 0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d +}; + +static const uint8_t sha384_thousand_bs[48] = { + 0x6d, 0xe5, 0xf5, 0x88, 0x57, 0x60, 0x83, 0xff, 0x7c, 0x94, 0x61, 0x5f, 0x8d, 0x96, 0xf2, 0x76, 0xd5, 0x3f, 0x77, 0x0c, 0x8e, 0xc1, 0xbf, 0xb6, 0x04, 0x27, 0xa4, 0xba, 0xea, 0x6c, 0x68, 0x44, 0xbd, 0xb0, 0x9c, 0xef, 0x6a, 0x09, 0x28, 0xe8, 0x1f, 0xfc, 0x95, 0x03, 0x69, 0x99, 0xab, 0x1a +}; + +static const uint8_t sha1_thousand_as[20] = { + 0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5, + 0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba }; + +TEST_CASE("mbedtls SHA interleaving", "[mbedtls]") +{ + mbedtls_sha1_context sha1_ctx; + mbedtls_sha256_context sha256_ctx; + mbedtls_sha512_context sha512_ctx; + unsigned char sha1[20], sha256[32], sha512[64]; + + mbedtls_sha1_init(&sha1_ctx); + mbedtls_sha256_init(&sha256_ctx); + mbedtls_sha512_init(&sha512_ctx); + + mbedtls_sha1_starts(&sha1_ctx); + mbedtls_sha256_starts(&sha256_ctx, false); + mbedtls_sha512_starts(&sha512_ctx, false); + + for (int i = 0; i < 10; i++) { + mbedtls_sha1_update(&sha1_ctx, one_hundred_as, 100); + mbedtls_sha256_update(&sha256_ctx, one_hundred_as, 100); + mbedtls_sha512_update(&sha512_ctx, one_hundred_bs, 100); + } + + mbedtls_sha1_finish(&sha1_ctx, sha1); + mbedtls_sha256_finish(&sha256_ctx, sha256); + mbedtls_sha512_finish(&sha512_ctx, sha512); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation"); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation"); +} + +static xSemaphoreHandle done_sem; +static void tskRunSHA1Test(void *pvParameters) +{ + mbedtls_sha1_context sha1_ctx; + unsigned char sha1[20]; + + for (int i = 0; i < 1000; i++) { + mbedtls_sha1_init(&sha1_ctx); + mbedtls_sha1_starts(&sha1_ctx); + for (int j = 0; j < 10; j++) { + mbedtls_sha1_update(&sha1_ctx, (unsigned char *)one_hundred_as, 100); + } + mbedtls_sha1_finish(&sha1_ctx, sha1); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation"); + } + xSemaphoreGive(done_sem); + vTaskDelete(NULL); +} + +static void tskRunSHA256Test(void *pvParameters) +{ + mbedtls_sha256_context sha256_ctx; + unsigned char sha256[32]; + + for (int i = 0; i < 1000; i++) { + mbedtls_sha256_init(&sha256_ctx); + mbedtls_sha256_starts(&sha256_ctx, false); + for (int j = 0; j < 10; j++) { + mbedtls_sha256_update(&sha256_ctx, (unsigned char *)one_hundred_bs, 100); + } + mbedtls_sha256_finish(&sha256_ctx, sha256); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation"); + } + xSemaphoreGive(done_sem); + vTaskDelete(NULL); +} + +TEST_CASE("mbedtls SHA multithreading", "[mbedtls]") +{ + done_sem = xSemaphoreCreateCounting(4, 0); + xTaskCreate(tskRunSHA1Test, "SHA1Task1", 8192, NULL, 3, NULL); + xTaskCreate(tskRunSHA1Test, "SHA1Task2", 8192, NULL, 3, NULL); + xTaskCreate(tskRunSHA256Test, "SHA256Task1", 8192, NULL, 3, NULL); + xTaskCreate(tskRunSHA256Test, "SHA256Task2", 8192, NULL, 3, NULL); + + for(int i = 0; i < 4; i++) { + if(!xSemaphoreTake(done_sem, 10000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("done_sem not released by test task"); + } + } + vSemaphoreDelete(done_sem); +} + +void tskRunSHASelftests(void *param) +{ + for (int i = 0; i < 5; i++) { + if(mbedtls_sha1_self_test(1)) { + printf("SHA1 self-tests failed.\n"); + while(1) {} + } + + if(mbedtls_sha256_self_test(1)) { + printf("SHA256 self-tests failed.\n"); + while(1) {} + } + + if(mbedtls_sha512_self_test(1)) { + printf("SHA512 self-tests failed.\n"); + while(1) {} + } + + if(mbedtls_sha512_self_test(1)) { + printf("SHA512 self-tests failed.\n"); + while(1) {} + } + } + xSemaphoreGive(done_sem); + vTaskDelete(NULL); +} + +TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]") +{ + done_sem = xSemaphoreCreateCounting(2, 0); + xTaskCreate(tskRunSHASelftests, "SHASelftests1", 8192, NULL, 3, NULL); + xTaskCreate(tskRunSHASelftests, "SHASelftests2", 8192, NULL, 3, NULL); + + for(int i = 0; i < 2; i++) { + if(!xSemaphoreTake(done_sem, 10000/portTICK_PERIOD_MS)) { + TEST_FAIL_MESSAGE("done_sem not released by test task"); + } + } + vSemaphoreDelete(done_sem); +} + +TEST_CASE("mbedtls SHA512 clone", "[mbedtls]") +{ + mbedtls_sha512_context ctx; + mbedtls_sha512_context clone; + unsigned char sha512[64]; + + mbedtls_sha512_init(&ctx); + mbedtls_sha512_starts(&ctx, false); + for (int i = 0; i < 5; i++) { + mbedtls_sha512_update(&ctx, one_hundred_bs, 100); + } + + mbedtls_sha512_clone(&clone, &ctx); + for (int i = 0; i < 5; i++) { + mbedtls_sha512_update(&ctx, one_hundred_bs, 100); + mbedtls_sha512_update(&clone, one_hundred_bs, 100); + } + mbedtls_sha512_finish(&ctx, sha512); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation"); + + mbedtls_sha512_finish(&clone, sha512); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation"); +} + +TEST_CASE("mbedtls SHA384 clone", "[mbedtls]") +{ + mbedtls_sha512_context ctx; + mbedtls_sha512_context clone; + unsigned char sha384[48]; + + mbedtls_sha512_init(&ctx); + mbedtls_sha512_starts(&ctx, true); + for (int i = 0; i < 5; i++) { + mbedtls_sha512_update(&ctx, one_hundred_bs, 100); + } + + mbedtls_sha512_clone(&clone, &ctx); + for (int i = 0; i < 5; i++) { + mbedtls_sha512_update(&ctx, one_hundred_bs, 100); + mbedtls_sha512_update(&clone, one_hundred_bs, 100); + } + mbedtls_sha512_finish(&ctx, sha384); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation"); + + mbedtls_sha512_finish(&clone, sha384); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation"); +} + + +TEST_CASE("mbedtls SHA256 clone", "[mbedtls]") +{ + mbedtls_sha256_context ctx; + mbedtls_sha256_context clone; + unsigned char sha256[64]; + + mbedtls_sha256_init(&ctx); + mbedtls_sha256_starts(&ctx, false); + for (int i = 0; i < 5; i++) { + mbedtls_sha256_update(&ctx, one_hundred_as, 100); + } + + mbedtls_sha256_clone(&clone, &ctx); + for (int i = 0; i < 5; i++) { + mbedtls_sha256_update(&ctx, one_hundred_as, 100); + mbedtls_sha256_update(&clone, one_hundred_as, 100); + } + mbedtls_sha256_finish(&ctx, sha256); + + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation"); + + mbedtls_sha256_finish(&clone, sha256); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation"); +} diff --git a/tools/unit-test-app/sdkconfig b/tools/unit-test-app/sdkconfig index cde49f3c8..7121dcc8a 100644 --- a/tools/unit-test-app/sdkconfig +++ b/tools/unit-test-app/sdkconfig @@ -9,6 +9,25 @@ CONFIG_TOOLPREFIX="xtensa-esp32-elf-" CONFIG_PYTHON="python" +# +# Bootloader config +# +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=2 + +# +# Secure boot configuration +# +CONFIG_SECURE_BOOTLOADER_DISABLED=y +# CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH is not set +# CONFIG_SECURE_BOOTLOADER_REFLASHABLE is not set +# CONFIG_SECURE_BOOTLOADER_ENABLED is not set + # # Serial flasher config # @@ -31,6 +50,12 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" # # Partition Table @@ -42,10 +67,14 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000 CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" CONFIG_APP_OFFSET=0x10000 +CONFIG_PHY_DATA_OFFSET=0xf000 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set # # Component config # +CONFIG_BT_RESERVE_DRAM=0 # # ESP32-specific config @@ -59,11 +88,30 @@ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_ESP32_ENABLE_STACK_NONE=y CONFIG_MEMMAP_SMP=y # CONFIG_MEMMAP_TRACEMEM is not set -# CONFIG_MEMMAP_SPISRAM is not set +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 CONFIG_MAIN_TASK_STACK_SIZE=4096 CONFIG_NEWLIB_STDOUT_ADDCR=y +# CONFIG_ULP_COPROC_ENABLED is not set +CONFIG_ULP_COPROC_RESERVE_MEM=0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +# CONFIG_TASK_WDT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +CONFIG_ESP32_PHY_AUTO_INIT=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_TX_POWER=20 # # FreeRTOS @@ -73,20 +121,18 @@ CONFIG_FREERTOS_CORETIMER_0=y # CONFIG_FREERTOS_CORETIMER_1 is not set # CONFIG_FREERTOS_CORETIMER_2 is not set CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3 -# CONFIG_FREERTOS_PANIC_PRINT_HALT is not set -CONFIG_FREERTOS_PANIC_PRINT_REBOOT=y -# CONFIG_FREERTOS_PANIC_SILENT_REBOOT is not set -# CONFIG_FREERTOS_PANIC_GDBSTUB is not set -CONFIG_FREERTOS_DEBUG_OCDAWARE=y CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y # CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set # CONFIG_FREERTOS_ASSERT_DISABLE is not set CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG=y # CONFIG_ENABLE_MEMORY_DEBUG is not set +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set # CONFIG_FREERTOS_DEBUG_INTERNALS is not set # @@ -104,22 +150,24 @@ CONFIG_LOG_COLORS=y # # LWIP # +# CONFIG_L2_TO_L3_COPY is not set CONFIG_LWIP_MAX_SOCKETS=4 CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0 # CONFIG_LWIP_SO_REUSE is not set +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 # # mbedTLS # CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 # CONFIG_MBEDTLS_DEBUG is not set +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_MPI_INTERRUPT_NUM=18 +CONFIG_MBEDTLS_HARDWARE_SHA=y # # SPI Flash driver # # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set - -# -# TESTS -# -CONFIG_FP_TEST_ENABLE=y From 88b264cfcee5cccd7cbd6aa0d277f6156d8e49a4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 25 Nov 2016 19:07:19 +1100 Subject: [PATCH 2/2] mbedTLS SHA: Fix cloning of SHA-384 digests Hardware unit only reads 384 bits of state for SHA-384 LOAD, which is enough for final digest but not enough if you plan to resume digest in software. --- components/esp32/hwcrypto/sha.c | 4 ++-- components/esp32/include/hwcrypto/sha.h | 7 +++++-- components/mbedtls/port/esp_sha512.c | 6 +++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/esp32/hwcrypto/sha.c b/components/esp32/hwcrypto/sha.c index 601981e2a..61e37b01d 100644 --- a/components/esp32/hwcrypto/sha.c +++ b/components/esp32/hwcrypto/sha.c @@ -82,7 +82,7 @@ inline static size_t sha_engine_index(esp_sha_type type) { } } -/* Return state & digest length (in bytes) for a given SHA type */ +/* Return digest length (in bytes) for a given SHA type */ inline static size_t sha_length(esp_sha_type type) { switch(type) { case SHA1: @@ -90,7 +90,7 @@ inline static size_t sha_length(esp_sha_type type) { case SHA2_256: return 32; case SHA2_384: - return 64; + return 48; case SHA2_512: return 64; default: diff --git a/components/esp32/include/hwcrypto/sha.h b/components/esp32/include/hwcrypto/sha.h index 2a0ec78ab..921f597fd 100644 --- a/components/esp32/include/hwcrypto/sha.h +++ b/components/esp32/include/hwcrypto/sha.h @@ -113,11 +113,14 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_ * value that is read is the SHA digest (in big endian * format). Otherwise, the value that is read is an interim SHA state. * + * @note If sha_type is SHA2_384, only 48 bytes of state will be read. + * This is enough for the final SHA2_384 digest, but if you want the + * interim SHA-384 state (to continue digesting) then pass SHA2_512 instead. + * * @param sha_type SHA algorithm in use. * * @param state Pointer to a memory buffer to hold the SHA state. Size - * is 20 bytes (SHA1), 64 bytes (SHA2_256), or 128 bytes (SHA2_384 or - * SHA2_512). + * is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512). * */ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state); diff --git a/components/mbedtls/port/esp_sha512.c b/components/mbedtls/port/esp_sha512.c index cfd0f3fdf..7a2bb15cb 100644 --- a/components/mbedtls/port/esp_sha512.c +++ b/components/mbedtls/port/esp_sha512.c @@ -121,8 +121,12 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst, if (src->mode == ESP_MBEDTLS_SHA512_HARDWARE) { /* Copy hardware digest state out to cloned state, which will be a software digest. + + Always read 512 bits of state, even for SHA-384 + (SHA-384 state is identical to SHA-512, only + digest is truncated.) */ - esp_sha_read_digest_state(sha_type(dst), dst->state); + esp_sha_read_digest_state(SHA2_512, dst->state); dst->mode = ESP_MBEDTLS_SHA512_SOFTWARE; } }