Commit fc77df61 authored by Jerome Peraldi's avatar Jerome Peraldi

Merge branch 'sequans/eap_aka' into 'sqn/3GPP_TTCN_System_Simulator'

bug #127303 - [L3 SIMU] NAS NR : EAP-AKA' support@TTCN level

See merge request sequans/system/ttcn/openairinterface5g!1
parents affb4dc8 daafc076
...@@ -1368,6 +1368,7 @@ set(NR_PDCP_SRC ...@@ -1368,6 +1368,7 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea1.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
...@@ -1794,6 +1795,7 @@ set(libnas_ies_OBJS ...@@ -1794,6 +1795,7 @@ set(libnas_ies_OBJS
${NAS_SRC}COMMON/IES/AuthenticationParameterAutn.c ${NAS_SRC}COMMON/IES/AuthenticationParameterAutn.c
${NAS_SRC}COMMON/IES/AuthenticationParameterRand.c ${NAS_SRC}COMMON/IES/AuthenticationParameterRand.c
${NAS_SRC}COMMON/IES/AuthenticationResponseParameter.c ${NAS_SRC}COMMON/IES/AuthenticationResponseParameter.c
${NAS_SRC}COMMON/IES/EapMessage.c
${NAS_SRC}COMMON/IES/CipheringKeySequenceNumber.c ${NAS_SRC}COMMON/IES/CipheringKeySequenceNumber.c
${NAS_SRC}COMMON/IES/Cli.c ${NAS_SRC}COMMON/IES/Cli.c
${NAS_SRC}COMMON/IES/CsfbResponse.c ${NAS_SRC}COMMON/IES/CsfbResponse.c
......
...@@ -1346,9 +1346,11 @@ INPUT = \ ...@@ -1346,9 +1346,11 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea1.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea1.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/nr_pdcp/nr_pdcp_asn1_utils.h \
...@@ -1758,6 +1760,7 @@ INPUT = \ ...@@ -1758,6 +1760,7 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TimeZoneAndTime.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TimeZoneAndTime.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/Cli.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/Cli.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationResponseParameter.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationResponseParameter.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EapMessage.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SORTransparentContainer.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SORTransparentContainer.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSRegistrationType.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSRegistrationType.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasRequestType.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasRequestType.h \
...@@ -1857,6 +1860,7 @@ INPUT = \ ...@@ -1857,6 +1860,7 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsQualityOfService.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsQualityOfService.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationResponseParameter.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationResponseParameter.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EapMessage.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PdnType.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PdnType.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsMobileIdentity.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsMobileIdentity.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SupportedCodecList.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SupportedCodecList.c \
......
...@@ -3761,6 +3761,7 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, ...@@ -3761,6 +3761,7 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
// For TypeB, ld is the duration of the scheduled PDSCH resources // For TypeB, ld is the duration of the scheduled PDSCH resources
ld = (mappingtype == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols; ld = (mappingtype == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols;
if (ld == 0) ld = 7; //TODO: ACHTUNG!!! Temporary W/A, need to fix the assert somewhere else.
AssertFatal(ld > 2 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld); AssertFatal(ld > 2 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld);
AssertFatal((NrOfSymbols + startSymbol) < 15,"Illegal S+L according to Table 5.1.2.1-1 Spec 38.214 S:%d L:%d\n",startSymbol, NrOfSymbols); AssertFatal((NrOfSymbols + startSymbol) < 15,"Illegal S+L according to Table 5.1.2.1-1 Spec 38.214 S:%d L:%d\n",startSymbol, NrOfSymbols);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "nr_pdcp_security_nea1.h"
#include "nr_pdcp_security_nea2.h" #include "nr_pdcp_security_nea2.h"
#include "nr_pdcp_integrity_nia2.h" #include "nr_pdcp_integrity_nia2.h"
#include "nr_pdcp_integrity_nia1.h" #include "nr_pdcp_integrity_nia1.h"
...@@ -342,14 +343,15 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, ...@@ -342,14 +343,15 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
entity->has_integrity = 0; entity->has_integrity = 0;
if (entity->free_integrity != NULL) { if (entity->free_integrity != NULL) {
entity->free_integrity(entity->integrity_context); entity->free_integrity(entity->integrity_context);
}
entity->free_integrity = NULL; entity->free_integrity = NULL;
} }
}
if (integrity_algorithm != 0 && integrity_algorithm != -1) { if (integrity_algorithm != 0 && integrity_algorithm != -1) {
entity->has_integrity = 1; entity->has_integrity = 1;
if (entity->free_integrity != NULL) { if (entity->free_integrity != NULL) {
entity->free_integrity(entity->integrity_context); entity->free_integrity(entity->integrity_context);
entity->free_integrity = NULL;
} }
if (integrity_algorithm == 2) { if (integrity_algorithm == 2) {
entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key);
...@@ -369,24 +371,31 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, ...@@ -369,24 +371,31 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity,
entity->has_ciphering = NR_PDCP_ENTITY_CIPHERING_OFF; entity->has_ciphering = NR_PDCP_ENTITY_CIPHERING_OFF;
if (entity->free_security != NULL) { if (entity->free_security != NULL) {
entity->free_security(entity->security_context); entity->free_security(entity->security_context);
}
entity->free_security = NULL; entity->free_security = NULL;
} }
}
if (ciphering_algorithm != 0 && ciphering_algorithm != -1) { if (ciphering_algorithm != 0 && ciphering_algorithm != -1) {
if (ciphering_algorithm != 2) {
LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
exit(1);
}
entity->has_ciphering = entity->has_ciphering == NR_PDCP_ENTITY_CIPHERING_ON?NR_PDCP_ENTITY_CIPHERING_ON:NR_PDCP_ENTITY_CIPHERING_SMC; entity->has_ciphering = entity->has_ciphering == NR_PDCP_ENTITY_CIPHERING_ON?NR_PDCP_ENTITY_CIPHERING_ON:NR_PDCP_ENTITY_CIPHERING_SMC;
LOG_I(PDCP, "%s: entity->has_ciphering %d\n", __FUNCTION__, entity->has_ciphering); LOG_I(PDCP, "%s: entity->has_ciphering %d\n", __FUNCTION__, entity->has_ciphering);
if (entity->free_security != NULL) { if (entity->free_security != NULL) {
entity->free_security(entity->security_context); entity->free_security(entity->security_context);
entity->free_security = NULL;
} }
if (ciphering_algorithm == 2) {
entity->security_context = nr_pdcp_security_nea2_init(entity->ciphering_key); entity->security_context = nr_pdcp_security_nea2_init(entity->ciphering_key);
entity->cipher = nr_pdcp_security_nea2_cipher; entity->cipher = nr_pdcp_security_nea2_cipher;
entity->free_security = nr_pdcp_security_nea2_free_security; entity->free_security = nr_pdcp_security_nea2_free_security;
} else if (ciphering_algorithm == 1) {
entity->security_context = nr_pdcp_security_nea1_init(entity->ciphering_key);
entity->cipher = nr_pdcp_security_nea1_cipher;
entity->free_security = nr_pdcp_security_nea1_free_security;
} else {
LOG_E(PDCP, "FATAL: only nea1 and nea2 supported for the moment\n");
exit(1);
}
} }
FNOUT; FNOUT;
} }
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "common/utils/assertions.h"
#include "nr_pdcp_security_nea1.h"
#include <arpa/inet.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "UTIL/OSA/osa_defs.h"
int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out);
void *nr_pdcp_security_nea1_init(unsigned char *ciphering_key)
{
// This is a hack, IMO init, cipher and free functions should be reduced to cipher.
// Test show a ~10% more processing time
return ciphering_key;
}
void nr_pdcp_security_nea1_cipher(void *security_context, unsigned char *buffer, int length, int bearer, int count, int direction)
{
DevAssert(security_context != NULL);
DevAssert(buffer != NULL);
DevAssert(length > 0);
DevAssert(bearer > -1 && bearer < 32);
DevAssert(direction > -1 && direction < 2);
DevAssert(count > -1);
uint8_t *ciphering_key = (uint8_t *)security_context;
uint8_t *out = NULL;
stream_cipher_t stream_cipher;
stream_cipher.key_length = 16;
stream_cipher.count = count;
stream_cipher.bearer = bearer - 1;
stream_cipher.direction = direction;
stream_cipher.key = ciphering_key;
stream_cipher.message = buffer;
/* length in bits */
stream_cipher.blength = length << 3;
// out will be set to stream_cipher.message, no need to free it
stream_encrypt_eea1(&stream_cipher, &out);
memmove(buffer, out, length);
}
void nr_pdcp_security_nea1_free_security(void *security_context)
{
(void)security_context;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _NR_PDCP_SECURITY_NEA1_H_
#define _NR_PDCP_SECURITY_NEA1_H_
void *nr_pdcp_security_nea1_init(unsigned char *ciphering_key);
void nr_pdcp_security_nea1_cipher(void *security_context,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void nr_pdcp_security_nea1_free_security(void *security_context);
#endif /* _NR_PDCP_SECURITY_NEA1_H_ */
...@@ -44,12 +44,25 @@ int encode_fgs_authentication_response(fgs_authentication_response_msg *authenti ...@@ -44,12 +44,25 @@ int encode_fgs_authentication_response(fgs_authentication_response_msg *authenti
int encode_result = 0; int encode_result = 0;
if ((authentication_response->presencemask & FGS_AUTHENTICATION_RESPONSE_AUTH_RESPONSE_PARAM_PRESENT)
== FGS_AUTHENTICATION_RESPONSE_AUTH_RESPONSE_PARAM_PRESENT) {
if ((encode_result = if ((encode_result =
encode_authentication_response_parameter(&authentication_response->authenticationresponseparameter, encode_authentication_response_parameter(&authentication_response->authenticationresponseparameter,
AUTHENTICATION_RESPONSE_PARAMETER_IEI, buffer + encoded, len - encoded)) < 0) //Return in case of error FGS_AUTHENTICATION_RESPONSE_AUTH_RESPONSE_PARAM_IEI, buffer + encoded, len - encoded)) < 0) //Return in case of error
return encode_result; return encode_result;
else else
encoded += encode_result; encoded += encode_result;
}
if ((authentication_response->presencemask & FGS_AUTHENTICATION_RESPONSE_EAP_MESSAGE_PRESENT)
== FGS_AUTHENTICATION_RESPONSE_EAP_MESSAGE_PRESENT) {
if ((encode_result =
encode_eap_message(&authentication_response->eapmessage,
FGS_AUTHENTICATION_RESPONSE_EAP_MESSAGE_IEI, buffer + encoded, len - encoded)) < 0) //Return in case of error
return encode_result;
else
encoded += encode_result;
}
return encoded; return encoded;
} }
......
...@@ -37,11 +37,18 @@ ...@@ -37,11 +37,18 @@
#include "SpareHalfOctet.h" #include "SpareHalfOctet.h"
#include "MessageType.h" #include "MessageType.h"
#include "AuthenticationResponseParameter.h" #include "AuthenticationResponseParameter.h"
#include "EapMessage.h"
#ifndef FGS_AUTHENTICATION_RESPONSE_H_ #ifndef FGS_AUTHENTICATION_RESPONSE_H_
#define FGS_AUTHENTICATION_RESPONSE_H_ #define FGS_AUTHENTICATION_RESPONSE_H_
#define AUTHENTICATION_RESPONSE_PARAMETER_IEI 0x2d # define FGS_AUTHENTICATION_RESPONSE_AUTH_RESPONSE_PARAM_PRESENT (1<<0)
# define FGS_AUTHENTICATION_RESPONSE_EAP_MESSAGE_PRESENT (1<<1)
typedef enum fgs_authentication_response_iei_tag {
FGS_AUTHENTICATION_RESPONSE_AUTH_RESPONSE_PARAM_IEI = 0x2D, /* 0x2D = 45 */
FGS_AUTHENTICATION_RESPONSE_EAP_MESSAGE_IEI = 0x78, /* 0x78 = 120 */
} fgs_authentication_response_iei;
/* /*
* Message name: Identity response * Message name: Identity response
...@@ -56,7 +63,10 @@ typedef struct fgs_authentication_response_msg_tag { ...@@ -56,7 +63,10 @@ typedef struct fgs_authentication_response_msg_tag {
SecurityHeaderType securityheadertype:4; SecurityHeaderType securityheadertype:4;
SpareHalfOctet sparehalfoctet:4; SpareHalfOctet sparehalfoctet:4;
MessageType messagetype; MessageType messagetype;
/* Optional fields */
uint32_t presencemask;
AuthenticationResponseParameter authenticationresponseparameter; AuthenticationResponseParameter authenticationresponseparameter;
EapMessage eapmessage;
} fgs_authentication_response_msg; } fgs_authentication_response_msg;
int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len); int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len);
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "EapMessage.h"
int decode_eap_message(EapMessage *eapmessage, uint8_t iei, uint8_t *buffer, uint32_t len)
{
int decoded = 0;
uint16_t ielen = 0;
int decode_result;
if (iei > 0) {
CHECK_IEI_DECODER(iei, *buffer);
decoded++;
}
ielen = (uint16_t)(*(buffer + decoded) << 8);
ielen |= (uint16_t)(*(buffer + decoded + 1));
decoded += 2;
CHECK_LENGTH_DECODER(len - decoded, ielen);
if ((decode_result = decode_octet_string(&eapmessage->eapMsg, ielen, buffer + decoded, len - decoded)) < 0)
return decode_result;
else
decoded += decode_result;
#if defined (NAS_DEBUG)
dump_eap_message_xml(eapmessage, iei);
#endif
return decoded;
}
int encode_eap_message(EapMessage *eapmessage, uint8_t iei, uint8_t *buffer, uint32_t len)
{
uint16_t ielen = 0;
uint8_t *lenPtr;
uint32_t encoded = 0;
int encode_result;
/* Checking IEI and pointer */
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, EAP_MESSAGE_MINIMUM_LENGTH, len);
#if defined (NAS_DEBUG)
dump_eap_message_xml(eapmessage, iei);
#endif
if (iei > 0) {
*buffer = iei;
encoded++;
}
lenPtr = (buffer + encoded);
encoded += 2;
if ((encode_result = encode_octet_string(&eapmessage->eapMsg, buffer + encoded, len - encoded)) < 0)
return encode_result;
else
encoded += encode_result;
ielen = encoded - 2 - ((iei > 0) ? 1 : 0);
*lenPtr = (uint8_t)((ielen >> 8) & 0xFF);
*(lenPtr + 1) = (uint8_t)(ielen & 0xFF);
return encoded;
}
void dump_eap_message_xml(EapMessage *eapmessage, uint8_t iei)
{
printf("<EAP Message>\n");
dump_octet_string_xml(&eapmessage->eapMsg);
printf("</EAP Message>\n");
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "OctetString.h"
#ifndef EAP_MESSAGE_H_
#define EAP_MESSAGE_H_
#define EAP_MESSAGE_MINIMUM_LENGTH 7
#define EAP_MESSAGE_MAXIMUM_LENGTH 1503
typedef struct EapMessage_tag {
OctetString eapMsg;
} EapMessage;
int encode_eap_message(EapMessage *eapmessage, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_eap_message(EapMessage *eapmessage, uint8_t iei, uint8_t *buffer, uint32_t len);
void dump_eap_message_xml(EapMessage *eapmessage, uint8_t iei);
#endif /* EAP_MESSAGE_H_ */
...@@ -191,6 +191,8 @@ void derive_keys_xor(uint8_t key[16], uint8_t rand[16], uint8_t ck[16], uint8_t ...@@ -191,6 +191,8 @@ void derive_keys_xor(uint8_t key[16], uint8_t rand[16], uint8_t ck[16], uint8_t
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
res[i] = key[i] ^ rand[i]; res[i] = key[i] ^ rand[i];
} }
printf("key: "); for (int i = 0; i < 16; ++i) printf("%02x", key[i]); printf("\n");
printf("rand: "); for (int i = 0; i < 16; ++i) printf("%02x", rand[i]); printf("\n");
printf("res: "); for (int i = 0; i < 16; ++i) printf("%02x", res[i]); printf("\n"); printf("res: "); for (int i = 0; i < 16; ++i) printf("%02x", res[i]); printf("\n");
// AK // AK
...@@ -294,6 +296,71 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[ ...@@ -294,6 +296,71 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[
kdf(key, data, 32, kausf); kdf(key, data, 32, kausf);
} }
void derive_mk(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t *mk, uicc_t *uicc) {
uint8_t S[256]={0};
uint8_t key[32];
printf(">>> %s\n", __FUNCTION__);
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); //KEY
printf("Key: "); for (int i = 0; i < 32; ++i) printf("%02x", key[i]); printf("\n");
printf("sqn: "); for (int i = 0; i < 6; ++i) printf("%02x", sqn[i]); printf("\n");
S[0] = 0x20;
printf("%s, nmc_sz=%d\n", uicc->imsiStr, uicc->nmc_size);
servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size);
int netNamesize = strlen((char*)S+1);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
for (int i = 0; i < 6; i++) {
S[3 + netNamesize + i] = sqn[i];
}
S[9 + netNamesize] = 0x00;
S[10 + netNamesize] = 0x06;
printf("Key: "); for (int i = 0; i < 11 + netNamesize; ++i) printf("%02x", S[i]); printf("\n");
uint8_t ck_ik_[32]; // CK' + IK'
byte_array_t data = {.buf = S, .len = 11 + netNamesize};
kdf(key, data, 32, ck_ik_);
printf("ck': "); for (int i = 0; i < 16; ++i) printf("%02x", ck_ik_[i]); printf("\n");
printf("ik': "); for (int i = 16; i < 32; ++i) printf("%02x", ck_ik_[i]); printf("\n");
memcpy(&key[0], ck_ik_ + 16, 16);
memcpy(&key[16], ck_ik_, 16); //KEY
printf("Key2: "); for (int i = 0; i < 32; ++i) printf("%02x", key[i]); printf("\n");
// PRF' calculation (RFC 5448 cl. 3.4.1)
int outBitsNum = 1664; // bits
int blockSize = 256; // bits
int prfIters = (outBitsNum + blockSize - 1) / blockSize; // 7 iters
int mkLen = 0; // resulting MK length
uint8_t out[32];
for (int i = 0; i < prfIters; i++) {
int sLen = 0; // length of string for key derivation
if (i != 0) {
memcpy(S, out, 32);
sLen += 32;
}
memcpy(S + sLen, "EAP-AKA'", 8);
sLen += 8;
memcpy(S + sLen, uicc->imsiStr, strlen(uicc->imsiStr));
sLen += strlen(uicc->imsiStr);
S[sLen] = (uint8_t)(i + 1);
sLen++;
printf("S: "); for (int j = 0; j < sLen; ++j) printf("%02x", S[j]); printf("\n");
byte_array_t data = {.buf = S, .len = sLen};
kdf(key, data, 32, out);
for (int j = 0; j < 32; j++) {
mk[mkLen + j] = out[j];
}
mkLen += 32;
}
}
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) {
uint8_t S[100]={0}; uint8_t S[100]={0};
S[0] = 0x6C; //FC S[0] = 0x6C; //FC
...@@ -375,6 +442,113 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ ...@@ -375,6 +442,113 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){
printf("\n"); printf("\n");
} }
// Hacky approach to detect if eapMessage is present in authentication_Request,
// then the auth type is EAP-AKA'.
// Returns the offset of eapMsg in eapMessage if present, zero otherwise.
int detect_eap_msg(uint8_t *buf)
{
int offset = -1;
// suppose here that 'abba' is 2 octets length in authentication_Request
int mandatory_fields_length = 7;
if (buf[mandatory_fields_length] == 0x21) { // rand field is present
offset = 0;
} else if (buf[mandatory_fields_length] == 0x20) { // autn field is present
offset = 0;
} else if (buf[mandatory_fields_length] == 0x78) {
// if rand or autn is present, more likely, the auth type is 5G-AKA,
// otherwise eapMessage should be present
offset = mandatory_fields_length + 3;
}
AssertFatal (offset != -1, "Failed, neither 5G-AKA nor EAP-AKA' detected\n");
return offset;
}
int parse_eap_msg_len(uint8_t *buf)
{
int len_offset = 2; // length offset in eapMsg
int len = ((int)buf[len_offset] << 8) + ((int)buf[len_offset + 1]);
return len;
}
void parse_eap_msg_rand(uint8_t *buf, uint8_t rand[16])
{
int mandatory_fields_length = 8; // offset for beginning of attributes in eapMsg
int eap_msg_len = parse_eap_msg_len(buf);
int off = mandatory_fields_length;
while (buf[off] != 0x01) {
off += buf[off + 1] * 4;
AssertFatal (off < eap_msg_len, "Failed, no RAND attribute found in eapMsg\n");
}
off += 4;
for (int i = 0; i < 16; i++) {
rand[i] = buf[off + i];
}
}
void parse_eap_msg_autn(uint8_t *buf, uint8_t autn[6])
{
int mandatory_fields_length = 8; // offset for beginning of attributes in eapMsg
int eap_msg_len = parse_eap_msg_len(buf);
int off = mandatory_fields_length;
while (buf[off] != 0x02) {
off += buf[off + 1] * 4;
AssertFatal (off < eap_msg_len, "Failed, no AUTN attribute found in eapMsg\n");
}
off += 4;
for (int i = 0; i < 6; i++) {
autn[i] = buf[off + i];
}
}
void make_eap_msg(int Mod_id, OctetString *msg)
{
uint8_t tmpl[] = { 0x02, 0x00, // code & id
0x00 , 0x00, // len
0x32, 0x01, 0x00, 0x00, // type & subtype & reserved
/* res attribute */
0x03, 0x05, // attributeType & len
0x00, 0x80, // reslen
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // res (to be set)
/* mac attribute */
0x0B, 0x05, 0x00, 0x00, // attributeType & len & reserved
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mac (placeholder for now, to be calculated)
};
int len = sizeof(tmpl);
uint8_t *lenPtr = &tmpl[2];
uint8_t *resPtr = &tmpl[8 + 4];
uint8_t *macPtr = &tmpl[8 + (4 + 16) + 4];
// set len field
lenPtr[0] = (uint8_t)((len >> 8) & 0xFF);
lenPtr[1] = (uint8_t)(len & 0xFF);
// set res attribute
memcpy(resPtr, ue_security_key[Mod_id]->res, 16);
// calc and set mac attribute
uint8_t *mk = ue_security_key[Mod_id]->mk; // EAP-AKA' master-key
uint8_t kaut[32];
uint8_t mac[32];
memcpy(kaut, mk + 16, 32); // RFC 5448 cl. 3.3 K_aut to be used for computing MAC
byte_array_t data = {.buf = tmpl, .len = len};
kdf(kaut, data, 16, mac);
memcpy(macPtr, mac, 16);
msg->length = len;
msg->value = calloc(1, msg->length);
memcpy(msg->value, tmpl, msg->length);
}
void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) { void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) {
LOG_FUNC_IN; LOG_FUNC_IN;
uint8_t ak[6]; uint8_t ak[6];
...@@ -388,20 +562,43 @@ void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) { ...@@ -388,20 +562,43 @@ void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) {
// Allocate new memory // Allocate new memory
ue_security_key[Mod_id]=(ue_sa_security_key_t *)calloc(1,sizeof(ue_sa_security_key_t)); ue_security_key[Mod_id]=(ue_sa_security_key_t *)calloc(1,sizeof(ue_sa_security_key_t));
} }
uint8_t *mk = ue_security_key[Mod_id]->mk; // EAP-AKA' master-key
uint8_t *kausf = ue_security_key[Mod_id]->kausf; uint8_t *kausf = ue_security_key[Mod_id]->kausf;
uint8_t *kseaf = ue_security_key[Mod_id]->kseaf; uint8_t *kseaf = ue_security_key[Mod_id]->kseaf;
uint8_t *kamf = ue_security_key[Mod_id]->kamf; uint8_t *kamf = ue_security_key[Mod_id]->kamf;
uint8_t *knas_int = ue_security_key[Mod_id]->knas_int; uint8_t *knas_int = ue_security_key[Mod_id]->knas_int;
uint8_t *knas_enc = ue_security_key[Mod_id]->knas_enc; uint8_t *knas_enc = ue_security_key[Mod_id]->knas_enc;
uint8_t *output = ue_security_key[Mod_id]->res; uint8_t *xres = ue_security_key[Mod_id]->res;
uint8_t *rand = ue_security_key[Mod_id]->rand; uint8_t *rand = ue_security_key[Mod_id]->rand;
uint8_t *kgnb = ue_security_key[Mod_id]->kgnb; uint8_t *kgnb = ue_security_key[Mod_id]->kgnb;
// get RAND for authentication request int eap_msg_offset = detect_eap_msg(buf);
for(int index = 0; index < 16;index++){ int eap_msg_len = 0;
if (eap_msg_offset) {
eap_msg_len = parse_eap_msg_len(&buf[eap_msg_offset]);
}
printf("eap_msg_offset: %d eap_msg_len: %d\n", eap_msg_offset, eap_msg_len);
if (!eap_msg_offset) {
// get RAND from authentication request, it is located by 8 octets offset,
// suppose here that 'abba' is 2 octets length
for (int index = 0; index < 16;index++){
rand[index] = buf[8+index]; rand[index] = buf[8+index];
} }
// get AUTN from authentication request, it is located by 26 octets offset,
// suppose here that 'abba' is 2 octets length
for(int index = 0; index < 6; index++){
sqn[index] = buf[26+index];
}
} else {
parse_eap_msg_rand(&buf[eap_msg_offset], rand);
parse_eap_msg_autn(&buf[eap_msg_offset], sqn);
}
uint8_t resTemp[16]; uint8_t resTemp[16];
uint8_t ck[16], ik[16]; uint8_t ck[16], ik[16];
...@@ -411,24 +608,32 @@ void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) { ...@@ -411,24 +608,32 @@ void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) {
derive_keys_xor(uicc->key, rand, ck, ik, ak, resTemp); derive_keys_xor(uicc->key, rand, ck, ik, ak, resTemp);
#endif #endif
transferRES(ck, ik, resTemp, rand, output, uicc); if (!eap_msg_offset) {
transferRES(ck, ik, resTemp, rand, xres, uicc); // calc XRES_Star
for(int index = 0; index < 6; index++){ derive_kausf(ck, ik, sqn, kausf, uicc);
sqn[index] = buf[26+index]; } else {
memcpy(xres, resTemp, 16); // no XRES_Star in EAP-AKA'
derive_mk(ck, ik, sqn, mk, uicc);
memcpy(kausf, mk + 144, 32); // KAUSF is EMSK in RFC 5448 cl. 3.3
} }
derive_kausf(ck, ik, sqn, kausf, uicc);
derive_kseaf(kausf, kseaf, uicc); derive_kseaf(kausf, kseaf, uicc);
derive_kamf(kseaf, kamf, 0x0000, uicc); derive_kamf(kseaf, kamf, 0x0000, uicc);
derive_knas(0x02, _nas_integrity_algo, kamf, knas_int); derive_knas(0x02, _nas_integrity_algo, kamf, knas_int); // _nas_integrity_algo is unknown here
derive_knas(0x01, _nas_ciphering_algo, kamf, knas_enc); derive_knas(0x01, _nas_ciphering_algo, kamf, knas_enc); // _nas_integrity_algo is unknown here
derive_kgnb(kamf,0,kgnb); derive_kgnb(kamf, 0, kgnb);
printf("xres:"); for(int i = 0; i < 16; i++) printf("%02x", output[i]); printf("\n"); printf("xres:"); for(int i = 0; i < 16; i++) printf("%02x", xres[i]); printf("\n");
printf("mk:"); for(int i = 0; i < 48; i++) printf("%02x", mk[i]); printf("\n");
printf("kausf:"); for(int i = 0; i < 32; i++) printf("%02x", kausf[i]); printf("\n"); printf("kausf:"); for(int i = 0; i < 32; i++) printf("%02x", kausf[i]); printf("\n");
printf("kseaf:"); for(int i = 0; i < 32; i++) printf("%02x", kseaf[i]); printf("\n"); printf("kseaf:"); for(int i = 0; i < 32; i++) printf("%02x", kseaf[i]); printf("\n");
printf("kamf:"); for(int i = 0; i < 32; i++) printf("%02x", kamf[i]); printf("\n"); printf("kamf:"); for(int i = 0; i < 32; i++) printf("%02x", kamf[i]); printf("\n");
printf("knas_int:"); for(int i = 0; i < 16; i++) printf("%02x", knas_int[i]); printf("\n"); /* printf("knas_int:"); for(int i = 0; i < 16; i++) printf("%02x", knas_int[i]); printf("\n"); */
/* printf("knas_enc:"); for(int i = 0; i < 16; i++) printf("%02x", knas_enc[i]); printf("\n"); */
printf("rand:"); for(int i = 0; i < 16; i++) printf("%02x", rand[i]); printf("\n");
printf("kgnb:"); for(int i = 0; i < 32; i++) printf("%02x", kgnb[i]); printf("\n");
LOG_FUNC_OUT; LOG_FUNC_OUT;
} }
...@@ -649,11 +854,9 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype ...@@ -649,11 +854,9 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){ static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){
LOG_FUNC_IN; LOG_FUNC_IN;
int eap_msg_offset = detect_eap_msg(buf);
derive_ue_keys(Mod_id,buf,uicc); derive_ue_keys(Mod_id,buf,uicc);
OctetString res;
res.length = 16;
res.value = calloc(1,16);
memcpy(res.value,ue_security_key[Mod_id]->res,16);
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg; fgs_nas_message_t nas_msg;
...@@ -675,8 +878,24 @@ static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg, ...@@ -675,8 +878,24 @@ static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg,
size += 1; size += 1;
//set response parameter //set response parameter
if (!eap_msg_offset) {
OctetString res;
res.length = 16;
res.value = calloc(1,16);
memcpy(res.value,ue_security_key[Mod_id]->res,16);
mm_msg->fgs_auth_response.presencemask |= FGS_AUTHENTICATION_RESPONSE_AUTH_RESPONSE_PARAM_PRESENT;
mm_msg->fgs_auth_response.authenticationresponseparameter.res = res; mm_msg->fgs_auth_response.authenticationresponseparameter.res = res;
size += 18; size += 18;
} else {
OctetString eapMsg;
make_eap_msg(Mod_id, &eapMsg);
mm_msg->fgs_auth_response.presencemask |= FGS_AUTHENTICATION_RESPONSE_EAP_MESSAGE_PRESENT;
mm_msg->fgs_auth_response.eapmessage.eapMsg = eapMsg;
size += 3 + eapMsg.length;
}
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
...@@ -694,28 +913,28 @@ int nas_itti_kgnb_refresh_req(const uint8_t kgnb[32], int instance){ ...@@ -694,28 +913,28 @@ int nas_itti_kgnb_refresh_req(const uint8_t kgnb[32], int instance){
return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
} }
static int addImeisv(int Mod_id,MM_msg *mm_msg) static int addImeisv(int Mod_id, FGSMobileIdentity *fgsmobileidentity)
{ {
int i=0; int i=0;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV; fgsmobileidentity->imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac01 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac01 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac02 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac02 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac03 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac03 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac04 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac04 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac05 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac05 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac06 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac06 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac07 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac07 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digittac08 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digittac08 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit09 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digit09 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit10 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digit10 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit11 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digit11 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit12 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digit12 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit13 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digit13 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit14 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digit14 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitsv1 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digitsv1 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitsv2 = getImeisvDigit(Mod_id,i++); fgsmobileidentity->imeisv.digitsv2 = getImeisvDigit(Mod_id,i++);
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.spare = 0x0f; fgsmobileidentity->imeisv.spare = 0x0f;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.oddeven = 1; fgsmobileidentity->imeisv.oddeven = 1;
return 19; return 19;
} }
...@@ -756,7 +975,7 @@ static void generateSecurityModeComplete(int Mod_id,as_nas_info_t *initialNasMsg ...@@ -756,7 +975,7 @@ static void generateSecurityModeComplete(int Mod_id,as_nas_info_t *initialNasMsg
/* Workaround fix for the issue in TTCN till imeisv is supported by TTCN */ /* Workaround fix for the issue in TTCN till imeisv is supported by TTCN */
if(0) if(0)
{ {
size += addImeisv(Mod_id, mm_msg); size += addImeisv(Mod_id, &mm_msg->fgs_security_mode_complete.fgsmobileidentity);
} }
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf; mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf;
...@@ -1219,12 +1438,15 @@ void generateServiceRequestInner(as_nas_info_t *initialNasMsg, int Mod_id) { ...@@ -1219,12 +1438,15 @@ void generateServiceRequestInner(as_nas_info_t *initialNasMsg, int Mod_id) {
mm_msg->fgs_service_request.naskeysetidentifier.naskeysetidentifier = 0; mm_msg->fgs_service_request.naskeysetidentifier.naskeysetidentifier = 0;
size += 1; size += 1;
size += addImeisv(Mod_id, mm_msg); size += addImeisv(Mod_id, &mm_msg->fgs_service_request.fgsmobileidentity);
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
// HACK: TTCN decrypts the piggybacked msg. Thus, need to encrypt it using expected NAS Count == 2
_ul_nas_count = 2;
_encrypt_nas_msg(Mod_id, _ul_nas_count, initialNasMsg->data, initialNasMsg->length);
} }
void generateServiceRequest(as_nas_info_t *initialNasMsg, int Mod_id) { void generateServiceRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
...@@ -1250,7 +1472,7 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, int Mod_id) { ...@@ -1250,7 +1472,7 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
mm_msg->fgs_service_request.naskeysetidentifier.naskeysetidentifier = 0; mm_msg->fgs_service_request.naskeysetidentifier.naskeysetidentifier = 0;
size += 1; size += 1;
size += addImeisv(Mod_id, mm_msg); size += addImeisv(Mod_id, &mm_msg->fgs_service_request.fgsmobileidentity);
as_nas_info_t serviceRequestInnerNasMsg; as_nas_info_t serviceRequestInnerNasMsg;
generateServiceRequestInner(&serviceRequestInnerNasMsg, Mod_id); generateServiceRequestInner(&serviceRequestInnerNasMsg, Mod_id);
...@@ -1264,8 +1486,8 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, int Mod_id) { ...@@ -1264,8 +1486,8 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
// HACK: TTCN decrypts the piggybacked msg. Thus, need to encrypt it using expected NAS Count == 2 // HACK: TTCN decrypts the piggybacked msg. Thus, need to encrypt it using expected NAS Count == 2
_ul_nas_count = 2; /* _ul_nas_count = 2; */
_encrypt_nas_msg(Mod_id, _ul_nas_count, initialNasMsg->data + 11, initialNasMsg->length - 11); /* _encrypt_nas_msg(Mod_id, _ul_nas_count, initialNasMsg->data + 11, initialNasMsg->length - 11); */
} }
uint8_t get_msg_type(uint8_t *pdu_buffer, uint32_t length) { uint8_t get_msg_type(uint8_t *pdu_buffer, uint32_t length) {
...@@ -1476,6 +1698,8 @@ void *nas_nrue_task(void *args_p) ...@@ -1476,6 +1698,8 @@ void *nas_nrue_task(void *args_p)
derive_knas(0x02, _nas_integrity_algo, ue_security_key[Mod_id]->kamf, ue_security_key[Mod_id]->knas_int); derive_knas(0x02, _nas_integrity_algo, ue_security_key[Mod_id]->kamf, ue_security_key[Mod_id]->knas_int);
derive_knas(0x01, _nas_ciphering_algo, ue_security_key[Mod_id]->kamf, ue_security_key[Mod_id]->knas_enc); derive_knas(0x01, _nas_ciphering_algo, ue_security_key[Mod_id]->kamf, ue_security_key[Mod_id]->knas_enc);
printf("knas_int:"); for(int i = 0; i < 16; i++) printf("%02x", ue_security_key[Mod_id]->knas_int[i]); printf("\n");
printf("knas_enc:"); for(int i = 0; i < 16; i++) printf("%02x", ue_security_key[Mod_id]->knas_enc[i]); printf("\n");
nas_itti_kgnb_refresh_req(ue_security_key[Mod_id]->kgnb, instance); nas_itti_kgnb_refresh_req(ue_security_key[Mod_id]->kgnb, instance);
generateSecurityModeComplete(Mod_id,&initialNasMsg); generateSecurityModeComplete(Mod_id,&initialNasMsg);
......
...@@ -103,6 +103,9 @@ ...@@ -103,6 +103,9 @@
/* Security Key for SA UE */ /* Security Key for SA UE */
typedef struct { typedef struct {
uint8_t mk[256]; // EAP-AKA' master-key.
// PRF' produces as many bits of output as is needed,
// lets define 256 bytes MK.
uint8_t kausf[32]; uint8_t kausf[32];
uint8_t kseaf[32]; uint8_t kseaf[32];
uint8_t kamf[32]; uint8_t kamf[32];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment