diff --git a/openair-cn/NAS/EURECOM-NAS/src/Makefile b/openair-cn/NAS/EURECOM-NAS/src/Makefile index 578f4078a6..fdae0fcc9d 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/Makefile +++ b/openair-cn/NAS/EURECOM-NAS/src/Makefile @@ -19,7 +19,7 @@ ifeq ($(TARGET), UEprocess) SRCS = UEprocess.c nas_network.c nas_parser.c nas_proc.c nas_user.c endif -LIBS = -lutil -lapi -lEMMmsg -lESMmsg -lEMMsap -lESMsap -lies -lrt -lnettle -lcrypto +LIBS = -lutil -lapi -lEMMmsg -lESMmsg -lEMMsap -lESMsap -lies -lrt -lnettle -lcrypto -lm INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(USERAPIDIR) -I$(NETAPIDIR) \ -I$(EMMDIR) -I$(EMMMSGDIR) -I$(EMMSAPDIR) \ -I$(ESMDIR) -I$(ESMMSGDIR) -I$(ESMSAPDIR) \ diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/Makefile b/openair-cn/NAS/EURECOM-NAS/src/api/Makefile index dd715d7a79..792b804f06 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/api/Makefile +++ b/openair-cn/NAS/EURECOM-NAS/src/api/Makefile @@ -26,6 +26,7 @@ all: @$(MAKE) $(TARGETS) $(TARGET).a: $(OBJS) + @echo target.a @$(RM) $@ @$(AR) $(ARFLAGS) $@ $^ @echo Replacing $@ to $(LIBPROCESS) diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c index 0d591b8b99..66514a7f4b 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c +++ b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c @@ -165,6 +165,35 @@ nas_message_encrypt( memcpy(outbuf, inbuf, length); } +#ifdef NAS_MME + /* TS 124.301, section 4.4.3.1 + * The NAS sequence number part of the NAS COUNT shall be + * exchanged between the UE and the MME as part of the + * NAS signalling. After each new or retransmitted outbound + * security protected NAS message, the sender shall increase + * the NAS COUNT number by one. Specifically, on the sender + * side, the NAS sequence number shall be increased by one, + * and if the result is zero (due to wrap around), the NAS + * overflow counter shall also be incremented by one (see + * subclause 4.4.3.5). + */ + emm_security_context->dl_count.seq_num += 1; + if ( ! emm_security_context->dl_count.seq_num) { + emm_security_context->dl_count.overflow += 1; + } + LOG_TRACE(DEBUG, + "Incremented emm_security_context.dl_count.seq_num -> %u", + emm_security_context->dl_count.seq_num); +#else + emm_security_context->ul_count.seq_num += 1; + if ( ! emm_security_context->ul_count.seq_num) { + emm_security_context->ul_count.overflow += 1; + } + LOG_TRACE(DEBUG, + "Incremented emm_security_context.ul_count.seq_num -> %u", + emm_security_context->ul_count.seq_num); +#endif + if (bytes < 0) { LOG_FUNC_RETURN (bytes); } @@ -413,16 +442,26 @@ int nas_message_encode( * overflow counter shall also be incremented by one (see * subclause 4.4.3.5). */ + emm_security_context->dl_count.seq_num += 1; if ( ! emm_security_context->dl_count.seq_num) { emm_security_context->dl_count.overflow += 1; } + LOG_TRACE(DEBUG, + "Incremented emm_security_context.dl_count.seq_num -> %u", + emm_security_context->dl_count.seq_num); #else emm_security_context->ul_count.seq_num += 1; if ( ! emm_security_context->ul_count.seq_num) { emm_security_context->ul_count.overflow += 1; } + LOG_TRACE(DEBUG, + "Incremented emm_security_context.ul_count.seq_num -> %u", + emm_security_context->ul_count.seq_num); #endif + } else { + LOG_TRACE(DEBUG, + "Did not increment emm_security_context.dl_count.seq_num because no security context"); } } #if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE))) @@ -895,10 +934,39 @@ static UInt32_t _nas_message_get_mac( switch (emm_security_context->selected_algorithms.integrity) { - case NAS_SECURITY_ALGORITHMS_EIA1: - LOG_TRACE(ERROR, - "EIA1_128_ALG_ID not implemented"); - break; + case NAS_SECURITY_ALGORITHMS_EIA1: { + UInt8_t mac[4]; + nas_stream_cipher_t stream_cipher; + UInt32_t count; + UInt32_t *mac32; + + 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); + } + stream_cipher.key = emm_security_context->knas_int.value; + stream_cipher.key_length = AUTH_KNAS_INT_SIZE; + stream_cipher.count = count; + stream_cipher.bearer = 0x00; //33.401 section 8.1.1 + stream_cipher.direction = direction; + stream_cipher.message = buffer; + /* length in bits */ + stream_cipher.blength = length << 3; + + nas_stream_encrypt_eia1( + &stream_cipher, + mac); + LOG_TRACE(DEBUG, + "NAS_SECURITY_ALGORITHMS_EIA1 returned MAC %x.%x.%x.%x for length %d direction %d, count %d", + mac[0], mac[1], mac[2],mac[3], length, direction, count); + mac32 = (UInt32_t*)&mac; + LOG_FUNC_RETURN (*mac32); + }break; case NAS_SECURITY_ALGORITHMS_EIA2: { UInt8_t mac[4]; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c index d04f6f221a..75db56245d 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c @@ -1069,12 +1069,12 @@ static int _security_select_algorithms( /* TODO work with loaded preferences from config file */ - if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA2)) { - LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA0"); - *mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA0; - } else if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA1)) { + if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA1)) { LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA1"); *mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA1; + } else if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA2)) { + LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA2"); + *mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA2; } else if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA0)) { LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA0"); *mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA0; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/msg/ServiceRequest.c b/openair-cn/NAS/EURECOM-NAS/src/emm/msg/ServiceRequest.c index 564a40619f..64295d4067 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/msg/ServiceRequest.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/msg/ServiceRequest.c @@ -13,21 +13,22 @@ int decode_service_request(service_request_msg *service_request, uint8_t *buffer uint32_t decoded = 0; int decoded_result = 0; + LOG_FUNC_IN; // Check if we got a NULL pointer and if buffer length is >= minimum length expected for the message. CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, SERVICE_REQUEST_MINIMUM_LENGTH, len); /* Decoding mandatory fields */ if ((decoded_result = decode_ksi_and_sequence_number(&service_request->ksiandsequencenumber, 0, buffer + decoded, len - decoded)) < 0) - return decoded_result; + LOG_FUNC_RETURN(decoded_result); else decoded += decoded_result; if ((decoded_result = decode_short_mac(&service_request->messageauthenticationcode, 0, buffer + decoded, len - decoded)) < 0) - return decoded_result; + LOG_FUNC_RETURN(decoded_result); else decoded += decoded_result; - return decoded; + LOG_FUNC_RETURN(decoded); } int encode_service_request(service_request_msg *service_request, uint8_t *buffer, uint32_t len) @@ -35,23 +36,24 @@ int encode_service_request(service_request_msg *service_request, uint8_t *buffer int encoded = 0; int encode_result = 0; + LOG_FUNC_IN; /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, SERVICE_REQUEST_MINIMUM_LENGTH, len); if ((encode_result = encode_ksi_and_sequence_number(&service_request->ksiandsequencenumber, 0, buffer + encoded, len - encoded)) < 0) //Return in case of error - return encode_result; + LOG_FUNC_RETURN(encode_result); else encoded += encode_result; if ((encode_result = encode_short_mac(&service_request->messageauthenticationcode, 0, buffer + encoded, len - encoded)) < 0) //Return in case of error - return encode_result; + LOG_FUNC_RETURN(encode_result); else encoded += encode_result; - return encoded; + LOG_FUNC_RETURN(encoded); } diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c index 1de8ef1255..d056d1d769 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c @@ -1391,7 +1391,16 @@ static int _emm_as_data_req(const emm_as_data_t *msg, #else emm_security_context = _emm_data.security; #endif - + if (emm_security_context) { +#ifdef NAS_MME + nas_msg.header.sequence_number = emm_security_context->dl_count.seq_num; +#else + nas_msg.header.sequence_number = emm_security_context->ul_count.seq_num; +#endif + LOG_TRACE(DEBUG, + "Set nas_msg.header.sequence_number -> %u", + nas_msg.header.sequence_number); + } if (!is_encoded) { /* Encode the NAS information message */ bytes = _emm_as_encode(&as_msg->nasMsg, @@ -1480,6 +1489,16 @@ static int _emm_as_status_ind(const emm_as_status_t *msg, #else emm_security_context = _emm_data.security; #endif + if (emm_security_context) { +#ifdef NAS_MME + nas_msg.header.sequence_number = emm_security_context->dl_count.seq_num; +#else + nas_msg.header.sequence_number = emm_security_context->ul_count.seq_num; +#endif + LOG_TRACE(DEBUG, + "Set nas_msg.header.sequence_number -> %u", + nas_msg.header.sequence_number); + } /* Encode the NAS information message */ int bytes = _emm_as_encode( &as_msg->nasMsg, @@ -1795,6 +1814,12 @@ static int _emm_as_security_req(const emm_as_security_t *msg, #endif if (emm_ctx) { emm_security_context = emm_ctx->security; + if (emm_security_context) { + nas_msg.header.sequence_number = emm_security_context->dl_count.seq_num; + LOG_TRACE(DEBUG, + "Set nas_msg.header.sequence_number -> %u", + nas_msg.header.sequence_number); + } } /* Encode the NAS security message */ @@ -1874,6 +1899,10 @@ static int _emm_as_security_rej(const emm_as_security_t *msg, #endif if (emm_ctx) { emm_security_context = emm_ctx->security; + nas_msg.header.sequence_number = emm_security_context->dl_count.seq_num; + LOG_TRACE(DEBUG, + "Set nas_msg.header.sequence_number -> %u", + nas_msg.header.sequence_number); } /* Encode the NAS security message */ @@ -1966,6 +1995,10 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, LOG_TRACE(DEBUG, "EMMAS-SAP - NAS UL COUNT %8x", as_msg->nas_ul_count); } + nas_msg.header.sequence_number = emm_security_context->dl_count.seq_num; + LOG_TRACE(DEBUG, + "Set nas_msg.header.sequence_number -> %u", + nas_msg.header.sequence_number); } /* Encode the initial NAS information message */ @@ -2055,6 +2088,10 @@ static int _emm_as_establish_rej(const emm_as_establish_t *msg, #endif if (emm_ctx) { emm_security_context = emm_ctx->security; + nas_msg.header.sequence_number = emm_security_context->dl_count.seq_num; + LOG_TRACE(DEBUG, + "Set nas_msg.header.sequence_number -> %u", + nas_msg.header.sequence_number); } /* Encode the initial NAS information message */ int bytes = _emm_as_encode( diff --git a/openair-cn/NAS/EURECOM-NAS/tools/Makefile b/openair-cn/NAS/EURECOM-NAS/tools/Makefile index 97bf016763..341f9a9c10 100644 --- a/openair-cn/NAS/EURECOM-NAS/tools/Makefile +++ b/openair-cn/NAS/EURECOM-NAS/tools/Makefile @@ -28,13 +28,13 @@ all: $(TARGETS) $(CC) $(CFLAGS) -c $< -o $@ $(USIM_TARGET): $(USIM_OBJ) $(LIBSUTIL) - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SECUDIR)/*.o -lnettle -lcrypto + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SECUDIR)/*.o -lnettle -lcrypto -lm @echo Replacing $@ to $(BINDIR) @$(RM) $(BINDIR)/$@ @$(CP) $@ $(BINDIR) $(UE_TARGET): $(UE_OBJ) $(LIBSUTIL) - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SECUDIR)/*.o -lnettle -lcrypto + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SECUDIR)/*.o -lnettle -lcrypto -lm @echo Replacing $@ to $(BINDIR) @$(RM) $(BINDIR)/$@ @$(CP) $@ $(BINDIR) diff --git a/openair-cn/NAS/EURECOM-NAS/tools/usim_data.c b/openair-cn/NAS/EURECOM-NAS/tools/usim_data.c index 853da1ac82..7ccd200821 100644 --- a/openair-cn/NAS/EURECOM-NAS/tools/usim_data.c +++ b/openair-cn/NAS/EURECOM-NAS/tools/usim_data.c @@ -34,7 +34,7 @@ Description Implements the utility used to generate data stored in the #define KSI USIM_KSI_NOT_AVAILABLE #define KSI_ASME USIM_KSI_NOT_AVAILABLE -#define INT_ALGO USIM_INT_EIA0 +#define INT_ALGO USIM_INT_EIA1 #define ENC_ALGO USIM_ENC_EEA0 #define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO)