Start to use struct osmo_auth_vector from gsm_auth_tuple

Rather than having a 'private' structure for kc, sres and rand, we
now finally (with 4 years delay) use osmo_auth_vector from libosmogsm,
which encapsulates authentication vectors that can be either GSM
triplets or UMTS quintuples or a combination of both.

gsm_auth_tuple becomes a wrapper around osmo_auth_vector, adding
use_count and key_seq to it.

key_seq is no longer initialized inside gprs_gsup_messages.c, as there
is no CKSN / key_seq inside the message anyway.  If a usre of the code
needs key_seq, they need to manage it themselves.
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 5f0a5fd..6b6e741 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -512,9 +512,9 @@
 
 	at = &ctx->auth_triplet;
 
-	if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->sres) ||
-	    memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->sres,
-		   sizeof(at->sres)) != 0) {
+	if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->vec.sres) ||
+	    memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->vec.sres,
+		   sizeof(at->vec.sres)) != 0) {
 
 		LOGMMCTXP(LOGL_NOTICE, ctx, "Received SRES doesn't match\n");
 		rc = gsm48_tx_gmm_auth_ciph_rej(ctx);
@@ -637,7 +637,8 @@
 		struct gsm_auth_tuple *at = &ctx->auth_triplet;
 
 		mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360);
-		return gsm48_tx_gmm_auth_ciph_req(ctx, at->rand, at->key_seq,
+		return gsm48_tx_gmm_auth_ciph_req(ctx, at->vec.rand,
+						  at->key_seq,
 						  GPRS_ALGO_GEA0);
 	}
 
@@ -1468,7 +1469,8 @@
 		}
 		at = &mm->auth_triplet;
 
-		gsm48_tx_gmm_auth_ciph_req(mm, at->rand, at->key_seq, GPRS_ALGO_GEA0);
+		gsm48_tx_gmm_auth_ciph_req(mm, at->vec.rand, at->key_seq,
+					   GPRS_ALGO_GEA0);
 		osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0);
 		break;
 	case 3370:	/* waiting for IDENTITY RESPONSE */
