/* Osmocom Visitor Location Register (VLR) Autentication FSM */

/* (C) 2016 by Harald Welte <laforge@gnumonks.org>
 *
 * 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 <http://www.gnu.org/licenses/>.
 *
 */


#include <osmocom/core/fsm.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/debug.h>

#include "vlr_core.h"
#include "vlr_auth_fsm.h"

#define S(x)	(1 << (x))

static const struct value_string fsm_auth_event_names[] = {
	OSMO_VALUE_STRING(VLR_AUTH_E_START),
	OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_ACK),
	OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_NACK),
	OSMO_VALUE_STRING(VLR_AUTH_E_HLR_SAI_ABORT),
	OSMO_VALUE_STRING(VLR_AUTH_E_MS_AUTH_RESP),
	OSMO_VALUE_STRING(VLR_AUTH_E_MS_AUTH_FAIL),
	OSMO_VALUE_STRING(VLR_AUTH_E_MS_ID_IMSI),
	{ 0, NULL }
};

/* private state of the auth_fsm_instance */
struct auth_fsm_priv {
	struct vlr_subscr *vsub;
	bool by_imsi;
	bool is_r99;
	bool is_utran;
	bool auth_requested;

	int auth_tuple_max_reuse_count; /* see vlr->cfg instead */
};

/***********************************************************************
 * Utility functions
 ***********************************************************************/

/* Always use either vlr_subscr_get_auth_tuple() or vlr_subscr_has_auth_tuple()
 * instead, to ensure proper use count.
 * Return an auth tuple with the lowest use_count among the auth tuples. If
 * max_reuse_count >= 0, return NULL if all available auth tuples have a use
 * count > max_reuse_count. If max_reuse_count is negative, return a currently
 * least used auth tuple without enforcing a maximum use count.  If there are
 * no auth tuples, return NULL.
 */
static struct vlr_auth_tuple *
_vlr_subscr_next_auth_tuple(struct vlr_subscr *vsub, int max_reuse_count)
{
	unsigned int count;
	unsigned int idx;
	struct vlr_auth_tuple *at = NULL;
	unsigned int key_seq = VLR_KEY_SEQ_INVAL;

	if (!vsub)
		return NULL;

	if (vsub->last_tuple)
		key_seq = vsub->last_tuple->key_seq;

	if (key_seq == VLR_KEY_SEQ_INVAL)
		/* Start with 0 after increment modulo array size */
		idx = ARRAY_SIZE(vsub->auth_tuples) - 1;
	else
		idx = key_seq;

	for (count = ARRAY_SIZE(vsub->auth_tuples); count > 0; count--) {
		idx = (idx + 1) % ARRAY_SIZE(vsub->auth_tuples);

		if (vsub->auth_tuples[idx].key_seq == VLR_KEY_SEQ_INVAL)
			continue;

		if (!at || vsub->auth_tuples[idx].use_count < at->use_count)
			at = &vsub->auth_tuples[idx];
	}

	if (!at || (max_reuse_count >= 0 && at->use_count > max_reuse_count))
		return NULL;

	return at;
}

/* Return an auth tuple and increment its use count. */
static struct vlr_auth_tuple *
vlr_subscr_get_auth_tuple(struct vlr_subscr *vsub, int max_reuse_count)
{
	struct vlr_auth_tuple *at = _vlr_subscr_next_auth_tuple(vsub,
							       max_reuse_count);
	if (!at)
		return NULL;
	at->use_count++;
	return at;
}

/* Return whether an auth tuple with a matching use_count is available. */
static bool vlr_subscr_has_auth_tuple(struct vlr_subscr *vsub,
				      int max_reuse_count)
{
	return _vlr_subscr_next_auth_tuple(vsub, max_reuse_count) != NULL;
}

