From f83c06cec28092cb1e00d9cb57ede46d088c282e Mon Sep 17 00:00:00 2001 From: garciay Date: Fri, 11 Jul 2025 09:23:41 +0200 Subject: [PATCH 1/5] Bug fixed in Abstract_Socket patch: missing set_ip_proto/get_ip_proto --- .../Abstract_Socket.cc.patch | 669 +++--------------- .../Abstract_Socket.hh.patch | 140 +--- 2 files changed, 138 insertions(+), 671 deletions(-) diff --git a/ttcn/patch_abstract_socket/Abstract_Socket.cc.patch b/ttcn/patch_abstract_socket/Abstract_Socket.cc.patch index 6389855..55f334a 100644 --- a/ttcn/patch_abstract_socket/Abstract_Socket.cc.patch +++ b/ttcn/patch_abstract_socket/Abstract_Socket.cc.patch @@ -1,580 +1,117 @@ -diff --git a/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.cc b/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.cc -old mode 100644 -new mode 100755 -index 910c13e..9d93bed ---- a/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.cc -+++ b/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.cc -@@ -1,28 +1,17 @@ - /****************************************************************************** --* Copyright (c) 2000-2019 Ericsson Telecom AB --* All rights reserved. This program and the accompanying materials --* are made available under the terms of the Eclipse Public License v2.0 --* which accompanies this distribution, and is available at --* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html --* --* Contributors: --* Zoltan Bibo - initial implementation and initial documentation --* Gergely Futo --* Oliver Ferenc Czerman --* Balasko Jeno --* Zoltan Bibo --* Eduard Czimbalmos --* Kulcsár Endre --* Gabor Szalai --* Jozsef Gyurusi --* Csöndes Tibor --* Zoltan Jasz --******************************************************************************/ -+ * Copyright (c) 2000-2025 Ericsson Telecom AB -+ * All rights reserved. This program and the accompanying materials -+ * are made available under the terms of the Eclipse Public License v2.0 -+ * which accompanies this distribution, and is available at -+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html -+ ******************************************************************************/ - // - // File: Abstract_Socket.cc - // Description: Abstract_Socket implementation file --// Rev: R9B -+// Rev: - // Prodnr: CNL 113 384 -+// Updated: 2012-08-07 -+// Contact: http://ttcn.ericsson.se - // - - #include "Abstract_Socket.hh" -@@ -254,20 +243,16 @@ bool Abstract_Socket::parameter_set(const char *parameter_name, - Free(local_host_name); - local_host_name = mcopystr(parameter_value); - } else if(strcmp(parameter_name, remote_port_name()) == 0){ -- int a; -- if (sscanf(parameter_value, "%d", &a)!=1) log_error("Invalid input as port number given: %s", parameter_value); -- if (a>65535 || a<0){ log_error("Port number must be between 0 and 65535, %d is given", remote_port_number);} -- else {remote_port_number=a;} -+ if (sscanf(parameter_value, "%d", &remote_port_number)!=1) log_error("Invalid input as port number given: %s", parameter_value); -+ if (remote_port_number>65535 || remote_port_number<0) log_error("Port number must be between 0 and 65535, %d is given", remote_port_number); - } else if(strcmp(parameter_name, ai_family_name()) == 0){ - if (strcasecmp(parameter_value,"IPv6")==0 || strcasecmp(parameter_value,"AF_INET6")==0) ai_family = AF_INET6; - else if (strcasecmp(parameter_value,"IPv4")==0 || strcasecmp(parameter_value,"AF_INET")==0) ai_family = AF_INET; - else if (strcasecmp(parameter_value,"UNSPEC")==0 || strcasecmp(parameter_value,"AF_UNSPEC")==0) ai_family = AF_UNSPEC; - else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ai_family_name()); - } else if(strcmp(parameter_name, local_port_name()) == 0){ -- int a; -- if (sscanf(parameter_value, "%d", &a)!=1) log_error("Invalid input as port number given: %s", parameter_value); -- if (a>65535 || a<0) {log_error("Port number must be between 0 and 65535, %d is given", local_port_number);} -- else {local_port_number=a;} -+ if (sscanf(parameter_value, "%d", &local_port_number)!=1) log_error("Invalid input as port number given: %s", parameter_value); -+ if (local_port_number>65535 || local_port_number<0) log_error("Port number must be between 0 and 65535, %d is given", local_port_number); - } else if (strcmp(parameter_name, nagling_name()) == 0) { - if (strcasecmp(parameter_value,"yes")==0) nagling = true; - else if (strcasecmp(parameter_value,"no")==0) nagling = false; -@@ -316,14 +301,16 @@ void Abstract_Socket::Handle_Socket_Event(int fd, boolean is_readable, boolean i - } else { - if(shutdown(fd, SHUT_RD) != 0) { - if(errno == ENOTCONN) { -+ remove_client(fd); -+ peer_disconnected(fd); - errno = 0; -- } else { -+ } else - log_error("shutdown(SHUT_RD) system call failed"); -- } -+ } else { -+ client_data->tcp_state = CLOSE_WAIT; -+ Remove_Fd_Read_Handler(fd); -+ peer_half_closed(fd); - } -- client_data->tcp_state = CLOSE_WAIT; -- Remove_Fd_Read_Handler(fd); -- peer_half_closed(fd); - } - } // switch (client_data->reading_state) - } else if (messageLength > 0) { -@@ -425,7 +412,6 @@ int Abstract_Socket::receive_message_on_fd(int client_id) - size_t end_len=AS_TCP_CHUNCK_SIZE; - recv_tb->get_end(end_ptr, end_len); - int messageLength = recv(client_id, (char *)end_ptr, end_len, 0); -- log_debug("========> receive_message_on_fd errno: '%d', '%s'", errno, strerror(errno)); - if (messageLength==0) return messageLength; // peer disconnected - else if (messageLength < 0) { - log_warning("Error when reading the received TCP PDU: %s", strerror(errno)); -@@ -464,11 +450,12 @@ int Abstract_Socket::send_message_on_nonblocking_fd(int client_id, - - log_debug("entering Abstract_Socket::" - "send_message_on_nonblocking_fd(id: %d)", client_id); -- as_client_struct * client_data = get_peer(client_id); -+ as_client_struct * client_data; - int sent_len = 0; - while(sent_len < length){ - int ret; - log_debug("Abstract_Socket::send_message_on_nonblocking_fd(id: %d): new iteration", client_id); -+ client_data = get_peer(client_id); - if (client_data->reading_state == STATE_DONT_CLOSE){ - goto client_closed_connection; - } else ret = send(client_id, send_par + sent_len, length - sent_len, 0); -@@ -549,7 +536,7 @@ const PacketHeaderDescr* Abstract_Socket::Get_Header_Descriptor() const - return NULL; - } - --void Abstract_Socket::peer_connected(int /*client_id*/, sockaddr_in& /*remote_addr*/) -+void Abstract_Socket::peer_connected(int client_id, sockaddr_in& remote_addr) - { - } - -@@ -614,8 +601,8 @@ void Abstract_Socket::map_user() - - char remotePort[6]; - char localPort[6]; -- sprintf(localPort, "%u", local_port_number); -- sprintf(remotePort, "%u", remote_port_number); -+ sprintf(localPort, "%d", local_port_number); -+ sprintf(remotePort, "%d", remote_port_number); - - if(!use_connection_ASPs) - { -@@ -797,7 +784,6 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - log_warning("Cannot open socket when trying to open the listen port: %s", strerror(errno)); - listen_port_opened(-1); - errno = 0; -- freeaddrinfo(aip); - return -1; - } - else log_error("Cannot open socket"); -@@ -815,7 +801,6 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - log_warning("Setsockopt failed when trying to open the listen port: %s", strerror(errno)); - listen_port_opened(-1); - errno = 0; -- freeaddrinfo(aip); - return -1; - } - else log_error("Setsockopt failed"); -@@ -828,10 +813,10 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - - log_debug("Bind to port..."); - if (bind(listen_fd, res->ai_addr, res->ai_addrlen) == -1) { -- error = errno; // save it for the warning message - close(listen_fd); - listen_fd = -1; - log_debug("Cannot bind to port when trying to open the listen port: %s", strerror(errno)); -+ error = errno; // save it for the warning message - errno = 0; - continue; - } -@@ -843,8 +828,8 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - { - log_warning("Cannot bind to port when trying to open the listen port: %s", strerror(error)); - listen_port_opened(-1); -+ error = errno; // save it for the warning message - error = 0; -- freeaddrinfo(aip); - return -1; - } - else log_error("Cannot bind to port"); -@@ -858,7 +843,6 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - log_warning("Cannot listen at port when trying to open the listen port: %s", strerror(errno)); - listen_port_opened(-1); - errno = 0; -- freeaddrinfo(aip); - return -1; - } - else log_error("Cannot listen at port"); -@@ -877,14 +861,13 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - log_warning("getsockname() system call failed on the server socket when trying to open the listen port: %s", strerror(errno)); - listen_port_opened(-1); - errno = 0; -- freeaddrinfo(aip); - return -1; - } - else log_error("getsockname() system call failed on the server socket"); - } - char hname[NI_MAXHOST]; - char sname[NI_MAXSERV]; --/* error = getnameinfo(res->ai_addr, res->ai_addrlen, -+ error = getnameinfo(res->ai_addr, res->ai_addrlen, - hname, sizeof (hname), sname, sizeof (sname), NI_NUMERICSERV); - if (error) { - close(listen_fd); -@@ -893,14 +876,13 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - { - log_warning("getnameinfo() system call failed on the server socket when trying to open the listen port: %s", gai_strerror(error)); - listen_port_opened(-1); -- freeaddrinfo(aip); - return -1; - } - else log_error("getsockname() system call failed on the server socket"); - } else { - log_debug("Listening on (name): %s/%s\n", - hname, sname); -- }*/ -+ } - error = getnameinfo(res->ai_addr, res->ai_addrlen, - hname, sizeof (hname), sname, sizeof (sname), NI_NUMERICHOST|NI_NUMERICSERV); - if (error) { -@@ -910,7 +892,6 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - { - log_warning("getnameinfo() system call failed on the server socket when trying to open the listen port: %s", gai_strerror(error)); - listen_port_opened(-1); -- freeaddrinfo(aip); - return -1; - } - else log_error("getsockname() system call failed on the server socket"); -@@ -932,12 +913,11 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc - if(use_connection_ASPs) - listen_port_opened(listenPort); - -- freeaddrinfo(aip); - return listenPort; +diff --git a/src/Abstract_Socket.cc b/src/Abstract_Socket.cc +index 8b7b753..5e4addf 100644 +--- a/src/Abstract_Socket.cc ++++ b/src/Abstract_Socket.cc +@@ -40,6 +40,7 @@ + # include #endif - } - --void Abstract_Socket::listen_port_opened(int /*port_number*/) -+void Abstract_Socket::listen_port_opened(int port_number) - { - // Intentionally blank - } -@@ -1084,9 +1064,7 @@ int Abstract_Socket::open_client_connection(const struct sockaddr_in & new_remot - Add_Fd_Read_Handler(socket_fd); // Done here - as in case of error: remove_client expects the handler as added - log_debug("Abstract_Socket::open_client_connection(). Handler set to socket fd %d", socket_fd); - client_data->fd_buff = new TTCN_Buffer; --// client_data->clientAddr = *(struct sockaddr_storage*)&new_remote_addr; -- memset(&client_data->clientAddr,0,sizeof(client_data->clientAddr)); -- memcpy(&client_data->clientAddr,&new_remote_addr,sizeof(new_remote_addr)); -+ client_data->clientAddr = *(struct sockaddr_storage*)&new_remote_addr; - client_data->clientAddrlen = sizeof(new_remote_addr); - client_data->tcp_state = ESTABLISHED; - client_data->reading_state = STATE_NORMAL; -@@ -1259,22 +1237,22 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch - ); - - if(bind(socket_fd, aip2->ai_addr, aip2->ai_addrlen)<0) { --/* if(use_connection_ASPs) // the if else branches are the same -- {*/ -+ if(use_connection_ASPs) -+ { - log_debug("Cannot bind to port when trying to open client connection: %s", strerror(errno)); - //client_connection_opened(-1); - //freeaddrinfo(localAddrinfo); - errno = 0; - continue; //aip2 cycle - //return -1; --/* } -+ } - else { - //freeaddrinfo(localAddrinfo); - //log_error("Cannot bind to port."); - log_debug("Cannot bind to port when trying to open client connection: %s", strerror(errno)); - errno = 0; - continue; //aip2 cycle -- }*/ -+ } - } - log_debug("Bind successful on client."); - freeaddrinfo(localAddrinfo); -@@ -1358,7 +1336,7 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch - } - char hname[NI_MAXHOST]; - char sname[NI_MAXSERV]; --/* error = getnameinfo(aip->ai_addr, aip->ai_addrlen, -+ error = getnameinfo(aip->ai_addr, aip->ai_addrlen, - hname, sizeof (hname), sname, sizeof (sname), NI_NUMERICSERV); - if (error) { - close(socket_fd); -@@ -1373,19 +1351,18 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch - log_debug("Connection established (name): %s/%s -> %s/%s\n", - hname, sname, - remoteHostname, remoteServicename); -- }*/ -+ } - error = getnameinfo(aip->ai_addr, aip->ai_addrlen, - hname, sizeof (hname), sname, sizeof (sname), NI_NUMERICHOST|NI_NUMERICSERV); - if (error) { --/* close(socket_fd); -+ close(socket_fd); - if(use_connection_ASPs) - { - log_warning("getnameinfo() system call failed on the client socket when trying to connect to server: %s", gai_strerror(error)); --// client_connection_opened(-1); --// return -1; -+ client_connection_opened(-1); -+ return -1; - } -- else*/ -- log_warning("getnameinfo() system call failed on the client socket when trying to connect to server: %s", gai_strerror(error)); -+ else log_error("getnameinfo() system call failed on the client socket when trying to connect to server: %s", gai_strerror(error)); - } else { - log_debug("Connection established (addr): %s/%s -> %s/%s\n", - hname, sname, -@@ -1421,20 +1398,18 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch - return -1; - } - else log_error("Set blocking mode failed."); -- } -+ } - as_client_struct * client_data=peer_list_add_peer(socket_fd); - Add_Fd_Read_Handler(socket_fd); // Done here - as in case of error: remove_client expects the handler as added - log_debug("Abstract_Socket::open_client_connection(). Handler set to socket fd %d", socket_fd); - client_data->fd_buff = new TTCN_Buffer; --// client_data->clientAddr = *(struct sockaddr_storage*)aip->ai_addr; -- memset(&client_data->clientAddr,0,sizeof(client_data->clientAddr)); -- memcpy(&client_data->clientAddr,aip->ai_addr,sizeof(*aip->ai_addr)); -+ client_data->clientAddr = *(struct sockaddr_storage*)aip->ai_addr; - client_data->clientAddrlen = aip->ai_addrlen; - client_data->tcp_state = ESTABLISHED; - client_data->reading_state = STATE_NORMAL; ++#include -- freeaddrinfo(res); -+ freeaddrinfo(res); - - if (!add_user_data(socket_fd)) { - remove_client(socket_fd); -@@ -1449,7 +1424,7 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch - } - - --void Abstract_Socket::client_connection_opened(int /*client_id*/) -+void Abstract_Socket::client_connection_opened(int client_id) - { - // Intentionally blank - } -@@ -1463,7 +1438,7 @@ void Abstract_Socket::unmap_user() - log_debug("leaving Abstract_Socket::unmap_user()"); - } - --void Abstract_Socket::peer_disconnected(int /*fd*/) -+void Abstract_Socket::peer_disconnected(int fd) - { - // virtual peer_disconnected() needs to be overriden in test ports! - if(!use_connection_ASPs) { -@@ -1547,19 +1522,11 @@ void Abstract_Socket::send_outgoing(const unsigned char* send_par, int length, i - nrOfBytesSent = use_non_blocking_socket ? send_message_on_nonblocking_fd(dest_fd, send_par, length) : - send_message_on_fd(dest_fd, send_par, length); - -- if (nrOfBytesSent == -1){ -- log_debug("Client %d closed connection. Error: %d %s", client_id, errno, strerror(errno)); -- report_unsent(dest_fd,length,nrOfBytesSent,send_par,"Client closed the connection"); -- -- if(client_data->tcp_state == CLOSE_WAIT){ -- log_debug("Client %d waiting for close ASP.", client_id); -- } else { -- errno = 0; -- log_debug("Client %d closed connection", client_id); -- client_data->tcp_state = CLOSE_WAIT; -- Remove_Fd_Read_Handler(dest_fd); -- peer_half_closed(dest_fd); -- } -+ if (nrOfBytesSent == -1 && errno == EPIPE){ // means connection was interrupted by peer -+ errno = 0; -+ log_debug("Client %d closed connection", client_id); -+ remove_client(dest_fd); -+ peer_disconnected(dest_fd); - }else if (nrOfBytesSent != length) { - char *error_text=mprintf("Send system call failed: %d bytes were sent instead of %d", nrOfBytesSent, length); - report_error(client_id,length,nrOfBytesSent,send_par,error_text); -@@ -1570,16 +1537,11 @@ void Abstract_Socket::send_outgoing(const unsigned char* send_par, int length, i - log_debug("leaving Abstract_Socket::send_outgoing()"); - } - --void Abstract_Socket::report_error(int /*client_id*/, int /*msg_length*/, int /*sent_length*/, const unsigned char* /*msg*/, const char* error_text) -+void Abstract_Socket::report_error(int client_id, int msg_length, int sent_length, const unsigned char* msg, const char* error_text) - { - log_error("%s",error_text); - } - --void Abstract_Socket::report_unsent(int /*client_id*/, int /*msg_length*/, int /*sent_length*/, const unsigned char* /*msg*/, const char* error_text) --{ -- log_debug("%s",error_text); --} -- - void Abstract_Socket::all_mandatory_configparameters_present() - { - if(!use_connection_ASPs) -@@ -1813,6 +1775,7 @@ void Abstract_Socket::peer_list_resize_list(int client_id) { - new_length++; // index starts from 0 - log_debug("Abstract_Socket::peer_list_resize_list: Resizing to %d", new_length); - peer_list_root = (as_client_struct **)Realloc(peer_list_root, new_length*sizeof(as_client_struct *)); -+ log_debug("Abstract_Socket::peer_list_resize_list: After Resizing: %p", peer_list_root); - - // initialize new entries - for (int i = peer_list_length; i < new_length; i++) -@@ -1974,13 +1937,6 @@ SSL_Socket::SSL_Socket() - ssl_password=NULL; + #define AS_TCP_CHUNCK_SIZE 4096 + #define AS_SSL_CHUNCK_SIZE 16384 +@@ -171,6 +172,7 @@ Abstract_Socket::Abstract_Socket() { + remote_host_name = NULL; + remote_port_number = 0; + ai_family = AF_UNSPEC; // default: Auto ++ ip_proto = IPPROTO_TCP; // default test_port_type=NULL; test_port_name=NULL; -- ssl_ctx = NULL; -- ssl_current_ssl = NULL; -- SSLv2=true; -- SSLv3=true; -- TLSv1=true; -- TLSv1_1=true; -- TLSv1_2=true; - } - - SSL_Socket::SSL_Socket(const char *tp_type, const char *tp_name) -@@ -1997,13 +1953,6 @@ SSL_Socket::SSL_Socket(const char *tp_type, const char *tp_name) - ssl_password=NULL; + ttcn_buffer_usercontrol=false; +@@ -199,6 +201,7 @@ Abstract_Socket::Abstract_Socket(const char *tp_type, const char *tp_name) { + remote_host_name = NULL; + remote_port_number = 0; + ai_family = AF_UNSPEC; // default: Auto ++ ip_proto = IPPROTO_TCP; // default test_port_type=tp_type; test_port_name=tp_name; -- ssl_ctx = NULL; -- ssl_current_ssl = NULL; -- SSLv2=true; -- SSLv3=true; -- TLSv1=true; -- TLSv1_1=true; -- TLSv1_2=true; - } - - SSL_Socket::~SSL_Socket() -@@ -2056,26 +2005,6 @@ bool SSL_Socket::parameter_set(const char *parameter_name, - if(strcasecmp(parameter_value, "yes") == 0) ssl_verify_certificate = true; - else if(strcasecmp(parameter_value, "no") == 0) ssl_verify_certificate = false; - else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ssl_verifycertificate_name()); -- } else if(strcasecmp(parameter_name, ssl_disable_SSLv2()) == 0) { -- if(strcasecmp(parameter_value, "yes") == 0) SSLv2= false; -- else if(strcasecmp(parameter_value, "no") == 0) SSLv2 = true; -- else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ssl_disable_SSLv2()); -- } else if(strcasecmp(parameter_name, ssl_disable_SSLv3()) == 0) { -- if(strcasecmp(parameter_value, "yes") == 0) SSLv2 = false; -- else if(strcasecmp(parameter_value, "no") == 0) SSLv2 = true; -- else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ssl_disable_SSLv3()); -- } else if(strcasecmp(parameter_name, ssl_disable_TLSv1()) == 0) { -- if(strcasecmp(parameter_value, "yes") == 0) TLSv1= false; -- else if(strcasecmp(parameter_value, "no") == 0) TLSv1 = true; -- else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ssl_disable_TLSv1()); -- } else if(strcasecmp(parameter_name, ssl_disable_TLSv1_1()) == 0) { -- if(strcasecmp(parameter_value, "yes") == 0) TLSv1_1 = false; -- else if(strcasecmp(parameter_value, "no") == 0) TLSv1_1 = true; -- else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ssl_disable_TLSv1_1()); -- } else if(strcasecmp(parameter_name, ssl_disable_TLSv1_2()) == 0) { -- if(strcasecmp(parameter_value, "yes") == 0) TLSv1_2 = false; -- else if(strcasecmp(parameter_value, "no") == 0) TLSv1_2 = true; -- else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ssl_disable_TLSv1_2()); - } else { - log_debug("leaving SSL_Socket::parameter_set(%s, %s)", parameter_name, parameter_value); - return Abstract_Socket::parameter_set(parameter_name, parameter_value); -@@ -2102,32 +2031,6 @@ bool SSL_Socket::add_user_data(int client_id) { + ttcn_buffer_usercontrol=false; +@@ -261,6 +264,10 @@ bool Abstract_Socket::parameter_set(const char *parameter_name, + else if (strcasecmp(parameter_value,"IPv4")==0 || strcasecmp(parameter_value,"AF_INET")==0) ai_family = AF_INET; + else if (strcasecmp(parameter_value,"UNSPEC")==0 || strcasecmp(parameter_value,"AF_UNSPEC")==0) ai_family = AF_UNSPEC; + else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ai_family_name()); ++ } else if(strcmp(parameter_name, ip_proto_name()) == 0){ ++ if (strcasecmp(parameter_value,"IPPROTO_TCP")==0) ip_proto = IPPROTO_TCP; ++ else if (strcasecmp(parameter_value,"IPPROTO_SCTP")==0) ip_proto = IPPROTO_SCTP; ++ else log_error("Parameter value '%s' not recognized for parameter '%s'", parameter_value, ip_proto_name()); + } else if(strcmp(parameter_name, local_port_name()) == 0){ + int a; + if (sscanf(parameter_value, "%d", &a)!=1) log_error("Invalid input as port number given: %s", parameter_value); +@@ -760,6 +767,7 @@ int Abstract_Socket::open_listen_port(const char* localHostname, const char* loc + hints.ai_flags = /*AI_ALL|*/AI_ADDRCONFIG|AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = ai_family; ++ hints.ai_protocol = ip_proto; + + error = getaddrinfo(localHostname, localServicename, &hints, &aip); + if (error != 0) { +@@ -1143,6 +1151,7 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch + } + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = ai_family; ++ hints.ai_protocol = ip_proto; - if (ssl_current_ssl==NULL) - log_error("Creation of SSL object failed"); --#ifdef SSL_OP_NO_SSLv2 -- if(!SSLv2){ -- SSL_set_options(ssl_current_ssl,SSL_OP_NO_SSLv2); -- } --#endif --#ifdef SSL_OP_NO_SSLv3 -- if(!SSLv3){ -- SSL_set_options(ssl_current_ssl,SSL_OP_NO_SSLv3); -- } --#endif --#ifdef SSL_OP_NO_TLSv1 -- if(!TLSv1){ -- SSL_set_options(ssl_current_ssl,SSL_OP_NO_TLSv1); -- } --#endif --#ifdef SSL_OP_NO_TLSv1_1 -- if(!TLSv1_1){ -- SSL_set_options(ssl_current_ssl,SSL_OP_NO_TLSv1_1); -- } --#endif --#ifdef SSL_OP_NO_TLSv1_2 -- if(!TLSv1_2){ -- SSL_set_options(ssl_current_ssl,SSL_OP_NO_TLSv1_2); -- } --#endif -- - set_user_data(client_id, ssl_current_ssl); - log_debug("New client added with key '%d'", client_id); - log_debug("Binding SSL to the socket"); -@@ -2362,10 +2265,9 @@ int SSL_Socket::send_message_on_fd(int client_id, const unsigned char* send_par, - log_debug("SSL_ERROR_ZERO_RETURN is received, setting SSL SHUTDOWN mode to QUIET"); - ssl_current_client=NULL; - log_debug("leaving SSL_Socket::send_message_on_fd()"); -- return -1; -+ return 0; - default: -- log_debug("SSL error occured"); -- return -1; -+ log_error("SSL error occured"); + error = getaddrinfo(remoteHostname, remoteServicename, &hints, &res); + if (error != 0) { +@@ -1191,9 +1200,11 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch + } } - } - // avoid compiler warnings -@@ -2457,8 +2359,7 @@ int SSL_Socket::send_message_on_nonblocking_fd(int client_id, const unsigned cha - case SSL_ERROR_ZERO_RETURN: - goto client_closed_connection; - default: -- log_warning("SSL error occured"); -- return -1; -+ log_error("SSL error occured"); + +- log_debug("Using address family for socket %d: %s",socket_fd, ++ log_debug("Using address family for socket %d: %s - %s",socket_fd, + ((aip->ai_family==AF_INET)?"IPv4": +- ((aip->ai_family==AF_INET6)?"IPv6":"unknown")) ++ ((aip->ai_family==AF_INET6)?"IPv6":"unknown")), ++ ((aip->ai_protocol==IPPROTO_TCP)?"IPPROTO_TCP": ++ ((aip->ai_protocol==IPPROTO_SCTP)?"IPPROTO_SCTP":"unknown")) + ); + + +@@ -1225,6 +1236,7 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch + hints.ai_flags = AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = ai_family;//aip->ai_family; // NOTE: On solaris 10 if is set to aip->ai_family, getaddrinfo will crash for IPv4-mapped addresses! ++ hints.ai_protocol = ip_proto; + + error = getaddrinfo(localHostname, localServicename, &hints, &localAddrinfo); + if (error != 0) { +@@ -1390,10 +1402,13 @@ int Abstract_Socket::open_client_connection(const char* remoteHostname, const ch } - } - -@@ -2547,11 +2448,6 @@ const char* SSL_Socket::ssl_certificate_file_name() { return "ssl_certific - const char* SSL_Socket::ssl_password_name() { return "ssl_private_key_password";} - const char* SSL_Socket::ssl_cipher_list_name() { return "ssl_allowed_ciphers_list";} - const char* SSL_Socket::ssl_verifycertificate_name() { return "ssl_verify_certificate";} --const char* SSL_Socket::ssl_disable_SSLv2() { return "ssl_disable_SSLv2";} --const char* SSL_Socket::ssl_disable_SSLv3() { return "ssl_disable_SSLv3";} --const char* SSL_Socket::ssl_disable_TLSv1() { return "ssl_disable_TLSv1";} --const char* SSL_Socket::ssl_disable_TLSv1_1() { return "ssl_disable_TLSv1_1";} --const char* SSL_Socket::ssl_disable_TLSv1_2() { return "ssl_disable_TLSv1_2";} - - void SSL_Socket::ssl_actions_to_seed_PRNG() { -@@ -2654,10 +2550,10 @@ void SSL_Socket::ssl_init_SSL() - - // check the other side's certificates - if (ssl_verify_certificate) { -- log_debug("Setting verification behaviour: verification required and do not allow to continue on failure.."); -+ log_debug("Setting verification behaviour: verification required and do not allow to continue on failure"); - SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_callback); - } else { -- log_debug("Setting verification behaviour: verification not required and do allow to continue on failure.."); -+ log_debug("Setting verification behaviour: verification not required and do allow to continue on failure"); - SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, ssl_verify_callback); + log_debug( +- "connected to: host %s service %s via address family %s\n", ++ "connected to: host %s service %s via address family %s with ip_proto %s\n", + remoteHostname, remoteServicename, + ((aip->ai_family==AF_INET)?"IPv4": +- ((aip->ai_family==AF_INET6)?"IPv6":"unknown"))); ++ ((aip->ai_family==AF_INET6)?"IPv6":"unknown")), ++ ((aip->ai_protocol==IPPROTO_TCP)?"IPPROTO_TCP": ++ ((aip->ai_protocol==IPPROTO_SCTP)?"IPPROTO_SCTP":"unknown")) ++ ); + break; } + if (aip==NULL) { +@@ -1774,18 +1789,19 @@ const char* Abstract_Socket::remote_address_name() { return "destIPAddr + const char* Abstract_Socket::local_address_name() { return "serverIPAddr";} + const char* Abstract_Socket::remote_port_name() { return "destPort";} + const char* Abstract_Socket::ai_family_name() { return "ai_family";} ++const char* Abstract_Socket::ip_proto_name() { return "ip_proto";} + const char* Abstract_Socket::use_connection_ASPs_name() { return "use_connection_ASPs";} + const char* Abstract_Socket::halt_on_connection_reset_name(){ return "halt_on_connection_reset";} +-const char* Abstract_Socket::client_TCP_reconnect_name() { return "client_TCP_reconnect";} ++const char* Abstract_Socket::client_TCP_reconnect_name() { return "client_TCP_reconnect";} + const char* Abstract_Socket::TCP_reconnect_attempts_name() { return "TCP_reconnect_attempts";} +-const char* Abstract_Socket::TCP_reconnect_delay_name() { return "TCP_reconnect_delay";} ++const char* Abstract_Socket::TCP_reconnect_delay_name() { return "TCP_reconnect_delay";} + const char* Abstract_Socket::server_mode_name() { return "server_mode";} + const char* Abstract_Socket::socket_debugging_name() { return "socket_debugging";} + const char* Abstract_Socket::nagling_name() { return "nagling";} + const char* Abstract_Socket::use_non_blocking_socket_name() { return "use_non_blocking_socket";} + const char* Abstract_Socket::server_backlog_name() { return "server_backlog";} +-bool Abstract_Socket::add_user_data(int) {return true;} +-bool Abstract_Socket::remove_user_data(int) {return true;} ++bool Abstract_Socket::add_user_data(int) {return true;} ++bool Abstract_Socket::remove_user_data(int) {return true;} + bool Abstract_Socket::user_all_mandatory_configparameters_present() { return true; } -@@ -2757,7 +2653,7 @@ int SSL_Socket::ssl_getresult(int res) - return err; - } - --int SSL_Socket::ssl_verify_certificates_at_handshake(int /*preverify_ok*/, X509_STORE_CTX */*ssl_ctx*/) { -+int SSL_Socket::ssl_verify_certificates_at_handshake(int preverify_ok, X509_STORE_CTX *ssl_ctx) { - // don't care by default - return -1; - } -@@ -2765,7 +2661,7 @@ int SSL_Socket::ssl_verify_certificates_at_handshake(int /*preverify_ok*/, X50 - // Callback function used by OpenSSL. - // Called when a password is needed to decrypt the private key file. - // NOTE: not thread safe --int SSL_Socket::ssl_password_cb(char *buf, int num, int /*rwflag*/,void */*userdata*/) { -+int SSL_Socket::ssl_password_cb(char *buf, int num, int rwflag,void *userdata) { - - if (ssl_current_client!=NULL) { - char *ssl_client_password; -@@ -2795,23 +2691,18 @@ int SSL_Socket::ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ssl_ctx) - ctx_pointer = SSL_get_SSL_CTX(ssl_pointer); - if (ssl_current_client!=NULL) { -- // if ssl_verifiycertificate == "no", then always accept connections -- if(((SSL_Socket *)ssl_current_client)->ssl_verify_certificate) { -- user_result=((SSL_Socket *)ssl_current_client)->ssl_verify_certificates_at_handshake(preverify_ok, ssl_ctx); -- if (user_result>=0) return user_result; -- } else { -- return 1; -- } -+ user_result=((SSL_Socket *)ssl_current_client)->ssl_verify_certificates_at_handshake(preverify_ok, ssl_ctx); -+ if (user_result>=0) return user_result; - } else { // go on with default authentication - fprintf(stderr, "Warning: no current SSL object found but ssl_verify_callback is called, programming error\n"); - } - - // if ssl_verifiycertificate == "no", then always accept connections -- if (SSL_CTX_get_verify_mode(ctx_pointer) == SSL_VERIFY_NONE) -+ if (SSL_CTX_get_verify_mode(ctx_pointer) && SSL_VERIFY_NONE) - return 1; - // if ssl_verifiycertificate == "yes", then accept connections only if the - // certificate is valid -- else if (SSL_CTX_get_verify_mode(ctx_pointer) & SSL_VERIFY_PEER) { -+ else if (SSL_CTX_get_verify_mode(ctx_pointer) && SSL_VERIFY_PEER) { - return preverify_ok; - } - // something went wrong diff --git a/ttcn/patch_abstract_socket/Abstract_Socket.hh.patch b/ttcn/patch_abstract_socket/Abstract_Socket.hh.patch index 2b4445e..bce5667 100644 --- a/ttcn/patch_abstract_socket/Abstract_Socket.hh.patch +++ b/ttcn/patch_abstract_socket/Abstract_Socket.hh.patch @@ -1,108 +1,38 @@ -diff --git a/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.hh b/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.hh -old mode 100644 -new mode 100755 -index 7de8446..ad2d65d ---- a/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.hh -+++ b/ttcn/modules/titan.TestPorts.Common_Components.Abstract_Socket/module/src/Abstract_Socket.hh -@@ -1,28 +1,17 @@ - /****************************************************************************** --* Copyright (c) 2000-2019 Ericsson Telecom AB --* All rights reserved. This program and the accompanying materials --* are made available under the terms of the Eclipse Public License v2.0 --* which accompanies this distribution, and is available at --* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html --* --* Contributors: --* Zoltan Bibo - initial implementation and initial documentation --* Gergely Futo --* Oliver Ferenc Czerman --* Balasko Jeno --* Zoltan Bibo --* Eduard Czimbalmos --* Kulcsár Endre --* Gabor Szalai --* Jozsef Gyurusi --* Csöndes Tibor --* Zoltan Jasz --******************************************************************************/ -+ * Copyright (c) 2000-2025 Ericsson Telecom AB -+ * All rights reserved. This program and the accompanying materials -+ * are made available under the terms of the Eclipse Public License v2.0 -+ * which accompanies this distribution, and is available at -+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html -+ ******************************************************************************/ - // - // File: Abstract_Socket.hh - // Description: Abstract_Socket header file --// Rev: R9B -+// Rev: - // Prodnr: CNL 113 384 -+// Updated: 2010-11-24 -+// Contact: http://ttcn.ericsson.se - // +diff --git a/src/Abstract_Socket.hh b/src/Abstract_Socket.hh +index 6d7bc3d..a068662 100644 +--- a/src/Abstract_Socket.hh ++++ b/src/Abstract_Socket.hh +@@ -134,7 +134,7 @@ protected: + bool get_handle_half_close() const {return handle_half_close;} + int get_socket_fd() const; + int get_listen_fd() const {return listen_fd;} +- ++ + //set non-blocking mode + int set_non_block_mode(int fd, bool enable_nonblock); - -@@ -120,7 +109,7 @@ protected: - // Shall be called from Handle_Fd_Event() - void Handle_Socket_Event(int fd, boolean is_readable, boolean is_writable, boolean is_error); - // Shall be called from Handle_Timeout() - for possible future development -- void Handle_Timeout_Event(double /*time_since_last_call*/) {}; -+ void Handle_Timeout_Event(double time_since_last_call) {}; - - // Shall be called from outgoing_send() - void send_outgoing(const unsigned char* message_buffer, int length, int client_id = -1); -@@ -144,9 +133,9 @@ protected: - bool increase_send_buffer(int fd, int &old_size, int& new_size); - - const char* get_local_host_name(){return local_host_name; }; -- unsigned int get_local_port_number(){return local_port_number; }; -+ const unsigned int get_local_port_number(){return local_port_number; }; - const char* get_remote_host_name(){return remote_host_name; }; -- unsigned int get_remote_port_number(){return remote_port_number; }; -+ const unsigned int get_remote_port_number(){return remote_port_number; }; - const struct sockaddr_in & get_remote_addr() {return remoteAddr; }; /* FIXME: This function is deprecated and should be removed! */ +@@ -149,6 +149,8 @@ protected: const struct sockaddr_in & get_local_addr() {return localAddr; }; /* FIXME: This function is deprecated and should be removed! */ const int& get_ai_family() const {return ai_family;} -@@ -190,15 +179,13 @@ protected: - virtual int send_message_on_nonblocking_fd(int client_id, const unsigned char *message_buffer, int message_length); - // Called after a peer is connected - virtual void peer_connected(int client_id, sockaddr_in& remote_addr); /* This function should be removed! deprecated by: */ -- virtual void peer_connected(int /*client_id*/, const char * /*host*/, const int /*port*/) {}; -+ virtual void peer_connected(int client_id, const char * host, const int port) {}; - // Called after a peer is disconnected - virtual void peer_disconnected(int client_id); - // Called when a peer shut down its fd for writing - virtual void peer_half_closed(int client_id); - // Called after a send error - virtual void report_error(int client_id, int msg_length, int sent_length, const unsigned char* msg, const char* error_text); -- // Called after a unsent message -- virtual void report_unsent(int client_id, int msg_length, int sent_length, const unsigned char* msg, const char* error_text); - - // Test port parameters - virtual const char* local_port_name(); -@@ -365,11 +352,6 @@ protected: - virtual const char* ssl_password_name(); - virtual const char* ssl_cipher_list_name(); - virtual const char* ssl_verifycertificate_name(); -- virtual const char* ssl_disable_SSLv2(); -- virtual const char* ssl_disable_SSLv3(); -- virtual const char* ssl_disable_TLSv1(); -- virtual const char* ssl_disable_TLSv1_1(); -- virtual const char* ssl_disable_TLSv1_2(); - - private: - bool ssl_verify_certificate; // verify other part's certificate or not -@@ -377,13 +359,6 @@ private: - bool ssl_initialized; // whether SSL already initialized or not - bool ssl_use_session_resumption; // use SSL sessions or not - -- bool SSLv2; -- bool SSLv3; -- bool TLSv1; -- bool TLSv1_1; -- bool TLSv1_2; -- -- - char *ssl_key_file; // private key file - char *ssl_certificate_file; // own certificate file - char *ssl_trustedCAlist_file; // trusted CA list file + void set_ai_family(int parameter_value) {ai_family=parameter_value;} ++ const int& get_ip_proto() const {return ip_proto;} ++ void set_ip_proto(int parameter_value) {ip_proto=parameter_value;} + bool get_ttcn_buffer_usercontrol() const {return ttcn_buffer_usercontrol; } + void set_nagling(bool parameter_value) {nagling=parameter_value;} + void set_server_mode(bool parameter_value) {server_mode=parameter_value;} +@@ -204,6 +206,7 @@ protected: + virtual const char* local_address_name(); + virtual const char* remote_port_name(); + virtual const char* ai_family_name(); ++ virtual const char* ip_proto_name(); + virtual const char* use_connection_ASPs_name(); + virtual const char* halt_on_connection_reset_name(); + virtual const char* client_TCP_reconnect_name(); +@@ -269,6 +272,7 @@ private: + char* remote_host_name; + unsigned int remote_port_number; + int ai_family; // address family to use ++ int ip_proto; // protocol to use (e.g. IPPROTO_TCP, IPPROTO_SCTP) + // remoteAddr and localAddr is filled when map_user is called + struct sockaddr_in remoteAddr; /* FIXME: not used! should be removed */ + struct sockaddr_in localAddr; /* FIXME: not used! should be removed */ -- GitLab From 82bb7aa1fdb1ce5147296dabb9ad43a9566cffe8 Mon Sep 17 00:00:00 2001 From: garciay Date: Tue, 12 Aug 2025 16:35:06 +0200 Subject: [PATCH 2/5] Bug fixed in f_f2345; Validation of security functions f1, f1*, f_2345 & f_5* --- NAS_ETSI.code-workspace | 6 + ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc | 85 ++- ccsrc/Externals/common_ext.cc | 1 + ccsrc/Protocols/FiveG_AKA/opc.cc | 12 +- ccsrc/Protocols/FiveG_AKA/opc.hh | 5 +- ccsrc/Protocols/FiveG_AKA/rijndael.cc | 20 +- etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ | 24 +- ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn | 700 +++++++++++++++++++- ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn | 62 +- ttcn/Lib_NG_NAS/Lib_NG_NAS_Pixits.ttcn | 2 +- ttcn/Lib_NG_NAS/Lib_NG_NAS_Templates.ttcn | 2 +- 11 files changed, 870 insertions(+), 49 deletions(-) diff --git a/NAS_ETSI.code-workspace b/NAS_ETSI.code-workspace index e2a5ee7..c1c0e96 100644 --- a/NAS_ETSI.code-workspace +++ b/NAS_ETSI.code-workspace @@ -11,6 +11,12 @@ }, { "path": "../5G-AKA-simulation-in-C" + }, + { + "path": "../free5gc" + }, + { + "path": "../free5gc.util" } ], "settings": { diff --git a/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc b/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc index 61e06ec..ca77731 100644 --- a/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc +++ b/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc @@ -15,6 +15,40 @@ namespace LIB__NG__NAS__Functions { loggers::get_instance().log_to_hexa("<<< fx__set__op: OP: ", static_cast(OP), 16); } + void fx__get__op(OCTETSTRING& p_op) { + loggers::get_instance().log_msg(">>> fx__get__op: p_op: ", p_op); + p_op = OCTETSTRING(16, static_cast(OP)); + loggers::get_instance().log_msg("<<< fx__get__op: OP: ", p_op); + } + + INTEGER fx__compute__opc(const OCTETSTRING& p_authK, OCTETSTRING& p_opc) { + loggers::get_instance().log_msg(">>> fx_compute_opc: OP: ", OCTETSTRING(16, static_cast(OP))); + + rijndael r; + r.rijndael_key_schedule(p_authK); + opc op(r, OP); + uint8_t op_c[16] = { 0x00 }; + op.compute_opc(op_c); + p_opc = OCTETSTRING(16, static_cast(op_c)); + + loggers::get_instance().log_msg("<<< fx_compute_opc: OPC: ", p_opc); + return 0; + } + + INTEGER fx__rijndael__encrypt(const OCTETSTRING& p_key, const OCTETSTRING& p_plain_text, OCTETSTRING& p_cypherer_text) { + loggers::get_instance().log_msg(">>> fx__rijndael__encrypt: p_key: ", p_key); + loggers::get_instance().log_msg(">>> fx__rijndael__encrypt: p_plain_text: ", p_plain_text); + + rijndael r; + r.rijndael_key_schedule(p_key); + uint8_t cypherer_text[16] = { 0x00 }; + r.rijndael_encrypt(static_cast(p_plain_text), cypherer_text); + p_cypherer_text = OCTETSTRING(16, static_cast(cypherer_text)); + + loggers::get_instance().log_msg("<<< fx__rijndael__encrypt: p_cypherer_text: ", p_cypherer_text); + return 0; + } + INTEGER fx__f1(const BITSTRING& p_authK, const BITSTRING& p_rand, const BITSTRING& p_sqn, const BITSTRING& p_amf, BITSTRING& p_mac_a) { loggers::get_instance().log_msg(">>> fx__f1: p_authK: ", bit2oct(p_authK)); loggers::get_instance().log_msg(">>> fx__f1: p_rand: ", bit2oct(p_rand)); @@ -25,7 +59,8 @@ namespace LIB__NG__NAS__Functions { opc op(r, OP); uint8_t op_c[16] = { 0x00 }; op.compute_opc(op_c); - + loggers::get_instance().log_to_hexa("fx__f1: op_c: ", op_c, 16); + OCTETSTRING rand = bit2oct(p_rand); uint8_t rijndael_input[16] = { 0x00 }; for (int i = 0; i < 16; i++) { @@ -33,6 +68,7 @@ namespace LIB__NG__NAS__Functions { } // End of 'for' statement uint8_t temp[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, temp); + loggers::get_instance().log_to_hexa("fx__f1: Value after 1st encryption: ", temp, 16); OCTETSTRING sqn = bit2oct(p_sqn); uint8_t in1[16] = { 0x00 }; @@ -58,6 +94,8 @@ namespace LIB__NG__NAS__Functions { uint8_t out1[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, out1); + loggers::get_instance().log_to_hexa("fx__f1: Value after 2sd encryption: ", out1, 16); + for (int i = 0; i < 16; i++) { out1[i] ^= op_c[i]; } // End of 'for' statement @@ -83,6 +121,7 @@ namespace LIB__NG__NAS__Functions { opc op(r, OP); uint8_t op_c[16] = { 0x00 }; op.compute_opc(op_c); + loggers::get_instance().log_to_hexa("fx__f1star: op_c: ", op_c, 16); OCTETSTRING rand = bit2oct(p_rand); uint8_t rijndael_input[16] = { 0x00 }; @@ -91,6 +130,7 @@ namespace LIB__NG__NAS__Functions { } // End of 'for' statement uint8_t temp[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, temp); + loggers::get_instance().log_to_hexa("fx__f1star: Value after 1st encryption: ", temp, 16); OCTETSTRING sqn = bit2oct(p_sqn); uint8_t in1[16] = { 0x00 }; @@ -116,6 +156,8 @@ namespace LIB__NG__NAS__Functions { uint8_t out1[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, out1); + loggers::get_instance().log_to_hexa("fx__f1: Value after 2sd encryption: ", out1, 16); + for (int i = 0; i < 16; i++) { out1[i] ^= op_c[i]; } // End of 'for' statement @@ -141,6 +183,7 @@ namespace LIB__NG__NAS__Functions { opc op(r, OP); uint8_t op_c[16] = { 0x00 }; op.compute_opc(op_c); + loggers::get_instance().log_to_hexa("fx_f2345: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", op_c, 16); OCTETSTRING rand = bit2oct(p_rand); uint8_t rijndael_input[16] = { 0x00 }; @@ -149,15 +192,19 @@ namespace LIB__NG__NAS__Functions { } // End of 'for' statement uint8_t temp[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, temp); + loggers::get_instance().log_to_hexa("fx_f2345: Value after 1st encryption: ", temp, 16); // To obtain output block OUT2: XOR OPc and TEMP, rotate by r2=0, and XOR on the constant c2 (which is all zeroes except that the last bit is 1) for (int i = 0; i < 16; i++) { rijndael_input[i] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 1; + loggers::get_instance().log_to_hexa("fx_f2345: b entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", rijndael_input, 16); uint8_t out[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, out); + loggers::get_instance().log_to_hexa("fx_f2345: f2/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); + for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; } // End of 'for' statement @@ -166,19 +213,23 @@ namespace LIB__NG__NAS__Functions { for (int i = 0; i < 8; i++) { res[i] = out[i + 8]; } // End of 'for' statement + loggers::get_instance().log_to_hexa("fx_f2345: f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", res, 8); uint8_t ak[6] = { 0x00 }; for (int i = 0; i < 6; i++) { ak[i] = out[i]; } // End of 'for' statement + loggers::get_instance().log_to_hexa("fx_f2345: f5/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ak, 6); // To obtain output block OUT3: XOR OPc and TEMP, rotate by r3=32, and XOR on the constant c3 (which is all zeroes except that the next to last bit is 1) for (int i = 0; i < 16; i++) { rijndael_input[(i + 12) % 16] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 2; - + loggers::get_instance().log_to_hexa("fx_f2345: f3/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); r.rijndael_encrypt(rijndael_input, out); + loggers::get_instance().log_to_hexa("fx_f2345: f3/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); + for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; } // End of 'for' statement @@ -187,14 +238,17 @@ namespace LIB__NG__NAS__Functions { for (int i = 0; i < 16; i++) { ck[i] = out[i]; } // End of 'for' statement + loggers::get_instance().log_to_hexa("fx_f2345: f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ck, 16); // To obtain output block OUT4: XOR OPc and TEMP, rotate by r4=64, and XOR on the constant c4 (which is all zeroes except that the 2nd from last bit is 1) for (int i = 0; i < 16; i++) { rijndael_input[(i+8) % 16] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 4; - + loggers::get_instance().log_to_hexa("fx_f2345: f4/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", rijndael_input, 16); r.rijndael_encrypt(rijndael_input, out); + loggers::get_instance().log_to_hexa("fx_f2345: f4/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", out, 16); + for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; } // End of 'for' statement @@ -203,24 +257,25 @@ namespace LIB__NG__NAS__Functions { for (int i = 0; i < 16; i++) { ik[i] = out[i]; } // End of 'for' statement + loggers::get_instance().log_to_hexa("fx_f2345: f4/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", ik, 16); OCTETSTRING os(8, static_cast(&res[0])); p_res = oct2bit(os); - os = OCTETSTRING(16, static_cast(&ik[0])); - p_ik = oct2bit(os); os = OCTETSTRING(16, static_cast(&ck[0])); p_ck = oct2bit(os); + os = OCTETSTRING(16, static_cast(&ik[0])); + p_ik = oct2bit(os); os = OCTETSTRING(6, static_cast(&ak[0])); p_ak = oct2bit(os); - loggers::get_instance().log_msg("fx_f2345: p_res: ", p_res); - loggers::get_instance().log_msg("fx_f2345: p_ck: ", p_ck); - loggers::get_instance().log_msg("fx_f2345: p_ik: ", p_ik); - loggers::get_instance().log_msg("fx_f2345: p_ak: ", p_ak); + loggers::get_instance().log_msg("fx_f2345: p_res: ", bit2oct(p_res)); + loggers::get_instance().log_msg("fx_f2345: p_ck: ", bit2oct(p_ck)); + loggers::get_instance().log_msg("fx_f2345: p_ik: ", bit2oct(p_ik)); + loggers::get_instance().log_msg("fx_f2345: p_ak: ", bit2oct(p_ak)); return 0; } - INTEGER fx__f5star(const BITSTRING& p_authK, const BITSTRING& p_rand, BITSTRING& p_ak) { + INTEGER fx__f5star(const BITSTRING& p_authK, const BITSTRING& p_rand, BITSTRING& p_ak_s) { loggers::get_instance().log_msg(">>> fx__f5star: p_authK: ", p_authK); loggers::get_instance().log_msg(">>> fx__f5star: p_rand: ", p_rand); @@ -230,6 +285,8 @@ namespace LIB__NG__NAS__Functions { opc op(r, OP); uint8_t op_c[16] = { 0x00 }; op.compute_opc(op_c); + loggers::get_instance().log_to_hexa("fx__f5star: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", op_c, 16); + OCTETSTRING rand = bit2oct(p_rand); uint8_t rijndael_input[16] = { 0x00 }; @@ -237,6 +294,7 @@ namespace LIB__NG__NAS__Functions { rijndael_input[i] = rand[i].get_octet() ^ op_c[i]; } // End of 'for' statement uint8_t temp[16] = { 0x00 }; + loggers::get_instance().log_to_hexa("fx__f5star: Before 1st encryption: ", rijndael_input, 16); r.rijndael_encrypt(rijndael_input, temp); // To obtain output block OUT5: XOR OPc and TEMP, rotate by r5=96, and XOR on the constant c5 (which is all zeroes except that the 3rd from last bit is 1) @@ -244,9 +302,10 @@ namespace LIB__NG__NAS__Functions { rijndael_input[(i + 4) % 16] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 8; - uint8_t out[16] = { 0x00 }; + loggers::get_instance().log_to_hexa("fx__f5star: Before 2sd encryption: ", rijndael_input, 16); r.rijndael_encrypt(rijndael_input, out); + loggers::get_instance().log_to_hexa("fx__f5star: After 2sd encryption: ", out, 16); for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; } // End of 'for' statement @@ -256,8 +315,8 @@ namespace LIB__NG__NAS__Functions { ak[i] = out[i]; } OCTETSTRING os(6, static_cast(&ak[0])); - p_ak = oct2bit(os); - loggers::get_instance().log_msg("fx__f5star: p_ak: ", os); + p_ak_s = oct2bit(os); + loggers::get_instance().log_msg("fx__f5star: p_ak: ", bit2oct(p_ak_s)); return 0; } diff --git a/ccsrc/Externals/common_ext.cc b/ccsrc/Externals/common_ext.cc index 0addcb8..ea34cad 100644 --- a/ccsrc/Externals/common_ext.cc +++ b/ccsrc/Externals/common_ext.cc @@ -23,6 +23,7 @@ namespace CommonDefs { * @desc This external function gets KEY * @return The KEY * @see fx_get...() return UInt64 + * @note ETSI TS 133 220 V18.3.0 (2024-05) Annex B.2 Generic key derivation function */ //INTEGER fx__KeyDerivationFunction(INTEGER const&, BITSTRING const&, OCTETSTRING const&){ BITSTRING fx__KeyDerivationFunction(const INTEGER& p__KDF, const BITSTRING& p__Key, const OCTETSTRING& p__String){ diff --git a/ccsrc/Protocols/FiveG_AKA/opc.cc b/ccsrc/Protocols/FiveG_AKA/opc.cc index 34d3966..8f600bc 100644 --- a/ccsrc/Protocols/FiveG_AKA/opc.cc +++ b/ccsrc/Protocols/FiveG_AKA/opc.cc @@ -1,12 +1,8 @@ #include "opc.hh" void opc::compute_opc(uint8_t p_opc[16]) { - if (!_computed) { - _rijndael.rijndael_encrypt(_op, p_opc); - for (uint8_t i = 0; i < 16; i++) { - p_opc[i] ^= _op[i]; - } // End of 'for' statement - } else { - std::memcpy(p_opc, _op, 16); - } + _rijndael.rijndael_encrypt(_op, p_opc); + for (uint8_t i = 0; i < 16; i++) { + p_opc[i] ^= _op[i]; + } // End of 'for' statement } diff --git a/ccsrc/Protocols/FiveG_AKA/opc.hh b/ccsrc/Protocols/FiveG_AKA/opc.hh index eeaaf80..861adbe 100644 --- a/ccsrc/Protocols/FiveG_AKA/opc.hh +++ b/ccsrc/Protocols/FiveG_AKA/opc.hh @@ -9,11 +9,10 @@ class opc { rijndael& _rijndael; uint8_t _op[16]; - bool _computed; public: - opc(rijndael& p_rijndael): _rijndael(p_rijndael), _op(), _computed{false} { std::memcpy(_op, OP, 16); std::memset(_op, 0x00, 16); }; - opc(rijndael& p_rijndael, uint8_t p_op[16]): _rijndael(p_rijndael), _computed{true} { std::memcpy(_op, p_op, 16); }; + opc(rijndael& p_rijndael): _rijndael(p_rijndael), _op() { std::memcpy(_op, OP, 16); std::memset(_op, 0x00, 16); }; + opc(rijndael& p_rijndael, uint8_t p_op[16]): _rijndael(p_rijndael) { std::memcpy(_op, p_op, 16); }; virtual ~opc() {}; void compute_opc(uint8_t p_opc[16]); diff --git a/ccsrc/Protocols/FiveG_AKA/rijndael.cc b/ccsrc/Protocols/FiveG_AKA/rijndael.cc index 701ada5..f43e8dc 100644 --- a/ccsrc/Protocols/FiveG_AKA/rijndael.cc +++ b/ccsrc/Protocols/FiveG_AKA/rijndael.cc @@ -1,5 +1,7 @@ #include "rijndael.hh" +#include "loggers.hh" + rijndael::rijndael() { } // End of ctor @@ -8,6 +10,8 @@ rijndael::~rijndael() { } // End of dtor int rijndael::rijndael_key_schedule(const uint8_t p_key[16]) { + loggers::get_instance().log_to_hexa(">>> rijndael::rijndael_key_schedule: ", p_key, 16); + uint8_t round_const = 1; // First round p_key equals p_key @@ -29,41 +33,55 @@ int rijndael::rijndael_key_schedule(const uint8_t p_key[16]) { } // End of 'for' statement // Update round constant - round_const = XTIME[round_const]; + round_const = XTIME[round_const]; } // End of 'for' statement + loggers::get_instance().log_to_hexa("rijndael::rijndael_key_schedule: ", static_cast(&_round_keys[0][0][0]), 16); + return 0; } void rijndael::rijndael_encrypt(const uint8_t p_input[16], uint8_t p_output[16]) { + loggers::get_instance().log_to_hexa(">>> rijndael::rijndael_encrypt: ", p_input, 16); // Initialise state array from p_input byte string uint8_t state[4][4]; for (int i = 0; i < 16; i++) { state[i & 0x3][i>>2] = p_input[i]; } // End of 'for' statement + loggers::get_instance().log_rijndael_state("rijndael::rijndael_encrypt: Initial state: ", state); // Add first round_key key_add(state, _round_keys, 0); + loggers::get_instance().log_rijndael_state("rijndael::rijndael_encrypt: First round: key_add:", state); // Do lots of full rounds int r = 1; for ( ; r <= 9; r++) { + loggers::get_instance().log("rijndael::rijndael_encrypt: Round %d:",r); byte_sub(state); + loggers::get_instance().log_rijndael_state("byte_sub: ", state); shift_row(state); + loggers::get_instance().log_rijndael_state("shift_row: ", state); mix_column(state); + loggers::get_instance().log_rijndael_state("mix_column: ", state); key_add(state, _round_keys, r); + loggers::get_instance().log_rijndael_state("key_add: ", state); } // End of 'for' statement // Final round byte_sub(state); + loggers::get_instance().log_rijndael_state("rijndael::rijndael_encrypt: Final round: byte_sub: ", state); shift_row(state); + loggers::get_instance().log_rijndael_state("rijndael::rijndael_encrypt: Final round: shift_row: ", state); key_add(state, _round_keys, r); + loggers::get_instance().log_rijndael_state("rijndael::rijndael_encrypt: Final round: key_add: ", state); /* produce output byte string from state array */ for (int i = 0; i < 16; i++) { p_output[i] = state[i & 0x3][i>>2]; } // End of 'for' statement + loggers::get_instance().log_to_hexa("<<< rijndael::rijndael_encrypt: ", p_output, 16); } void rijndael::key_add(uint8_t p_state[4][4], const uint8_t p_round_keys[11][4][4], const int p_round) { diff --git a/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ b/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ index 9a5c40c..b7f9e0e 100644 --- a/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ +++ b/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ @@ -59,13 +59,35 @@ system.N2_gNBaMF_P.params := "NGAP/SCTP_FILE/IP_OFFLINE/ETH(mac_src=8c554ac1eee0 # In this section you can specify what parts of your test suite you want to execute. #AtsImsIot_TestControl.control +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_01 +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_02 +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_03 +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_04 + +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_01 +NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01 + #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_01 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_02 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_03 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_04 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_05 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_ABN_01 -NG_NAS_TestCases.TC_NGNAS_AMF_AUT_SEQ_01 +#NG_NAS_TestCases.TC_NGNAS_AMF_AUT_SEQ_01 #NG_NAS_TestCases.TC_5GNAS_AMF_SEC_ACC_01 #NG_NAS_TestCases.TC_5GNAS_AMF_SEC_REJ_01 #NG_NAS_TestCases.TC_5GNAS_AMF_DLN_ACC_01 diff --git a/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn b/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn index ebff74a..1df3001 100644 --- a/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn +++ b/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn @@ -15,24 +15,30 @@ module NG_NAS_TestCases { // LibCommon import from LibCommon_Sync all ; - // NG_NAS + // Lib3GPP + import from CommonDefs all; + + // Lib_NG_NAS import from Lib_NG_NAS_Interface all; + import from LIB_NG_NAS_Functions all; + + // NG_NAS import from NG_NAS_TCFunctions all; import from NG_NAS_Pics all; import from NG_NAS_TestConfiguration all; import from NG_NAS_TestSystem all; // LibNGAP - import from NGAP_Constants language "ASN.1:2002" all; - import from NGAP_CommonDataTypes language "ASN.1:2002" all; - import from NGAP_IEs language "ASN.1:2002" all; - import from NGAP_PDU_Contents language "ASN.1:2002" all; - import from NGAP_PDU_Descriptions language "ASN.1:2002" all; - import from NGAP_Containers language "ASN.1:2002" all; + import from NGAP_Constants language "ASN.1:2002" all; + import from NGAP_CommonDataTypes language "ASN.1:2002" all; + import from NGAP_IEs language "ASN.1:2002" all; + import from NGAP_PDU_Contents language "ASN.1:2002" all; + import from NGAP_PDU_Descriptions language "ASN.1:2002" all; + import from NGAP_Containers language "ASN.1:2002" all; - //import from LibNGAP_TypesAndValues all; - //import from LibNGAP_Templates all; - //import from LibNGAP_Pixits all; + //import from LibNGAP_TypesAndValues all; + //import from LibNGAP_Templates all; + //import from LibNGAP_Pixits all; // NGAP_Ats //import from LibNGAP_TypesAndValues all; @@ -41,6 +47,7 @@ module NG_NAS_TestCases { //import from NGAP_TCFunctions all; //import from NGAP_Pics all; + group TC_AMF { group /*5_4_*/fiveGMM_Common_Procedures { @@ -833,4 +840,677 @@ module NG_NAS_TestCases { } // End of group TC_AMF_NGAP + group fiveG_AKA_Crypto_Functions { + + /** + * @desc Verify that OP is set correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Annex 2: Specification of the Block Cipher Algorithm Rijndael + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.3 Test Set 1 + */ + testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.3 Test Set 1 + var O16_Type v_key := '465b5ce8 b199b49f aa5f0a2e e238a6bc'O; + var O16_Type v_plain_text := 'ee36f7cf037d37d3692f7f0399e7949a'O; + var O16_Type v_cypher := '9e2980c59739da67b136355e3cede6a2'O; + + var O16_Type v_cypher_computed; + var integer v_result := f_rijndael_encrypt(v_key, v_plain_text, v_cypher_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_rijndael_encrypt' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_cypher_computed, v_cypher))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_cypher_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_cypher_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01 + + /** + * @desc Verify that OP is set correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Annex 2: Specification of the Block Cipher Algorithm Rijndael + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.4. Test Set 2 + */ + testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.4. Test Set 2 + var O16_Type v_key := '0396eb317b6d1c36f19c1c84cd6ffd16'O; + var O16_Type v_plain_text := '93cc3640c5d6a521d81235bd0882bf0a'O; + var O16_Type v_cypher := '009a9e0996561525f611667bbf79e226'O; + + var O16_Type v_cypher_computed; + var integer v_result := f_rijndael_encrypt(v_key, v_plain_text, v_cypher_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_rijndael_encrypt' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_cypher_computed, v_cypher))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_cypher_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_cypher_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_02 + + /** + * @desc Verify that OP is set correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Annex 2: Specification of the Block Cipher Algorithm Rijndael + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.5. Test Set 3 + */ + testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_03() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.5. Test Set 3 + var O16_Type v_key := 'fec86ba6eb707ed08905757b1bb44b8f'O; + var O16_Type v_plain_text := '8f7a8f0d108b7f2d97a53eacc1d958d9'O; + var O16_Type v_cypher := '5d9bce854decaf0da93d28b7e35f608c'O; + + var O16_Type v_cypher_computed; + var integer v_result := f_rijndael_encrypt(v_key, v_plain_text, v_cypher_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_rijndael_encrypt' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_cypher_computed, v_cypher))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_cypher_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_cypher_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_03 + + /** + * @desc Verify that OP is set correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Annex 2: Specification of the Block Cipher Algorithm Rijndael + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.6 Test Set 4 + */ + testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_04() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.6 Test Set 4 + var O16_Type v_key := '9e5944aea94b81165c82fbf9f32db751'O; + var O16_Type v_plain_text := '68c98bbfab628ec1adf2a3d90c34a751'O; + var O16_Type v_cypher := 'db2944cce8e683cd03fff19931a12135'O; + + var O16_Type v_cypher_computed; + var integer v_result := f_rijndael_encrypt(v_key, v_plain_text, v_cypher_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_rijndael_encrypt' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_cypher_computed, v_cypher))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_cypher_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_cypher_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_04 + + /** + * @desc Verify that OP is set correctly + * @see ETSI TS 135 205 V16.0.0 (2020-08) Clause 8.3 Analysis of the role of OP and OPc + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var O16_Type v_test; + + f_set_op(v_op); + + f_get_op(v_test); + if (not(match(v_test, v_op))) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_get_op' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'fx_get_op' returned the expected value ***"); + setverdict(pass); + } + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_01 + + /** + * @desc Verify that computing of OPC is working fine + * @see ETSI TS 135 205 V16.0.0 (2020-08) Clause 8.3 Analysis of the role of OP and OPc + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var O16_Type v_opc := 'cd63cb71954a9f4e48a5994e37a02baf'O; + + var O16_Type v_opc_computed; + + f_set_op(v_op); + var integer v_result := f_compute_opc(v_K, v_opc_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_compute_opc' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_opc, v_opc_computed))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_opc_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_opc_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_01 + + /** + * @desc Verify that computing of OPC is working fine + * @see ETSI TS 135 205 V16.0.0 (2020-08) Clause 8.3 Analysis of the role of OP and OPc + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.4 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.4 Test Set 2 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var O16_Type v_opc := '53c15671c60a4b731c55b4a441c0bde2'O; + + var O16_Type v_opc_computed; + + f_set_op(v_op); + var integer v_result := f_compute_opc(v_K, v_opc_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_compute_opc' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_opc, v_opc_computed))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_opc_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_opc_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_02 + + /** + * @desc Verify that computing of OPC is working fine + * @see ETSI TS 135 205 V16.0.0 (2020-08) Clause 8.3 Analysis of the role of OP and OPc + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.5 Test Set 3 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_03() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.5 Test Set 3 + var O16_Type v_K := 'fec86ba6eb707ed08905757b1bb44b8f'O; // The long-term key: Subscriber key + var O16_Type v_op := 'dbc59adcb6f9a0ef735477b7fadf8374'O; // Operator Variant Algorithm Configuration Field + var O16_Type v_opc := '1006020f0a478bf6b699f15c062e42b3'O; + + var O16_Type v_opc_computed; + + f_set_op(v_op); + var integer v_result := f_compute_opc(v_K, v_opc_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_compute_opc' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_opc, v_opc_computed))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_opc_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_opc_computed' returned the expected value ***"); + setverdict(pass); + } + } + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_03 + + /** + * @desc Verify that the f_extract_xxx_from_autn functions are working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) Clause 3.1 Definitions + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_03() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var B64_Type v_mac := oct2bit('4a9ffac354dfafb3'O); // MAC: Message Authentication Code + + // Rebuild AUTN, the Authentication Token: AUTN = SQN ⊕ AK || AMF || MAC + var B128_Type v_autn := v_sqn & v_amf & v_mac; + + // Extract SQN from v_sqn_ak and XOR it with calculated MAC + var B48_Type v_sqn_ex := f_extract_sqn_ak_from_autn(v_autn); + var B16_Type v_amf_ex := f_extract_amf_from_autn(v_autn); + var B64_Type v_mac_ex := f_extract_mac_from_autn(v_autn); + + if (not(match(v_sqn_ex, v_sqn))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_sqn_ex' mismatch. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_sqn_ex' is as expected. ***"); + } + + if (not(match(v_amf_ex, v_amf))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_amf_ex' mismatch. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_amf_ex' is as expected. ***"); + } + + if (not(match(v_mac_ex, v_mac))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_ex' mismatch. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_ex' is as expected. ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_03 + + /** + * @desc Verify that the f1 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var B64_Type v_mac_a := oct2bit('4a9ffac354dfafb3'O); // MAC-A: Network authentication code + + f_set_op(v_op); + var B64_Type v_mac_a_computed; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn, v_amf, v_mac_a_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_mac_a_computed, v_mac_a))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_a_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_a_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_01 + + /** + * @desc Verify that the f1 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.4 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var B48_Type v_sqn := oct2bit('fd8eef40df7d'O); + var B16_Type v_amf := oct2bit('af17'O); // AMF: Authentication Management Field + var B64_Type v_mac_a := oct2bit('5df5b31807e258b0'O); // MAC-A: Network authentication code + + f_set_op(v_op); + var B64_Type v_mac_a_computed; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn, v_amf, v_mac_a_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_mac_a_computed, v_mac_a))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_a_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_a_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_02 + + /** + * @desc Verify that the f1 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.5 Test Set 3 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_03() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := 'fec86ba6eb707ed08905757b1bb44b8f'O; // The long-term key: Subscriber key + var O16_Type v_op := 'dbc59adcb6f9a0ef735477b7fadf8374'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('9f7c8d021accf4db213ccff0c7f71a6a'O); + var B48_Type v_sqn := oct2bit('9d0277595ffc'O); + var B16_Type v_amf := oct2bit('725c'O); // AMF: Authentication Management Field + var B64_Type v_mac_a := oct2bit('9cabc3e99baf7281'O); // MAC-A: Network authentication code + + f_set_op(v_op); + var B64_Type v_mac_a_computed; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn, v_amf, v_mac_a_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_mac_a_computed, v_mac_a))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_a_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_a_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_03 + + /** + * @desc Verify that the f1* functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var B64_Type v_mac_s := oct2bit('01cfaf9ec4e871e9'O); // MAC-S: Resynch authentication code + + f_set_op(v_op); + var B64_Type v_mac_s_computed; + var integer v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn, v_amf, v_mac_s_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_mac_s_computed, v_mac_s))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_s_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_s_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_01 + + /** + * @desc Verify that the f1* functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.4 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var B48_Type v_sqn := oct2bit('fd8eef40df7d'O); + var B16_Type v_amf := oct2bit('af17'O); // AMF: Authentication Management Field + var B64_Type v_mac_s := oct2bit('a8c016e51ef4a343'O); // MAC-S: Resynch authentication code + + f_set_op(v_op); + var B64_Type v_mac_s_computed; + var integer v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn, v_amf, v_mac_s_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_mac_s_computed, v_mac_s))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_s_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_s_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_02 + + /** + * @desc Verify that the f1* functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.5 Test Set 3 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_03() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var O16_Type v_K := 'fec86ba6eb707ed08905757b1bb44b8f'O; // The long-term key: Subscriber key + var O16_Type v_op := 'dbc59adcb6f9a0ef735477b7fadf8374'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('9f7c8d021accf4db213ccff0c7f71a6a'O); + var B48_Type v_sqn := oct2bit('9d0277595ffc'O); + var B16_Type v_amf := oct2bit('725c'O); // AMF: Authentication Management Field + var B64_Type v_mac_s := oct2bit('95814ba2b3044324'O); // MAC-S: Resynch authentication code + + f_set_op(v_op); + var B64_Type v_mac_s_computed; + var integer v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn, v_amf, v_mac_s_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_mac_s_computed, v_mac_s))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_s_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_mac_s_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_03 + + /** + * @desc Verify that the f2 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987 b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('535bc878505c5e56ea44d2dffeb95fc4'O); // Integrity key + var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_res_computed, v_res))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_res_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_res_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_01 + + /** + * @desc Verify that the f3 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key + var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ck_computed, v_ck))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ck_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ck_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_01 + + /** + * @desc Verify that the f4 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key + var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ik_computed, v_ik))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ik_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ik_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_01 + + /** + * @desc Verify that the f5 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key + var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ak_computed, v_ak))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ak_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ak_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_01 + + /** + * @desc Verify that the f5* functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.3 Test Set 1 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_ak_s := oct2bit('451e8beca43b'O); // Anonymity key for the re-synchronisation + + f_set_op(v_op); + var B48_Type v_ak_s_computed; + var integer v_result := f_f5star(oct2bit(v_K), v_rand, v_ak_s_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f5star' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ak_s_computed, v_ak_s))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ak_s_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ak_s_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01 + + } // End of group fiveG_AKA_Crypto_Functions + }// End of module NG_NAS_TestCases diff --git a/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn b/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn index 581b0fa..9aa459f 100644 --- a/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn +++ b/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn @@ -167,7 +167,7 @@ module LIB_NG_NAS_Functions { return; } // Compute RES/XRES - f_5g_aka_compute_res_xres(v_message.authentication_Request.rand.randValue, v_message.authentication_Request.autn.aUTN, v_message.authentication_Request.abba, PX_PLMN_IDENTITY, oct2hex(PX_SUPI_DIGITS), vc_ng_nas_security_params_type); + f_5g_aka_compute_res_xres(-, v_message.authentication_Request.rand.randValue, v_message.authentication_Request.autn.aUTN, v_message.authentication_Request.abba, PX_PLMN_IDENTITY, oct2hex(PX_SUPI_DIGITS), vc_ng_nas_security_params_type); // Send response vt_NgNasUl_Msg := m_NG_AUTHENTICATION_RESPONSE( { iei := '2d'O, iel := '10'O, res := vc_ng_nas_security_params_type.AuthParams.XRES } @@ -539,6 +539,7 @@ module LIB_NG_NAS_Functions { * @param [in,out] p_ng_nas_security_params_type Built security parameters */ function f_5g_aka_compute_res_xres( + in B128_Type p_long_term_key := PX_LONG_TERM_KEY, in B128_Type p_rand, in B128_Type p_autn, in ABBA p_abba, @@ -554,12 +555,12 @@ module LIB_NG_NAS_Functions { p_ng_nas_security_params_type.AuthParams.RandValue := p_rand; p_ng_nas_security_params_type.AuthParams.AUTN := p_autn; - log("f_5g_aka_compute_res_xres: PX_USIM_SECRET_KEY=", PX_USIM_SECRET_KEY); + log("f_5g_aka_compute_res_xres: PX_LONG_TERM_KEY=", PX_LONG_TERM_KEY); // Extract SQN from v_sqn_ak and XOR it with calculated MAC - var B48_Type v_sqn_ak := substr(p_autn, 0, 48); - var B16_Type v_amf := substr(p_autn, 48, 16); - var B64_Type v_mac := substr(p_autn, 64, 64); + var B48_Type v_sqn_ak := f_extract_sqn_ak_from_autn(p_autn); + var B16_Type v_amf := f_extract_amf_from_autn(p_autn); + var B64_Type v_mac := f_extract_mac_from_autn(p_autn); log("f_5g_aka_compute_res_xres: v_sqn_ak=", v_sqn_ak); log("f_5g_aka_compute_res_xres: v_amf=", v_amf); log("f_5g_aka_compute_res_xres: v_mac=", v_mac); @@ -571,7 +572,8 @@ module LIB_NG_NAS_Functions { var B128_Type v_ik; var B48_Type v_ak; var B64_Type v_res; - if (f_f2345(PX_USIM_SECRET_KEY, p_rand, v_res, v_ck, v_ik, v_ak) == -1) { + if (f_f2345(PX_LONG_TERM_KEY, p_rand, v_res, v_ck, v_ik, v_ak) == -1) { + log("f_f2345 failed: "); return false; } p_ng_nas_security_params_type.AuthParams.CK := v_ck; @@ -585,11 +587,13 @@ module LIB_NG_NAS_Functions { // Verify that MAC was accepted var B64_Type v_mac_p; - if (f_f1(PX_USIM_SECRET_KEY, p_rand, v_sqn, v_amf, v_mac_p) == -1) { + if (f_f1(PX_LONG_TERM_KEY, p_rand, v_sqn, v_amf, v_mac_p) == -1) { + log("f_f1 failed: "); return false; } log("f_5g_aka_compute_res_xres: v_mac_p=", v_mac_p); if (v_mac != v_mac_p) { + log("v_mac != v_mac_p"); return false; } @@ -627,16 +631,50 @@ module LIB_NG_NAS_Functions { // ); //log("f_5g_aka_compute_res_xres: KAMF=", p_ng_nas_security_params_type.KAMF); - // TODO Generate KMAF - - log("<<< f_5g_aka_compute_res_xres: ", p_ng_nas_security_params_type); return true; } // End of function f_5g_aka_compute_res_xres + + + + + function f_extract_sqn_ak_from_autn(in B128_Type p_autn) return B48_Type { + return substr(p_autn, 0, 48); + } + + function f_extract_amf_from_autn(in B128_Type p_autn) return B16_Type { + return substr(p_autn, 48, 16); + } + + function f_extract_mac_from_autn(in B128_Type p_autn) return B64_Type { + return substr(p_autn, 64, 64); + } + function f_set_op(in O16_Type p_op) { fx_set_op(p_op); } + function f_get_op(out O16_Type p_op) { + fx_get_op(p_op); + } + function f_compute_opc(in O16_Type p_authK, out O16_Type p_opc) return integer { + return fx_compute_opc(p_authK, p_opc); + } + + + + + + + external function fx_rijndael_encrypt(in octetstring p_key, in octetstring p_plain_text, out octetstring p_cypherer_text) return integer; + function f_rijndael_encrypt(in octetstring p_key, in octetstring p_plain_text, out octetstring p_cypherer_text) return integer { + return fx_rijndael_encrypt(p_key, p_plain_text, p_cypherer_text); + } + + + + + function f_f1(in B128_Type p_authK, in B128_Type p_rand, in B48_Type v_sqn, in B16_Type v_amf, out B64_Type v_mac_a) return integer { return fx_f1(p_authK, p_rand, v_sqn, v_amf, v_mac_a); @@ -647,7 +685,7 @@ module LIB_NG_NAS_Functions { } function f_f2345(in B128_Type p_authK, in B128_Type p_rand, out B64_Type v_res, out B128_Type v_ck, out B128_Type v_ik, out B48_Type v_ak) return integer { - return fx_f2345(p_authK, p_rand, v_res, v_ik, v_ck, v_ak); + return fx_f2345(p_authK, p_rand, v_res, v_ck, v_ik, v_ak); } function f_f5star(in B128_Type p_authK, in B128_Type p_rand, out B48_Type p_ak) return integer { @@ -655,6 +693,8 @@ module LIB_NG_NAS_Functions { } external function fx_set_op(in O16_Type p_op); + external function fx_get_op(out O16_Type p_op); + external function fx_compute_opc(in O16_Type p_authK, out O16_Type p_opc) return integer; external function fx_f1(in B128_Type p_authK, in B128_Type p_rand, in B48_Type v_sqn, in B16_Type v_amf, out B64_Type v_mac_a) return integer; external function fx_f1star(in B128_Type p_authK, in B128_Type p_rand, in B48_Type v_sqn, in B16_Type v_amf, out B64_Type v_mac_s) return integer; external function fx_f2345(in B128_Type p_authK, in B128_Type p_rand, out B64_Type v_res, out B128_Type v_ck, out B128_Type v_ik, out B48_Type v_ak) return integer; diff --git a/ttcn/Lib_NG_NAS/Lib_NG_NAS_Pixits.ttcn b/ttcn/Lib_NG_NAS/Lib_NG_NAS_Pixits.ttcn index 59ccfc4..b6dc62c 100755 --- a/ttcn/Lib_NG_NAS/Lib_NG_NAS_Pixits.ttcn +++ b/ttcn/Lib_NG_NAS/Lib_NG_NAS_Pixits.ttcn @@ -20,7 +20,7 @@ module Lib_NG_NAS_Pixits { modulepar O16_Type PX_USIM_OPERATOR_VARIANT_ALGORITHM_CONFIGURATION := '00000000000000000000000000000000'O; - modulepar B128_Type PX_USIM_SECRET_KEY := oct2bit('00000000000000000000000000000000'O); + modulepar B128_Type PX_LONG_TERM_KEY := oct2bit('00000000000000000000000000000000'O); modulepar NAS_PlmnId PX_PLMN := '000000'O; diff --git a/ttcn/Lib_NG_NAS/Lib_NG_NAS_Templates.ttcn b/ttcn/Lib_NG_NAS/Lib_NG_NAS_Templates.ttcn index 627d996..78f6ccd 100644 --- a/ttcn/Lib_NG_NAS/Lib_NG_NAS_Templates.ttcn +++ b/ttcn/Lib_NG_NAS/Lib_NG_NAS_Templates.ttcn @@ -443,7 +443,7 @@ module Lib_NG_NAS_Templates { template NG_TrackingAreaIdList p_ForbidTAIList_Roaming := *, template NG_TrackingAreaIdList p_ForbidTAIList_RegProvService := *, template ExtdCAGInfoList p_ExtdCAGInfoList := *, - template NSAG_Info p_NsagInfo + template NSAG_Info p_NsagInfo := * ) := { /* 24.501 cl. 8.2.7 */ /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ registration_Accept := { -- GitLab From ff1a5e5c744d6d883fc002aceb17c4f9271aa6f6 Mon Sep 17 00:00:00 2001 From: garciay Date: Tue, 19 Aug 2025 12:21:32 +0200 Subject: [PATCH 3/5] Enhance security tests group --- ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc | 44 +- ccsrc/Externals/common_ext.cc | 180 ++-- etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ | 76 +- titan-test-system-framework | 2 +- ttcn/Ats_NG_NAS/NG_NAS_TCFunctions.ttcn | 86 +- ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn | 890 +++++++++++++++++- ttcn/Lib3GPP/Common/CommonDefs.ttcn | 2 + .../NG_NAS/NG_NAS_SecurityFunctions.ttcn | 62 +- ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn | 80 +- 9 files changed, 1231 insertions(+), 191 deletions(-) diff --git a/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc b/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc index ca77731..e79682e 100644 --- a/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc +++ b/ccsrc/Externals/LIB_NG_NAS_Functions_ext.cc @@ -106,7 +106,7 @@ namespace LIB__NG__NAS__Functions { } // End of 'for' statement OCTETSTRING os(8, static_cast(&mac_a[0])); p_mac_a = oct2bit(os); - loggers::get_instance().log_msg("fx__f1star: p_mac_a: ", os); + loggers::get_instance().log_msg("fx__f1: p_mac_a: ", os); return 0; } @@ -174,8 +174,8 @@ namespace LIB__NG__NAS__Functions { } INTEGER fx__f2345(const BITSTRING& p_authK, const BITSTRING& p_rand, BITSTRING& p_res, BITSTRING& p_ck, BITSTRING& p_ik, BITSTRING& p_ak) { - loggers::get_instance().log_msg(">>> fx_f2345: p_authK: ", p_authK); - loggers::get_instance().log_msg(">>> fx_f2345: p_rand: ", p_rand); + loggers::get_instance().log_msg(">>> fx__f2345: p_authK: ", bit2oct(p_authK)); + loggers::get_instance().log_msg(">>> fx__f2345: p_rand: ", bit2oct(p_rand)); rijndael r; OCTETSTRING authK = bit2oct(p_authK); @@ -183,7 +183,7 @@ namespace LIB__NG__NAS__Functions { opc op(r, OP); uint8_t op_c[16] = { 0x00 }; op.compute_opc(op_c); - loggers::get_instance().log_to_hexa("fx_f2345: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", op_c, 16); + loggers::get_instance().log_to_hexa("fx__f2345: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", op_c, 16); OCTETSTRING rand = bit2oct(p_rand); uint8_t rijndael_input[16] = { 0x00 }; @@ -192,18 +192,18 @@ namespace LIB__NG__NAS__Functions { } // End of 'for' statement uint8_t temp[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, temp); - loggers::get_instance().log_to_hexa("fx_f2345: Value after 1st encryption: ", temp, 16); + loggers::get_instance().log_to_hexa("fx__f2345: Value after 1st encryption: ", temp, 16); // To obtain output block OUT2: XOR OPc and TEMP, rotate by r2=0, and XOR on the constant c2 (which is all zeroes except that the last bit is 1) for (int i = 0; i < 16; i++) { rijndael_input[i] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 1; - loggers::get_instance().log_to_hexa("fx_f2345: b entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", rijndael_input, 16); + loggers::get_instance().log_to_hexa("fx__f2345: b entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", rijndael_input, 16); uint8_t out[16] = { 0x00 }; r.rijndael_encrypt(rijndael_input, out); - loggers::get_instance().log_to_hexa("fx_f2345: f2/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f2/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; @@ -213,22 +213,22 @@ namespace LIB__NG__NAS__Functions { for (int i = 0; i < 8; i++) { res[i] = out[i + 8]; } // End of 'for' statement - loggers::get_instance().log_to_hexa("fx_f2345: f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", res, 8); + loggers::get_instance().log_to_hexa("fx__f2345: f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", res, 8); uint8_t ak[6] = { 0x00 }; for (int i = 0; i < 6; i++) { ak[i] = out[i]; } // End of 'for' statement - loggers::get_instance().log_to_hexa("fx_f2345: f5/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ak, 6); + loggers::get_instance().log_to_hexa("fx__f2345: f5/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ak, 6); // To obtain output block OUT3: XOR OPc and TEMP, rotate by r3=32, and XOR on the constant c3 (which is all zeroes except that the next to last bit is 1) for (int i = 0; i < 16; i++) { rijndael_input[(i + 12) % 16] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 2; - loggers::get_instance().log_to_hexa("fx_f2345: f3/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f3/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); r.rijndael_encrypt(rijndael_input, out); - loggers::get_instance().log_to_hexa("fx_f2345: f3/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f3/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16); for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; @@ -238,16 +238,16 @@ namespace LIB__NG__NAS__Functions { for (int i = 0; i < 16; i++) { ck[i] = out[i]; } // End of 'for' statement - loggers::get_instance().log_to_hexa("fx_f2345: f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ck, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ck, 16); // To obtain output block OUT4: XOR OPc and TEMP, rotate by r4=64, and XOR on the constant c4 (which is all zeroes except that the 2nd from last bit is 1) for (int i = 0; i < 16; i++) { rijndael_input[(i+8) % 16] = temp[i] ^ op_c[i]; } // End of 'for' statement rijndael_input[15] ^= 4; - loggers::get_instance().log_to_hexa("fx_f2345: f4/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", rijndael_input, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f4/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", rijndael_input, 16); r.rijndael_encrypt(rijndael_input, out); - loggers::get_instance().log_to_hexa("fx_f2345: f4/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", out, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f4/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", out, 16); for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; @@ -257,7 +257,7 @@ namespace LIB__NG__NAS__Functions { for (int i = 0; i < 16; i++) { ik[i] = out[i]; } // End of 'for' statement - loggers::get_instance().log_to_hexa("fx_f2345: f4/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", ik, 16); + loggers::get_instance().log_to_hexa("fx__f2345: f4/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", ik, 16); OCTETSTRING os(8, static_cast(&res[0])); p_res = oct2bit(os); @@ -267,10 +267,10 @@ namespace LIB__NG__NAS__Functions { p_ik = oct2bit(os); os = OCTETSTRING(6, static_cast(&ak[0])); p_ak = oct2bit(os); - loggers::get_instance().log_msg("fx_f2345: p_res: ", bit2oct(p_res)); - loggers::get_instance().log_msg("fx_f2345: p_ck: ", bit2oct(p_ck)); - loggers::get_instance().log_msg("fx_f2345: p_ik: ", bit2oct(p_ik)); - loggers::get_instance().log_msg("fx_f2345: p_ak: ", bit2oct(p_ak)); + loggers::get_instance().log_msg("fx__f2345: p_res: ", bit2oct(p_res)); + loggers::get_instance().log_msg("fx__f2345: p_ck: ", bit2oct(p_ck)); + loggers::get_instance().log_msg("fx__f2345: p_ik: ", bit2oct(p_ik)); + loggers::get_instance().log_msg("fx__f2345: p_ak: ", bit2oct(p_ak)); return 0; } @@ -286,7 +286,6 @@ namespace LIB__NG__NAS__Functions { uint8_t op_c[16] = { 0x00 }; op.compute_opc(op_c); loggers::get_instance().log_to_hexa("fx__f5star: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", op_c, 16); - OCTETSTRING rand = bit2oct(p_rand); uint8_t rijndael_input[16] = { 0x00 }; @@ -294,7 +293,6 @@ namespace LIB__NG__NAS__Functions { rijndael_input[i] = rand[i].get_octet() ^ op_c[i]; } // End of 'for' statement uint8_t temp[16] = { 0x00 }; - loggers::get_instance().log_to_hexa("fx__f5star: Before 1st encryption: ", rijndael_input, 16); r.rijndael_encrypt(rijndael_input, temp); // To obtain output block OUT5: XOR OPc and TEMP, rotate by r5=96, and XOR on the constant c5 (which is all zeroes except that the 3rd from last bit is 1) @@ -303,9 +301,9 @@ namespace LIB__NG__NAS__Functions { } // End of 'for' statement rijndael_input[15] ^= 8; uint8_t out[16] = { 0x00 }; - loggers::get_instance().log_to_hexa("fx__f5star: Before 2sd encryption: ", rijndael_input, 16); + loggers::get_instance().log_to_hexa("fx__f5star: f5*/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", rijndael_input, 16); r.rijndael_encrypt(rijndael_input, out); - loggers::get_instance().log_to_hexa("fx__f5star: After 2sd encryption: ", out, 16); + loggers::get_instance().log_to_hexa("fx__f5star: f5*/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", out, 16); for (int i = 0; i < 16; i++) { out[i] ^= op_c[i]; } // End of 'for' statement diff --git a/ccsrc/Externals/common_ext.cc b/ccsrc/Externals/common_ext.cc index ea34cad..dfd722e 100644 --- a/ccsrc/Externals/common_ext.cc +++ b/ccsrc/Externals/common_ext.cc @@ -1,62 +1,118 @@ -#include -#include -#include -#include - -#include "CommonDefs.hh" - -#include "base_time.hh" -//#include "converter.hh" -#include "loggers.hh" - -#include "hmac.hh" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#define earthRadius 6378137.0L -#define rbis = ((double)(earthRadius * M_PI / 180)) - -namespace CommonDefs { - - /** - * @desc This external function gets KEY - * @return The KEY - * @see fx_get...() return UInt64 - * @note ETSI TS 133 220 V18.3.0 (2024-05) Annex B.2 Generic key derivation function - */ - //INTEGER fx__KeyDerivationFunction(INTEGER const&, BITSTRING const&, OCTETSTRING const&){ - BITSTRING fx__KeyDerivationFunction(const INTEGER& p__KDF, const BITSTRING& p__Key, const OCTETSTRING& p__String){ - loggers::get_instance().log_msg(">>> fx__KeyDerivationFunction: p__KDF: ", p__KDF); - loggers::get_instance().log_msg(">>> fx__KeyDerivationFunction: p__Key: ", bit2oct(p__Key)); - - hmac h; // hash_algorithms::sha_256: p__KDF == 1 (tsc_KDF_HMAC_SHA_256 see CommonDefs.ttcn) - OCTETSTRING res; - if (h.generate(p__String, bit2oct(p__Key), res) == -1) { - loggers::get_instance().error("fx__KeyDerivationFunction: Key derivation failed"); - return int2bit(0, 0); - } - - loggers::get_instance().log_msg("<<< fx__KeyDerivationFunction: res: ", res); - return oct2bit(res); - } - /** - * @desc This external function gets the current time since 01/01/1970 in UTC format - * @return The current time since 01/01/1970 in UTC format in milliseconds - * @see fx_getSystemTime() return UInt64 - */ -//INTEGER fx__GetSystemTime(CommonDefs::Struct__tm__Type&, INTEGER&){ -void fx__GetSystemTime(CommonDefs::Struct__tm__Type& p__Struct__tm, INTEGER& p__TimezoneInfo){ - const time_t t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - tm* now = std::localtime(&t); - p__Struct__tm = Struct__tm__Type(now->tm_sec, now->tm_min, now->tm_hour, now->tm_mday, now->tm_mon, now->tm_year, now->tm_wday, now->tm_yday, now->tm_isdst); - p__TimezoneInfo = 0; // TODO FSCOM - - return; -} -//void fx__CalculateFCS32(BITSTRING const&) { - BITSTRING fx__CalculateFCS32(const BITSTRING& p__TMSI){ -return int2bit(0, 0); -} - -} // namespace CommonDefs +#include +#include +#include +#include + +#include "CommonDefs.hh" + +#include "base_time.hh" +//#include "converter.hh" +#include "loggers.hh" + +#include "sha256.hh" +#include "hmac.hh" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#define earthRadius 6378137.0L +#define rbis = ((double)(earthRadius * M_PI / 180)) + +namespace CommonDefs { + + /** + * @desc This external function gets KEY + * @return The KEY + * @see fx_get...() return UInt64 + * @note ETSI TS 133 220 V18.3.0 (2024-05) Annex B.2 Generic key derivation function + */ + //INTEGER fx__KeyDerivationFunction(INTEGER const&, BITSTRING const&, OCTETSTRING const&){ + BITSTRING fx__KeyDerivationFunction(const INTEGER& p__KDF, const BITSTRING& p__Key, const OCTETSTRING& p__String){ + loggers::get_instance().log_msg(">>> fx__KeyDerivationFunction: p__KDF: ", p__KDF); + loggers::get_instance().log_msg(">>> fx__KeyDerivationFunction: p__Key: ", bit2oct(p__Key)); + loggers::get_instance().log_msg(">>> fx__KeyDerivationFunction: p__String: ", p__String); + + if (p__KDF == 1) { // tsc_KDF_HMAC_SHA_256 see CommonDefs.ttcn + hmac h; + OCTETSTRING res; + if (h.generate(p__String, bit2oct(p__Key), res, false) == -1) { + loggers::get_instance().error("fx__KeyDerivationFunction: Key derivation failed"); + return int2bit(0, 0); + } + + loggers::get_instance().log_msg("<<< fx__KeyDerivationFunction: res: ", res); + return oct2bit(res); + } else { + loggers::get_instance().error("fx__KeyDerivationFunction: Unsupported KDF: %d", p__KDF); + return int2bit(0, 0); + } + } + + /** + * @desc This external function compute the SHA 256 hash of a string + * @param p__String The string to hash + * @return The SHA 256 hash of the specified string + * @see fx_sha256(in octetstring p_String) return B256_Type + */ + BITSTRING fx__sha256(const OCTETSTRING& p__String){ + loggers::get_instance().log_msg(">>> fx__sha256: p__String: ", p__String); + + sha256 sha; + OCTETSTRING res; + if (sha.generate(p__String, res) == -1) { + loggers::get_instance().error("fx__sha256: Key derivation failed"); + return int2bit(0, 0); + } + + loggers::get_instance().log_msg("<<< fx__sha256: res: ", res); + return oct2bit(res); + } + + /** + * @desc This external function gets the current time since 01/01/1970 in UTC format + * @return The current time since 01/01/1970 in UTC format in milliseconds + * @see fx_getSystemTime() return UInt64 + */ + //INTEGER fx__GetSystemTime(CommonDefs::Struct__tm__Type&, INTEGER&){ + void fx__GetSystemTime(CommonDefs::Struct__tm__Type& p__Struct__tm, INTEGER& p__TimezoneInfo){ + const time_t t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + tm* now = std::localtime(&t); + p__Struct__tm = Struct__tm__Type(now->tm_sec, now->tm_min, now->tm_hour, now->tm_mday, now->tm_mon, now->tm_year, now->tm_wday, now->tm_yday, now->tm_isdst); + p__TimezoneInfo = 0; // TODO FSCOM + + return; + } + //void fx__CalculateFCS32(BITSTRING const&) { + BITSTRING fx__CalculateFCS32(const BITSTRING& p__TMSI){ + loggers::get_instance().log_msg(">>> fx__CalculateFCS32: p__TMSI: ", p__TMSI); + + // Sanity checks + if (p__TMSI.lengthof() == 0) { + loggers::get_instance().error("fx__CalculateFCS32: Empty TMSI"); + return int2bit(0, 0); + } + + OCTETSTRING os = bit2oct(p__TMSI); + const unsigned char *data = static_cast(os); + if (data == NULL) { + loggers::get_instance().error("fx__CalculateFCS32: Failed to get data buffer"); + return int2bit(0, 0); + } + unsigned int crc = 0xffffffff; + for (size_t i = 0; i < os.lengthof(); i++) { + unsigned int val = (crc ^ os[i].get_octet()) & 0xFF; + for(size_t j = 0; j < 8; j++){ + val = val & 0x1 ? (val >> 1) ^ 0xEDB88320 : val >> 1; // 0xEDB88320 is the reverse of 0x04C11DB7 + } // End of 'for' statement + crc = val ^ crc >> 8; + } // End of 'for' statement + crc ^= 0xffffffff; + + crc = ((crc & 0xFF) << 24) | ((crc & 0xFF00) << 8) | ((crc & 0xFF0000) >> 8) | ((crc & 0xFF000000) >> 24); // Reverse the bits of the CRC value + OCTETSTRING crc_os(4, (const unsigned char*)&crc); + loggers::get_instance().log_msg("fx__CalculateFCS32: crc: ", crc_os); + + return oct2bit(crc_os); + } + +} // namespace CommonDefs diff --git a/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ b/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ index b7f9e0e..a5961f3 100644 --- a/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ +++ b/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ @@ -10,9 +10,16 @@ LibNGAP_Pixits.PX_AMF_NAME := "Kontron5G-amf" LibNGAP_Pixits.PX_RAN_UE_NGAP_ID := 0 LibNGAP_Pixits.PX_AMF_UE_NGAP_ID := 22 LibNGAP_Pixits.PX_PLMN_IDENTITY := '00f110'O +LibNGAP_Pixits.PX_GNB_ID := '0000000000000001001110'B -Lib_NG_NAS_Pixits.PX_SUPI_FORMAT := '0000'B -Lib_NG_NAS_Pixits.PX_SUPI_DIGITS := '00f110214300014444330302'O +Lib_NG_NAS_Pixits.PX_SUPI_FORMAT := '0000'B +Lib_NG_NAS_Pixits.PX_SUPI_DIGITS := '00f110214300014444330302'O +Lib_NG_NAS_Pixits.PX_USIM_OPERATOR_VARIANT_ALGORITHM_CONFIGURATION := '00000000000000000000000000000000'O +Lib_NG_NAS_Pixits.PX_LONG_TERM_KEY := '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'B +Lib_NG_NAS_Pixits.PX_PLMN := '000000'O; + + +NAS_5GC_Parameters.px_NAS_5GC_XRES_Length := 8 # In ETSI TS 135 206 V16.0.0 (2020-08) Table Table 5. f2 output, RES length is 8 octets (64 bits) [LOGGING] # In this section you can specify the name of the log file and the classes of events @@ -59,30 +66,8 @@ system.N2_gNBaMF_P.params := "NGAP/SCTP_FILE/IP_OFFLINE/ETH(mac_src=8c554ac1eee0 # In this section you can specify what parts of your test suite you want to execute. #AtsImsIot_TestControl.control -#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_01 -#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_02 -#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_03 -#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_04 - -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_02 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_03 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_03 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_02 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_03 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_02 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_03 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_01 -#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_01 -NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01 - #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_01 -#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_02 +###########################NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_02 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_03 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_04 #NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_05 @@ -104,6 +89,47 @@ NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01 #NG_NAS_TestCases.TC_5GNAS_AMF_DRG_REQ_02 #NG_NAS_TestCases.TC_5GNAS_AMF_DRG_REQ_03 + +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_01 +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_02 +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_03 +#NG_NAS_TestCases.TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_04 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_02_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_04_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_05_03 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_11 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_13 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_01 +#G_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_02 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_15_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_16_01 +NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_02 +NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_03 +NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_18_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_19_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01 + [GROUPS] # In this section you can specify groups of hosts. These groups can be used inside the # [COMPONENTS] section to restrict the creation of certain PTCs to a given set of hosts. diff --git a/titan-test-system-framework b/titan-test-system-framework index 9ed59eb..f8843ac 160000 --- a/titan-test-system-framework +++ b/titan-test-system-framework @@ -1 +1 @@ -Subproject commit 9ed59ebd3c0a769688262f2370f6d3c3507b2a5f +Subproject commit f8843ac9740f8efe537f4938918920c8e8f8e692 diff --git a/ttcn/Ats_NG_NAS/NG_NAS_TCFunctions.ttcn b/ttcn/Ats_NG_NAS/NG_NAS_TCFunctions.ttcn index 7fa779a..fca5346 100755 --- a/ttcn/Ats_NG_NAS/NG_NAS_TCFunctions.ttcn +++ b/ttcn/Ats_NG_NAS/NG_NAS_TCFunctions.ttcn @@ -64,7 +64,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); f_send_NasRegistrationRequest(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -83,7 +83,7 @@ module NG_NAS_TCFunctions { if (f_Check_5GAKA_NAS_DL_Message( vc_recvNAS_PDU, mw_NG_AUTHENTICATION_REQUEST( - '111'B, + '100'B, -, ?, // Authentication_parameter_RAND ? // Authentication_parameter_AUTN @@ -92,6 +92,9 @@ module NG_NAS_TCFunctions { ) == false) { setverdict(fail); log("*** " & __SCOPE__ & ": FAIL: Unexpected NG_AUTHENTICATION_REQUEST ***"); + } else { + setverdict(pass); + log("*** " & __SCOPE__ & ": PASS: Expected NG_AUTHENTICATION_REQUEST ***"); } f_selfOrClientSyncAndVerdict(c_tbDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Testbody done. ***"); @@ -111,10 +114,10 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); f_send_NasRegistrationRequest(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -131,6 +134,9 @@ module NG_NAS_TCFunctions { if (f_Check_5GAKA_NAS_DL_Message(vc_recvNAS_PDU, mw_NG_SECURITY_MODE_COMMAND, v_message) == false) { setverdict(fail); log("*** " & __SCOPE__ & ": FAIL: NG_SECURITY_MODE_COMMAND mismatch. ***"); + } else { + setverdict(pass); + log("*** " & __SCOPE__ & ": PASS: Expected NG_SECURITY_MODE_COMMAND ***"); } f_selfOrClientSyncAndVerdict(c_tbDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Testbody done. ***"); @@ -152,7 +158,7 @@ module NG_NAS_TCFunctions { var integer v_start_time_ms; // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); f_send_NasRegistrationRequest(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -214,7 +220,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); f_send_NasRegistrationRequest(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -279,7 +285,7 @@ module NG_NAS_TCFunctions { var NAS_KsiValue ngKSI; // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); f_send_NasRegistrationRequest(); f_decode_5G_NAS_DL_Message(vc_recvNAS_PDU, v_NG_NAS_DL_Message_Type); @@ -343,7 +349,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); f_send_NasRegistrationRequest(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -410,9 +416,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -453,10 +459,10 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -494,10 +500,10 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -543,9 +549,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_await_NGInitialContextSetupRequest_send_NGInitialContextSetupRespone(); f_send_NGUERadioCApabilityInfoIndication(); @@ -611,9 +617,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_send_NGUERadioCApabilityInfoIndication(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -726,9 +732,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_send_NGUERadioCApabilityInfoIndication(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -848,9 +854,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_send_NGUERadioCApabilityInfoIndication(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -971,9 +977,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_send_NGUERadioCApabilityInfoIndication(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -1089,9 +1095,9 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_send_NGSetupRequest_await_NGSetupRespone(); - f_await_NasAuthorizationRequest_send_NasAuthorizationResponse(); + f_await_NasAuthenticationRequest_send_NasAuthenticationResponse(); f_await_NasSecurityModeCommand_send_NasSecurityModeComplete(); f_send_NGUERadioCApabilityInfoIndication(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); @@ -1207,7 +1213,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1369,7 +1375,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1487,7 +1493,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1549,7 +1555,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1615,7 +1621,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); //USER REGISTRATION log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1669,7 +1675,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1751,7 +1757,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1819,7 +1825,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1842,7 +1848,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1865,7 +1871,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1888,7 +1894,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); @@ -1911,7 +1917,7 @@ module NG_NAS_TCFunctions { // Local variables // Preamble - f_NGAP_gnb_init(); + f_NGAP_gnb_init2(); f_selfOrClientSyncAndVerdict(c_prDone, f_getVerdict()); log("*** " & __SCOPE__ & ": INFO: Preamble done. ***"); diff --git a/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn b/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn index 1df3001..c8f0cb8 100644 --- a/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn +++ b/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn @@ -17,6 +17,11 @@ module NG_NAS_TestCases { // Lib3GPP import from CommonDefs all; + // Lib3GPP/NAS + import from NAS_CommonTypeDefs all; + import from NAS_AuthenticationCommon all; + // Lib3GPP/NG_NAS + import from NG_NAS_SecurityFunctions all; // Lib_NG_NAS import from Lib_NG_NAS_Interface all; @@ -850,7 +855,7 @@ module NG_NAS_TestCases { testcase TC_5G_AKA_RIJNDAEL_FUNCTIONS_TEST_01_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 3.3 Test Set 1 - var O16_Type v_key := '465b5ce8 b199b49f aa5f0a2e e238a6bc'O; + var O16_Type v_key := '465b5ce8b199b49faa5f0a2ee238a6bc'O; var O16_Type v_plain_text := 'ee36f7cf037d37d3692f7f0399e7949a'O; var O16_Type v_cypher := '9e2980c59739da67b136355e3cede6a2'O; @@ -1338,9 +1343,9 @@ module NG_NAS_TestCases { var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); - var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table - var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987 b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table - var B128_Type v_ik := oct2bit('535bc878505c5e56ea44d2dffeb95fc4'O); // Integrity key + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key f_set_op(v_op); @@ -1353,7 +1358,7 @@ module NG_NAS_TestCases { log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); setverdict(fail); } else { - if (not(match(v_res_computed, v_res))) { + if (not(match(v_res_computed, v_xres))) { log("*** " & __SCOPE__ & ": ERROR: 'v_res_computed' did not return the expected value. ***"); setverdict(fail); } else { @@ -1365,6 +1370,44 @@ module NG_NAS_TestCases { } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_01 + /** + * @desc Verify that the f2 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B64_Type v_xres := oct2bit('d3a628ed988620f0'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('58c433ff 7a7082ac d424220f 2b67c556'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('21a8c1f929702adb3e738488b9f5c5da'O); // Integrity key + var B48_Type v_ak := oct2bit('c47783995f72'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_res_computed, v_xres))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_res_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_res_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_06_02 + /** * @desc Verify that the f3 functions is working correctly * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework @@ -1376,7 +1419,7 @@ module NG_NAS_TestCases { var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); - var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key @@ -1403,6 +1446,44 @@ module NG_NAS_TestCases { } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_01 + /** + * @desc Verify that the f3 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B64_Type v_xres := oct2bit('d3a628ed988620f0'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('58c433ff 7a7082ac d424220f 2b67c556'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('21a8c1f929702adb3e738488b9f5c5da'O); // Integrity key + var B48_Type v_ak := oct2bit('c47783995f72'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ck_computed, v_ck))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ck_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ck_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_07_02 + /** * @desc Verify that the f4 functions is working correctly * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework @@ -1414,7 +1495,7 @@ module NG_NAS_TestCases { var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); - var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key @@ -1441,6 +1522,44 @@ module NG_NAS_TestCases { } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_01 + /** + * @desc Verify that the f4 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B64_Type v_xres := oct2bit('d3a628ed988620f0'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('58c433ff 7a7082ac d424220f 2b67c556'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('21a8c1f929702adb3e738488b9f5c5da'O); // Integrity key + var B48_Type v_ak := oct2bit('c47783995f72'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ik_computed, v_ik))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ik_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ik_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_08_02 + /** * @desc Verify that the f5 functions is working correctly * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework @@ -1452,7 +1571,7 @@ module NG_NAS_TestCases { var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); - var B64_Type v_res := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key @@ -1479,6 +1598,45 @@ module NG_NAS_TestCases { } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_01 + /** + * @desc Verify that the f5 functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B64_Type v_xres := oct2bit('d3a628ed988620f0'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('58c433ff 7a7082ac d424220f 2b67c556'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('21a8c1f929702adb3e738488b9f5c5da'O); // Integrity key + var B48_Type v_ak := oct2bit('c47783995f72'O); // Anonymity key + + f_set_op(v_op); + var B64_Type v_res_computed; + var B128_Type v_ck_computed; + var B128_Type v_ik_computed; + var B48_Type v_ak_computed; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_res_computed, v_ck_computed, v_ik_computed, v_ak_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ak_computed, v_ak))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ak_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ak_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_02 + /** * @desc Verify that the f5* functions is working correctly * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework @@ -1488,12 +1646,12 @@ module NG_NAS_TestCases { // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.3 Test Set 1 var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key - var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); - var B48_Type v_ak_s := oct2bit('451e8beca43b'O); // Anonymity key for the re-synchronisation + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B48_Type v_ak_s := oct2bit('451e8beca43b'O); // Anonymity key for the re-synchronisation f_set_op(v_op); - var B48_Type v_ak_s_computed; + var B48_Type v_ak_s_computed; var integer v_result := f_f5star(oct2bit(v_K), v_rand, v_ak_s_computed); if (v_result != 0) { log("*** " & __SCOPE__ & ": ERROR: 'f_f5star' returned an error code: " & int2str(v_result) & ". ***"); @@ -1511,6 +1669,714 @@ module NG_NAS_TestCases { } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_01 - } // End of group fiveG_AKA_Crypto_Functions + /** + * @desc Verify that the f5* functions is working correctly + * @see ETSI TS 135 206 V16.0.0 (2020-08) Clause 4.1 Algorithm Framework + * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.3 Test Set 2 + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.3 Test Set 1 + var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); + var O16_Type v_op := 'ff53bade17df5d4e793073ce9d7579fa'O; // Operator Variant Algorithm Configuration Field + var B48_Type v_ak_s := oct2bit('30f1197061c1'O); // Anonymity key for the re-synchronisation + + f_set_op(v_op); + var B48_Type v_ak_s_computed; + var integer v_result := f_f5star(oct2bit(v_K), v_rand, v_ak_s_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f5star' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + } else { + if (not(match(v_ak_s_computed, v_ak_s))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_ak_s_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_ak_s_computed' returned the expected value ***"); + } + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_10_02 + + /** + * @desc Verify that the KeyDerivationFunctions is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_11() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + var B256_Type v_Ks := oct2bit('efa09b59f3995f1a4ec7e99816290253c01ce4d774b21e1e141379d59c665ee3'O); // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + var octetstring v_S := '06D540050123456789000f00000002'O; + var B256_Type v_derived_key := oct2bit('0c01ec8210931fdaa57448583b69e8f0ce99db7560d07dd3719765d26bf4c12f'O); + + var B256_Type v_derived_key_computed := fx_KeyDerivationFunction(1, v_Ks, v_S); + if (not(match(v_derived_key_computed, v_derived_key))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_derived_key_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_derived_key_computed' returned the expected value ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_11 + + /** + * @desc Verify that the fl_GetServingNetworkName function is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + var octetstring v_P0 := fl_GetServingNetworkName(v_PLMN, v_NID); + log("v_P0 =", oct2char(v_P0)); + if (v_P0 != '35473A6D6E633030312E6D63633030312E336770706E6574776F726B2E6F72673A303030313338'O) { + log("*** " & __SCOPE__ & ": ERROR: 'fl_GetServingNetworkName' returned an unexpected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'fl_GetServingNetworkName' returned: " & oct2char(v_P0) & " ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_01 + + /** + * @desc Verify that the fl_GetServingNetworkName function is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + var NAS_PlmnId v_PLMN := '641010'O; // PLMN ID: 001-01 + var octetstring v_P0 := fl_GetServingNetworkName(v_PLMN); + log("v_P0 =", oct2char(v_P0)); + if (v_P0 != '35473a6d6e633031312e6d63633436302e336770706e6574776f726b2e6f7267'O) { + log("*** " & __SCOPE__ & ": ERROR: 'fl_GetServingNetworkName' returned an unexpected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'fl_GetServingNetworkName' returned: " & oct2char(v_P0) & " ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_02 + + // 13: fl_GetNAI + + /** + * @desc Verify that the fx__CalculateFCS32 function is working correctly + * @see https://crccalc.com/?crc=aaaaaaaaaaaa5555555555550004deadbeef&method=CRC-32&datatype=hex&outtype=hex + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + var bitstring v_crc := oct2bit('855D5CB0'O); + + var bitstring v_crc_computed := fx_CalculateFCS32(oct2bit('aaaaaaaaaaaa5555555555550004deadbeef'O)); + log(v_crc); + log(v_crc_computed); + if (not(match(v_crc_computed, v_crc))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_crc_computed' returned an unexpected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_crc_computed' returned: ", bit2oct(v_crc_computed), " ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_01 + + /** + * @desc Verify that the fx__CalculateFCS32 function is working correctly + * @see https://crccalc.com/?crc=35473A6D6E633030312E6D63633030312E336770706E6574776F726B2E6F72673A303030313338&method=CRC-32&datatype=hex&outtype=hex + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + var bitstring v_crc := oct2bit('C2FE72FD'O); + + var bitstring v_crc_computed := fx_CalculateFCS32(oct2bit('35473A6D6E633030312E6D63633030312E336770706E6574776F726B2E6F72673A303030313338'O)); + log(match(v_crc_computed, v_crc)); + if (not(match(v_crc_computed, v_crc))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_crc_computed' returned an unexpected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_crc_computed' returned: ", bit2oct(v_crc_computed), " ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_02 + + /** + * @desc Verify that the KAUSF derivation function is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_15_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var B48_Type v_sqn_ak := oct2bit('000102030405'O); // SQN: Sequence Number + var B16_Type v_amf := oct2bit('0000'O); // Dummy value + var B64_Type v_mac_a := oct2bit('0000000000000000'O); // Dummy value + var B128_Type v_ck := oct2bit('4a3b7c89acbd1234ef567890abcdef12'O); + var B128_Type v_ik := oct2bit('9f1e2345ac7890fab345678912345678'O); + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + + var Common_AuthenticationParams_Type v_auth_params; + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + var B256_Type v_k_ausf := oct2bit('69EC2C51E14725BCCB24562470C25BE38C45701DCEBB6EF38B48ACE1082FE3C0'O); + var B256_Type v_k_ausf_computed := f_NG_Authentication_A2(v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_PLMN, v_NID); + if (not(match(v_k_ausf_computed, v_k_ausf))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_k_ausf_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_k_ausf_computed' returned the expected value ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_15_01 + + /** + * @desc Verify that the CK' and IK' derivation function is working correctly + * @see ETSI TS 133 402 V16.0.0 (2020-08) A.2 Function for the derivation of CK’, IK’ from CK, IK + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.3 CK' and IK' derivation function + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_16_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 + var B48_Type v_sqn_ak := oct2bit('000102030405'O); // SQN: Sequence Number + var B16_Type v_amf := oct2bit('0000'O); // Dummy value + var B64_Type v_mac_a := oct2bit('0000000000000000'O); // Dummy value + var B128_Type v_ck := oct2bit('4a3b7c89acbd1234ef567890abcdef12'O); + var B128_Type v_ik := oct2bit('9f1e2345ac7890fab345678912345678'O); + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + var B128_Type v_ck_p := oct2bit('23e5e46389721ca3a3abe4a0c9e60efd'O); + var B128_Type v_ik_p := oct2bit('fce88fcd5e9e293ba6adaa5934c3687c'O); + + var B256_Type v_derived_key := oct2bit('23e5e46389721ca3a3abe4a0c9e60efdfce88fcd5e9e293ba6adaa5934c3687c'O); + + var Common_AuthenticationParams_Type v_auth_params; + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + var B256_Type v_derived_key_computed := f_NG_Authentication_A3(v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_PLMN, v_NID); + if (not(match(v_derived_key_computed, v_derived_key))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_derived_key_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_derived_key_computed' returned the expected value: ", v_derived_key_computed, " ***"); + var B128_Type v_Ck_computed := substr (v_derived_key_computed, 0, 128); + log("*** " & __SCOPE__ & ": v_Ck_computed: ", v_Ck_computed, " ***"); + var B128_Type v_Ik_computed := substr (v_derived_key_computed, 128, 128); + log("*** " & __SCOPE__ & ": v_Ik_computed: ", v_Ik_computed, " ***"); + if (not(match(v_Ck_computed, v_ck_p))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_Ck_computed' did not return the expected value. ***"); + setverdict(fail); + } + if (not(match(v_Ik_computed, v_ik_p))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_Ik_computed' did not return the expected value. ***"); + setverdict(fail); + } + + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_16_01 + + /** + * @desc Verify that the RES* and XRES* derivation functions are working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.4 RES* and XRES* derivation function + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see https://www.eurecom.fr/publication/6408/download/comsys-publi-6408.pdf + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From https://www.eurecom.fr/publication/6408/download/comsys-publi-6408.pdf DATA 1 + var O16_Type v_K := '00112233445566778899aabbccddeeff'O; // The long-term key: Subscriber key + var O16_Type v_op := '000102030405060708090a0b0c0d0e0f'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('6a8959fb188c73308d679f7bc8313d65'O); + var B48_Type v_sqn_ak := oct2bit('97779b305686'O); + var NAS_PlmnId v_PLMN := '641010'O; // PLMN ID: 641-010 + + f_set_op(v_op); + + var B64_Type v_xres := oct2bit('6283ace5e894a0ad'O); + var B64_Type v_xres_computed; + var B128_Type v_ck; + var B128_Type v_ik; + var B48_Type v_ak; + var integer v_result := f_f2345(oct2bit(v_K), v_rand, v_xres_computed, v_ck, v_ik, v_ak); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + if (not(match(v_xres_computed, v_xres))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_xres_computed' did not return the expected value. ***"); + setverdict(fail); + } + + var B256_Type v_Ks := oct2bit('12757da1c0747d4a88b7d8b86446244b7f64a6ccf95b98b25e9a41f007037d86'O); + var B256_Type v_Ks_computed := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + if (not(match(v_Ks_computed, v_Ks))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_Ks_computed' did not return the expected value. ***"); + setverdict(fail); + } + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + v_auth_params.XRES := v_xres; + v_auth_params.XRESLength := lengthof(v_xres); + + var B64_Type v_RESstar := oct2bit('03f8627a00448408'O); + var B64_Type v_XRESstar := oct2bit('6f35398f7c56df32'O); + + var B128_Type v_res := f_NG_Authentication_A4(v_PLMN, v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks); + var B64_Type v_RESstar_computed := substr(v_res, 0, 64); + var B64_Type v_XRESstar_computed := substr(v_res, 64, 64); + if (not(match(v_RESstar_computed, v_RESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_RESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_RESstar_computed' returned the expected value ***"); + } + if (not(match(v_XRESstar_computed, v_XRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_XRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_XRESstar_computed' returned the expected value ***"); + } + + var octetstring v_S := '6b35473a6d6e633031312e6d63633436302e336770706e6574776f726b2e6f726700206a8959fb188c73308d679f7bc8313d6500106283ace5e894a0ad0008'O; + var B256_Type v_k_ausf := oct2bit('117cc3da749fb0b92c6fc4f4547a1e7af9499391028d80d75bfe88eb813ead4c'O); + var B256_Type v_k_ausf_computed := fx_KeyDerivationFunction(1, v_Ks, v_S); + if (not(match(v_k_ausf_computed, v_k_ausf))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_k_ausf_computed' did not return the expected value. ***"); + setverdict(fail); + } + var B256_Type v_k_ausf_A2 := f_NG_Authentication_A2(v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_PLMN); + log("v_k_ausf (f_NG_Authentication_A2): ", bit2oct(v_k_ausf_A2)); + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01 + + /** + * @desc Verify that the RES* and XRES* derivation functions are working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.4 RES* and XRES* derivation function + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn_ak := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + + f_set_op(v_op); + + var B64_Type v_mac_a; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_a); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_mac_s; + v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_s); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_xres; + var B128_Type v_ck; + var B128_Type v_ik; + var B48_Type v_ak; + v_result := f_f2345(oct2bit(v_K), v_rand, v_xres, v_ck, v_ik, v_ak); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + v_auth_params.XRES := v_xres; + v_auth_params.XRESLength := lengthof(v_xres); + + var B64_Type v_RESstar := oct2bit('03F8627A00448408'O); + var B64_Type v_XRESstar := oct2bit('6F35398F7C56DF32'O); + + var B128_Type v_res := f_NG_Authentication_A4(v_PLMN, v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_NID); + var B64_Type v_RESstar_computed := substr(v_res, 0, 64); + var B64_Type v_XRESstar_computed := substr(v_res, 64, 64); + log("v_RESstar_computed =", v_RESstar_computed); + log("v_XRESstar_computed =", v_XRESstar_computed); + if (not(match(v_RESstar_computed, v_RESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_RESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_RESstar_computed' returned the expected value ***"); + } + if (not(match(v_XRESstar_computed, v_XRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_XRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_XRESstar_computed' returned the expected value ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_02 + + /** + * @desc Verify that the RES* and XRES* derivation functions are working correctly with Kontron Wireshark captures + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.4 RES* and XRES* derivation function + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_03() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From Kontron Wireshark captures: UI=001014444333000 + var O16_Type v_K := '00000000000000000000000000000000'O; // The long-term key: Subscriber key + var O16_Type v_op := '00000000000000000000000000000000'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('807df0fdd3ef28786d10f425df603f3b'O); + var B48_Type v_sqn_ak := oct2bit('b22bfb46d847'O); + var B16_Type v_amf := oct2bit('8000'O); // AMF: Authentication Management Field + var B64_Type v_mac_a := oct2bit('5cd041c2fc08f6da'O); + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + + f_set_op(v_op); + + var B64_Type v_mac_a_computed; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_a_computed); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + if (not(match(v_mac_a_computed, v_mac_a))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_mac_a_computed' did not return the expected value. ***"); + setverdict(fail); + stop; + } + + var B64_Type v_xres; + var B128_Type v_ck; + var B128_Type v_ik; + var B48_Type v_ak; + v_result := f_f2345(oct2bit(v_K), v_rand, v_xres, v_ck, v_ik, v_ak); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + v_auth_params.XRES := v_xres; + v_auth_params.XRESLength := lengthof(v_xres); + + var B64_Type v_RESstar := oct2bit('a7c39d021cc80709'O); + var B64_Type v_XRESstar := oct2bit('60775ce133f05be3'O); + + var B128_Type v_res := f_NG_Authentication_A4(v_PLMN, v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks); + var B64_Type v_RESstar_computed := substr(v_res, 0, 64); + var B64_Type v_XRESstar_computed := substr(v_res, 64, 64); + log("v_RESstar_computed =", v_RESstar_computed); + log("v_XRESstar_computed =", v_XRESstar_computed); + if (not(match(v_RESstar_computed, v_RESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_RESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_RESstar_computed' returned the expected value ***"); + } + if (not(match(v_XRESstar_computed, v_XRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_XRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_XRESstar_computed' returned the expected value ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_03 + + /** + * @desc Verify that the HRES* and HXRES* derivation function is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.6 KSEAF derivation function + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_18_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn_ak := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + + f_set_op(v_op); + + var B64_Type v_mac_a; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_a); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_mac_s; + v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_s); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_xres; + var B128_Type v_ck; + var B128_Type v_ik; + var B48_Type v_ak; + v_result := f_f2345(oct2bit(v_K), v_rand, v_xres, v_ck, v_ik, v_ak); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + v_auth_params.XRES := v_xres; + v_auth_params.XRESLength := lengthof(v_xres); + + var B128_Type v_res := f_NG_Authentication_A4(v_PLMN, v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_NID); + var B64_Type v_RESstar := substr(v_res, 0, 64); + var B64_Type v_XRESstar := substr(v_res, 64, 64); + log("v_RESstar: ", bit2oct(v_RESstar)); + log("v_XRESstar: ", bit2oct(v_XRESstar)); + + // Using RES* + var B64_Type v_HRESstar := oct2bit('73DE4773A2C4222A'O); + var B64_Type v_HXRESstar := oct2bit('8E36B2B676510129'O); + var B128_Type v_hres := f_NG_Authentication_A5(v_rand, v_RESstar, tsc_KDF_HMAC_SHA_256, v_Ks); + var B64_Type v_HRESstar_computed := substr(v_hres, 0, 64); + var B64_Type v_HXRESstar_computed := substr(v_hres, 64, 64); + log("v_HRESstar_computed: ", bit2oct(v_HRESstar_computed)); + log("v_HXRESstar_computed: ", bit2oct(v_HXRESstar_computed)); + if (not(match(v_HRESstar_computed, v_HRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_HRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_HRESstar_computed' returned the expected value ***"); + } + if (not(match(v_HXRESstar_computed, v_HXRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_HXRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_HXRESstar_computed' returned the expected value ***"); + } + + var bitstring v_S := v_rand & v_HXRESstar; + var B256_Type v_sha256 := fx_sha256(bit2oct(v_S)); + log("v_sha256: ", bit2oct(v_sha256)); + log("High 128 bits (1): ", bit2oct(substr(v_sha256, 0, 128))); + log("Low 128 bits (1) : ", bit2oct(substr(v_sha256, 128, 128))); + + // Using XRES* + v_HRESstar := oct2bit('4DF167EA4AF5720C'O); + v_HXRESstar := oct2bit('66597478359DA9FA'O); + v_hres := f_NG_Authentication_A5(v_rand, v_XRESstar, tsc_KDF_HMAC_SHA_256, v_Ks); + v_HRESstar_computed := substr(v_hres, 0, 64); + v_HXRESstar_computed := substr(v_hres, 64, 64); + log("v_HRESstar_computed: ", bit2oct(v_HRESstar_computed)); + log("v_HXRESstar_computed: ", bit2oct(v_HXRESstar_computed)); + if (not(match(v_HRESstar_computed, v_HRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_HRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_HRESstar_computed' returned the expected value ***"); + } + if (not(match(v_HXRESstar_computed, v_HXRESstar))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_HXRESstar_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_HXRESstar_computed' returned the expected value ***"); + } + + v_S := v_rand & v_HXRESstar; + v_sha256 := fx_sha256(bit2oct(v_S)); + log("v_sha256: ", bit2oct(v_sha256)); + log("High 128 bits (2): ", bit2oct(substr(v_sha256, 0, 128))); + log("Low 128 bits (2) : ", bit2oct(substr(v_sha256, 128, 128))); + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_18_01 + + /** + * @desc Verify that the KSEAF derivation function is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.6 KSEAF derivation function + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_19_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B48_Type v_sqn_ak := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + + f_set_op(v_op); + + var B64_Type v_mac_a; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_a); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_mac_s; + v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_s); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + + var B64_Type v_xres; + var B128_Type v_ck; + var B128_Type v_ik; + var B48_Type v_ak; + v_result := f_f2345(oct2bit(v_K), v_rand, v_xres, v_ck, v_ik, v_ak); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + v_auth_params.XRES := v_xres; + v_auth_params.XRESLength := lengthof(v_xres); + + var B256_Type v_k_ausf := f_NG_Authentication_A2(v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_PLMN, v_NID); + log("v_k_ausf: ", bit2oct(v_k_ausf)); + + var B256_Type v_k_seaf := oct2bit('B435F90FEA784700244C12804C53E087E0E2B90C8E9DDCE76EC4D3811FDEB901'O); + var B256_Type v_k_seaf_computed := f_NG_Authentication_A6(v_PLMN, v_k_ausf, tsc_KDF_HMAC_SHA_256, v_NID); + if (not(match(v_k_seaf_computed, v_k_seaf))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_k_seaf_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_k_seaf_computed' returned the expected value ***"); + } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_19_01 + + /** + * @desc Verify that the KAMF derivation function is working correctly + * @see ETSI TS 133 501 V16.18.0 (2024-04) Figure 6.2.2-2: Key distribution and key derivation scheme for 5G for the UE + * @see ETSI TS 133 501 V16.18.0 (2024-04) A.7 KAMF derivation function + * @see https://cryptii.com/pipes/hmac + */ + testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { + + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B48_Type v_sqn_ak := oct2bit('ff9bb4d0b607'O); + var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + + f_set_op(v_op); + + var B64_Type v_mac_a; + var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_a); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_mac_s; + v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_s); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + var B64_Type v_xres; + var B128_Type v_ck; + var B128_Type v_ik; + var B48_Type v_ak; + v_result := f_f2345(oct2bit(v_K), v_rand, v_xres, v_ck, v_ik, v_ak); + if (v_result != 0) { + log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); + setverdict(fail); + stop; + } + // var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + // var octetstring v_S := '06D540050123456789000f00000002'O; + // var B256_Type v_k_aus := fx_KeyDerivationFunction(1, v_Ks, v_S); + // var B256_Type v_k_seaf := f_NG_Authentication_A6(v_PLMN, v_k_aus, tsc_KDF_HMAC_SHA_256, v_NID); + + // var charstring v_supi := "460110123456789"; + // var octetstring v_abba := '0000'O; // ETSI TS 133 501 V16.18.0 (2024-04) A.7.1 ABBA parameter values + // var B256_Type v_k_amf := int2bit(0, 256); // Expected KAMF value + // var B256_Type v_k_amf_computed := f_NG_Authentication_A7(v_supi, v_k_seaf, v_abba, tsc_KDF_HMAC_SHA_256); + // if (not(match(v_k_amf_computed, v_k_amf))) { + // log("*** " & __SCOPE__ & ": ERROR: 'v_k_amf_computed' did not return the expected value. ***"); + // setverdict(fail); + // } else { + // log("*** " & __SCOPE__ & ": 'v_k_amf_computed' returned the expected value ***"); + // } + + setverdict(pass) + + } // End of testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01 + + } // End of group fiveG_AKA_Crypto_Functions }// End of module NG_NAS_TestCases diff --git a/ttcn/Lib3GPP/Common/CommonDefs.ttcn b/ttcn/Lib3GPP/Common/CommonDefs.ttcn index 2a54ee4..64c4a92 100644 --- a/ttcn/Lib3GPP/Common/CommonDefs.ttcn +++ b/ttcn/Lib3GPP/Common/CommonDefs.ttcn @@ -1311,6 +1311,8 @@ module CommonDefs { SHA-256 encoding algorithm used as KEY Description Function @status APPROVED (LTE) */ + external function fx_sha256(octetstring p_String) return B256_Type; + external function fx_CalculateFCS32 (bitstring p_TMSI) return B32_Type; /* Cyclic Redundancy Check calculation according to ITU-T Recommendation V.42 of CRC-32 Algorithm @sic R5-172046 sic@ */ //---------------------------------------------------------------------------- diff --git a/ttcn/Lib3GPP/NG_NAS/NG_NAS_SecurityFunctions.ttcn b/ttcn/Lib3GPP/NG_NAS/NG_NAS_SecurityFunctions.ttcn index 5a90d5b..9198e0e 100644 --- a/ttcn/Lib3GPP/NG_NAS/NG_NAS_SecurityFunctions.ttcn +++ b/ttcn/Lib3GPP/NG_NAS/NG_NAS_SecurityFunctions.ttcn @@ -234,14 +234,19 @@ module NG_NAS_SecurityFunctions { { var charstring v_MNC := ""; var hexstring v_PLMN_hexstring := oct2hex(p_NAS_PlmnId); + log("fl_Nas2SNN_MNC: p_NAS_PlmnId=", p_NAS_PlmnId); + log("fl_Nas2SNN_MNC: v_PLMN_hexstring=", v_PLMN_hexstring); if (v_PLMN_hexstring[2] == 'F'H) { v_MNC := "0"; } + log("fl_Nas2SNN_MNC: v_MNC (1)=", v_MNC); v_MNC := v_MNC & hex2str(v_PLMN_hexstring[5]) & hex2str(v_PLMN_hexstring[4]); + log("fl_Nas2SNN_MNC: v_MNC (2)=", v_MNC); if (v_PLMN_hexstring[2] != 'F'H) { // add last digit if not F v_MNC := v_MNC & hex2str(v_PLMN_hexstring[2]); } + log("fl_Nas2SNN_MNC: v_MNC (3)=", v_MNC); return v_MNC; } @@ -255,8 +260,14 @@ module NG_NAS_SecurityFunctions { { var charstring v_MCC; var hexstring v_PLMN_hexstring := oct2hex(p_NAS_PlmnId); + log("fl_Nas2SNN_MCC: p_NAS_PlmnId=", p_NAS_PlmnId); + log("fl_Nas2SNN_MCC: v_PLMN_hexstring=", v_PLMN_hexstring); + log("fl_Nas2SNN_MCC: v_PLMN_hexstring[1]=", v_PLMN_hexstring[1]); + log("fl_Nas2SNN_MCC: v_PLMN_hexstring[0]=", v_PLMN_hexstring[0]); + log("fl_Nas2SNN_MCC: v_PLMN_hexstring[3]=", v_PLMN_hexstring[3]); v_MCC := hex2str(v_PLMN_hexstring[1]) & hex2str(v_PLMN_hexstring[0]) & hex2str(v_PLMN_hexstring[3]); + log("fl_Nas2SNN_MCC: v_MCC=", v_MCC); return v_MCC; } @@ -313,18 +324,28 @@ module NG_NAS_SecurityFunctions { var octetstring v_S; var octetstring v_P0; + log(">>> f_NG_Authentication_A2: p_PLMN=", p_PLMN); + log(">>> f_NG_Authentication_A2: p_AuthParams=", p_AuthParams); + log(">>> f_NG_Authentication_A2: p_KDF=", p_KDF); + log(">>> f_NG_Authentication_A2: p_Ks=", bit2oct(p_Ks)); + // Generation of String v_S := const_S6A_FC; + log("f_NG_Authentication_A2 (1): v_S=", v_S); //FC = 0x6A v_P0 := fl_GetServingNetworkName(p_PLMN, p_NID); // @sic R5s220753 sic@ v_S := (v_S & v_P0); + log("f_NG_Authentication_A2 (2): v_S=", v_S); //P0 = serving network ID v_S := (v_S & int2oct(lengthof(v_P0), 2)) ; + log("f_NG_Authentication_A2 (3): v_S=", v_S); //L0 = length of serving network ID (i.e. 0x00 0x03) v_S := ( v_S & ( substr (( bit2oct ( p_AuthParams.AUTN )) , 0,6 ))); + log("f_NG_Authentication_A2 (4): v_S=", v_S); //P1 = SQN XOR AK // to have MSB 6 bytes which is SQN xor AK and truncated as SQN xor AK is first 6 bytes of AUTN v_S := ( v_S & '0006'O ); + log("f_NG_Authentication_A2 (5): v_S=", v_S); //L1 = length of SQN XOR AK (i.e. 0x00 0x06) return fx_KeyDerivationFunction( p_KDF, p_Ks, v_S ); } @@ -350,18 +371,28 @@ module NG_NAS_SecurityFunctions { var octetstring v_S; var octetstring v_P0; + log(">>> f_NG_Authentication_A3: p_PLMN=", p_PLMN); + log(">>> f_NG_Authentication_A3: p_AuthParams=", p_AuthParams); + log(">>> f_NG_Authentication_A3: p_KDF=", p_KDF); + log(">>> f_NG_Authentication_A3: p_Ks=", bit2oct(p_Ks)); + // Generation of String v_S := const_S20_FC; + log("f_NG_Authentication_A3 (1): v_S=", v_S); //FC = 0x20 v_P0 := fl_GetServingNetworkName(p_PLMN, p_NID); // @sic R5s220753 sic@ v_S := (v_S & v_P0); + log("f_NG_Authentication_A3 (2): v_S=", v_S); //P0 = serving network ID v_S := (v_S & int2oct(lengthof(v_P0), 2)) ; + log("f_NG_Authentication_A3 (3): v_S=", v_S); //L0 = length of serving network ID (i.e. 0x00 0x03) v_S := ( v_S & ( substr (( bit2oct ( p_AuthParams.AUTN )) , 0,6 ))); + log("f_NG_Authentication_A3 (4): v_S=", v_S); //P1 = SQN XOR AK // to have MSB 6 bytes which is SQN xor AK and truncated as SQN xor AK is first 6 bytes of AUTN v_S := ( v_S & '0006'O ); + log("f_NG_Authentication_A3 (5): v_S=", v_S); //L1 = length of SQN XOR AK (i.e. 0x00 0x06) return fx_KeyDerivationFunction( p_KDF, p_Ks, v_S ); } @@ -391,37 +422,33 @@ module NG_NAS_SecurityFunctions { log(">>> f_NG_Authentication_A4: p_PLMN=", p_PLMN); log(">>> f_NG_Authentication_A4: p_AuthParams=", p_AuthParams); log(">>> f_NG_Authentication_A4: p_KDF=", p_KDF); - log(">>> f_NG_Authentication_A4: p_Key=", p_Key); - + log(">>> f_NG_Authentication_A4: p_Key=", bit2oct(p_Key)); // Generation of String v_S := const_S6B_FC; //FC = 0x6B v_P0 := fl_GetServingNetworkName(p_PLMN, p_NID); // @sic R5s220753 sic@ - log("f_NG_Authentication_A4: v_P0=", v_P0); + log("f_NG_Authentication_A4 (1): v_P0=", v_P0); v_S := (v_S & v_P0); - log("f_NG_Authentication_A4: v_S=", v_S); + log("f_NG_Authentication_A4 (2): v_S=", v_S); //P0 = serving network ID v_S := (v_S & int2oct(lengthof(v_P0), 2)) ; - log("f_NG_Authentication_A4: v_S=", v_S); + log("f_NG_Authentication_A4 (3): v_S=", v_S); //L0 = length of serving network ID v_S := ( v_S & bit2oct ( p_AuthParams.RandValue ) ); - log("f_NG_Authentication_A4: v_S=", v_S); + log("f_NG_Authentication_A4 (4): v_S=", v_S); //P1 = RAND v_S := ( v_S & '0010'O ); //L1 = length of RAND (i.e. 0x00 0x10) - log("f_NG_Authentication_A4: v_S=", v_S); + log("f_NG_Authentication_A4 (5): v_S=", v_S); v_S := ( v_S & bit2oct (substr(p_AuthParams.XRES, 0, px_NAS_5GC_XRES_Length*8))); // @sic R5s190394 sic@ - log("f_NG_Authentication_A4: v_S=", v_S); + log("f_NG_Authentication_A4 (6): v_S=", v_S); //P2 = RES or XRES v_S := ( v_S & int2oct(px_NAS_5GC_XRES_Length, 2) ); // @sic R5w190117 sic@ - log("f_NG_Authentication_A4: v_S=", v_S); + log("f_NG_Authentication_A4 (7): v_S=", v_S); //L2 = length of RES/XRES (e.g. 0x00 0x10) - var bitstring bs := fx_KeyDerivationFunction(p_KDF, p_Key, v_S); // Already 128 bits length - - return bs; - //return substr(fx_KeyDerivationFunction(p_KDF, p_Key, v_S), 128, 128); + return substr(fx_KeyDerivationFunction(p_KDF, p_Key, v_S), 128, 128); // returns LSB 128 bits[truncated] of the key generated } @@ -439,19 +466,26 @@ module NG_NAS_SecurityFunctions { function f_NG_Authentication_A6(NAS_PlmnId p_PLMN, B256_Type p_KAUSF, KDF_Type p_KDF_Type, - template (omit) hexstring p_NID := omit) return B256_Type + template (omit) hexstring p_NID := omit) return B256_Type { const octetstring const_S6C_FC :='6C'O; var octetstring v_S; var octetstring v_P0; + log(">>> f_NG_Authentication_A6: p_PLMN=", p_PLMN); + log(">>> f_NG_Authentication_A6: p_KAUSF=", bit2oct(p_KAUSF)); + log(">>> f_NG_Authentication_A6: p_KDF_Type=", p_KDF_Type); + // Generation of String v_S := const_S6C_FC; + log("f_NG_Authentication_A6 (1): v_S=", v_S); //FC = 0x6C v_P0 := fl_GetServingNetworkName(p_PLMN, p_NID); // @sic R5s220753 sic@ v_S := (v_S & v_P0); + log("f_NG_Authentication_A6 (2): v_S=", v_S); //P0 = serving network ID v_S := (v_S & int2oct(lengthof(v_P0), 2)) ; + log("f_NG_Authentication_A6 (3): v_S=", v_S); //L0 = length of serving network ID return fx_KeyDerivationFunction(p_KDF_Type, p_KAUSF, v_S); diff --git a/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn b/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn index 9aa459f..a4b727f 100644 --- a/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn +++ b/ttcn/Lib_NG_NAS/LIB_NG_NAS_Functions.ttcn @@ -140,16 +140,16 @@ module LIB_NG_NAS_Functions { } /** - * @desc Function to await NAS AuthorizationRequest message and send AuthorizationResponse message with security computation for future encryption + * @desc Function to await NAS AuthenticationRequest message and send AuthenticationResponse message with security computation for future encryption */ - function f_await_NasAuthorizationRequest_send_NasAuthorizationResponse() runs on NGNASComponent { - // Await request for authorization + function f_await_NasAuthenticationRequest_send_NasAuthenticationResponse() runs on NGNASComponent { + // Await request for authentication f_recv_NGAP_PDU( mw_ngap_initMsg( mw_n2_DownlinkNASTransport( PX_AMF_UE_NGAP_ID, PX_RAN_UE_NGAP_ID, - ? // AuthorizationRequest + ? // AuthenticationRequest ))); f_NASPDU_Get(vc_recvNGAP_PDU); var NG_NAS_DL_Message_Type v_message; @@ -167,7 +167,10 @@ module LIB_NG_NAS_Functions { return; } // Compute RES/XRES - f_5g_aka_compute_res_xres(-, v_message.authentication_Request.rand.randValue, v_message.authentication_Request.autn.aUTN, v_message.authentication_Request.abba, PX_PLMN_IDENTITY, oct2hex(PX_SUPI_DIGITS), vc_ng_nas_security_params_type); + if (f_5g_aka_compute_res_xres(-, v_message.authentication_Request.rand.randValue, v_message.authentication_Request.autn.aUTN, v_message.authentication_Request.abba, PX_PLMN_IDENTITY, oct2hex(PX_SUPI_DIGITS), vc_ng_nas_security_params_type) == false) { + setverdict(fail); + return; + } // Send response vt_NgNasUl_Msg := m_NG_AUTHENTICATION_RESPONSE( { iei := '2d'O, iel := '10'O, res := vc_ng_nas_security_params_type.AuthParams.XRES } @@ -561,9 +564,9 @@ module LIB_NG_NAS_Functions { var B48_Type v_sqn_ak := f_extract_sqn_ak_from_autn(p_autn); var B16_Type v_amf := f_extract_amf_from_autn(p_autn); var B64_Type v_mac := f_extract_mac_from_autn(p_autn); - log("f_5g_aka_compute_res_xres: v_sqn_ak=", v_sqn_ak); - log("f_5g_aka_compute_res_xres: v_amf=", v_amf); - log("f_5g_aka_compute_res_xres: v_mac=", v_mac); + log("f_5g_aka_compute_res_xres: v_sqn_ak=", bit2oct(v_sqn_ak)); + log("f_5g_aka_compute_res_xres: v_amf=", bit2oct(v_amf)); + log("f_5g_aka_compute_res_xres: v_mac=", bit2oct(v_mac)); // Set OP f_set_op(PX_USIM_OPERATOR_VARIANT_ALGORITHM_CONFIGURATION); @@ -573,17 +576,17 @@ module LIB_NG_NAS_Functions { var B48_Type v_ak; var B64_Type v_res; if (f_f2345(PX_LONG_TERM_KEY, p_rand, v_res, v_ck, v_ik, v_ak) == -1) { - log("f_f2345 failed: "); + log("f_f2345 failed"); return false; } p_ng_nas_security_params_type.AuthParams.CK := v_ck; - log("f_5g_aka_compute_res_xres: CK=", p_ng_nas_security_params_type.AuthParams.CK); + log("f_5g_aka_compute_res_xres: CK=", bit2oct(p_ng_nas_security_params_type.AuthParams.CK)); p_ng_nas_security_params_type.AuthParams.IK := v_ik; - log("f_5g_aka_compute_res_xres: IK=", p_ng_nas_security_params_type.AuthParams.IK); + log("f_5g_aka_compute_res_xres: IK=", bit2oct(p_ng_nas_security_params_type.AuthParams.IK)); p_ng_nas_security_params_type.Ks := p_ng_nas_security_params_type.AuthParams.CK & p_ng_nas_security_params_type.AuthParams.IK; - log("f_5g_aka_compute_res_xres: Ks=", p_ng_nas_security_params_type.Ks); + log("f_5g_aka_compute_res_xres: Ks=", bit2oct(p_ng_nas_security_params_type.Ks)); var B48_Type v_sqn := v_sqn_ak xor4b v_ak; - log("f_5g_aka_compute_res_xres: v_sqn=", v_sqn); + log("f_5g_aka_compute_res_xres: v_sqn=", bit2oct(v_sqn)); // Verify that MAC was accepted var B64_Type v_mac_p; @@ -591,7 +594,7 @@ module LIB_NG_NAS_Functions { log("f_f1 failed: "); return false; } - log("f_5g_aka_compute_res_xres: v_mac_p=", v_mac_p); + log("f_5g_aka_compute_res_xres: v_mac_p=", bit2oct(v_mac_p)); if (v_mac != v_mac_p) { log("v_mac != v_mac_p"); return false; @@ -639,6 +642,55 @@ module LIB_NG_NAS_Functions { + + //-------------------------------------------------------------------------- + /* + * @desc HRES* and HXRES* derivation function + * As per annex A.5 of 33.501 + * @param p_AuthParams + * @param p_KAUSF + * @param p_KDF_Type + * @param p_NID (default value: omit) + * @return B256_Type + */ + function f_NG_Authentication_A5( + in B128_Type p_RAND, + in B64_Type p_XRESstar, + KDF_Type p_KDF_Type, + B256_Type p_Key + ) return B128_Type + { + const octetstring const_S6C_FC :='6C'O; + var octetstring v_S; + var octetstring v_P0; + var octetstring v_P1; + + log(">>> f_NG_Authentication_A5: p_RAND=", bit2oct(p_RAND)); + log(">>> f_NG_Authentication_A5: p_XRESstar=", bit2oct(p_XRESstar)); + log(">>> f_NG_Authentication_A5: p_KDF=", p_KDF_Type); + log(">>> f_NG_Authentication_A5: p_Key=", bit2oct(p_Key)); + + v_S := bit2oct(p_RAND) & bit2oct(p_XRESstar); + log("f_NG_Authentication_A5: v_S=", v_S); + + //return substr(fx_KeyDerivationFunction(p_KDF_Type, p_Key, v_S), 128, 128); + return substr(fx_sha256(v_S), 128, 128); + }; + + + + + + + + + + + + + + + function f_extract_sqn_ak_from_autn(in B128_Type p_autn) return B48_Type { return substr(p_autn, 0, 48); } -- GitLab From d1eeee77e84786c6b1004e83f2003e6e4fc05c62 Mon Sep 17 00:00:00 2001 From: garciay Date: Wed, 20 Aug 2025 10:49:11 +0200 Subject: [PATCH 4/5] Finalyse TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01 --- etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ | 4 +- ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn | 134 ++++++++++++++------------ 2 files changed, 76 insertions(+), 62 deletions(-) diff --git a/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ b/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ index a5961f3..12c2011 100644 --- a/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ +++ b/etc/Ats_NG_NAS/AtsNGAP_AMF.cfg_ @@ -123,10 +123,10 @@ system.N2_gNBaMF_P.params := "NGAP/SCTP_FILE/IP_OFFLINE/ETH(mac_src=8c554ac1eee0 #G_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_02 #NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_15_01 #NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_16_01 -NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01 #NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_02 NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_03 -NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_18_01 +#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_18_01 #NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_19_01 #NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01 diff --git a/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn b/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn index c8f0cb8..c5af3f0 100644 --- a/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn +++ b/ttcn/Ats_NG_NAS/NG_NAS_TestCases.ttcn @@ -1495,7 +1495,7 @@ module NG_NAS_TestCases { var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); - var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key @@ -1605,7 +1605,6 @@ module NG_NAS_TestCases { */ testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_09_02() runs on gNB_NGNAS_NGAPComponent system TestAdapter { - // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 2 var O16_Type v_K := '0396eb317b6d1c36f19c1c84cd6ffd16'O; // The long-term key: Subscriber key var B128_Type v_rand := oct2bit('c00d603103dcee52c4478119494202e8'O); @@ -1713,7 +1712,7 @@ module NG_NAS_TestCases { var B256_Type v_derived_key := oct2bit('0c01ec8210931fdaa57448583b69e8f0ce99db7560d07dd3719765d26bf4c12f'O); var B256_Type v_derived_key_computed := fx_KeyDerivationFunction(1, v_Ks, v_S); - if (not(match(v_derived_key_computed, v_derived_key))) { + if (not(match(v_derived_key_computed, v_derived_key))) { // Verified by https://cryptii.com/pipes/hmac log("*** " & __SCOPE__ & ": ERROR: 'v_derived_key_computed' did not return the expected value. ***"); setverdict(fail); } else { @@ -1819,21 +1818,28 @@ module NG_NAS_TestCases { testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_15_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 - var B48_Type v_sqn_ak := oct2bit('000102030405'O); // SQN: Sequence Number - var B16_Type v_amf := oct2bit('0000'O); // Dummy value - var B64_Type v_mac_a := oct2bit('0000000000000000'O); // Dummy value - var B128_Type v_ck := oct2bit('4a3b7c89acbd1234ef567890abcdef12'O); - var B128_Type v_ik := oct2bit('9f1e2345ac7890fab345678912345678'O); - var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 - var hexstring v_NID := '000138'H; // NID: Network Identifier - - var Common_AuthenticationParams_Type v_auth_params; - v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn_ak := oct2bit('ff9bb4d0b607'O); // SQN: Sequence Number + var B16_Type v_amf := oct2bit('b9b9'O); + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key + var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key + var B64_Type v_mac_a := oct2bit('9cabc3e99baf7281'O); // MAC-A: Network authentication code + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + + f_set_op(v_op); + + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side v_auth_params.CK := v_ck; v_auth_params.IK := v_ik; var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK - var B256_Type v_k_ausf := oct2bit('69EC2C51E14725BCCB24562470C25BE38C45701DCEBB6EF38B48ACE1082FE3C0'O); + var B256_Type v_k_ausf := oct2bit('F42CFB5BCF426A3715BB5412E16F1177DB0EECF1EC2A21AE9826E941CA2B23EC'O); var B256_Type v_k_ausf_computed := f_NG_Authentication_A2(v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_PLMN, v_NID); if (not(match(v_k_ausf_computed, v_k_ausf))) { log("*** " & __SCOPE__ & ": ERROR: 'v_k_ausf_computed' did not return the expected value. ***"); @@ -1856,20 +1862,27 @@ module NG_NAS_TestCases { testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_16_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 - var B48_Type v_sqn_ak := oct2bit('000102030405'O); // SQN: Sequence Number - var B16_Type v_amf := oct2bit('0000'O); // Dummy value - var B64_Type v_mac_a := oct2bit('0000000000000000'O); // Dummy value - var B128_Type v_ck := oct2bit('4a3b7c89acbd1234ef567890abcdef12'O); - var B128_Type v_ik := oct2bit('9f1e2345ac7890fab345678912345678'O); - var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 - var hexstring v_NID := '000138'H; // NID: Network Identifier - var B128_Type v_ck_p := oct2bit('23e5e46389721ca3a3abe4a0c9e60efd'O); - var B128_Type v_ik_p := oct2bit('fce88fcd5e9e293ba6adaa5934c3687c'O); + var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key + var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); + var B48_Type v_sqn_ak := oct2bit('ff9bb4d0b607'O); // SQN: Sequence Number + var B16_Type v_amf := oct2bit('b9b9'O); + var B64_Type v_xres := oct2bit('a54211d5e3ba50bf'O); // Response. f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ck := oct2bit('b40ba9a3c58b2a05bbf0d987b21bf8cb'O); // Confidentiality key. f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 table + var B128_Type v_ik := oct2bit('f769bcd751044604127672711c6d3441'O); // Integrity key + var B48_Type v_ak := oct2bit('aa689c648370'O); // Anonymity key + var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 + var hexstring v_NID := '000138'H; // NID: Network Identifier + var B128_Type v_ck_p := oct2bit('8b9be2d9e808246a2f3ad44094c374fe'O); + var B128_Type v_ik_p := oct2bit('154fad1c3c57a85cbdbbcf7db7549f03'O); + var B64_Type v_mac_a := oct2bit('0000000000000000'O); // Dummy value - var B256_Type v_derived_key := oct2bit('23e5e46389721ca3a3abe4a0c9e60efdfce88fcd5e9e293ba6adaa5934c3687c'O); + f_set_op(v_op); + + var B256_Type v_derived_key := oct2bit('8B9BE2D9E808246A2F3AD44094C374FE154FAD1C3C57A85CBDBBCF7DB7549F03'O); - var Common_AuthenticationParams_Type v_auth_params; - v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side v_auth_params.CK := v_ck; v_auth_params.IK := v_ik; @@ -1909,11 +1922,11 @@ module NG_NAS_TestCases { testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { // From https://www.eurecom.fr/publication/6408/download/comsys-publi-6408.pdf DATA 1 - var O16_Type v_K := '00112233445566778899aabbccddeeff'O; // The long-term key: Subscriber key - var O16_Type v_op := '000102030405060708090a0b0c0d0e0f'O; // Operator Variant Algorithm Configuration Field - var B128_Type v_rand := oct2bit('6a8959fb188c73308d679f7bc8313d65'O); - var B48_Type v_sqn_ak := oct2bit('97779b305686'O); - var NAS_PlmnId v_PLMN := '641010'O; // PLMN ID: 641-010 + var O16_Type v_K := '00112233445566778899aabbccddeeff'O; // The long-term key: Subscriber key + var O16_Type v_op := '000102030405060708090a0b0c0d0e0f'O; // Operator Variant Algorithm Configuration Field + var B128_Type v_rand := oct2bit('6a8959fb188c73308d679f7bc8313d65'O); + var B48_Type v_sqn_ak := oct2bit('97779b305686'O); + var NAS_PlmnId v_PLMN := '641010'O; // PLMN ID: 641-010 f_set_op(v_op); @@ -2023,7 +2036,7 @@ module NG_NAS_TestCases { } var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); - v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side v_auth_params.CK := v_ck; v_auth_params.IK := v_ik; v_auth_params.XRES := v_xres; @@ -2098,7 +2111,7 @@ module NG_NAS_TestCases { } var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); - v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side v_auth_params.CK := v_ck; v_auth_params.IK := v_ik; v_auth_params.XRES := v_xres; @@ -2175,7 +2188,7 @@ module NG_NAS_TestCases { var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); - v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side v_auth_params.CK := v_ck; v_auth_params.IK := v_ik; v_auth_params.XRES := v_xres; @@ -2292,7 +2305,7 @@ module NG_NAS_TestCases { var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); - v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side v_auth_params.CK := v_ck; v_auth_params.IK := v_ik; v_auth_params.XRES := v_xres; @@ -2322,7 +2335,7 @@ module NG_NAS_TestCases { */ testcase TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01() runs on gNB_NGNAS_NGAPComponent system TestAdapter { - // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.3 Test Set 1 + // From ETSI TS 135 207 V16.0.0 (2020-08) Clause 4.3 Test Set 1 var O16_Type v_K := '465b5ce8b199b49faa5f0a2ee238a6bc'O; // The long-term key: Subscriber key var B128_Type v_rand := oct2bit('23553cbe9637a89d218ae64dae47bf35'O); var O16_Type v_op := 'cdc202d5123e20f62b6d676ac72cb318'O; // Operator Variant Algorithm Configuration Field @@ -2330,7 +2343,8 @@ module NG_NAS_TestCases { var B16_Type v_amf := oct2bit('b9b9'O); // AMF: Authentication Management Field var NAS_PlmnId v_PLMN := '00f110'O; // PLMN ID: 001-01 var hexstring v_NID := '000138'H; // NID: Network Identifier - + var charstring v_supi := "001014444333000"; + f_set_op(v_op); var B64_Type v_mac_a; @@ -2340,13 +2354,7 @@ module NG_NAS_TestCases { setverdict(fail); stop; } - var B64_Type v_mac_s; - v_result := f_f1star(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_s); - if (v_result != 0) { - log("*** " & __SCOPE__ & ": ERROR: 'fx_f1' returned an error code: " & int2str(v_result) & ". ***"); - setverdict(fail); - stop; - } + var B64_Type v_xres; var B128_Type v_ck; var B128_Type v_ik; @@ -2355,23 +2363,29 @@ module NG_NAS_TestCases { if (v_result != 0) { log("*** " & __SCOPE__ & ": ERROR: 'f_f2345' returned an error code: " & int2str(v_result) & ". ***"); setverdict(fail); - stop; } - // var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK - // var octetstring v_S := '06D540050123456789000f00000002'O; - // var B256_Type v_k_aus := fx_KeyDerivationFunction(1, v_Ks, v_S); - // var B256_Type v_k_seaf := f_NG_Authentication_A6(v_PLMN, v_k_aus, tsc_KDF_HMAC_SHA_256, v_NID); - - // var charstring v_supi := "460110123456789"; - // var octetstring v_abba := '0000'O; // ETSI TS 133 501 V16.18.0 (2024-04) A.7.1 ABBA parameter values - // var B256_Type v_k_amf := int2bit(0, 256); // Expected KAMF value - // var B256_Type v_k_amf_computed := f_NG_Authentication_A7(v_supi, v_k_seaf, v_abba, tsc_KDF_HMAC_SHA_256); - // if (not(match(v_k_amf_computed, v_k_amf))) { - // log("*** " & __SCOPE__ & ": ERROR: 'v_k_amf_computed' did not return the expected value. ***"); - // setverdict(fail); - // } else { - // log("*** " & __SCOPE__ & ": 'v_k_amf_computed' returned the expected value ***"); - // } + + var Common_AuthenticationParams_Type v_auth_params := valueof(cs_CommonAuthParams_Init(v_rand)); + v_auth_params.AUTN := v_sqn_ak & v_amf & v_mac_a; // ETSI TS 135 205 V16.0.0 (2020-08) 7.2 Use of the algorithms on the AuC side + v_auth_params.CK := v_ck; + v_auth_params.IK := v_ik; + v_auth_params.XRES := v_xres; + v_auth_params.XRESLength := lengthof(v_xres); + + var B256_Type v_Ks := v_ck & v_ik; // ETSI TS 133 501 V16.18.0 (2024-04) A.2 KAUSF derivation function: Ks = CK || IK + var B256_Type v_k_ausf := f_NG_Authentication_A2(v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_PLMN, v_NID); + + var B256_Type v_k_seaf := f_NG_Authentication_A6(v_PLMN, v_k_ausf, tsc_KDF_HMAC_SHA_256, v_NID); + + var B256_Type v_k_amf := oct2bit('9379A99B1ED68C2F0643EBA74692E617563A21CDA85C5619D8686CF661FC8995'O); // KAMF: Authentication Management Field Key + var B256_Type v_k_amf_computed := f_NG_Authentication_A7(v_supi, v_k_seaf, bit2oct(v_amf), tsc_KDF_HMAC_SHA_256) + if (not(match(v_k_amf_computed, v_k_amf))) { + log("*** " & __SCOPE__ & ": ERROR: 'v_k_amf_computed' did not return the expected value. ***"); + setverdict(fail); + } else { + log("*** " & __SCOPE__ & ": 'v_k_amf_computed' returned the expected value ***"); + } + setverdict(pass) -- GitLab From 2f44ab13e8cb350d993ff3db260e317e9641ead2 Mon Sep 17 00:00:00 2001 From: garciay Date: Fri, 22 Aug 2025 07:36:15 +0200 Subject: [PATCH 5/5] Add cfg file etc/Ats_NG_NAS/AtsNGAP_GNB.cfg_ --- etc/Ats_NG_NAS/AtsNGAP_GNB.cfg_ | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 etc/Ats_NG_NAS/AtsNGAP_GNB.cfg_ diff --git a/etc/Ats_NG_NAS/AtsNGAP_GNB.cfg_ b/etc/Ats_NG_NAS/AtsNGAP_GNB.cfg_ new file mode 100644 index 0000000..7f8b8a2 --- /dev/null +++ b/etc/Ats_NG_NAS/AtsNGAP_GNB.cfg_ @@ -0,0 +1,64 @@ +[MODULE_PARAMETERS] +# This section shall contain the values of all parameters that are defined in your TTCN-3 modules. + +NAS_Pics.PICS_NAS_GNB_IUT := true +NAS_Pics.PICS_NAS_AMF_IUT := false + +[LOGGING] +# In this section you can specify the name of the log file and the classes of events +# you want to log into the file or display on console (standard error). + +LogFile := "../logs/Ats_NG_NAS/%e.%h-%r.%s" +FileMask := LOG_ALL | USER | DEBUG | MATCHING +ConsoleMask := LOG_ALL | USER | DEBUG | MATCHING +#FileMask := ERROR | WARNING | USER | MATCHING | EXECUTOR_RUNTIME | VERDICTOP | PORTEVENT | TESTCASE +#ConsoleMask := ERROR | WARNING | USER | MATCHING | EXECUTOR_RUNTIME | VERDICTOP | PORTEVENT | TESTCASE +LogSourceInfo := Stack +LogEntityName:= Yes +LogEventTypes:= Yes +#TimeStampFormat := DateTime + +[TESTPORT_PARAMETERS] +# In this section you can specify parameters that are passed to Test Ports. +system.NGAP_gNB_1.params := "NAS/NGAP/SCTP_FILE/IP_OFFLINE/PCAP_FILE(file=../captures/5g_reg.pcapng)" +system.N2_gNBaMF_P.params := "NAS/NGAP/SCTP_FILE/IP_OFFLINE/PCAP_FILE(file=../captures/5g_reg.pcapng)" +#aMFNASComponent.N2_gNBaMF_P.params := "NAS/SCTP_FILE/IP_FILE/ETH/PCAP_FILE(file=../captures/free5gc.pcap)" + +[DEFINE] +# In this section you can create macro definitions, +# that can be used in other configuration file sections except [INCLUDE] and [ORDERED_INCLUDE]. + +[INCLUDE] +# To use configuration settings given in other configuration files, +# the configuration files just need to be listed in this section, with their full or relative pathnames. + +[ORDERED_INCLUDE] +# To use configuration settings given in other configuration files, +# the configuration files just need to be listed in this section, with their full or relative pathnames. + +[EXTERNAL_COMMANDS] +# This section can define external commands (shell scripts) to be executed by the ETS +# whenever a control part or test case is started or terminated. + +#BeginTestCase := "" +#EndTestCase := "" +#BeginControlPart := "" +#EndControlPart := "" + +[EXECUTE] +# In this section you can specify what parts of your test suite you want to execute. +#AtsImsIot_TestControl.control + +[GROUPS] +# In this section you can specify groups of hosts. These groups can be used inside the +# [COMPONENTS] section to restrict the creation of certain PTCs to a given set of hosts. + +[COMPONENTS] +# This section consists of rules restricting the location of created PTCs. + +[MAIN_CONTROLLER] +# The options herein control the behavior of MC. +KillTimer := 10.0 +LocalAddress := 127.0.0.1 +TCPPort := 12000 +NumHCs := 1 -- GitLab