From 79e3de0967fdd3e41805196d9c3f24b22978ca84 Mon Sep 17 00:00:00 2001 From: Lionel Gauthier <lionel.gauthier@eurecom.fr> Date: Thu, 28 May 2015 12:38:52 +0000 Subject: [PATCH] OPc in database (computed by HSS if OP provided) git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7476 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/OPENAIRHSS/auc/auc.h | 32 ++-- openair-cn/OPENAIRHSS/auc/fx.c | 125 +++++++------- openair-cn/OPENAIRHSS/auc/kdf.c | 22 +-- openair-cn/OPENAIRHSS/auc/random.c | 13 +- openair-cn/OPENAIRHSS/auc/sequence_number.c | 10 +- openair-cn/OPENAIRHSS/conf/hss.conf.in | 1 - openair-cn/OPENAIRHSS/db/db_connector.c | 124 +++++++++++++- openair-cn/OPENAIRHSS/db/db_proto.h | 26 ++- openair-cn/OPENAIRHSS/db/oai_db.sql | 36 ++-- openair-cn/OPENAIRHSS/db/pft_db.sql | 173 ++++++++++++++++++++ openair-cn/OPENAIRHSS/hss_main.c | 5 + openair-cn/OPENAIRHSS/s6a/s6a_auth_info.c | 4 +- openair-cn/OPENAIRHSS/utils/hss_config.c | 70 ++++---- openair-cn/OPENAIRHSS/utils/hss_config.h | 6 +- openair-cn/OPENAIRHSS/utils/hss_parser.y | 8 +- openair-cn/OPENAIRHSS/utils/hss_scanner.l | 2 +- 16 files changed, 468 insertions(+), 189 deletions(-) create mode 100644 openair-cn/OPENAIRHSS/db/pft_db.sql diff --git a/openair-cn/OPENAIRHSS/auc/auc.h b/openair-cn/OPENAIRHSS/auc/auc.h index 81d7876cec..00ca2b9dc7 100644 --- a/openair-cn/OPENAIRHSS/auc/auc.h +++ b/openair-cn/OPENAIRHSS/auc/auc.h @@ -50,7 +50,7 @@ extern uint8_t opc[16]; typedef mpz_t random_t; typedef mpz_t sqn_t; -typedef uint8_t u8; +typedef uint8_t uint8_t; typedef struct { uint8_t rand[16]; @@ -60,8 +60,8 @@ typedef struct { uint8_t kasme[32]; } auc_vector_t; -void RijndaelKeySchedule(const u8 const key[16]); -void RijndaelEncrypt(const u8 const in[16], u8 out[16]); +void RijndaelKeySchedule(const uint8_t const key[16]); +void RijndaelEncrypt(const uint8_t const in[16], uint8_t out[16]); /* Sequence number functions */ struct sqn_ue_s; @@ -77,19 +77,21 @@ struct random_state_s; void random_init(void); void generate_random(uint8_t *random, ssize_t length); -void SetOP(char *opP); +//void SetOP(char *opP); -void f1 ( const u8 const k[16], const u8 const rand[16], const u8 const sqn[6], const u8 const amf[2], - u8 mac_a[8] ); -void f1star( const u8 const k[16], const u8 const rand[16], const u8 const sqn[6], const u8 const amf[2], - u8 mac_s[8] ); -void f2345 ( const u8 const k[16], const u8 const rand[16], - u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] ); -void f5star( const u8 const k[16], const u8 const rand[16], - u8 ak[6] ); +void ComputeOPc( const uint8_t const kP[16], const uint8_t const opP[16], uint8_t opcP[16] ); -void generate_autn(const u8 const sqn[6], const u8 const ak[6], const u8 const amf[2], const u8 const mac_a[8], u8 autn[16]); -int generate_vector(uint64_t imsi, uint8_t key[16], uint8_t plmn[3], +void f1 ( const uint8_t const kP[16],const uint8_t const k[16], const uint8_t const rand[16], const uint8_t const sqn[6], const uint8_t const amf[2], + uint8_t mac_a[8] ); +void f1star( const uint8_t const kP[16],const uint8_t const k[16], const uint8_t const rand[16], const uint8_t const sqn[6], const uint8_t const amf[2], + uint8_t mac_s[8] ); +void f2345 ( const uint8_t const kP[16],const uint8_t const k[16], const uint8_t const rand[16], + uint8_t res[8], uint8_t ck[16], uint8_t ik[16], uint8_t ak[6] ); +void f5star( const uint8_t const kP[16],const uint8_t const k[16], const uint8_t const rand[16], + uint8_t ak[6] ); + +void generate_autn(const uint8_t const sqn[6], const uint8_t const ak[6], const uint8_t const amf[2], const uint8_t const mac_a[8], uint8_t autn[16]); +int generate_vector(const uint8_t const opc[16], uint64_t imsi, uint8_t key[16], uint8_t plmn[3], uint8_t sqn[6], auc_vector_t *vector); void kdf(uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out, @@ -98,7 +100,7 @@ void kdf(uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *ou void derive_kasme(uint8_t ck[16], uint8_t ik[16], uint8_t plmn[3], uint8_t sqn[6], uint8_t ak[6], uint8_t kasme[32]); -uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand); +uint8_t *sqn_ms_derive(const uint8_t const opc[16], uint8_t *key, uint8_t *auts, uint8_t *rand); static inline void print_buffer(const char *prefix, uint8_t *buffer, int length) { diff --git a/openair-cn/OPENAIRHSS/auc/fx.c b/openair-cn/OPENAIRHSS/auc/fx.c index 1e21fe80c5..446599a86d 100644 --- a/openair-cn/OPENAIRHSS/auc/fx.c +++ b/openair-cn/OPENAIRHSS/auc/fx.c @@ -26,36 +26,16 @@ extern hss_config_t hss_config; /*--------- Operator Variant Algorithm Configuration Field --------*/ -/*------- Insert your value of OP here -------*/ -extern uint8_t opc[16]; -extern uint8_t op[16]; + /*--------------------------- prototypes --------------------------*/ -void ComputeOPc( u8 opP[16] ); -void SetOP(char *opP) -{ - int ret = sscanf(opP, - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - (unsigned int*)&op[0],(unsigned int*)&op[1], - (unsigned int*)&op[2],(unsigned int*)&op[3], - (unsigned int*)&op[4],(unsigned int*)&op[5], - (unsigned int*)&op[6],(unsigned int*)&op[7], - (unsigned int*)&op[8],(unsigned int*)&op[9], - (unsigned int*)&op[10],(unsigned int*)&op[11], - (unsigned int*)&op[12],(unsigned int*)&op[13], - (unsigned int*)&op[14],(unsigned int*)&op[15]); - if (ret != 16) { - fprintf(stderr, - "Error in operator key\n"); - abort(); - } - printf("SetOP: OP : %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", - op[0],op[1],op[2],op[3],op[4],op[5],op[6],op[7], - op[8],op[9],op[10],op[11],op[12],op[13],op[14],op[15]); -} -void generate_autn(const u8 const sqn[6], const u8 const ak[6], const u8 const amf[2], const u8 const mac_a[8], u8 autn[16]) +/*------------------------------------------------------------------- + * + *------------------------------------------------------------------- + *-----------------------------------------------------------------*/ +void generate_autn(const uint8_t const sqn[6], const uint8_t const ak[6], const uint8_t const amf[2], const uint8_t const mac_a[8], uint8_t autn[16]) { int i; @@ -76,19 +56,20 @@ void generate_autn(const u8 const sqn[6], const u8 const ak[6], const u8 const a * field AMF. * *-----------------------------------------------------------------*/ -void f1 ( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[6], const u8 const amf[2], - u8 mac_a[8] ) +void f1 ( const uint8_t const opc[16], const uint8_t const k[16], const uint8_t const _rand[16], const uint8_t const sqn[6], const uint8_t const amf[2], + uint8_t mac_a[8] ) { - u8 temp[16]; - u8 in1[16]; - u8 out1[16]; - u8 rijndaelInput[16]; - u8 i; + uint8_t temp[16]; + uint8_t in1[16]; + uint8_t out1[16]; + uint8_t rijndaelInput[16]; + uint8_t i; RijndaelKeySchedule( k ); - if (hss_config.valid_opc == 0) { + /* + if (hss_config.valid_op > 0) { SetOP(hss_config.operator_key); ComputeOPc( opc ); - } + }*/ for (i=0; i<16; i++) rijndaelInput[i] = _rand[i] ^ opc[i]; @@ -133,18 +114,19 @@ void f1 ( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[6], * confidentiality key CK, integrity key IK and anonymity key AK. * *-----------------------------------------------------------------*/ -void f2345 ( const u8 const k[16], const u8 const _rand[16], - u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] ) +void f2345 ( const uint8_t const opc[16], const uint8_t const k[16], const uint8_t const _rand[16], + uint8_t res[8], uint8_t ck[16], uint8_t ik[16], uint8_t ak[6] ) { - u8 temp[16]; - u8 out[16]; - u8 rijndaelInput[16]; - u8 i; + uint8_t temp[16]; + uint8_t out[16]; + uint8_t rijndaelInput[16]; + uint8_t i; RijndaelKeySchedule( k ); - if (hss_config.valid_opc == 0) { + + /*if (hss_config.valid_op > 0) { SetOP(hss_config.operator_key); ComputeOPc( opc ); - } + }*/ for (i=0; i<16; i++) rijndaelInput[i] = _rand[i] ^ opc[i]; @@ -212,23 +194,23 @@ void f2345 ( const u8 const k[16], const u8 const _rand[16], * field AMF. * *-----------------------------------------------------------------*/ -void f1star( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[6], const u8 const amf[2], - u8 mac_s[8] ) +void f1star( const uint8_t const opc[16], const uint8_t const k[16], const uint8_t const _rand[16], const uint8_t const sqn[6], const uint8_t const amf[2], + uint8_t mac_s[8] ) { - u8 temp[16]; - u8 in1[16]; - u8 out1[16]; - u8 rijndaelInput[16]; - u8 i; + uint8_t temp[16]; + uint8_t in1[16]; + uint8_t out1[16]; + uint8_t rijndaelInput[16]; + uint8_t i; RijndaelKeySchedule( k ); - if (hss_config.valid_opc == 0) { + /*if (hss_config.valid_opc == 0) { SetOP(hss_config.operator_key); ComputeOPc( opc ); } else { printf("Using opc: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", opc[0],opc[1],opc[2],opc[3],opc[4],opc[5],opc[6],opc[7], opc[8],opc[9],opc[10],opc[11],opc[12],opc[13],opc[14],opc[15] ); - } + }*/ for (i=0; i<16; i++) rijndaelInput[i] = _rand[i] ^ opc[i]; @@ -273,23 +255,23 @@ void f1star( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[ * anonymity key AK. * *-----------------------------------------------------------------*/ -void f5star( const u8 const k[16], const u8 const _rand[16], - u8 ak[6] ) +void f5star( const uint8_t const opc[16], const uint8_t const k[16], const uint8_t const _rand[16], + uint8_t ak[6] ) { - u8 temp[16]; - u8 out[16]; - u8 rijndaelInput[16]; - u8 i; + uint8_t temp[16]; + uint8_t out[16]; + uint8_t rijndaelInput[16]; + uint8_t i; RijndaelKeySchedule( k ); - if (hss_config.valid_opc == 0) { + /*if (hss_config.valid_opc == 0) { SetOP(hss_config.operator_key); ComputeOPc(opc); } else { printf("Using OPc: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", opc[0],opc[1],opc[2],opc[3],opc[4],opc[5],opc[6],opc[7], opc[8],opc[9],opc[10],opc[11],opc[12],opc[13],opc[14],opc[15]); - } + }*/ for (i=0; i<16; i++) rijndaelInput[i] = _rand[i] ^ opc[i]; @@ -315,22 +297,25 @@ void f5star( const u8 const k[16], const u8 const _rand[16], } /* end of function f5star */ /*------------------------------------------------------------------- - * Function to compute OPc from OP and K. Assumes key schedule has - * already been performed. + * Function to compute OPc from OP and K. *-----------------------------------------------------------------*/ -void ComputeOPc( u8 opcP[16] ) +void ComputeOPc( const uint8_t const kP[16], const uint8_t const opP[16], uint8_t opcP[16] ) { - u8 i; - - RijndaelEncrypt( op, opcP ); - printf("Compute opc:\n\tIn:\t%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n\tRinj:\t%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", - op[0],op[1],op[2],op[3],op[4],op[5],op[6],op[7], - op[8],op[9],op[10],op[11],op[12],op[13],op[14],op[15], + uint8_t i; + + RijndaelKeySchedule( kP ); + printf("Compute opc:\n\tK:\t%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", + kP[0],kP[1],kP[2],kP[3],kP[4],kP[5],kP[6],kP[7], + kP[8],kP[9],kP[10],kP[11],kP[12],kP[13],kP[14],kP[15]); + RijndaelEncrypt( opP, opcP ); + printf("\tIn:\t%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n\tRinj:\t%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", + opP[0],opP[1],opP[2],opP[3],opP[4],opP[5],opP[6],opP[7], + opP[8],opP[9],opP[10],opP[11],opP[12],opP[13],opP[14],opP[15], opcP[0],opcP[1],opcP[2],opcP[3],opcP[4],opcP[5],opcP[6],opcP[7], opcP[8],opcP[9],opcP[10],opcP[11],opcP[12],opcP[13],opcP[14],opcP[15] ); for (i=0; i<16; i++) - opcP[i] ^= op[i]; + opcP[i] ^= opP[i]; printf("\tOut:\t%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", opcP[0],opcP[1],opcP[2],opcP[3],opcP[4],opcP[5],opcP[6],opcP[7], opcP[8],opcP[9],opcP[10],opcP[11],opcP[12],opcP[13],opcP[14],opcP[15] ); diff --git a/openair-cn/OPENAIRHSS/auc/kdf.c b/openair-cn/OPENAIRHSS/auc/kdf.c index 437b9d9b31..8c83c9665a 100644 --- a/openair-cn/OPENAIRHSS/auc/kdf.c +++ b/openair-cn/OPENAIRHSS/auc/kdf.c @@ -41,15 +41,6 @@ #define DEBUG_AUC_KDF 1 extern hss_config_t hss_config; -uint8_t opc[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -uint8_t op[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - /* * @param key the input key * @param key_len length of the key @@ -93,9 +84,9 @@ void derive_kasme(uint8_t ck[16], uint8_t ik[16], uint8_t plmn[3], uint8_t sqn[6 memcpy(&key[0], ck, 16); memcpy(&key[16], ik, 16); - if (hss_config.valid_opc == 0) { + /*if (hss_config.valid_opc == 0) { SetOP(hss_config.operator_key); - } + }*/ /* FC */ s[0] = 0x10; @@ -137,7 +128,7 @@ void derive_kasme(uint8_t ck[16], uint8_t ik[16], uint8_t plmn[3], uint8_t sqn[6 kdf(key, 32, s, 14, kasme, 32); } -int generate_vector(uint64_t imsi, uint8_t key[16], uint8_t plmn[3], +int generate_vector(const uint8_t const opc[16], uint64_t imsi, uint8_t key[16], uint8_t plmn[3], uint8_t sqn[6], auc_vector_t *vector) { /* in E-UTRAN an authentication vector is composed of: @@ -147,7 +138,8 @@ int generate_vector(uint64_t imsi, uint8_t key[16], uint8_t plmn[3], * - KASME */ - uint8_t amf[] = { 0x80, 0x00 }; + //uint8_t amf[] = { 0x80, 0x00 }; + uint8_t amf[] = { 0x90, 0x01 }; uint8_t mac_a[8]; uint8_t ck[16]; uint8_t ik[16]; @@ -158,14 +150,14 @@ int generate_vector(uint64_t imsi, uint8_t key[16], uint8_t plmn[3], } /* Compute MAC */ - f1(key, vector->rand, sqn, amf, mac_a); + f1(opc, key, vector->rand, sqn, amf, mac_a); print_buffer("MAC_A : ", mac_a, 8); print_buffer("SQN : ", sqn, 6); print_buffer("RAND : ", vector->rand, 16); /* Compute XRES, CK, IK, AK */ - f2345(key, vector->rand, vector->xres, ck, ik, ak); + f2345(opc, key, vector->rand, vector->xres, ck, ik, ak); print_buffer("AK : ", ak, 6); print_buffer("CK : ", ck, 16); print_buffer("IK : ", ik, 16); diff --git a/openair-cn/OPENAIRHSS/auc/random.c b/openair-cn/OPENAIRHSS/auc/random.c index ff9d4f9866..5e71b32461 100644 --- a/openair-cn/OPENAIRHSS/auc/random.c +++ b/openair-cn/OPENAIRHSS/auc/random.c @@ -35,6 +35,7 @@ #include <sys/time.h> #include "auc.h" +#include "hss_config.h" typedef struct random_state_s { pthread_mutex_t lock; @@ -42,6 +43,7 @@ typedef struct random_state_s { } random_state_t; random_state_t random_state; +extern hss_config_t hss_config; void random_init(void) { @@ -70,13 +72,18 @@ void generate_random(uint8_t *random_p, ssize_t length) // mpz_export(random_p, NULL, 1, length, 0, 0, random_nb); int i;//r = 0, mask = 0, shift; - - for (i = 0; i < length; i ++) { + if (hss_config.random_bool > 0) { + for (i = 0; i < length; i ++) { // if ((i % sizeof(i)) == 0) // r = rand(); // shift = 8 * (i % sizeof(i)); // mask = 0xFF << shift; // random_p[i] = (r & mask) >> shift; - random_p[i] = rand(); + random_p[i] = rand(); + } + } else { + for (i = 0; i < length; i ++) { + random_p[i] = 0; + } } } diff --git a/openair-cn/OPENAIRHSS/auc/sequence_number.c b/openair-cn/OPENAIRHSS/auc/sequence_number.c index 0e8ad2d756..2f53b98be0 100644 --- a/openair-cn/OPENAIRHSS/auc/sequence_number.c +++ b/openair-cn/OPENAIRHSS/auc/sequence_number.c @@ -37,7 +37,7 @@ extern hss_config_t hss_config; extern uint8_t op[16]; -uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand_p) +uint8_t *sqn_ms_derive(const uint8_t const opc[16], uint8_t *key, uint8_t *auts, uint8_t *rand_p) { /* AUTS = Conc(SQN MS ) || MAC-S * Conc(SQN MS ) = SQN MS ^ f5* (RAND) @@ -56,12 +56,12 @@ uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand_p) sqn_ms = malloc(SQN_LENGTH_OCTEST); - if (hss_config.valid_opc == 0) { + /*if (hss_config.valid_opc == 0) { SetOP(hss_config.operator_key); - } + }*/ /* Derive AK from key and rand */ - f5star(key, rand_p, ak); + f5star(opc, key, rand_p, ak); for (i = 0; i < 6; i++) { sqn_ms[i] = ak[i] ^ conc_sqn_ms[i]; @@ -74,7 +74,7 @@ uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand_p) print_buffer("sqn_ms_derive() SQN_MS : ", sqn_ms, 6); print_buffer("sqn_ms_derive() MAC_S : ", mac_s, 8); - f1star(key, rand_p, sqn_ms, amf, mac_s_computed); + f1star(opc, key, rand_p, sqn_ms, amf, mac_s_computed); print_buffer("MAC_S +: ", mac_s_computed, 8); diff --git a/openair-cn/OPENAIRHSS/conf/hss.conf.in b/openair-cn/OPENAIRHSS/conf/hss.conf.in index f0732669ad..4c5e4c7d93 100644 --- a/openair-cn/OPENAIRHSS/conf/hss.conf.in +++ b/openair-cn/OPENAIRHSS/conf/hss.conf.in @@ -6,7 +6,6 @@ MYSQL_db = "@MYSQL_db@"; ## HSS options OPERATOR_key = "@OPERATOR_key@"; -OPERATOR_ckey = "@OPERATOR_ckey@"; ## Freediameter options FD_conf = "@FREEDIAMETER_PATH@/../etc/freeDiameter/hss_fd.conf"; diff --git a/openair-cn/OPENAIRHSS/db/db_connector.c b/openair-cn/OPENAIRHSS/db/db_connector.c index 7e5fada9c7..6585036b04 100644 --- a/openair-cn/OPENAIRHSS/db/db_connector.c +++ b/openair-cn/OPENAIRHSS/db/db_connector.c @@ -42,6 +42,9 @@ #include "hss_config.h" #include "db_proto.h" +extern void ComputeOPc( const uint8_t const kP[16], const uint8_t const opP[16], uint8_t opcP[16] ); + + database_t *db_desc; static void print_buffer(const char *prefix, uint8_t *buffer, int length) @@ -519,7 +522,7 @@ int hss_mysql_auth_info(mysql_auth_info_req_t *auth_info_req, return EINVAL; } - sprintf(query, "SELECT `key`,`sqn`,`rand` FROM `users` WHERE `users`.`imsi`=%s ", + sprintf(query, "SELECT `key`,`sqn`,`rand`,`OPc` FROM `users` WHERE `users`.`imsi`=%s ", auth_info_req->imsi); DB_DEBUG("Query: %s\n", query); @@ -539,7 +542,7 @@ int hss_mysql_auth_info(mysql_auth_info_req_t *auth_info_req, pthread_mutex_unlock(&db_desc->db_cs_mutex); if ((row = mysql_fetch_row(res)) != NULL) { - if (row[0] == NULL || row[1] == NULL || row[2] == NULL) { + if (row[0] == NULL || row[1] == NULL || row[2] == NULL || row[3] == NULL) { ret = EINVAL; } @@ -569,6 +572,11 @@ int hss_mysql_auth_info(mysql_auth_info_req_t *auth_info_req, memcpy(auth_info_resp->rand, row[2], RAND_LENGTH); } + if (row[3] != NULL) { + print_buffer("OPc: ", (uint8_t*)row[3], KEY_LENGTH); + memcpy(auth_info_resp->opc, row[3], KEY_LENGTH); + } + mysql_free_result(res); mysql_thread_end(); return ret; @@ -579,3 +587,115 @@ int hss_mysql_auth_info(mysql_auth_info_req_t *auth_info_req, return EINVAL; } + +int hss_mysql_check_opc_keys(const uint8_t const opP[16]) +{ + int ret = 0; + MYSQL_RES *res = NULL; + MYSQL_RES *res2 = NULL; + MYSQL_ROW row; + char query[1000]; + char update[1000]; + uint8_t k[16]; + uint8_t opc[16]; + int update_length = 0; + int status = 0; + int i; + + if (db_desc->db_conn == NULL) { + return EINVAL; + } + + sprintf(query, "SELECT `imsi`,`key`,`OPc` FROM `users` "); + + DB_DEBUG("Query: %s\n", query); + + pthread_mutex_lock(&db_desc->db_cs_mutex); + + if (mysql_query(db_desc->db_conn, query)) { + pthread_mutex_unlock(&db_desc->db_cs_mutex); + DB_ERROR("Query execution failed: %s\n", + mysql_error(db_desc->db_conn)); + mysql_thread_end(); + return EINVAL; + } + + res = mysql_store_result(db_desc->db_conn); + + pthread_mutex_unlock(&db_desc->db_cs_mutex); + + + while ((row = mysql_fetch_row(res))) { + if (row[0] == NULL || row[1] == NULL ) { + DB_ERROR("Query execution failed: %s\n", + mysql_error(db_desc->db_conn)); + ret = EINVAL; + } else { + if (row[0] != NULL) { + printf("IMSI: %s", (uint8_t*)row[0]); + } + if (row[1] != NULL) { + print_buffer("Key: ", (uint8_t*)row[1], KEY_LENGTH); + memcpy(k, row[1], KEY_LENGTH); + } + //if (row[3] != NULL) + { + print_buffer("OPc: ", (uint8_t*)row[2], KEY_LENGTH); + //} else { + ComputeOPc( k, opP, opc); + update_length = sprintf(update, "UPDATE `users` SET `OPc`=UNHEX('"); + for (i = 0; i < KEY_LENGTH; i ++) { + update_length += sprintf(&update[update_length], "%02x", opc[i]); + } + update_length += sprintf(&update[update_length], "') WHERE `users`.`imsi`='%s'", (uint8_t*)row[0]); + DB_DEBUG("Query: %s\n", update); + + if (mysql_query(db_desc->db_conn, update)) { + DB_ERROR("Query execution failed: %s\n", + mysql_error(db_desc->db_conn)); + } else { + printf("IMSI %s Updated OPc ", (uint8_t*)row[0]); + for (i = 0; i < KEY_LENGTH; i ++) { + printf("%02x", (uint8_t)(row[2][i])); + } + printf(" -> "); + for (i = 0; i < KEY_LENGTH; i ++) { + printf("%02x", opc[i]); + } + printf("\n"); + + /* process each statement result */ + do { + /* did current statement return data? */ + res2 = mysql_store_result(db_desc->db_conn); + + if (res2) { + /* yes; process rows and free the result set */ + mysql_free_result(res2); + } else { /* no result set or error */ + if (mysql_field_count(db_desc->db_conn) == 0) { + DB_ERROR("%lld rows affected\n", + mysql_affected_rows(db_desc->db_conn)); + } else { /* some error occurred */ + DB_ERROR("Could not retrieve result set\n"); + break; + } + } + + /* more results? -1 = no, >0 = error, 0 = yes (keep looping) */ + if ((status = mysql_next_result(db_desc->db_conn)) > 0) + DB_ERROR("Could not execute statement\n"); + } while (status == 0); + } + } + } + } + + mysql_free_result(res); + mysql_thread_end(); + + return ret; + +} + + diff --git a/openair-cn/OPENAIRHSS/db/db_proto.h b/openair-cn/OPENAIRHSS/db/db_proto.h index 1e08236ec1..d87ed461e5 100644 --- a/openair-cn/OPENAIRHSS/db/db_proto.h +++ b/openair-cn/OPENAIRHSS/db/db_proto.h @@ -72,26 +72,33 @@ typedef struct { #define SQN_LENGTH (6) #define RAND_LENGTH (16) -typedef struct { +typedef struct mysql_auth_info_resp_s{ uint8_t key[KEY_LENGTH]; uint8_t sqn[SQN_LENGTH]; /* RAND should not be here... */ uint8_t rand[RAND_LENGTH]; + uint8_t opc[KEY_LENGTH]; } mysql_auth_info_resp_t; -typedef struct { +typedef struct mysql_opc_push_s{ + char imsi[IMSI_LENGTH_MAX + 1]; + /* New computed SQN that will be used on next auth info req */ + uint8_t sqn[SQN_LENGTH]; +} mysql_opc_push_t; + +typedef struct mysql_sqn_push_s{ char imsi[IMSI_LENGTH_MAX + 1]; /* New computed SQN that will be used on next auth info req */ uint8_t sqn[SQN_LENGTH]; } mysql_sqn_push_t; -typedef struct { +typedef struct mysql_mme_identity_s{ /* An MME may have already been registered as serving the UE. */ char mme_host[255]; char mme_realm[200]; } mysql_mme_identity_t; -typedef struct { +typedef struct mysql_ul_ans_s{ char imsi[16]; /* MSISDN this parameter may be NULL */ char msisdn[16]; @@ -107,7 +114,7 @@ typedef struct { mysql_mme_identity_t mme_identity; } mysql_ul_ans_t; -typedef struct { +typedef struct mysql_ul_push_s{ /* Bit masks indicating presence of optional fields */ #define MME_IDENTITY_PRESENT (0x1) #define MME_SUPPORTED_FEATURES_PRESENT (0x1) @@ -140,12 +147,12 @@ typedef enum { IPV4_OR_IPV6 = 3, } pdn_type_t; -typedef struct { +typedef struct pdn_address_s{ char ipv4_address[INET_ADDRSTRLEN]; char ipv6_address[INET6_ADDRSTRLEN]; } pdn_address_t; -typedef struct { +typedef struct mysql_pdn_s{ char apn[61]; pdn_type_t pdn_type; pdn_address_t pdn_address; @@ -157,7 +164,7 @@ typedef struct { pre_emp_vul_t pre_emp_vul; } mysql_pdn_t; -typedef struct { +typedef struct mysql_pu_req_s{ /* IMSI */ char imsi[16]; } mysql_pu_req_t; @@ -193,4 +200,7 @@ int hss_mysql_push_rand_sqn(const char *imsi, uint8_t *rand_p, uint8_t *sqn); int hss_mysql_increment_sqn(const char *imsi); +int hss_mysql_check_opc_keys(const uint8_t const opP[16]); + + #endif /* DB_PROTO_H_ */ diff --git a/openair-cn/OPENAIRHSS/db/oai_db.sql b/openair-cn/OPENAIRHSS/db/oai_db.sql index 2f2a1ae2d3..c763ce4afb 100644 --- a/openair-cn/OPENAIRHSS/db/oai_db.sql +++ b/openair-cn/OPENAIRHSS/db/oai_db.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Host: localhost --- Generation Time: May 04, 2015 at 10:41 AM +-- Generation Time: May 28, 2015 at 02:32 PM -- Server version: 5.5.43-0ubuntu0.14.04.1 -- PHP Version: 5.5.9-1ubuntu4.9 @@ -80,22 +80,19 @@ CREATE TABLE IF NOT EXISTS `pdn` ( PRIMARY KEY (`id`,`pgw_id`,`users_imsi`), KEY `fk_pdn_pgw1_idx` (`pgw_id`), KEY `fk_pdn_users1_idx` (`users_imsi`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=19 ; +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=36 ; -- -- Dumping data for table `pdn` -- INSERT INTO `pdn` (`id`, `apn`, `pdn_type`, `pdn_ipv4`, `pdn_ipv6`, `aggregate_ambr_ul`, `aggregate_ambr_dl`, `pgw_id`, `users_imsi`, `qci`, `priority_level`, `pre_emp_cap`, `pre_emp_vul`, `LIPA-Permissions`) VALUES -(18, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208930000000001', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(1, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '20834123456789', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(8, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000008', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(9, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000009', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(1, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208930000000001', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(11, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '20834123456789', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), (10, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '20810000001234', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(11, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000053', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(12, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000055', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(13, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '31002890832150', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), -(16, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000054', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'); +(12, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '31002890832150', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(2, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208950000000002', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(3, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '001010123456789', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'); -- -------------------------------------------------------- @@ -156,6 +153,7 @@ CREATE TABLE IF NOT EXISTS `users` ( `urrp_mme` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'UE Reachability Request Parameter indicating that UE activity notification from MME has been requested by the HSS.', `sqn` bigint(20) unsigned zerofill NOT NULL, `rand` varbinary(16) NOT NULL, + `OPc` varbinary(16) DEFAULT NULL COMMENT 'Can be computed by HSS', PRIMARY KEY (`imsi`,`mmeidentity_idmmeidentity`), KEY `fk_users_mmeidentity_idx1` (`mmeidentity_idmmeidentity`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -164,17 +162,13 @@ CREATE TABLE IF NOT EXISTS `users` ( -- Dumping data for table `users` -- -INSERT INTO `users` (`imsi`, `msisdn`, `imei`, `imei_sv`, `ms_ps_status`, `rau_tau_timer`, `ue_ambr_ul`, `ue_ambr_dl`, `access_restriction`, `mme_cap`, `mmeidentity_idmmeidentity`, `key`, `RFSP-Index`, `urrp_mme`, `sqn`, `rand`) VALUES -('20834123456789', '380561234567', '12345678', '23', 'PURGED', 50, 40000000, 100000000, 47, 0000000000, 2, '+�E��ų\0�,IH��H', 0, 0, 00000000000000000096, 'Px�X \Z1��x��'), -('208920000000008', '33638060008', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000004294969388, '��I�j���>O�O�K)'), -('208920000000009', '33638060009', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�ДWdiHC�', 1, 0, 00000000000000033361, '\ZM{�h��#�\\*l��'), -('20810000001234', '33611123456', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000281454575616097, 's���$r�C�f�=:�x�'), -('208920000000053', '33638060053', '35611302209415', NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д6�`FB&w', 1, 0, 00000000004294972622, 'o.�q@�#�\0�^���4�'), -('208920000000055', '33638060055', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�ДM_^r v', 1, 0, 00000000004294969388, '��I�j���>O�O�K)'), -('31002890832150', '33638060059', '35611302209414', NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000000000012416, '`�F�݆��D��ϛ���'), -('208920000000054', '33638060054', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�ДM_^r v', 1, 0, 00000000000000039820, 'B@W�شJUٰTo�C'), -('001010123456789', '33600101789', NULL, NULL, 'PURGED', 120, 50000000, 100000000, 47, 0000000000, 2, '\0 \n\r', 1, 0, 00000000000000000032, '��e�E�S��Aj��|'), -('208930000000001', '33638060008', NULL, NULL, 'NOT_PURGED', 120, 50000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000000000002487, '�$�N!�Mp�-T�)#�'); +INSERT INTO `users` (`imsi`, `msisdn`, `imei`, `imei_sv`, `ms_ps_status`, `rau_tau_timer`, `ue_ambr_ul`, `ue_ambr_dl`, `access_restriction`, `mme_cap`, `mmeidentity_idmmeidentity`, `key`, `RFSP-Index`, `urrp_mme`, `sqn`, `rand`, `OPc`) VALUES +('20834123456789', '380561234567', '12345678', '23', 'PURGED', 50, 40000000, 100000000, 47, 0000000000, 2, '+�E��ų\0�,IH��H', 0, 0, 00000000000000000096, 'Px�X \Z1��x��', 'g퐐jS+Aq���6Y'), +('20810000001234', '33611123456', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000281454575616097, 's���$r�C�f�=:�x�', '�''��i.u2fz;`]'), +('31002890832150', '33638060059', '35611302209414', NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000000000012416, '`�F�݆��D��ϛ���', '�''��i.u2fz;`]'), +('001010123456789', '33600101789', NULL, NULL, 'PURGED', 120, 50000000, 100000000, 47, 0000000000, 2, '\0 \n\r', 1, 0, 00000000000000000351, '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', '$�_|/+6��%/%���'), +('208930000000001', '33638060008', NULL, NULL, 'PURGED', 120, 50000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000000000006103, '��wq��gzW�Ё��Z]', '�''��i.u2fz;`]'), +('208950000000002', '33638060009', NULL, NULL, 'PURGED', 120, 50000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000000000006391, 'U�|� w�D��\Z�7', '�''��i.u2fz;`]'); /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; diff --git a/openair-cn/OPENAIRHSS/db/pft_db.sql b/openair-cn/OPENAIRHSS/db/pft_db.sql new file mode 100644 index 0000000000..e2eb8bfaa6 --- /dev/null +++ b/openair-cn/OPENAIRHSS/db/pft_db.sql @@ -0,0 +1,173 @@ +-- phpMyAdmin SQL Dump +-- version 4.0.10deb1 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: May 28, 2015 at 02:24 PM +-- Server version: 5.5.43-0ubuntu0.14.04.1 +-- PHP Version: 5.5.9-1ubuntu4.9 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- Database: `oai_db` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `apn` +-- + +CREATE TABLE IF NOT EXISTS `apn` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `apn-name` varchar(60) NOT NULL, + `pdn-type` enum('IPv4','IPv6','IPv4v6','IPv4_or_IPv6') NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `apn-name` (`apn-name`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `mmeidentity` +-- + +CREATE TABLE IF NOT EXISTS `mmeidentity` ( + `idmmeidentity` int(11) NOT NULL AUTO_INCREMENT, + `mmehost` varchar(255) DEFAULT NULL, + `mmerealm` varchar(200) DEFAULT NULL, + `UE-Reachability` tinyint(1) NOT NULL COMMENT 'Indicates whether the MME supports UE Reachability Notifcation', + PRIMARY KEY (`idmmeidentity`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=43 ; + +-- +-- Dumping data for table `mmeidentity` +-- + +INSERT INTO `mmeidentity` (`idmmeidentity`, `mmehost`, `mmerealm`, `UE-Reachability`) VALUES +(2, 'yang.openair4G.eur', 'openair4G.eur', 0), +(1, 'ng40-erc.openair4G.eur', 'openair4G.eur', 0); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pdn` +-- + +CREATE TABLE IF NOT EXISTS `pdn` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `apn` varchar(60) NOT NULL, + `pdn_type` enum('IPv4','IPv6','IPv4v6','IPv4_or_IPv6') NOT NULL DEFAULT 'IPv4', + `pdn_ipv4` varchar(15) DEFAULT '0.0.0.0', + `pdn_ipv6` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT '0:0:0:0:0:0:0:0', + `aggregate_ambr_ul` int(10) unsigned DEFAULT '50000000', + `aggregate_ambr_dl` int(10) unsigned DEFAULT '100000000', + `pgw_id` int(11) NOT NULL, + `users_imsi` varchar(15) NOT NULL, + `qci` tinyint(3) unsigned NOT NULL DEFAULT '9', + `priority_level` tinyint(3) unsigned NOT NULL DEFAULT '15', + `pre_emp_cap` enum('ENABLED','DISABLED') DEFAULT 'DISABLED', + `pre_emp_vul` enum('ENABLED','DISABLED') DEFAULT 'DISABLED', + `LIPA-Permissions` enum('LIPA-prohibited','LIPA-only','LIPA-conditional') NOT NULL DEFAULT 'LIPA-only', + PRIMARY KEY (`id`,`pgw_id`,`users_imsi`), + KEY `fk_pdn_pgw1_idx` (`pgw_id`), + KEY `fk_pdn_users1_idx` (`users_imsi`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=36 ; + +-- +-- Dumping data for table `pdn` +-- + +INSERT INTO `pdn` (`id`, `apn`, `pdn_type`, `pdn_ipv4`, `pdn_ipv6`, `aggregate_ambr_ul`, `aggregate_ambr_dl`, `pgw_id`, `users_imsi`, `qci`, `priority_level`, `pre_emp_cap`, `pre_emp_vul`, `LIPA-Permissions`) VALUES +(8, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000008', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(9, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000009', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(11, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000053', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(12, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000055', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'), +(16, 'oai.ipv4', 'IPv4', '0.0.0.0', '0:0:0:0:0:0:0:0', 50000000, 100000000, 3, '208920000000054', 9, 15, 'DISABLED', 'ENABLED', 'LIPA-only'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pgw` +-- + +CREATE TABLE IF NOT EXISTS `pgw` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ipv4` varchar(15) NOT NULL, + `ipv6` varchar(39) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `ipv4` (`ipv4`), + UNIQUE KEY `ipv6` (`ipv6`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; + +-- +-- Dumping data for table `pgw` +-- + +INSERT INTO `pgw` (`id`, `ipv4`, `ipv6`) VALUES +(1, '127.0.0.1', '0:0:0:0:0:0:0:1'), +(2, '192.168.56.101', ''), +(3, '10.0.0.2', '0'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `terminal-info` +-- + +CREATE TABLE IF NOT EXISTS `terminal-info` ( + `imei` varchar(15) NOT NULL, + `sv` varchar(2) NOT NULL, + UNIQUE KEY `imei` (`imei`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +CREATE TABLE IF NOT EXISTS `users` ( + `imsi` varchar(15) NOT NULL COMMENT 'IMSI is the main reference key.', + `msisdn` varchar(46) DEFAULT NULL COMMENT 'The basic MSISDN of the UE (Presence of MSISDN is optional).', + `imei` varchar(15) DEFAULT NULL COMMENT 'International Mobile Equipment Identity', + `imei_sv` varchar(2) DEFAULT NULL COMMENT 'International Mobile Equipment Identity Software Version Number', + `ms_ps_status` enum('PURGED','NOT_PURGED') DEFAULT 'PURGED' COMMENT 'Indicates that ESM and EMM status are purged from MME', + `rau_tau_timer` int(10) unsigned DEFAULT '120', + `ue_ambr_ul` bigint(20) unsigned DEFAULT '50000000' COMMENT 'The Maximum Aggregated uplink MBRs to be shared across all Non-GBR bearers according to the subscription of the user.', + `ue_ambr_dl` bigint(20) unsigned DEFAULT '100000000' COMMENT 'The Maximum Aggregated downlink MBRs to be shared across all Non-GBR bearers according to the subscription of the user.', + `access_restriction` int(10) unsigned DEFAULT '60' COMMENT 'Indicates the access restriction subscription information. 3GPP TS.29272 #7.3.31', + `mme_cap` int(10) unsigned zerofill DEFAULT NULL COMMENT 'Indicates the capabilities of the MME with respect to core functionality e.g. regional access restrictions.', + `mmeidentity_idmmeidentity` int(11) NOT NULL DEFAULT '0', + `key` varbinary(16) NOT NULL DEFAULT '0' COMMENT 'UE security key', + `RFSP-Index` smallint(5) unsigned NOT NULL DEFAULT '1' COMMENT 'An index to specific RRM configuration in the E-UTRAN. Possible values from 1 to 256', + `urrp_mme` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'UE Reachability Request Parameter indicating that UE activity notification from MME has been requested by the HSS.', + `sqn` bigint(20) unsigned zerofill NOT NULL, + `rand` varbinary(16) NOT NULL, + `OPc` varbinary(16) DEFAULT NULL COMMENT 'Can be computed by HSS', + PRIMARY KEY (`imsi`,`mmeidentity_idmmeidentity`), + KEY `fk_users_mmeidentity_idx1` (`mmeidentity_idmmeidentity`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `users` +-- + +INSERT INTO `users` (`imsi`, `msisdn`, `imei`, `imei_sv`, `ms_ps_status`, `rau_tau_timer`, `ue_ambr_ul`, `ue_ambr_dl`, `access_restriction`, `mme_cap`, `mmeidentity_idmmeidentity`, `key`, `RFSP-Index`, `urrp_mme`, `sqn`, `rand`, `OPc`) VALUES +('208920000000008', '33638060008', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д���� |hb', 1, 0, 00000000004294969388, '��I�j���>O�O�K)', '�''��i.u2fz;`]'), +('208920000000009', '33638060009', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�ДWdiHC�', 1, 0, 00000000000000033361, '\ZM{�h��#�\\*l��', '����x�J�� ��'), +('208920000000053', '33638060053', '35611302209415', NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�Д6�`FB&w', 1, 0, 00000000004294972622, 'o.�q@�#�\0�^���4�', 'O��~�����ɭ��'), +('208920000000055', '33638060055', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�ДM_^r v', 1, 0, 00000000004294969388, '��I�j���>O�O�K)', 'N�0;�bCR����_'), +('208920000000054', '33638060054', NULL, NULL, 'PURGED', 120, 40000000, 100000000, 47, 0000000000, 2, '��G?/�ДM_^r v', 1, 0, 00000000000000039820, 'B@W�شJUٰTo�C', 'N�0;�bCR����_'); + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/openair-cn/OPENAIRHSS/hss_main.c b/openair-cn/OPENAIRHSS/hss_main.c index be21f1c1f6..5a226bc0d9 100644 --- a/openair-cn/OPENAIRHSS/hss_main.c +++ b/openair-cn/OPENAIRHSS/hss_main.c @@ -37,6 +37,7 @@ hss_config_t hss_config; + int main(int argc, char *argv[]) { @@ -52,6 +53,10 @@ int main(int argc, char *argv[]) random_init(); + if (hss_config.valid_op) { + hss_mysql_check_opc_keys((uint8_t*)hss_config.operator_key_bin); + } + s6a_init(&hss_config); while(1) { diff --git a/openair-cn/OPENAIRHSS/s6a/s6a_auth_info.c b/openair-cn/OPENAIRHSS/s6a/s6a_auth_info.c index 69651c9116..718e48cce4 100644 --- a/openair-cn/OPENAIRHSS/s6a/s6a_auth_info.c +++ b/openair-cn/OPENAIRHSS/s6a/s6a_auth_info.c @@ -210,7 +210,7 @@ int s6a_auth_info_cb(struct msg **msg, struct avp *paramavp, if (auts != NULL) { /* Try to derive SQN_MS from previous RAND */ - sqn = sqn_ms_derive(auth_info_resp.key, auts, auth_info_resp.rand); + sqn = sqn_ms_derive(auth_info_resp.opc, auth_info_resp.key, auts, auth_info_resp.rand); if (sqn != NULL) { /* We succeeded to verify SQN_MS... */ @@ -245,7 +245,7 @@ int s6a_auth_info_cb(struct msg **msg, struct avp *paramavp, hss_mysql_increment_sqn(auth_info_req.imsi); /* Generate authentication vector */ - generate_vector(imsi, auth_info_resp.key, + generate_vector(auth_info_resp.opc, imsi, auth_info_resp.key, hdr->avp_value->os.data, sqn, &vector); /* We add the vector */ diff --git a/openair-cn/OPENAIRHSS/utils/hss_config.c b/openair-cn/OPENAIRHSS/utils/hss_config.c index 6428d11f80..415504fc75 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_config.c +++ b/openair-cn/OPENAIRHSS/utils/hss_config.c @@ -65,8 +65,6 @@ int fd_g_debug_lvl = 1; /* YACC forward declarations */ extern int yyparse (struct hss_config_s *hss_config_p); -extern uint8_t opc[16]; -extern uint8_t op [16]; static int config_parse_command_line(int argc, char *argv[], hss_config_t *hss_config_p); static int config_parse_file(hss_config_t *hss_config_p); @@ -91,7 +89,6 @@ int config_init(int argc, char *argv[], hss_config_t *hss_config_p) } hss_config_p->valid_op = 0; - hss_config_p->valid_opc = 0; if ((ret = config_parse_command_line(argc, argv, hss_config_p)) != 0) { return ret; @@ -103,22 +100,38 @@ int config_init(int argc, char *argv[], hss_config_t *hss_config_p) /* Parsing of the file failed. -> abort */ abort(); } - - config_display(hss_config_p); + if (hss_config_p->random) { + if (strcasecmp(hss_config_p->random, "false") == 0) { + hss_config_p->random_bool = 0; + } else if (strcasecmp(hss_config_p->random, "true") == 0) { + hss_config_p->random_bool = 1; + } else { + fprintf(stderr, + "Error in configuration file: random: %s (allowed values {true,false})\n", + hss_config_p->random); + abort(); + } + } else { + hss_config_p->random = "true"; + hss_config_p->random_bool = 1; + fprintf(stderr, + "Default values for random: %s (allowed values {true,false})\n", + hss_config_p->random); + } // post processing for op key if (hss_config_p->operator_key) { if (strlen(hss_config_p->operator_key) == 32) { ret = sscanf(hss_config_p->operator_key, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - (unsigned int*)&op[0],(unsigned int*)&op[1], - (unsigned int*)&op[2],(unsigned int*)&op[3], - (unsigned int*)&op[4],(unsigned int*)&op[5], - (unsigned int*)&op[6],(unsigned int*)&op[7], - (unsigned int*)&op[8],(unsigned int*)&op[9], - (unsigned int*)&op[10],(unsigned int*)&op[11], - (unsigned int*)&op[12],(unsigned int*)&op[13], - (unsigned int*)&op[14],(unsigned int*)&op[15]); + (unsigned int*)&hss_config_p->operator_key_bin[0],(unsigned int*)&hss_config_p->operator_key_bin[1], + (unsigned int*)&hss_config_p->operator_key_bin[2],(unsigned int*)&hss_config_p->operator_key_bin[3], + (unsigned int*)&hss_config_p->operator_key_bin[4],(unsigned int*)&hss_config_p->operator_key_bin[5], + (unsigned int*)&hss_config_p->operator_key_bin[6],(unsigned int*)&hss_config_p->operator_key_bin[7], + (unsigned int*)&hss_config_p->operator_key_bin[8],(unsigned int*)&hss_config_p->operator_key_bin[9], + (unsigned int*)&hss_config_p->operator_key_bin[10],(unsigned int*)&hss_config_p->operator_key_bin[11], + (unsigned int*)&hss_config_p->operator_key_bin[12],(unsigned int*)&hss_config_p->operator_key_bin[13], + (unsigned int*)&hss_config_p->operator_key_bin[14],(unsigned int*)&hss_config_p->operator_key_bin[15]); if (ret != 16) { fprintf(stderr, @@ -129,32 +142,9 @@ int config_init(int argc, char *argv[], hss_config_t *hss_config_p) hss_config_p->valid_op = 1; } } - if (hss_config_p->operator_ckey) { - if (strlen(hss_config_p->operator_ckey) == 32) { - ret = sscanf(hss_config_p->operator_ckey, - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - (unsigned int*)&opc[0],(unsigned int*)&opc[1], - (unsigned int*)&opc[2],(unsigned int*)&opc[3], - (unsigned int*)&opc[4],(unsigned int*)&opc[5], - (unsigned int*)&opc[6],(unsigned int*)&opc[7], - (unsigned int*)&opc[8],(unsigned int*)&opc[9], - (unsigned int*)&opc[10],(unsigned int*)&opc[11], - (unsigned int*)&opc[12],(unsigned int*)&opc[13], - (unsigned int*)&opc[14],(unsigned int*)&opc[15]); + config_display(hss_config_p); + - if (ret != 16) { - fprintf(stderr, - "Error in configuration file: operator ckey: %s\n", - hss_config_p->operator_ckey); - abort(); - } - hss_config_p->valid_opc = 1; - } - } - if ((hss_config_p->valid_opc == 0) && (hss_config_p->valid_op ==0)) { - fprintf(stderr, "Error in configuration file: no valid OP or OPC key\n"); - abort(); - } return 0; } @@ -195,8 +185,8 @@ static void config_display(hss_config_t *hss_config_p) fprintf(stdout, "* Security:\n"); fprintf(stdout, "\t- Operator key......: %s\n", hss_config_p->operator_key); - fprintf(stdout, "\t- Operator ckey......: %s\n", - hss_config_p->operator_ckey); + fprintf(stdout, "\t- Random ......: %s\n", + hss_config_p->random); } static int config_parse_command_line(int argc, char *argv[], diff --git a/openair-cn/OPENAIRHSS/utils/hss_config.h b/openair-cn/OPENAIRHSS/utils/hss_config.h index a3bd22979b..6f3425c6d0 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_config.h +++ b/openair-cn/OPENAIRHSS/utils/hss_config.h @@ -37,15 +37,17 @@ typedef struct hss_config_s { char *operator_key; + unsigned char operator_key_bin[16]; int valid_op; - char *operator_ckey; - int valid_opc; /* The freediameter configuration file */ char *freediameter_config; /* THe HSS global configuration file */ char *config; + + char *random; + char random_bool; } hss_config_t; int config_init(int argc, char *argv[], hss_config_t *hss_config_p); diff --git a/openair-cn/OPENAIRHSS/utils/hss_parser.y b/openair-cn/OPENAIRHSS/utils/hss_parser.y index b01de3552d..5fb532dcdf 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_parser.y +++ b/openair-cn/OPENAIRHSS/utils/hss_parser.y @@ -70,7 +70,7 @@ int fddlex(YYSTYPE *lvalp, YYLTYPE *llocp); %token MYSQL_PASS %token MYSQL_DB %token OPERATOR_KEY -%token OPERATOR_CKEY +%token RANDOM %% conffile: /* Empty is OK -- for simplicity here, we reject in daemon later */ @@ -79,7 +79,7 @@ conffile: /* Empty is OK -- for simplicity here, we reject in daemon later | conffile mysql_user | conffile mysql_pass | conffile operator_key - | conffile operator_ckey + | conffile random | conffile fdconf | conffile errors { @@ -118,9 +118,9 @@ operator_key: OPERATOR_KEY '=' QSTRING ';' } ; -operator_ckey: OPERATOR_CKEY '=' QSTRING ';' +random: RANDOM '=' QSTRING ';' { - hss_config_p->operator_ckey = $3; + hss_config_p->random = $3; } ; diff --git a/openair-cn/OPENAIRHSS/utils/hss_scanner.l b/openair-cn/OPENAIRHSS/utils/hss_scanner.l index 9c3590ae7e..e9c43c9a2b 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_scanner.l +++ b/openair-cn/OPENAIRHSS/utils/hss_scanner.l @@ -114,7 +114,7 @@ qstring \"[^\"\n]*\" (?i:"MYSQL_pass") { return MYSQL_PASS; } (?i:"MYSQL_db") { return MYSQL_DB; } (?i:"OPERATOR_key") { return OPERATOR_KEY; } -(?i:"OPERATOR_ckey") { return OPERATOR_CKEY; } +(?i:"RANDOM") { return RANDOM; } /* Valid single characters for yyparse */ <*>[=,:;{}] { return yytext[0]; } -- GitLab