static bool check_auth_resp(struct vlr_subscr *vsub, bool is_r99,
			    bool is_utran, const uint8_t *res,
			    uint8_t res_len)
{
	struct vlr_auth_tuple *at = vsub->last_tuple;
	struct osmo_auth_vector *vec = &at->vec;
	bool check_umts;
	bool res_is_umts_aka;
	OSMO_ASSERT(at);

	LOGVSUBP(LOGL_DEBUG, vsub, "AUTH on %s received %s: %s (%u bytes)\n",
		 is_utran ? "UTRAN" : "GERAN",
		 is_utran ? "RES" : "SRES/RES",
		 osmo_hexdump_nospc(res, res_len), res_len);

	/* RES must be present and at least 32bit */
	if (!res || !res_len) {
		LOGVSUBP(LOGL_NOTICE, vsub, "AUTH SRES/RES missing\n");
		goto out_false;
	}

	/* We're deciding the UMTS AKA-ness of the response by the RES size. So let's make sure we can't
	 * mix them up by size. On UTRAN, we expect full length RES always, no way to mix up there. */
	if (!is_utran && vec->res_len == sizeof(vec->sres))
		LOGVSUBP(LOGL_ERROR, vsub, "Unforeseen situation: UMTS AKA's RES length"
			 " equals the size of SRES: %u -- this code wants to differentiate"
			 " the two by their size, which won't work properly now.\n", vec->res_len);

	/* RES must be either vec->res_len (UMTS AKA) or sizeof(sres) (GSM AKA) */
	if (res_len == vec->res_len)
		res_is_umts_aka = true;
	else if (res_len == sizeof(vec->sres))
		res_is_umts_aka = false;
	else {
		if (is_utran)
			LOGVSUBP(LOGL_NOTICE, vsub, "AUTH RES has invalid length: %u."
				 " Expected %u (UMTS AKA)\n",
				 res_len, vec->res_len);
		else
			LOGVSUBP(LOGL_NOTICE, vsub, "AUTH SRES/RES has invalid length: %u."
				 " Expected either %zu (GSM AKA) or %u (UMTS AKA)\n",
				 res_len, sizeof(vec->sres), vec->res_len);
		goto out_false;
	}

	check_umts = (is_r99
		      && (vec->auth_types & OSMO_AUTH_TYPE_UMTS)
		      && res_is_umts_aka);

	/* Even on an R99 capable MS with a UMTS AKA capable USIM,
	 * the MS may still choose to only perform GSM AKA, as
	 * long as the bearer is GERAN -- never on UTRAN: */
	if (is_utran && !check_umts) {
		LOGVSUBP(LOGL_ERROR, vsub,
			 "AUTH via UTRAN, cannot allow GSM AKA"
			 " (MS is %sR99 capable, vec has %sUMTS AKA tokens, res_len=%u is %s)\n",
			 is_r99 ? "" : "NOT ",
			 (vec->auth_types & OSMO_AUTH_TYPE_UMTS) ? "" : "NO ",
			 res_len, (res_len == vec->res_len)? "valid" : "INVALID on UTRAN");
		goto out_false;
	}

	if (check_umts) {
		if (res_len != vec->res_len
		    || memcmp(res, vec->res, res_len)) {
			LOGVSUBP(LOGL_INFO, vsub, "UMTS AUTH failure:"
				 " mismatching res (expected res=%s)\n",
				 osmo_hexdump(vec->res, vec->res_len));
			goto out_false;
		}

		LOGVSUBP(LOGL_INFO, vsub, "AUTH established UMTS security"
			 " context\n");
		vsub->sec_ctx = VLR_SEC_CTX_UMTS;
		return true;
	} else {
		if (res_len != sizeof(vec->sres)
		    || memcmp(res, vec->sres, sizeof(vec->sres))) {
			LOGVSUBP(LOGL_INFO, vsub, "GSM AUTH failure:"
				 " mismatching sres (expected sres=%s)\n",
				 osmo_hexdump(vec->sres, sizeof(vec->sres)));
			goto out_false;
		}

		LOGVSUBP(LOGL_INFO, vsub, "AUTH established GSM security"
			 " context\n");
		vsub->sec_ctx = VLR_SEC_CTX_GSM;
		return true;
	}

out_false:
	vsub->sec_ctx = VLR_SEC_CTX_NONE;
	return false;
}

