Commit f445dc33 authored by gauthier's avatar gauthier
Browse files

Bugs on network initiated authentication

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5476 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 7196ef93
......@@ -12,10 +12,11 @@
* The functions f2, f3, f4 and f5 share the same inputs and have
* been coded together as a single function. f1, f1* and f5* are
* all coded separately.
*
* From 3GPP 35.206-900
*-----------------------------------------------------------------*/
#include "aka_functions.h"
#include "nas_log.h"
/*--------- Operator Variant Algorithm Configuration Field --------*/
/*------- Insert your value of OP here -------*/
......@@ -33,8 +34,8 @@ u8 OP[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
* field AMF.
*
*-----------------------------------------------------------------*/
void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
u8 mac_a[8] )
void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
u8 mac_a_pP[8] )
{
u8 op_c[16];
u8 temp[16];
......@@ -42,20 +43,20 @@ void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
u8 out1[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
RijndaelKeySchedule( k_pP );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = rand[i] ^ op_c[i];
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
for (i=0; i<6; i++)
{
in1[i] = sqn[i];
in1[i+8] = sqn[i];
in1[i] = sqn_pP[i];
in1[i+8] = sqn_pP[i];
}
for (i=0; i<2; i++)
{
in1[i+6] = amf[i];
in1[i+14] = amf[i];
in1[i+6] = amf_pP[i];
in1[i+14] = amf_pP[i];
}
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
......@@ -68,7 +69,7 @@ void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
for (i=0; i<16; i++)
out1[i] ^= op_c[i];
for (i=0; i<8; i++)
mac_a[i] = out1[i];
mac_a_pP[i] = out1[i];
return;
} /* end of function f1 */
......@@ -80,18 +81,28 @@ void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
* confidentiality key CK, integrity key IK and anonymity key AK.
*
*-----------------------------------------------------------------*/
void f2345 ( u8 k[16], u8 rand[16],
u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] )
void f2345 ( u8 k_pP[16], u8 rand_pP[16],
u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6] )
{
u8 op_c[16];
u8 temp[16];
u8 out[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
LOG_TRACE(DEBUG,
"USIM-API - f2345 : in k[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
k_pP[0],k_pP[1],k_pP[2], k_pP[3], k_pP[4], k_pP[5], k_pP[6], k_pP[7],
k_pP[8],k_pP[9],k_pP[10],k_pP[11],k_pP[12],k_pP[13],k_pP[14],k_pP[15]);
LOG_TRACE(DEBUG,
"USIM-API - f2345 : in rand[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
rand_pP[0],rand_pP[1],rand_pP[2], rand_pP[3], rand_pP[4], rand_pP[5], rand_pP[6], rand_pP[7],
rand_pP[8],rand_pP[9],rand_pP[10],rand_pP[11],rand_pP[12],rand_pP[13],rand_pP[14],rand_pP[15]);
RijndaelKeySchedule( k_pP );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = rand[i] ^ op_c[i];
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
/* To obtain output block OUT2: XOR OPc and TEMP, *
* rotate by r2=0, and XOR on the constant c2 (which *
......@@ -103,9 +114,16 @@ void f2345 ( u8 k[16], u8 rand[16],
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<8; i++)
res[i] = out[i+8];
res_pP[i] = out[i+8];
for (i=0; i<6; i++)
ak[i] = out[i];
ak_pP[i] = out[i];
LOG_TRACE(DEBUG,
"USIM-API - f2345 : out f2 res[0..7]=%02X%02X%02X%02X%02X%02X%02X%02X",
res_pP[0],res_pP[1],res_pP[2], res_pP[3], res_pP[4], res_pP[5], res_pP[6], res_pP[7]);
LOG_TRACE(DEBUG,
"USIM-API - f2345 : out f5 ak[0..5]=%02X%02X%02X%02X%02X%02X",
ak_pP[0],ak_pP[1],ak_pP[2], ak_pP[3], ak_pP[4], ak_pP[5]);
/* To obtain output block OUT3: XOR OPc and TEMP, *
* rotate by r3=32, and XOR on the constant c3 (which *
......@@ -117,7 +135,10 @@ void f2345 ( u8 k[16], u8 rand[16],
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<16; i++)
ck[i] = out[i];
ck_pP[i] = out[i];
LOG_TRACE(DEBUG,
"USIM-API - f2345 : out f3 ik_pP[0..7]=%02X%02X%02X%02X%02X%02X%02X%02",
ck_pP[0],ck_pP[1],ck_pP[2], ck_pP[3], ck_pP[4], ck_pP[5], ck_pP[6], ck_pP[7]);
/* 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). */
......@@ -128,7 +149,11 @@ void f2345 ( u8 k[16], u8 rand[16],
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<16; i++)
ik[i] = out[i];
ik_pP[i] = out[i];
LOG_TRACE(DEBUG,
"USIM-API - f2345 : out f4 ik_pP[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
ik_pP[0],ik_pP[1],ik_pP[2], ik_pP[3], ik_pP[4], ik_pP[5], ik_pP[6], ik_pP[7],
ik_pP[8],ik_pP[9],ik_pP[10],ik_pP[11],ik_pP[12],ik_pP[13],ik_pP[14],ik_pP[15]);
return;
} /* end of function f2345 */
......@@ -141,8 +166,8 @@ void f2345 ( u8 k[16], u8 rand[16],
* field AMF.
*
*-----------------------------------------------------------------*/
void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
u8 mac_s[8] )
void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2],
u8 mac_s_pP[8] )
{
u8 op_c[16];
u8 temp[16];
......@@ -150,20 +175,20 @@ void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
u8 out1[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
RijndaelKeySchedule( k_pP );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = rand[i] ^ op_c[i];
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
for (i=0; i<6; i++)
{
in1[i] = sqn[i];
in1[i+8] = sqn[i];
in1[i] = sqn_pP[i];
in1[i+8] = sqn_pP[i];
}
for (i=0; i<2; i++)
{
in1[i+6] = amf[i];
in1[i+14] = amf[i];
in1[i+6] = amf_pP[i];
in1[i+14] = amf_pP[i];
}
/* XOR op_c and in1, rotate by r1=64, and XOR *
* on the constant c1 (which is all zeroes) */
......@@ -176,7 +201,7 @@ void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
for (i=0; i<16; i++)
out1[i] ^= op_c[i];
for (i=0; i<8; i++)
mac_s[i] = out1[i+8];
mac_s_pP[i] = out1[i+8];
return;
} /* end of function f1star */
......@@ -188,18 +213,18 @@ void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
* anonymity key AK.
*
*-----------------------------------------------------------------*/
void f5star( u8 k[16], u8 rand[16],
u8 ak[6] )
void f5star( u8 k_pP[16], u8 rand_pP[16],
u8 ak_pP[6] )
{
u8 op_c[16];
u8 temp[16];
u8 out[16];
u8 rijndaelInput[16];
u8 i;
RijndaelKeySchedule( k );
RijndaelKeySchedule( k_pP );
ComputeOPc( op_c );
for (i=0; i<16; i++)
rijndaelInput[i] = rand[i] ^ op_c[i];
rijndaelInput[i] = rand_pP[i] ^ op_c[i];
RijndaelEncrypt( rijndaelInput, temp );
/* To obtain output block OUT5: XOR OPc and TEMP, *
* rotate by r5=96, and XOR on the constant c5 (which *
......@@ -211,19 +236,23 @@ void f5star( u8 k[16], u8 rand[16],
for (i=0; i<16; i++)
out[i] ^= op_c[i];
for (i=0; i<6; i++)
ak[i] = out[i];
ak_pP[i] = out[i];
return;
} /* end of function f5star */
/*-------------------------------------------------------------------
* Function to compute OPc from OP and K. Assumes key schedule has
already been performed.
*-----------------------------------------------------------------*/
void ComputeOPc( u8 op_c[16] )
void ComputeOPc( u8 op_c_pP[16] )
{
u8 i;
RijndaelEncrypt( OP, op_c );
LOG_TRACE(DEBUG,
"USIM-API - ComputeOPc : OP[0..15]=%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_pP );
for (i=0; i<16; i++)
op_c[i] ^= OP[i];
op_c_pP[i] ^= OP[i];
return;
} /* end of function ComputeOPc */
/*-------------------- Rijndael round subkeys ---------------------*/
......@@ -247,6 +276,7 @@ u8 S[256] = {
225,248,152, 17,105,217,142,148,155, 30,135,233,206, 85, 40,223,
140,161,137, 13,191,230, 66,104, 65,153, 45, 15,176, 84,187, 22,
};
/*------- This array does the multiplication by x in GF(2^8) ------*/
u8 Xtime[256] = {
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
......
......@@ -172,59 +172,76 @@ int usim_api_write(const usim_data_t* data)
** Authentication and key generating function algorithms are **
** specified in 3GPP TS 35.206. **
** **
** Inputs: rand: Random challenge number **
** autn: Authentication token **
** Inputs: rand_pP: Random challenge number **
** autn_pP: Authentication token **
** AUTN = (SQN xor AK) || AMF || MAC **
** 48 16 64 bits **
** Others: Security key **
** **
** Outputs: auts: Re-synchronization token **
** res: Authentication response **
** ck: Ciphering key **
** ik Integrity key **
** Outputs: auts_pP: Re-synchronization token **
** res_pP: Authentication response **
** ck_pP: Ciphering key **
** ik_pP Integrity key **
** **
** Return: RETURNerror, RETURNok **
** Others: None **
** **
***************************************************************************/
int usim_api_authenticate(const OctetString* rand, const OctetString* autn,
OctetString* auts, OctetString* res,
OctetString* ck, OctetString* ik)
int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP,
OctetString* auts_pP, OctetString* res_pP,
OctetString* ck_pP, OctetString* ik_pP)
{
LOG_FUNC_IN;
int rc;
int i;
LOG_TRACE(DEBUG, "USIM-API - rand :");dump_octet_string(rand_pP);
LOG_TRACE(DEBUG, "USIM-API - autn :");dump_octet_string(autn_pP);
/* Compute the authentication response RES = f2K (RAND) */
/* Compute the cipher key CK = f3K (RAND) */
/* Compute the integrity key IK = f4K (RAND) */
/* Compute the anonymity key AK = f5K (RAND) */
#define USIM_API_AK_SIZE 6
u8 ak[USIM_API_AK_SIZE];
f2345(_usim_api_k, rand->value,
res->value, ck->value, ik->value, ak);
f2345(_usim_api_k, rand_pP->value,
res_pP->value, ck_pP->value, ik_pP->value, ak);
LOG_TRACE(DEBUG, "USIM-API - res(f2) :");dump_octet_string(res_pP);
LOG_TRACE(DEBUG, "USIM-API - ck(f3) :");dump_octet_string(ck_pP);
LOG_TRACE(DEBUG, "USIM-API - ik(f4) :");dump_octet_string(ik_pP);
LOG_TRACE(DEBUG, "USIM-API - ak(f5) : %02X%02X%02X%02X%02X%02X",
ak[0],ak[1],ak[2],ak[3],ak[4],ak[5]);
/* Retrieve the sequence number SQN = (SQN ⊕ AK) ⊕ AK */
#define USIM_API_SQN_SIZE USIM_API_AK_SIZE
u8 sqn[USIM_API_SQN_SIZE];
for (i = 0; i < USIM_API_SQN_SIZE; i++) {
sqn[i] = rand->value[i] ^ ak[i];
sqn[i] = autn_pP->value[i] ^ ak[i];
}
LOG_TRACE(DEBUG, "USIM-API - Retrieved SQN %02X%02X%02X%02X%02X%02X",
sqn[0],sqn[1],sqn[2],sqn[3],sqn[4],sqn[5]);
/* Compute XMAC = f1K (SQN || RAND || AMF) */
#define USIM_API_XMAC_SIZE 8
u8 xmac[USIM_API_XMAC_SIZE];
f1(_usim_api_k, rand->value, sqn, &rand->value[USIM_API_SQN_SIZE], xmac);
f1(_usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac);
LOG_TRACE(DEBUG,
"USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X",
xmac[0],xmac[1],xmac[2],xmac[3],
xmac[4],xmac[5],xmac[6],xmac[7]);
/* Compare the XMAC with the MAC included in AUTN */
#if 0 // TODO !!! TO BE REMOVED
#define USIM_API_AMF_SIZE 2
if ( memcmp(xmac, &rand->value[USIM_API_SQN_SIZE + USIM_API_AMF_SIZE],
if ( memcmp(xmac, &autn_pP->value[USIM_API_SQN_SIZE + USIM_API_AMF_SIZE],
USIM_API_XMAC_SIZE) != 0 ) {
LOG_FUNC_RETURN (RETURNerror);
LOG_TRACE(INFO,
"USIM-API - Comparing the XMAC with the MAC included in AUTN Failed");
//LOG_FUNC_RETURN (RETURNerror);
} else {
LOG_TRACE(INFO,
"USIM-API - Comparing the XMAC with the MAC included in AUTN Succeeded");
}
#endif // TODO !!! TO BE REMOVED
/* Verify that the received sequence number SQN is in the correct range */
rc = _usim_api_check_sqn(*(UInt32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]);
......@@ -233,13 +250,14 @@ int usim_api_authenticate(const OctetString* rand, const OctetString* autn,
/* Concealed value of the counter SQNms in the USIM:
* Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */
f5star(_usim_api_k, rand->value, ak);
f5star(_usim_api_k, rand_pP->value, ak);
#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE
u8 sqn_ms[USIM_API_SQNMS_SIZE];
memset(sqn_ms, 0, USIM_API_SQNMS_SIZE);
#define USIM_API_SQN_MS_SIZE 3
for (i = 0; i < USIM_API_SQN_MS_SIZE; i++) {
#warning "LG:BUG HERE TODO"
sqn_ms[USIM_API_SQNMS_SIZE - i] =
((UInt8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQN_MS_SIZE - i];
}
......@@ -248,18 +266,23 @@ int usim_api_authenticate(const OctetString* rand, const OctetString* autn,
for (i = 0; i < USIM_API_SQNMS_SIZE; i++) {
sqnms[i] = sqn_ms[i] ^ ak[i];
}
LOG_TRACE(DEBUG, "USIM-API - SQNms %02X%02X%02X%02X%02X%02X",
sqnms[0],sqnms[1],sqnms[2],sqnms[3],sqnms[4],sqnms[5]);
/* Synchronisation message authentication code:
* MACS = f1*K(SQNMS || RAND || AMF) */
#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE
u8 macs[USIM_API_MACS_SIZE];
f1star(_usim_api_k, rand->value, sqn_ms,
&rand->value[USIM_API_SQN_SIZE], macs);
f1star(_usim_api_k, rand_pP->value, sqn_ms,
&rand_pP->value[USIM_API_SQN_SIZE], macs);
LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X",
macs[0],macs[1],macs[2],macs[3],
macs[4],macs[5],macs[6],macs[7]);
/* Synchronisation authentication token:
* AUTS = Conc(SQNMS) || MACS */
memcpy(&auts->value[0], sqnms, USIM_API_SQNMS_SIZE);
memcpy(&auts->value[USIM_API_SQNMS_SIZE], macs, USIM_API_MACS_SIZE);
memcpy(&auts_pP->value[0], sqnms, USIM_API_SQNMS_SIZE);
memcpy(&auts_pP->value[USIM_API_SQNMS_SIZE], macs, USIM_API_MACS_SIZE);
}
LOG_FUNC_RETURN (RETURNok);
......@@ -332,7 +355,7 @@ static void _usim_api_hex_string_to_hex_value (UInt8_t *hex_value, const char *h
** whether the specified sequence number is in the correct **
** range and acceptabled by the USIM. **
** **
** 3GPP TS 31.102, Annex C.2 **
** 3GPP TS 33.102, Annex C.2 **
** **
** Inputs: seq: Sequence number value **
** ind: Index value **
......
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