hlr_auc_gw: Use 5 bit IND for SQN updates
Change the SQN generation mechanism to use not time-based Profile 2 as described in 3GPP TS 33.102 Annex C.3.2. The previous implementation used void IND (i.e.., all of SQN was SEQ1). The new default uses 5 bits of SQN as IND. The length of IND can be configured on the command line with the new -i<IND len in bits> parameter. -i0 would make hlr_auc_gw behave in the same way as the previous implementation. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
5336861301
commit
5daba48ca7
1 changed files with 41 additions and 5 deletions
|
@ -34,7 +34,11 @@
|
|||
* text file in IMSI:Kc:SRES:RAND format, IMSI in ASCII, other fields as hex
|
||||
* strings. This is used to simulate an HLR/AuC. As such, it is not very useful
|
||||
* for real life authentication, but it is useful both as an example
|
||||
* implementation and for EAP-SIM testing.
|
||||
* implementation and for EAP-SIM/AKA/AKA' testing.
|
||||
*
|
||||
* SQN generation follows the not time-based Profile 2 described in
|
||||
* 3GPP TS 33.102 Annex C.3.2. The length of IND is 5 bits by default, but this
|
||||
* can be changed with a command line options if needed.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
@ -50,6 +54,7 @@ static int serv_sock = -1;
|
|||
static char *milenage_file = NULL;
|
||||
static int update_milenage = 0;
|
||||
static int sqn_changes = 0;
|
||||
static int ind_len = 5;
|
||||
|
||||
/* GSM triplets */
|
||||
struct gsm_triplet {
|
||||
|
@ -537,6 +542,28 @@ send:
|
|||
}
|
||||
|
||||
|
||||
static void inc_sqn(u8 *sqn)
|
||||
{
|
||||
u64 val, seq, ind;
|
||||
|
||||
/*
|
||||
* SQN = SEQ | IND = SEQ1 | SEQ2 | IND
|
||||
*
|
||||
* The mechanism used here is not time-based, so SEQ2 is void and
|
||||
* SQN = SEQ1 | IND. The length of IND is ind_len bits and the length
|
||||
* of SEQ1 is 48 - ind_len bits.
|
||||
*/
|
||||
|
||||
/* Increment both SEQ and IND by one */
|
||||
val = ((u64) WPA_GET_BE32(sqn) << 16) | ((u64) WPA_GET_BE16(sqn + 4));
|
||||
seq = (val >> ind_len) + 1;
|
||||
ind = (val + 1) & ((1 << ind_len) - 1);
|
||||
val = (seq << ind_len) | ind;
|
||||
WPA_PUT_BE32(sqn, val >> 16);
|
||||
WPA_PUT_BE16(sqn + 4, val & 0xffff);
|
||||
}
|
||||
|
||||
|
||||
static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
|
||||
char *imsi)
|
||||
{
|
||||
|
@ -556,7 +583,7 @@ static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
|
|||
if (random_get_bytes(_rand, EAP_AKA_RAND_LEN) < 0)
|
||||
return;
|
||||
res_len = EAP_AKA_RES_MAX_LEN;
|
||||
inc_byte_array(m->sqn, 6);
|
||||
inc_sqn(m->sqn);
|
||||
sqn_changes = 1;
|
||||
printf("AKA: Milenage with SQN=%02x%02x%02x%02x%02x%02x\n",
|
||||
m->sqn[0], m->sqn[1], m->sqn[2],
|
||||
|
@ -725,7 +752,8 @@ static void usage(void)
|
|||
"\n"
|
||||
"usage:\n"
|
||||
"hlr_auc_gw [-hu] [-s<socket path>] [-g<triplet file>] "
|
||||
"[-m<milenage file>]\n"
|
||||
"[-m<milenage file>] \\\n"
|
||||
" [-i<IND len in bits>]\n"
|
||||
"\n"
|
||||
"options:\n"
|
||||
" -h = show this usage help\n"
|
||||
|
@ -733,7 +761,8 @@ static void usage(void)
|
|||
" -s<socket path> = path for UNIX domain socket\n"
|
||||
" (default: %s)\n"
|
||||
" -g<triplet file> = path for GSM authentication triplets\n"
|
||||
" -m<milenage file> = path for Milenage keys\n",
|
||||
" -m<milenage file> = path for Milenage keys\n"
|
||||
" -i<IND len in bits> = IND length for SQN (default: 5)\n",
|
||||
default_socket_path);
|
||||
}
|
||||
|
||||
|
@ -749,7 +778,7 @@ int main(int argc, char *argv[])
|
|||
socket_path = default_socket_path;
|
||||
|
||||
for (;;) {
|
||||
c = getopt(argc, argv, "g:hm:s:u");
|
||||
c = getopt(argc, argv, "g:hi:m:s:u");
|
||||
if (c < 0)
|
||||
break;
|
||||
switch (c) {
|
||||
|
@ -759,6 +788,13 @@ int main(int argc, char *argv[])
|
|||
case 'h':
|
||||
usage();
|
||||
return 0;
|
||||
case 'i':
|
||||
ind_len = atoi(optarg);
|
||||
if (ind_len < 0 || ind_len > 32) {
|
||||
printf("Invalid IND length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
milenage_file = optarg;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue