From a72e47b8a09d6a870b093cfa3b5716b6817c33b8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 21 Mar 2012 09:03:16 +0100 Subject: [PATCH] auth_milenage/osmo-auc-gen: compute OPC in case only OP is known --- include/osmocom/crypt/auth.h | 1 + src/gsm/auth_milenage.c | 15 +++++++++++++-- utils/osmo-auc-gen.c | 12 ++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/osmocom/crypt/auth.h b/include/osmocom/crypt/auth.h index 30e16e824..67b320097 100644 --- a/include/osmocom/crypt/auth.h +++ b/include/osmocom/crypt/auth.h @@ -33,6 +33,7 @@ struct osmo_sub_auth_data { uint8_t k[16]; uint8_t amf[2]; uint64_t sqn; + int opc_is_op; } umts; struct { uint8_t ki[16]; diff --git a/src/gsm/auth_milenage.c b/src/gsm/auth_milenage.c index 2a9ba3344..5b2787dda 100644 --- a/src/gsm/auth_milenage.c +++ b/src/gsm/auth_milenage.c @@ -83,10 +83,21 @@ static int milenage_gen_vec_auts(struct osmo_auth_vector *vec, const uint8_t *_rand) { uint8_t sqn_out[6]; + uint8_t gen_opc[16]; + uint8_t *opc; int rc; - rc = milenage_auts(aud->u.umts.opc, aud->u.umts.k, - rand_auts, auts, sqn_out); + /* Check if we only know OP and compute OPC if required */ + if (aud->type == OSMO_AUTH_TYPE_UMTS && aud->u.umts.opc_is_op) { + rc = milenage_opc_gen(gen_opc, aud->u.umts.k, + aud->u.umts.opc); + if (rc < 0) + return rc; + opc = gen_opc; + } else + opc = aud->u.umts.opc; + + rc = milenage_auts(opc, aud->u.umts.k, rand_auts, auts, sqn_out); if (rc < 0) return rc; diff --git a/utils/osmo-auc-gen.c b/utils/osmo-auc-gen.c index 93f126f1e..a3c4dc274 100644 --- a/utils/osmo-auc-gen.c +++ b/utils/osmo-auc-gen.c @@ -59,6 +59,7 @@ static void help() "-a --algorithm\tSpecify name of the algorithm\n" "-k --key\tSpecify Ki / K\n" "-o --opc\tSpecify OPC (only for 3G)\n" + "-O --op\tSpecify OP (only for 3G)\n" "-a --amf\tSpecify AMF (only for 3G)\n" "-s --sqn\tSpecify SQN (only for 3G)\n" "-r --rand\tSpecify random value\n"); @@ -84,6 +85,7 @@ int main(int argc, char **argv) { "algorithm", 1, 0, 'a' }, { "key", 1, 0, 'k' }, { "opc", 1, 0, 'o' }, + { "op", 1, 0, 'O' }, { "amf", 1, 0, 'f' }, { "sqn", 1, 0, 's' }, { "rand", 1, 0, 'r' }, @@ -133,6 +135,16 @@ int main(int argc, char **argv) } rc = osmo_hexparse(optarg, test_aud.u.umts.opc, sizeof(test_aud.u.umts.opc)); + test_aud.u.umts.opc_is_op = 0; + break; + case 'O': + if (test_aud.type != OSMO_AUTH_TYPE_UMTS) { + fprintf(stderr, "Only UMTS has OP\n"); + exit(2); + } + rc = osmo_hexparse(optarg, test_aud.u.umts.opc, + sizeof(test_aud.u.umts.opc)); + test_aud.u.umts.opc_is_op = 1; break; case 'f': if (test_aud.type != OSMO_AUTH_TYPE_UMTS) {