Now, MME can authorize UE
This commit is contained in:
parent
512c0fbd5c
commit
638173bd28
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue