Commit cf70265b authored by rmagueta's avatar rmagueta

Merge remote-tracking branch 'origin/develop' into develop-SA-CBRA

# Conflicts:
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
#	openair2/LAYER2/NR_MAC_gNB/mac_proto.h
parents c8fbcdf7 17d4c5c2
...@@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC ...@@ -1968,6 +1968,7 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
) )
......
...@@ -1292,7 +1292,9 @@ ...@@ -1292,7 +1292,9 @@
(Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols), (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
(Test9: SC-FDMA, 50 PRBs), (Test9: SC-FDMA, 50 PRBs),
(Test10: SC-FDMA, 75 PRBs), (Test10: SC-FDMA, 75 PRBs),
(Test11: SC-FDMA, 3 DMRS)</desc> (Test11: SC-FDMA, 216 PRBs),
(Test12: SC-FDMA, 273 PRBs),
(Test13: SC-FDMA, 3 DMRS)</desc>
<pre_compile_prog></pre_compile_prog> <pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args> <compile_prog_args> --phy_simulators -c </compile_prog_args>
...@@ -1307,10 +1309,13 @@ ...@@ -1307,10 +1309,13 @@
-n100 -s5 -T 2 1 2 -U 2 0 2 -n100 -s5 -T 2 1 2 -U 2 0 2
-n100 -s5 -T 2 2 2 -U 2 1 2 -n100 -s5 -T 2 2 2 -U 2 1 2
-n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
-n100 -s20 -Z -n100 -s2 -Z
-n100 -s20 -Z -r75 -n100 -s2 -Z -r75
-n100 -s20 -Z -U 2 0 2</main_exec_args> -n100 -s2 -Z -r216 -R217
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11</tags> -n100 -s2 -Z -r270 -R273
-n100 -s2 -Z -U 2 0 2</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13</tags>
<search_expr_true>PUSCH test OK</search_expr_true> <search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns> <nruns>3</nruns>
......
...@@ -715,8 +715,10 @@ typedef struct { ...@@ -715,8 +715,10 @@ typedef struct {
uint16_t prgSize; uint16_t prgSize;
/// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
uint8_t digBFInterfaces; uint8_t digBFInterfaces;
// Depends on numPRGs
uint16_t PMIdx[275]; uint16_t PMIdx[275];
uint16_t *beamIdx[275]; // Depends on digBFInterfaces
uint16_t beamIdx[256];
} nfapi_nr_tx_precoding_and_beamforming_t; } nfapi_nr_tx_precoding_and_beamforming_t;
//table 3-37 //table 3-37
......
...@@ -325,10 +325,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, ...@@ -325,10 +325,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
{ {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || +defined(__i386__)
__m128i dft_in128[1][1200], dft_out128[1][1200]; __m128i dft_in128[1][3240], dft_out128[1][3240];
#elif defined(__arm__) #elif defined(__arm__)
int16x8_t dft_in128[1][1200], dft_out128[1][1200]; int16x8_t dft_in128[1][3240], dft_out128[1][3240];
#endif #endif
uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0]; uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0];
...@@ -340,8 +340,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) ...@@ -340,8 +340,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
int16x8_t norm128; int16x8_t norm128;
#endif #endif
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { if ((Msc_PUSCH % 1536) > 0) {
dft_in0[ip] = d[i]; for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
dft_in0[ip] = d[i];
}
} }
switch (Msc_PUSCH) { switch (Msc_PUSCH) {
...@@ -480,7 +482,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) ...@@ -480,7 +482,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
break; break;
case 972: case 972:
dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); dft(DFT_972,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break; break;
case 1080: case 1080:
...@@ -494,11 +496,98 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) ...@@ -494,11 +496,98 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
case 1200: case 1200:
dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break; break;
case 1296:
dft(DFT_1296,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1440:
dft(DFT_1440,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1500:
dft(DFT_1500,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1536:
//dft(DFT_1536,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
dft(DFT_1536,(int16_t*)d, (int16_t*)z, 1);
break;
case 1620:
dft(DFT_1620,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1728:
dft(DFT_1728,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1800:
dft(DFT_1800,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1920:
dft(DFT_1920,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1944:
dft(DFT_1944,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2160:
dft(DFT_2160,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2304:
dft(DFT_2304,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2400:
dft(DFT_2400,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2592:
dft(DFT_2592,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2700:
dft(DFT_2700,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2880:
dft(DFT_2880,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 2916:
dft(DFT_2916,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 3000:
dft(DFT_3000,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 3072:
//dft(DFT_3072,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
dft(DFT_3072,(int16_t*)d, (int16_t*)z, 1);
break;
case 3240:
dft(DFT_3240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
default:
// should not be reached
LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
return;
} }
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
z[i] = dft_out0[ip]; if ((Msc_PUSCH % 1536) > 0) {
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
z[i] = dft_out0[ip];
} }
} }
......
...@@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) ...@@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
{ {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
__m128i idft_in128[1][1200], idft_out128[1][1200]; __m128i idft_in128[1][3240], idft_out128[1][3240];
__m128i norm128; __m128i norm128;
#elif defined(__arm__) #elif defined(__arm__)
int16x8_t idft_in128[1][1200], idft_out128[1][1200]; int16x8_t idft_in128[1][3240], idft_out128[1][3240];
int16x8_t norm128; int16x8_t norm128;
#endif #endif
int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0]; int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0];
...@@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) ...@@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
// conjugate input if ((Msc_PUSCH % 1536) > 0) {
for (i = 0; i < (Msc_PUSCH>>2); i++) { // conjugate input
for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__)||defined(__i386__) #if defined(__x86_64__)||defined(__i386__)
*&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
#elif defined(__arm__) #elif defined(__arm__)
*&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif #endif
}
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
((uint32_t*)idft_in0)[ip+0] = z[i];
} }
for (i=0,ip=0; i<Msc_PUSCH; i++, ip+=4) {
((int32_t*)idft_in0)[ip+0] = z[i];
}
switch (Msc_PUSCH) { switch (Msc_PUSCH) {
case 12: case 12:
dft(DFT_12,(int16_t *)idft_in0, (int16_t *)idft_out0,0); dft(DFT_12,(int16_t *)idft_in0, (int16_t *)idft_out0,0);
...@@ -194,25 +193,102 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) ...@@ -194,25 +193,102 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
dft(DFT_1200,idft_in0, idft_out0, 1); dft(DFT_1200,idft_in0, idft_out0, 1);
break; break;
case 1296:
dft(DFT_1296,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1440:
dft(DFT_1440,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1500:
dft(DFT_1500,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1536:
//dft(DFT_1536,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
idft(IDFT_1536,(int16_t*)z, (int16_t*)z, 1);
break;
case 1620:
dft(DFT_1620,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1728:
dft(DFT_1728,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1800:
dft(DFT_1800,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1920:
dft(DFT_1920,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1944:
dft(DFT_1944,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2160:
dft(DFT_2160,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2304:
dft(DFT_2304,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2400:
dft(DFT_2400,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2592:
dft(DFT_2592,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2700:
dft(DFT_2700,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2880:
dft(DFT_2880,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 2916:
dft(DFT_2916,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 3000:
dft(DFT_3000,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 3072:
//dft(DFT_3072,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
idft(IDFT_3072,(int16_t*)z, (int16_t*)z, 1);
break;
case 3240:
dft(DFT_3240,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
default: default:
// should not be reached // should not be reached
LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH ); LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
return; return;
} }
if ((Msc_PUSCH % 1536) > 0) {
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
z[i] = ((uint32_t*)idft_out0)[ip];
// conjugate output
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { for (i = 0; i < (Msc_PUSCH>>2); i++) {
z[i] = ((int32_t*)idft_out0)[ip];
}
// conjugate output
for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
#elif defined(__arm__) #elif defined(__arm__)
*&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif #endif
}
} }
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
...@@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) ...@@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
} }
void nr_ulsch_extract_rbs_single(int32_t **rxdataF, void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars, NR_gNB_PUSCH *pusch_vars,
unsigned char symbol, unsigned char symbol,
......
This diff is collapsed.
...@@ -226,9 +226,26 @@ void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag); ...@@ -226,9 +226,26 @@ void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag); void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag); void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag); void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag); void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag); void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag); void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
...@@ -283,21 +300,25 @@ typedef enum DFT_size_idx { ...@@ -283,21 +300,25 @@ typedef enum DFT_size_idx {
DFT_108, DFT_120, DFT_128, DFT_144, DFT_180, DFT_192, DFT_216, DFT_240, DFT_108, DFT_120, DFT_128, DFT_144, DFT_180, DFT_192, DFT_216, DFT_240,
DFT_256, DFT_288, DFT_300, DFT_324, DFT_360, DFT_384, DFT_432, DFT_480, DFT_256, DFT_288, DFT_300, DFT_324, DFT_360, DFT_384, DFT_432, DFT_480,
DFT_512, DFT_540, DFT_576, DFT_600, DFT_648, DFT_720, DFT_768, DFT_864, DFT_512, DFT_540, DFT_576, DFT_600, DFT_648, DFT_720, DFT_768, DFT_864,
DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1536, DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1296,
DFT_2048, DFT_3072, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, DFT_18432, DFT_1440, DFT_1500, DFT_1536, DFT_1620, DFT_1728, DFT_1800, DFT_1920, DFT_1944,
DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, DFT_2048, DFT_2160, DFT_2304, DFT_2400, DFT_2592, DFT_2700, DFT_2880, DFT_2916,
DFT_3000, DFT_3072, DFT_3240, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288,
DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304,
DFT_SIZE_IDXTABLESIZE DFT_SIZE_IDXTABLESIZE
} dft_size_idx_t; } dft_size_idx_t;
#ifdef OAIDFTS_MAIN #ifdef OAIDFTS_MAIN
adftfunc_t dft_ftab[]={ adftfunc_t dft_ftab[]={
dft12, dft24, dft36, dft48, dft60, dft72, dft96, dft12, dft24, dft36, dft48, dft60, dft72, dft96,
dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240,
dft256, dft288, dft300, dft324, dft360, dft384, dft432, dft480, dft256, dft288, dft300, dft324, dft360, dft384, dft432, dft480,
dft512, dft540, dft576, dft600, dft648, dft720, dft768, dft864, dft512, dft540, dft576, dft600, dft648, dft720, dft768, dft864,
dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1536, dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1296,
dft2048, dft3072, dft4096, dft6144, dft8192, dft9216, dft12288, dft18432, dft1440, dft1500, dft1536, dft1620, dft1728, dft1800, dft1920, dft1944,
dft24576, dft36864, dft49152, dft73728, dft98304 dft2048, dft2160, dft2304, dft2400, dft2592, dft2700, dft2880, dft2916,
dft3000, dft3072, dft3240, dft4096, dft6144, dft8192, dft9216, dft12288,
dft18432, dft24576, dft36864, dft49152, dft73728, dft98304
}; };
#endif #endif
...@@ -309,9 +330,9 @@ typedef enum idft_size_idx { ...@@ -309,9 +330,9 @@ typedef enum idft_size_idx {
} idft_size_idx_t; } idft_size_idx_t;
#ifdef OAIDFTS_MAIN #ifdef OAIDFTS_MAIN
aidftfunc_t idft_ftab[]={ aidftfunc_t idft_ftab[]={
idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096,
idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152,
idft73728, idft98304 idft73728, idft98304
}; };
#endif #endif
......
...@@ -166,6 +166,12 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( ...@@ -166,6 +166,12 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
return 0; return 0;
} }
int nr_derive_key(int alg_type, uint8_t alg_id,
const uint8_t key[32], uint8_t **out)
{
return 0;
}
void config_common(int Mod_idP, void config_common(int Mod_idP,
int pdsch_AntennaPorts, int pdsch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc NR_ServingCellConfigCommon_t *scc
......
...@@ -153,6 +153,12 @@ int is_x2ap_enabled(void) ...@@ -153,6 +153,12 @@ int is_x2ap_enabled(void)
return 0; return 0;
} }
int nr_derive_key(int alg_type, uint8_t alg_id,
const uint8_t key[32], uint8_t **out)
{
return 0;
}
int main(int argc, char **argv){ int main(int argc, char **argv){
char c; char c;
......
...@@ -177,6 +177,12 @@ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); ...@@ -177,6 +177,12 @@ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0);
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int nr_derive_key(int alg_type, uint8_t alg_id,
const uint8_t key[32], uint8_t **out)
{
return 0;
}
// needed for some functions // needed for some functions
uint16_t n_rnti = 0x1234; uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS]; openair0_config_t openair0_cfg[MAX_CARDS];
......
...@@ -155,6 +155,11 @@ typedef struct security_capabilities_s { ...@@ -155,6 +155,11 @@ typedef struct security_capabilities_s {
uint16_t integrity_algorithms; uint16_t integrity_algorithms;
} security_capabilities_t; } security_capabilities_t;
typedef struct nr_security_capabilities_s {
uint16_t encryption_algorithms;
uint16_t integrity_algorithms;
} nr_security_capabilities_t;
/* Provides the establishment cause for the RRC connection request as provided /* Provides the establishment cause for the RRC connection request as provided
* by the upper layers. W.r.t. the cause value names: highPriorityAccess * by the upper layers. W.r.t. the cause value names: highPriorityAccess
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for * concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
...@@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s { ...@@ -538,6 +543,9 @@ typedef struct s1ap_initial_context_setup_req_s {
uint8_t nb_of_e_rabs; uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */ /* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB]; e_rab_t e_rab_param[S1AP_MAX_E_RAB];
/* NR Security algorithms (if any, set to 0 if not present) */
nr_security_capabilities_t nr_security_capabilities;
} s1ap_initial_context_setup_req_t; } s1ap_initial_context_setup_req_t;
typedef struct tai_plmn_identity_s { typedef struct tai_plmn_identity_s {
......
...@@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { ...@@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s {
/* used for RRC->X2AP in source eNB */ /* used for RRC->X2AP in source eNB */
int rnti; int rnti;
security_capabilities_t security_capabilities; nr_security_capabilities_t security_capabilities;
/* SgNB Security Key */ /* SgNB Security Key */
uint8_t kgnb[32]; uint8_t kgnb[32];
......
...@@ -163,6 +163,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { ...@@ -163,6 +163,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t)); // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long));
// 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED.
*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t));
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup;
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon)); scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon));
...@@ -513,6 +515,101 @@ void RCconfig_nr_macrlc() { ...@@ -513,6 +515,101 @@ void RCconfig_nr_macrlc() {
} }
void config_security(gNB_RRC_INST *rrc)
{
paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC;
int ret = config_get(logparams_defaults,
sizeof(logparams_defaults) / sizeof(paramdef_t),
CONFIG_STRING_SECURITY);
int i;
if (ret < 0) {
LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n");
rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
rrc->security.ciphering_algorithms_count = 1;
rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
rrc->security.integrity_algorithms_count = 1;
return;
}
if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) {
LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n");
exit(1);
}
if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) {
LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n");
exit(1);
}
/* get ciphering algorithms */
rrc->security.ciphering_algorithms_count = 0;
for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) {
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) {
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0;
rrc->security.ciphering_algorithms_count++;
continue;
}
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) {
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1;
rrc->security.ciphering_algorithms_count++;
continue;
}
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) {
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2;
rrc->security.ciphering_algorithms_count++;
continue;
}
if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) {
rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3;
rrc->security.ciphering_algorithms_count++;
continue;
}
LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n",
logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]);
exit(1);
}
/* get integrity algorithms */
rrc->security.integrity_algorithms_count = 0;
for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) {
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) {
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0;
rrc->security.integrity_algorithms_count++;
continue;
}
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) {
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1;
rrc->security.integrity_algorithms_count++;
continue;
}
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) {
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2;
rrc->security.integrity_algorithms_count++;
continue;
}
if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) {
rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3;
rrc->security.integrity_algorithms_count++;
continue;
}
LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n",
logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]);
exit(1);
}
if (rrc->security.ciphering_algorithms_count == 0) {
LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n");
rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
rrc->security.ciphering_algorithms_count = 1;
}
if (rrc->security.integrity_algorithms_count == 0) {
LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n");
rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
rrc->security.integrity_algorithms_count = 1;
}
}
void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
int num_gnbs = 0; int num_gnbs = 0;
...@@ -679,7 +776,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { ...@@ -679,7 +776,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}//End for (k=0; k <num_gnbs ; k++) }//End for (k=0; k <num_gnbs ; k++)
}//End if (num_gnbs>0) }//End if (num_gnbs>0)
config_security(rrc);
}//End RCconfig_NRRRC function }//End RCconfig_NRRRC function
int RCconfig_nr_gtpu(void ) { int RCconfig_nr_gtpu(void ) {
......
...@@ -452,4 +452,27 @@ typedef enum { ...@@ -452,4 +452,27 @@ typedef enum {
#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n" #define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n" #define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* security configuration */
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CONFIG_STRING_SECURITY "security"
#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms"
#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms"
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* security configuration */
/* optname help paramflags XXXptr defXXXval type numelt */
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define SECURITY_GLOBALPARAMS_DESC { \
{SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
{SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
}
#define SECURITY_CONFIG_CIPHERING_IDX 0
#define SECURITY_CONFIG_INTEGRITY_IDX 1
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif #endif
...@@ -401,21 +401,37 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ...@@ -401,21 +401,37 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup); const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup);
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti); LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) { } else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
/* TODO: should check for free RA process */
const int CC_id = 0; const int CC_id = 0;
NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0]; NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id];
ra->state = RA_IDLE; uint8_t ra_index = 0;
/* checking for free RA process */
for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) {
if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break;
}
if (ra_index == NR_NB_RA_PROC_MAX) {
LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
return -1;
}
NR_RA_t *ra = &cc->ra[ra_index];
ra->secondaryCellGroup = secondaryCellGroup; ra->secondaryCellGroup = secondaryCellGroup;
if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) { if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) {
if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) { if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
ra->cfra = true; ra->cfra = true;
ra->rnti = rnti; ra->rnti = rnti;
struct NR_CFRA cfra = *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; struct NR_CFRA *cfra = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
uint8_t num_preamble = cfra.resources.choice.ssb->ssb_ResourceList.list.count; uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble; ra->preambles.num_preambles = num_preamble;
ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
for (int i = 0; i < num_preamble; i++) for(int i=0; i<cc->num_active_ssb; i++) {
ra->preambles.preamble_list[i] = cfra.resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; for(int j=0; j<num_preamble; j++) {
if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
// one dedicated preamble for each beam
ra->preambles.preamble_list[i] =
cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
break;
}
}
}
} }
} else { } else {
ra->cfra = false; ra->cfra = false;
......
...@@ -245,7 +245,9 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, ...@@ -245,7 +245,9 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
TX_req->PDU_index = nr_mac->pdu_index[CC_id]++; TX_req->PDU_index = nr_mac->pdu_index[CC_id]++;
TX_req->num_TLV = 1; TX_req->num_TLV = 1;
TX_req->TLVs[0].length = 8; TX_req->TLVs[0].length = 8;
memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length); // why do we copy from RAR_pdu here? Shouldn't we fill some more or less
// meaningful data, e.g., padding + random data?
//memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length);
nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].SFN=frameP; nr_mac->TX_req[CC_id].SFN=frameP;
nr_mac->TX_req[CC_id].Slot=slotP; nr_mac->TX_req[CC_id].Slot=slotP;
......
...@@ -432,7 +432,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -432,7 +432,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (sduP != NULL){ if (sduP != NULL){
LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); LOG_D(NR_MAC, "Received PDU at MAC gNB \n");
UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0) if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0; UE_scheduling_control->sched_ul_bytes = 0;
...@@ -442,7 +443,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -442,7 +443,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
/* reduce sched_ul_bytes when cur_harq->round == 3 */ /* reduce sched_ul_bytes when cur_harq->round == 3 */
if (cur_harq->round == 3){ if (cur_harq->round == 3){
UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0) if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0; UE_scheduling_control->sched_ul_bytes = 0;
} }
...@@ -867,7 +869,7 @@ void nr_schedule_ulsch(module_id_t module_id, ...@@ -867,7 +869,7 @@ void nr_schedule_ulsch(module_id_t module_id,
/* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each /* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each
* allocated PDCCH so we can easily allocate UE's DCIs independent of any * allocated PDCCH so we can easily allocate UE's DCIs independent of any
* CORESET order */ * CORESET order */
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {0}; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {{0}};
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
...@@ -921,6 +923,7 @@ void nr_schedule_ulsch(module_id_t module_id, ...@@ -921,6 +923,7 @@ void nr_schedule_ulsch(module_id_t module_id,
/* Save information on MCS, TBS etc for the current initial transmission /* Save information on MCS, TBS etc for the current initial transmission
* so we have access to it when retransmitting */ * so we have access to it when retransmitting */
cur_harq->sched_pusch = *sched_pusch; cur_harq->sched_pusch = *sched_pusch;
sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
} else { } else {
LOG_D(MAC, LOG_D(MAC,
"%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n",
...@@ -934,7 +937,6 @@ void nr_schedule_ulsch(module_id_t module_id, ...@@ -934,7 +937,6 @@ void nr_schedule_ulsch(module_id_t module_id,
cur_harq->ndi); cur_harq->ndi);
} }
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
LOG_D(MAC, LOG_D(MAC,
"%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
......
...@@ -353,10 +353,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, ...@@ -353,10 +353,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
unsigned char drx_cmd, unsigned char drx_cmd,
unsigned char *ue_cont_res_id); unsigned char *ue_cont_res_id);
void nr_generate_Msg2(module_id_t module_idP, void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
int CC_id,
frame_t frameP,
sub_frame_t slotP);
void nr_generate_Msg4(module_id_t module_idP, void nr_generate_Msg4(module_id_t module_idP,
int CC_id, int CC_id,
......
...@@ -194,8 +194,6 @@ typedef struct { ...@@ -194,8 +194,6 @@ typedef struct {
uint32_t PCCH_alloc_pdu; uint32_t PCCH_alloc_pdu;
/// Outgoing PCCH pdu for PHY /// Outgoing PCCH pdu for PHY
PCCH_PDU PCCH_pdu; PCCH_PDU PCCH_pdu;
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations /// Template for RA computations
NR_RA_t ra[NR_NB_RA_PROC_MAX]; NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels /// VRB map for common channels
...@@ -215,6 +213,8 @@ typedef struct { ...@@ -215,6 +213,8 @@ typedef struct {
uint8_t max_association_period; uint8_t max_association_period;
//SSB index //SSB index
uint8_t ssb_index[MAX_NUM_OF_SSB]; uint8_t ssb_index[MAX_NUM_OF_SSB];
//CB preambles for each SSB
uint8_t cb_preambles_per_ssb;
} NR_COMMON_channels_t; } NR_COMMON_channels_t;
......
...@@ -22,11 +22,12 @@ ...@@ -22,11 +22,12 @@
#include "nr_pdcp_entity.h" #include "nr_pdcp_entity.h"
#include "nr_pdcp_entity_drb_am.h" #include "nr_pdcp_entity_drb_am.h"
#include "nr_pdcp_security_nea2.h"
#include "LOG/log.h" #include "LOG/log.h"
nr_pdcp_entity_t *new_nr_pdcp_entity_srb( nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
int rb_id, int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size), char *buf, int size),
void *deliver_sdu_data, void *deliver_sdu_data,
...@@ -38,7 +39,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb( ...@@ -38,7 +39,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
} }
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
int rb_id, int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size), char *buf, int size),
void *deliver_sdu_data, void *deliver_sdu_data,
...@@ -47,7 +48,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ...@@ -47,7 +48,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_pdu_data, void *deliver_pdu_data,
int sn_size, int sn_size,
int t_reordering, int t_reordering,
int discard_timer) int discard_timer,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_drb_am_t *ret; nr_pdcp_entity_drb_am_t *ret;
...@@ -76,5 +81,25 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ...@@ -76,5 +81,25 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1; ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
if (ciphering_key != NULL && ciphering_algorithm != 0) {
if (ciphering_algorithm != 2) {
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
exit(1);
}
ret->common.has_ciphering = 1;
ret->common.ciphering_algorithm = ciphering_algorithm;
memcpy(ret->common.ciphering_key, ciphering_key, 16);
ret->common.security_context = nr_pdcp_security_nea2_init(ciphering_key);
ret->common.cipher = nr_pdcp_security_nea2_cipher;
ret->common.free_security = nr_pdcp_security_nea2_free_security;
}
ret->common.is_gnb = is_gnb;
if (integrity_key != NULL) {
printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return (nr_pdcp_entity_t *)ret; return (nr_pdcp_entity_t *)ret;
} }
...@@ -42,10 +42,28 @@ typedef struct nr_pdcp_entity_t { ...@@ -42,10 +42,28 @@ typedef struct nr_pdcp_entity_t {
int tx_hfn; int tx_hfn;
int next_nr_pdcp_tx_sn; int next_nr_pdcp_tx_sn;
int maximum_nr_pdcp_sn; int maximum_nr_pdcp_sn;
/* security */
int has_ciphering;
int has_integrity;
int ciphering_algorithm;
int integrity_algorithm;
unsigned char ciphering_key[16];
unsigned char integrity_key[16];
void *security_context;
void (*cipher)(void *security_context,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void (*free_security)(void *security_context);
/* security algorithms need to know uplink/downlink information
* which is reverse for gnb and ue, so we need to know if this
* pdcp entity is for a gnb or an ue
*/
int is_gnb;
} nr_pdcp_entity_t; } nr_pdcp_entity_t;
nr_pdcp_entity_t *new_nr_pdcp_entity_srb( nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
int rb_id, int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size), char *buf, int size),
void *deliver_sdu_data, void *deliver_sdu_data,
...@@ -54,7 +72,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb( ...@@ -54,7 +72,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
void *deliver_pdu_data); void *deliver_pdu_data);
nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
int rb_id, int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size), char *buf, int size),
void *deliver_sdu_data, void *deliver_sdu_data,
...@@ -63,7 +81,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ...@@ -63,7 +81,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_pdu_data, void *deliver_pdu_data,
int sn_size, int sn_size,
int t_reordering, int t_reordering,
int discard_timer); int discard_timer,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key);
void nr_DRB_preconfiguration(uint16_t crnti); void nr_DRB_preconfiguration(uint16_t crnti);
......
...@@ -29,12 +29,21 @@ ...@@ -29,12 +29,21 @@
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size) void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
{ {
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
int sn;
if (size < 3) abort(); if (size < 3) abort();
if (!(buffer[0] & 0x80)) if (!(buffer[0] & 0x80))
LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
sn = (((unsigned char)buffer[0] & 0x3) << 16) |
((unsigned char)buffer[1] << 8) |
(unsigned char)buffer[2];
if (entity->common.has_ciphering)
entity->common.cipher(entity->common.security_context, (unsigned char *)buffer+3, size-3,
entity->rb_id, sn, entity->common.is_gnb ? 0 : 1);
entity->common.deliver_sdu(entity->common.deliver_sdu_data, entity->common.deliver_sdu(entity->common.deliver_sdu_data,
(nr_pdcp_entity_t *)entity, buffer+3, size-3); (nr_pdcp_entity_t *)entity, buffer+3, size-3);
} }
...@@ -59,6 +68,10 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int ...@@ -59,6 +68,10 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int
buf[2] = sn & 0xff; buf[2] = sn & 0xff;
memcpy(buf+3, buffer, size); memcpy(buf+3, buffer, size);
if (entity->common.has_ciphering)
entity->common.cipher(entity->common.security_context, (unsigned char *)buf+3, size,
entity->rb_id, sn, entity->common.is_gnb ? 1 : 0);
entity->common.deliver_pdu(entity->common.deliver_pdu_data, entity->common.deliver_pdu(entity->common.deliver_pdu_data,
(nr_pdcp_entity_t *)entity, buf, size+3, sdu_id); (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
} }
...@@ -71,5 +84,7 @@ void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *ke ...@@ -71,5 +84,7 @@ void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *ke
void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity) void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
{ {
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
if (entity->common.free_security != NULL)
entity->common.free_security(entity->common.security_context);
free(entity); free(entity);
} }
...@@ -591,7 +591,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s) ...@@ -591,7 +591,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s)
TODO; TODO;
} }
static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
nr_pdcp_entity_t *pdcp_drb; nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue; nr_pdcp_ue_t *ue;
...@@ -621,8 +625,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) ...@@ -621,8 +625,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti); __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else { } else {
pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue, pdcp_drb = new_nr_pdcp_entity_drb_am(is_gnb, drb_id,
sn_size_dl, t_reordering, discard_timer); deliver_sdu_drb, ue, deliver_pdu_drb, ue,
sn_size_dl, t_reordering, discard_timer,
ciphering_algorithm, integrity_algorithm,
ciphering_key, integrity_key);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
...@@ -630,16 +637,23 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) ...@@ -630,16 +637,23 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager); nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
} }
static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config) static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
NR_RLC_Config_t *rlc_Config,
int ciphering_algorithm,
int integrity_algorithm,
unsigned char *ciphering_key,
unsigned char *integrity_key)
{ {
switch (rlc_Config->present) { switch (rlc_Config->present) {
case NR_RLC_Config_PR_am: case NR_RLC_Config_PR_am:
add_drb_am(rnti, s); add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm,
ciphering_key, integrity_key);
break; break;
case NR_RLC_Config_PR_um_Bi_Directional: case NR_RLC_Config_PR_um_Bi_Directional:
//add_drb_um(rnti, s); //add_drb_um(rnti, s);
/* hack */ /* hack */
add_drb_am(rnti, s); add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm,
ciphering_key, integrity_key);
break; break;
default: default:
LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
...@@ -657,7 +671,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -657,7 +671,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kRRCenc, uint8_t *const kRRCenc,
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc uint8_t *const kUPenc,
uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif #endif
...@@ -676,7 +691,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -676,7 +691,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
//srb2add_list == NULL || //srb2add_list == NULL ||
//drb2add_list != NULL || //drb2add_list != NULL ||
drb2release_list != NULL || drb2release_list != NULL ||
security_modeP != 255 || //security_modeP != 255 ||
//kRRCenc != NULL || //kRRCenc != NULL ||
//kRRCint != NULL || //kRRCint != NULL ||
//kUPenc != NULL || //kUPenc != NULL ||
...@@ -693,7 +708,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -693,7 +708,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
if (drb2add_list != NULL) { if (drb2add_list != NULL) {
for (i = 0; i < drb2add_list->list.count; i++) { for (i = 0; i < drb2add_list->list.count; i++) {
add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config); add_drb(ctxt_pP->enb_flag, rnti, drb2add_list->list.array[i],
rlc_bearer2add_list->list.array[i]->rlc_Config,
security_modeP & 0x0f, (security_modeP >> 4) & 0x0f,
kUPenc, kUPint);
} }
} }
...@@ -705,6 +723,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -705,6 +723,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
free(kRRCenc); free(kRRCenc);
free(kRRCint); free(kRRCint);
free(kUPenc); free(kUPenc);
free(kUPint);
return 0; return 0;
} }
...@@ -805,6 +824,7 @@ void nr_DRB_preconfiguration(uint16_t crnti) ...@@ -805,6 +824,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
Rlc_Bearer_ToAdd_list); Rlc_Bearer_ToAdd_list);
nr_rrc_rlc_config_asn1_req (&ctxt, nr_rrc_rlc_config_asn1_req (&ctxt,
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nr_pdcp_security_nea2.h"
#include <stdlib.h>
#include <string.h>
#include <nettle/nettle-meta.h>
#include <nettle/aes.h>
#include <nettle/ctr.h>
void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
{
void *ctx = calloc(1, nettle_aes128.context_size);
if (ctx == NULL) exit(1);
#if NETTLE_VERSION_MAJOR < 3
nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key);
#else
nettle_aes128.set_encrypt_key(ctx, ciphering_key);
#endif
return ctx;
}
void nr_pdcp_security_nea2_cipher(void *security_context,
unsigned char *buffer, int length,
int bearer, int count, int direction)
{
unsigned char t[16];
t[0] = (count >> 24) & 255;
t[1] = (count >> 16) & 255;
t[2] = (count >> 8) & 255;
t[3] = (count ) & 255;
t[4] = ((bearer-1) << 3) | (direction << 2);
memset(&t[5], 0, 16-5);
nettle_ctr_crypt(security_context, nettle_aes128.encrypt,
nettle_aes128.block_size, t,
length, buffer, buffer);
}
void nr_pdcp_security_nea2_free_security(void *security_context)
{
free(security_context);
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _NR_PDCP_SECURITY_NEA2_H_
#define _NR_PDCP_SECURITY_NEA2_H_
void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
void nr_pdcp_security_nea2_cipher(void *security_context,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void nr_pdcp_security_nea2_free_security(void *security_context);
#endif /* _NR_PDCP_SECURITY_NEA2_H_ */
...@@ -546,6 +546,13 @@ typedef struct rrc_gummei_s { ...@@ -546,6 +546,13 @@ typedef struct rrc_gummei_s {
uint16_t mme_group_id; uint16_t mme_group_id;
} rrc_gummei_t; } rrc_gummei_t;
typedef struct {
uint16_t ciphering_algorithms;
uint16_t integrity_algorithms;
uint16_t sk_counter;
uint8_t kgNB[32];
} lte_rrc_nr_security_t;
typedef struct eNB_RRC_UE_s { typedef struct eNB_RRC_UE_s {
uint8_t primaryCC_id; uint8_t primaryCC_id;
LTE_SCellToAddMod_r10_t sCell_config[2]; LTE_SCellToAddMod_r10_t sCell_config[2];
...@@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s { ...@@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s {
security_capabilities_t security_capabilities; security_capabilities_t security_capabilities;
/* security capabilities and settings for an UE in ENDC mode */
lte_rrc_nr_security_t nr_security;
int next_hop_chain_count; int next_hop_chain_count;
uint8_t next_security_key[SECURITY_KEY_LENGTH]; uint8_t next_security_key[SECURITY_KEY_LENGTH];
......
...@@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo( ...@@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo(
struct NR_RadioBearerConfig *rb_config = NULL; struct NR_RadioBearerConfig *rb_config = NULL;
asn_enc_rval_t enc_rval; asn_enc_rval_t enc_rval;
int RRC_OK = 1; int RRC_OK = 1;
int index = 0;
char temp_buff[ASN_MAX_ENCODE_SIZE]; char temp_buff[ASN_MAX_ENCODE_SIZE];
NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL; NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL;
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL;
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL;
int RAT_Container_count = 0; int RAT_Container_count = 0;
rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig));
AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config");
if(ue_context_pP->ue_context.DRB_configList->list.count != 0) {
rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList ));
AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist");
rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED;
rb_config->drb_ToAddModList->list.array
= calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *));
AssertFatal( rb_config->drb_ToAddModList->list.array != NULL,
"falied to allocate memory for list.array");
for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) {
rb_config->drb_ToAddModList->list.array[index]
= calloc(1,sizeof(struct NR_DRB_ToAddMod));
AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL,
"failed to allocate memory for drb_toaddmod");
rb_config->drb_ToAddModList->list.array[index]->drb_Identity
= ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity;
if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) {
rb_config->drb_ToAddModList->list.array[index]->cnAssociation
= calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation));
AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL,
"failed to allocate memory cnAssociation");
rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present
= NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity
= *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity);
}
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config));
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb));
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long));
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer
= *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer);
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long));
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL
= NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long));
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL
= NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present
= NR_PDCP_Config__drb__headerCompression_PR_notUsed;
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long));
*rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering
= NR_PDCP_Config__t_Reordering_ms0;
}
rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig ));
rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig));
rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
rb_config->securityConfig->keyToUse = calloc(1,sizeof(long));
*rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
}
cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo)); cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo));
AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo"); AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo");
...@@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo( ...@@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo(
(const char *)temp_buff, (enc_rval.encoded+7)>>3); (const char *)temp_buff, (enc_rval.encoded+7)>>3);
} }
cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config
= calloc(1,sizeof(OCTET_STRING_t));
AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->
mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config");
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,temp_buff,ASN_MAX_ENCODE_SIZE);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config,
(const char *)temp_buff, (enc_rval.encoded+7)>>3);
// this xer_fprint can be enabled for additional debugging messages // this xer_fprint can be enabled for additional debugging messages
// xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo); // xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo, enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo,
...@@ -4665,11 +4598,20 @@ rrc_eNB_process_MeasurementReport( ...@@ -4665,11 +4598,20 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ); msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ);
memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t)); memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t));
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms;
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32);
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size); memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size; X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId
= measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId; = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId;
//For the moment we have a single E-RAB which will be the one to be added to the gNB //For the moment we have a single E-RAB which will be the one to be added to the gNB
//Not sure how to select bearers to be added if there are multiple. //Not sure how to select bearers to be added if there are multiple.
X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1;
......
...@@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char ...@@ -1045,6 +1045,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
} }
} }
ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms;
ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms;
/* let's initialize sk_counter to 0 */
ue_context_p->ue_context.nr_security.sk_counter = 0;
/* let's compute kgNB */
derive_skgNB(ue_context_p->ue_context.kenb,
ue_context_p->ue_context.nr_security.sk_counter,
ue_context_p->ue_context.nr_security.kgNB);
// in case, send the S1SP initial context response if it is not sent with the attach complete message // in case, send the S1SP initial context response if it is not sent with the attach complete message
if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
......
...@@ -447,6 +447,15 @@ typedef struct { ...@@ -447,6 +447,15 @@ typedef struct {
//--------------------------------------------------- //---------------------------------------------------
typedef struct {
/* nea0 = 0, nea1 = 1, ... */
int ciphering_algorithms[4];
int ciphering_algorithms_count;
/* nia0 = 0, nia1 = 1, ... */
int integrity_algorithms[4];
int integrity_algorithms_count;
} nr_security_configuration_t;
//---NR---(completely change)--------------------- //---NR---(completely change)---------------------
typedef struct gNB_RRC_INST_s { typedef struct gNB_RRC_INST_s {
...@@ -479,6 +488,8 @@ typedef struct gNB_RRC_INST_s { ...@@ -479,6 +488,8 @@ typedef struct gNB_RRC_INST_s {
int srb1_timer_status_prohibit; int srb1_timer_status_prohibit;
int srs_enable[MAX_NUM_CCs]; int srs_enable[MAX_NUM_CCs];
// security configuration (preferred algorithms)
nr_security_configuration_t security;
} gNB_RRC_INST; } gNB_RRC_INST;
#include "nr_rrc_proto.h" //should be put here otherwise compilation error #include "nr_rrc_proto.h" //should be put here otherwise compilation error
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h" #include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h" #include "NR_CG-Config.h"
#include "NR_CG-ConfigInfo.h" #include "NR_CG-ConfigInfo.h"
#include "NR_SecurityConfig.h"
int rrc_init_nr_global_param(void); int rrc_init_nr_global_param(void);
...@@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon ...@@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
int n_physical_antenna_ports, int n_physical_antenna_ports,
int initial_csi_index); int initial_csi_index);
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig); void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
int eps_bearer_id, int rb_id,
e_NR_CipheringAlgorithm ciphering_algorithm,
e_NR_SecurityConfig__keyToUse key_to_use);
int generate_CG_Config(gNB_RRC_INST *rrc, int generate_CG_Config(gNB_RRC_INST *rrc,
NR_CG_Config_t *cg_Config, NR_CG_Config_t *cg_Config,
......
...@@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kRRCenc, uint8_t *const kRRCenc,
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc uint8_t *const kUPenc,
uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif #endif
...@@ -887,6 +888,7 @@ rrc_gNB_process_RRCReconfigurationComplete( ...@@ -887,6 +888,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
kUPenc, kUPenc,
NULL, NULL,
NULL, NULL,
NULL,
NULL); NULL);
/* Refresh SRBs/DRBs */ /* Refresh SRBs/DRBs */
nr_rrc_rlc_config_asn1_req(ctxt_pP, nr_rrc_rlc_config_asn1_req(ctxt_pP,
...@@ -1702,6 +1704,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, ...@@ -1702,6 +1704,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
// NULL, // NULL,
// NULL, // NULL,
// NULL, // NULL,
// NULL,
// NULL); // NULL);
// if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { // if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include <openair2/RRC/NR/rrc_gNB_UE_context.h> #include <openair2/RRC/NR/rrc_gNB_UE_context.h>
#include "UTIL/OSA/osa_defs.h"
extern boolean_t nr_rrc_pdcp_config_asn1_req( extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP, const protocol_ctxt_t *const ctxt_pP,
...@@ -48,7 +49,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -48,7 +49,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kRRCenc, uint8_t *const kRRCenc,
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc uint8_t *const kUPenc,
uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif #endif
...@@ -115,28 +117,14 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL ...@@ -115,28 +117,14 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
// dump ue_capabilities // dump ue_capabilities
if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) { if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr); xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
} }
if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) { if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
} }
if(cg_config_info && cg_config_info->mcg_RB_Config) {
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_RadioBearerConfig,
(void **)&ue_context_p->ue_context.rb_config,
cg_config_info->mcg_RB_Config->buf,
cg_config_info->mcg_RB_Config->size, 0, 0);
if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n",
dec_rval.consumed, cg_config_info->mcg_RB_Config->size);
}
}
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config);
rrc_add_nsa_user(rrc,ue_context_p, m); rrc_add_nsa_user(rrc,ue_context_p, m);
} }
...@@ -152,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ...@@ -152,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
protocol_ctxt_t ctxt={0}; protocol_ctxt_t ctxt={0};
unsigned char *kUPenc = NULL;
int i;
// NR RRCReconfiguration // NR RRCReconfiguration
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n"); AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t)); ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
...@@ -162,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ...@@ -162,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
carrier->initial_csi_index[rrc->Nb_ue] = 0; carrier->initial_csi_index[rrc->Nb_ue] = 0;
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); fill_default_rbconfig(ue_context_p->ue_context.rb_config,
fill_default_rbconfig(ue_context_p->ue_context.rb_config); 5 /* EPS bearer ID */,
1 /* drb ID */,
NR_CipheringAlgorithm_nea0,
NR_SecurityConfig__keyToUse_master);
} else {
/* TODO: handle more than one bearer */
if (m == NULL) {
LOG_E(RRC, "fatal: m==NULL\n");
exit(1);
}
if (m->nb_e_rabs_tobeadded != 1) {
LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded);
exit(1);
}
/* store security key and security capabilities */
memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
/* Select ciphering algorithm based on gNB configuration file and
* UE's supported algorithms.
* We take the first from the list that is supported by the UE.
* The ordering of the list comes from the configuration file.
*/
/* preset nea0 as fallback */
ue_context_p->ue_context.ciphering_algorithm = 0;
for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) {
int nea_mask[4] = {
0,
0x8000, /* nea1 */
0x4000, /* nea2 */
0x2000 /* nea3 */
};
if (rrc->security.ciphering_algorithms[i] == 0) {
/* nea0 already preselected */
break;
}
if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i];
break;
}
}
LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm);
/* integrity: no integrity protection for DRB in ENDC mode
* as written in 38.331: "If UE is connected to E-UTRA/EPC, this field
* indicates the integrity protection algorithm to be used for SRBs
* configured with NR PDCP, as specified in TS 33.501"
* So nothing for DRB. Plus a test with a COTS UE revealed that it
* did not apply integrity on the DRB.
*/
ue_context_p->ue_context.integrity_algorithm = 0;
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
/* derive UP security key */
unsigned char *kUPenc_kdf;
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
ue_context_p->ue_context.kgnb,
&kUPenc_kdf);
/* kUPenc: last 128 bits of key derivation function which returns 256 bits */
kUPenc = malloc(16);
if (kUPenc == NULL) exit(1);
memcpy(kUPenc, kUPenc_kdf+16, 16);
free(kUPenc_kdf);
e_NR_CipheringAlgorithm cipher_algo;
switch (ue_context_p->ue_context.ciphering_algorithm) {
case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break;
case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break;
case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break;
case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break;
default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1);
}
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
m->e_rabs_tobeadded[0].e_rab_id,
m->e_rabs_tobeadded[0].drb_ID,
cipher_algo,
NR_SecurityConfig__keyToUse_secondary);
} }
fill_default_reconfig(carrier->servingcellconfigcommon, fill_default_reconfig(carrier->servingcellconfigcommon,
reconfig_ies, reconfig_ies,
...@@ -285,10 +357,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ...@@ -285,10 +357,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
(NR_SRB_ToAddModList_t *) NULL, (NR_SRB_ToAddModList_t *) NULL,
ue_context_p->ue_context.rb_config->drb_ToAddModList , ue_context_p->ue_context.rb_config->drb_ToAddModList ,
ue_context_p->ue_context.rb_config->drb_ToReleaseList, ue_context_p->ue_context.rb_config->drb_ToReleaseList,
0xff, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
NULL, NULL, /* kRRCenc - unused */
NULL, NULL, /* kRRCint - unused */
NULL, kUPenc, /* kUPenc */
NULL, /* kUPint - unused */
NULL, NULL,
NULL, NULL,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
......
...@@ -1334,7 +1334,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon ...@@ -1334,7 +1334,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
reconfig->nonCriticalExtension = NULL; reconfig->nonCriticalExtension = NULL;
} }
void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
int eps_bearer_id, int rb_id,
e_NR_CipheringAlgorithm ciphering_algorithm,
e_NR_SecurityConfig__keyToUse key_to_use) {
rbconfig->srb_ToAddModList = NULL; rbconfig->srb_ToAddModList = NULL;
rbconfig->srb3_ToRelease = NULL; rbconfig->srb3_ToRelease = NULL;
...@@ -1342,8 +1345,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { ...@@ -1342,8 +1345,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id;
drb_ToAddMod->drb_Identity = 1; drb_ToAddMod->drb_Identity = rb_id;
drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL;
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
...@@ -1372,12 +1375,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { ...@@ -1372,12 +1375,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm;
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
*rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; *rbconfig->securityConfig->keyToUse = key_to_use;
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); // xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
} }
/* Function to set or overwrite PTRS DL RRC parameters */ /* Function to set or overwrite PTRS DL RRC parameters */
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset) void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset)
......
...@@ -186,7 +186,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( ...@@ -186,7 +186,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP, const uint8_t security_modeP,
uint8_t *const kRRCenc, uint8_t *const kRRCenc,
uint8_t *const kRRCint, uint8_t *const kRRCint,
uint8_t *const kUPenc uint8_t *const kUPenc,
uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif #endif
...@@ -1999,6 +2000,7 @@ nr_sa_rrc_ue_process_radioBearerConfig( ...@@ -1999,6 +2000,7 @@ nr_sa_rrc_ue_process_radioBearerConfig(
// NULL, // NULL,
// NULL, // NULL,
// NULL, // NULL,
// NULL,
// NULL); // NULL);
// Refresh SRBs // Refresh SRBs
// nr_rrc_rlc_config_asn1_req(ctxt_pP, // nr_rrc_rlc_config_asn1_req(ctxt_pP,
...@@ -2090,6 +2092,7 @@ nr_sa_rrc_ue_process_radioBearerConfig( ...@@ -2090,6 +2092,7 @@ nr_sa_rrc_ue_process_radioBearerConfig(
// NULL, // NULL,
// kUPenc, // kUPenc,
// NULL, // NULL,
// NULL,
// NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
// NULL); // NULL);
// Refresh DRBs // Refresh DRBs
......
...@@ -53,6 +53,8 @@ typedef enum { ...@@ -53,6 +53,8 @@ typedef enum {
//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); //int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB);
int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t key[32], uint8_t **out); const uint8_t key[32], uint8_t **out);
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
......
...@@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) ...@@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
return 0; return 0;
} }
*/ */
int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB)
{
uint8_t *out;
uint8_t s[5];
/* FC is 0x1c (see 3gpp 33.401 annex A.15) */
s[0] = 0x1c;
/* put sk_counter */
s[1] = (sk_counter >> 8) & 0xff;
s[2] = sk_counter & 0xff;
/* put length of sk_counter (2) */
s[3] = 0x00;
s[4] = 0x02;
kdf(s, 5, keNB, 32, &out, 32);
memcpy(skgNB, out, 32);
free(out);
return 0;
}
...@@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, ...@@ -864,22 +864,36 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
/* id-SecurityKey : Copy the security key */
} else {/* ie != NULL */ } else {/* ie != NULL */
return -1; return -1;
} }
/* id-SecurityKey : Copy the security key */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_SecurityKey, true); S1AP_ProtocolIE_ID_id_SecurityKey, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
} else {/* ie != NULL */ } else {/* ie != NULL */
return -1; return -1;
} }
/* id-NRUESecurityCapabilities */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
if (ie != NULL) {
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
} else {
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0;
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0;
}
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
return 0; return 0;
} }
......
...@@ -33,7 +33,7 @@ gNBs = ...@@ -33,7 +33,7 @@ gNBs =
# downlinkConfigCommon # downlinkConfigCommon
#frequencyInfoDL #frequencyInfoDL
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 642364; absoluteFrequencySSB = 642016;#642364;
dl_frequencyBand = 78; dl_frequencyBand = 78;
# this is 3600 MHz # this is 3600 MHz
dl_absoluteFrequencyPointA = 640000; dl_absoluteFrequencyPointA = 640000;
...@@ -130,16 +130,21 @@ gNBs = ...@@ -130,16 +130,21 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B # 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0, restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements) # pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2; initialULBWPk2_0 = 6; #2;
initialULBWPmappingType_0 = 1 initialULBWPmappingType_0 = 1
# this is SS=0 L=11 # this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55; initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2; initialULBWPk2_1 = 6; #2;
initialULBWPmappingType_1 = 1; initialULBWPmappingType_1 = 1;
# this is SS=0 L=12 # this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69; initialULBWPstartSymbolAndLength_1 = 69;
initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1; msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90; p0_NominalWithGrant =-90;
......
...@@ -130,16 +130,21 @@ gNBs = ...@@ -130,16 +130,21 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B # 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0, restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements) # pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2; initialULBWPk2_0 = 6;#2;
initialULBWPmappingType_0 = 1 initialULBWPmappingType_0 = 1
# this is SS=0 L=11 # this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55; initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2; initialULBWPk2_1 = 6;#2;
initialULBWPmappingType_1 = 1; initialULBWPmappingType_1 = 1;
# this is SS=0 L=12 # this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69; initialULBWPstartSymbolAndLength_1 = 69;
initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1; msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90; p0_NominalWithGrant =-90;
......
...@@ -278,6 +278,18 @@ THREAD_STRUCT = ( ...@@ -278,6 +278,18 @@ THREAD_STRUCT = (
} }
); );
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0", "nea2" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia0" );
};
log_config : log_config :
{ {
global_log_level ="info"; global_log_level ="info";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment