gsup_messages: Add UMTS AKA related encoding/decoding support
diff --git a/openbsc/include/openbsc/osmo_gsup_messages.h b/openbsc/include/openbsc/osmo_gsup_messages.h
index bdc46aa..4ccc029 100644
--- a/openbsc/include/openbsc/osmo_gsup_messages.h
+++ b/openbsc/include/openbsc/osmo_gsup_messages.h
@@ -51,6 +51,12 @@
 	OSMO_GSUP_RAND_IE			= 0x20,
 	OSMO_GSUP_SRES_IE			= 0x21,
 	OSMO_GSUP_KC_IE				= 0x22,
+	/* 3G support */
+	OSMO_GSUP_IK_IE				= 0x23,
+	OSMO_GSUP_CK_IE				= 0x24,
+	OSMO_GSUP_AUTN_IE			= 0x25,
+	OSMO_GSUP_AUTS_IE			= 0x26,
+	OSMO_GSUP_RES_IE			= 0x27,
 };
 
 enum osmo_gsup_message_type {
@@ -113,6 +119,7 @@
 	size_t				msisdn_enc_len;
 	const uint8_t			*hlr_enc;
 	size_t				hlr_enc_len;
+	const uint8_t			*auts;
 };
 
 int osmo_gsup_decode(const uint8_t *data, size_t data_len,
diff --git a/openbsc/src/gprs/osmo_gsup_messages.c b/openbsc/src/gprs/osmo_gsup_messages.c
index 773588b..e820b5a 100644
--- a/openbsc/src/gprs/osmo_gsup_messages.c
+++ b/openbsc/src/gprs/osmo_gsup_messages.c
@@ -90,6 +90,7 @@
 	uint8_t *value;
 	size_t value_len;
 	enum osmo_gsup_iei iei;
+	uint8_t presence = 0;
 
 	/* specific parts */
 	while (data_len > 0) {
@@ -105,6 +106,7 @@
 				goto parse_error;
 
 			memcpy(auth_vector->rand, value, value_len);
+			presence |= (1 << 0);
 			break;
 
 		case OSMO_GSUP_SRES_IE:
@@ -112,6 +114,7 @@
 				goto parse_error;
 
 			memcpy(auth_vector->sres, value, value_len);
+			presence |= (1 << 1);
 			break;
 
 		case OSMO_GSUP_KC_IE:
@@ -119,6 +122,35 @@
 				goto parse_error;
 
 			memcpy(auth_vector->kc, value, value_len);
+			presence |= (1 << 2);
+			break;
+
+		case OSMO_GSUP_IK_IE:
+			if (value_len != sizeof(auth_vector->ik))
+				goto parse_error;
+			memcpy(auth_vector->ik, value, value_len);
+			presence |= (1 << 4);
+			break;
+
+		case OSMO_GSUP_CK_IE:
+			if (value_len != sizeof(auth_vector->ck))
+				goto parse_error;
+			memcpy(auth_vector->ck, value, value_len);
+			presence |= (1 << 5);
+			break;
+
+		case OSMO_GSUP_AUTN_IE:
+			if (value_len != sizeof(auth_vector->autn))
+				goto parse_error;
+			memcpy(auth_vector->autn, value, value_len);
+			presence |= (1 << 6);
+			break;
+		case OSMO_GSUP_RES_IE:
+			if (value_len > sizeof(auth_vector->res))
+				goto parse_error;
+			memcpy(auth_vector->res, value, value_len);
+			auth_vector->res_len = value_len;
+			presence |= (1 << 7);
 			break;
 
 		default:
@@ -128,6 +160,11 @@
 		}
 	}
 
+	if (presence & 0x07)
+		auth_vector->auth_types |= OSMO_AUTH_TYPE_GSM;
+	if (presence & 0xf0)
+		auth_vector->auth_types |= OSMO_AUTH_TYPE_UMTS;
+
 	return 0;
 
 parse_error:
@@ -270,6 +307,15 @@
 				auth_info;
 			break;
 
+		case OSMO_GSUP_AUTS_IE:
+			if (value_len != 16) {
+				LOGP(DGPRS, LOGL_ERROR,
+					"AUTS length != 16 received\n");
+				return -GMM_CAUSE_COND_IE_ERR;
+			}
+			gsup_msg->auts = value;
+			break;
+
 		case OSMO_GSUP_MSISDN_IE:
 			gsup_msg->msisdn_enc = value;
 			gsup_msg->msisdn_enc_len = value_len;