Commit 1ebc0f0b authored by Lionel Gauthier's avatar Lionel Gauthier

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
parent 08b8af29
......@@ -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] );
......
......@@ -21,23 +21,38 @@
#include <string.h>
#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 */
......@@ -36,12 +36,18 @@
#include <nettle/hmac.h>
#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;
......
......@@ -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];
......
......@@ -32,6 +32,10 @@
#include <string.h>
#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);
......
......@@ -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";
......@@ -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));
......
......@@ -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[],
......
......@@ -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;
......
......@@ -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;
......
......@@ -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]; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment