From 762ddb1ce988c2450343f712b074a89f62e5f6be Mon Sep 17 00:00:00 2001 From: Lionel Gauthier Date: Fri, 22 May 2015 10:15:12 +0000 Subject: [PATCH] Hss now can take OPC key as argument in config file git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7458 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/OPENAIRHSS/auc/auc.h | 2 +- openair-cn/OPENAIRHSS/auc/fx.c | 117 +++++++++++++------- openair-cn/OPENAIRHSS/auc/kdf.c | 14 ++- openair-cn/OPENAIRHSS/auc/rijndael.c | 3 + openair-cn/OPENAIRHSS/auc/sequence_number.c | 8 +- openair-cn/OPENAIRHSS/conf/hss.conf.in | 1 + openair-cn/OPENAIRHSS/hss_main.c | 3 +- openair-cn/OPENAIRHSS/utils/hss_config.c | 44 ++++++-- openair-cn/OPENAIRHSS/utils/hss_config.h | 3 + openair-cn/OPENAIRHSS/utils/hss_parser.y | 8 ++ openair-cn/OPENAIRHSS/utils/hss_scanner.l | 1 + 11 files changed, 148 insertions(+), 56 deletions(-) diff --git a/openair-cn/OPENAIRHSS/auc/auc.h b/openair-cn/OPENAIRHSS/auc/auc.h index 07aa199086..81d7876cec 100644 --- a/openair-cn/OPENAIRHSS/auc/auc.h +++ b/openair-cn/OPENAIRHSS/auc/auc.h @@ -77,7 +77,7 @@ struct random_state_s; void random_init(void); void generate_random(uint8_t *random, ssize_t length); -void SetOPc(const u8 const op_c[16]); +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] ); diff --git a/openair-cn/OPENAIRHSS/auc/fx.c b/openair-cn/OPENAIRHSS/auc/fx.c index 41394c4444..284927fe3d 100644 --- a/openair-cn/OPENAIRHSS/auc/fx.c +++ b/openair-cn/OPENAIRHSS/auc/fx.c @@ -21,23 +21,38 @@ #include #include "auc.h" +#include "hss_config.h" + +extern hss_config_t hss_config; /*--------- Operator Variant Algorithm Configuration Field --------*/ /*------- Insert your value of OP here -------*/ -u8 OP[16]= { - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 -}; +extern uint8_t opc[16]; +extern uint8_t op[16]; /*--------------------------- prototypes --------------------------*/ -void ComputeOPc( u8 op_c[16] ); +void ComputeOPc( u8 opP[16] ); -void SetOPc(const u8 const op_c[16]) +void SetOP(char *opP) { - memcpy(OP, op_c, 16); - printf("SetOPc: OP : %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X ", - 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]); + 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 ", + 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]) @@ -64,17 +79,19 @@ void generate_autn(const u8 const sqn[6], const u8 const ak[6], const u8 const a 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] ) { - u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); - ComputeOPc( op_c ); + if (hss_config.valid_opc == 0) { + SetOP(hss_config.operator_key); + ComputeOPc( opc ); + } for (i=0; i<16; i++) - rijndaelInput[i] = _rand[i] ^ op_c[i]; + rijndaelInput[i] = _rand[i] ^ opc[i]; RijndaelEncrypt( rijndaelInput, temp ); @@ -91,7 +108,7 @@ void f1 ( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[6], /* XOR op_c and in1, rotate by r1=64, and XOR * * on the constant c1 (which is all zeroes) */ for (i=0; i<16; i++) - rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i]; + rijndaelInput[(i+8) % 16] = in1[i] ^ opc[i]; /* XOR on the value temp computed before */ for (i=0; i<16; i++) @@ -100,7 +117,7 @@ void f1 ( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[6], RijndaelEncrypt( rijndaelInput, out1 ); for (i=0; i<16; i++) - out1[i] ^= op_c[i]; + out1[i] ^= opc[i]; for (i=0; i<8; i++) mac_a[i] = out1[i]; @@ -119,16 +136,18 @@ void f1 ( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[6], void f2345 ( const u8 const k[16], const u8 const _rand[16], u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] ) { - u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); - ComputeOPc( op_c ); + if (hss_config.valid_opc == 0) { + SetOP(hss_config.operator_key); + ComputeOPc( opc ); + } for (i=0; i<16; i++) - rijndaelInput[i] = _rand[i] ^ op_c[i]; + rijndaelInput[i] = _rand[i] ^ opc[i]; RijndaelEncrypt( rijndaelInput, temp ); @@ -136,13 +155,13 @@ void f2345 ( const u8 const k[16], const u8 const _rand[16], * rotate by r2=0, and XOR on the constant c2 (which * * is all zeroes except that the last bit is 1). */ for (i=0; i<16; i++) - rijndaelInput[i] = temp[i] ^ op_c[i]; + rijndaelInput[i] = temp[i] ^ opc[i]; rijndaelInput[15] ^= 1; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) - out[i] ^= op_c[i]; + out[i] ^= opc[i]; for (i=0; i<8; i++) res[i] = out[i+8]; @@ -155,13 +174,13 @@ void f2345 ( const u8 const k[16], const u8 const _rand[16], * is all zeroes except that the next to last bit is 1). */ for (i=0; i<16; i++) - rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i]; + rijndaelInput[(i+12) % 16] = temp[i] ^ opc[i]; rijndaelInput[15] ^= 2; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) - out[i] ^= op_c[i]; + out[i] ^= opc[i]; for (i=0; i<16; i++) ck[i] = out[i]; @@ -170,13 +189,13 @@ void f2345 ( const u8 const k[16], const u8 const _rand[16], * rotate by r4=64, and XOR on the constant c4 (which * * is all zeroes except that the 2nd from last bit is 1). */ for (i=0; i<16; i++) - rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i]; + rijndaelInput[(i+8) % 16] = temp[i] ^ opc[i]; rijndaelInput[15] ^= 4; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) - out[i] ^= op_c[i]; + out[i] ^= opc[i]; for (i=0; i<16; i++) ik[i] = out[i]; @@ -196,17 +215,23 @@ void f2345 ( const u8 const k[16], const u8 const _rand[16], 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] ) { - u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k ); - ComputeOPc( op_c ); + 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] ^ op_c[i]; + rijndaelInput[i] = _rand[i] ^ opc[i]; RijndaelEncrypt( rijndaelInput, temp ); @@ -223,7 +248,7 @@ void f1star( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[ /* XOR op_c and in1, rotate by r1=64, and XOR * * on the constant c1 (which is all zeroes) */ for (i=0; i<16; i++) - rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i]; + rijndaelInput[(i+8) % 16] = in1[i] ^ opc[i]; /* XOR on the value temp computed before */ for (i=0; i<16; i++) @@ -232,7 +257,7 @@ void f1star( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[ RijndaelEncrypt( rijndaelInput, out1 ); for (i=0; i<16; i++) - out1[i] ^= op_c[i]; + out1[i] ^= opc[i]; for (i=0; i<8; i++) mac_s[i] = out1[i+8]; @@ -251,16 +276,23 @@ void f1star( const u8 const k[16], const u8 const _rand[16], const u8 const sqn[ void f5star( const u8 const k[16], const u8 const _rand[16], u8 ak[6] ) { - u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; u8 i; + RijndaelKeySchedule( k ); - ComputeOPc( op_c ); + 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] ^ op_c[i]; + rijndaelInput[i] = _rand[i] ^ opc[i]; RijndaelEncrypt( rijndaelInput, temp ); @@ -268,13 +300,13 @@ void f5star( const u8 const k[16], const u8 const _rand[16], * rotate by r5=96, and XOR on the constant c5 (which * * is all zeroes except that the 3rd from last bit is 1). */ for (i=0; i<16; i++) - rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i]; + rijndaelInput[(i+4) % 16] = temp[i] ^ opc[i]; rijndaelInput[15] ^= 8; RijndaelEncrypt( rijndaelInput, out ); for (i=0; i<16; i++) - out[i] ^= op_c[i]; + out[i] ^= opc[i]; for (i=0; i<6; i++) ak[i] = out[i]; @@ -286,17 +318,22 @@ void f5star( const u8 const k[16], const u8 const _rand[16], * Function to compute OPc from OP and K. Assumes key schedule has * already been performed. *-----------------------------------------------------------------*/ -void ComputeOPc( u8 op_c[16] ) +void ComputeOPc( u8 opcP[16] ) { u8 i; - printf("ComputeOPc: OP : %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X ", - 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]); - RijndaelEncrypt( OP, op_c ); + 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], + 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++) - op_c[i] ^= OP[i]; + opcP[i] ^= op[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] ); return; } /* end of function ComputeOPc */ diff --git a/openair-cn/OPENAIRHSS/auc/kdf.c b/openair-cn/OPENAIRHSS/auc/kdf.c index fcd423c4bf..437b9d9b31 100644 --- a/openair-cn/OPENAIRHSS/auc/kdf.c +++ b/openair-cn/OPENAIRHSS/auc/kdf.c @@ -36,12 +36,18 @@ #include #include "auc.h" +#include "hss_config.h" #define DEBUG_AUC_KDF 1 +extern hss_config_t hss_config; uint8_t opc[16] = { - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 + 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 }; /* @@ -87,7 +93,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); - SetOPc(opc); + if (hss_config.valid_opc == 0) { + SetOP(hss_config.operator_key); + } /* FC */ s[0] = 0x10; diff --git a/openair-cn/OPENAIRHSS/auc/rijndael.c b/openair-cn/OPENAIRHSS/auc/rijndael.c index 230e3e1f40..bbf1e57d30 100644 --- a/openair-cn/OPENAIRHSS/auc/rijndael.c +++ b/openair-cn/OPENAIRHSS/auc/rijndael.c @@ -84,6 +84,9 @@ void RijndaelKeySchedule( const u8 const key[16] ) u8 roundConst; int i, j; + printf("RijndaelKeySchedule: K %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", + key[0],key[1],key[2],key[3],key[4],key[5],key[6],key[7], + key[8],key[9],key[10],key[11],key[12],key[13],key[14],key[15] ); /* first round key equals key */ for (i=0; i<16; i++) roundKeys[0][i & 0x03][i>>2] = key[i]; diff --git a/openair-cn/OPENAIRHSS/auc/sequence_number.c b/openair-cn/OPENAIRHSS/auc/sequence_number.c index 754603d246..0e8ad2d756 100644 --- a/openair-cn/OPENAIRHSS/auc/sequence_number.c +++ b/openair-cn/OPENAIRHSS/auc/sequence_number.c @@ -32,6 +32,10 @@ #include #include "auc.h" +#include "hss_config.h" + +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) { @@ -52,7 +56,9 @@ uint8_t *sqn_ms_derive(uint8_t *key, uint8_t *auts, uint8_t *rand_p) sqn_ms = malloc(SQN_LENGTH_OCTEST); - SetOPc(opc); + if (hss_config.valid_opc == 0) { + SetOP(hss_config.operator_key); + } /* Derive AK from key and rand */ f5star(key, rand_p, ak); diff --git a/openair-cn/OPENAIRHSS/conf/hss.conf.in b/openair-cn/OPENAIRHSS/conf/hss.conf.in index 4c5e4c7d93..f0732669ad 100644 --- a/openair-cn/OPENAIRHSS/conf/hss.conf.in +++ b/openair-cn/OPENAIRHSS/conf/hss.conf.in @@ -6,6 +6,7 @@ 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/hss_main.c b/openair-cn/OPENAIRHSS/hss_main.c index fa0f3a451a..be21f1c1f6 100644 --- a/openair-cn/OPENAIRHSS/hss_main.c +++ b/openair-cn/OPENAIRHSS/hss_main.c @@ -35,9 +35,10 @@ #include "s6a_proto.h" #include "auc.h" +hss_config_t hss_config; + int main(int argc, char *argv[]) { - hss_config_t hss_config; memset(&hss_config, 0, sizeof(hss_config_t)); diff --git a/openair-cn/OPENAIRHSS/utils/hss_config.c b/openair-cn/OPENAIRHSS/utils/hss_config.c index ad3749a85c..6428d11f80 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_config.c +++ b/openair-cn/OPENAIRHSS/utils/hss_config.c @@ -66,6 +66,7 @@ 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); @@ -89,6 +90,9 @@ int config_init(int argc, char *argv[], hss_config_t *hss_config_p) return EINVAL; } + 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; } @@ -106,6 +110,28 @@ int config_init(int argc, char *argv[], hss_config_t *hss_config_p) 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]); + + if (ret != 16) { + fprintf(stderr, + "Error in configuration file: operator key: %s\n", + hss_config_p->operator_key); + abort(); + } + 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], @@ -118,21 +144,17 @@ int config_init(int argc, char *argv[], hss_config_t *hss_config_p) if (ret != 16) { fprintf(stderr, - "Error in configuration file: operator key: %s\n", - hss_config_p->operator_key); + "Error in configuration file: operator ckey: %s\n", + hss_config_p->operator_ckey); abort(); } - } else { - fprintf(stderr, - "Error in configuration file: operator key length != 32 (16 hex bytes): %s\n", - hss_config_p->operator_key); - abort(); + hss_config_p->valid_opc = 1; } - } else { - fprintf(stderr, "Error in configuration file: operator key is null\n"); + } + 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; } @@ -173,6 +195,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); } 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 40711d8995..a3bd22979b 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_config.h +++ b/openair-cn/OPENAIRHSS/utils/hss_config.h @@ -37,6 +37,9 @@ typedef struct hss_config_s { char *operator_key; + int valid_op; + char *operator_ckey; + int valid_opc; /* The freediameter configuration file */ char *freediameter_config; diff --git a/openair-cn/OPENAIRHSS/utils/hss_parser.y b/openair-cn/OPENAIRHSS/utils/hss_parser.y index 19c4e81610..b01de3552d 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_parser.y +++ b/openair-cn/OPENAIRHSS/utils/hss_parser.y @@ -70,6 +70,7 @@ int fddlex(YYSTYPE *lvalp, YYLTYPE *llocp); %token MYSQL_PASS %token MYSQL_DB %token OPERATOR_KEY +%token OPERATOR_CKEY %% conffile: /* Empty is OK -- for simplicity here, we reject in daemon later */ @@ -78,6 +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 fdconf | conffile errors { @@ -116,6 +118,12 @@ operator_key: OPERATOR_KEY '=' QSTRING ';' } ; +operator_ckey: OPERATOR_CKEY '=' QSTRING ';' + { + hss_config_p->operator_ckey = $3; + } + ; + fdconf: FDCONF '=' QSTRING ';' { hss_config_p->freediameter_config = $3; diff --git a/openair-cn/OPENAIRHSS/utils/hss_scanner.l b/openair-cn/OPENAIRHSS/utils/hss_scanner.l index bca348528c..9c3590ae7e 100644 --- a/openair-cn/OPENAIRHSS/utils/hss_scanner.l +++ b/openair-cn/OPENAIRHSS/utils/hss_scanner.l @@ -114,6 +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; } /* Valid single characters for yyparse */ <*>[=,:;{}] { return yytext[0]; }