diff --git a/openbsc/src/gprs/gprs_gsup_messages.c b/openbsc/src/gprs/gprs_gsup_messages.c
index 07485f7..0b1dc9b 100644
--- a/openbsc/src/gprs/gprs_gsup_messages.c
+++ b/openbsc/src/gprs/gprs_gsup_messages.c
@@ -3,6 +3,7 @@
 /*
  * (C) 2014 by Sysmocom s.f.m.c. GmbH
  * (C) 2015 by Holger Hans Peter Freyther
+ * (C) 2016 by Harald Welte <laforge@gnumonks.org>
  * All Rights Reserved
  *
  * Author: Jacob Erlbeck
@@ -82,7 +83,7 @@
 }
 
 static int decode_auth_info(uint8_t *data, size_t data_len,
-			   struct gsm_auth_tuple *auth_tuple)
+			   struct osmo_auth_vector *auth_vector)
 {
 	int rc;
 	uint8_t tag;
@@ -100,24 +101,24 @@
 
 		switch (iei) {
 		case GPRS_GSUP_RAND_IE:
-			if (value_len != sizeof(auth_tuple->rand))
+			if (value_len != sizeof(auth_vector->rand))
 				goto parse_error;
 
-			memcpy(auth_tuple->rand, value, value_len);
+			memcpy(auth_vector->rand, value, value_len);
 			break;
 
 		case GPRS_GSUP_SRES_IE:
-			if (value_len != sizeof(auth_tuple->sres))
+			if (value_len != sizeof(auth_vector->sres))
 				goto parse_error;
 
-			memcpy(auth_tuple->sres, value, value_len);
+			memcpy(auth_vector->sres, value, value_len);
 			break;
 
 		case GPRS_GSUP_KC_IE:
-			if (value_len != sizeof(auth_tuple->kc))
+			if (value_len != sizeof(auth_vector->kc))
 				goto parse_error;
 
-			memcpy(auth_tuple->kc, value, value_len);
+			memcpy(auth_vector->kc, value, value_len);
 			break;
 
 		default:
@@ -149,7 +150,7 @@
 	uint8_t *value;
 	size_t value_len;
 	static const struct gprs_gsup_pdp_info empty_pdp_info = {0};
-	static const struct gsm_auth_tuple empty_auth_info = {0};
+	static const struct osmo_auth_vector empty_auth_info = {0};
 	static const struct gprs_gsup_message empty_gsup_message = {0};
 
 	*gsup_msg = empty_gsup_message;
@@ -183,7 +184,7 @@
 	while (data_len > 0) {
 		enum gprs_gsup_iei iei;
 		struct gprs_gsup_pdp_info pdp_info;
-		struct gsm_auth_tuple auth_info;
+		struct osmo_auth_vector auth_info;
 
 		rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
 		if (rc < 0)
@@ -252,7 +253,7 @@
 			break;
 
 		case GPRS_GSUP_AUTH_TUPLE_IE:
-			if (gsup_msg->num_auth_tuples >= GPRS_GSUP_MAX_NUM_AUTH_INFO) {
+			if (gsup_msg->num_auth_vectors >= GPRS_GSUP_MAX_NUM_AUTH_INFO) {
 				LOGP(DGPRS, LOGL_ERROR,
 				     "GSUP IE type %d (AUTH_INFO) max exceeded\n",
 				     iei);
@@ -260,13 +261,12 @@
 			}
 
 			auth_info = empty_auth_info;
-			auth_info.key_seq = gsup_msg->num_auth_tuples;
 
 			rc = decode_auth_info(value, value_len, &auth_info);
 			if (rc < 0)
 				return rc;
 
-			gsup_msg->auth_tuples[gsup_msg->num_auth_tuples++] =
+			gsup_msg->auth_vectors[gsup_msg->num_auth_vectors++] =
 				auth_info;
 			break;
 
@@ -325,7 +325,7 @@
 }
 
 static void encode_auth_info(struct msgb *msg, enum gprs_gsup_iei iei,
-			     const struct gsm_auth_tuple *auth_tuple)
+			     const struct osmo_auth_vector *auth_vector)
 {
 	uint8_t *len_field;
 	size_t old_len;
@@ -334,13 +334,13 @@
 	old_len = msgb_length(msg);
 
 	msgb_tlv_put(msg, GPRS_GSUP_RAND_IE,
-		     sizeof(auth_tuple->rand), auth_tuple->rand);
+		     sizeof(auth_vector->rand), auth_vector->rand);
 
 	msgb_tlv_put(msg, GPRS_GSUP_SRES_IE,
-		     sizeof(auth_tuple->sres), auth_tuple->sres);
+		     sizeof(auth_vector->sres), auth_vector->sres);
 
 	msgb_tlv_put(msg, GPRS_GSUP_KC_IE,
-		     sizeof(auth_tuple->kc), auth_tuple->kc);
+		     sizeof(auth_vector->kc), auth_vector->kc);
 
 	/* Update length field */
 	*len_field = msgb_length(msg) - old_len;
@@ -406,14 +406,11 @@
 		}
 	}
 
-	for (idx = 0; idx < gsup_msg->num_auth_tuples; idx++) {
-		const struct gsm_auth_tuple *auth_info;
+	for (idx = 0; idx < gsup_msg->num_auth_vectors; idx++) {
+		const struct osmo_auth_vector *auth_vector;
 
-		auth_info = &gsup_msg->auth_tuples[idx];
+		auth_vector = &gsup_msg->auth_vectors[idx];
 
-		if (auth_info->key_seq == GSM_KEY_SEQ_INVAL)
-			continue;
-
-		encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_info);
+		encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_vector);
 	}
 }
diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c
index 3467293..678c1de 100644
--- a/openbsc/src/gprs/gprs_subscriber.c
+++ b/openbsc/src/gprs/gprs_subscriber.c
@@ -199,18 +199,18 @@
 	struct sgsn_subscriber_data *sdata = subscr->sgsn_data;
 
 	LOGGSUBSCRP(LOGL_INFO, subscr,
-		"Got SendAuthenticationInfoResult, num_auth_tuples = %zu\n",
-		gsup_msg->num_auth_tuples);
+		"Got SendAuthenticationInfoResult, num_auth_vectors = %zu\n",
+		gsup_msg->num_auth_vectors);
 
-	if (gsup_msg->num_auth_tuples > 0) {
+	if (gsup_msg->num_auth_vectors > 0) {
 		memset(sdata->auth_triplets, 0, sizeof(sdata->auth_triplets));
 
 		for (idx = 0; idx < ARRAY_SIZE(sdata->auth_triplets); idx++)
 			sdata->auth_triplets[idx].key_seq = GSM_KEY_SEQ_INVAL;
 	}
 
-	for (idx = 0; idx < gsup_msg->num_auth_tuples; idx++) {
-		size_t key_seq = gsup_msg->auth_tuples[idx].key_seq;
+	for (idx = 0; idx < gsup_msg->num_auth_vectors; idx++) {
+		size_t key_seq = idx;
 		LOGGSUBSCRP(LOGL_DEBUG, subscr,
 			"Adding auth tuple, cksn = %zu\n", key_seq);
 		if (key_seq >= ARRAY_SIZE(sdata->auth_triplets)) {
@@ -219,7 +219,8 @@
 				key_seq);
 			continue;
 		}
-		sdata->auth_triplets[key_seq] = gsup_msg->auth_tuples[idx];
+		sdata->auth_triplets[key_seq].vec = gsup_msg->auth_vectors[idx];
+		sdata->auth_triplets[key_seq].key_seq = key_seq;
 	}
 
 	sdata->auth_triplets_updated = 1;
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
index 3f61163..50f0e8f 100644
--- a/openbsc/src/gprs/sgsn_vty.c
+++ b/openbsc/src/gprs/sgsn_vty.c
@@ -613,11 +613,11 @@
 		vty_out(vty, "     seq # : %d, ",
 			at->key_seq);
 		vty_out(vty, "     RAND  : %s, ",
-			osmo_hexdump(at->rand, sizeof(at->rand)));
+			osmo_hexdump(at->vec.rand, sizeof(at->vec.rand)));
 		vty_out(vty, "     SRES  : %s, ",
-			osmo_hexdump(at->sres, sizeof(at->sres)));
+			osmo_hexdump(at->vec.sres, sizeof(at->vec.sres)));
 		vty_out(vty, "     Kc    : %s%s",
-			osmo_hexdump(at->kc, sizeof(at->kc)),
+			osmo_hexdump(at->vec.kc, sizeof(at->vec.kc)),
 			VTY_NEWLINE);
 	}
 
@@ -704,17 +704,17 @@
 
 	OSMO_ASSERT(subscr->sgsn_data);
 
-	if (osmo_hexparse(sres_str, &at.sres[0], sizeof(at.sres)) < 0) {
+	if (osmo_hexparse(sres_str, &at.vec.sres[0], sizeof(at.vec.sres)) < 0) {
 		vty_out(vty, "%% invalid SRES value '%s'%s",
 			sres_str, VTY_NEWLINE);
 		goto failed;
 	}
-	if (osmo_hexparse(rand_str, &at.rand[0], sizeof(at.rand)) < 0) {
+	if (osmo_hexparse(rand_str, &at.vec.rand[0], sizeof(at.vec.rand)) < 0) {
 		vty_out(vty, "%% invalid RAND value '%s'%s",
 			rand_str, VTY_NEWLINE);
 		goto failed;
 	}
-	if (osmo_hexparse(kc_str, &at.kc[0], sizeof(at.kc)) < 0) {
+	if (osmo_hexparse(kc_str, &at.vec.kc[0], sizeof(at.vec.kc)) < 0) {
 		vty_out(vty, "%% invalid Kc value '%s'%s",
 			kc_str, VTY_NEWLINE);
 		goto failed;