static void auth_fsm_onenter_failed(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;

	/* If authentication hasn't even started, e.g. the HLR sent no auth
	 * info, then we also don't need to tell the HLR about an auth failure.
	 */
	if (afp->auth_requested) {
		int rc = vlr_subscr_tx_auth_fail_rep(vsub);
		if (rc < 0)
			LOGVSUBP(LOGL_ERROR, vsub, "Failed to communicate AUTH failure to HLR\n");
	}
}

static const char *vlr_auth_fsm_result_name(enum gsm48_reject_value result)
{
	if (!result)
		return "PASSED";
	return get_value_string(gsm48_gmm_cause_names, result);
}

/* Terminate the Auth FSM Instance and notify parent */
static void auth_fsm_term(struct osmo_fsm_inst *fi, enum gsm48_reject_value result)
{
	LOGPFSM(fi, "Authentication terminating with result %s\n",
		vlr_auth_fsm_result_name(result));

	/* Do one final state transition (mostly for logging purpose) */
	if (!result)
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTHENTICATED, 0, 0);
	else
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0);

	/* return the result to the parent FSM */
	osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, &result);
}

static void auth_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	vsub->auth_fsm = NULL;
}

/* back-end function transmitting authentication. Caller ensures we have valid
 * tuple */
static int _vlr_subscr_authenticate(struct osmo_fsm_inst *fi)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	struct vlr_auth_tuple *at;
	bool use_umts_aka;

	/* Caller ensures we have vectors available */
	at = vlr_subscr_get_auth_tuple(vsub, afp->auth_tuple_max_reuse_count);
	if (!at) {
		LOGPFSML(fi, LOGL_ERROR, "A previous check ensured that an"
			 " auth tuple was available, but now there is in fact"
			 " none.\n");
		auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
		return -1;
	}

	use_umts_aka = vlr_use_umts_aka(&at->vec, afp->is_r99);
	LOGPFSM(fi, "got auth tuple: use_count=%d key_seq=%d"
		" -- will use %s AKA (is_r99=%s, at->vec.auth_types=0x%x)\n",
		at->use_count, at->key_seq,
		use_umts_aka ? "UMTS" : "GSM", afp->is_r99 ? "yes" : "no", at->vec.auth_types);

	/* Transmit auth req to subscriber */
	afp->auth_requested = true;
	vsub->last_tuple = at;
	vsub->vlr->ops.tx_auth_req(vsub->msc_conn_ref, at, use_umts_aka);
	return 0;
}

/***********************************************************************
 * FSM State Action functions
 ***********************************************************************/

/* Initial State of TS 23.018 AUT_VLR */
static void auth_fsm_needs_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;

	OSMO_ASSERT(event == VLR_AUTH_E_START);

	/* Start off with the default max_reuse_count, possibly change that if we
	 * need to re-use an old tuple. */
	afp->auth_tuple_max_reuse_count = vsub->vlr->cfg.auth_tuple_max_reuse_count;

	/* Check if we have vectors available */
	if (!vlr_subscr_has_auth_tuple(vsub, afp->auth_tuple_max_reuse_count)) {
		/* Obtain_Authentication_Sets_VLR */
		int rc = vlr_subscr_req_sai(vsub, NULL, NULL);
		if (rc < 0)
			LOGPFSM(fi, "Failed to request Authentication Sets from VLR\n");
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
					GSM_29002_TIMER_M, 0);
	} else {
		/* go straight ahead with sending auth request */
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP,
					vlr_timer(vsub->vlr, 3260), 3260);
		_vlr_subscr_authenticate(fi);
	}
}

