Delta / NNN50_WIFI_API

Dependents:   NNN50_CE_Test_UDP NNN50_linux_firmware NNN50_SoftAP_HelloWorld NNN50_BLEWIFISensor ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2m_ssl.c Source File

m2m_ssl.c

Go to the documentation of this file.
00001 /**
00002  *
00003  * \file
00004  *
00005  * \brief This module contains M2M Wi-Fi APIs implementation.
00006  *
00007  * Copyright (c) 2017 Atmel Corporation. All rights reserved.
00008  *
00009  * \asf_license_start
00010  *
00011  * \page License
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. The name of Atmel may not be used to endorse or promote products derived
00024  *    from this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00027  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00028  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00029  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00030  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00034  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00035  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * \asf_license_stop
00039  *
00040  */
00041 
00042 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00043 INCLUDES
00044 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00045 
00046 #include "driver/include/m2m_ssl.h"
00047 #include "driver/source/m2m_hif.h"
00048 #include "driver/source/nmasic.h"
00049 
00050 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00051 MACROS
00052 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00053 
00054 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00055 DATA TYPES
00056 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00057 static tpfAppSSLCb gpfAppSSLCb = NULL;
00058 static uint32 gu32HIFAddr = 0;
00059 
00060 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
00061 FUNCTION PROTOTYPES
00062 *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
00063 
00064 /*!
00065     @fn \   m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
00066     @brief      SSL callback function
00067     @param [in] u8OpCode
00068                 HIF Opcode type.
00069     @param [in] u16DataSize
00070                 HIF data length.
00071     @param [in] u32Addr
00072                 HIF address.
00073 */
00074 static void m2m_ssl_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
00075 {
00076     sint8 s8tmp = M2M_SUCCESS;
00077     switch(u8OpCode)
00078     {
00079         case M2M_SSL_REQ_ECC:
00080         {
00081             tstrEccReqInfo strEccREQ;
00082             s8tmp = hif_receive(u32Addr, (uint8*)&strEccREQ, sizeof(tstrEccReqInfo), 0);
00083             if(s8tmp == M2M_SUCCESS)
00084             {
00085                 if (gpfAppSSLCb)
00086                 {
00087                     gu32HIFAddr = u32Addr + sizeof(tstrEccReqInfo);
00088                     gpfAppSSLCb(M2M_SSL_REQ_ECC, &strEccREQ);
00089                 }
00090             }
00091         }
00092         break;
00093         case M2M_SSL_RESP_SET_CS_LIST:
00094         {
00095             tstrSslSetActiveCsList strCsList;
00096             s8tmp = hif_receive(u32Addr, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), 0);
00097             if(s8tmp == M2M_SUCCESS)
00098             {
00099                 if (gpfAppSSLCb)
00100                     gpfAppSSLCb(M2M_SSL_RESP_SET_CS_LIST, &strCsList);
00101             }
00102         }
00103         break;
00104     }
00105     if(s8tmp != M2M_SUCCESS)
00106     {
00107         M2M_ERR("Error receiving SSL from the HIF\n");
00108     }
00109 }
00110 
00111 
00112 /*!
00113     @fn \    m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
00114     @brief   Sends ECC responses to the WINC
00115     @param [in] strECCResp
00116                 ECC Response struct.
00117     @param [in] pu8RspDataBuffe
00118                 Pointer of the response data to be sent.
00119     @param [in] u16RspDataSz
00120                 Response data size.
00121     @return     The function SHALL return 0 for success and a negative value otherwise.
00122 */
00123 NMI_API sint8 m2m_ssl_handshake_rsp(tstrEccReqInfo* strECCResp, uint8* pu8RspDataBuff, uint16 u16RspDataSz)
00124 {
00125     sint8 s8Ret = M2M_SUCCESS;
00126     
00127     s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_RESP_ECC | M2M_REQ_DATA_PKT), (uint8*)strECCResp, sizeof(tstrEccReqInfo), pu8RspDataBuff, u16RspDataSz, sizeof(tstrEccReqInfo));
00128 
00129     return s8Ret;
00130 }
00131 
00132 /*!
00133     @fn \   m2m_ssl_send_certs_to_winc(uint8* sector_buffer, uint32 sector_size)
00134     @brief  Sends certificates to the WINC
00135     @param [in] pu8Buffer
00136                 Pointer to the certificates.
00137     @param [in] u32BufferSz
00138                 Size of the certificates.
00139     @return     The function SHALL return 0 for success and a negative value otherwise.
00140 */
00141 NMI_API sint8 m2m_ssl_send_certs_to_winc(uint8* pu8Buffer, uint32 u32BufferSz)
00142 {
00143     sint8 s8Ret = M2M_SUCCESS;
00144 
00145     s8Ret = hif_send(M2M_REQ_GROUP_SSL, (M2M_SSL_IND_CERTS_ECC | M2M_REQ_DATA_PKT), NULL, 0, pu8Buffer, u32BufferSz, 0);
00146 
00147     return s8Ret;
00148 }
00149 
00150 /*!
00151     @fn \   m2m_ssl_retrieve_cert(uint32 u32ReadAddr, uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
00152     @brief  Retrieve the certificate to be verified from the WINC
00153     @param [in] pu16CurveType
00154                 Pointer to the certificate curve type.
00155     @param [in] pu8Hash
00156                 Pointer to the certificate hash.
00157     @param [in] pu8Sig
00158                 Pointer to the certificate signature.
00159     @param [in] pu8Key
00160                 Pointer to the certificate Key.
00161     @return     The function SHALL return 0 for success and a negative value otherwise.
00162 */
00163 NMI_API sint8 m2m_ssl_retrieve_cert(uint16* pu16CurveType, uint8* pu8Hash, uint8* pu8Sig, tstrECPoint* pu8Key)
00164 {
00165     uint8   bSetRxDone  = 1;
00166     uint16  u16HashSz, u16SigSz, u16KeySz;
00167     sint8   s8Ret = M2M_SUCCESS;
00168 
00169     if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
00170     
00171     if(hif_receive(gu32HIFAddr, (uint8*)pu16CurveType, 2, 0) != M2M_SUCCESS) goto __ERR;
00172     gu32HIFAddr += 2;
00173 
00174     if(hif_receive(gu32HIFAddr, (uint8*)&u16KeySz, 2, 0) != M2M_SUCCESS) goto __ERR;
00175     gu32HIFAddr += 2;
00176 
00177     if(hif_receive(gu32HIFAddr, (uint8*)&u16HashSz, 2, 0) != M2M_SUCCESS) goto __ERR;
00178     gu32HIFAddr += 2;
00179 
00180     if(hif_receive(gu32HIFAddr, (uint8*)&u16SigSz, 2, 0) != M2M_SUCCESS) goto __ERR;
00181     gu32HIFAddr += 2;
00182 
00183     (*pu16CurveType)= _htons((*pu16CurveType));
00184     pu8Key->u16Size = _htons(u16KeySz);
00185     u16HashSz       = _htons(u16HashSz);
00186     u16SigSz        = _htons(u16SigSz);
00187     
00188     if(hif_receive(gu32HIFAddr, pu8Key->X, pu8Key->u16Size * 2, 0) != M2M_SUCCESS) goto __ERR;
00189     gu32HIFAddr += (pu8Key->u16Size * 2);
00190 
00191     if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
00192     gu32HIFAddr += u16HashSz;
00193 
00194     if(hif_receive(gu32HIFAddr, pu8Sig, u16SigSz, 0) != M2M_SUCCESS) goto __ERR;
00195     gu32HIFAddr += u16SigSz;
00196     
00197     bSetRxDone = 0;
00198 
00199 __ERR:
00200     if(bSetRxDone)
00201     {
00202         s8Ret = M2M_ERR_FAIL;
00203         hif_receive(0, NULL, 0, 1);
00204     }
00205     return s8Ret;
00206 }
00207 
00208 /*!
00209     @fn \   m2m_ssl_retrieve_hash(uint32 u32ReadAddr, uint8* pu8Hash, uint16 u16HashSz)
00210     @brief  Retrieve the certificate hash
00211     @param [in] pu8Hash
00212                 Pointer to the certificate hash.
00213     @param [in] u16HashSz
00214                 Hash size.
00215     @return     The function SHALL return 0 for success and a negative value otherwise.
00216 */
00217 NMI_API sint8 m2m_ssl_retrieve_hash(uint8* pu8Hash, uint16 u16HashSz)
00218 {
00219     uint8   bSetRxDone  = 1;
00220     sint8   s8Ret = M2M_SUCCESS;
00221 
00222     if(gu32HIFAddr == 0) return M2M_ERR_FAIL;
00223 
00224     if(hif_receive(gu32HIFAddr, pu8Hash, u16HashSz, 0) != M2M_SUCCESS) goto __ERR;
00225     
00226     bSetRxDone = 0;
00227 
00228 __ERR:
00229     if(bSetRxDone)
00230     {
00231         s8Ret = M2M_ERR_FAIL;
00232         hif_receive(0, NULL, 0, 1);
00233     }
00234     return s8Ret;
00235 }
00236 
00237 /*!
00238     @fn \   m2m_ssl_stop_processing_certs(void)
00239     @brief  Stops receiving from the HIF
00240 */
00241 NMI_API void m2m_ssl_stop_processing_certs(void)
00242 {
00243     hif_receive(0, NULL, 0, 1);
00244 }
00245 
00246 /*!
00247     @fn \   m2m_ssl_ecc_process_done(void)
00248     @brief  Stops receiving from the HIF
00249 */
00250 NMI_API void m2m_ssl_ecc_process_done(void)
00251 {
00252     gu32HIFAddr = 0;
00253 }
00254 
00255 /*!
00256 @fn \
00257     m2m_ssl_set_active_ciphersuites(uint32 u32SslCsBMP);
00258     Override the default Active SSL ciphers in the SSL module with a certain combination selected by the caller in the form of
00259     a bitmap containing the required ciphers to be on.
00260     There is no need to call this function if the application will not change the default ciphersuites.
00261 
00262 @param [in] u32SslCsBMP
00263                 Bitmap containing the desired ciphers to be enabled for the SSL module. The ciphersuites are defined in
00264                 @ref SSLCipherSuiteID.
00265                 The default ciphersuites are all ciphersuites supported by the firmware with the exception of ECC ciphersuites.
00266                 The caller can override the default with any desired combination, except for combinations involving both RSA
00267                 and ECC; if any RSA ciphersuite is enabled, then firmware will disable all ECC ciphersuites.
00268                 If u32SslCsBMP does not contain any ciphersuites supported by firmware, then the current active list will not
00269                 be changed.
00270 
00271 @return     
00272     - [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
00273     - [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
00274 */
00275 sint8 m2m_ssl_set_active_ciphersuites (uint32 u32SslCsBMP)
00276 {
00277     sint8 s8Ret = M2M_SUCCESS;
00278     tstrSslSetActiveCsList  strCsList;
00279     
00280     strCsList.u32CsBMP = u32SslCsBMP;
00281     s8Ret = hif_send(M2M_REQ_GROUP_SSL, M2M_SSL_REQ_SET_CS_LIST, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0);
00282 
00283     return s8Ret;
00284 }
00285 
00286 /*!
00287     @fn \   m2m_ssl_init(tpfAppSslCb pfAppSslCb);
00288     @brief  Initializes the SSL layer.
00289     @param [in] pfAppSslCb
00290     Application SSL callback function.
00291     @return     The function SHALL return 0 for success and a negative value otherwise.
00292 */
00293 NMI_API sint8 m2m_ssl_init(tpfAppSSLCb pfAppSSLCb)
00294 {
00295     sint8 s8Ret = M2M_SUCCESS;
00296 
00297     gpfAppSSLCb = pfAppSSLCb;
00298     gu32HIFAddr = 0;
00299 
00300     s8Ret = hif_register_cb(M2M_REQ_GROUP_SSL,m2m_ssl_cb);
00301     if (s8Ret != M2M_SUCCESS)
00302     {
00303         M2M_ERR("hif_register_cb() failed with ret=%d", s8Ret);
00304     }
00305     return s8Ret;
00306 }