encryption tested OK with EEA1 and NAS UE/CN from EURECOM: TO DO test with dongle in real time.
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5599 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -77,7 +77,8 @@ static int _nas_message_plain_decode(const char* buffer,
|
|||||||
nas_message_plain_t* msg, int length);
|
nas_message_plain_t* msg, int length);
|
||||||
static int _nas_message_protected_decode(const char* buffer,
|
static int _nas_message_protected_decode(const char* buffer,
|
||||||
nas_message_security_header_t* header,
|
nas_message_security_header_t* header,
|
||||||
nas_message_plain_t* msg, int length);
|
nas_message_plain_t* msg, int length,
|
||||||
|
const emm_security_context_t * const emm_security_context);
|
||||||
|
|
||||||
/* Functions used to encode layer 3 NAS messages */
|
/* Functions used to encode layer 3 NAS messages */
|
||||||
static int _nas_message_header_encode(char* buffer,
|
static int _nas_message_header_encode(char* buffer,
|
||||||
@@ -99,7 +100,9 @@ static int _nas_message_decrypt(
|
|||||||
UInt8_t type,
|
UInt8_t type,
|
||||||
UInt32_t code,
|
UInt32_t code,
|
||||||
UInt8_t seq,
|
UInt8_t seq,
|
||||||
int length);
|
int length,
|
||||||
|
const emm_security_context_t * const emm_security_context);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_nas_message_encrypt(
|
_nas_message_encrypt(
|
||||||
@@ -181,7 +184,7 @@ nas_message_encrypt(
|
|||||||
/* Compute the NAS message authentication code */
|
/* Compute the NAS message authentication code */
|
||||||
UInt32_t mac = _nas_message_get_mac(
|
UInt32_t mac = _nas_message_get_mac(
|
||||||
outbuf + offset,
|
outbuf + offset,
|
||||||
length - offset,
|
bytes + size - offset,
|
||||||
#ifdef NAS_MME
|
#ifdef NAS_MME
|
||||||
SECU_DIRECTION_DOWNLINK,
|
SECU_DIRECTION_DOWNLINK,
|
||||||
#else
|
#else
|
||||||
@@ -331,7 +334,8 @@ int nas_message_decrypt(
|
|||||||
header->security_header_type,
|
header->security_header_type,
|
||||||
header->message_authentication_code,
|
header->message_authentication_code,
|
||||||
header->sequence_number,
|
header->sequence_number,
|
||||||
length - size);
|
length - size,
|
||||||
|
emm_security_context);
|
||||||
bytes = length - size;
|
bytes = length - size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -418,13 +422,18 @@ int nas_message_decode(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Decode security protected NAS message */
|
/* Decode security protected NAS message */
|
||||||
bytes = _nas_message_protected_decode(buffer + size, &msg->header,
|
bytes = _nas_message_protected_decode(buffer + size,
|
||||||
&msg->plain, length - size);
|
&msg->header,
|
||||||
|
&msg->plain,
|
||||||
|
length - size,
|
||||||
|
emm_security_context);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Decode plain NAS message */
|
/* Decode plain NAS message */
|
||||||
bytes = _nas_message_plain_decode(buffer, &msg->header,
|
bytes = _nas_message_plain_decode(buffer,
|
||||||
&msg->plain, length);
|
&msg->header,
|
||||||
|
&msg->plain,
|
||||||
|
length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
@@ -666,15 +675,15 @@ _nas_message_plain_decode(
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** **
|
** **
|
||||||
** Name: _nas_message_protected_decode() **
|
** Name: _nas_message_protected_decode() **
|
||||||
** **
|
** **
|
||||||
** Description: Decode security protected NAS message **
|
** Description: Decode security protected NAS message **
|
||||||
** **
|
** **
|
||||||
** Inputs: buffer: Pointer to the buffer containing the secu- **
|
** Inputs: buffer: Pointer to the buffer containing the secu- **
|
||||||
** rity protected NAS message data **
|
** rity protected NAS message data **
|
||||||
** header: Header of the security protected NAS mes- **
|
** header: Header of the security protected NAS message **
|
||||||
** sage **
|
** length: Number of bytes that should be decoded **
|
||||||
** length: Number of bytes that should be decoded **
|
** emm_security_context: security context **
|
||||||
** Others: None **
|
** Others: None **
|
||||||
** **
|
** **
|
||||||
** Outputs: msg: Decoded NAS message **
|
** Outputs: msg: Decoded NAS message **
|
||||||
@@ -688,7 +697,8 @@ static int _nas_message_protected_decode(
|
|||||||
const char *buffer,
|
const char *buffer,
|
||||||
nas_message_security_header_t *header,
|
nas_message_security_header_t *header,
|
||||||
nas_message_plain_t *msg,
|
nas_message_plain_t *msg,
|
||||||
int length)
|
int length,
|
||||||
|
const emm_security_context_t * const emm_security_context)
|
||||||
{
|
{
|
||||||
LOG_FUNC_IN;
|
LOG_FUNC_IN;
|
||||||
|
|
||||||
@@ -699,10 +709,13 @@ static int _nas_message_protected_decode(
|
|||||||
{
|
{
|
||||||
/* Decrypt the security protected NAS message */
|
/* Decrypt the security protected NAS message */
|
||||||
header->protocol_discriminator =
|
header->protocol_discriminator =
|
||||||
_nas_message_decrypt(plain_msg, buffer,
|
_nas_message_decrypt(plain_msg,
|
||||||
|
buffer,
|
||||||
header->security_header_type,
|
header->security_header_type,
|
||||||
header->message_authentication_code,
|
header->message_authentication_code,
|
||||||
header->sequence_number, length);
|
header->sequence_number,
|
||||||
|
length,
|
||||||
|
emm_security_context);
|
||||||
/* Decode the decrypted message as plain NAS message */
|
/* Decode the decrypted message as plain NAS message */
|
||||||
bytes = _nas_message_plain_decode(plain_msg, header, msg, length);
|
bytes = _nas_message_plain_decode(plain_msg, header, msg, length);
|
||||||
free(plain_msg);
|
free(plain_msg);
|
||||||
@@ -820,20 +833,20 @@ static int _nas_message_plain_encode(
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** **
|
** **
|
||||||
** Name: _nas_message_protected_encode() **
|
** Name: _nas_message_protected_encode() **
|
||||||
** **
|
** **
|
||||||
** Description: Encode security protected NAS message **
|
** Description: Encode security protected NAS message **
|
||||||
** **
|
** **
|
||||||
** Inputs msg: Security protected NAS message structure **
|
** Inputs msg: Security protected NAS message structure **
|
||||||
** to encode **
|
** to encode **
|
||||||
** length: Maximal capacity of the output buffer **
|
** length: Maximal capacity of the output buffer **
|
||||||
** Others: None **
|
** Others: None **
|
||||||
** **
|
** **
|
||||||
** Outputs: buffer: Pointer to the encoded data buffer **
|
** Outputs: buffer: Pointer to the encoded data buffer **
|
||||||
** Return: The number of bytes in the buffer if the **
|
** Return: The number of bytes in the buffer if the **
|
||||||
** data have been successfully encoded; **
|
** data have been successfully encoded; **
|
||||||
** A negative error code otherwise. **
|
** A negative error code otherwise. **
|
||||||
** Others: None **
|
** Others: None **
|
||||||
** **
|
** **
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int _nas_message_protected_encode(
|
static int _nas_message_protected_encode(
|
||||||
@@ -889,7 +902,7 @@ static int _nas_message_protected_encode(
|
|||||||
** Description: Decrypt security protected NAS message **
|
** Description: Decrypt security protected NAS message **
|
||||||
** **
|
** **
|
||||||
** Inputs src: Pointer to the encrypted data buffer **
|
** Inputs src: Pointer to the encrypted data buffer **
|
||||||
** type: The security header type **
|
** security_header_type: The security header type **
|
||||||
** code: The message authentication code **
|
** code: The message authentication code **
|
||||||
** seq: The sequence number **
|
** seq: The sequence number **
|
||||||
** length: Maximal capacity of the output buffer **
|
** length: Maximal capacity of the output buffer **
|
||||||
@@ -904,24 +917,140 @@ static int _nas_message_protected_encode(
|
|||||||
static int _nas_message_decrypt(
|
static int _nas_message_decrypt(
|
||||||
char *dest,
|
char *dest,
|
||||||
const char *src,
|
const char *src,
|
||||||
UInt8_t type,
|
UInt8_t security_header_type,
|
||||||
UInt32_t code,
|
UInt32_t code,
|
||||||
UInt8_t seq,
|
UInt8_t seq,
|
||||||
int length)
|
int length,
|
||||||
|
const emm_security_context_t * const emm_security_context)
|
||||||
{
|
{
|
||||||
|
nas_stream_cipher_t stream_cipher;
|
||||||
|
uint32_t count;
|
||||||
|
uint8_t direction;
|
||||||
|
|
||||||
LOG_FUNC_IN;
|
LOG_FUNC_IN;
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
nas_message_security_header_t header;
|
nas_message_security_header_t header;
|
||||||
|
|
||||||
/* TODO: run the uncyphering algorithm */
|
#ifdef NAS_MME
|
||||||
memcpy(dest, src, length);
|
direction = SECU_DIRECTION_UPLINK;
|
||||||
|
#else
|
||||||
|
direction = SECU_DIRECTION_DOWNLINK;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Decode the first octet (security header type or EPS bearer identity,
|
switch (security_header_type) {
|
||||||
* and protocol discriminator) */
|
case SECURITY_HEADER_TYPE_NOT_PROTECTED:
|
||||||
DECODE_U8(src, *(UInt8_t*)(&header), size);
|
case SECURITY_HEADER_TYPE_SERVICE_REQUEST:
|
||||||
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED:
|
||||||
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED_NEW:
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"No decryption of message according to security header type 0x%02x",
|
||||||
|
security_header_type);
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
LOG_FUNC_RETURN (length);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED_CYPHERED:
|
||||||
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED_CYPHERED_NEW:
|
||||||
|
switch (emm_security_context->selected_algorithms.encryption) {
|
||||||
|
|
||||||
|
case NAS_SECURITY_ALGORITHMS_EEA1: {
|
||||||
|
if (direction == SECU_DIRECTION_UPLINK) {
|
||||||
|
count = 0x00000000 ||
|
||||||
|
((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->ul_count.seq_num & 0x000000FF);
|
||||||
|
} else {
|
||||||
|
count = 0x00000000 ||
|
||||||
|
((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->dl_count.seq_num & 0x000000FF);
|
||||||
|
}
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"NAS_SECURITY_ALGORITHMS_EEA1 dir %s count.seq_num %u count %u",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||||
|
count);
|
||||||
|
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||||
|
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||||
|
stream_cipher.count = count;
|
||||||
|
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||||
|
stream_cipher.direction = direction;
|
||||||
|
stream_cipher.message = src;
|
||||||
|
/* length in bits */
|
||||||
|
stream_cipher.blength = length << 3;
|
||||||
|
nas_stream_encrypt_eea1(&stream_cipher, dest);
|
||||||
|
/* Decode the first octet (security header type or EPS bearer identity,
|
||||||
|
* and protocol discriminator) */
|
||||||
|
DECODE_U8(dest, *(UInt8_t*)(&header), size);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN (header.protocol_discriminator);
|
||||||
|
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case NAS_SECURITY_ALGORITHMS_EEA2: {
|
||||||
|
if (direction == SECU_DIRECTION_UPLINK) {
|
||||||
|
count = 0x00000000 ||
|
||||||
|
((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->ul_count.seq_num & 0x000000FF);
|
||||||
|
} else {
|
||||||
|
count = 0x00000000 ||
|
||||||
|
((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->dl_count.seq_num & 0x000000FF);
|
||||||
|
}
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"NAS_SECURITY_ALGORITHMS_EEA2 dir %s count.seq_num %u count %u",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||||
|
count);
|
||||||
|
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||||
|
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||||
|
stream_cipher.count = count;
|
||||||
|
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||||
|
stream_cipher.direction = direction;
|
||||||
|
stream_cipher.message = src;
|
||||||
|
/* length in bits */
|
||||||
|
stream_cipher.blength = length << 3;
|
||||||
|
nas_stream_encrypt_eea1(&stream_cipher, dest);
|
||||||
|
/* Decode the first octet (security header type or EPS bearer identity,
|
||||||
|
* and protocol discriminator) */
|
||||||
|
DECODE_U8(dest, *(UInt8_t*)(&header), size);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN (header.protocol_discriminator);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case NAS_SECURITY_ALGORITHMS_EEA0:
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"NAS_SECURITY_ALGORITHMS_EEA0 dir %d ul_count.seq_num %d dl_count.seq_num %d",
|
||||||
|
direction,
|
||||||
|
emm_security_context->ul_count.seq_num,
|
||||||
|
emm_security_context->dl_count.seq_num);
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
/* Decode the first octet (security header type or EPS bearer identity,
|
||||||
|
* and protocol discriminator) */
|
||||||
|
DECODE_U8(dest, *(UInt8_t*)(&header), size);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN (header.protocol_discriminator);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_TRACE(ERROR,
|
||||||
|
"Unknown Cyphering protection algorithm %d",
|
||||||
|
emm_security_context->selected_algorithms.encryption);
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
/* Decode the first octet (security header type or EPS bearer identity,
|
||||||
|
* and protocol discriminator) */
|
||||||
|
DECODE_U8(dest, *(UInt8_t*)(&header), size);
|
||||||
|
|
||||||
|
LOG_FUNC_RETURN (header.protocol_discriminator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_TRACE(ERROR,
|
||||||
|
"Unknown security header type %u", security_header_type);
|
||||||
|
LOG_FUNC_RETURN (0);
|
||||||
|
};
|
||||||
|
|
||||||
LOG_FUNC_RETURN (header.protocol_discriminator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -931,7 +1060,7 @@ static int _nas_message_decrypt(
|
|||||||
** Description: Encrypt plain NAS message **
|
** Description: Encrypt plain NAS message **
|
||||||
** **
|
** **
|
||||||
** Inputs src: Pointer to the decrypted data buffer **
|
** Inputs src: Pointer to the decrypted data buffer **
|
||||||
** type: The security header type **
|
** security_header_type: The security header type **
|
||||||
** code: The message authentication code **
|
** code: The message authentication code **
|
||||||
** seq: The sequence number **
|
** seq: The sequence number **
|
||||||
** direction: The sequence number **
|
** direction: The sequence number **
|
||||||
@@ -948,13 +1077,15 @@ static int _nas_message_decrypt(
|
|||||||
static int _nas_message_encrypt(
|
static int _nas_message_encrypt(
|
||||||
char *dest,
|
char *dest,
|
||||||
const char *src,
|
const char *src,
|
||||||
UInt8_t type,
|
UInt8_t security_header_type,
|
||||||
UInt32_t code,
|
UInt32_t code,
|
||||||
UInt8_t seq,
|
UInt8_t seq,
|
||||||
int const direction,
|
int const direction,
|
||||||
int length,
|
int length,
|
||||||
const emm_security_context_t * const emm_security_context)
|
const emm_security_context_t * const emm_security_context)
|
||||||
{
|
{
|
||||||
|
nas_stream_cipher_t stream_cipher;
|
||||||
|
uint32_t count;
|
||||||
LOG_FUNC_IN;
|
LOG_FUNC_IN;
|
||||||
|
|
||||||
if (!emm_security_context) {
|
if (!emm_security_context) {
|
||||||
@@ -963,46 +1094,103 @@ static int _nas_message_encrypt(
|
|||||||
LOG_FUNC_RETURN (0);
|
LOG_FUNC_RETURN (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (emm_security_context->selected_algorithms.encryption) {
|
switch (security_header_type) {
|
||||||
|
case SECURITY_HEADER_TYPE_NOT_PROTECTED:
|
||||||
|
case SECURITY_HEADER_TYPE_SERVICE_REQUEST:
|
||||||
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED:
|
||||||
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED_NEW:
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"No encryption of message according to security header type 0x%02x",
|
||||||
|
security_header_type);
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
LOG_FUNC_RETURN (length);
|
||||||
|
break;
|
||||||
|
|
||||||
case NAS_SECURITY_ALGORITHMS_EEA1: {
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED_CYPHERED:
|
||||||
LOG_TRACE(WARNING,
|
case SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED_CYPHERED_NEW:
|
||||||
"TODO NAS_SECURITY_ALGORITHMS_EEA1 dir %d ul_count.seq_num %d dl_count.seq_num %d",
|
switch (emm_security_context->selected_algorithms.encryption) {
|
||||||
direction,
|
|
||||||
emm_security_context->ul_count.seq_num,
|
|
||||||
emm_security_context->dl_count.seq_num);
|
|
||||||
memcpy(dest, src, length);
|
|
||||||
LOG_FUNC_RETURN (length);
|
|
||||||
|
|
||||||
}break;
|
case NAS_SECURITY_ALGORITHMS_EEA1: {
|
||||||
|
if (direction == SECU_DIRECTION_UPLINK) {
|
||||||
|
count = 0x00000000 ||
|
||||||
|
((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->ul_count.seq_num & 0x000000FF);
|
||||||
|
} else {
|
||||||
|
count = 0x00000000 ||
|
||||||
|
((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->dl_count.seq_num & 0x000000FF);
|
||||||
|
}
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"NAS_SECURITY_ALGORITHMS_EEA1 dir %s count.seq_num %u count %u",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||||
|
count);
|
||||||
|
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||||
|
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||||
|
stream_cipher.count = count;
|
||||||
|
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||||
|
stream_cipher.direction = direction;
|
||||||
|
stream_cipher.message = src;
|
||||||
|
/* length in bits */
|
||||||
|
stream_cipher.blength = length << 3;
|
||||||
|
nas_stream_encrypt_eea1(&stream_cipher, dest);
|
||||||
|
|
||||||
case NAS_SECURITY_ALGORITHMS_EEA2: {
|
LOG_FUNC_RETURN (length);
|
||||||
LOG_TRACE(WARNING,
|
|
||||||
"TODO NAS_SECURITY_ALGORITHMS_EEA2 dir %d ul_count.seq_num %d dl_count.seq_num %d",
|
|
||||||
direction,
|
|
||||||
emm_security_context->ul_count.seq_num,
|
|
||||||
emm_security_context->dl_count.seq_num);
|
|
||||||
memcpy(dest, src, length);
|
|
||||||
LOG_FUNC_RETURN (length);
|
|
||||||
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case NAS_SECURITY_ALGORITHMS_EEA0:
|
case NAS_SECURITY_ALGORITHMS_EEA2: {
|
||||||
LOG_TRACE(DEBUG,
|
if (direction == SECU_DIRECTION_UPLINK) {
|
||||||
"NAS_SECURITY_ALGORITHMS_EEA0 dir %d ul_count.seq_num %d dl_count.seq_num %d",
|
count = 0x00000000 ||
|
||||||
direction,
|
((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
emm_security_context->ul_count.seq_num,
|
(emm_security_context->ul_count.seq_num & 0x000000FF);
|
||||||
emm_security_context->dl_count.seq_num);
|
} else {
|
||||||
memcpy(dest, src, length);
|
count = 0x00000000 ||
|
||||||
LOG_FUNC_RETURN (length);
|
((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
|
||||||
|
(emm_security_context->dl_count.seq_num & 0x000000FF);
|
||||||
|
}
|
||||||
|
LOG_TRACE(DEBUG,
|
||||||
|
"NAS_SECURITY_ALGORITHMS_EEA2 dir %s count.seq_num %u count %u",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
|
||||||
|
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
|
||||||
|
count);
|
||||||
|
stream_cipher.key = emm_security_context->knas_enc.value;
|
||||||
|
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
|
||||||
|
stream_cipher.count = count;
|
||||||
|
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||||
|
stream_cipher.direction = direction;
|
||||||
|
stream_cipher.message = src;
|
||||||
|
/* length in bits */
|
||||||
|
stream_cipher.blength = length << 3;
|
||||||
|
nas_stream_encrypt_eea2(&stream_cipher, dest);
|
||||||
|
|
||||||
break;
|
LOG_FUNC_RETURN (length);
|
||||||
|
|
||||||
default:
|
}break;
|
||||||
LOG_TRACE(ERROR,
|
|
||||||
"Unknown Cyphering protection algorithm %d",
|
case NAS_SECURITY_ALGORITHMS_EEA0:
|
||||||
emm_security_context->selected_algorithms.encryption);
|
LOG_TRACE(DEBUG,
|
||||||
break;
|
"NAS_SECURITY_ALGORITHMS_EEA0 dir %d ul_count.seq_num %d dl_count.seq_num %d",
|
||||||
|
direction,
|
||||||
|
emm_security_context->ul_count.seq_num,
|
||||||
|
emm_security_context->dl_count.seq_num);
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
LOG_FUNC_RETURN (length);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_TRACE(ERROR,
|
||||||
|
"Unknown Cyphering protection algorithm %d",
|
||||||
|
emm_security_context->selected_algorithms.encryption);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_TRACE(ERROR,
|
||||||
|
"Unknown security header type %u", security_header_type);
|
||||||
|
LOG_FUNC_RETURN (0);
|
||||||
}
|
}
|
||||||
LOG_FUNC_RETURN (length);
|
LOG_FUNC_RETURN (length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1144,15 +1144,15 @@ static int _security_select_algorithms(
|
|||||||
LOG_FUNC_RETURN (rc);
|
LOG_FUNC_RETURN (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA0)) {
|
if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA1)) {
|
||||||
|
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA1");
|
||||||
|
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA1;
|
||||||
|
} else if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA0)) {
|
||||||
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA0");
|
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA0");
|
||||||
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA0;
|
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA0;
|
||||||
} else if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA2)) {
|
} else if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA2)) {
|
||||||
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA2");
|
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA2");
|
||||||
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA2;
|
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA2;
|
||||||
} else if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA1)) {
|
|
||||||
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA1");
|
|
||||||
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA1;
|
|
||||||
} else {
|
} else {
|
||||||
LOG_FUNC_RETURN (rc);
|
LOG_FUNC_RETURN (rc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
|
|||||||
buffer += header_result;
|
buffer += header_result;
|
||||||
len -= header_result;
|
len -= header_result;
|
||||||
|
|
||||||
LOG_TRACE(INFO, "EMM-MSG - Message Type %02x", msg->header.message_type);
|
LOG_TRACE(INFO, "EMM-MSG - Message Type 0x%02x", msg->header.message_type);
|
||||||
|
|
||||||
switch(msg->header.message_type) {
|
switch(msg->header.message_type) {
|
||||||
case EMM_INFORMATION:
|
case EMM_INFORMATION:
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Description Implements the utility used to generate data stored in the
|
|||||||
#define KSI USIM_KSI_NOT_AVAILABLE
|
#define KSI USIM_KSI_NOT_AVAILABLE
|
||||||
#define KSI_ASME USIM_KSI_NOT_AVAILABLE
|
#define KSI_ASME USIM_KSI_NOT_AVAILABLE
|
||||||
#define INT_ALGO USIM_INT_EIA1
|
#define INT_ALGO USIM_INT_EIA1
|
||||||
#define ENC_ALGO USIM_ENC_EEA0
|
#define ENC_ALGO USIM_ENC_EEA1
|
||||||
#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO)
|
#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO)
|
||||||
|
|
||||||
#define MIN_TAC 0x0000
|
#define MIN_TAC 0x0000
|
||||||
|
|||||||
Reference in New Issue
Block a user