summaryrefslogtreecommitdiff
path: root/wolfcrypt/src/port/nrf51.c
diff options
context:
space:
mode:
Diffstat (limited to 'wolfcrypt/src/port/nrf51.c')
-rw-r--r--wolfcrypt/src/port/nrf51.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/wolfcrypt/src/port/nrf51.c b/wolfcrypt/src/port/nrf51.c
new file mode 100644
index 0000000..c7db4b0
--- /dev/null
+++ b/wolfcrypt/src/port/nrf51.c
@@ -0,0 +1,220 @@
+/* nrf51.c
+ *
+ * Copyright (C) 2006-2020 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_NRF51
+
+#include "bsp.h"
+#include "nrf_delay.h"
+#include "app_uart.h"
+#include "app_error.h"
+#include "nrf_drv_rng.h"
+#include "nrf_drv_rtc.h"
+#include "nrf_drv_clock.h"
+#include "nrf_ecb.h"
+
+#ifdef SOFTDEVICE_PRESENT
+ #include "softdevice_handler.h"
+ #include "nrf_soc.h"
+#endif /* SOFTDEVICE_PRESENT */
+
+/* RTC */
+#ifndef NO_CRYPT_BENCHMARK
+static byte mRtcInitDone = 0;
+static int mRtcSec = 0;
+const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of nrf_drv_rtc for RTC0. */
+#endif /* !NO_CRYPT_BENCHMARK */
+
+/* AES */
+#if !defined(NO_AES) && !defined(SOFTDEVICE_PRESENT)
+ static byte mAesInitDone = 0;
+#endif
+
+/** @brief Function for getting vector of random numbers.
+ *
+ * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
+ * @param[in] length Number of bytes to take from pool and place in p_buff.
+ *
+ * @retval 0 = Success, else error
+ */
+int nrf51_random_generate(byte* output, word32 size)
+{
+ int remaining = size, length, pos = 0;
+ uint8_t available;
+ uint32_t err_code;
+
+ /* 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;
+ }
+
+ 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;
+ }
+ }
+
+ if (err_code != NRF_SUCCESS) {
+ break;
+ }
+ }
+
+ return (err_code == NRF_SUCCESS) ? 0 : -1;
+}
+
+#if !defined(NO_AES) && defined(WOLFSSL_NRF51_AES)
+
+#ifdef SOFTDEVICE_PRESENT
+static const byte* nRF51AesKey = NULL;
+#endif
+int nrf51_aes_set_key(const byte* key)
+{
+#ifdef SOFTDEVICE_PRESENT
+ nRF51AesKey = key;
+#else
+ if (!mAesInitDone) {
+ nrf_ecb_init();
+ mAesInitDone = 1;
+ }
+ nrf_ecb_set_key(key);
+#endif
+ return 0;
+}
+
+
+int nrf51_aes_encrypt(const byte* in, const byte* key, word32 rounds, byte* out)
+{
+ int ret;
+ uint32_t err_code = 0;
+#ifdef SOFTDEVICE_PRESENT
+ nrf_ecb_hal_data_t ecb_hal_data;
+#endif
+
+ /* Set key */
+ ret = nrf51_aes_set_key(key);
+ if (ret != 0) {
+ return ret;
+ }
+
+#ifdef SOFTDEVICE_PRESENT
+ /* Define ECB record */
+ XMEMCPY(ecb_hal_data.key, nRF51AesKey, SOC_ECB_KEY_LENGTH);
+ XMEMCPY(ecb_hal_data.cleartext, in, SOC_ECB_CLEARTEXT_LENGTH);
+ XMEMSET(ecb_hal_data.ciphertext, 0, SOC_ECB_CIPHERTEXT_LENGTH);
+
+ /* Perform block encrypt */
+ err_code = sd_ecb_block_encrypt(&ecb_hal_data);
+ if (err_code != NRF_SUCCESS) {
+ return -1;
+ }
+
+ /* Grab result */
+ XMEMCPY(out, ecb_hal_data.ciphertext, SOC_ECB_CIPHERTEXT_LENGTH);
+#else
+ err_code = nrf_ecb_crypt(out, in);
+ err_code = err_code ? 0 : -1;
+#endif
+
+ return err_code;
+}
+
+#endif /* !NO_AES && WOLFSSL_NRF51_AES */
+
+
+#ifndef NO_CRYPT_BENCHMARK
+static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
+{
+ if (int_type == NRF_DRV_RTC_INT_COMPARE0)
+ {
+ mRtcSec++;
+ nrf_drv_rtc_counter_clear(&rtc);
+ nrf_drv_rtc_int_enable(&rtc, RTC_CHANNEL_INT_MASK(0));
+
+#ifdef BSP_LED_0
+ nrf_gpio_pin_toggle(BSP_LED_0);
+#endif
+ }
+}
+
+static void rtc_config(void)
+{
+ uint32_t err_code;
+
+ // Start the internal LFCLK XTAL oscillator
+ err_code = nrf_drv_clock_init(NULL);
+ APP_ERROR_CHECK(err_code);
+
+ nrf_drv_clock_lfclk_request();
+
+ // Initialize RTC instance
+ err_code = nrf_drv_rtc_init(&rtc, NULL, rtc_handler);
+ APP_ERROR_CHECK(err_code);
+
+ // Enable tick event
+ nrf_drv_rtc_tick_enable(&rtc, false);
+
+ // 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
+ nrf_drv_rtc_enable(&rtc);
+}
+
+static int rtc_get_ms(void)
+{
+ /* Prescaler is 12-bit for COUNTER: frequency = (32768/(PRESCALER+1)) */
+ int frequency = (32768 / (rtc_prescaler_get(rtc.p_reg) + 1));
+ int counter = nrf_drv_rtc_counter_get(&rtc);
+
+ /* Convert with rounding frequency to milliseconds */
+ return ((counter * 1000) + (frequency / 2) ) / frequency;
+}
+
+double current_time(int reset)
+{
+ double time;
+
+ if (!mRtcInitDone) {
+ rtc_config();
+ mRtcInitDone = 1;
+ }
+
+ time = mRtcSec;
+ time += (double)rtc_get_ms() / 1000;
+
+ return time;
+}
+#endif /* !NO_CRYPT_BENCHMARK */
+
+#endif /* WOLFSSL_NRF51 */