summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile11
-rw-r--r--src/auc.h47
-rw-r--r--src/auc_core.c125
-rw-r--r--src/auc_main.c77
-rw-r--r--src/auc_rand.c37
-rw-r--r--src/auc_rec_csv.c226
-rwxr-xr-xsrc/gen_auc_txt.pl10
7 files changed, 533 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..8e5d254
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,11 @@
+LDFLAGS=`pkg-config --libs libosmocore libosmogsm`
+CFLAGS=`pkg-config --cflags libosmocore libosmogsm`
+
+auc: auc_main.o auc_core.o auc_rec_csv.o auc_rand.o
+ $(CC) -o $@ $^ $(LDFLAGS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o $@ -c $^
+
+clean:
+ @rm -f auc *.o
diff --git a/src/auc.h b/src/auc.h
new file mode 100644
index 0000000..ae47ac8
--- /dev/null
+++ b/src/auc.h
@@ -0,0 +1,47 @@
+#ifndef _AUC_INT_H
+#define _AUC_INT_H
+
+/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/crypt/auth.h>
+
+struct auc_rec {
+ struct llist_head list;
+ struct llist_head hash_list;
+ uint8_t imsi[15+1];
+ struct osmo_sub_auth_data auth;
+};
+
+int auc_core_init(void *ctx);
+int auc_add_rec(struct auc_rec *rec);
+int auc_gen_vecs(struct osmo_auth_vector *vec,
+ const char *imsi, int n_vecs);
+int auc_gen_vec_auts(struct osmo_auth_vector *vec,
+ const char *imsi, const uint8_t *rand_auts,
+ const uint8_t *auts);
+
+/* auc_rand.c */
+int auc_rand_init(void);
+int auc_get_rand(uint8_t *rand, unsigned int len);
+
+#endif
+
diff --git a/src/auc_core.c b/src/auc_core.c
new file mode 100644
index 0000000..0fd09f8
--- /dev/null
+++ b/src/auc_core.c
@@ -0,0 +1,125 @@
+/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/crypt/auth.h>
+
+#include "auc.h"
+
+#define NBUCKETS 1024
+static struct llist_head auc_buckets[NBUCKETS];
+
+int auc_core_init(void *ctx)
+{
+ int i;
+
+ for (i = 0; i < NBUCKETS; i++)
+ INIT_LLIST_HEAD(&auc_buckets[i]);
+
+ return 0;
+}
+
+static unsigned int osmo_auc_hashfn(const char *imsi)
+{
+ int len = strlen(imsi);
+ unsigned int res;
+
+ res = atoi(imsi + len - 6);
+
+ return res % NBUCKETS;
+}
+
+int auc_add_rec(struct auc_rec *rec)
+{
+ struct auc_rec *exist;
+ unsigned int hash = osmo_auc_hashfn(rec->imsi);
+ struct llist_head *list = &auc_buckets[hash];
+
+ /* make sure we don't get duplicates */
+ llist_for_each_entry(exist, list, hash_list) {
+ if (!strcmp(exist->imsi, rec->imsi))
+ return -EEXIST;
+ }
+
+ llist_add(&rec->hash_list, list);
+
+ return 0;
+}
+
+struct auc_rec *auc_lookup(const char *imsi)
+{
+ struct auc_rec *exist;
+ unsigned int hash = osmo_auc_hashfn(imsi);
+ struct llist_head *list = &auc_buckets[hash];
+
+ /* make sure we don't get duplicates */
+ llist_for_each_entry(exist, list, hash_list) {
+ if (!strcmp(exist->imsi, imsi))
+ return exist;
+ }
+
+ return NULL;
+}
+
+int auc_gen_vecs(struct osmo_auth_vector *vec,
+ const char *imsi, int n_vecs)
+{
+ struct auc_rec *rec;
+ int i;
+
+ rec = auc_lookup(imsi);
+ if (!rec)
+ return -ENOENT;
+
+ for (i = 0; i < n_vecs; i++) {
+ uint8_t rand[16];
+ int rc;
+
+ rc = auc_get_rand(rand, sizeof(rand));
+ if (rc < 0)
+ return rc;
+ rc = osmo_auth_gen_vec(&vec[i], &rec->auth, rand);
+ if (rc < 0)
+ return rc;
+ }
+
+ return 0;
+}
+
+int auc_gen_vec_auts(struct osmo_auth_vector *vec,
+ const char *imsi, const uint8_t *rand_auts,
+ const uint8_t *auts)
+{
+ struct auc_rec *rec;
+ uint8_t rand[16];
+ int rc;
+
+ rec = auc_lookup(imsi);
+ if (!rec)
+ return -ENOENT;
+
+ rc = auc_get_rand(rand, sizeof(rand));
+ if (rc < 0)
+ return rc;
+
+ return osmo_auth_gen_vec_auts(vec, &rec->auth, rand_auts, auts, rand);
+}
diff --git a/src/auc_main.c b/src/auc_main.c
new file mode 100644
index 0000000..a0b97ac
--- /dev/null
+++ b/src/auc_main.c
@@ -0,0 +1,77 @@
+/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/crypt/auth.h>
+
+void *tall_ctx;
+
+static int auc_test(void)
+{
+ int rc, i, success = 0;
+ char imsi[15+1];
+ struct osmo_auth_vector vecs[3];
+ struct timeval start, end, res;
+ uint64_t usec;
+
+ gettimeofday(&start, NULL);
+ for (i = 0; i < 100000; i++) {
+ snprintf(imsi, 16, "90170%010u", i);
+ rc = auc_gen_vecs(vecs, imsi, 3);
+ if (rc < 0)
+ fprintf(stderr, "IMSI %s: error %d\n", imsi, rc);
+ success++;
+ }
+ gettimeofday(&end, NULL);
+ timersub(&end, &start, &res);
+
+ usec = res.tv_sec * 1000000 + res.tv_usec;
+
+ printf("Generated 3 vectors for each of %u IMSIs in %u usec\n",
+ success, usec);
+ printf("=> %f requests of 3vec / sec\n", success / ((float) usec / 1000000));
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+
+ tall_ctx = talloc_zero_size(NULL, 1);
+
+ rc = auc_core_init(tall_ctx);
+ if (rc < 0)
+ exit(1);
+
+ rc = auc_rand_init();
+ if (rc < 0)
+ exit(1);
+
+ rc = auc_storage_read(tall_ctx, "auc.txt");
+ printf("%u records read from disk\n", rc);
+
+ auc_test();
+
+ exit(0);
+}
diff --git a/src/auc_rand.c b/src/auc_rand.c
new file mode 100644
index 0000000..1a19844
--- /dev/null
+++ b/src/auc_rand.c
@@ -0,0 +1,37 @@
+/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/stat.h>
+
+static int rand_fd = -1;
+int auc_rand_init(void)
+{
+ rand_fd = open("/dev/urandom", O_RDONLY);
+
+ return rand_fd;
+}
+
+int auc_get_rand(uint8_t *rand, unsigned int len)
+{
+ return read(rand_fd, rand, len);
+}
diff --git a/src/auc_rec_csv.c b/src/auc_rec_csv.c
new file mode 100644
index 0000000..21a87a8
--- /dev/null
+++ b/src/auc_rec_csv.c
@@ -0,0 +1,226 @@
+/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+#include "auc.h"
+
+/*
+# imsi,algo,ki,0,0,0,0
+# imsi,algo,k,opc,amf,sqn,opc_is_op
+2620301,1,000102030405060708090a0b0c0d0e0f,0,0,0,0
+2620301,1,000102030405060708090a0b0c0d0e0f,0f0e0d0c0b0a09080706050403020100,0001,32,0
+*/
+
+static struct auc_rec *auc_rec_from_csv(void *ctx,
+ const char *line_orig)
+{
+ char *line = talloc_strdup(ctx, line_orig);
+ char *tok;
+ struct auc_rec *rec;
+
+ if (!line)
+ return NULL;
+
+ rec = talloc_zero(ctx, struct auc_rec);
+ if (!rec) {
+ talloc_free(line);
+ return NULL;
+ }
+
+ /* IMSI */
+ tok = strtok(line, ",");
+ if (!tok)
+ goto ret_free;
+ strncpy(rec->imsi, tok, OSMO_MIN(strlen(tok), sizeof(rec->imsi)));
+ rec->imsi[sizeof(rec->imsi)-1] = '\0';
+
+ /* ALGO */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ rec->auth.algo = atoi(tok);
+ if (rec->auth.algo > _OSMO_AUTH_ALG_NUM)
+ goto ret_free;
+
+ /* K / Ki */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+
+ switch (rec->auth.algo) {
+ case OSMO_AUTH_ALG_NONE:
+
+ break;
+ case OSMO_AUTH_ALG_COMP128v1:
+ case OSMO_AUTH_ALG_COMP128v2:
+ case OSMO_AUTH_ALG_COMP128v3:
+ osmo_hexparse(tok, rec->auth.u.gsm.ki,
+ sizeof(rec->auth.u.gsm.ki));
+ break;
+ case OSMO_AUTH_ALG_XOR:
+ case OSMO_AUTH_ALG_MILENAGE:
+ osmo_hexparse(tok, rec->auth.u.umts.k,
+ sizeof(rec->auth.u.umts.k));
+ /* OPC */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ osmo_hexparse(tok, rec->auth.u.umts.opc,
+ sizeof(rec->auth.u.umts.opc));
+ /* AMF */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ osmo_hexparse(tok, rec->auth.u.umts.amf,
+ sizeof(rec->auth.u.umts.amf));
+ /* SQN */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ rec->auth.u.umts.sqn = strtoull(tok, NULL, 10);
+ /* IS_OP */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ if (tok[0] == '1')
+ rec->auth.u.umts.opc_is_op = 1;
+ break;
+ }
+
+ talloc_free(line);
+
+ return rec;
+
+ret_free:
+ talloc_free(rec);
+ talloc_free(line);
+ return NULL;
+}
+
+static char *auc_rec_to_csv(void *ctx, const struct auc_rec *rec)
+{
+ char *line = talloc_zero_size(ctx, 256);
+ char *cur = line;
+ int i;
+
+ if (!line)
+ return NULL;
+
+ i = sprintf("%s,%u,", rec->imsi, rec->auth.algo);
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ switch (rec->auth.algo) {
+ case OSMO_AUTH_ALG_NONE:
+ break;
+ case OSMO_AUTH_ALG_COMP128v1:
+ case OSMO_AUTH_ALG_COMP128v2:
+ case OSMO_AUTH_ALG_COMP128v3:
+ i = sprintf(cur, "%s,0,0,0,0",
+ osmo_hexdump_nospc(rec->auth.u.gsm.ki,
+ sizeof(rec->auth.u.gsm.ki)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+ break;
+ case OSMO_AUTH_ALG_XOR:
+ case OSMO_AUTH_ALG_MILENAGE:
+ i = sprintf(cur, "%s,",
+ osmo_hexdump_nospc(rec->auth.u.umts.k,
+ sizeof(rec->auth.u.umts.k)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ i = sprintf(cur, "%s,",
+ osmo_hexdump_nospc(rec->auth.u.umts.opc,
+ sizeof(rec->auth.u.umts.opc)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ i = sprintf(cur, "%s,",
+ osmo_hexdump_nospc(rec->auth.u.umts.amf,
+ sizeof(rec->auth.u.umts.amf)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ i = sprintf(cur, "%llu,%u", rec->auth.u.umts.sqn,
+ rec->auth.u.umts.opc_is_op);
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+ break;
+ }
+
+ return line;
+
+ret_free:
+ talloc_free(line);
+ return NULL;
+}
+
+int auc_storage_read(void *ctx, const char *fname)
+{
+ FILE *file = fopen(fname, "r");
+ char *line = talloc_zero_size(ctx, 256);
+ int rc, num = 0;
+
+ while ((line = fgets(line, 256, file))) {
+ struct auc_rec *rec;
+
+ if (line[0] == '#')
+ continue;
+
+ rec = auc_rec_from_csv(ctx, line);
+ if (!rec)
+ continue;
+
+ rc = auc_add_rec(rec);
+ if (rc == 0)
+ num++;
+ }
+
+ return num;
+}
+
+static int auc_rec_dump(void *priv, void *ctx,
+ const struct auc_rec *rec)
+{
+ FILE *file = priv;
+ char *line;
+ int rc;
+
+ line = auc_rec_to_csv(ctx, rec);
+ if (!line)
+ return -EIO;
+
+ rc = fputs(line, file);
+
+ talloc_free(line);
+
+ return rc;
+}
diff --git a/src/gen_auc_txt.pl b/src/gen_auc_txt.pl
new file mode 100755
index 0000000..504c771
--- /dev/null
+++ b/src/gen_auc_txt.pl
@@ -0,0 +1,10 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $COUNT = $ARGV[0];
+my $i;
+
+for ($i = 0; $i < $COUNT; $i++) {
+ printf("90170%010u,5,%032u,%032u,0000,%u,0\n", $i, $i, $i, $i);
+}