diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index e0556b92bfb92dd3ca6a399fef214ff80a7f5a3d..3fe10c92f826c8b81ad2b4f81d723d52e92b131a 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -117,6 +117,7 @@ typedef struct xer_sprint_string_s { } xer_sprint_string_t; extern unsigned char NB_eNB_INST; +extern uint8_t usim_test; uint16_t two_tier_hexagonal_cellIds[7] = {0,1,2,4,5,7,8}; uint16_t two_tier_hexagonal_adjacent_cellIds[7][6] = {{1,2,4,5,7,8}, // CellId 0 @@ -1268,7 +1269,10 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension)); - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity=2; + if(usim_test == 0) + rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 2; + else + rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME = NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME)); diff --git a/openair3/NAS/TOOLS/usim_data.c b/openair3/NAS/TOOLS/usim_data.c index 1835f0b8b127bbdcf7ab74f778fe52dfdefa5023..126ff4f78c9a9b9c07d3730bb70abf876b8931b7 100644 --- a/openair3/NAS/TOOLS/usim_data.c +++ b/openair3/NAS/TOOLS/usim_data.c @@ -227,6 +227,7 @@ int main (int argc, const char* argv[]) usim_data.imsi.u.num.digit13 = 3; usim_data.imsi.u.num.digit14 = 4; usim_data.imsi.u.num.digit15 = 0xF; + usim_data.usimtestmode = 1; // set usim in test mode in order to get the CMW500 K key #endif /* * Ciphering and Integrity Keys diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index b0ccbf9504ac1c96cfac14898f17c5b71c5d3791..df7d22db8edb31c60b13f9049672c7584a84c30b 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -79,6 +79,7 @@ Description Implements the API used by the NAS layer to read/write #define USIM_API_K_SIZE 16 //#define USIM_API_K_VALUE "fec86ba6eb707ed08905757b1bb44b8f" #define USIM_API_K_VALUE "8BAF473F2F8FD09487CCCBD7097C6862" +#define TEST_USIM_API_K_VALUE "000102030405060708090a0b0c0d0e0f" // CMW500 K key static uint8_t _usim_api_k[USIM_API_K_SIZE]; @@ -143,7 +144,14 @@ int usim_api_read(usim_data_t* data) } /* initialize the subscriber authentication security key */ - _usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); + if(data->usimtestmode == 0) + { + _usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); + } + else + { + _usim_api_hex_string_to_hex_value(_usim_api_k, TEST_USIM_API_K_VALUE, USIM_API_K_SIZE); + } free(path); LOG_FUNC_RETURN (RETURNok); @@ -188,6 +196,189 @@ int usim_api_write(const usim_data_t* data) LOG_FUNC_RETURN (RETURNok); } +/**************************************************************************** + ** ** + ** Name: usim_api_authenticate_test() ** + ** ** + ** Description: Performs mutual authentication of the USIM to the network,** + ** checking whether authentication token AUTN can be accep- ** + ** ted. If so, returns an authentication response RES and ** + ** the ciphering and integrity keys. ** + ** In case of synch failure, returns a re-synchronization ** + ** token AUTS. ** + ** ** + ** Key Generation for Test USIM based on 34.108 ** + ** ** + ** Authentication and key generating function algorithms are ** + ** specified in 3GPP TS 35.206. ** + ** ** + ** Inputs: rand_pP: Random challenge number ** + ** autn_pP: Authentication token ** + ** AUTN = (SQN xor AK) || AMF || MAC ** + ** 48 16 64 bits ** + ** Others: Security key ** + ** ** + ** Outputs: auts_pP: Re-synchronization token ** + ** res_pP: Authentication response ** + ** ck_pP: Ciphering key ** + ** ik_pP Integrity key ** + ** ** + ** Return: RETURNerror, RETURNok ** + ** Others: None ** + ** ** + ***************************************************************************/ +int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* autn_pP, + OctetString* auts_pP, OctetString* res_pP, + OctetString* ck_pP, OctetString* ik_pP) +{ + LOG_FUNC_IN; + + int rc; + int i; + + LOG_TRACE(INFO, "USIM-API - rand :%s",dump_octet_string(rand_pP)); + LOG_TRACE(INFO, "USIM-API - autn :%s",dump_octet_string(autn_pP)); + + //step1: XDOUT = RAND xor K + // RES = XDOUT + for (i=0; i<USIM_API_K_SIZE; i++) + { + res_pP->value[i] = rand_pP->value[i] ^ _usim_api_k[i]; + } + + //step2: res = f2(xdout,n) + // ck = f3(xdout) + // ik = f4(xdout) + // ak = f5(xdout) + u8 ak[USIM_API_AK_SIZE]; + for (i=0; i<15; i++) + { + ck_pP->value[i] = res_pP->value[i+1]; + } + ck_pP->value[15] = res_pP->value[0]; + + for (i=0; i<14; i++) + { + ik_pP->value[i] = res_pP->value[i+2]; + } + ik_pP->value[14] = res_pP->value[0]; + ik_pP->value[15] = res_pP->value[1]; + + for (i=0; i<USIM_API_AK_SIZE; i++) + { + ak[i] = res_pP->value[i+3]; + } + LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP)); + LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP)); + LOG_TRACE(INFO, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP)); + LOG_TRACE(INFO, "USIM-API - ak(f5) : %02X%02X%02X%02X%02X%02X", + ak[0],ak[1],ak[2],ak[3],ak[4],ak[5]); + + //step3: concatenate SQN with AMP SQN||AMF + // SQN = AUTN xor ak + u8 sqn[USIM_API_SQN_SIZE]; + for (i = 0; i < USIM_API_SQN_SIZE; i++) { + sqn[i] = autn_pP->value[i] ^ ak[i]; + } + LOG_TRACE(INFO, "USIM-API - Retrieved SQN %02X%02X%02X%02X%02X%02X", + sqn[0],sqn[1],sqn[2],sqn[3],sqn[4],sqn[5]); + LOG_TRACE(INFO, "USIM-API - Retrieved AMF %02X%02X", + autn_pP->value[USIM_API_SQN_SIZE],autn_pP->value[USIM_API_SQN_SIZE+1]); + +#define USIM_API_XMAC_SIZE 8 + u8 cdout[USIM_API_XMAC_SIZE]; + for (i = 0; i < USIM_API_XMAC_SIZE; i++) + { + if(i < USIM_API_SQN_SIZE) + { + cdout[i] = sqn[i]; + } + else + { + cdout[i] = autn_pP->value[i]; + } + } + LOG_TRACE(INFO, "USIM-API - Retrieved CDOUT %02X%02X%02X%02X%02X%02X%02X%02X", + cdout[0],cdout[1],cdout[2],cdout[3],cdout[4],cdout[5],cdout[6],cdout[7]); + + //step4:calculate XMAC from cdout and xdout + u8 xmac[USIM_API_XMAC_SIZE]; + for(i = 0; i < USIM_API_XMAC_SIZE; i++) + { + xmac[i] = res_pP->value[i] ^ cdout[i]; + } + LOG_TRACE(INFO, + "USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X", + xmac[0],xmac[1],xmac[2],xmac[3], + xmac[4],xmac[5],xmac[6],xmac[7]); + + /* Compare the XMAC with the MAC included in AUTN */ +#define USIM_API_AMF_SIZE 2 + + if ( memcmp(xmac, &autn_pP->value[USIM_API_SQN_SIZE + USIM_API_AMF_SIZE], + USIM_API_XMAC_SIZE) != 0 ) { + LOG_TRACE(INFO, + "USIM-API - Comparing the XMAC with the MAC included in AUTN Failed"); + rc = RETURNerror; + //LOG_FUNC_RETURN (RETURNerror); + } else { + LOG_TRACE(INFO, + "USIM-API - Comparing the XMAC with the MAC included in AUTN Succeeded"); + /* Verify that the received sequence number SQN is in the correct range */ + rc = _usim_api_check_sqn(*(uint32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]); + } + + + if (rc != RETURNok) { + /* Synchronisation failure; compute the AUTS parameter */ + + /* Concealed value of the counter SQNms in the USIM: + * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ + f5star(_usim_api_k, rand_pP->value, ak); + + + u8 sqn_ms[USIM_API_SQNMS_SIZE]; + memset(sqn_ms, 0, USIM_API_SQNMS_SIZE); + + //#define USIM_API_SQN_MS_SIZE 3 + printf("_usim_api_data.sqn_ms %p\n",_usim_api_data.sqn_ms); + for (i = 0; i < USIM_API_SQNMS_SIZE; i++) { + //#warning "LG:BUG HERE TODO" + printf("i %d: ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); + sqn_ms[USIM_API_SQNMS_SIZE - i] = + ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; + } + + u8 sqnms[USIM_API_SQNMS_SIZE]; + + for (i = 0; i < USIM_API_SQNMS_SIZE; i++) { + sqnms[i] = sqn_ms[i] ^ ak[i]; + } + + LOG_TRACE(DEBUG, "USIM-API - SQNms %02X%02X%02X%02X%02X%02X", + sqnms[0],sqnms[1],sqnms[2],sqnms[3],sqnms[4],sqnms[5]); + + /* Synchronisation message authentication code: + * MACS = f1*K(SQNMS || RAND || AMF) */ +#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE + u8 macs[USIM_API_MACS_SIZE]; + f1star(_usim_api_k, rand_pP->value, sqn_ms, + &rand_pP->value[USIM_API_SQN_SIZE], macs); + LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X", + macs[0],macs[1],macs[2],macs[3], + macs[4],macs[5],macs[6],macs[7]); + + /* Synchronisation authentication token: + * AUTS = Conc(SQNMS) || MACS */ + memcpy(&auts_pP->value[0], sqnms, USIM_API_SQNMS_SIZE); + memcpy(&auts_pP->value[USIM_API_SQNMS_SIZE], macs, USIM_API_MACS_SIZE); + auts_pP->length = USIM_API_SQNMS_SIZE + USIM_API_MACS_SIZE; + LOG_FUNC_RETURN (RETURNerror); + } + + LOG_FUNC_RETURN (RETURNok); +} + /**************************************************************************** ** ** ** Name: usim_api_authenticate() ** diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index f7e85f95e7b8df4e013967b3f3ddce0bc74c037d..fd4b3e33013029bd43cd0ed54e0f815eda3ad0f0 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -334,6 +334,8 @@ typedef struct { usim_epsloci_t epsloci; /* Non-Access Stratum configuration */ usim_nasconfig_t nasconfig; + /* usim test mode */ + uint8_t usimtestmode; } usim_data_t; /****************************************************************************/ @@ -351,5 +353,8 @@ int usim_api_write(const usim_data_t* data); int usim_api_authenticate(const OctetString* rand, const OctetString* autn, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); +int usim_api_authenticate_test(const OctetString* rand, const OctetString* autn, + OctetString* auts, OctetString* res, + OctetString* ck, OctetString* ik); #endif /* __USIM_API_H__*/ diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 6285534450091b69ac51617bac62f6fbaa78ebc8..96f28d7e86b3d9db9ace43273214728a7712bbda 100755 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -86,6 +86,8 @@ extern void *_emm_service_t3417_handler(void *); extern void *_emm_detach_t3421_handler(void *); extern void *_emm_tau_t3430_handler(void *); +extern uint8_t usim_test; + /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -240,7 +242,14 @@ int emm_proc_authentication_request(int native_ksi, int ksi, * of the core network by means of the received AUTN parameter and * request the USIM to compute RES, CK and IK for given RAND */ - rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik); + if(usim_test == 0) + { + rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik); + } + else + { + rc = usim_api_authenticate_test(rand, autn, &auts, &res, &ck, &ik); // XOR algo for autentication on usim test mode + } } if (rc != RETURNok) { diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index 25924fd9f27e5971fbf90a7d5be8e9b81e88a653..167c80ee513a37fd3eb58e9e94077f0bb1e306c3 100755 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -62,6 +62,7 @@ Description Implements the EPS Mobility Management procedures executed /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +extern uint8_t usim_test; /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ @@ -116,7 +117,14 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt) /* * Initiate the attach procedure for EPS services */ - rc = emm_proc_attach(EMM_ATTACH_TYPE_EPS); + if(usim_test == 0) + { + rc = emm_proc_attach(EMM_ATTACH_TYPE_EPS); + } + else + { + rc = emm_proc_attach(EMM_ATTACH_TYPE_IMSI); // CMW500 IMSI initial attach expected + } break; case _EMMREG_ATTACH_REQ: diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index dbeacaa149080fedad33093e9cc796bd72348605..3ec9aa5cac86f3bebb9009ad8528d4890849c5b3 100755 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -59,6 +59,7 @@ Description Defines the EPS Mobility Management procedure call manager, /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +extern uint8_t usim_test; /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ @@ -166,6 +167,7 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) /* * Get USIM application data */ + _usim_data.usimtestmode = usim_test; if ( usim_api_read(&_usim_data) != RETURNok ) { /* The USIM application may not be present or not valid */ LOG_TRACE(WARNING, "EMM-MAIN - Failed to read USIM application data"); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index d055eea3adbbfa6907b62af3e2ecdefdd6b223ec..ba4988cbfab3f50385f2a0ddfca83a1a41f83dca 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -212,6 +212,7 @@ char rf_config_file[1024]; int chain_offset=0; int phy_test = 0; +uint8_t usim_test = 0; char ref[128] = "internal"; @@ -387,6 +388,7 @@ void help (void) { printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n"); printf(" --mmapped-dma sets flag for improved EXMIMO UE performance\n"); printf(" --single-thread runs lte-softmodem in only one thread\n"); + printf(" --usim-test use XOR autentication algo in case of test usim mode\n"); printf(" -C Set the downlink frequency for all component carriers\n"); printf(" -d Enable soft scope and L1 and L2 stats (Xforms)\n"); printf(" -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"); @@ -693,6 +695,7 @@ static void get_options (int argc, char **argv) LONG_OPTION_DUMP_FRAME, LONG_OPTION_LOOPMEMORY, LONG_OPTION_PHYTEST, + LONG_OPTION_USIMTEST, LONG_OPTION_MMAPPED_DMA, LONG_OPTION_SINGLE_THREAD, #if T_TRACER @@ -719,6 +722,7 @@ static void get_options (int argc, char **argv) {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME}, {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY}, {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST}, + {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST}, {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA}, {"single-thread", no_argument, NULL, LONG_OPTION_SINGLE_THREAD}, #if T_TRACER @@ -818,6 +822,9 @@ static void get_options (int argc, char **argv) phy_test = 1; break; + case LONG_OPTION_USIMTEST: + usim_test = 1; + break; case LONG_OPTION_MMAPPED_DMA: mmapped_dma = 1; break;