imob

Dependencies:   mbedtls mbed BLE_API nRF51822 AccelSensor

Committer:
osilvam
Date:
Sat Mar 20 19:09:06 2021 +0000
Revision:
1:471d502617fe
Parent:
0:5284859bb3e8
last version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
osilvam 0:5284859bb3e8 1 #include "nrf_soc.h"
osilvam 0:5284859bb3e8 2 #include "nrf_delay.h"
osilvam 0:5284859bb3e8 3 #include "app_error.h"
osilvam 0:5284859bb3e8 4
osilvam 0:5284859bb3e8 5 #define ECB_KEY_LEN (16UL)
osilvam 0:5284859bb3e8 6 #define COUNTER_BYTE_LEN (4UL)
osilvam 0:5284859bb3e8 7 #define NONCE_RAND_BYTE_LEN (12UL)
osilvam 0:5284859bb3e8 8
osilvam 0:5284859bb3e8 9 // The RNG wait values are typical and not guaranteed. See Product Specifications for more info.
osilvam 0:5284859bb3e8 10 #ifdef NRF51
osilvam 0:5284859bb3e8 11 #define RNG_BYTE_WAIT_US (677UL)
osilvam 0:5284859bb3e8 12 #elif defined NRF52
osilvam 0:5284859bb3e8 13 #define RNG_BYTE_WAIT_US (124UL)
osilvam 0:5284859bb3e8 14 #else
osilvam 0:5284859bb3e8 15 #error "Either NRF51 or NRF52 must be defined."
osilvam 0:5284859bb3e8 16 #endif
osilvam 0:5284859bb3e8 17
osilvam 0:5284859bb3e8 18 /**
osilvam 0:5284859bb3e8 19 * @brief Uses the RNG to write a 12-byte nonce to a buffer
osilvam 0:5284859bb3e8 20 * @details The 12 bytes will be written to the buffer starting at index 4 to leave
osilvam 0:5284859bb3e8 21 * space for the 4-byte counter value.
osilvam 0:5284859bb3e8 22 *
osilvam 0:5284859bb3e8 23 * @param[in] p_buf An array of length 16
osilvam 0:5284859bb3e8 24 */
osilvam 0:5284859bb3e8 25 void nonce_generate(uint8_t * p_buf)
osilvam 0:5284859bb3e8 26 {
osilvam 0:5284859bb3e8 27 uint8_t i = COUNTER_BYTE_LEN;
osilvam 0:5284859bb3e8 28 uint8_t remaining = NONCE_RAND_BYTE_LEN;
osilvam 0:5284859bb3e8 29
osilvam 0:5284859bb3e8 30 // The random number pool may not contain enough bytes at the moment so
osilvam 0:5284859bb3e8 31 // a busy wait may be necessary.
osilvam 0:5284859bb3e8 32 while(0 != remaining)
osilvam 0:5284859bb3e8 33 {
osilvam 0:5284859bb3e8 34 uint32_t err_code;
osilvam 0:5284859bb3e8 35 uint8_t available = 0;
osilvam 0:5284859bb3e8 36
osilvam 0:5284859bb3e8 37 err_code = sd_rand_application_bytes_available_get(&available);
osilvam 0:5284859bb3e8 38 APP_ERROR_CHECK(err_code);
osilvam 0:5284859bb3e8 39
osilvam 0:5284859bb3e8 40 available = ((available > remaining) ? remaining : available);
osilvam 0:5284859bb3e8 41 if (0 != available)
osilvam 0:5284859bb3e8 42 {
osilvam 0:5284859bb3e8 43 err_code = sd_rand_application_vector_get((p_buf + i), available);
osilvam 0:5284859bb3e8 44 APP_ERROR_CHECK(err_code);
osilvam 0:5284859bb3e8 45
osilvam 0:5284859bb3e8 46 i += available;
osilvam 0:5284859bb3e8 47 remaining -= available;
osilvam 0:5284859bb3e8 48 }
osilvam 0:5284859bb3e8 49
osilvam 0:5284859bb3e8 50 if (0 != remaining)
osilvam 0:5284859bb3e8 51 {
osilvam 0:5284859bb3e8 52 nrf_delay_us(RNG_BYTE_WAIT_US * remaining);
osilvam 0:5284859bb3e8 53 }
osilvam 0:5284859bb3e8 54 }
osilvam 0:5284859bb3e8 55 }
osilvam 0:5284859bb3e8 56
osilvam 0:5284859bb3e8 57 static bool m_initialized = false;
osilvam 0:5284859bb3e8 58
osilvam 0:5284859bb3e8 59 // NOTE: The ECB data must be located in RAM or a HardFault will be triggered.
osilvam 0:5284859bb3e8 60 static nrf_ecb_hal_data_t m_ecb_data;
osilvam 0:5284859bb3e8 61
osilvam 0:5284859bb3e8 62 /**
osilvam 0:5284859bb3e8 63 * @brief Initializes the module with the given nonce and key
osilvam 0:5284859bb3e8 64 * @details The nonce will be copied to an internal buffer so it does not need to
osilvam 0:5284859bb3e8 65 * be retained after the function returns. Additionally, a 32-bit counter
osilvam 0:5284859bb3e8 66 * will be initialized to zero and placed into the least-significant 4 bytes
osilvam 0:5284859bb3e8 67 * of the internal buffer. The nonce value should be generated in a
osilvam 0:5284859bb3e8 68 * reasonable manner (e.g. using this module's nonce_generate function).
osilvam 0:5284859bb3e8 69 *
osilvam 0:5284859bb3e8 70 * @param[in] p_nonce An array of length 16 containing 12 random bytes
osilvam 0:5284859bb3e8 71 * starting at index 4
osilvam 0:5284859bb3e8 72 * @param[in] p_ecb_key An array of length 16 containing the ECB key
osilvam 0:5284859bb3e8 73 */
osilvam 0:5284859bb3e8 74 void ctr_init(const uint8_t * p_nonce, const uint8_t * p_ecb_key)
osilvam 0:5284859bb3e8 75 {
osilvam 0:5284859bb3e8 76 m_initialized = true;
osilvam 0:5284859bb3e8 77
osilvam 0:5284859bb3e8 78 // Save the key.
osilvam 0:5284859bb3e8 79 memcpy(&m_ecb_data.key[0], p_ecb_key, ECB_KEY_LEN);
osilvam 0:5284859bb3e8 80
osilvam 0:5284859bb3e8 81 // Copy the nonce.
osilvam 0:5284859bb3e8 82 memcpy(&m_ecb_data.cleartext[COUNTER_BYTE_LEN],
osilvam 0:5284859bb3e8 83 &p_nonce[COUNTER_BYTE_LEN],
osilvam 0:5284859bb3e8 84 NONCE_RAND_BYTE_LEN);
osilvam 0:5284859bb3e8 85
osilvam 0:5284859bb3e8 86 // Zero the counter value.
osilvam 0:5284859bb3e8 87 memset(&m_ecb_data.cleartext[0], 0x00, COUNTER_BYTE_LEN);
osilvam 0:5284859bb3e8 88 }
osilvam 0:5284859bb3e8 89
osilvam 0:5284859bb3e8 90 static uint32_t crypt(uint8_t * buf)
osilvam 0:5284859bb3e8 91 {
osilvam 0:5284859bb3e8 92 uint8_t i;
osilvam 0:5284859bb3e8 93 uint32_t err_code;
osilvam 0:5284859bb3e8 94
osilvam 0:5284859bb3e8 95 if (!m_initialized)
osilvam 0:5284859bb3e8 96 {
osilvam 0:5284859bb3e8 97 return NRF_ERROR_INVALID_STATE;
osilvam 0:5284859bb3e8 98 }
osilvam 0:5284859bb3e8 99
osilvam 0:5284859bb3e8 100 err_code = sd_ecb_block_encrypt(&m_ecb_data);
osilvam 0:5284859bb3e8 101 if (NRF_SUCCESS != err_code)
osilvam 0:5284859bb3e8 102 {
osilvam 0:5284859bb3e8 103 return err_code;
osilvam 0:5284859bb3e8 104 }
osilvam 0:5284859bb3e8 105
osilvam 0:5284859bb3e8 106 for (i=0; i < ECB_KEY_LEN; i++)
osilvam 0:5284859bb3e8 107 {
osilvam 0:5284859bb3e8 108 buf[i] ^= m_ecb_data.ciphertext[i];
osilvam 0:5284859bb3e8 109 }
osilvam 0:5284859bb3e8 110
osilvam 0:5284859bb3e8 111 // Increment the counter.
osilvam 0:5284859bb3e8 112 (*((uint32_t*) m_ecb_data.cleartext))++;
osilvam 0:5284859bb3e8 113
osilvam 0:5284859bb3e8 114 return NRF_SUCCESS;
osilvam 0:5284859bb3e8 115 }
osilvam 0:5284859bb3e8 116
osilvam 0:5284859bb3e8 117 /**
osilvam 0:5284859bb3e8 118 * @brief Encrypts the given buffer in-situ
osilvam 0:5284859bb3e8 119 * @details The encryption step is done separately (using the nonce, counter, and
osilvam 0:5284859bb3e8 120 * key) and then the result from the encryption is XOR'd with the given
osilvam 0:5284859bb3e8 121 * buffer in-situ. The counter will be incremented only if no error occurs.
osilvam 0:5284859bb3e8 122 *
osilvam 0:5284859bb3e8 123 * @param[in] p_clear_text An array of length 16 containing the clear text
osilvam 0:5284859bb3e8 124 *
osilvam 0:5284859bb3e8 125 * @retval NRF_SUCCESS Success
osilvam 0:5284859bb3e8 126 * @retval NRF_ERROR_INVALID_STATE Module has not been initialized
osilvam 0:5284859bb3e8 127 * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED SoftDevice is present, but not enabled
osilvam 0:5284859bb3e8 128 */
osilvam 0:5284859bb3e8 129 uint32_t ctr_encrypt(uint8_t * p_clear_text)
osilvam 0:5284859bb3e8 130 {
osilvam 0:5284859bb3e8 131 return crypt(p_clear_text);
osilvam 0:5284859bb3e8 132 }
osilvam 0:5284859bb3e8 133
osilvam 0:5284859bb3e8 134 /**
osilvam 0:5284859bb3e8 135 * @brief Decrypts the given buffer in-situ
osilvam 0:5284859bb3e8 136 * @details The encryption step is done separately (using the nonce, counter, and
osilvam 0:5284859bb3e8 137 * key) and then the result from the encryption is XOR'd with the given
osilvam 0:5284859bb3e8 138 * buffer in-situ. The counter will be incremented only if no error occurs.
osilvam 0:5284859bb3e8 139 *
osilvam 0:5284859bb3e8 140 * @param[in] p_cipher_text An array of length 16 containing the cipher text
osilvam 0:5284859bb3e8 141 *
osilvam 0:5284859bb3e8 142 * @retval NRF_SUCCESS Succeess
osilvam 0:5284859bb3e8 143 * @retval NRF_ERROR_INVALID_STATE Module has not been initialized
osilvam 0:5284859bb3e8 144 * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED SoftDevice is present, but not enabled
osilvam 0:5284859bb3e8 145 */
osilvam 0:5284859bb3e8 146 uint32_t ctr_decrypt(uint8_t * p_cipher_text)
osilvam 0:5284859bb3e8 147 {
osilvam 0:5284859bb3e8 148 return crypt(p_cipher_text);
osilvam 0:5284859bb3e8 149 }
osilvam 0:5284859bb3e8 150