|
|
@ -345,30 +345,38 @@ void nas::integrity_generate(uint8_t *key_128,
|
|
|
|
|
|
|
|
|
|
|
|
bool nas::integrity_check(byte_buffer_t *pdu)
|
|
|
|
bool nas::integrity_check(byte_buffer_t *pdu)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint8_t exp_mac[4];
|
|
|
|
if (!pdu) {
|
|
|
|
uint8_t *mac = &pdu->msg[1];
|
|
|
|
nas_log->error("Invalid PDU\n");
|
|
|
|
int i;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pdu->N_bytes > 5) {
|
|
|
|
|
|
|
|
uint8_t exp_mac[4];
|
|
|
|
|
|
|
|
uint8_t *mac = &pdu->msg[1];
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
integrity_generate(&k_nas_int[16],
|
|
|
|
integrity_generate(&k_nas_int[16],
|
|
|
|
ctxt.rx_count,
|
|
|
|
ctxt.rx_count,
|
|
|
|
SECURITY_DIRECTION_DOWNLINK,
|
|
|
|
SECURITY_DIRECTION_DOWNLINK,
|
|
|
|
&pdu->msg[5],
|
|
|
|
&pdu->msg[5],
|
|
|
|
pdu->N_bytes-5,
|
|
|
|
pdu->N_bytes-5,
|
|
|
|
&exp_mac[0]);
|
|
|
|
&exp_mac[0]);
|
|
|
|
|
|
|
|
|
|
|
|
// Check if expected mac equals the sent mac
|
|
|
|
// Check if expected mac equals the sent mac
|
|
|
|
for(i=0; i<4; i++){
|
|
|
|
for(i=0; i<4; i++){
|
|
|
|
if(exp_mac[i] != mac[i]){
|
|
|
|
if(exp_mac[i] != mac[i]){
|
|
|
|
nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
|
|
|
|
nas_log->warning("Integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
|
|
|
|
"Received: count=%d, [%02x %02x %02x %02x]\n",
|
|
|
|
"Received: count=%d, [%02x %02x %02x %02x]\n",
|
|
|
|
ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3],
|
|
|
|
ctxt.rx_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3],
|
|
|
|
pdu->msg[5], mac[0], mac[1], mac[2], mac[3]);
|
|
|
|
pdu->msg[5], mac[0], mac[1], mac[2], mac[3]);
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n",
|
|
|
|
|
|
|
|
ctxt.rx_count, pdu->msg[5]);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
nas_log->error("Invalid integrity check PDU size (%d)\n", pdu->N_bytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n",
|
|
|
|
|
|
|
|
ctxt.rx_count, pdu->msg[5]);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nas::cipher_encrypt(byte_buffer_t *pdu)
|
|
|
|
void nas::cipher_encrypt(byte_buffer_t *pdu)
|
|
|
@ -454,6 +462,17 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT *caps)
|
|
|
|
******************************************************************************/
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
|
|
|
|
void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!pdu) {
|
|
|
|
|
|
|
|
nas_log->error("Invalid PDU\n");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pdu->N_bytes <= 5) {
|
|
|
|
|
|
|
|
nas_log->error("Invalid attach accept PDU size (%d)\n", pdu->N_bytes);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept;
|
|
|
|
LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept;
|
|
|
|
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req;
|
|
|
|
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT act_def_eps_bearer_context_req;
|
|
|
|
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete;
|
|
|
|
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete;
|
|
|
@ -679,6 +698,17 @@ void nas::parse_identity_request(uint32_t lcid, byte_buffer_t *pdu) {
|
|
|
|
|
|
|
|
|
|
|
|
void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
|
|
|
|
void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!pdu) {
|
|
|
|
|
|
|
|
nas_log->error("Invalid PDU\n");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pdu->N_bytes <= 5) {
|
|
|
|
|
|
|
|
nas_log->error("Invalid security mode command PDU size (%d)\n", pdu->N_bytes);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd;
|
|
|
|
LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd;
|
|
|
|
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp;
|
|
|
|
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp;
|
|
|
|
|
|
|
|
|
|
|
@ -808,6 +838,8 @@ void nas::parse_emm_information(uint32_t lcid, byte_buffer_t *pdu) {
|
|
|
|
******************************************************************************/
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
void nas::send_attach_request() {
|
|
|
|
void nas::send_attach_request() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req;
|
|
|
|
LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req;
|
|
|
|
byte_buffer_t *msg = pool_allocate;
|
|
|
|
byte_buffer_t *msg = pool_allocate;
|
|
|
|
if (!msg) {
|
|
|
|
if (!msg) {
|
|
|
@ -861,12 +893,16 @@ void nas::send_attach_request() {
|
|
|
|
(LIBLTE_BYTE_MSG_STRUCT *) msg);
|
|
|
|
(LIBLTE_BYTE_MSG_STRUCT *) msg);
|
|
|
|
|
|
|
|
|
|
|
|
// Add MAC
|
|
|
|
// Add MAC
|
|
|
|
integrity_generate(&k_nas_int[16],
|
|
|
|
if (msg->N_bytes > 5) {
|
|
|
|
ctxt.tx_count,
|
|
|
|
integrity_generate(&k_nas_int[16],
|
|
|
|
SECURITY_DIRECTION_UPLINK,
|
|
|
|
ctxt.tx_count,
|
|
|
|
&msg->msg[5],
|
|
|
|
SECURITY_DIRECTION_UPLINK,
|
|
|
|
msg->N_bytes - 5,
|
|
|
|
&msg->msg[5],
|
|
|
|
&msg->msg[1]);
|
|
|
|
msg->N_bytes - 5,
|
|
|
|
|
|
|
|
&msg->msg[1]);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
nas_log->error("Invalid PDU size %d\n", msg->N_bytes);
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI;
|
|
|
|
attach_req.eps_mobile_id.type_of_id = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI;
|
|
|
|
usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15);
|
|
|
|
usim->get_imsi_vec(attach_req.eps_mobile_id.imsi, 15);
|
|
|
|