/* Waiting for Authentication Info from HLR */
static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event,
			     void *data)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	struct osmo_gsup_message *gsup = data;

	if (event == VLR_AUTH_E_HLR_SAI_NACK)
		LOGPFSM(fi, "GSUP: rx Auth Info Error cause: %d: %s\n",
			gsup->cause,
			get_value_string(gsm48_gmm_cause_names, gsup->cause));

	/* We are in what corresponds to the
	 * Wait_For_Authentication_Sets state of TS 23.018 OAS_VLR */
	if ((event == VLR_AUTH_E_HLR_SAI_ACK && !gsup->num_auth_vectors)
	    || (event == VLR_AUTH_E_HLR_SAI_NACK &&
		gsup->cause != GMM_CAUSE_IMSI_UNKNOWN)
	    || (event == VLR_AUTH_E_HLR_SAI_ABORT)) {
		if (vsub->vlr->cfg.auth_reuse_old_sets_on_error
		    && vlr_subscr_has_auth_tuple(vsub, -1)) {
			/* To re-use an old tuple, disable the max_reuse_count
			 * constraint. */
			afp->auth_tuple_max_reuse_count = -1;
			goto pass;
		}
		/* result = procedure error */
		auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
		return;
	}

	switch (event) {
	case VLR_AUTH_E_HLR_SAI_ACK:
		vlr_subscr_update_tuples(vsub, gsup);
		goto pass;
		break;
	case VLR_AUTH_E_HLR_SAI_NACK:
		auth_fsm_term(fi,
			      gsup->cause == GMM_CAUSE_IMSI_UNKNOWN?
				      GSM48_REJECT_IMSI_UNKNOWN_IN_HLR
				      : GSM48_REJECT_NETWORK_FAILURE);
		break;
	}

	return;
pass:
	osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP,
				vlr_timer(vsub->vlr, 3260), 3260);
	_vlr_subscr_authenticate(fi);
}

/* Waiting for Authentication Response from MS */
static void auth_fsm_wait_auth_resp(struct osmo_fsm_inst *fi, uint32_t event,
				    void *data)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	struct vlr_instance *vlr = vsub->vlr;
	struct vlr_auth_resp_par *par = data;
	int rc;

	switch (event) {
	case VLR_AUTH_E_MS_AUTH_RESP:
		rc = check_auth_resp(vsub, par->is_r99, par->is_utran,
				     par->res, par->res_len);
		if (rc == false) {
			if (!afp->by_imsi) {
				vlr->ops.tx_id_req(vsub->msc_conn_ref,
						   GSM_MI_TYPE_IMSI);
				osmo_fsm_inst_state_chg(fi,
						VLR_SUB_AS_WAIT_ID_IMSI,
						vlr_timer(vlr, 3270), 3270);
			} else {
				auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS);
			}
		} else {
			auth_fsm_term(fi, 0);
		}
		break;
	case VLR_AUTH_E_MS_AUTH_FAIL:
		if (par->auts) {
			/* First failure, start re-sync attempt */
			rc = vlr_subscr_req_sai(vsub, par->auts,
					   vsub->last_tuple->vec.rand);
			osmo_fsm_inst_state_chg(fi,
					VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
					GSM_29002_TIMER_M, 0);
		} else
			auth_fsm_term(fi, GSM48_REJECT_ILLEGAL_MS);
		break;
	}
}

/* Waiting for Authentication Info from HLR (resync case) */
static void auth_fsm_wait_ai_resync(struct osmo_fsm_inst *fi,
				    uint32_t event, void *data)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	struct osmo_gsup_message *gsup = data;

	/* We are in what corresponds to the
	 * Wait_For_Authentication_Sets state of TS 23.018 OAS_VLR */
	if ((event == VLR_AUTH_E_HLR_SAI_ACK && !gsup->num_auth_vectors) ||
	    (event == VLR_AUTH_E_HLR_SAI_NACK &&
	     gsup->cause != GMM_CAUSE_IMSI_UNKNOWN) ||
	    (event == VLR_AUTH_E_HLR_SAI_ABORT)) {
		/* result = procedure error */
		auth_fsm_term(fi, GSM48_REJECT_NETWORK_FAILURE);
	}
	switch (event) {
	case VLR_AUTH_E_HLR_SAI_ACK:
		vlr_subscr_update_tuples(vsub, gsup);
		goto pass;
		break;
	case VLR_AUTH_E_HLR_SAI_NACK:
		auth_fsm_term(fi,
			      gsup->cause == GMM_CAUSE_IMSI_UNKNOWN?
				      GSM48_REJECT_IMSI_UNKNOWN_IN_HLR
				      : GSM48_REJECT_NETWORK_FAILURE);
		break;
	}

	return;
