nas message is added(auth, security-mode)

This commit is contained in:
Sukchan Lee 2017-03-06 14:01:59 +09:00
parent a99e31651a
commit 44a55c5a1e
5 changed files with 361 additions and 11 deletions

View File

@ -275,6 +275,59 @@ c_int32_t nas_decode_authentication_response(nas_message_t *message,
return decoded;
}
c_int32_t nas_decode_security_mode_complete(nas_message_t *message,
pkbuf_t *pkbuf)
{
nas_security_mode_complete_t *security_mode_complete =
&message->emm.security_mode_complete;
c_uint16_t decoded = 0;
c_int32_t size = 0;
while(pkbuf->len > 0)
{
c_uint8_t *buffer = pkbuf->payload;
c_uint8_t type = (*buffer) >= 0x80 ? ((*buffer) & 0xf0) : (*buffer);
size = sizeof(c_uint8_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK, return -1,
"pkbuf_header error");
decoded += size;
switch(type)
{
case NAS_SECURITY_MODE_COMPLETE_IMEISV_TYPE:
size = nas_decode_mobile_identity(
&security_mode_complete->imeisv, pkbuf);
d_assert(size >= 0, return -1, "decode failed");
security_mode_complete->presencemask |=
NAS_SECURITY_MODE_COMPLETE_IMEISV_PRESENT;
decoded += size;
break;
default:
d_error("Unknown type(0x%x) or not implemented\n", type);
return -1;
}
}
return decoded;
}
c_int32_t nas_decode_security_mode_reject(nas_message_t *message,
pkbuf_t *pkbuf)
{
nas_security_mode_reject_t *security_mode_reject =
&message->emm.security_mode_reject;
c_uint16_t decoded = 0;
c_int32_t size = 0;
size = nas_decode_emm_cause(&security_mode_reject->emm_cause, pkbuf);
d_assert(size >= 0, return -1, "decode failed");
decoded += size;
return decoded;
}
status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
{
status_t rv = CORE_ERROR;
@ -311,7 +364,7 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
decoded += size;
break;
case NAS_ATTACH_ACCEPT:
d_error("Not implemented");
d_error("Not implemented(0x%x)", message->h.message_type);
return CORE_ERROR;
case NAS_ATTACH_COMPLETE:
size = nas_decode_attach_complete(message, pkbuf);
@ -336,7 +389,7 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
decoded += size;
break;
case NAS_AUTHENTICATION_REJECT:
d_error("Not implemented");
d_error("Not implemented(0x%x)", message->h.message_type);
return CORE_ERROR;
case NAS_AUTHENTICATION_FAILURE:
size = nas_decode_authentication_failure(message, pkbuf);
@ -346,8 +399,18 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
case NAS_IDENTITY_REQUEST:
case NAS_IDENTITY_RESPONSE:
case NAS_SECURITY_MODE_COMMAND:
d_error("Not implemented(0x%x)", message->h.message_type);
return CORE_ERROR;
case NAS_SECURITY_MODE_COMPLETE:
size = nas_decode_security_mode_complete(message, pkbuf);
d_assert(size >= CORE_OK, return CORE_ERROR, "decode error");
decoded += size;
break;
case NAS_SECURITY_MODE_REJECT:
size = nas_decode_security_mode_reject(message, pkbuf);
d_assert(size >= CORE_OK, return CORE_ERROR, "decode error");
decoded += size;
break;
case NAS_EMM_STATUS:
case NAS_EMM_INFORMATION:
case NAS_DOWNLINK_NAS_TRANSPORT:
@ -379,7 +442,7 @@ status_t nas_decode_pdu(nas_message_t *message, pkbuf_t *pkbuf)
case NAS_ESM_INFORMATION_RESPONSE:
case NAS_ESM_STATUS:
default:
d_error("Unknown message type (%d) or not implemented",
d_error("Unknown message type (0x%x) or not implemented",
message->h.message_type);
break;
}

View File

@ -207,7 +207,7 @@ c_int32_t nas_encode_attach_reject(pkbuf_t *pkbuf, nas_message_t *message)
if (attach_reject->presencemask & NAS_ATTACH_REJECT_T3346_VALUE_PRESENT)
{
size = nas_encode_optional_type(pkbuf,
NAS_ATTACH_REJECT_T3346_VALUE_PRESENT);
NAS_ATTACH_REJECT_T3346_VALUE_TYPE);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
@ -216,7 +216,7 @@ c_int32_t nas_encode_attach_reject(pkbuf_t *pkbuf, nas_message_t *message)
encoded += size;
}
if (attach_reject->presencemask & NAS_ATTACH_REJECT_T3402_VALUE_TYPE)
if (attach_reject->presencemask & NAS_ATTACH_REJECT_T3402_VALUE_PRESENT)
{
size = nas_encode_optional_type(pkbuf,
NAS_ATTACH_REJECT_T3402_VALUE_TYPE);
@ -228,7 +228,8 @@ c_int32_t nas_encode_attach_reject(pkbuf_t *pkbuf, nas_message_t *message)
encoded += size;
}
if (attach_reject->presencemask & NAS_ATTACH_REJECT_EXTENDED_EMM_CAUSE_TYPE)
if (attach_reject->presencemask &
NAS_ATTACH_REJECT_EXTENDED_EMM_CAUSE_PRESENT)
{
attach_reject->extended_emm_cause.type =
(NAS_ATTACH_ACCEPT_ADDITIONAL_UPDATE_RESULT_TYPE >> 4);
@ -268,6 +269,70 @@ c_int32_t nas_encode_authentication_request(
return encoded;
}
c_int32_t nas_encode_security_mode_command(
pkbuf_t *pkbuf, nas_message_t *message)
{
nas_security_mode_command_t *security_mode_command =
&message->emm.security_mode_command;
c_int32_t size = 0;
c_int32_t encoded = 0;
size = nas_encode_nas_security_algorithms(
pkbuf, &security_mode_command->selected_nas_security_algorithms);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_nas_key_set_identifier(
pkbuf, &security_mode_command->nas_key_set_identifier);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_ue_security_capability(
pkbuf, &security_mode_command->replayed_ue_security_capabilities);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
if (security_mode_command->presencemask &
NAS_SECURITY_MODE_COMMAND_IMEISV_REQUEST_PRESENT)
{
size = nas_encode_optional_type(pkbuf,
NAS_SECURITY_MODE_COMMAND_IMEISV_REQUEST_TYPE);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_imeisv_request(pkbuf,
&security_mode_command->imeisv_request);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
}
if (security_mode_command->presencemask &
NAS_SECURITY_MODE_COMMAND_REPLAYED_NONCE_PRESENT)
{
size = nas_encode_optional_type(pkbuf,
NAS_SECURITY_MODE_COMMAND_REPLAYED_NONCE_TYPE);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_nonce(pkbuf, &security_mode_command->replayed_nonce);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
}
if (security_mode_command->presencemask &
NAS_SECURITY_MODE_COMMAND_NONCE_PRESENT)
{
size = nas_encode_optional_type(pkbuf,
NAS_SECURITY_MODE_COMMAND_NONCE_TYPE);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
size = nas_encode_nonce(pkbuf, &security_mode_command->nonce);
d_assert(size >= 0, return encoded, "decode failed");
encoded += size;
}
return encoded;
}
status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
{
status_t rv = CORE_ERROR;
@ -288,7 +353,7 @@ status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
switch(message->h.message_type)
{
case NAS_ATTACH_REQUEST:
d_error("Not implemented", message->h.message_type);
d_error("Not implemented(0x%x)", message->h.message_type);
pkbuf_free((*pkbuf));
return CORE_ERROR;
case NAS_ATTACH_ACCEPT:
@ -297,7 +362,7 @@ status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
encoded += size;
break;
case NAS_ATTACH_COMPLETE:
d_error("Not implemented", message->h.message_type);
d_error("Not implemented(0x%x)", message->h.message_type);
pkbuf_free((*pkbuf));
return CORE_ERROR;
case NAS_ATTACH_REJECT:
@ -319,8 +384,9 @@ status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
size = nas_encode_authentication_request(*pkbuf, message);
d_assert(size >= 0, return CORE_ERROR, "decode error");
encoded += size;
break;
case NAS_AUTHENTICATION_RESPONSE:
d_error("Not implemented", message->h.message_type);
d_error("Not implemented(0x%x)", message->h.message_type);
pkbuf_free((*pkbuf));
return CORE_ERROR;
case NAS_AUTHENTICATION_REJECT:
@ -329,6 +395,10 @@ status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
case NAS_IDENTITY_REQUEST:
case NAS_IDENTITY_RESPONSE:
case NAS_SECURITY_MODE_COMMAND:
size = nas_encode_security_mode_command(*pkbuf, message);
d_assert(size >= 0, return CORE_ERROR, "decode error");
encoded += size;
break;
case NAS_SECURITY_MODE_COMPLETE:
case NAS_SECURITY_MODE_REJECT:
case NAS_EMM_STATUS:
@ -362,7 +432,7 @@ status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message)
case NAS_ESM_INFORMATION_RESPONSE:
case NAS_ESM_STATUS:
default:
d_error("Unknown message type (%d) or not implemented",
d_error("Unknown message type (0x%x) or not implemented",
message->h.message_type);
pkbuf_free((*pkbuf));
return CORE_ERROR;

View File

@ -93,6 +93,22 @@ c_int32_t nas_encode_mobile_identity(
return size;
}
c_int32_t nas_decode_mobile_identity(
nas_mobile_identity_t *mobile_identity, pkbuf_t *pkbuf)
{
c_uint16_t size = 0;
nas_mobile_identity_t *source = pkbuf->payload;
mobile_identity->length = source->length;
size = mobile_identity->length + sizeof(mobile_identity->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(mobile_identity, pkbuf->payload - size, size);
return size;
}
/* 9.9.2.4 Mobile station classmark 2
* See subclause 10.5.1.6 in 3GPP TS 24.008
* O TLV 5 */
@ -569,6 +585,16 @@ CORE_DECLARE(c_int32_t) nas_encode_gprs_timer_3(
return size;
}
/* 9.9.3.18 IMEISV request
* See subclause 10.5.5.10 in 3GPP TS 24.008 [13].
* O TV 1 */
c_int32_t nas_encode_imeisv_request(
pkbuf_t *pkbuf, nas_imeisv_request_t *imeisv_request)
{
memcpy(imeisv_request, pkbuf->payload - 1, 1);
return 0;
}
/* 9.9.3.20 MS network capability
* See subclause 10.5.5.12 in 3GPP TS 24.008
* O TLV 4-10 */
@ -591,7 +617,6 @@ c_int32_t nas_decode_ms_network_capability(
/* 9.9.3.20A MS network feature support
* See subclause 10.5.1.15 in 3GPP TS 24.008 [13].
* O TV 1 */
c_int32_t nas_decode_ms_network_feature_support(
nas_ms_network_feature_support_t *ms_network_feature_support,
pkbuf_t *pkbuf)
@ -619,6 +644,23 @@ c_int32_t nas_encode_nas_key_set_identifier(
return size;
}
/* 9.9.3.23 NAS security algorithms
* M V 1 */
c_int32_t nas_encode_nas_security_algorithms(
pkbuf_t *pkbuf, nas_security_algorithms_t *nas_security_algorithms)
{
c_uint16_t size = 0;
d_assert(nas_security_algorithms, return -1, "Null param");
size = sizeof(nas_security_algorithms_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(pkbuf->payload - size, nas_security_algorithms, size);
return size;
}
/* 9.9.3.24A Network resource identifier container
* See subclause 10.5.5.31 in 3GPP TS 24.008 [13].
* O TLV 4 */
@ -640,6 +682,25 @@ c_int32_t nas_decode_network_resource_identifier_container(
return size;
}
/* 9.9.3.25 Nonce
* O TV 5 */
c_int32_t nas_encode_nonce(pkbuf_t *pkbuf, nas_nonce_t *nonce)
{
c_uint16_t size = 0;
c_uint32_t target;
d_assert(nonce, return -1, "Null param");
size = sizeof(nas_nonce_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
target = htonl(*nonce);
memcpy(pkbuf->payload - size, &target, size);
return size;
}
/* 9.9.3.26 P-TMSI signature
* See subclause 10.5.5.8 in 3GPP TS 24.008
* O TV 4 */
@ -773,6 +834,25 @@ c_int32_t nas_decode_ue_network_capability(
return size;
}
/* 9.9.3.36 UE security capability
* M LV 3-6 */
c_int32_t nas_encode_ue_security_capability(
pkbuf_t *pkbuf, nas_ue_security_capability_t *ue_security_capability)
{
c_uint16_t size = 0;
nas_ue_security_capability_t *source = pkbuf->payload;
ue_security_capability->length = source->length;
size = ue_security_capability->length +
sizeof(ue_security_capability->length);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return -1, "pkbuf_header error");
memcpy(ue_security_capability, pkbuf->payload - size, size);
return size;
}
/* 9.9.3.44 Voice domain preference and UE's usage setting
* See subclause 10.5.5.28 in 3GPP TS 24.008 [13].
* O TLV 3 */

View File

@ -108,6 +108,8 @@ typedef struct _nas_mobile_identity_t {
CORE_DECLARE(c_int32_t) nas_encode_mobile_identity(
pkbuf_t *pkbuf, nas_mobile_identity_t *mobile_identity);
CORE_DECLARE(c_int32_t) nas_decode_mobile_identity(
nas_mobile_identity_t *mobile_identity, pkbuf_t *pkbuf);
/* 9.9.2.4 Mobile station classmark 2
* See subclause 10.5.1.6 in 3GPP TS 24.008
@ -490,6 +492,18 @@ CORE_DECLARE(c_int32_t) nas_decode_gprs_timer_3(
CORE_DECLARE(c_int32_t) nas_encode_gprs_timer_3(
pkbuf_t *pkbuf, nas_gprs_timer_3_t *gprs_timer_3);
/* 9.9.3.18 IMEISV request
* See subclause 10.5.5.10 in 3GPP TS 24.008 [13].
* O TV 1 */
typedef struct _nas_imeisv_request_t {
ED3(c_uint8_t type:4;,
c_uint8_t spare:1;,
c_uint8_t imeisv_request_value:3;)
} __attribute__ ((packed)) nas_imeisv_request_t;
CORE_DECLARE(c_int32_t) nas_encode_imeisv_request(
pkbuf_t *pkbuf, nas_imeisv_request_t *imeisv_request);
/* 9.9.3.20 MS network capability
* See subclause 10.5.5.12 in 3GPP TS 24.008
* O TLV 4-10 */
@ -556,6 +570,26 @@ ED3(c_uint8_t spare:4;,
CORE_DECLARE(c_int32_t) nas_encode_nas_key_set_identifier(
pkbuf_t *pkbuf, nas_key_set_identifier_t *nas_key_set_identifier);
/* 9.9.3.23 NAS security algorithms
* M V 1 */
#define NAS_SECURITY_ALGORITHMS_EIA0 0
#define NAS_SECURITY_ALGORITHMS_128_EIA1 1
#define NAS_SECURITY_ALGORITHMS_128_EIA2 2
#define NAS_SECURITY_ALGORITHMS_128_EIA3 3
#define NAS_SECURITY_ALGORITHMS_EIA4 4
#define NAS_SECURITY_ALGORITHMS_EIA5 5
#define NAS_SECURITY_ALGORITHMS_EIA6 6
#define NAS_SECURITY_ALGORITHMS_EIA7 7
typedef struct _nas_security_algorithms_t {
ED4(c_uint8_t spare1:1;,
c_uint8_t type_of_ciphering_algorithm:1;,
c_uint8_t spare2:1;,
c_uint8_t type_of_integrity_protection_algorithm:1;)
} __attribute__ ((packed)) nas_security_algorithms_t;
CORE_DECLARE(c_int32_t) nas_encode_nas_security_algorithms(
pkbuf_t *pkbuf, nas_security_algorithms_t *nas_security_algorithms);
/* 9.9.3.24A Network resource identifier container
* See subclause 10.5.5.31 in 3GPP TS 24.008 [13].
* O TLV 4 */
@ -571,6 +605,12 @@ CORE_DECLARE(c_int32_t) nas_decode_network_resource_identifier_container(
network_resource_identifier_container,
pkbuf_t *pkbuf);
/* 9.9.3.25 Nonce
* O TV 5 */
typedef c_uint32_t nas_nonce_t;
CORE_DECLARE(c_int32_t) nas_encode_nonce(pkbuf_t *pkbuf, nas_nonce_t *nonce);
/* 9.9.3.26 P-TMSI signature
* See subclause 10.5.5.8 in 3GPP TS 24.008
* O TV 4 */
@ -705,6 +745,55 @@ ED2(c_uint8_t spare:7;,
CORE_DECLARE(c_int32_t) nas_decode_ue_network_capability(
nas_ue_network_capability_t *ue_network_capability, pkbuf_t *pkbuf);
/* 9.9.3.36 UE security capability
* M LV 3-6 */
typedef struct _nas_ue_security_capability_t {
c_uint8_t length;
ED8(c_uint8_t eea0:1;,
c_uint8_t eea1:1;,
c_uint8_t eea2:1;,
c_uint8_t eea3:1;,
c_uint8_t eea4:1;,
c_uint8_t eea5:1;,
c_uint8_t eea6:1;,
c_uint8_t eea7:1;)
ED8(c_uint8_t eia0:1;,
c_uint8_t eia1:1;,
c_uint8_t eia2:1;,
c_uint8_t eia3:1;,
c_uint8_t eia4:1;,
c_uint8_t eia5:1;,
c_uint8_t eia6:1;,
c_uint8_t eia7:1;)
ED8(c_uint8_t uea0:1;,
c_uint8_t uea1:1;,
c_uint8_t uea2:1;,
c_uint8_t uea3:1;,
c_uint8_t uea4:1;,
c_uint8_t uea5:1;,
c_uint8_t uea6:1;,
c_uint8_t uea7:1;)
ED8(c_uint8_t spare1:1;,
c_uint8_t uia1:1;,
c_uint8_t uia2:1;,
c_uint8_t uia3:1;,
c_uint8_t uia4:1;,
c_uint8_t uia5:1;,
c_uint8_t uia6:1;,
c_uint8_t uia7:1;)
ED8(c_uint8_t spare2:1;,
c_uint8_t gea1:1;,
c_uint8_t gea2:1;,
c_uint8_t gea3:1;,
c_uint8_t gea4:1;,
c_uint8_t gea5:1;,
c_uint8_t gea6:1;,
c_uint8_t gea7:1;)
} __attribute__ ((packed)) nas_ue_security_capability_t;
CORE_DECLARE(c_int32_t) nas_encode_ue_security_capability(
pkbuf_t *pkbuf, nas_ue_security_capability_t *ue_security_capability);
/* 9.9.3.44 Voice domain preference and UE's usage setting
* See subclause 10.5.5.28 in 3GPP TS 24.008 [13].
* O TLV 3 */

View File

@ -294,6 +294,51 @@ typedef struct _nas_authentication_response_t {
/* Optional fields */
} nas_authentication_response_t;
/******************************
* 8.2.20 Security mode command
******************************/
#define NAS_SECURITY_MODE_COMMAND_IMEISV_REQUEST_PRESENT (1<<0)
#define NAS_SECURITY_MODE_COMMAND_REPLAYED_NONCE_PRESENT (1<<1)
#define NAS_SECURITY_MODE_COMMAND_NONCE_PRESENT (1<<2)
#define NAS_SECURITY_MODE_COMMAND_IMEISV_REQUEST_TYPE 0xC0
#define NAS_SECURITY_MODE_COMMAND_REPLAYED_NONCE_TYPE 0x55
#define NAS_SECURITY_MODE_COMMAND_NONCE_TYPE 0x56
typedef struct _nas_security_mode_command_t {
/* Mandatory fields */
nas_security_algorithms_t selected_nas_security_algorithms;
nas_key_set_identifier_t nas_key_set_identifier;
nas_ue_security_capability_t replayed_ue_security_capabilities;
/* Optional fields */
c_uint32_t presencemask;
nas_imeisv_request_t imeisv_request;
nas_nonce_t replayed_nonce;
nas_nonce_t nonce;
} nas_security_mode_command_t;
/*******************************
* 8.2.21 Security mode complete
*******************************/
#define NAS_SECURITY_MODE_COMPLETE_IMEISV_PRESENT (1<<0)
#define NAS_SECURITY_MODE_COMPLETE_IMEISV_TYPE 0x23
typedef struct _nas_security_mode_complete_t {
/* Optional fields */
c_uint32_t presencemask;
nas_mobile_identity_t imeisv;
} nas_security_mode_complete_t;
/******************************
* 8.2.22 Security mode reject
******************************/
typedef struct _nas_security_mode_reject_t {
/* Mandatory fields */
nas_emm_cause_t emm_cause;
/* Optional fields */
} nas_security_mode_reject_t;
typedef struct _nas_message_t {
nas_header_t h;
union {
@ -304,6 +349,9 @@ typedef struct _nas_message_t {
nas_authentication_failure_t authentication_failure;
nas_authentication_request_t authentication_request;
nas_authentication_response_t authentication_response;
nas_security_mode_command_t security_mode_command;
nas_security_mode_complete_t security_mode_complete;
nas_security_mode_reject_t security_mode_reject;
} emm;
} nas_message_t;