/* (C) 2012 by Harald Welte * * 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 . * */ #include #include #include #include #include #include "auc.h" static struct llist_head *auc_buckets; static unsigned int g_nbuckets; int auc_core_init(void *ctx, unsigned int nbuckets) { int i; auc_buckets = talloc_array(ctx, struct llist_head, nbuckets); if (!auc_buckets) return -ENOMEM; g_nbuckets = nbuckets; 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 % g_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); }