O-CU-UP
[scp/ocu/5gnr.git] / Cu / CuUp / Pdcp / PdcpUp / Src / pdcpuUpc.c
1 /******************************************************************************
2 ###############################################################################
3 #   Copyright (c) [2017-2020] [ICT/CAS]                                        #
4 #   Licensed under the ORAN Software License v1.0 (License)             #
5 ###############################################################################
6 ******************************************************************************/
7 #include "vos_types.h"
8 #include "vos_string.h"
9 #include "vos_lib.h"
10 #include "pdcpu.h"
11 #include "pdcpuCore.h"
12 #include "pdcpCommon.h"
13 #include "cuupCommon.h"
14 #include "cuModuleInterface.h"
15 #include "pdcpComprohc.h"
16 #include "cuupTest.h"
17 #include "cuupUeIdTransf.h"
18 #include "upcContext.h"
19
20 extern PdcpuUeInfo_t *gPdcpuUeInfo[MAX_UE_NUM];
21 ULONG gPdcpuModuleId;
22 CuupUeIdxTable_t gPdcpuUeIdxTable;
23
24
25 /*******************************************************************************
26 * To  
27 * INPUT:
28 *         : 
29 * OUTPUT:
30 *        0:success
31 *       -1:fail
32 *******************************************************************************/ 
33 INT32 pdcpuInit(ULONG userModuleId)
34 {       
35         /* get pdcpu moduleId */
36         gPdcpuModuleId = userModuleId;
37
38         /* init ueIdx table */
39         UINT8 i = 0;
40         for(i=0; i<MAX_UE_NUM; i++)
41         {
42                 gPdcpuUeIdxTable.ueIdxInfo[i].isUsed = FALSE;
43         }
44
45         /* init ue info */
46         for(i=0; i<MAX_UE_NUM; i++)
47         {
48                 gPdcpuUeInfo[i] = NULL;
49         }
50         
51         return VOS_OK;
52 }
53
54
55 INT32 pdcpuFreeSecInfo(UINT16 ueIdx)
56 {
57         PdcpuSecInfo_t *pDrbSecInfo = gPdcpuUeInfo[ueIdx]->secInfo;
58         if(NULL != pDrbSecInfo)
59         {
60                 VOS_Free(pDrbSecInfo);
61                 gPdcpuUeInfo[ueIdx]->secInfo = NULL;
62         }
63         
64         return VOS_OK;
65 }
66
67 /*******************************************************************************
68 * To deal with security indication
69 * Security Result indicates whether the security policy indicated as "preferred" 
70 * in the Security Indication IE is performed or not.
71 * INPUT:
72 *        ueE1apId : UE E1AP ID
73 *        pduSessionId : pdu session id
74 *        pSecInd : security indication
75 *        pSecResult : security result
76 * OUTPUT:
77 *        0:success
78 *       -1:fail
79 *******************************************************************************/ 
80 INT32 pdcpuDealSecurityInd(PdcpuSecInfo_t *pSec, PdcpuSecEnableInfo_t *pEnableInfo, SecuInd_t *pSecInd, PdcpuCfgResult_t *pResult)
81 {
82         /* get security enable information global variable */
83         pdcpuNullCheck(pSec);
84         pdcpuNullCheck(pEnableInfo);
85         pdcpuNullCheck(pSecInd);
86         
87         /* for integrity protection */
88         if(ACTIVE_INT_STATE == pSec->intActiveFlag)
89         {
90                 /* integrity protection is active for the UE, apply the indication */
91                 if(IP_REQUIRED == pSecInd->IPIndication)
92                 {
93                         pEnableInfo->integrityEnableFlag = TRUE;
94                         pEnableInfo->maxIPDataRate               = pSecInd->maxIPdataRate;
95                         pResult->secResPresent                   = FALSE;
96                         
97                 }else if(IP_PREFERRED == pSecInd->IPIndication)
98                 {                       
99                         pEnableInfo->integrityEnableFlag = TRUE;
100                         pEnableInfo->maxIPDataRate               = pSecInd->maxIPdataRate;
101                         pResult->secResPresent                   = TRUE;
102                         pResult->secuResult.integrityProtectionResult= IP_RESULT_PERFORMED;
103                         
104                 }else
105                 {
106                         pEnableInfo->integrityEnableFlag = FALSE;
107                         pResult->secResPresent                   = FALSE;
108                         
109                 }
110                 
111         }else
112         {               
113                 /* integrity protection is inactive for the UE */
114                 pEnableInfo->integrityEnableFlag = FALSE;               
115                 if(IP_PREFERRED == pSecInd->IPIndication)
116                 {                       
117                         pResult->secResPresent = TRUE;
118                         pResult->secuResult.integrityProtectionResult= IP_RESULT_NOT_PERFORMED;                 
119                 }
120         }
121         
122         /* for ciphering */
123         if(ACTIVE_ENC_STATE == pSec->encActiveFlag)
124         {
125                 /* ciphering is active for the UE, apply the indication */
126                 if(CP_REQUIRED == pSecInd->CPIndication)
127                 {
128                         pEnableInfo->cipherEnableFlag = TRUE;                   
129                         pResult->secResPresent            = FALSE;
130                         
131                 }else if(CP_PREFERRED == pSecInd->CPIndication)
132                 {
133                         pEnableInfo->cipherEnableFlag = TRUE;
134                         pResult->secResPresent            = TRUE;
135                         pResult->secuResult.confidentialityProtectionResult = CP_RESULT_PERFORMED;
136                         
137                 }else
138                 {
139                         pEnableInfo->cipherEnableFlag = FALSE;
140                         pResult->secResPresent            = FALSE;
141                         
142                 }
143                 
144         }else
145         {               
146                 /* ciphering is inactive for the UE */
147                 pEnableInfo->cipherEnableFlag = FALSE;          
148                 if(CP_PREFERRED == pSecInd->CPIndication)
149                 {                       
150                         pResult->secResPresent = TRUE;
151                         pResult->secuResult.confidentialityProtectionResult= CP_RESULT_NOT_PERFORMED;                   
152                 }
153         }
154         
155         return VOS_OK;
156 }
157
158 INT32 pdcpuRetFailResult(UpcCfgType_e cfgType, upcTempSessInfo_t *pCfgInfo, PdcpuCfgResult_t *pResult)
159 {
160         pdcpuLog(LOG_ERR,"[PDCPU] pdu session config failed\n");
161
162         UINT8 i = 0;
163         if(PDU_SESSION_ADD == cfgType)
164         {
165                 /* drb to setup list */
166                 for(i=0; i<pCfgInfo->drbSetupNum; i++)
167                 {
168                         pResult->drbSetupFailedArray[i].drbId = pCfgInfo->pTempDrbSetupList[i].drbId;
169                         pResult->drbSetupFailedArray[i].cause = RNL_UNSPECIFIED;
170                 }
171                 pResult->drbSetupFailNum = pCfgInfo->drbSetupNum;
172                 pResult->pduSessionCause = RNL_UNSPECIFIED;
173                 
174         }
175
176         
177         return VOS_ERROR;
178 }
179
180 /*******************************************************************************
181 * To deal with PDU session to setup config 
182 * INPUT:
183 *        ueE1apId : UE E1AP ID
184 *        pPduSessionCfg : PDU session to setup config
185 *        pResult : PDU session to setup result
186 * OUTPUT:
187 *        none
188 *******************************************************************************/ 
189 INT32 pdcpuSessionAddProc(UINT64 ueE1apId, VOID *pCfgInfo, PdcpuCfgResult_t *pResult)
190 {
191         upcTempSessInfo_t *pSetupInfo = (upcTempSessInfo_t *)pCfgInfo;
192         upcTempDrbInfo_t  *pDrbTemp   = NULL;
193         PdcpuSecInfo_t           *pSec            = NULL;
194         PdcpuSecEnableInfo_t *pEnableInfo = NULL;
195
196         UINT16 pduSessionId = pSetupInfo->pduSessId;
197         pResult->pduSessionId = pduSessionId;   
198
199         /* get ueIdx */
200         UINT16 ueIdx;   
201         if(VOS_ERROR == cuupAddUeE1apid(ueE1apId, &ueIdx, &gPdcpuUeIdxTable))
202         {
203                 pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n");
204                 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
205         }
206
207         /* check ue and security context block */
208         if((NULL == gPdcpuUeInfo[ueIdx]) || (NULL == gPdcpuUeInfo[ueIdx]->secInfo))
209         {               
210                 pdcpuLog(LOG_ERR,"[PDCPU] ue and security context block not exist\n");
211                 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
212         }
213         pSec = gPdcpuUeInfo[ueIdx]->secInfo;
214         
215         /* alloc pdu session information */
216         pEnableInfo = gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId];
217         if(NULL == pEnableInfo)
218         {
219                 pEnableInfo = VOS_Malloc(sizeof(PdcpuSecEnableInfo_t), gPdcpuModuleId);
220                 if(NULL == pEnableInfo)
221                 {
222                         pdcpuLog(LOG_ERR,"[PDCPU] vos_malloc failed\n");
223                         return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
224                 }
225                 VOS_MemZero(pEnableInfo, sizeof(PdcpuSecEnableInfo_t));
226                 gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId] = pEnableInfo;
227         }
228         pEnableInfo->pduSessionId = pduSessionId;
229
230         /* deal with security indication */     
231         if(VOS_ERROR == pdcpuDealSecurityInd(pSec, pEnableInfo, &pSetupInfo->secuIndi, pResult))
232         {
233                 pdcpuLog(LOG_ERR,"[PDCPU] deal security indication failed\n");
234                 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
235         }
236         
237         /* create pdcp entity */
238         UINT8 i = 0;    
239         for(i = 0; i < pSetupInfo->drbSetupNum; i++)
240         {
241                 pDrbTemp = &pSetupInfo->pTempDrbSetupList[i];
242                 
243                 if((NULL == pDrbTemp) || (FALSE == pDrbTemp->drbSetupAllowed))
244                 {
245                         continue;
246                 }
247                 
248                 if(VOS_OK == pdcpuCreateEntity(ueE1apId, ueIdx, pduSessionId, pDrbTemp))
249                 {
250                         pResult->drbSetupSuccessArray[pResult->drbSetupSuccessNum] = pDrbTemp->drbId;
251                         pResult->drbSetupSuccessNum += 1;
252                 }else
253                 {                       
254                         pResult->drbSetupFailedArray[pResult->drbSetupFailNum].drbId = pDrbTemp->drbId;
255                         pResult->drbSetupFailedArray[pResult->drbSetupFailNum].cause = RNL_PDCP_CONFIG_NOT_SUPPORT;
256                         pResult->drbSetupFailNum += 1;
257                         
258                 }
259         }
260
261         /* return */
262         if(0 != pResult->drbSetupSuccessNum)
263         {
264                 return VOS_OK;
265         }else
266         {
267                 pResult->pduSessionCause = RNL_UNSPECIFIED;
268                 pdcpuLog(LOG_ERR,"[PDCPU] all drbs setup failed\n");
269                 return VOS_ERROR;
270         }
271 }
272
273 /*******************************************************************************
274  * To manage pdcp-u entity 
275  * INPUT:
276  *              ueE1apId                : UE E1AP ID
277  *              pPduSessionCfg  : PDU Session Resource to setup item
278  *              cfgType                 : configuration type
279  *              pResult                 : result which will return to upc
280  * OUTPUT:
281  *              result: PDCP config result
282  *******************************************************************************/
283 INT32 pdcpuConfig(UINT64 ueE1apId, VOID *pCfgInfo, UpcCfgType_e cfgType, PdcpuCfgResult_t *pResult)
284 {               
285         switch(cfgType)
286         {
287                 case PDU_SESSION_ADD:
288                 {
289                         pdcpuNullCheck(pCfgInfo);
290                         pdcpuNullCheck(pResult);
291                         VOS_MemZero(pResult, sizeof(PdcpuCfgResult_t));
292                         pResult->cfgType = cfgType;
293                         return pdcpuSessionAddProc(ueE1apId, pCfgInfo, pResult);
294                 }               
295                 default:
296                 {
297                         pdcpuLog(LOG_ERR,"[PDCPU] cfgType error\n");
298                         return VOS_ERROR;
299                 }
300         }
301
302 }
303
304
305 /*******************************************************************************
306  * To get ue security information pointer
307  * INPUT:
308  *              ueIdx: UE index
309  * OUTPUT:
310  *              pDrbSecInfo: ue security information pointer
311  *******************************************************************************/
312 PdcpuSecInfo_t *pdcpuAllocUeSecInfo(UINT16 ueIdx)
313 {
314         PdcpuSecInfo_t *pSecInfo        = NULL;         
315         PdcpuUeInfo_t  *pPdcpUeInfo = NULL;
316
317         //check ue
318         if(NULL == gPdcpuUeInfo[ueIdx])
319         {               
320                 pPdcpUeInfo = VOS_Malloc(sizeof(PdcpuUeInfo_t), gPdcpuModuleId);
321                 pdcpuNullCheckRp(pPdcpUeInfo);
322                 VOS_MemZero(pPdcpUeInfo, sizeof(PdcpuUeInfo_t));
323                 gPdcpuUeInfo[ueIdx] = pPdcpUeInfo;
324         }else
325         {
326                 pPdcpUeInfo = gPdcpuUeInfo[ueIdx];
327         }
328         //check secInfo
329         if(NULL == pPdcpUeInfo->secInfo)
330         {               
331                 pSecInfo = VOS_Malloc(sizeof(PdcpuSecInfo_t), gPdcpuModuleId);
332                 pdcpuNullCheckRp(pSecInfo);
333                 VOS_MemZero(pSecInfo, sizeof(PdcpuSecInfo_t));
334                 pPdcpUeInfo->secInfo = pSecInfo;
335         }else
336         {
337                 pSecInfo = pPdcpUeInfo->secInfo;
338         }
339
340         VOS_MemZero(pSecInfo, sizeof(PdcpuSecInfo_t));
341         
342         return pSecInfo;
343 }
344
345
346 /*******************************************************************************
347  * To set ue security parameters. When receiving security information, 
348  * pdcp-u shall save AS keys, AS algorithm and active integrity and ciphering. 
349  * INPUT:
350  *              ueE1apId: UE E1AP ID
351  *              secInfo: security information
352  * OUTPUT:
353  *              0: success
354  *              -1:failed
355  *******************************************************************************/
356 INT32 pdcpuSetSecParam(UINT64 ueE1apId, SecuInfo_t *secInfo)
357 {
358         pdcpuNullCheck(secInfo);
359         
360         UINT16 ueIdx;   
361         if(VOS_ERROR == cuupAddUeE1apid(ueE1apId, &ueIdx, &gPdcpuUeIdxTable))
362         {
363                 pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n");
364                 return VOS_ERROR;
365         }
366         
367         /* find ue security struct */
368         PdcpuSecInfo_t *pDrbSecInfo = pdcpuAllocUeSecInfo(ueIdx);
369         pdcpuNullCheck(pDrbSecInfo);
370         
371         /* activate integrity */
372         if(secInfo->secuAlgorithm.bitMask & SECURITY_ALGORITHM_INTERGRITY_PROTECTION_ALGORITHM)
373         {       
374                 UINT8  intAlgorithm = secInfo->secuAlgorithm.integrityProtectionAlgorithm;
375                 UINT8 *pIntKey          = secInfo->upSecukey.integrityProtectionKey.buffer;
376                 UINT8  intKeyLen        = secInfo->upSecukey.integrityProtectionKey.size;       /* 128 bits */
377
378                 if(intKeyLen < AS_KEY_LEN)
379                 {
380                         pdcpuLog(LOG_ERR,"[PDCPU] integrity parameter is wrong!\n");
381                         pdcpuFreeSecInfo(ueIdx);
382                         return VOS_ERROR;
383                 }
384                 
385                 pDrbSecInfo->intActiveFlag = ACTIVE_INT_STATE;                                  /* 0-inactive, 1-active */
386                 if(intAlgorithm == NIA0 || intAlgorithm == NIA1 || intAlgorithm == NIA2)
387                 {
388                         pDrbSecInfo->intAlgorithm  = intAlgorithm;
389                         VOS_MemCpy(pDrbSecInfo->kUpInt, pIntKey, AS_KEY_LEN);           /* 128 bits */
390                 }else
391                 {
392                         pDrbSecInfo->intActiveFlag = INACTIVE_INT_STATE;
393                         pdcpuLog(LOG_ERR,"[PDCPU] integrity algorithm is %d, not supported!\n",intAlgorithm);
394                         pdcpuFreeSecInfo(ueIdx);
395                         return VOS_ERROR;
396                 }
397         }else
398         {
399                 pDrbSecInfo->intActiveFlag = INACTIVE_INT_STATE;
400                 pdcpuLog(LOG_INFO,"[PDCPU] integrity is not config\n");
401         }
402         
403         /* activate encryption */       
404         UINT8  encAlgorithm = secInfo->secuAlgorithm.cipheringAlgorithm;
405         UINT8 *pEncKey          = secInfo->upSecukey.encryptionKey.buffer;
406         UINT8  encKeyLen        = secInfo->upSecukey.encryptionKey.size;                /* 128 bits */
407
408         if(encKeyLen < AS_KEY_LEN)
409         {
410                 pdcpuLog(LOG_ERR,"[PDCPU] encryption parameter is wrong!\n");
411                 pdcpuFreeSecInfo(ueIdx);
412                 return VOS_ERROR;
413         }
414
415         pDrbSecInfo->encActiveFlag = ACTIVE_ENC_STATE;                                          /* 0-inactive, 1-active */
416         if(encAlgorithm == NEA0 || encAlgorithm == NEA1 || encAlgorithm == NEA2)
417         {                       
418                 pDrbSecInfo->encAlgorithm  = encAlgorithm;      
419                 VOS_MemCpy(pDrbSecInfo->kUpEnc, pEncKey, AS_KEY_LEN);                   /* 128 bits */
420         }else
421         {
422                 pDrbSecInfo->encActiveFlag = INACTIVE_ENC_STATE;                
423                 pdcpuLog(LOG_ERR,"[PDCPU] encryption algorithm:%d, is not supported!\n", encAlgorithm);
424                 pdcpuFreeSecInfo(ueIdx);
425                 return VOS_ERROR;
426         }
427
428         pDrbSecInfo->ueE1apId = ueE1apId;
429         pDrbSecInfo->ueIdx        = ueIdx;
430         pDrbSecInfo->nhInd        = FALSE;
431                 
432         return VOS_OK;
433 }
434