NETAPI integration with ipsecmgr
[keystone-rtos/netapi.git] / ti / runtime / netapi / applications / ipsec_offload / ipsecmgr / src / netapilib_interface.c
1 /*
2  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *    Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *    Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *    Neither the name of Texas Instruments Incorporated nor the names of
18  *    its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33 */
35 /* Standard includes */
36 #include <stdio.h>
37 #include <arpa/inet.h>
38 #include <inttypes.h>
40 /* ipsecmgr includes */
41 #include <ipsecmgr_snoop.h>
42 #include <ipsecmgr_syslog.h>
44 #include "netapilib_interface.h"
47 extern ipsecMgrMcb_t globalCfg;
48 extern NETAPI_T netapi_handle;
49 NETCP_CFG_SA_T saAppIdOut = 0;
50 NETCP_CFG_SA_T saAppIdIn = 0;
52 /**************************************************************************
53  * FUNCTION PURPOSE: The function is used to translate the SA configuration
54  * parameters received from the IPSec Snopper and call the NETAPI function
55  * to create a security association
56  ********************************************************************/
57 int netapilib_ifAddSA
58 (
59     ipsecmgr_af_t               af,
60     ipsecmgr_sa_id_t            *sa_id,
61     ipsecmgr_sa_info_t          *sa_info,
62     ipsecmgr_sa_dscp_map_cfg_t  *dscp_map_cfg,
63     ipsecmgr_ifname_t           *if_name,
64     ipsecmgr_sa_encap_tmpl_t    *encap,
65     ipsecmgr_fp_handle_t        *sa_handle
66 )
67 {
68     uint8_t                 auth_key[36];
69     uint8_t                 encr_key[36];
70     int error, index;
71     NETAPI_SEC_SA_INFO_T saInfo;
72     nwalSecKeyParams_t  keyParams;
73     void * p_rx_inflow_mode_handle;
74     void * p_tx_inflow_mode_handle;
75     NETCP_CFG_ROUTE_T  route;
76     NETCP_CFG_FLOW_T flow;
77     NETCP_CFG_SA_HANDLE_T pSaHandle;
78     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
79                 "netapilib_ifAddSA:, DEBUG: Translating SA\n");
82     memset((void *)&saInfo, 0, sizeof (NETAPI_SEC_SA_INFO_T));
83     memset((void *)&keyParams, 0, sizeof (nwalSecKeyParams_t));
84     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
85     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
87     flow.dma_engine= 1;
88     flow.flowid = globalCfg.flowId;
89     route.p_flow = &flow;
90     route.p_dest_q = globalCfg.pktio_channel;
93     /* Initialize the SA Config structure. */
94     /* Get the IP protocol version. */
95     if (af == IPSECMGR_AF_IPV4)
96     {
97         saInfo.ipType = nwal_IPV4;
98         /* Populate the source and destination IP addresses. */
99         for (index = 0; index < 4; index++)
100         {
101             saInfo.dst.ipv4[index] = sa_id->daddr.ipv4[index];
102             saInfo.src.ipv4[index] = sa_info->saddr.ipv4[index];
103         }
104     }
105     else if (af == IPSECMGR_AF_IPV6)
106     { 
107         saInfo.ipType = nwal_IPV6;
109         /* Populate the source and destination IP addresses. */
110         for (index = 0; index < 16; index++)
111         {
112             saInfo.dst.ipv6[index] = sa_id->daddr.ipv6[index];
113             saInfo.src.ipv6[index] = sa_info->saddr.ipv6[index];
114         }
115     }
116     else
117     {
118         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
119             "netapilib_ifAddSA: Address family (%d) is invalid\n", af);
120         return -1;
121     }
122     /* Get the SPI. */
123     saInfo.spi = sa_id->spi;
125     /* Get the SA direction. */
126     if (sa_info->dir == DIR_INBOUND)
127         saInfo.dir = NWAL_SA_DIR_INBOUND;
128     else if (sa_info->dir == DIR_OUTBOUND)
129         saInfo.dir = NWAL_SA_DIR_OUTBOUND;
130     else
131     {
132         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
133             "netapilib_ifAddSA: IPSec direction (%d) is invalid\n", sa_info->dir);
134         return -1;
135     }
136     
138     /* Get the replay Window */
139     saInfo.replayWindow = sa_info->replay_window;
140    
141     /* Get the IPSec protocol. */
142     if (sa_id->proto == SA_PROTO_AH)
143         saInfo.proto = nwal_IpSecProtoAH;
144     else if (sa_id->proto == SA_PROTO_ESP)
145         saInfo.proto = nwal_IpSecProtoESP;
146     else
147     {
148         ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
149             "netapilib_ifAddSA: IPSec protocol (%d) is invalid.\n", sa_id->proto);
150         return -1;
151     }
152     /* Get the IPSec mode. */
153     if (sa_info->mode == SA_MODE_TRANSPORT)
154         saInfo.saMode = nwal_SA_MODE_TRANSPORT;
155     else if (sa_info->mode == SA_MODE_TUNNEL)
156         saInfo.saMode = nwal_SA_MODE_TUNNEL;
157     else
158     {
159         ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
160             "netapilib_ifAddSA: IPSec mode (%d) is invalid.\n", sa_info->mode);
161         return -1;
162     }
163     /* Get the authentication mode algorithm. */
164     if (sa_info->auth.algo == SA_AALG_HMAC_SHA1)
165     {
166         saInfo.authMode = NWAL_SA_AALG_HMAC_SHA1;
167         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
168             "netapilib_ifAddSA: auth algo is SA_AALG_HMAC_SHA1\n");
169     }
170     else if (sa_info->auth.algo == SA_AALG_HMAC_MD5)
171         saInfo.authMode = NWAL_SA_AALG_HMAC_MD5;
172     else if (sa_info->auth.algo == SA_AALG_NONE || sa_info->auth.algo == SA_AALG_NULL)  
173         saInfo.authMode = NWAL_SA_AALG_NULL;
174     else
175     {
176         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
177             "netapilib_ifAddSA: Authentication algorithm (%d) is invalid\n", sa_info->auth.algo);
178         return -1;
179     }
181     /* Get the encryption mode algorithm. */
182     if (sa_info->enc.algo == SA_EALG_NULL) 
183         saInfo.cipherMode = NWAL_SA_EALG_NULL;
184     else if (sa_info->enc.algo == SA_EALG_AES_CTR) 
185         saInfo.cipherMode = NWAL_SA_EALG_AES_CTR;
186     else if (sa_info->enc.algo == SA_EALG_AES_CBC)
187     {
188         saInfo.cipherMode = NWAL_SA_EALG_AES_CBC;
189         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"encr algo is NWAL_SA_EALG_AES_CBC\n");
190     }
191     else if (sa_info->enc.algo == SA_EALG_3DES_CBC) 
192         saInfo.cipherMode = NWAL_SA_EALG_3DES_CBC;
193     else if (sa_info->enc.algo == SA_EALG_DES_CBC) 
194         saInfo.cipherMode = NWAL_SA_EALG_DES_CBC;
195     else
196     {
197         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
198             "netapilib_ifAddSA: Encryption algorithm (%d) is invalid\n", sa_info->enc.algo);
199         return -1;
200     }
201     /* Validate the key lengths. */
202     if ((keyParams.macKeySize = sa_info->auth_key_len) > 32)
203     {
204         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
205             "netapilib_ifAddSA: Authentication key size (%d) is invalid.\n", sa_info->auth_key_len);
206         return -1;
207     }
208     if ((keyParams.encKeySize = sa_info->enc_key_len) > 32)
209     {
210         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
211             "netapilib_ifAddSA: Encryption key size (%d) is invalid.\n", sa_info->enc_key_len);
212         return -1;
213     }
215     /* Get the authentication/encryption keys. */
216     keyParams.pAuthKey = &sa_info->auth_key[0];
217     keyParams.pEncKey = &sa_info->enc_key[0];
219     if (saInfo.dir == NWAL_SA_DIR_INBOUND)
220     {
221         /* Inbound == RX */
222         saAppIdIn = netapi_secAddSA(netapi_handle,
223                         NETCP_CFG_NO_INTERFACE,
224                         &saInfo,
225                         &keyParams,
226                         NETAPI_SEC_SA_INFLOW,
227                         (NETCP_CFG_ROUTE_HANDLE_T)&route,
228                         &p_rx_inflow_mode_handle,
229                         &p_tx_inflow_mode_handle,
230                         NULL, &error);
232         if (error == NETAPI_ERR_OK)
233         {
234             *sa_handle = saAppIdIn;
235         }
236         else
237         {
238             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
239                                 "netapilib_ifAddSA: netapi_secAddSA returned error: %d.\n",
240                                  error);
241             return -1;
242         }
243     }
244     else
245     {
246         /* OUTBOUND == TX */
247         saAppIdOut = netapi_secAddSA(netapi_handle,
248                         NETCP_CFG_NO_INTERFACE,
249                         &saInfo,
250                         &keyParams,
251                         NETAPI_SEC_SA_INFLOW,
252                         (NETCP_CFG_ROUTE_HANDLE_T)NULL,
253                         &p_rx_inflow_mode_handle,
254                         &p_tx_inflow_mode_handle,
255                         NULL, &error);
256         if (error == NETAPI_ERR_OK)
257         {
258             *sa_handle = saAppIdOut;
259 #if 0
260              netapi_secGetPaHandle(netapi_handle,
261                           saAppIdOut,
262                           NULL,
263                           &pSaHandle);
264 #endif
265         }
266         else
267         {
268             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
269                                 "netapilib_ifAddSA: netapi_secAddSA returned error: %d.\n",
270                                  error);
271             return -1;
272         }
273     }
274     
275     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
276     "netapilib_ifAddSA: Translation of SA successful, app_id: 0x%x\n", *sa_handle);
278     /* SA was created successfully. */
279     return 0;
281 /**************************************************************************
282  * FUNCTION PURPOSE: The function is used to translate the SA configuration
283  * parameters received from the IPSec Snopper and call the NETAPI function
284  * to delete a security association
285  ********************************************************************/
286 int netapilib_ifDeleteSA (ipsecmgr_fp_handle_t sa_handle)
288     int error;
289     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
290     "netapilib_ifDeleteSA: sa_app_id 0x%x\n", sa_handle);
291     netapi_secDelSA(netapi_handle,
292                     NETCP_CFG_NO_INTERFACE,
293                     (NETCP_CFG_SA_T) sa_handle,
294                     &error);
295     return error;
298 /**************************************************************************
299  * FUNCTION PURPOSE: The function is used to translate the SP configuration
300  * parameters received from the IPSec Snopper and call the NETAPI function
301  * to create a security policy
302  ********************************************************************/
303 int32_t netapilib_ifAddSP
305     ipsecmgr_af_t           af,
306     ipsecmgr_selector_t     *sel,
307     ipsecmgr_dir_t          dir,
308     uint32_t                reqid,
309     ipsecmgr_fp_handle_t    sa_handle, 
310     ipsecmgr_policy_id_t    policy_id,
311     ipsecmgr_fp_handle_t    *sp_handle
314     NETCP_CFG_IPSEC_POLICY_T spAppIdIn;
315     int error, index;
316     nwal_IpType ipType;
317     nwalIpAddr_t src_ip_addr;
318     nwalIpAddr_t dst_ip_addr;
319     nwalIpOpt_t ip_qualifiers;
320     NETCP_CFG_SA_T sa =(NETCP_CFG_SA_T)sa_handle;
321     NETCP_CFG_ROUTE_T  route;
322     NETCP_CFG_FLOW_T flow;
323     NETCP_CFG_PA_HANDLE_T* pPaHandle;
324     NETCP_CFG_SA_HANDLE_T* pSaHandle;
325     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifAddSP: called\n");
328     if (dir == DIR_OUTBOUND)
329     {
330         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
331             "netapilib_ifAddSP: called for outbound SA, no RX policy required\n");
332         return 0;
333     }
334     flow.dma_engine= 1;
335     flow.flowid = globalCfg.flowId;
336     route.p_flow = &flow;
337     route.p_dest_q = globalCfg.pktio_channel;
339     /* Get the IP protocol version. */
340     if (af == IPSECMGR_AF_IPV4)
341     {
342         ipType = nwal_IPV4;
343         /* Populate the source and destination IP addresses. */
344         for (index = 0; index < 4; index++)
345         {
346             dst_ip_addr.ipv4[index] = sel->daddr.ipv4[index];
347             src_ip_addr.ipv4[index] = sel->saddr.ipv4[index];
348         }
349     }
350     else if (af == IPSECMGR_AF_IPV6)
351     { 
352         ipType = nwal_IPV6;
353         /* Populate the source and destination IP addresses. */
354         for (index = 0; index < 16; index++)
355         {
356             dst_ip_addr.ipv6[index] = sel->daddr.ipv6[index];
357             src_ip_addr.ipv6[index] = sel->saddr.ipv6[index];
358         }
359     }
360     else
361     {
362         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
363             "netapilib_ifAddSP: Address family (%d) is invalid\n", af);
364         return -1;
365     }
367     ip_qualifiers.flowLabel = 1; 
368     ip_qualifiers.proto = 1;
369     ip_qualifiers.tos = 1;
370     ip_qualifiers.validParams = 1;
371     
372     spAppIdIn = netapi_secAddRxPolicy(netapi_handle,
373                                      (NETCP_CFG_SA_T) sa_handle,
374                                      ipType,
375                                      &src_ip_addr,
376                                      &dst_ip_addr,
377                                      NULL,
378                                      (NETCP_CFG_ROUTE_HANDLE_T)&route,
379                                      NULL,
380                                      &error);
382         if (error == NETAPI_ERR_OK)
383         {
384                 *sp_handle = spAppIdIn;
385         }
386         else
387         {
388             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
389                                 "netapilib_ifAddSA: netapi_secAddRxPolicy returned error: %d.\n",
390                                  error);
391             return -1;
392         }
394     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
395         "netapi_proxy:DEBUG: Translation of SP successful.\n");
397 #if 0
398     netapi_secGetPaHandle(netapi_handle,
399                           (NETCP_CFG_SA_T)sa_handle,
400                           pPaHandle,
401                           pSaHandle);
402 #endif
403     return 0;
406 /**************************************************************************
407  * FUNCTION PURPOSE: The function is used to translate the SP configuration
408  * parameters received from the IPSec Snopper and call the NETAPI function
409  * to delete a security association
410  ********************************************************************/
411 int32_t netapilib_ifDeleteSP
413     ipsecmgr_fp_handle_t    sp_handle,
414     ipsecmgr_policy_id_t    policy_id,
415     ipsecmgr_dir_t          dir
418     int error =0;
419     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifDeleteSP: called\n");
421     if (dir == DIR_OUTBOUND)
422     {
423         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
424             "netapilib_ifDeleteSP: called for outbound SA, no RX policy to delete\n");
425             return 0;
426     }
427     netapi_secDelRxPolicy(netapi_handle,
428                           (NETCP_CFG_IPSEC_POLICY_T) sp_handle,
429                           &error);
430                           
431     return 0;
434 /**************************************************************************
435  * FUNCTION PURPOSE: The function is used to translate the SA configuration
436  * parameters received from the IPSec Snopper and retrieve SA context
437  * information for SA.
438  *************************************************************************/
439 int netapilib_ifGetSACtx
441     ipsecmgr_fp_handle_t    sa_handle,
442     ipsecmgr_sa_hw_ctx_t*   hw_ctx
445     uint32_t swInfo0 = 0;
446     uint32_t swInfo1 = 0;
447     nwalGlobCxtInfo_t info;
448     nwal_RetValue retVal;
450     memset(&info, 0, sizeof(nwalGlobCxtInfo_t));
451     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) netapi_handle;
452     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifGetSACtx: called\n");
455     netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context,
456                                     (NETCP_CFG_SA_T) sa_handle,
457                                     &swInfo0,
458                                     &swInfo1);
460     hw_ctx->swinfo_sz = 2;
461     hw_ctx->swinfo[0] = swInfo0;
462     hw_ctx->swinfo[1] = swInfo1;
464     retVal = nwal_getGlobCxtInfo(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
465         &info);
466     if (retVal != nwal_OK)
467     {
468         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
469             "netapilib_ifGetSACtx: nwal_getGlobCxtInfo returned error: 0x%x\n", retVal);
470         return -1;
471     }
472     hw_ctx->flow_id = info.rxSaPaFlowId;
474     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
475             "netapilib_ifGetSACtx: rxPaSaFlowId: 0x%x, rxSaPaFlowId: 0x%x\n", 
476             info.rxPaSaFlowId,
477             info.rxSaPaFlowId);
478     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
479             "netapilib_ifGetSACtx: swInfo0: 0x%x, swInfo1: 0x%x, flowId: 0x%x\n",
480             hw_ctx->swinfo[0],
481             hw_ctx->swinfo[1],
482             hw_ctx->flow_id);
484    /* return success */
485     return 0;