nrf_gzp.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /**
  2. * Copyright (c) 2009 - 2019, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /**
  41. * @file
  42. * @brief Implementation of Gazell Pairing Library (gzp), Common functions.
  43. * @defgroup gzp_source_common Gazell Pairing common functions implementation
  44. * @{
  45. * @ingroup gzp_04_source
  46. */
  47. #include "nrf_gzp.h"
  48. #include "nrf_gzll.h"
  49. #include "nrf_ecb.h"
  50. #include <string.h>
  51. #define SOURCE_FILE NRF_SOURCE_FILE_GZP ///< File identifer for asserts.
  52. /******************************************************************************/
  53. /** @name Global variables
  54. * @{ */
  55. /******************************************************************************/
  56. /**
  57. * Constant holding base address part of the pairing address.
  58. */
  59. static const uint8_t pairing_base_address[4] = { GZP_ADDRESS };
  60. /**
  61. * Constant holding prefix byte of the pairing address.
  62. */
  63. static const uint8_t pairing_address_prefix_byte = 0;
  64. /**
  65. * Constant holding pre-defined "validation ID".
  66. */
  67. static const uint8_t gzp_validation_id[GZP_VALIDATION_ID_LENGTH] = GZP_VALIDATION_ID;
  68. /**
  69. * Constant holding pre-defined "secret key".
  70. */
  71. static const uint8_t gzp_secret_key[16] = GZP_SECRET_KEY;
  72. /**
  73. * Variable used for AES key selection
  74. */
  75. static gzp_key_select_t gzp_key_select;
  76. /** @} */
  77. /******************************************************************************/
  78. /** @name Misc. external variables.
  79. * @{ */
  80. /******************************************************************************/
  81. static uint8_t gzp_session_token[GZP_SESSION_TOKEN_LENGTH];
  82. static uint8_t gzp_dyn_key[GZP_DYN_KEY_LENGTH];
  83. /** @} */
  84. /******************************************************************************/
  85. /** @name Implementation common internal GZP functions
  86. * @{ */
  87. /******************************************************************************/
  88. bool gzp_update_radio_params(const uint8_t* system_address)
  89. {
  90. uint8_t i;
  91. uint8_t channels[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE];
  92. uint32_t channel_table_size;
  93. uint32_t pairing_base_address_32, system_address_32;
  94. bool update_ok = true;
  95. bool gzll_enabled_state;
  96. gzll_enabled_state = nrf_gzll_is_enabled();
  97. // Configure "global" pairing address
  98. pairing_base_address_32 = (pairing_base_address[0]) +
  99. ((uint32_t)pairing_base_address[1] << 8) +
  100. ((uint32_t)pairing_base_address[2] << 16) +
  101. ((uint32_t)pairing_base_address[3] << 24) ;
  102. if (system_address != NULL)
  103. {
  104. system_address_32 = (system_address[0]) +
  105. ((uint32_t)system_address[1] << 8) +
  106. ((uint32_t)system_address[2] << 16) +
  107. ((uint32_t)system_address[3] << 24) ;
  108. }
  109. else
  110. {
  111. return false;
  112. }
  113. nrf_gzp_disable_gzll();
  114. update_ok = update_ok && nrf_gzll_set_base_address_0(pairing_base_address_32);
  115. update_ok = update_ok && nrf_gzll_set_address_prefix_byte(GZP_PAIRING_PIPE, pairing_address_prefix_byte);
  116. update_ok = update_ok && nrf_gzll_set_base_address_1(system_address_32);
  117. // Configure address for pipe 1 - 5. Address byte set to equal pipe number.
  118. for (i = 1; i < NRF_GZLL_CONST_PIPE_COUNT; i++)
  119. {
  120. update_ok = update_ok && nrf_gzll_set_address_prefix_byte(i,i);
  121. }
  122. channel_table_size = nrf_gzll_get_channel_table_size();
  123. gzp_generate_channels(&channels[0], system_address, channel_table_size);
  124. // Write generated channel subset to Gazell Link Layer
  125. update_ok = update_ok && nrf_gzll_set_channel_table(&channels[0], channel_table_size);
  126. if (gzll_enabled_state)
  127. {
  128. update_ok = update_ok && nrf_gzll_enable();
  129. }
  130. return update_ok;
  131. }
  132. void gzp_generate_channels(uint8_t* ch_dst, const uint8_t* system_address, uint8_t channel_tab_size)
  133. {
  134. uint8_t binsize, spacing, i;
  135. binsize = (GZP_CHANNEL_MAX - GZP_CHANNEL_MIN) / channel_tab_size;
  136. ch_dst[0] = GZP_CHANNEL_LOW;
  137. ch_dst[channel_tab_size - 1] = GZP_CHANNEL_HIGH;
  138. if (system_address != NULL)
  139. {
  140. for (i = 1; i < (channel_tab_size - 1); i++)
  141. {
  142. ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize);
  143. }
  144. }
  145. // If channels are too close, shift them to better positions
  146. for (i = 1; i < channel_tab_size; i++)
  147. {
  148. spacing = (ch_dst[i] - ch_dst[i - 1]);
  149. if (spacing < GZP_CHANNEL_SPACING_MIN)
  150. {
  151. ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing);
  152. }
  153. }
  154. }
  155. __INLINE void nrf_gzp_disable_gzll(void)
  156. {
  157. if (nrf_gzll_is_enabled())
  158. {
  159. nrf_gzll_disable();
  160. __WFI();
  161. while (nrf_gzll_is_enabled())
  162. {
  163. }
  164. }
  165. }
  166. #ifndef GZP_CRYPT_DISABLE
  167. void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length)
  168. {
  169. uint8_t i;
  170. for (i = 0; i < length; i++)
  171. {
  172. *dst = *src ^ *pad;
  173. dst++;
  174. src++;
  175. pad++;
  176. }
  177. }
  178. bool gzp_validate_id(const uint8_t* id)
  179. {
  180. return (memcmp(id, (void*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH) == 0);
  181. }
  182. void gzp_add_validation_id(uint8_t* dst)
  183. {
  184. memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH);
  185. }
  186. void gzp_crypt_set_session_token(const uint8_t * token)
  187. {
  188. memcpy(gzp_session_token, (void const*)token, GZP_SESSION_TOKEN_LENGTH);
  189. }
  190. void gzp_crypt_set_dyn_key(const uint8_t* key)
  191. {
  192. memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH);
  193. }
  194. void gzp_crypt_get_session_token(uint8_t * dst_token)
  195. {
  196. memcpy(dst_token, (void const*)gzp_session_token, GZP_SESSION_TOKEN_LENGTH);
  197. }
  198. void gzp_crypt_get_dyn_key(uint8_t* dst_key)
  199. {
  200. memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH);
  201. }
  202. void gzp_crypt_select_key(gzp_key_select_t key_select)
  203. {
  204. gzp_key_select = key_select;
  205. }
  206. void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length)
  207. {
  208. uint8_t i;
  209. uint8_t key[16];
  210. uint8_t iv[16];
  211. // Build AES key based on "gzp_key_select"
  212. switch (gzp_key_select)
  213. {
  214. case GZP_ID_EXCHANGE:
  215. memcpy(key, (void const*)gzp_secret_key, 16);
  216. break;
  217. case GZP_KEY_EXCHANGE:
  218. memcpy(key, (void const*)gzp_secret_key, 16);
  219. gzp_get_host_id(key);
  220. break;
  221. case GZP_DATA_EXCHANGE:
  222. memcpy(key, (void const*)gzp_secret_key, 16);
  223. memcpy(key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH);
  224. break;
  225. default:
  226. return;
  227. }
  228. // Build init vector from "gzp_session_token"
  229. for (i = 0; i < 16; i++)
  230. {
  231. if (i < GZP_SESSION_TOKEN_LENGTH)
  232. {
  233. iv[i] = gzp_session_token[i];
  234. }
  235. else
  236. {
  237. iv[i] = 0;
  238. }
  239. }
  240. // Set up hal_aes using new key and init vector
  241. (void)nrf_ecb_init();
  242. nrf_ecb_set_key(key);
  243. //hal_aes_setup(false, ECB, key, NULL); // Note, here we skip the IV as we use ECB mode
  244. // Encrypt IV using ECB mode
  245. (void)nrf_ecb_crypt(iv, iv);
  246. // Encrypt data by XOR'ing with AES output
  247. gzp_xor_cipher(dst, src, iv, length);
  248. }
  249. void gzp_random_numbers_generate(uint8_t * dst, uint8_t n)
  250. {
  251. uint8_t i;
  252. NRF_RNG->EVENTS_VALRDY=0;
  253. NRF_RNG->TASKS_START = 1;
  254. for (i = 0; i < n; i++)
  255. {
  256. while (NRF_RNG->EVENTS_VALRDY==0)
  257. {}
  258. dst[i] = (uint8_t)NRF_RNG->VALUE;
  259. NRF_RNG->EVENTS_VALRDY=0;
  260. }
  261. NRF_RNG->TASKS_STOP = 1;
  262. }
  263. /******************************************************************************/
  264. /** @name Implementation of nRF51 specific GZP functions
  265. * @{ */
  266. /******************************************************************************/
  267. /**
  268. * @brief Function for setting the Primask variable. Only necessary if ARMCC
  269. * compiler skips __set_PRIMASK at high optimization levels.
  270. *
  271. * @param primask The primask value. 1 to disable interrupts, 0 otherwise.
  272. */
  273. static void nrf_gzp_set_primask(uint32_t primask)
  274. {
  275. #if defined(__CC_ARM)
  276. //lint -save -e10 -e618 -e438 -e550 -e526 -e628 -e526
  277. volatile register uint32_t __regPriMask __ASM("primask");
  278. __regPriMask = (primask);
  279. #else
  280. __set_PRIMASK(primask);
  281. #endif
  282. //lint -restore
  283. }
  284. void nrf_gzp_flush_rx_fifo(uint32_t pipe)
  285. {
  286. static uint8_t dummy_packet[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
  287. uint32_t length;
  288. nrf_gzp_set_primask(1);
  289. while (nrf_gzll_get_rx_fifo_packet_count(pipe) >0)
  290. {
  291. length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
  292. (void)nrf_gzll_fetch_packet_from_rx_fifo(pipe,dummy_packet,&length);
  293. }
  294. nrf_gzp_set_primask(0);
  295. }
  296. /** @} */
  297. /******************************************************************************/
  298. /** @name Implementation of debug functions
  299. * @{ */
  300. /******************************************************************************/
  301. /** @} */
  302. /** @} */
  303. #endif