blob: ee349ae64c51de76a80c0983c984a8b990a94611 [file] [log] [blame]
Harald Welte915e0ef2011-12-07 02:38:42 +01001/* GSM/GPRS/3G authentication testing tool */
2
Harald Weltebc6f56c2012-03-21 17:37:53 +01003/* (C) 2010-2012 by Harald Welte <laforge@gnumonks.org>
Harald Welte915e0ef2011-12-07 02:38:42 +01004 *
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <errno.h>
27#include <string.h>
28#include <getopt.h>
Harald Welteb53717f2012-08-02 08:42:59 +020029#include <unistd.h>
Holger Hans Peter Freythera652abc2013-07-14 09:11:47 +020030#include <inttypes.h>
31#include <time.h>
Harald Welte915e0ef2011-12-07 02:38:42 +010032
33#include <osmocom/crypt/auth.h>
34#include <osmocom/core/utils.h>
35
Harald Welte57799ed2012-06-27 15:06:19 +020036static void dump_triplets_dat(struct osmo_auth_vector *vec)
37{
38 if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) {
39 fprintf(stderr, "triplets.dat doesn't support UMTS!\n");
40 return;
41 }
42 printf("imsi,");
43 printf("%s,", osmo_hexdump_nospc(vec->rand, sizeof(vec->rand)));
44 printf("%s,", osmo_hexdump_nospc(vec->sres, sizeof(vec->sres)));
45 printf("%s\n", osmo_hexdump_nospc(vec->kc, sizeof(vec->kc)));
46}
47
Harald Welte915e0ef2011-12-07 02:38:42 +010048static void dump_auth_vec(struct osmo_auth_vector *vec)
49{
50 printf("RAND:\t%s\n", osmo_hexdump(vec->rand, sizeof(vec->rand)));
51
52 if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) {
53 printf("AUTN:\t%s\n", osmo_hexdump(vec->autn, sizeof(vec->autn)));
54 printf("IK:\t%s\n", osmo_hexdump(vec->ik, sizeof(vec->ik)));
55 printf("CK:\t%s\n", osmo_hexdump(vec->ck, sizeof(vec->ck)));
56 printf("RES:\t%s\n", osmo_hexdump(vec->res, vec->res_len));
57 }
58
59 if (vec->auth_types & OSMO_AUTH_TYPE_GSM) {
60 printf("SRES:\t%s\n", osmo_hexdump(vec->sres, sizeof(vec->sres)));
61 printf("Kc:\t%s\n", osmo_hexdump(vec->kc, sizeof(vec->kc)));
62 }
63}
64
65static struct osmo_sub_auth_data test_aud = {
66 .type = OSMO_AUTH_TYPE_NONE,
67 .algo = OSMO_AUTH_ALG_NONE,
68};
69
Harald Welte5fb795e2012-03-21 08:51:48 +010070static void help()
71{
72 printf( "-2 --2g\tUse 2G (GSM) authentication\n"
73 "-3 --3g\tUse 3G (UMTS) authentication\n"
74 "-a --algorithm\tSpecify name of the algorithm\n"
75 "-k --key\tSpecify Ki / K\n"
76 "-o --opc\tSpecify OPC (only for 3G)\n"
Harald Weltea72e47b2012-03-21 09:03:16 +010077 "-O --op\tSpecify OP (only for 3G)\n"
Harald Welte5fb795e2012-03-21 08:51:48 +010078 "-a --amf\tSpecify AMF (only for 3G)\n"
79 "-s --sqn\tSpecify SQN (only for 3G)\n"
Harald Weltecebf3f02012-03-22 16:45:23 +010080 "-A --auts\tSpecify AUTS (only for 3G)\n"
Harald Welte57799ed2012-06-27 15:06:19 +020081 "-r --rand\tSpecify random value\n"
82 "-I --ipsec\tOutput in triplets.dat format for strongswan\n");
Harald Welte5fb795e2012-03-21 08:51:48 +010083}
84
Harald Welte915e0ef2011-12-07 02:38:42 +010085int main(int argc, char **argv)
86{
87 struct osmo_auth_vector _vec;
88 struct osmo_auth_vector *vec = &_vec;
Harald Weltecebf3f02012-03-22 16:45:23 +010089 uint8_t _rand[16], _auts[16];
Harald Welte915e0ef2011-12-07 02:38:42 +010090 int rc, option_index;
91 int rand_is_set = 0;
Harald Weltecebf3f02012-03-22 16:45:23 +010092 int auts_is_set = 0;
Harald Welte57799ed2012-06-27 15:06:19 +020093 int fmt_triplets_dat = 0;
Harald Welte915e0ef2011-12-07 02:38:42 +010094
Harald Weltebc6f56c2012-03-21 17:37:53 +010095 printf("osmo-auc-gen (C) 2011-2012 by Harald Welte\n");
Harald Welte915e0ef2011-12-07 02:38:42 +010096 printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");
97
Harald Weltecebf3f02012-03-22 16:45:23 +010098 memset(_auts, 0, sizeof(_auts));
99
Harald Welte915e0ef2011-12-07 02:38:42 +0100100 while (1) {
101 int c;
102 unsigned long ul;
103 static struct option long_options[] = {
104 { "2g", 0, 0, '2' },
105 { "3g", 0, 0, '3' },
106 { "algorithm", 1, 0, 'a' },
107 { "key", 1, 0, 'k' },
108 { "opc", 1, 0, 'o' },
Harald Weltea72e47b2012-03-21 09:03:16 +0100109 { "op", 1, 0, 'O' },
Harald Welte915e0ef2011-12-07 02:38:42 +0100110 { "amf", 1, 0, 'f' },
111 { "sqn", 1, 0, 's' },
112 { "rand", 1, 0, 'r' },
Harald Weltecebf3f02012-03-22 16:45:23 +0100113 { "auts", 1, 0, 'A' },
Harald Welte5fb795e2012-03-21 08:51:48 +0100114 { "help", 0, 0, 'h' },
Harald Welte915e0ef2011-12-07 02:38:42 +0100115 { 0, 0, 0, 0 }
116 };
117
118 rc = 0;
119
Harald Welte57799ed2012-06-27 15:06:19 +0200120 c = getopt_long(argc, argv, "23a:k:o:f:s:r:hO:A:I", long_options,
Harald Welte915e0ef2011-12-07 02:38:42 +0100121 &option_index);
122
123 if (c == -1)
124 break;
125
126 switch (c) {
127 case '2':
128 test_aud.type = OSMO_AUTH_TYPE_GSM;
129 break;
130 case '3':
131 test_aud.type = OSMO_AUTH_TYPE_UMTS;
132 break;
133 case 'a':
134 rc = osmo_auth_alg_parse(optarg);
135 if (rc < 0)
136 break;
137 test_aud.algo = rc;
138 break;
139 case 'k':
140 switch (test_aud.type) {
141 case OSMO_AUTH_TYPE_GSM:
Harald Welteaae23622011-12-07 11:35:02 +0100142 rc = osmo_hexparse(optarg, test_aud.u.gsm.ki,
143 sizeof(test_aud.u.gsm.ki));
Harald Welte915e0ef2011-12-07 02:38:42 +0100144 break;
145 case OSMO_AUTH_TYPE_UMTS:
Harald Welteaae23622011-12-07 11:35:02 +0100146 rc = osmo_hexparse(optarg, test_aud.u.umts.k,
147 sizeof(test_aud.u.umts.k));
Harald Welte915e0ef2011-12-07 02:38:42 +0100148 break;
149 default:
150 fprintf(stderr, "please specify 2g/3g first!\n");
151 }
152 break;
153 case 'o':
154 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
155 fprintf(stderr, "Only UMTS has OPC\n");
156 exit(2);
157 }
Harald Welteaae23622011-12-07 11:35:02 +0100158 rc = osmo_hexparse(optarg, test_aud.u.umts.opc,
159 sizeof(test_aud.u.umts.opc));
Harald Weltea72e47b2012-03-21 09:03:16 +0100160 test_aud.u.umts.opc_is_op = 0;
161 break;
162 case 'O':
163 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
164 fprintf(stderr, "Only UMTS has OP\n");
165 exit(2);
166 }
167 rc = osmo_hexparse(optarg, test_aud.u.umts.opc,
168 sizeof(test_aud.u.umts.opc));
169 test_aud.u.umts.opc_is_op = 1;
Harald Welte915e0ef2011-12-07 02:38:42 +0100170 break;
Harald Weltecebf3f02012-03-22 16:45:23 +0100171 case 'A':
172 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
173 fprintf(stderr, "Only UMTS has AUTS\n");
174 exit(2);
175 }
176 rc = osmo_hexparse(optarg, _auts, sizeof(_auts));
177 auts_is_set = 1;
178 break;
Harald Welte915e0ef2011-12-07 02:38:42 +0100179 case 'f':
180 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
181 fprintf(stderr, "Only UMTS has AMF\n");
182 exit(2);
183 }
Harald Welteaae23622011-12-07 11:35:02 +0100184 rc = osmo_hexparse(optarg, test_aud.u.umts.amf,
185 sizeof(test_aud.u.umts.amf));
Harald Welte915e0ef2011-12-07 02:38:42 +0100186 break;
187 case 's':
188 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
189 fprintf(stderr, "Only UMTS has SQN\n");
190 exit(2);
191 }
192 ul = strtoul(optarg, 0, 10);
Harald Welteaae23622011-12-07 11:35:02 +0100193 test_aud.u.umts.sqn = ul;
Harald Welte915e0ef2011-12-07 02:38:42 +0100194 break;
195 case 'r':
196 rc = osmo_hexparse(optarg, _rand, sizeof(_rand));
197 rand_is_set = 1;
198 break;
Harald Welte57799ed2012-06-27 15:06:19 +0200199 case 'I':
200 fmt_triplets_dat = 1;
201 break;
Harald Welte5fb795e2012-03-21 08:51:48 +0100202 case 'h':
203 help();
204 exit(0);
205 default:
206 help();
207 exit(1);
Harald Welte915e0ef2011-12-07 02:38:42 +0100208 }
209
210 if (rc < 0) {
211 fprintf(stderr, "Error parsing argument of option `%c'\n", c);
212 exit(2);
213 }
214 }
215
216 if (!rand_is_set) {
217 printf("WARNING: We're using really weak random numbers!\n\n");
218 srand(time(NULL));
219 *(uint32_t *)&_rand[0] = rand();
220 *(uint32_t *)(&_rand[4]) = rand();
221 *(uint32_t *)(&_rand[8]) = rand();
222 *(uint32_t *)(&_rand[12]) = rand();
223 }
224
Harald Welte5fb795e2012-03-21 08:51:48 +0100225 if (test_aud.type == OSMO_AUTH_TYPE_NONE ||
226 test_aud.algo == OSMO_AUTH_ALG_NONE) {
227 help();
228 exit(2);
229 }
230
Harald Welte915e0ef2011-12-07 02:38:42 +0100231 memset(vec, 0, sizeof(*vec));
232
Harald Weltecebf3f02012-03-22 16:45:23 +0100233 if (!auts_is_set)
234 rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
235 else
236 rc = osmo_auth_gen_vec_auts(vec, &test_aud, _auts, _rand, _rand);
Harald Welte915e0ef2011-12-07 02:38:42 +0100237 if (rc < 0) {
Harald Weltecebf3f02012-03-22 16:45:23 +0100238 if (!auts_is_set)
239 fprintf(stderr, "error generating auth vector\n");
240 else
241 fprintf(stderr, "AUTS from MS seems incorrect\n");
Harald Welte915e0ef2011-12-07 02:38:42 +0100242 exit(1);
243 }
244
Harald Welte57799ed2012-06-27 15:06:19 +0200245 if (fmt_triplets_dat)
246 dump_triplets_dat(vec);
247 else
248 dump_auth_vec(vec);
Harald Welte915e0ef2011-12-07 02:38:42 +0100249
Harald Weltecebf3f02012-03-22 16:45:23 +0100250 if (auts_is_set)
Holger Hans Peter Freythera652abc2013-07-14 09:11:47 +0200251 printf("AUTS success: SEQ.MS = %" PRIu64 "\n", test_aud.u.umts.sqn);
Harald Welte915e0ef2011-12-07 02:38:42 +0100252
Harald Weltecebf3f02012-03-22 16:45:23 +0100253 exit(0);
Harald Welte915e0ef2011-12-07 02:38:42 +0100254}