Now, MME can authorize UE

This commit is contained in:
Sukchan Lee 2017-03-08 23:42:27 +09:00
parent 512c0fbd5c
commit 638173bd28
2 changed files with 108 additions and 16 deletions

View File

@ -97,6 +97,7 @@ typedef struct _ue_ctx_t {
c_uint8_t imsi_len;
/* Security Context */
int security_context_available;
nas_ue_network_capability_t ue_network_capability;
nas_ms_network_capability_t ms_network_capability;
c_uint8_t xres[MAX_RES_LEN];

View File

@ -48,10 +48,14 @@ status_t nas_security_encode(
ue->ul_count = 0;
}
if (mme_self()->selected_enc_algorithm == 0)
ciphered = 0;
if (mme_self()->selected_int_algorithm == 0)
integrity_protected = 0;
if (ciphered || integrity_protected)
{
nas_security_header_t h;
c_uint8_t mac[NAS_SECURITY_MAC_SIZE];
pkbuf_t *new = NULL;
memset(&h, 0, sizeof(h));
@ -64,8 +68,7 @@ status_t nas_security_encode(
/* encode sequence number */
d_assert(CORE_OK == pkbuf_header(new, 1),
pkbuf_free(new);return CORE_ERROR,
"pkbuf_header error");
pkbuf_free(new);return CORE_ERROR, "pkbuf_header error");
*(c_uint8_t *)(new->payload) = h.sequence_number;
if (ciphered)
@ -78,6 +81,8 @@ status_t nas_security_encode(
if (integrity_protected)
{
c_uint8_t mac[NAS_SECURITY_MAC_SIZE];
/* calculate NAS MAC(message authentication code) */
nas_mac_calculate(mme_self()->selected_int_algorithm,
ue->knas_int, ue->dl_count, NAS_SECURITY_BEARER,
@ -89,14 +94,15 @@ status_t nas_security_encode(
/* encode all security header */
d_assert(CORE_OK == pkbuf_header(new, 5),
pkbuf_free(new);return CORE_ERROR,
"pkbuf_header error");
pkbuf_free(new);return CORE_ERROR, "pkbuf_header error");
/* h.message_authentication_code =
htonl(h.message_authentication_code); */
memcpy(new->payload, &h, sizeof(nas_security_header_t));
ue->dl_count = (ue->dl_count + 1) & 0xffffff; /* Use 24bit */
*pkbuf = new;
ue->security_context_available = 1;
}
return CORE_OK;
@ -105,24 +111,109 @@ status_t nas_security_encode(
status_t nas_security_decode(
nas_message_t *message, ue_ctx_t *ue, pkbuf_t *pkbuf)
{
nas_security_header_t *security_header = NULL;
c_uint16_t size = 0;
c_uint16_t decoded = 0;
status_t rv;
c_int32_t hsize = 0;
int integrity_protected = 0;
int new_security_context = 0;
int ciphered = 0;
nas_security_header_t *h = NULL;
d_assert(ue, return CORE_ERROR, "Null param");
d_assert(pkbuf, return CORE_ERROR, "Null param");
d_assert(pkbuf->payload, return CORE_ERROR, "Null param");
security_header = pkbuf->payload;
if (security_header->security_header_type !=
NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE)
h = pkbuf->payload;
switch(h->security_header_type)
{
size = sizeof(nas_security_header_t);
d_assert(pkbuf_header(pkbuf, -size) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
decoded += size;
case NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE:
return nas_plain_decode(message, pkbuf);
case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED:
integrity_protected = 1;
break;
case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED:
integrity_protected = 1;
ciphered = 1;
break;
case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT:
integrity_protected = 1;
new_security_context = 1;
break;
case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHTERD_WITH_NEW_INTEGRITY_CONTEXT:
integrity_protected = 1;
new_security_context = 1;
ciphered = 1;
break;
default:
d_warn("Not implemented(securiry header type:0x%x)",
message->h.security_header_type);
return CORE_ERROR;
}
return nas_plain_decode(message, pkbuf);
hsize = sizeof(nas_security_header_t);
d_assert(pkbuf_header(pkbuf, -hsize) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
if (!ue->security_context_available)
{
integrity_protected = 0;
new_security_context = 0;
ciphered = 0;
}
if (new_security_context)
{
ue->ul_count = 0;
}
if (mme_self()->selected_enc_algorithm == 0)
ciphered = 0;
if (mme_self()->selected_int_algorithm == 0)
integrity_protected = 0;
if (ciphered || integrity_protected)
{
d_assert(CORE_OK == pkbuf_header(pkbuf, 1),
return CORE_ERROR, "pkbuf_header error");
if (ciphered)
{
/* decrypt NAS message */
nas_encrypt(mme_self()->selected_enc_algorithm,
ue->knas_enc, ue->ul_count, NAS_SECURITY_BEARER,
NAS_SECURITY_UPLINK_DIRECTION, pkbuf);
}
if(integrity_protected)
{
c_uint8_t mac[NAS_SECURITY_MAC_SIZE];
c_uint32_t mac32;
/* calculate NAS MAC(message authentication code) */
nas_mac_calculate(mme_self()->selected_int_algorithm,
ue->knas_int, ue->ul_count, NAS_SECURITY_BEARER,
NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac);
memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE);
if (h->message_authentication_code != mac32)
{
d_error("NAS MAC verification failed");
d_assert(pkbuf_header(pkbuf, hsize-1) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
return CORE_ERROR;
}
}
d_assert(CORE_OK == pkbuf_header(pkbuf, -1),
return CORE_ERROR, "pkbuf_header error");
}
rv = nas_plain_decode(message, pkbuf);
d_assert(pkbuf_header(pkbuf, hsize) == CORE_OK,
return CORE_ERROR, "pkbuf_header error");
return rv;
}
void nas_mac_calculate(c_uint8_t algorithm_identity,