Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

311 wiersze
10 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief This module contains M2M Wi-Fi APIs implementation.
  6. *
  7. * Copyright (c) 2017-2018 Atmel Corporation. All rights reserved.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions are met:
  15. *
  16. * 1. Redistributions of source code must retain the above copyright notice,
  17. * this list of conditions and the following disclaimer.
  18. *
  19. * 2. Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. *
  23. * 3. The name of Atmel may not be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  27. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  28. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  29. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  30. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  34. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  35. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * \asf_license_stop
  39. *
  40. */
  41. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  42. INCLUDES
  43. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  44. #include "driver/include/m2m_ssl.h"
  45. #include "driver/source/m2m_hif.h"
  46. #include "driver/source/nmasic.h"
  47. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  48. MACROS
  49. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  50. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  51. DATA TYPES
  52. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  53. static tpfAppSSLCb gpfAppSSLCb = NULL;
  54. static uint32 gu32HIFAddr = 0;
  55. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  56. FUNCTION PROTOTYPES
  57. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  58. /*!
  59. @fn \ m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
  60. @brief SSL callback function
  61. @param [in] u8OpCode
  62. HIF Opcode type.
  63. @param [in] u16DataSize
  64. HIF data length.
  65. @param [in] u32Addr
  66. HIF address.
  67. */
  68. static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
  69. {
  70. sint8 s8tmp = M2M_SUCCESS;
  71. switch (u8OpCode) {
  72. case M2M_SSL_REQ_ECC: {
  73. tstrEccReqInfo strEccREQ;
  74. s8tmp = hif_receive(u32Addr, (uint8 *)&strEccREQ, sizeof(tstrEccReqInfo), 0);
  75. if (s8tmp == M2M_SUCCESS) {
  76. if (gpfAppSSLCb) {
  77. gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
  78. gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
  79. }
  80. }
  81. } break;
  82. case M2M_SSL_RESP_SET_CS_LIST: {
  83. tstrSslSetActiveCsList strCsList;
  84. s8tmp = hif_receive(u32Addr, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
  85. if (s8tmp == M2M_SUCCESS) {
  86. if (gpfAppSSLCb)
  87. gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
  88. }
  89. } break;
  90. }
  91. if (s8tmp != M2M_SUCCESS) {
  92. M2M_ERR("Error receiving SSL from the HIF\n");
  93. }
  94. }
  95. /*!
  96. @fn \ m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
  97. @brief Sends ECC responses to the WINC
  98. @param [in] strECCResp
  99. ECC Response struct.
  100. @param [in] pu8RspDataBuffe
  101. Pointer of the response data to be sent.
  102. @param [in] u16RspDataSz
  103. Response data size.
  104. @return The function SHALL return 0 for success and a negative value otherwise.
  105. */
  106. NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo *strECCResp, uint8 *pu8RspDataBuff, uint16 u16RspDataSz)
  107. {
  108. sint8 s8Ret = M2M_SUCCESS;
  109. s8Ret = hif_send(M2M_REQ_GROUP_SSL,
  110. (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT),
  111. (uint8 *)strECCResp,
  112. sizeof(tstrEccReqInfo),
  113. pu8RspDataBuff,
  114. u16RspDataSz,
  115. sizeof(tstrEccReqInfo));
  116. return s8Ret;
  117. }
  118. /*!
  119. @fn \ m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size)
  120. @brief Sends certificates to the WINC
  121. @param [in] pu8Buffer
  122. Pointer to the certificates.
  123. @param [in] u32BufferSz
  124. Size of the certificates.
  125. @return The function SHALL return 0 for success and a negative value otherwise.
  126. */
  127. NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8 *pu8Buffer, uint32 u32BufferSz)
  128. {
  129. sint8 s8Ret = M2M_SUCCESS;
  130. s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_IND_CERTS_ECC | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0);
  131. return s8Ret;
  132. }
  133. /*!
  134. @fn \ m2m_ssl_retrieve_cert(uint32 u32ReadAddr, uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig,
  135. tstrECPoint* pu8Key)
  136. @brief Retrieve the certificate to be verified from the WINC
  137. @param [in] pu16CurveType
  138. Pointer to the certificate curve type.
  139. @param [in] pu8Hash
  140. Pointer to the certificate hash.
  141. @param [in] pu8Sig
  142. Pointer to the certificate signature.
  143. @param [in] pu8Key
  144. Pointer to the certificate Key.
  145. @return The function SHALL return 0 for success and a negative value otherwise.
  146. */
  147. NMI_API sint8 m2m_ssl_retrieve_cert(uint16 *pu16CurveType, uint8 *pu8Hash, uint8 *pu8Sig, tstrECPoint *pu8Key)
  148. {
  149. uint8 bSetRxDone = 1;
  150. uint16 u16HashSz, u16SigSz, u16KeySz;
  151. sint8 s8Ret = M2M_SUCCESS;
  152. if (gu32HIFAddr == 0)
  153. return M2M_ERR_FAIL;
  154. if (hif_receive(gu32HIFAddr, (uint8 *)pu16CurveType, 2, 0) != M2M_SUCCESS)
  155. goto __ERR;
  156. gu32HIFAddr += 2;
  157. if (hif_receive(gu32HIFAddr, (uint8 *)&u16KeySz, 2, 0) != M2M_SUCCESS)
  158. goto __ERR;
  159. gu32HIFAddr += 2;
  160. if (hif_receive(gu32HIFAddr, (uint8 *)&u16HashSz, 2, 0) != M2M_SUCCESS)
  161. goto __ERR;
  162. gu32HIFAddr += 2;
  163. if (hif_receive(gu32HIFAddr, (uint8 *)&u16SigSz, 2, 0) != M2M_SUCCESS)
  164. goto __ERR;
  165. gu32HIFAddr += 2;
  166. (*pu16CurveType) = _htons((*pu16CurveType));
  167. pu8Key->u16Size = _htons(u16KeySz);
  168. u16HashSz = _htons(u16HashSz);
  169. u16SigSz = _htons(u16SigSz);
  170. if (hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2, 0) != M2M_SUCCESS)
  171. goto __ERR;
  172. gu32HIFAddr += (pu8Key->u16Size * 2);
  173. if (hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS)
  174. goto __ERR;
  175. gu32HIFAddr += u16HashSz;
  176. if (hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS)
  177. goto __ERR;
  178. gu32HIFAddr += u16SigSz;
  179. bSetRxDone = 0;
  180. __ERR:
  181. if (bSetRxDone) {
  182. s8Ret = M2M_ERR_FAIL;
  183. hif_receive(0, NULL, 0, 1);
  184. }
  185. return s8Ret;
  186. }
  187. /*!
  188. @fn \ m2m_ssl_retrieve_hash(uint32 u32ReadAddr, uint8* pu8Hash, uint16 u16HashSz)
  189. @brief Retrieve the certificate hash
  190. @param [in] pu8Hash
  191. Pointer to the certificate hash.
  192. @param [in] u16HashSz
  193. Hash size.
  194. @return The function SHALL return 0 for success and a negative value otherwise.
  195. */
  196. NMI_API sint8 m2m_ssl_retrieve_hash(uint8 *pu8Hash, uint16 u16HashSz)
  197. {
  198. uint8 bSetRxDone = 1;
  199. sint8 s8Ret = M2M_SUCCESS;
  200. if (gu32HIFAddr == 0)
  201. return M2M_ERR_FAIL;
  202. if (hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS)
  203. goto __ERR;
  204. bSetRxDone = 0;
  205. __ERR:
  206. if (bSetRxDone) {
  207. s8Ret = M2M_ERR_FAIL;
  208. hif_receive(0, NULL, 0, 1);
  209. }
  210. return s8Ret;
  211. }
  212. /*!
  213. @fn \ m2m_ssl_stop_processing_certs(void)
  214. @brief Stops receiving from the HIF
  215. */
  216. NMI_API void m2m_ssl_stop_processing_certs(void)
  217. {
  218. hif_receive(0, NULL, 0, 1);
  219. }
  220. /*!
  221. @fn \ m2m_ssl_ecc_process_done(void)
  222. @brief Stops receiving from the HIF
  223. */
  224. NMI_API void m2m_ssl_ecc_process_done(void)
  225. {
  226. gu32HIFAddr = 0;
  227. }
  228. /*!
  229. @fn \
  230. m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
  231. Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the
  232. form of a bitmap containing the required ciphers to be on. There is no need to call this function if the application
  233. will not change the default ciphersuites.
  234. @param [in] u32SslCsBMP
  235. Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
  236. @ref SSLCipherSuiteID.
  237. The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC
  238. ciphersuites. The caller can override the default with any desired combination, except for combinations involving both
  239. RSA and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites. If u32SslCsBMP does not
  240. contain any ciphersuites supported by firmware, then the current active list will not be changed.
  241. @return
  242. - [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
  243. - [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
  244. */
  245. sint8 m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP)
  246. {
  247. sint8 s8Ret = M2M_SUCCESS;
  248. tstrSslSetActiveCsList strCsList;
  249. strCsList.u32CsBMP = u32SslCsBMP;
  250. s8Ret = hif_send(
  251. M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8 *)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
  252. return s8Ret;
  253. }
  254. /*!
  255. @fn \ m2m_ssl_init(tpfAppSslCb pfAppSslCb);
  256. @brief Initializes the SSL layer.
  257. @param [in] pfAppSslCb
  258. Application SSL callback function.
  259. @return The function SHALL return 0 for success and a negative value otherwise.
  260. */
  261. NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
  262. {
  263. sint8 s8Ret = M2M_SUCCESS;
  264. gpfAppSSLCb = pfAppSSLCb;
  265. gu32HIFAddr = 0;
  266. s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL, m2m_ssl_cb);
  267. if (s8Ret != M2M_SUCCESS) {
  268. M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
  269. }
  270. return s8Ret;
  271. }