Lines Matching +full:- +full:16 +full:g

2  * HLR/AuC testing gateway for hostapd EAP-SIM/AKA database/authenticator
3 * Copyright (c) 2005-2007, 2012-2017, Jouni Malinen <j@w1.fi>
8 * This is an example implementation of the EAP-SIM/AKA database/authentication
14 * to and external program, e.g., this hlr_auc_gw. This interface uses simple
15 * text-based format:
17 * EAP-SIM / GSM triplet query/response:
18 * SIM-REQ-AUTH <IMSI> <max_chal>
19 * SIM-RESP-AUTH <IMSI> Kc1:SRES1:RAND1 Kc2:SRES2:RAND2 [Kc3:SRES3:RAND3]
20 * SIM-RESP-AUTH <IMSI> FAILURE
21 * GSM-AUTH-REQ <IMSI> RAND1:RAND2[:RAND3]
22 * GSM-AUTH-RESP <IMSI> Kc1:SRES1:Kc2:SRES2[:Kc3:SRES3]
23 * GSM-AUTH-RESP <IMSI> FAILURE
25 * EAP-AKA / UMTS query/response:
26 * AKA-REQ-AUTH <IMSI>
27 * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES>
28 * AKA-RESP-AUTH <IMSI> FAILURE
30 * EAP-AKA / UMTS AUTS (re-synchronization):
31 * AKA-AUTS <IMSI> <AUTS> <RAND>
40 * implementation and for EAP-SIM/AKA/AKA' testing.
42 * For a stronger example design, Milenage and GSM-Milenage algorithms can be
43 * used to dynamically generate authenticatipn information for EAP-AKA/AKA' and
44 * EAP-SIM, respectively, if Ki is known.
46 * SQN generation follows the not time-based Profile 2 described in
63 static int serv_sock = -1;
76 u8 _rand[16];
85 u8 ki[16];
86 u8 opc[16];
97 #define EAP_AKA_RAND_LEN 16
98 #define EAP_AKA_AUTN_LEN 16
101 #define EAP_AKA_RES_MAX_LEN 16
102 #define EAP_AKA_IK_LEN 16
103 #define EAP_AKA_CK_LEN 16
137 return -1; in db_table_create_milenage()
170 m->set = 1; in get_milenage_cb()
174 hexstr2bin(argv[i], m->ki, sizeof(m->ki))) { in get_milenage_cb()
176 return -1; in get_milenage_cb()
180 hexstr2bin(argv[i], m->opc, sizeof(m->opc))) { in get_milenage_cb()
182 return -1; in get_milenage_cb()
186 hexstr2bin(argv[i], m->amf, sizeof(m->amf))) { in get_milenage_cb()
188 return -1; in get_milenage_cb()
192 hexstr2bin(argv[i], m->sqn, sizeof(m->sqn))) { in get_milenage_cb()
194 return -1; in get_milenage_cb()
198 m->res_len = atoi(argv[i]); in get_milenage_cb()
235 pos += wpa_snprintf_hex(pos, sizeof(val), m->sqn, 6); in db_update_milenage_sqn()
239 val, m->imsi); in db_update_milenage_sqn()
242 m->imsi); in db_update_milenage_sqn()
243 return -1; in db_update_milenage_sqn()
259 return -1; in open_socket()
266 perror("hlr-auc-gw: bind(PF_UNIX)"); in open_socket()
268 return -1; in open_socket()
279 struct gsm_triplet *g = NULL; in read_gsm_triplets() local
283 return -1; in read_gsm_triplets()
288 return -1; in read_gsm_triplets()
296 buf[sizeof(buf) - 1] = '\0'; in read_gsm_triplets()
308 g = os_zalloc(sizeof(*g)); in read_gsm_triplets()
309 if (g == NULL) { in read_gsm_triplets()
310 ret = -1; in read_gsm_triplets()
317 if (!pos || os_strlen(pos) >= sizeof(g->imsi)) { in read_gsm_triplets()
318 printf("%s:%d - Invalid IMSI\n", fname, line); in read_gsm_triplets()
319 ret = -1; in read_gsm_triplets()
322 os_strlcpy(g->imsi, pos, sizeof(g->imsi)); in read_gsm_triplets()
326 if (!pos || os_strlen(pos) != 16 || hexstr2bin(pos, g->kc, 8)) { in read_gsm_triplets()
327 printf("%s:%d - Invalid Kc\n", fname, line); in read_gsm_triplets()
328 ret = -1; in read_gsm_triplets()
335 hexstr2bin(pos, g->sres, 4)) { in read_gsm_triplets()
336 printf("%s:%d - Invalid SRES\n", fname, line); in read_gsm_triplets()
337 ret = -1; in read_gsm_triplets()
344 hexstr2bin(pos, g->_rand, 16)) { in read_gsm_triplets()
345 printf("%s:%d - Invalid RAND\n", fname, line); in read_gsm_triplets()
346 ret = -1; in read_gsm_triplets()
350 g->next = gsm_db; in read_gsm_triplets()
351 gsm_db = g; in read_gsm_triplets()
352 g = NULL; in read_gsm_triplets()
354 os_free(g); in read_gsm_triplets()
364 struct gsm_triplet *g = gsm_db_pos; in get_gsm_triplet() local
366 while (g) { in get_gsm_triplet()
367 if (strcmp(g->imsi, imsi) == 0) { in get_gsm_triplet()
368 gsm_db_pos = g->next; in get_gsm_triplet()
369 return g; in get_gsm_triplet()
371 g = g->next; in get_gsm_triplet()
374 g = gsm_db; in get_gsm_triplet()
375 while (g && g != gsm_db_pos) { in get_gsm_triplet()
376 if (strcmp(g->imsi, imsi) == 0) { in get_gsm_triplet()
377 gsm_db_pos = g->next; in get_gsm_triplet()
378 return g; in get_gsm_triplet()
380 g = g->next; in get_gsm_triplet()
395 return -1; in read_milenage()
400 return -1; in read_milenage()
408 buf[sizeof(buf) - 1] = '\0'; in read_milenage()
422 ret = -1; in read_milenage()
429 if (!pos || os_strlen(pos) >= sizeof(m->imsi)) { in read_milenage()
430 printf("%s:%d - Invalid IMSI\n", fname, line); in read_milenage()
431 ret = -1; in read_milenage()
434 os_strlcpy(m->imsi, pos, sizeof(m->imsi)); in read_milenage()
439 hexstr2bin(pos, m->ki, 16)) { in read_milenage()
440 printf("%s:%d - Invalid Ki\n", fname, line); in read_milenage()
441 ret = -1; in read_milenage()
448 hexstr2bin(pos, m->opc, 16)) { in read_milenage()
449 printf("%s:%d - Invalid OPc\n", fname, line); in read_milenage()
450 ret = -1; in read_milenage()
456 if (!pos || os_strlen(pos) != 4 || hexstr2bin(pos, m->amf, 2)) { in read_milenage()
457 printf("%s:%d - Invalid AMF\n", fname, line); in read_milenage()
458 ret = -1; in read_milenage()
465 hexstr2bin(pos, m->sqn, 6)) { in read_milenage()
466 printf("%s:%d - Invalid SEQ\n", fname, line); in read_milenage()
467 ret = -1; in read_milenage()
473 m->res_len = atoi(pos); in read_milenage()
474 if (m->res_len && in read_milenage()
475 (m->res_len < EAP_AKA_RES_MIN_LEN || in read_milenage()
476 m->res_len > EAP_AKA_RES_MAX_LEN)) { in read_milenage()
477 printf("%s:%d - Invalid RES_len\n", in read_milenage()
479 ret = -1; in read_milenage()
484 m->next = milenage_db; in read_milenage()
520 buf[sizeof(buf) - 1] = '\0'; in update_milenage_file()
523 if (buf[0] == '#' || pos == NULL || pos - buf >= 20) in update_milenage_file()
526 imsi_len = pos - buf; in update_milenage_file()
528 for (m = milenage_db; m; m = m->next) { in update_milenage_file()
529 if (strncmp(buf, m->imsi, imsi_len) == 0 && in update_milenage_file()
530 m->imsi[imsi_len] == '\0') in update_milenage_file()
538 pos += snprintf(pos, end - pos, "%s ", m->imsi); in update_milenage_file()
539 pos += wpa_snprintf_hex(pos, end - pos, m->ki, 16); in update_milenage_file()
541 pos += wpa_snprintf_hex(pos, end - pos, m->opc, 16); in update_milenage_file()
543 pos += wpa_snprintf_hex(pos, end - pos, m->amf, 2); in update_milenage_file()
545 pos += wpa_snprintf_hex(pos, end - pos, m->sqn, 6); in update_milenage_file()
575 if (strcmp(m->imsi, imsi) == 0) in get_milenage()
577 m = m->next; in get_milenage()
595 struct gsm_triplet *g; in sim_req_auth() local
610 ret = snprintf(rpos, rend - rpos, "SIM-RESP-AUTH %s", imsi); in sim_req_auth()
611 if (ret < 0 || ret >= rend - rpos) in sim_req_auth()
612 return -1; in sim_req_auth()
617 u8 _rand[16], sres[4], kc[8]; in sim_req_auth()
619 if (random_get_bytes(_rand, 16) < 0) in sim_req_auth()
620 return -1; in sim_req_auth()
621 gsm_milenage(m->opc, m->ki, _rand, sres, kc); in sim_req_auth()
623 rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8); in sim_req_auth()
625 rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4); in sim_req_auth()
627 rpos += wpa_snprintf_hex(rpos, rend - rpos, _rand, 16); in sim_req_auth()
634 while (count < max_chal && (g = get_gsm_triplet(imsi))) { in sim_req_auth()
635 if (strcmp(g->imsi, imsi) != 0) in sim_req_auth()
640 rpos += wpa_snprintf_hex(rpos, rend - rpos, g->kc, 8); in sim_req_auth()
643 rpos += wpa_snprintf_hex(rpos, rend - rpos, g->sres, 4); in sim_req_auth()
646 rpos += wpa_snprintf_hex(rpos, rend - rpos, g->_rand, 16); in sim_req_auth()
652 ret = snprintf(rpos, rend - rpos, " FAILURE"); in sim_req_auth()
653 if (ret < 0 || ret >= rend - rpos) in sim_req_auth()
654 return -1; in sim_req_auth()
672 return -1; in gsm_auth_req()
677 ret = os_snprintf(rpos, rend - rpos, "GSM-AUTH-RESP %s", imsi); in gsm_auth_req()
678 if (os_snprintf_error(rend - rpos, ret)) in gsm_auth_req()
679 return -1; in gsm_auth_req()
684 u8 _rand[16], sres[4], kc[8]; in gsm_auth_req()
686 if (hexstr2bin(pos, _rand, 16) != 0) in gsm_auth_req()
687 return -1; in gsm_auth_req()
688 gsm_milenage(m->opc, m->ki, _rand, sres, kc); in gsm_auth_req()
690 rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8); in gsm_auth_req()
692 rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4); in gsm_auth_req()
693 pos += 16 * 2; in gsm_auth_req()
703 ret = os_snprintf(rpos, rend - rpos, " FAILURE"); in gsm_auth_req()
704 if (os_snprintf_error(rend - rpos, ret)) in gsm_auth_req()
705 return -1; in gsm_auth_req()
719 * The mechanism used here is not time-based, so SEQ2 is void and in inc_sqn()
721 * of SEQ1 is 48 - ind_len bits. in inc_sqn()
725 val = ((u64) WPA_GET_BE32(sqn) << 16) | ((u64) WPA_GET_BE16(sqn + 4)); in inc_sqn()
727 ind = (val + 1) & ((1 << ind_len) - 1); in inc_sqn()
729 WPA_PUT_BE32(sqn, val >> 16); in inc_sqn()
736 /* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> */ in aka_req_auth()
751 return -1; in aka_req_auth()
753 inc_sqn(m->sqn); in aka_req_auth()
760 m->sqn[0], m->sqn[1], m->sqn[2], in aka_req_auth()
761 m->sqn[3], m->sqn[4], m->sqn[5]); in aka_req_auth()
763 milenage_generate(m->opc, m->amf, m->ki, m->sqn, _rand, in aka_req_auth()
765 if (m->res_len >= EAP_AKA_RES_MIN_LEN && in aka_req_auth()
766 m->res_len <= EAP_AKA_RES_MAX_LEN && in aka_req_auth()
767 m->res_len < res_len) in aka_req_auth()
768 res_len = m->res_len; in aka_req_auth()
786 ret = snprintf(pos, end - pos, "AKA-RESP-AUTH %s ", imsi); in aka_req_auth()
787 if (ret < 0 || ret >= end - pos) in aka_req_auth()
788 return -1; in aka_req_auth()
791 ret = snprintf(pos, end - pos, "FAILURE"); in aka_req_auth()
792 if (ret < 0 || ret >= end - pos) in aka_req_auth()
793 return -1; in aka_req_auth()
797 pos += wpa_snprintf_hex(pos, end - pos, _rand, EAP_AKA_RAND_LEN); in aka_req_auth()
799 pos += wpa_snprintf_hex(pos, end - pos, autn, EAP_AKA_AUTN_LEN); in aka_req_auth()
801 pos += wpa_snprintf_hex(pos, end - pos, ik, EAP_AKA_IK_LEN); in aka_req_auth()
803 pos += wpa_snprintf_hex(pos, end - pos, ck, EAP_AKA_CK_LEN); in aka_req_auth()
805 pos += wpa_snprintf_hex(pos, end - pos, res, res_len); in aka_req_auth()
819 /* AKA-AUTS <IMSI> <AUTS> <RAND> */ in aka_auts()
823 return -1; in aka_auts()
828 return -1; in aka_auts()
832 printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", in aka_auts()
838 return -1; in aka_auts()
844 return -1; in aka_auts()
847 if (milenage_auts(m->opc, m->ki, _rand, _auts, sqn)) { in aka_auts()
848 printf("AKA-AUTS: Incorrect MAC-S\n"); in aka_auts()
850 memcpy(m->sqn, sqn, 6); in aka_auts()
852 printf("AKA-AUTS: Re-synchronized: " in aka_auts()
868 if (os_strncmp(cmd, "SIM-REQ-AUTH ", 13) == 0) in process_cmd()
871 if (os_strncmp(cmd, "GSM-AUTH-REQ ", 13) == 0) in process_cmd()
874 if (os_strncmp(cmd, "AKA-REQ-AUTH ", 13) == 0) in process_cmd()
877 if (os_strncmp(cmd, "AKA-AUTS ", 9) == 0) in process_cmd()
881 return -1; in process_cmd()
897 return -1; in process()
904 res = sizeof(buf) - 1; in process()
911 return -1; in process()
931 struct gsm_triplet *g, *gprev; in cleanup() local
937 g = gsm_db; in cleanup()
938 while (g) { in cleanup()
939 gprev = g; in cleanup()
940 g = g->next; in cleanup()
947 m = m->next; in cleanup()
967 printf("Signal %d - terminate\n", sig); in handle_term()
974 printf("HLR/AuC testing gateway for hostapd EAP-SIM/AKA " in usage()
976 "Copyright (c) 2005-2017, Jouni Malinen <j@w1.fi>\n" in usage()
979 "hlr_auc_gw [-hu] [-s<socket path>] [-g<triplet file>] " in usage()
980 "[-m<milenage file>] \\\n" in usage()
981 " [-D<DB file>] [-i<IND len in bits>] [command]\n" in usage()
984 " -h = show this usage help\n" in usage()
985 " -u = update SQN in Milenage file on exit\n" in usage()
986 " -s<socket path> = path for UNIX domain socket\n" in usage()
988 " -g<triplet file> = path for GSM authentication triplets\n" in usage()
989 " -m<milenage file> = path for Milenage keys\n" in usage()
990 " -D<DB file> = path to SQLite database\n" in usage()
991 " -i<IND len in bits> = IND length for SQN (default: 5)\n" in usage()
994 "\"AKA-REQ-AUTH <IMSI>\" is used, a single\n" in usage()
998 "(e.g., by EAP server\n" in usage()
1012 return -1; in main()
1017 c = getopt(argc, argv, "D:g:hi:m:s:u"); in main()
1027 return -1; in main()
1029 case 'g': in main()
1039 return -1; in main()
1053 return -1; in main()
1059 return -1; in main()
1064 return -1; in main()
1068 return -1; in main()
1071 return -1; in main()
1076 return -1; in main()
1092 ret = -1; in main()