blob: 62b5128987856983a4f65fb5544a914a56590de5 [file] [log] [blame]
Harald Welte915e0ef2011-12-07 02:38:42 +01001/* GSM/GPRS/3G authentication testing tool */
2
3/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
4 *
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>
29
30#include <osmocom/crypt/auth.h>
31#include <osmocom/core/utils.h>
32
33static void dump_auth_vec(struct osmo_auth_vector *vec)
34{
35 printf("RAND:\t%s\n", osmo_hexdump(vec->rand, sizeof(vec->rand)));
36
37 if (vec->auth_types & OSMO_AUTH_TYPE_UMTS) {
38 printf("AUTN:\t%s\n", osmo_hexdump(vec->autn, sizeof(vec->autn)));
39 printf("IK:\t%s\n", osmo_hexdump(vec->ik, sizeof(vec->ik)));
40 printf("CK:\t%s\n", osmo_hexdump(vec->ck, sizeof(vec->ck)));
41 printf("RES:\t%s\n", osmo_hexdump(vec->res, vec->res_len));
42 }
43
44 if (vec->auth_types & OSMO_AUTH_TYPE_GSM) {
45 printf("SRES:\t%s\n", osmo_hexdump(vec->sres, sizeof(vec->sres)));
46 printf("Kc:\t%s\n", osmo_hexdump(vec->kc, sizeof(vec->kc)));
47 }
48}
49
50static struct osmo_sub_auth_data test_aud = {
51 .type = OSMO_AUTH_TYPE_NONE,
52 .algo = OSMO_AUTH_ALG_NONE,
53};
54
55int main(int argc, char **argv)
56{
57 struct osmo_auth_vector _vec;
58 struct osmo_auth_vector *vec = &_vec;
59 uint8_t _rand[16];
60 int rc, option_index;
61 int rand_is_set = 0;
62
63 printf("osmo-auc-gen (C) 2011 by Harald Welte\n");
64 printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");
65
66 while (1) {
67 int c;
68 unsigned long ul;
69 static struct option long_options[] = {
70 { "2g", 0, 0, '2' },
71 { "3g", 0, 0, '3' },
72 { "algorithm", 1, 0, 'a' },
73 { "key", 1, 0, 'k' },
74 { "opc", 1, 0, 'o' },
75 { "amf", 1, 0, 'f' },
76 { "sqn", 1, 0, 's' },
77 { "rand", 1, 0, 'r' },
78 { 0, 0, 0, 0 }
79 };
80
81 rc = 0;
82
83 c = getopt_long(argc, argv, "23a:k:o:f:s:r:", long_options,
84 &option_index);
85
86 if (c == -1)
87 break;
88
89 switch (c) {
90 case '2':
91 test_aud.type = OSMO_AUTH_TYPE_GSM;
92 break;
93 case '3':
94 test_aud.type = OSMO_AUTH_TYPE_UMTS;
95 break;
96 case 'a':
97 rc = osmo_auth_alg_parse(optarg);
98 if (rc < 0)
99 break;
100 test_aud.algo = rc;
101 break;
102 case 'k':
103 switch (test_aud.type) {
104 case OSMO_AUTH_TYPE_GSM:
Harald Welteaae23622011-12-07 11:35:02 +0100105 rc = osmo_hexparse(optarg, test_aud.u.gsm.ki,
106 sizeof(test_aud.u.gsm.ki));
Harald Welte915e0ef2011-12-07 02:38:42 +0100107 break;
108 case OSMO_AUTH_TYPE_UMTS:
Harald Welteaae23622011-12-07 11:35:02 +0100109 rc = osmo_hexparse(optarg, test_aud.u.umts.k,
110 sizeof(test_aud.u.umts.k));
Harald Welte915e0ef2011-12-07 02:38:42 +0100111 break;
112 default:
113 fprintf(stderr, "please specify 2g/3g first!\n");
114 }
115 break;
116 case 'o':
117 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
118 fprintf(stderr, "Only UMTS has OPC\n");
119 exit(2);
120 }
Harald Welteaae23622011-12-07 11:35:02 +0100121 rc = osmo_hexparse(optarg, test_aud.u.umts.opc,
122 sizeof(test_aud.u.umts.opc));
Harald Welte915e0ef2011-12-07 02:38:42 +0100123 break;
124 case 'f':
125 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
126 fprintf(stderr, "Only UMTS has AMF\n");
127 exit(2);
128 }
Harald Welteaae23622011-12-07 11:35:02 +0100129 rc = osmo_hexparse(optarg, test_aud.u.umts.amf,
130 sizeof(test_aud.u.umts.amf));
Harald Welte915e0ef2011-12-07 02:38:42 +0100131 break;
132 case 's':
133 if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {
134 fprintf(stderr, "Only UMTS has SQN\n");
135 exit(2);
136 }
137 ul = strtoul(optarg, 0, 10);
Harald Welteaae23622011-12-07 11:35:02 +0100138 test_aud.u.umts.sqn = ul;
Harald Welte915e0ef2011-12-07 02:38:42 +0100139 break;
140 case 'r':
141 rc = osmo_hexparse(optarg, _rand, sizeof(_rand));
142 rand_is_set = 1;
143 break;
144 }
145
146 if (rc < 0) {
147 fprintf(stderr, "Error parsing argument of option `%c'\n", c);
148 exit(2);
149 }
150 }
151
152 if (!rand_is_set) {
153 printf("WARNING: We're using really weak random numbers!\n\n");
154 srand(time(NULL));
155 *(uint32_t *)&_rand[0] = rand();
156 *(uint32_t *)(&_rand[4]) = rand();
157 *(uint32_t *)(&_rand[8]) = rand();
158 *(uint32_t *)(&_rand[12]) = rand();
159 }
160
161 memset(vec, 0, sizeof(*vec));
162
163 rc = osmo_auth_gen_vec(vec, &test_aud, _rand);
164 if (rc < 0) {
165 fprintf(stderr, "error generating auth vector\n");
166 exit(1);
167 }
168
169 dump_auth_vec(vec);
170#if 0
171 const uint8_t auts[14] = { 0x87, 0x11, 0xa0, 0xec, 0x9e, 0x16, 0x37, 0xdf,
172 0x17, 0xf8, 0x0b, 0x38, 0x4e, 0xe4 };
173
174 rc = osmo_auth_gen_vec_auts(vec, &test_aud, auts, _rand, _rand);
175 if (rc < 0) {
176 printf("AUTS failed\n");
177 } else {
Harald Welteaae23622011-12-07 11:35:02 +0100178 printf("AUTS success: SEQ.MS = %lu\n", test_aud.u.umts.sqn);
Harald Welte915e0ef2011-12-07 02:38:42 +0100179 }
180#endif
181 exit(0);
182
183}