pass:
	osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC,
				vlr_timer(vsub->vlr, 3260), 3260);
	_vlr_subscr_authenticate(fi);
}

/* Waiting for AUTH RESP from MS (re-sync case) */
static void auth_fsm_wait_auth_resp_resync(struct osmo_fsm_inst *fi,
					   uint32_t event, void *data)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	struct vlr_auth_resp_par *par = data;
	struct vlr_instance *vlr = vsub->vlr;
	int rc;

	switch (event) {
	case VLR_AUTH_E_MS_AUTH_RESP:
		rc = check_auth_resp(vsub, par->is_r99, par->is_utran,
				     par->res, par->res_len);
		if (rc == false) {
			if (!afp->by_imsi) {
				vlr->ops.tx_id_req(vsub->msc_conn_ref,
						   GSM_MI_TYPE_IMSI);
				osmo_fsm_inst_state_chg(fi,
						VLR_SUB_AS_WAIT_ID_IMSI,
						vlr_timer(vlr, 3270), 3270);
			} else {
				/* Result = Aborted */
				auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE);
			}
		} else {
			/* Result = Pass */
			auth_fsm_term(fi, 0);
		}
		break;
	case VLR_AUTH_E_MS_AUTH_FAIL:
		/* Second failure: Result = Fail */
		auth_fsm_term(fi, GSM48_REJECT_SYNCH_FAILURE);
		break;
	}
}

/* AUT_VLR waiting for Obtain_IMSI_VLR result */
static void auth_fsm_wait_imsi(struct osmo_fsm_inst *fi, uint32_t event,
				void *data)
{
	struct auth_fsm_priv *afp = fi->priv;
	struct vlr_subscr *vsub = afp->vsub;
	const char *mi_string = data;

	switch (event) {
	case VLR_AUTH_E_MS_ID_IMSI:
		if (vsub->imsi[0]
		    && !vlr_subscr_matches_imsi(vsub, mi_string)) {
			LOGVSUBP(LOGL_ERROR, vsub, "IMSI in ID RESP differs:"
				 " %s\n", mi_string);
		} else {
			strncpy(vsub->imsi, mi_string, sizeof(vsub->imsi));
			vsub->imsi[sizeof(vsub->imsi)-1] = '\0';
		}
		/* retry with identity=IMSI */
		afp->by_imsi = true;
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_NEEDS_AUTH, 0, 0);
		osmo_fsm_inst_dispatch(fi, VLR_AUTH_E_START, NULL);
		break;
	}
}

