Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbedtls mbed BLE_API nRF51822 AccelSensor
crypt.h
00001 #include "nrf_soc.h" 00002 #include "nrf_delay.h" 00003 #include "app_error.h" 00004 00005 #define ECB_KEY_LEN (16UL) 00006 #define COUNTER_BYTE_LEN (4UL) 00007 #define NONCE_RAND_BYTE_LEN (12UL) 00008 00009 // The RNG wait values are typical and not guaranteed. See Product Specifications for more info. 00010 #ifdef NRF51 00011 #define RNG_BYTE_WAIT_US (677UL) 00012 #elif defined NRF52 00013 #define RNG_BYTE_WAIT_US (124UL) 00014 #else 00015 #error "Either NRF51 or NRF52 must be defined." 00016 #endif 00017 00018 /** 00019 * @brief Uses the RNG to write a 12-byte nonce to a buffer 00020 * @details The 12 bytes will be written to the buffer starting at index 4 to leave 00021 * space for the 4-byte counter value. 00022 * 00023 * @param[in] p_buf An array of length 16 00024 */ 00025 void nonce_generate(uint8_t * p_buf) 00026 { 00027 uint8_t i = COUNTER_BYTE_LEN; 00028 uint8_t remaining = NONCE_RAND_BYTE_LEN; 00029 00030 // The random number pool may not contain enough bytes at the moment so 00031 // a busy wait may be necessary. 00032 while(0 != remaining) 00033 { 00034 uint32_t err_code; 00035 uint8_t available = 0; 00036 00037 err_code = sd_rand_application_bytes_available_get(&available); 00038 APP_ERROR_CHECK(err_code); 00039 00040 available = ((available > remaining) ? remaining : available); 00041 if (0 != available) 00042 { 00043 err_code = sd_rand_application_vector_get((p_buf + i), available); 00044 APP_ERROR_CHECK(err_code); 00045 00046 i += available; 00047 remaining -= available; 00048 } 00049 00050 if (0 != remaining) 00051 { 00052 nrf_delay_us(RNG_BYTE_WAIT_US * remaining); 00053 } 00054 } 00055 } 00056 00057 static bool m_initialized = false; 00058 00059 // NOTE: The ECB data must be located in RAM or a HardFault will be triggered. 00060 static nrf_ecb_hal_data_t m_ecb_data; 00061 00062 /** 00063 * @brief Initializes the module with the given nonce and key 00064 * @details The nonce will be copied to an internal buffer so it does not need to 00065 * be retained after the function returns. Additionally, a 32-bit counter 00066 * will be initialized to zero and placed into the least-significant 4 bytes 00067 * of the internal buffer. The nonce value should be generated in a 00068 * reasonable manner (e.g. using this module's nonce_generate function). 00069 * 00070 * @param[in] p_nonce An array of length 16 containing 12 random bytes 00071 * starting at index 4 00072 * @param[in] p_ecb_key An array of length 16 containing the ECB key 00073 */ 00074 void ctr_init(const uint8_t * p_nonce, const uint8_t * p_ecb_key) 00075 { 00076 m_initialized = true; 00077 00078 // Save the key. 00079 memcpy(&m_ecb_data.key[0], p_ecb_key, ECB_KEY_LEN); 00080 00081 // Copy the nonce. 00082 memcpy(&m_ecb_data.cleartext[COUNTER_BYTE_LEN], 00083 &p_nonce[COUNTER_BYTE_LEN], 00084 NONCE_RAND_BYTE_LEN); 00085 00086 // Zero the counter value. 00087 memset(&m_ecb_data.cleartext[0], 0x00, COUNTER_BYTE_LEN); 00088 } 00089 00090 static uint32_t crypt(uint8_t * buf) 00091 { 00092 uint8_t i; 00093 uint32_t err_code; 00094 00095 if (!m_initialized) 00096 { 00097 return NRF_ERROR_INVALID_STATE; 00098 } 00099 00100 err_code = sd_ecb_block_encrypt(&m_ecb_data); 00101 if (NRF_SUCCESS != err_code) 00102 { 00103 return err_code; 00104 } 00105 00106 for (i=0; i < ECB_KEY_LEN; i++) 00107 { 00108 buf[i] ^= m_ecb_data.ciphertext[i]; 00109 } 00110 00111 // Increment the counter. 00112 (*((uint32_t*) m_ecb_data.cleartext))++; 00113 00114 return NRF_SUCCESS; 00115 } 00116 00117 /** 00118 * @brief Encrypts the given buffer in-situ 00119 * @details The encryption step is done separately (using the nonce, counter, and 00120 * key) and then the result from the encryption is XOR'd with the given 00121 * buffer in-situ. The counter will be incremented only if no error occurs. 00122 * 00123 * @param[in] p_clear_text An array of length 16 containing the clear text 00124 * 00125 * @retval NRF_SUCCESS Success 00126 * @retval NRF_ERROR_INVALID_STATE Module has not been initialized 00127 * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED SoftDevice is present, but not enabled 00128 */ 00129 uint32_t ctr_encrypt(uint8_t * p_clear_text) 00130 { 00131 return crypt(p_clear_text); 00132 } 00133 00134 /** 00135 * @brief Decrypts the given buffer in-situ 00136 * @details The encryption step is done separately (using the nonce, counter, and 00137 * key) and then the result from the encryption is XOR'd with the given 00138 * buffer in-situ. The counter will be incremented only if no error occurs. 00139 * 00140 * @param[in] p_cipher_text An array of length 16 containing the cipher text 00141 * 00142 * @retval NRF_SUCCESS Succeess 00143 * @retval NRF_ERROR_INVALID_STATE Module has not been initialized 00144 * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED SoftDevice is present, but not enabled 00145 */ 00146 uint32_t ctr_decrypt(uint8_t * p_cipher_text) 00147 { 00148 return crypt(p_cipher_text); 00149 } 00150
Generated on Mon Dec 12 2022 13:13:31 by
1.7.2