2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 typedef struct triplet_t triplet_t
;
32 unsigned char imsi
[IMSI_LEN
];
33 unsigned char rand
[RAND_LEN
];
34 unsigned char sres
[SRES_LEN
];
35 unsigned char kc
[KC_LEN
];
38 static triplet_t
*triplets
= NULL
;
39 static int triplet_count
= 0;
41 #define TRIPLET_FILE IPSEC_CONFDIR "/ipsec.d/triplets.dat"
44 * convert a single HEX char to its integer value
46 static int hexchr(char chr
)
53 return 10 + chr
- 'A';
55 return 10 + chr
- 'a';
61 * convert a HEX string into a char array bin, limited by array length len
63 static void hex2bin(char *hex
, unsigned char *bin
, size_t len
)
69 /* find the end, as we convert bottom up */
82 /* convert two hex chars into a single bin byte */
83 for (i
= 0; pos
>= hex
&& i
< len
; pos
--)
87 bin
[len
- 1 - i
] = hexchr(*pos
);
91 bin
[len
- 1 - i
] |= 16 * hexchr(*pos
);
99 * free up allocated triplets
101 static void __attribute__ ((destructor
)) free_triplets()
107 * read the triplets from the file, using freeradius triplet file syntax:
108 * http://www.freeradius.org/radiusd/doc/rlm_sim_triplets
110 static void __attribute__ ((constructor
)) read_triplets()
112 char line
[512], *data
[4], *pos
;
117 file
= fopen(TRIPLET_FILE
, "r");
120 DBG1(DBG_CFG
, "opening triplet file %s failed: %s",
121 TRIPLET_FILE
, strerror(errno
));
132 /* read line by line */
133 while (fgets(line
, sizeof(line
), file
))
136 /* skip comments, empty lines */
147 /* read comma separated values */
149 for (i
= 0; i
< 4; i
++)
152 pos
= strchr(pos
, ',');
160 DBG1(DBG_CFG
, "error in triplet file, line %d", nr
);
165 /* allocate new triplet */
167 triplets
= realloc(triplets
, triplet_count
* sizeof(triplet_t
));
168 triplet
= &triplets
[triplet_count
- 1];
169 memset(triplet
, 0, sizeof(triplet_t
));
171 /* convert/copy triplet data */
172 for (i
= 0; i
< IMSI_LEN
- 1; i
++)
181 triplet
->imsi
[i
] = data
[0][i
];
186 hex2bin(data
[1], triplet
->rand
, RAND_LEN
);
187 hex2bin(data
[2], triplet
->sres
, SRES_LEN
);
188 hex2bin(data
[3], triplet
->kc
, KC_LEN
);
190 DBG4(DBG_CFG
, "triplet: imsi %b\nrand %b\nsres %b\nkc %b",
191 triplet
->imsi
, IMSI_LEN
, triplet
->rand
, RAND_LEN
,
192 triplet
->sres
, SRES_LEN
, triplet
->kc
, KC_LEN
);
195 DBG2(DBG_CFG
, "read %d triplets from %s", triplet_count
, TRIPLET_FILE
);
199 * Run the sim algorithm, see eap_sim.h
201 int sim_run_alg(const unsigned char *rand
, int rand_length
,
202 unsigned char *sres
, int *sres_length
,
203 unsigned char *kc
, int *kc_length
)
207 if (rand_length
!= RAND_LEN
||
208 *sres_length
< SRES_LEN
||
214 for (current
= 0; current
< triplet_count
; current
++)
216 if (memcmp(triplets
[current
].rand
, rand
, RAND_LEN
) == 0)
218 memcpy(sres
, triplets
[current
].sres
, SRES_LEN
);
219 memcpy(kc
, triplets
[current
].kc
, KC_LEN
);
220 *sres_length
= SRES_LEN
;
229 * Get a single triplet, see_eap_sim.h
231 int sim_get_triplet(char *imsi
,
232 unsigned char *rand
, int *rand_length
,
233 unsigned char *sres
, int *sres_length
,
234 unsigned char *kc
, int *kc_length
)
238 static int skip
= -1;
240 DBG2(DBG_CFG
, "getting triplet for %s", imsi
);
242 if (*rand_length
< RAND_LEN
||
243 *sres_length
< SRES_LEN
||
248 if (triplet_count
== 0)
252 for (current
= 0; current
< triplet_count
; current
++)
254 triplet
= &triplets
[current
];
256 if (streq(imsi
, triplet
->imsi
))
258 /* skip triplet if already used */
263 *rand_length
= RAND_LEN
;
264 *sres_length
= SRES_LEN
;
266 memcpy(rand
, triplet
->rand
, RAND_LEN
);
267 memcpy(sres
, triplet
->sres
, SRES_LEN
);
268 memcpy(kc
, triplet
->kc
, KC_LEN
);
269 /* remember used triplet */
276 /* no triplet left, reuse triplets */
278 return sim_get_triplet(imsi
, rand
, rand_length
,
279 sres
, sres_length
, kc
, kc_length
);