From 8417e0b725da988c7847fdadb959c61b260b1722 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 24 Jul 2020 15:44:30 -0700 Subject: [PATCH 1/5] Fixes for building against latest nRF52 SDK. Allow nRF5x AES GCM to be enabled (uses software, but ECB is accelerated). Fix in wolfCrypt test for building AES GSM only with `NO_AES_DECRYPT`. --- wolfcrypt/src/aes.c | 3 --- wolfcrypt/src/port/nrf51.c | 44 ++++++++++++++++++++++---------------- wolfcrypt/src/random.c | 37 ++++++++++++++++++-------------- wolfcrypt/test/test.c | 6 +++--- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index b0001f198..cf15e828d 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -3999,9 +3999,6 @@ static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) #if defined(HAVE_COLDFIRE_SEC) #error "Coldfire SEC doesn't currently support AES-GCM mode" -#elif defined(WOLFSSL_NRF51_AES) - #error "nRF51 doesn't currently support AES-GCM mode" - #endif #ifdef WOLFSSL_ARMASM diff --git a/wolfcrypt/src/port/nrf51.c b/wolfcrypt/src/port/nrf51.c index c7db4b067..112274606 100644 --- a/wolfcrypt/src/port/nrf51.c +++ b/wolfcrypt/src/port/nrf51.c @@ -25,8 +25,9 @@ #endif #include +#include -#ifdef WOLFSSL_NRF51 +#if defined(WOLFSSL_NRF51) || defined(WOLFSSL_NRF5x) #include "bsp.h" #include "nrf_delay.h" @@ -50,7 +51,7 @@ const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of #endif /* !NO_CRYPT_BENCHMARK */ /* AES */ -#if !defined(NO_AES) && !defined(SOFTDEVICE_PRESENT) +#if !defined(NO_AES) && defined(WOLFSSL_NRF51_AES) && !defined(SOFTDEVICE_PRESENT) static byte mAesInitDone = 0; #endif @@ -74,16 +75,14 @@ int nrf51_random_generate(byte* output, word32 size) } while (remaining > 0) { - err_code = nrf_drv_rng_bytes_available(&available); - if (err_code == NRF_SUCCESS) { - length = (remaining < available) ? remaining : available; - if (length > 0) { - err_code = nrf_drv_rng_rand(&output[pos], length); - remaining -= length; - pos += length; - } + available = 0; + nrf_drv_rng_bytes_available(&available); /* is void */ + length = (remaining < available) ? remaining : available; + if (length > 0) { + err_code = nrf_drv_rng_rand(&output[pos], length); + remaining -= length; + pos += length; } - if (err_code != NRF_SUCCESS) { break; } @@ -166,28 +165,37 @@ static void rtc_handler(nrf_drv_rtc_int_type_t int_type) } } +#ifndef RTC0_CONFIG_FREQUENCY +#define RTC0_CONFIG_FREQUENCY 32768 +#endif + static void rtc_config(void) { uint32_t err_code; - // Start the internal LFCLK XTAL oscillator + /* Start the internal LFCLK XTAL oscillator */ +#ifdef NRF52 + err_code = nrf_drv_clock_init(); + APP_ERROR_CHECK(err_code); + nrf_drv_clock_lfclk_request(NULL); +#else err_code = nrf_drv_clock_init(NULL); APP_ERROR_CHECK(err_code); - nrf_drv_clock_lfclk_request(); +#endif - // Initialize RTC instance + /* Initialize RTC instance */ err_code = nrf_drv_rtc_init(&rtc, NULL, rtc_handler); APP_ERROR_CHECK(err_code); - // Enable tick event + /* Enable tick event */ nrf_drv_rtc_tick_enable(&rtc, false); - // Set compare channel to trigger interrupt after 1 seconds + /* Set compare channel to trigger interrupt after 1 seconds */ err_code = nrf_drv_rtc_cc_set(&rtc, 0, RTC0_CONFIG_FREQUENCY, true); APP_ERROR_CHECK(err_code); - // Power on RTC instance + /* Power on RTC instance */ nrf_drv_rtc_enable(&rtc); } @@ -217,4 +225,4 @@ double current_time(int reset) } #endif /* !NO_CRYPT_BENCHMARK */ -#endif /* WOLFSSL_NRF51 */ +#endif /* WOLFSSL_NRF51 || WOLFSSL_NRF5x */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index afed0a4bb..0c3a79524 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2070,36 +2070,41 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } -#elif defined(WOLFSSL_NRF51) +#elif defined(WOLFSSL_NRF51) || defined(WOLFSSL_NRF5x) #include "app_error.h" #include "nrf_drv_rng.h" int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { int remaining = sz, length, pos = 0; - uint8_t available; uint32_t err_code; + uint8_t available; + static uint8_t initialized = 0; (void)os; /* Make sure RNG is running */ - err_code = nrf_drv_rng_init(NULL); - if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) { - return -1; + if (!initialized) { + err_code = nrf_drv_rng_init(NULL); + if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE + #ifdef NRF_ERROR_MODULE_ALREADY_INITIALIZED + && err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED + #endif + ) { + return -1; + } } while (remaining > 0) { - err_code = nrf_drv_rng_bytes_available(&available); - if (err_code == NRF_SUCCESS) { - length = (remaining < available) ? remaining : available; - if (length > 0) { - err_code = nrf_drv_rng_rand(&output[pos], length); - remaining -= length; - pos += length; + available = 0; + nrf_drv_rng_bytes_available(&available); /* void func */ + length = (remaining < available) ? remaining : available; + if (length > 0) { + err_code = nrf_drv_rng_rand(&output[pos], length); + if (err_code != NRF_SUCCESS) { + break; } - } - - if (err_code != NRF_SUCCESS) { - break; + remaining -= length; + pos += length; } } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 019e0b95c..3be2651e6 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8438,7 +8438,7 @@ int aesgcm_test(void) 0xba, 0x63, 0x7b, 0x39 }; -#if defined(HAVE_AES_DECRYPT) || defined(WOLFSSL_AES_256) +#if defined(WOLFSSL_AES_256) const byte a[] = { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, @@ -9014,7 +9014,7 @@ int gmac_test(void) if (XMEMCMP(t2, tag, sizeof(t2)) != 0) return -6201; -#if !(defined(WC_NO_RNG) || defined(HAVE_SELFTEST)) +#if !defined(WC_NO_RNG) && !defined(HAVE_SELFTEST) && !defined(NO_AES_DECRYPT) { const byte badT[] = { @@ -9053,7 +9053,7 @@ int gmac_test(void) return -6208; wc_FreeRng(&rng); } -#endif /* WC_NO_RNG HAVE_SELFTEST */ +#endif /* !WC_NO_RNG && !HAVE_SELFTEST && !NO_AES_DECRYPT */ #endif /* HAVE_FIPS */ return 0; From 99f72faedbf80f53fc6839f0890b71728bc9c37c Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 27 Jul 2020 14:30:41 -0700 Subject: [PATCH 2/5] Fix for nRF5x AES GCM so `key` is set. Fixes GMAC test. Don't force enable wolf memory and no ASN time for `WOLFSSL_NRF5x`. --- wolfcrypt/src/aes.c | 1 + wolfssl/wolfcrypt/settings.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index cf15e828d..3266d0f26 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2391,6 +2391,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) aes->keylen = keylen; aes->rounds = keylen/4 + 6; + XMEMCPY(aes->key, userKey, keylen); ret = nrf51_aes_set_key(userKey); #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 87f1ab396..ef9339e9f 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -620,7 +620,6 @@ #ifdef WOLFSSL_NRF5x #define SIZEOF_LONG 4 #define SIZEOF_LONG_LONG 8 - #define NO_ASN_TIME #define NO_DEV_RANDOM #define NO_FILESYSTEM #define NO_MAIN_DRIVER @@ -628,7 +627,6 @@ #define SINGLE_THREADED #define USE_FAST_MATH #define TFM_TIMING_RESISTANT - #define USE_WOLFSSL_MEMORY #define WOLFSSL_NRF51 #define WOLFSSL_USER_IO #define NO_SESSION_CACHE From 13eab0aeab87258925da33f6e8bcca597d08b35d Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 27 Jul 2020 15:26:55 -0700 Subject: [PATCH 3/5] Also check for `NRF52_SERIES`, since `NRF52` is only for `NRF52832_XXAA`. --- wolfcrypt/src/port/nrf51.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/port/nrf51.c b/wolfcrypt/src/port/nrf51.c index 112274606..042fe9da4 100644 --- a/wolfcrypt/src/port/nrf51.c +++ b/wolfcrypt/src/port/nrf51.c @@ -174,7 +174,7 @@ static void rtc_config(void) uint32_t err_code; /* Start the internal LFCLK XTAL oscillator */ -#ifdef NRF52 +#if defined(NRF52) || defined(NRF52_SERIES) err_code = nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); nrf_drv_clock_lfclk_request(NULL); From 9160a126e41623fb4ffc1aa1784dff34647ad388 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 28 Jul 2020 11:43:48 -0700 Subject: [PATCH 4/5] Fixes for running wolfCrypt test/benchmark with SECP256R1 disabled. Improved detection of ECC key generation size. --- wolfcrypt/benchmark/benchmark.c | 12 ++++++++++-- wolfcrypt/test/test.c | 28 ++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 5619fe35a..03b38d0f4 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -5195,9 +5195,17 @@ void bench_ntruKeyGen(void) #ifdef HAVE_ECC -/* Default to testing P-256 */ +/* Detect ECC key size to use */ #ifndef BENCH_ECC_SIZE - #define BENCH_ECC_SIZE 32 + #ifndef NO_ECC256 + #define BENCH_ECC_SIZE 32 + #elif defined(HAVE_ECC384) + #define BENCH_ECC_SIZE 48 + #elif defined(HAVE_ECC224) + #define BENCH_ECC_SIZE 28 + #else + #error No ECC keygen size defined for benchmark + #endif #endif static int bench_ecc_size = BENCH_ECC_SIZE; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 3be2651e6..db08db8d0 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -344,7 +344,7 @@ int scrypt_test(void); int ecc_encrypt_test(void); #endif #if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) /* skip for ATECC508/608A, cannot import private key buffers */ int ecc_test_buffers(void); #endif @@ -1016,7 +1016,7 @@ initDefaultName(); test_pass("ECC Enc test passed!\n"); #endif #if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) /* skip for ATECC508/608A, cannot import private key buffers */ if ( (ret = ecc_test_buffers()) != 0) return err_sys("ECC buffer test failed!\n", ret); @@ -17768,9 +17768,17 @@ int x963kdf_test(void) #ifdef HAVE_ECC +/* size to use for ECC key gen tests */ #ifndef ECC_KEYGEN_SIZE - /* size to use for ECC key gen tests */ - #define ECC_KEYGEN_SIZE 32 + #ifndef NO_ECC256 + #define ECC_KEYGEN_SIZE 32 + #elif defined(HAVE_ECC384) + #define ECC_KEYGEN_SIZE 48 + #elif defined(HAVE_ECC224) + #define ECC_KEYGEN_SIZE 28 + #else + #error No ECC keygen size defined for test + #endif #endif #ifdef BENCH_EMBEDDED #define ECC_SHARED_SIZE 128 @@ -18288,6 +18296,7 @@ static int ecc_test_make_pub(WC_RNG* rng) wc_ecc_init_ex(&key, HEAP_HINT, devId); +#ifndef NO_ECC256 #ifdef USE_CERT_BUFFERS_256 XMEMCPY(tmp, ecc_key_der_256, (size_t)sizeof_ecc_key_der_256); tmpSz = (size_t)sizeof_ecc_key_der_256; @@ -18367,13 +18376,16 @@ static int ecc_test_make_pub(WC_RNG* rng) ERROR_OUT(-9627, done); } #endif /* HAVE_ECC_KEY_EXPORT */ -#if defined(WOLFSSL_CRYPTOCELL) - /* create a new key since building private key from public key is unsupported */ +#endif /* !NO_ECC256 */ + + /* create a new key since above test for loading key is not supported */ +#if defined(WOLFSSL_CRYPTOCELL) || defined(NO_ECC256) ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, &key); if (ret != 0) { ERROR_OUT(-9628, done); } #endif + #ifdef HAVE_ECC_SIGN tmpSz = sizeof(tmp); ret = 0; @@ -20812,7 +20824,7 @@ done: #endif /* HAVE_ECC_ENCRYPT */ #if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \ - !defined(WOLFSSL_ATECC608A) + !defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) int ecc_test_buffers(void) { size_t bytes; ecc_key cliKey; @@ -20924,7 +20936,7 @@ int ecc_test_buffers(void) { return 0; } -#endif /* USE_CERT_BUFFERS_256 */ +#endif /* USE_CERT_BUFFERS_256 && !WOLFSSL_ATECCX08A && !NO_ECC256 */ #endif /* HAVE_ECC */ From 904241cba44263db8d4e4c6dff02bd7b8f2bc822 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 31 Jul 2020 11:56:32 -0700 Subject: [PATCH 5/5] Fix to only init the RNG once for nRF51/nRF52x. --- wolfcrypt/src/random.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 0c3a79524..5641844f8 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2092,6 +2092,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) ) { return -1; } + initialized = 1; } while (remaining > 0) {