summaryrefslogtreecommitdiffstats
path: root/src/gsm/auth_milenage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsm/auth_milenage.c')
-rw-r--r--src/gsm/auth_milenage.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/src/gsm/auth_milenage.c b/src/gsm/auth_milenage.c
index 8d50990b..6dd4f45a 100644
--- a/src/gsm/auth_milenage.c
+++ b/src/gsm/auth_milenage.c
@@ -30,17 +30,37 @@
* @{
*/
+static const uint8_t *gen_opc_if_needed(const struct osmo_sub_auth_data *aud, uint8_t *gen_opc)
+{
+ int rc;
+
+ /* 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 NULL;
+ return gen_opc;
+ } else
+ return aud->u.umts.opc;
+}
+
static int milenage_gen_vec(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data *aud,
const uint8_t *_rand)
{
size_t res_len = sizeof(vec->res);
uint64_t next_sqn;
+ uint8_t gen_opc[16];
+ const uint8_t *opc;
uint8_t sqn[6];
uint64_t ind_mask;
uint64_t seq_1;
int rc;
+ opc = gen_opc_if_needed(aud, gen_opc);
+ if (!opc)
+ return -1;
+
/* Determine next SQN, according to 3GPP TS 33.102:
* SQN consists of SEQ and a lower significant part of IND bits:
*
@@ -106,11 +126,11 @@ static int milenage_gen_vec(struct osmo_auth_vector *vec,
next_sqn = ((aud->u.umts.sqn + seq_1) & ind_mask) + aud->u.umts.ind;
osmo_store64be_ext(next_sqn, sqn, 6);
- milenage_generate(aud->u.umts.opc, aud->u.umts.amf, aud->u.umts.k,
+ milenage_generate(opc, aud->u.umts.amf, aud->u.umts.k,
sqn, _rand,
vec->autn, vec->ik, vec->ck, vec->res, &res_len);
vec->res_len = res_len;
- rc = gsm_milenage(aud->u.umts.opc, aud->u.umts.k, _rand, vec->sres, vec->kc);
+ rc = gsm_milenage(opc, aud->u.umts.k, _rand, vec->sres, vec->kc);
if (rc < 0)
return rc;
@@ -129,18 +149,10 @@ static int milenage_gen_vec_auts(struct osmo_auth_vector *vec,
{
uint8_t sqn_out[6];
uint8_t gen_opc[16];
- uint8_t *opc;
+ const uint8_t *opc;
int rc;
- /* 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;
+ opc = gen_opc_if_needed(aud, gen_opc);
rc = milenage_auts(opc, aud->u.umts.k, rand_auts, auts, sqn_out);
if (rc < 0)