mirror of https://github.com/PentHertz/srsLTE.git
adding hard SIM card support using PCSC
This commit is contained in:
parent
cc866b6de1
commit
3fe6dad323
|
@ -131,6 +131,16 @@ else(POLARSSL_FOUND)
|
|||
endif (MBEDTLS_FOUND)
|
||||
endif(POLARSSL_FOUND)
|
||||
|
||||
# Hard-SIM support
|
||||
find_package(PCSCLite)
|
||||
if (PCSCLITE_FOUND)
|
||||
message(STATUS "Building with PCSC support.")
|
||||
add_definitions(-DHAVE_PCSC)
|
||||
set(HAVE_PCSC TRUE)
|
||||
include_directories(${PCSCLITE_INCLUDE_DIR})
|
||||
#link_directories(${PCSCLITE_LIBRARIES})
|
||||
endif (PCSCLITE_FOUND)
|
||||
|
||||
# UHD
|
||||
find_package(UHD)
|
||||
if(UHD_FOUND)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# - Find PCSC-Lite
|
||||
# Find the native PCSC-Lite includes and library
|
||||
#
|
||||
# PCSCLITE_INCLUDE_DIR - where to find winscard.h, wintypes.h, etc.
|
||||
# PCSCLITE_LIBRARIES - List of libraries when using PCSC-Lite.
|
||||
# PCSCLITE_FOUND - True if PCSC-Lite found.
|
||||
|
||||
FIND_PACKAGE(PkgConfig)
|
||||
PKG_CHECK_MODULES(PC_PCSCLITE libpcsclite)
|
||||
|
||||
IF(NOT PCSCLITE_FOUND)
|
||||
|
||||
FIND_PATH(PCSCLITE_INCLUDE_DIR winscard.h
|
||||
HINTS
|
||||
/usr/include/PCSC
|
||||
${PC_PCSCLITE_INCLUDEDIR}
|
||||
${PC_PCSCLITE_INCLUDE_DIRS}
|
||||
${PC_PCSCLITE_INCLUDE_DIRS}/PCSC
|
||||
)
|
||||
|
||||
FIND_LIBRARY(PCSCLITE_LIBRARY NAMES pcsclite libpcsclite PCSC
|
||||
HINTS
|
||||
${PC_PCSCLITE_LIBDIR}
|
||||
${PC_PCSCLITE_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set PCSCLITE_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCSCLITE DEFAULT_MSG PCSCLITE_LIBRARY PCSCLITE_INCLUDE_DIR)
|
||||
|
||||
IF(PCSCLITE_FOUND)
|
||||
SET(PCSCLITE_LIBRARIES ${PCSCLITE_LIBRARY})
|
||||
ELSE(PCSCLITE_FOUND)
|
||||
SET(PCSCLITE_LIBRARIES )
|
||||
ENDIF(PCSCLITE_FOUND)
|
||||
|
||||
message(STATUS "PCSC LIBRARIES: " ${PCSCLITE_LIBRARY})
|
||||
message(STATUS "PCSC INCLUDE DIRS: " ${PCSCLITE_INCLUDE_DIR})
|
||||
|
||||
MARK_AS_ADVANCED( PCSCLITE_LIBRARY PCSCLITE_INCLUDE_DIR )
|
||||
ENDIF(NOT PCSCLITE_FOUND)
|
|
@ -43,6 +43,12 @@
|
|||
|
||||
namespace srsue {
|
||||
|
||||
typedef enum {
|
||||
AUTH_OK,
|
||||
AUTH_FAILED,
|
||||
AUTH_SYNCH_FAILURE
|
||||
} auth_result_t;
|
||||
|
||||
// UE interface
|
||||
class ue_interface
|
||||
{
|
||||
|
@ -57,12 +63,12 @@ public:
|
|||
virtual bool get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0;
|
||||
virtual bool get_imei_vec(uint8_t* imei_, uint32_t n) = 0;
|
||||
virtual bool get_home_plmn_id(LIBLTE_RRC_PLMN_IDENTITY_STRUCT *home_plmn_id) = 0;
|
||||
virtual void generate_authentication_response(uint8_t *rand,
|
||||
virtual auth_result_t generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme) = 0;
|
||||
virtual void generate_nas_keys(uint8_t *k_asme,
|
||||
uint8_t *k_nas_enc,
|
||||
|
|
|
@ -98,7 +98,7 @@ private:
|
|||
srsue::rrc rrc;
|
||||
srsue::nas nas;
|
||||
srsue::gw gw;
|
||||
srsue::usim usim;
|
||||
srsue::usim_base* usim;
|
||||
|
||||
srslte::logger_stdout logger_stdout;
|
||||
srslte::logger_file logger_file;
|
||||
|
|
|
@ -172,6 +172,8 @@ private:
|
|||
// Senders
|
||||
void send_identity_response();
|
||||
void send_esm_information_response();
|
||||
void send_authentication_response(const uint8_t* res, const size_t res_len);
|
||||
void send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param);
|
||||
void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg);
|
||||
void send_security_mode_reject(uint8_t cause);
|
||||
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSUE_PCSC_USIM_H
|
||||
#define SRSUE_PCSC_USIM_H
|
||||
|
||||
#include <string>
|
||||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/security.h"
|
||||
#include "srsue/hdr/upper/usim.h"
|
||||
#include <winscard.h>
|
||||
|
||||
namespace srsue {
|
||||
|
||||
#define AKA_RAND_LEN 16
|
||||
#define AKA_AUTN_LEN 16
|
||||
#define AKA_AUTS_LEN 14
|
||||
#define RES_MAX_LEN 16
|
||||
#define MAC_LEN 8
|
||||
#define IK_LEN 16
|
||||
#define CK_LEN 16
|
||||
#define AK_LEN 6
|
||||
#define SQN_LEN 6
|
||||
|
||||
#define KEY_LEN 32
|
||||
|
||||
typedef enum {
|
||||
SCARD_GSM_SIM,
|
||||
SCARD_USIM
|
||||
} sim_types_t;
|
||||
|
||||
static inline uint16_t to_uint16(const uint8_t *a)
|
||||
{
|
||||
return (a[0] << 8) | a[1];
|
||||
}
|
||||
|
||||
class pcsc_usim
|
||||
:public usim_base
|
||||
{
|
||||
public:
|
||||
pcsc_usim();
|
||||
~pcsc_usim();
|
||||
void init(usim_args_t *args, srslte::log *usim_log_);
|
||||
void stop();
|
||||
|
||||
// NAS interface
|
||||
std::string get_imsi_str();
|
||||
std::string get_imei_str();
|
||||
|
||||
bool get_imsi_vec(uint8_t* imsi_, uint32_t n);
|
||||
bool get_imei_vec(uint8_t* imei_, uint32_t n);
|
||||
bool get_home_plmn_id(LIBLTE_RRC_PLMN_IDENTITY_STRUCT *home_plmn_id);
|
||||
|
||||
auth_result_t generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme);
|
||||
|
||||
void generate_nas_keys(uint8_t *k_asme,
|
||||
uint8_t *k_nas_enc,
|
||||
uint8_t *k_nas_int,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo);
|
||||
|
||||
// RRC interface
|
||||
void generate_as_keys(uint8_t *k_asme,
|
||||
uint32_t count_ul,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
uint8_t *k_up_enc,
|
||||
uint8_t *k_up_int,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo);
|
||||
|
||||
void generate_as_keys_ho(uint32_t pci,
|
||||
uint32_t earfcn,
|
||||
int ncc,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
uint8_t *k_up_enc,
|
||||
uint8_t *k_up_int,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo);
|
||||
|
||||
|
||||
private:
|
||||
srslte::log *log;
|
||||
|
||||
// User data
|
||||
uint8_t amf[2]; // 3GPP 33.102 v10.0.0 Annex H
|
||||
uint8_t op[16];
|
||||
uint64_t imsi;
|
||||
uint64_t imei;
|
||||
uint8_t k[16];
|
||||
|
||||
std::string imsi_str;
|
||||
std::string imei_str;
|
||||
|
||||
uint32_t mnc_length;
|
||||
|
||||
// Security variables
|
||||
uint8_t rand[AKA_RAND_LEN];
|
||||
uint8_t ck[CK_LEN];
|
||||
uint8_t ik[IK_LEN];
|
||||
uint8_t ak[AK_LEN];
|
||||
uint8_t mac[MAC_LEN];
|
||||
uint8_t autn[AKA_AUTN_LEN];
|
||||
uint8_t k_asme[KEY_LEN];
|
||||
uint8_t nh[KEY_LEN];
|
||||
uint8_t k_enb[KEY_LEN];
|
||||
uint8_t k_enb_star[KEY_LEN];
|
||||
uint8_t auts[AKA_AUTS_LEN];
|
||||
|
||||
uint32_t current_ncc;
|
||||
|
||||
bool initiated;
|
||||
|
||||
// Smartcard sub-class which is a port of the PC/SC smartcard implementation
|
||||
// of WPA Supplicant written by Jouni Malinen <j@w1.fi> and licensed under BSD
|
||||
// Source: https://w1.fi/cvs.html
|
||||
class scard {
|
||||
public:
|
||||
scard() : log(NULL) {};
|
||||
~scard() {};
|
||||
|
||||
int init(usim_args_t *args, srslte::log *log_);
|
||||
void deinit();
|
||||
|
||||
int select_file(unsigned short file_id,unsigned char *buf, size_t *buf_len);
|
||||
int _select_file(unsigned short file_id, unsigned char *buf, size_t *buf_len, sim_types_t sim_type, unsigned char *aid, size_t aidlen);
|
||||
|
||||
long transmit(unsigned char *_send, size_t send_len, unsigned char *_recv, size_t *recv_len);
|
||||
|
||||
int get_aid(unsigned char *aid, size_t maxlen);
|
||||
int get_record_len(unsigned char recnum, unsigned char mode);
|
||||
int read_record(unsigned char *data, size_t len, unsigned char recnum, unsigned char mode);
|
||||
int get_imsi(char *imsi, size_t *len);
|
||||
int parse_fsp_templ(unsigned char *buf, size_t buf_len, int *ps_do, int *file_len);
|
||||
int read_file(unsigned char *data, size_t len);
|
||||
int get_mnc_len();
|
||||
int umts_auth(const unsigned char *_rand,
|
||||
const unsigned char *autn,
|
||||
unsigned char *res, int *res_len,
|
||||
unsigned char *ik, unsigned char *ck, unsigned char *auts);
|
||||
int pin_needed(unsigned char *hdr, size_t hlen);
|
||||
int verify_pin(const char *pin);
|
||||
int get_pin_retry_counter();
|
||||
|
||||
private:
|
||||
/* See ETSI GSM 11.11 and ETSI TS 102 221 for details.
|
||||
* SIM commands:
|
||||
* Command APDU: CLA INS P1 P2 P3 Data
|
||||
* CLA (class of instruction): A0 for GSM, 00 for USIM
|
||||
* INS (instruction)
|
||||
* P1 P2 P3 (parameters, P3 = length of Data)
|
||||
* Response APDU: Data SW1 SW2
|
||||
* SW1 SW2 (Status words)
|
||||
* Commands (INS P1 P2 P3):
|
||||
* SELECT: A4 00 00 02 <file_id, 2 bytes>
|
||||
* GET RESPONSE: C0 00 00 <len>
|
||||
* RUN GSM ALG: 88 00 00 00 <RAND len = 10>
|
||||
* RUN UMTS ALG: 88 00 81 <len=0x22> data: 0x10 | RAND | 0x10 | AUTN
|
||||
* P1 = ID of alg in card
|
||||
* P2 = ID of secret key
|
||||
* READ BINARY: B0 <offset high> <offset low> <len>
|
||||
* READ RECORD: B2 <record number> <mode> <len>
|
||||
* P2 (mode) = '02' (next record), '03' (previous record),
|
||||
* '04' (absolute mode)
|
||||
* VERIFY CHV: 20 00 <CHV number> 08
|
||||
* CHANGE CHV: 24 00 <CHV number> 10
|
||||
* DISABLE CHV: 26 00 01 08
|
||||
* ENABLE CHV: 28 00 01 08
|
||||
* UNBLOCK CHV: 2C 00 <00=CHV1, 02=CHV2> 10
|
||||
* SLEEP: FA 00 00 00
|
||||
*/
|
||||
|
||||
/* GSM SIM commands */
|
||||
#define SIM_CMD_SELECT 0xa0, 0xa4, 0x00, 0x00, 0x02
|
||||
#define SIM_CMD_RUN_GSM_ALG 0xa0, 0x88, 0x00, 0x00, 0x10
|
||||
#define SIM_CMD_GET_RESPONSE 0xa0, 0xc0, 0x00, 0x00
|
||||
#define SIM_CMD_READ_BIN 0xa0, 0xb0, 0x00, 0x00
|
||||
#define SIM_CMD_READ_RECORD 0xa0, 0xb2, 0x00, 0x00
|
||||
#define SIM_CMD_VERIFY_CHV1 0xa0, 0x20, 0x00, 0x01, 0x08
|
||||
|
||||
/* USIM commands */
|
||||
#define USIM_CLA 0x00
|
||||
#define USIM_CMD_RUN_UMTS_ALG 0x00, 0x88, 0x00, 0x81, 0x22
|
||||
#define USIM_CMD_GET_RESPONSE 0x00, 0xc0, 0x00, 0x00
|
||||
|
||||
#define SIM_RECORD_MODE_ABSOLUTE 0x04
|
||||
|
||||
#define USIM_FSP_TEMPL_TAG 0x62
|
||||
|
||||
#define USIM_TLV_FILE_DESC 0x82
|
||||
#define USIM_TLV_FILE_ID 0x83
|
||||
#define USIM_TLV_DF_NAME 0x84
|
||||
#define USIM_TLV_PROPR_INFO 0xA5
|
||||
#define USIM_TLV_LIFE_CYCLE_STATUS 0x8A
|
||||
#define USIM_TLV_FILE_SIZE 0x80
|
||||
#define USIM_TLV_TOTAL_FILE_SIZE 0x81
|
||||
#define USIM_TLV_PIN_STATUS_TEMPLATE 0xC6
|
||||
#define USIM_TLV_SHORT_FILE_ID 0x88
|
||||
#define USIM_TLV_SECURITY_ATTR_8B 0x8B
|
||||
#define USIM_TLV_SECURITY_ATTR_8C 0x8C
|
||||
#define USIM_TLV_SECURITY_ATTR_AB 0xAB
|
||||
|
||||
#define USIM_PS_DO_TAG 0x90
|
||||
|
||||
/* GSM files
|
||||
* File type in first octet:
|
||||
* 3F = Master File
|
||||
* 7F = Dedicated File
|
||||
* 2F = Elementary File under the Master File
|
||||
* 6F = Elementary File under a Dedicated File
|
||||
*/
|
||||
#define SCARD_FILE_MF 0x3F00
|
||||
#define SCARD_FILE_GSM_DF 0x7F20
|
||||
#define SCARD_FILE_UMTS_DF 0x7F50
|
||||
#define SCARD_FILE_GSM_EF_IMSI 0x6F07
|
||||
#define SCARD_FILE_GSM_EF_AD 0x6FAD
|
||||
#define SCARD_FILE_EF_DIR 0x2F00
|
||||
#define SCARD_FILE_EF_ICCID 0x2FE2
|
||||
#define SCARD_FILE_EF_CK 0x6FE1
|
||||
#define SCARD_FILE_EF_IK 0x6FE2
|
||||
|
||||
#define SCARD_CHV1_OFFSET 13
|
||||
#define SCARD_CHV1_FLAG 0x80
|
||||
|
||||
SCARDCONTEXT scard_context;
|
||||
SCARDHANDLE scard_handle;
|
||||
long unsigned scard_protocol;
|
||||
sim_types_t sim_type;
|
||||
bool pin1_needed;
|
||||
srslte::log *log;
|
||||
};
|
||||
|
||||
scard sc;
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
||||
#endif // SRSUE_PCSC_USIM_H
|
|
@ -28,6 +28,7 @@
|
|||
#define SRSUE_USIM_H
|
||||
|
||||
#include <string>
|
||||
#include "usim_base.h"
|
||||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
|
@ -35,22 +36,8 @@
|
|||
|
||||
namespace srsue {
|
||||
|
||||
typedef enum{
|
||||
auth_algo_milenage = 0,
|
||||
auth_algo_xor,
|
||||
}auth_algo_t;
|
||||
|
||||
typedef struct{
|
||||
std::string algo;
|
||||
std::string op;
|
||||
std::string imsi;
|
||||
std::string imei;
|
||||
std::string k;
|
||||
}usim_args_t;
|
||||
|
||||
class usim
|
||||
:public usim_interface_nas
|
||||
,public usim_interface_rrc
|
||||
:public usim_base
|
||||
{
|
||||
public:
|
||||
usim();
|
||||
|
@ -65,13 +52,13 @@ public:
|
|||
bool get_imei_vec(uint8_t* imei_, uint32_t n);
|
||||
bool get_home_plmn_id(LIBLTE_RRC_PLMN_IDENTITY_STRUCT *home_plmn_id);
|
||||
|
||||
void generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
uint8_t *k_asme);
|
||||
auth_result_t generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme);
|
||||
|
||||
void generate_nas_keys(uint8_t *k_asme,
|
||||
uint8_t *k_nas_enc,
|
||||
|
@ -101,20 +88,20 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
void gen_auth_res_milenage( uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
uint8_t *k_asme);
|
||||
void gen_auth_res_xor( uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
uint8_t *k_asme);
|
||||
auth_result_t gen_auth_res_milenage(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme);
|
||||
auth_result_t gen_auth_res_xor(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme);
|
||||
void str_to_hex(std::string str, uint8_t *hex);
|
||||
|
||||
srslte::log *usim_log;
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSUE_USIM_BASE_H
|
||||
#define SRSUE_USIM_BASE_H
|
||||
|
||||
#include <string>
|
||||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/common.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srslte/common/security.h"
|
||||
|
||||
namespace srsue {
|
||||
|
||||
typedef enum{
|
||||
auth_algo_milenage = 0,
|
||||
auth_algo_xor,
|
||||
}auth_algo_t;
|
||||
|
||||
typedef struct{
|
||||
std::string mode;
|
||||
std::string algo;
|
||||
std::string op;
|
||||
std::string imsi;
|
||||
std::string imei;
|
||||
std::string k;
|
||||
std::string pin;
|
||||
}usim_args_t;
|
||||
|
||||
class usim_base
|
||||
:public usim_interface_nas
|
||||
,public usim_interface_rrc
|
||||
{
|
||||
public:
|
||||
usim_base();
|
||||
virtual ~usim_base();
|
||||
static usim_base* get_instance(usim_args_t *args, srslte::log *usim_log_);
|
||||
|
||||
virtual void init(usim_args_t *args, srslte::log *usim_log_) = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
// NAS interface
|
||||
virtual std::string get_imsi_str() = 0;
|
||||
virtual std::string get_imei_str() = 0;
|
||||
|
||||
virtual bool get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0;
|
||||
virtual bool get_imei_vec(uint8_t* imei_, uint32_t n) = 0;
|
||||
virtual bool get_home_plmn_id(LIBLTE_RRC_PLMN_IDENTITY_STRUCT *home_plmn_id) = 0;
|
||||
|
||||
virtual auth_result_t generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme) = 0;
|
||||
|
||||
virtual void generate_nas_keys(uint8_t *k_asme,
|
||||
uint8_t *k_nas_enc,
|
||||
uint8_t *k_nas_int,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
|
||||
|
||||
// RRC interface
|
||||
virtual void generate_as_keys(uint8_t *k_asme,
|
||||
uint32_t count_ul,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
uint8_t *k_up_enc,
|
||||
uint8_t *k_up_int,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
|
||||
|
||||
virtual void generate_as_keys_ho(uint32_t pci,
|
||||
uint32_t earfcn,
|
||||
int ncc,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
uint8_t *k_up_enc,
|
||||
uint8_t *k_up_int,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
|
||||
};
|
||||
|
||||
} // namespace srsue
|
||||
|
||||
#endif // SRSUE_USIM_BASE_H
|
|
@ -124,12 +124,13 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
|
|||
("log.filename", bpo::value<string>(&args->log.filename)->default_value("/tmp/ue.log"), "Log filename")
|
||||
("log.file_max_size", bpo::value<int>(&args->log.file_max_size)->default_value(-1), "Maximum file size (in kilobytes). When passed, multiple files are created. Default -1 (single file)")
|
||||
|
||||
("usim.mode", bpo::value<string>(&args->usim.mode)->default_value("soft"), "USIM mode (soft or pcsc)")
|
||||
("usim.algo", bpo::value<string>(&args->usim.algo), "USIM authentication algorithm")
|
||||
("usim.op", bpo::value<string>(&args->usim.op), "USIM operator variant")
|
||||
("usim.imsi", bpo::value<string>(&args->usim.imsi), "USIM IMSI")
|
||||
("usim.imei", bpo::value<string>(&args->usim.imei), "USIM IMEI")
|
||||
("usim.k", bpo::value<string>(&args->usim.k), "USIM K")
|
||||
|
||||
("usim.pin", bpo::value<string>(&args->usim.pin), "PIN in case real SIM card is used")
|
||||
|
||||
/* Expert section */
|
||||
("expert.ip_netmask",
|
||||
|
|
|
@ -47,11 +47,13 @@ ue::~ue()
|
|||
for (uint32_t i = 0; i < phy_log.size(); i++) {
|
||||
delete(phy_log[i]);
|
||||
}
|
||||
if (usim) {
|
||||
delete usim;
|
||||
}
|
||||
}
|
||||
|
||||
bool ue::init(all_args_t *args_)
|
||||
{
|
||||
args = args_;
|
||||
bool ue::init(all_args_t *args_) {
|
||||
args = args_;
|
||||
|
||||
if (!args->log.filename.compare("stdout")) {
|
||||
logger = &logger_stdout;
|
||||
|
@ -195,15 +197,15 @@ bool ue::init(all_args_t *args_)
|
|||
mac.init(&phy, &rlc, &rrc, &mac_log);
|
||||
rlc.init(&pdcp, &rrc, this, &rlc_log, &mac, 0 /* RB_ID_SRB0 */);
|
||||
pdcp.init(&rlc, &rrc, &gw, &pdcp_log, 0 /* RB_ID_SRB0 */, SECURITY_DIRECTION_UPLINK);
|
||||
|
||||
usim.init(&args->usim, &usim_log);
|
||||
usim = usim_base::get_instance(&args->usim, &usim_log);
|
||||
usim->init(&args->usim, &usim_log);
|
||||
srslte_nas_config_t nas_cfg(1, args->apn); /* RB_ID_SRB1 */
|
||||
nas.init(&usim, &rrc, &gw, &nas_log, nas_cfg);
|
||||
nas.init(usim, &rrc, &gw, &nas_log, nas_cfg);
|
||||
gw.init(&pdcp, &nas, &gw_log, 3 /* RB_ID_DRB1 */);
|
||||
|
||||
gw.set_netmask(args->expert.ip_netmask);
|
||||
|
||||
rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log);
|
||||
rrc.init(&phy, &mac, &rlc, &pdcp, &nas, usim, &mac, &rrc_log);
|
||||
|
||||
// Get current band from provided EARFCN
|
||||
args->rrc.supported_bands[0] = srslte_band_get_band(args->rf.dl_earfcn);
|
||||
|
@ -244,7 +246,7 @@ void ue::stop()
|
|||
{
|
||||
if(started)
|
||||
{
|
||||
usim.stop();
|
||||
usim->stop();
|
||||
nas.stop();
|
||||
rrc.stop();
|
||||
|
||||
|
|
|
@ -18,6 +18,16 @@
|
|||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
file(GLOB SOURCES "*.cc")
|
||||
set(SOURCES gw.cc nas.cc rrc.cc usim_base.cc usim.cc)
|
||||
|
||||
if(HAVE_PCSC)
|
||||
list(APPEND SOURCES "pcsc_usim.cc")
|
||||
endif(HAVE_PCSC)
|
||||
|
||||
add_library(srsue_upper STATIC ${SOURCES})
|
||||
install(TARGETS srsue_upper DESTINATION ${LIBRARY_DIR})
|
||||
|
||||
if(HAVE_PCSC)
|
||||
target_link_libraries(srsue_upper ${PCSCLITE_LIBRARY})
|
||||
endif(HAVE_PCSC)
|
||||
|
||||
install(TARGETS srsue_upper DESTINATION ${LIBRARY_DIR})
|
|
@ -695,14 +695,12 @@ void nas::parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu) {
|
|||
void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) {
|
||||
LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req;
|
||||
bzero(&auth_req, sizeof(LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT));
|
||||
LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_res;
|
||||
bzero(&auth_res, sizeof(LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT));
|
||||
|
||||
nas_log->info("Received Authentication Request\n");
|
||||
liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT *) pdu, &auth_req);
|
||||
|
||||
// Reuse the pdu for the response message
|
||||
pdu->reset();
|
||||
// Deallocate PDU after parsing
|
||||
pool->deallocate(pdu);
|
||||
|
||||
// Generate authentication response using RAND, AUTN & KSI-ASME
|
||||
uint16 mcc, mnc;
|
||||
|
@ -711,11 +709,12 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) {
|
|||
|
||||
nas_log->info("MCC=%d, MNC=%d\n", mcc, mnc);
|
||||
|
||||
bool net_valid;
|
||||
uint8_t res[16];
|
||||
usim->generate_authentication_response(auth_req.rand, auth_req.autn, mcc, mnc,
|
||||
&net_valid, res, ctxt.k_asme);
|
||||
nas_log->info("Generated k_asme=%s\n", hex_to_string(ctxt.k_asme, 32).c_str());
|
||||
int res_len = 0;
|
||||
nas_log->debug_hex(auth_req.rand, 16, "Authentication request RAND\n");
|
||||
nas_log->debug_hex(auth_req.autn, 16, "Authentication request AUTN\n");
|
||||
auth_result_t auth_result = usim->generate_authentication_response(auth_req.rand, auth_req.autn, mcc, mnc,
|
||||
res, &res_len, ctxt.k_asme);
|
||||
if(LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE == auth_req.nas_ksi.tsc_flag) {
|
||||
ctxt.ksi = auth_req.nas_ksi.nas_ksi;
|
||||
} else {
|
||||
|
@ -723,23 +722,17 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) {
|
|||
nas_log->console("Warning: NAS mapped security context not currently supported\n");
|
||||
}
|
||||
|
||||
if (net_valid) {
|
||||
if (auth_result == AUTH_OK) {
|
||||
nas_log->info("Network authentication successful\n");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
auth_res.res[i] = res[i];
|
||||
}
|
||||
liblte_mme_pack_authentication_response_msg(&auth_res, (LIBLTE_BYTE_MSG_STRUCT *) pdu);
|
||||
|
||||
nas_log->info("Sending Authentication Response\n");
|
||||
// Write NAS pcap
|
||||
if (pcap != NULL) {
|
||||
pcap->write_nas(pdu->msg, pdu->N_bytes);
|
||||
}
|
||||
rrc->write_sdu(lcid, pdu);
|
||||
send_authentication_response(res, res_len);
|
||||
nas_log->info("Generated k_asme=%s\n", hex_to_string(ctxt.k_asme, 32).c_str());
|
||||
} else if (auth_result == AUTH_SYNCH_FAILURE) {
|
||||
nas_log->error("Network authentication synchronization failure.\n");
|
||||
send_authentication_failure(LIBLTE_MME_EMM_CAUSE_SYNCH_FAILURE, res);
|
||||
} else {
|
||||
nas_log->warning("Network authentication failure\n");
|
||||
nas_log->console("Warning: Network authentication failure\n");
|
||||
pool->deallocate(pdu);
|
||||
send_authentication_failure(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1058,13 @@ void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) {
|
|||
strncpy(apn.apn, cfg.apn.c_str(), LIBLTE_STRING_LEN);
|
||||
pdn_con_req.apn = apn;
|
||||
}
|
||||
pdn_con_req.protocol_cnfg_opts_present = false;
|
||||
|
||||
// Request DNS Server
|
||||
pdn_con_req.protocol_cnfg_opts_present = true;
|
||||
pdn_con_req.protocol_cnfg_opts.opt[0].id = LIBLTE_MME_ADDITIONAL_PARAMETERS_UL_P_CSCF_IPV4_ADDRESS_REQUEST;
|
||||
pdn_con_req.protocol_cnfg_opts.opt[1].id = LIBLTE_MME_ADDITIONAL_PARAMETERS_UL_DNS_SERVER_IPV4_ADDRESS_REQUEST;
|
||||
pdn_con_req.protocol_cnfg_opts.N_opts = 2;
|
||||
|
||||
pdn_con_req.device_properties_present = false;
|
||||
|
||||
// Pack the message
|
||||
|
@ -1089,6 +1088,57 @@ void nas::send_security_mode_reject(uint8_t cause) {
|
|||
rrc->write_sdu(cfg.lcid, msg);
|
||||
}
|
||||
|
||||
|
||||
void nas::send_authentication_response(const uint8_t* res, const size_t res_len) {
|
||||
byte_buffer_t *msg = pool_allocate;
|
||||
if (!msg) {
|
||||
nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_res;
|
||||
bzero(&auth_res, sizeof(LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT));
|
||||
|
||||
for (uint32_t i = 0; i < res_len; i++) {
|
||||
auth_res.res[i] = res[i];
|
||||
}
|
||||
auth_res.res_len = res_len;
|
||||
liblte_mme_pack_authentication_response_msg(&auth_res, (LIBLTE_BYTE_MSG_STRUCT *)msg);
|
||||
|
||||
if(pcap != NULL) {
|
||||
pcap->write_nas(msg->msg, msg->N_bytes);
|
||||
}
|
||||
nas_log->info("Sending Authentication Response\n");
|
||||
rrc->write_sdu(cfg.lcid, msg);
|
||||
}
|
||||
|
||||
|
||||
void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param) {
|
||||
byte_buffer_t *msg = pool_allocate;
|
||||
if (!msg) {
|
||||
nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_failure().\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_failure;
|
||||
auth_failure.emm_cause = cause;
|
||||
if (auth_fail_param) {
|
||||
memcpy(auth_failure.auth_fail_param, auth_fail_param, 14);
|
||||
nas_log->debug_hex(auth_failure.auth_fail_param, 14, "auth_failure.auth_fail_param\n");
|
||||
auth_failure.auth_fail_param_present = true;
|
||||
} else {
|
||||
auth_failure.auth_fail_param_present = false;
|
||||
}
|
||||
|
||||
liblte_mme_pack_authentication_failure_msg(&auth_failure, (LIBLTE_BYTE_MSG_STRUCT *)msg);
|
||||
if(pcap != NULL) {
|
||||
pcap->write_nas(msg->msg, msg->N_bytes);
|
||||
}
|
||||
nas_log->info("Sending authentication failure.\n");
|
||||
rrc->write_sdu(cfg.lcid, msg);
|
||||
}
|
||||
|
||||
|
||||
void nas::send_identity_response() {}
|
||||
|
||||
void nas::send_esm_information_response() {}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -189,18 +189,18 @@ bool usim::get_home_plmn_id(LIBLTE_RRC_PLMN_IDENTITY_STRUCT *home_plmn_id)
|
|||
return true;
|
||||
}
|
||||
|
||||
void usim::generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
uint8_t *k_asme)
|
||||
auth_result_t usim::generate_authentication_response(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme)
|
||||
{
|
||||
if(auth_algo_xor == auth_algo) {
|
||||
gen_auth_res_xor(rand, autn_enb, mcc, mnc, net_valid, res, k_asme);
|
||||
return gen_auth_res_xor(rand, autn_enb, mcc, mnc, res, res_len, k_asme);
|
||||
} else {
|
||||
gen_auth_res_milenage(rand, autn_enb, mcc, mnc, net_valid, res, k_asme);
|
||||
return gen_auth_res_milenage(rand, autn_enb, mcc, mnc, res, res_len, k_asme);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,19 +322,18 @@ void usim::generate_as_keys_ho(uint32_t pci,
|
|||
Helpers
|
||||
*******************************************************************************/
|
||||
|
||||
void usim::gen_auth_res_milenage( uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
uint8_t *k_asme)
|
||||
auth_result_t usim::gen_auth_res_milenage(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme)
|
||||
{
|
||||
auth_result_t result = AUTH_OK;
|
||||
uint32_t i;
|
||||
uint8_t sqn[6];
|
||||
|
||||
*net_valid = true;
|
||||
|
||||
// Use RAND and K to compute RES, CK, IK and AK
|
||||
security_milenage_f2345( k,
|
||||
op,
|
||||
|
@ -344,6 +343,8 @@ void usim::gen_auth_res_milenage( uint8_t *rand,
|
|||
ik,
|
||||
ak);
|
||||
|
||||
*res_len = 8;
|
||||
|
||||
// Extract sqn from autn
|
||||
for(i=0;i<6;i++)
|
||||
{
|
||||
|
@ -382,7 +383,7 @@ void usim::gen_auth_res_milenage( uint8_t *rand,
|
|||
{
|
||||
if(autn[i] != autn_enb[i])
|
||||
{
|
||||
*net_valid = false;
|
||||
result = AUTH_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,24 +395,25 @@ void usim::gen_auth_res_milenage( uint8_t *rand,
|
|||
mcc,
|
||||
mnc,
|
||||
k_asme);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3GPP TS 34.108 version 10.0.0 Section 8
|
||||
void usim::gen_auth_res_xor(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
bool *net_valid,
|
||||
uint8_t *res,
|
||||
uint8_t *k_asme)
|
||||
auth_result_t usim::gen_auth_res_xor(uint8_t *rand,
|
||||
uint8_t *autn_enb,
|
||||
uint16_t mcc,
|
||||
uint16_t mnc,
|
||||
uint8_t *res,
|
||||
int *res_len,
|
||||
uint8_t *k_asme)
|
||||
{
|
||||
auth_result_t result = AUTH_OK;
|
||||
uint32_t i;
|
||||
uint8_t sqn[6];
|
||||
uint8_t xdout[16];
|
||||
uint8_t cdout[8];
|
||||
|
||||
*net_valid = true;
|
||||
|
||||
// Use RAND and K to compute RES, CK, IK and AK
|
||||
for(i=0; i<16; i++) {
|
||||
xdout[i] = k[i]^rand[i];
|
||||
|
@ -425,6 +427,8 @@ void usim::gen_auth_res_xor(uint8_t *rand,
|
|||
ak[i] = xdout[i+3];
|
||||
}
|
||||
|
||||
*res_len = 8;
|
||||
|
||||
// Extract sqn from autn
|
||||
for(i=0;i<6;i++) {
|
||||
sqn[i] = autn_enb[i] ^ ak[i];
|
||||
|
@ -466,7 +470,7 @@ void usim::gen_auth_res_xor(uint8_t *rand,
|
|||
{
|
||||
if(autn[i] != autn_enb[i])
|
||||
{
|
||||
*net_valid = false;
|
||||
result = AUTH_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,6 +482,8 @@ void usim::gen_auth_res_xor(uint8_t *rand,
|
|||
mcc,
|
||||
mnc,
|
||||
k_asme);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void usim::str_to_hex(std::string str, uint8_t *hex)
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <srsue/hdr/upper/usim_base.h>
|
||||
#include <srsue/hdr/upper/usim.h>
|
||||
#ifdef HAVE_PCSC
|
||||
#include <srsue/hdr/upper/pcsc_usim.h>
|
||||
#endif
|
||||
|
||||
namespace srsue{
|
||||
|
||||
usim_base* usim_base::get_instance(usim_args_t *args, srslte::log *usim_log_)
|
||||
{
|
||||
usim_base* instance = NULL;
|
||||
if (args->mode == "soft") {
|
||||
instance = new usim();
|
||||
}
|
||||
#if HAVE_PCSC
|
||||
else if (args->mode == "pcsc") {
|
||||
instance = new pcsc_usim();
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
// default to soft USIM
|
||||
instance = new usim();
|
||||
}
|
||||
return(instance);
|
||||
}
|
||||
|
||||
usim_base::usim_base() {
|
||||
}
|
||||
|
||||
usim_base::~usim_base() {
|
||||
}
|
||||
|
||||
} // namespace srsue
|
|
@ -22,6 +22,11 @@ add_executable(usim_test usim_test.cc)
|
|||
target_link_libraries(usim_test srsue_upper srslte_upper srslte_phy)
|
||||
add_test(usim_test usim_test)
|
||||
|
||||
if(HAVE_PCSC)
|
||||
add_executable(pcsc_usim_test pcsc_usim_test.cc)
|
||||
target_link_libraries(pcsc_usim_test srsue_upper srslte_upper srslte_phy)
|
||||
endif(HAVE_PCSC)
|
||||
|
||||
add_executable(rrc_reconfig_test rrc_reconfig_test.cc)
|
||||
target_link_libraries(rrc_reconfig_test srsue_upper srslte_upper srslte_phy)
|
||||
add_test(rrc_reconfig_test rrc_reconfig_test)
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <srsue/hdr/upper/usim_base.h>
|
||||
#include "srsue/hdr/upper/usim.h"
|
||||
#include "srsue/hdr/upper/pcsc_usim.h"
|
||||
#include "srsue/hdr/upper/nas.h"
|
||||
#include "srslte/upper/rlc.h"
|
||||
#include "srsue/hdr/upper/rrc.h"
|
||||
|
@ -195,13 +197,16 @@ int mme_attach_request_test()
|
|||
|
||||
nas_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||
rrc_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||
usim_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||
nas_log.set_hex_limit(100000);
|
||||
rrc_log.set_hex_limit(100000);
|
||||
usim_log.set_hex_limit(100000);
|
||||
|
||||
rrc_dummy rrc_dummy;
|
||||
gw_dummy gw;
|
||||
srsue::usim usim;
|
||||
srsue::pcsc_usim usim;
|
||||
usim_args_t args;
|
||||
args.mode = "pcsc";
|
||||
args.algo = "xor";
|
||||
args.imei = "353490069873319";
|
||||
args.imsi = "001010123456789";
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2015 Software Radio Systems Limited
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsUE library.
|
||||
*
|
||||
* srsUE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsUE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Affero General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "srsue/hdr/upper/pcsc_usim.h"
|
||||
#include "srslte/common/log_filter.h"
|
||||
#include <assert.h>
|
||||
#include <srsue/hdr/upper/usim_base.h>
|
||||
|
||||
using namespace srsue;
|
||||
using namespace std;
|
||||
|
||||
|
||||
uint8_t rand_enb[] = {0xbc, 0x4c, 0xb0, 0x27, 0xb3, 0x4b, 0x7f, 0x51, 0x21, 0x5e, 0x56, 0x5f, 0x67, 0x3f, 0xde, 0x4f};
|
||||
uint8_t autn_enb[] = {0x5a, 0x17, 0x77, 0x3c, 0x62, 0x57, 0x90, 0x01, 0xcf, 0x47, 0xf7, 0x6d, 0xb3, 0xa0, 0x19, 0x46};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
srslte::log_filter usim_log("USIM");
|
||||
usim_log.set_level(srslte::LOG_LEVEL_DEBUG);
|
||||
usim_log.set_hex_limit(100000);
|
||||
uint8_t res[16];
|
||||
int res_len;
|
||||
uint8_t k_asme[32];
|
||||
uint16 mcc = 0;
|
||||
uint16 mnc = 0;
|
||||
|
||||
usim_args_t args;
|
||||
args.pin = "6129";
|
||||
args.imei = "353490069873319";
|
||||
|
||||
srsue::pcsc_usim usim;
|
||||
usim.init(&args, &usim_log);
|
||||
|
||||
std::string imsi = usim.get_imsi_str();
|
||||
cout << "IMSI: " << imsi << endl;
|
||||
auth_result_t result = usim.generate_authentication_response(rand_enb, autn_enb, mcc, mnc, res, &res_len, k_asme);
|
||||
}
|
|
@ -70,18 +70,18 @@ int main(int argc, char **argv)
|
|||
srslte::log_filter usim_log("USIM");
|
||||
bool net_valid;
|
||||
uint8_t res[16];
|
||||
int res_len;
|
||||
uint8_t k_asme[32];
|
||||
|
||||
usim_args_t args;
|
||||
args.algo = "milenage";
|
||||
args.imei = "35609204079301";
|
||||
args.imei = "356092040793011";
|
||||
args.imsi = "208930000000001";
|
||||
args.k = "8BAF473F2F8FD09487CCCBD7097C6862";
|
||||
args.op = "11111111111111111111111111111111";
|
||||
|
||||
srsue::usim usim;
|
||||
usim.init(&args, &usim_log);
|
||||
usim.generate_authentication_response(rand_enb, autn_enb, mcc, mnc, &net_valid, res, k_asme);
|
||||
|
||||
assert(net_valid == true);
|
||||
assert(usim.generate_authentication_response(rand_enb, autn_enb, mcc, mnc, res, &res_len, k_asme) == AUTH_OK);
|
||||
}
|
||||
|
|
|
@ -86,20 +86,22 @@ file_max_size = -1
|
|||
#####################################################################
|
||||
# USIM configuration
|
||||
#
|
||||
# mode: USIM mode (soft/pcsc)
|
||||
# algo: Authentication algorithm (xor/milenage)
|
||||
# op: 128-bit Operator Variant Algorithm Configuration Field (hex)
|
||||
# amf: 16-bit Authentication Management Field (hex)
|
||||
# k: 128-bit subscriber key (hex)
|
||||
# imsi: 15 digit International Mobile Subscriber Identity
|
||||
# imei: 15 digit International Mobile Station Equipment Identity
|
||||
# pin: PIN in case real SIM card is used
|
||||
#####################################################################
|
||||
[usim]
|
||||
mode = soft
|
||||
algo = xor
|
||||
op = 63BFA50EE6523365FF14C1F45F88737D
|
||||
k = 00112233445566778899aabbccddeeff
|
||||
imsi = 001010123456789
|
||||
imei = 353490069873319
|
||||
|
||||
#pin = 1234
|
||||
|
||||
#####################################################################
|
||||
# RRC configuration
|
||||
|
|
Loading…
Reference in New Issue