1 /******************************************************************************
3 * Copyright (c) 2020 ICT/CAS.
5 * Licensed under the O-RAN Software License, Version 1.0 (the "Software License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * https://www.o-ran.org/software
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
19 #include "vos_types.h"
20 #include "vos_string.h"
23 #include "pdcpuCore.h"
24 #include "pdcpCommon.h"
25 #include "cuupCommon.h"
26 #include "cuModuleInterface.h"
27 #include "pdcpComprohc.h"
29 #include "cuupUeIdTransf.h"
30 #include "upcContext.h"
32 extern PdcpuUeInfo_t *gPdcpuUeInfo[MAX_UE_NUM];
34 CuupUeIdxTable_t gPdcpuUeIdxTable;
37 /*******************************************************************************
44 *******************************************************************************/
45 INT32 pdcpuInit(ULONG userModuleId)
47 /* get pdcpu moduleId */
48 gPdcpuModuleId = userModuleId;
50 /* init ueIdx table */
52 for(i=0; i<MAX_UE_NUM; i++)
54 gPdcpuUeIdxTable.ueIdxInfo[i].isUsed = FALSE;
58 for(i=0; i<MAX_UE_NUM; i++)
60 gPdcpuUeInfo[i] = NULL;
67 INT32 pdcpuFreeSecInfo(UINT16 ueIdx)
69 PdcpuSecInfo_t *pDrbSecInfo = gPdcpuUeInfo[ueIdx]->secInfo;
70 if(NULL != pDrbSecInfo)
72 VOS_Free(pDrbSecInfo);
73 gPdcpuUeInfo[ueIdx]->secInfo = NULL;
79 /*******************************************************************************
80 * To deal with security indication
81 * Security Result indicates whether the security policy indicated as "preferred"
82 * in the Security Indication IE is performed or not.
84 * ueE1apId : UE E1AP ID
85 * pduSessionId : pdu session id
86 * pSecInd : security indication
87 * pSecResult : security result
91 *******************************************************************************/
92 INT32 pdcpuDealSecurityInd(PdcpuSecInfo_t *pSec, PdcpuSecEnableInfo_t *pEnableInfo, SecuInd_t *pSecInd, PdcpuCfgResult_t *pResult)
94 /* get security enable information global variable */
96 pdcpuNullCheck(pEnableInfo);
97 pdcpuNullCheck(pSecInd);
99 /* for integrity protection */
100 if(ACTIVE_INT_STATE == pSec->intActiveFlag)
102 /* integrity protection is active for the UE, apply the indication */
103 if(IP_REQUIRED == pSecInd->IPIndication)
105 pEnableInfo->integrityEnableFlag = TRUE;
106 pEnableInfo->maxIPDataRate = pSecInd->maxIPdataRate;
107 pResult->secResPresent = FALSE;
109 }else if(IP_PREFERRED == pSecInd->IPIndication)
111 pEnableInfo->integrityEnableFlag = TRUE;
112 pEnableInfo->maxIPDataRate = pSecInd->maxIPdataRate;
113 pResult->secResPresent = TRUE;
114 pResult->secuResult.integrityProtectionResult= IP_RESULT_PERFORMED;
118 pEnableInfo->integrityEnableFlag = FALSE;
119 pResult->secResPresent = FALSE;
125 /* integrity protection is inactive for the UE */
126 pEnableInfo->integrityEnableFlag = FALSE;
127 if(IP_PREFERRED == pSecInd->IPIndication)
129 pResult->secResPresent = TRUE;
130 pResult->secuResult.integrityProtectionResult= IP_RESULT_NOT_PERFORMED;
135 if(ACTIVE_ENC_STATE == pSec->encActiveFlag)
137 /* ciphering is active for the UE, apply the indication */
138 if(CP_REQUIRED == pSecInd->CPIndication)
140 pEnableInfo->cipherEnableFlag = TRUE;
141 pResult->secResPresent = FALSE;
143 }else if(CP_PREFERRED == pSecInd->CPIndication)
145 pEnableInfo->cipherEnableFlag = TRUE;
146 pResult->secResPresent = TRUE;
147 pResult->secuResult.confidentialityProtectionResult = CP_RESULT_PERFORMED;
151 pEnableInfo->cipherEnableFlag = FALSE;
152 pResult->secResPresent = FALSE;
158 /* ciphering is inactive for the UE */
159 pEnableInfo->cipherEnableFlag = FALSE;
160 if(CP_PREFERRED == pSecInd->CPIndication)
162 pResult->secResPresent = TRUE;
163 pResult->secuResult.confidentialityProtectionResult= CP_RESULT_NOT_PERFORMED;
170 INT32 pdcpuRetFailResult(UpcCfgType_e cfgType, upcTempSessInfo_t *pCfgInfo, PdcpuCfgResult_t *pResult)
172 pdcpuLog(LOG_ERR,"[PDCPU] pdu session config failed\n");
175 if(PDU_SESSION_ADD == cfgType)
177 /* drb to setup list */
178 for(i=0; i<pCfgInfo->drbSetupNum; i++)
180 pResult->drbSetupFailedArray[i].drbId = pCfgInfo->pTempDrbSetupList[i].drbId;
181 pResult->drbSetupFailedArray[i].cause = RNL_UNSPECIFIED;
183 pResult->drbSetupFailNum = pCfgInfo->drbSetupNum;
184 pResult->pduSessionCause = RNL_UNSPECIFIED;
192 /*******************************************************************************
193 * To deal with PDU session to setup config
195 * ueE1apId : UE E1AP ID
196 * pPduSessionCfg : PDU session to setup config
197 * pResult : PDU session to setup result
200 *******************************************************************************/
201 INT32 pdcpuSessionAddProc(UINT64 ueE1apId, VOID *pCfgInfo, PdcpuCfgResult_t *pResult)
203 upcTempSessInfo_t *pSetupInfo = (upcTempSessInfo_t *)pCfgInfo;
204 upcTempDrbInfo_t *pDrbTemp = NULL;
205 PdcpuSecInfo_t *pSec = NULL;
206 PdcpuSecEnableInfo_t *pEnableInfo = NULL;
208 UINT16 pduSessionId = pSetupInfo->pduSessId;
209 pResult->pduSessionId = pduSessionId;
213 if(VOS_ERROR == cuupAddUeE1apid(ueE1apId, &ueIdx, &gPdcpuUeIdxTable))
215 pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n");
216 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
219 /* check ue and security context block */
220 if((NULL == gPdcpuUeInfo[ueIdx]) || (NULL == gPdcpuUeInfo[ueIdx]->secInfo))
222 pdcpuLog(LOG_ERR,"[PDCPU] ue and security context block not exist\n");
223 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
225 pSec = gPdcpuUeInfo[ueIdx]->secInfo;
227 /* alloc pdu session information */
228 pEnableInfo = gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId];
229 if(NULL == pEnableInfo)
231 pEnableInfo = VOS_Malloc(sizeof(PdcpuSecEnableInfo_t), gPdcpuModuleId);
232 if(NULL == pEnableInfo)
234 pdcpuLog(LOG_ERR,"[PDCPU] vos_malloc failed\n");
235 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
237 VOS_MemZero(pEnableInfo, sizeof(PdcpuSecEnableInfo_t));
238 gPdcpuUeInfo[ueIdx]->secEnableInfo[pduSessionId] = pEnableInfo;
240 pEnableInfo->pduSessionId = pduSessionId;
242 /* deal with security indication */
243 if(VOS_ERROR == pdcpuDealSecurityInd(pSec, pEnableInfo, &pSetupInfo->secuIndi, pResult))
245 pdcpuLog(LOG_ERR,"[PDCPU] deal security indication failed\n");
246 return pdcpuRetFailResult(PDU_SESSION_ADD,pCfgInfo,pResult);
249 /* create pdcp entity */
251 for(i = 0; i < pSetupInfo->drbSetupNum; i++)
253 pDrbTemp = &pSetupInfo->pTempDrbSetupList[i];
255 if((NULL == pDrbTemp) || (FALSE == pDrbTemp->drbSetupAllowed))
260 if(VOS_OK == pdcpuCreateEntity(ueE1apId, ueIdx, pduSessionId, pDrbTemp))
262 pResult->drbSetupSuccessArray[pResult->drbSetupSuccessNum] = pDrbTemp->drbId;
263 pResult->drbSetupSuccessNum += 1;
266 pResult->drbSetupFailedArray[pResult->drbSetupFailNum].drbId = pDrbTemp->drbId;
267 pResult->drbSetupFailedArray[pResult->drbSetupFailNum].cause = RNL_PDCP_CONFIG_NOT_SUPPORT;
268 pResult->drbSetupFailNum += 1;
274 if(0 != pResult->drbSetupSuccessNum)
279 pResult->pduSessionCause = RNL_UNSPECIFIED;
280 pdcpuLog(LOG_ERR,"[PDCPU] all drbs setup failed\n");
285 /*******************************************************************************
286 * To manage pdcp-u entity
288 * ueE1apId : UE E1AP ID
289 * pPduSessionCfg : PDU Session Resource to setup item
290 * cfgType : configuration type
291 * pResult : result which will return to upc
293 * result: PDCP config result
294 *******************************************************************************/
295 INT32 pdcpuConfig(UINT64 ueE1apId, VOID *pCfgInfo, UpcCfgType_e cfgType, PdcpuCfgResult_t *pResult)
299 case PDU_SESSION_ADD:
301 pdcpuNullCheck(pCfgInfo);
302 pdcpuNullCheck(pResult);
303 VOS_MemZero(pResult, sizeof(PdcpuCfgResult_t));
304 pResult->cfgType = cfgType;
305 return pdcpuSessionAddProc(ueE1apId, pCfgInfo, pResult);
309 pdcpuLog(LOG_ERR,"[PDCPU] cfgType error\n");
317 /*******************************************************************************
318 * To get ue security information pointer
322 * pDrbSecInfo: ue security information pointer
323 *******************************************************************************/
324 PdcpuSecInfo_t *pdcpuAllocUeSecInfo(UINT16 ueIdx)
326 PdcpuSecInfo_t *pSecInfo = NULL;
327 PdcpuUeInfo_t *pPdcpUeInfo = NULL;
330 if(NULL == gPdcpuUeInfo[ueIdx])
332 pPdcpUeInfo = VOS_Malloc(sizeof(PdcpuUeInfo_t), gPdcpuModuleId);
333 pdcpuNullCheckRp(pPdcpUeInfo);
334 VOS_MemZero(pPdcpUeInfo, sizeof(PdcpuUeInfo_t));
335 gPdcpuUeInfo[ueIdx] = pPdcpUeInfo;
338 pPdcpUeInfo = gPdcpuUeInfo[ueIdx];
341 if(NULL == pPdcpUeInfo->secInfo)
343 pSecInfo = VOS_Malloc(sizeof(PdcpuSecInfo_t), gPdcpuModuleId);
344 pdcpuNullCheckRp(pSecInfo);
345 VOS_MemZero(pSecInfo, sizeof(PdcpuSecInfo_t));
346 pPdcpUeInfo->secInfo = pSecInfo;
349 pSecInfo = pPdcpUeInfo->secInfo;
352 VOS_MemZero(pSecInfo, sizeof(PdcpuSecInfo_t));
358 /*******************************************************************************
359 * To set ue security parameters. When receiving security information,
360 * pdcp-u shall save AS keys, AS algorithm and active integrity and ciphering.
362 * ueE1apId: UE E1AP ID
363 * secInfo: security information
367 *******************************************************************************/
368 INT32 pdcpuSetSecParam(UINT64 ueE1apId, SecuInfo_t *secInfo)
370 pdcpuNullCheck(secInfo);
373 if(VOS_ERROR == cuupAddUeE1apid(ueE1apId, &ueIdx, &gPdcpuUeIdxTable))
375 pdcpuLog(LOG_ERR,"[PDCPU] add ueE1apId failed\n");
379 /* find ue security struct */
380 PdcpuSecInfo_t *pDrbSecInfo = pdcpuAllocUeSecInfo(ueIdx);
381 pdcpuNullCheck(pDrbSecInfo);
383 /* activate integrity */
384 if(secInfo->secuAlgorithm.bitMask & SECURITY_ALGORITHM_INTERGRITY_PROTECTION_ALGORITHM)
386 UINT8 intAlgorithm = secInfo->secuAlgorithm.integrityProtectionAlgorithm;
387 UINT8 *pIntKey = secInfo->upSecukey.integrityProtectionKey.buffer;
388 UINT8 intKeyLen = secInfo->upSecukey.integrityProtectionKey.size; /* 128 bits */
390 if(intKeyLen < AS_KEY_LEN)
392 pdcpuLog(LOG_ERR,"[PDCPU] integrity parameter is wrong!\n");
393 pdcpuFreeSecInfo(ueIdx);
397 pDrbSecInfo->intActiveFlag = ACTIVE_INT_STATE; /* 0-inactive, 1-active */
398 if(intAlgorithm == NIA0 || intAlgorithm == NIA1 || intAlgorithm == NIA2)
400 pDrbSecInfo->intAlgorithm = intAlgorithm;
401 VOS_MemCpy(pDrbSecInfo->kUpInt, pIntKey, AS_KEY_LEN); /* 128 bits */
404 pDrbSecInfo->intActiveFlag = INACTIVE_INT_STATE;
405 pdcpuLog(LOG_ERR,"[PDCPU] integrity algorithm is %d, not supported!\n",intAlgorithm);
406 pdcpuFreeSecInfo(ueIdx);
411 pDrbSecInfo->intActiveFlag = INACTIVE_INT_STATE;
412 pdcpuLog(LOG_INFO,"[PDCPU] integrity is not config\n");
415 /* activate encryption */
416 UINT8 encAlgorithm = secInfo->secuAlgorithm.cipheringAlgorithm;
417 UINT8 *pEncKey = secInfo->upSecukey.encryptionKey.buffer;
418 UINT8 encKeyLen = secInfo->upSecukey.encryptionKey.size; /* 128 bits */
420 if(encKeyLen < AS_KEY_LEN)
422 pdcpuLog(LOG_ERR,"[PDCPU] encryption parameter is wrong!\n");
423 pdcpuFreeSecInfo(ueIdx);
427 pDrbSecInfo->encActiveFlag = ACTIVE_ENC_STATE; /* 0-inactive, 1-active */
428 if(encAlgorithm == NEA0 || encAlgorithm == NEA1 || encAlgorithm == NEA2)
430 pDrbSecInfo->encAlgorithm = encAlgorithm;
431 VOS_MemCpy(pDrbSecInfo->kUpEnc, pEncKey, AS_KEY_LEN); /* 128 bits */
434 pDrbSecInfo->encActiveFlag = INACTIVE_ENC_STATE;
435 pdcpuLog(LOG_ERR,"[PDCPU] encryption algorithm:%d, is not supported!\n", encAlgorithm);
436 pdcpuFreeSecInfo(ueIdx);
440 pDrbSecInfo->ueE1apId = ueE1apId;
441 pDrbSecInfo->ueIdx = ueIdx;
442 pDrbSecInfo->nhInd = FALSE;