static const struct osmo_fsm_state auth_fsm_states[] = {
	[VLR_SUB_AS_NEEDS_AUTH] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH),
		.in_event_mask = S(VLR_AUTH_E_START),
		.out_state_mask = S(VLR_SUB_AS_NEEDS_AUTH_WAIT_AI) |
				  S(VLR_SUB_AS_WAIT_RESP),
		.action = auth_fsm_needs_auth,
	},
	[VLR_SUB_AS_NEEDS_AUTH_WAIT_AI] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH_WAIT_AI),
		.in_event_mask = S(VLR_AUTH_E_HLR_SAI_ACK) |
				 S(VLR_AUTH_E_HLR_SAI_NACK),
		.out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) |
				  S(VLR_SUB_AS_WAIT_RESP),
		.action = auth_fsm_wait_ai,
	},
	[VLR_SUB_AS_WAIT_RESP] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_RESP),
		.in_event_mask = S(VLR_AUTH_E_MS_AUTH_RESP) |
				 S(VLR_AUTH_E_MS_AUTH_FAIL),
		.out_state_mask = S(VLR_SUB_AS_WAIT_ID_IMSI) |
				  S(VLR_SUB_AS_AUTH_FAILED) |
				  S(VLR_SUB_AS_AUTHENTICATED) |
				  S(VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC),
		.action = auth_fsm_wait_auth_resp,
	},
	[VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC),
		.in_event_mask = S(VLR_AUTH_E_HLR_SAI_ACK) |
				 S(VLR_AUTH_E_HLR_SAI_NACK),
		.out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) |
				  S(VLR_SUB_AS_WAIT_RESP_RESYNC),
		.action = auth_fsm_wait_ai_resync,
	},
	[VLR_SUB_AS_WAIT_RESP_RESYNC] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_RESP_RESYNC),
		.in_event_mask = S(VLR_AUTH_E_MS_AUTH_RESP) |
				 S(VLR_AUTH_E_MS_AUTH_FAIL),
		.out_state_mask = S(VLR_SUB_AS_AUTH_FAILED) |
				  S(VLR_SUB_AS_AUTHENTICATED),
		.action = auth_fsm_wait_auth_resp_resync,
	},
	[VLR_SUB_AS_WAIT_ID_IMSI] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_WAIT_ID_IMSI),
		.in_event_mask = S(VLR_AUTH_E_MS_ID_IMSI),
		.out_state_mask = S(VLR_SUB_AS_NEEDS_AUTH),
		.action = auth_fsm_wait_imsi,
	},
	[VLR_SUB_AS_AUTHENTICATED] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_AUTHENTICATED),
		.in_event_mask = 0,
		.out_state_mask = 0,
	},
	[VLR_SUB_AS_AUTH_FAILED] = {
		.name = OSMO_STRINGIFY(VLR_SUB_AS_AUTH_FAILED),
		.in_event_mask = 0,
		.out_state_mask = 0,
		.onenter = auth_fsm_onenter_failed,
	},
};

struct osmo_fsm vlr_auth_fsm = {
	.name = "VLR_Authenticate",
	.states = auth_fsm_states,
	.num_states = ARRAY_SIZE(auth_fsm_states),
	.allstate_event_mask = 0,
	.allstate_action = NULL,
	.log_subsys = DVLR,
	.event_names = fsm_auth_event_names,
	.cleanup = auth_fsm_cleanup,
};

/***********************************************************************
 * User API (for SGSN/MSC code)
 ***********************************************************************/

/* MSC->VLR: Start Procedure Authenticate_VLR (TS 23.012 Ch. 4.1.2.2) */
struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
				     uint32_t log_level,
				     struct osmo_fsm_inst *parent,
				     uint32_t parent_term_event,
				     bool is_r99,
				     bool is_utran)
{
	struct osmo_fsm_inst *fi;
	struct auth_fsm_priv *afp;

	fi = osmo_fsm_inst_alloc_child(&vlr_auth_fsm, parent,
					parent_term_event);
	if (!fi) {
		osmo_fsm_inst_dispatch(parent, parent_term_event, 0);
		return NULL;
	}

	afp = talloc_zero(fi, struct auth_fsm_priv);
	if (!afp) {
		osmo_fsm_inst_dispatch(parent, parent_term_event, 0);
		return NULL;
	}

	afp->vsub = vsub;
	if (vsub->imsi[0])
		afp->by_imsi = true;
	afp->is_r99 = is_r99;
	afp->is_utran = is_utran;
	fi->priv = afp;
	vsub->auth_fsm = fi;

	osmo_fsm_inst_dispatch(fi, VLR_AUTH_E_START, NULL);

	return fi;
}

bool auth_try_reuse_tuple(struct vlr_subscr *vsub, uint8_t key_seq)
{
	int max_reuse_count = vsub->vlr->cfg.auth_tuple_max_reuse_count;
	struct vlr_auth_tuple *at = vsub->last_tuple;

	if (!at)
		return false;
	if ((max_reuse_count >= 0) && (at->use_count > max_reuse_count))
		return false;
	if (at->key_seq != key_seq)
		return false;
	at->use_count++;
	return true;
}
