/* Osmocom Visitor Location Register (VLR) Authentication 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 */

	uint32_t parent_event_success;
	uint32_t parent_event_no_auth_info;
	uint32_t parent_event_failure;
};

/***********************************************************************
 * 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");
	}
}

enum auth_fsm_result {
	/* Authentication verified the subscriber. */
	AUTH_FSM_PASSED = 0,
	/* HLR does not have authentication info for this subscriber. */
	AUTH_FSM_NO_AUTH_INFO,
	/* Authentication was attempted but failed. */
	AUTH_FSM_FAILURE,
};

const char *auth_fsm_result_str[] = {
	[AUTH_FSM_PASSED] = "PASSED",
	[AUTH_FSM_NO_AUTH_INFO] = "NO_AUTH_INFO",
	[AUTH_FSM_FAILURE] = "FAILURE",
};

/* Terminate the Auth FSM Instance and notify parent */
static void auth_fsm_term(struct osmo_fsm_inst *fi, enum auth_fsm_result result, enum gsm48_reject_value cause)
{
	struct auth_fsm_priv *afp = fi->priv;

	LOGPFSM(fi, "Authentication terminating with result %s%s%s\n",
		auth_fsm_result_str[result],
		cause ? ", cause " : "",
		cause ? get_value_string(gsm48_gmm_cause_names, cause) : "");

	/* Do one final state transition (mostly for logging purpose)
	 * and set the parent_term_event according to result */
	switch (result) {
	case AUTH_FSM_PASSED:
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTHENTICATED, 0, 0);
		fi->proc.parent_term_event = afp->parent_event_success;
		break;
	case AUTH_FSM_NO_AUTH_INFO:
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0);
		fi->proc.parent_term_event = afp->parent_event_no_auth_info;
		break;
	case AUTH_FSM_FAILURE:
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_AUTH_FAILED, 0, 0);
		fi->proc.parent_term_event = afp->parent_event_failure;
		break;
	}

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

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, AUTH_FSM_FAILURE, 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;
	enum gsm48_reject_value gsm48_rej;

	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;
		}
	}

	switch (event) {
	case VLR_AUTH_E_HLR_SAI_ACK:
		if (!gsup->num_auth_vectors) {
			auth_fsm_term(fi, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE);
			return;
		}
		vlr_subscr_update_tuples(vsub, gsup);
		goto pass;
		break;
	case VLR_AUTH_E_HLR_SAI_NACK:
		/* HLR did not return Auth Info, hence cannot authenticate. (The caller may still decide to permit
		 * attaching without authentication) */
		auth_fsm_term(fi, AUTH_FSM_NO_AUTH_INFO, gsup->cause);
		break;
	case VLR_AUTH_E_HLR_SAI_ABORT:
		vlr_gmm_cause_to_mm_cause(gsup->cause, &gsm48_rej);
		auth_fsm_term(fi, AUTH_FSM_FAILURE, gsm48_rej);
		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, AUTH_FSM_FAILURE, GSM48_REJECT_ILLEGAL_MS);
			}
		} else {
			auth_fsm_term(fi, AUTH_FSM_PASSED, 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, AUTH_FSM_FAILURE, 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, AUTH_FSM_FAILURE, GSM48_REJECT_NETWORK_FAILURE);
	}
	switch (event) {
	case VLR_AUTH_E_HLR_SAI_ACK:
		vlr_subscr_update_tuples(vsub, gsup);
		osmo_fsm_inst_state_chg(fi, VLR_SUB_AS_WAIT_RESP_RESYNC,
					vlr_timer(vsub->vlr, 3260), 3260);
		_vlr_subscr_authenticate(fi);
		break;
	case VLR_AUTH_E_HLR_SAI_NACK:
		auth_fsm_term(fi,
			      AUTH_FSM_FAILURE,
			      gsup->cause == GMM_CAUSE_IMSI_UNKNOWN?
				      GSM48_REJECT_IMSI_UNKNOWN_IN_HLR
				      : GSM48_REJECT_NETWORK_FAILURE);
		break;
	}
}

/* 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, AUTH_FSM_FAILURE, GSM48_REJECT_SYNCH_FAILURE);
			}
		} else {
			/* Result = Pass */
			auth_fsm_term(fi, AUTH_FSM_PASSED, 0);
		}
		break;
	case VLR_AUTH_E_MS_AUTH_FAIL:
		/* Second failure: Result = Fail */
		auth_fsm_term(fi, AUTH_FSM_FAILURE, 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,
				     struct osmo_fsm_inst *parent,
				     uint32_t parent_event_success,
				     uint32_t parent_event_no_auth_info,
				     uint32_t parent_event_failure,
				     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_event_failure);
	if (!fi) {
		osmo_fsm_inst_dispatch(parent, parent_event_failure, 0);
		return NULL;
	}

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

	afp->vsub = vsub;
	if (vsub->imsi[0])
		afp->by_imsi = true;
	afp->is_r99 = is_r99;
	afp->is_utran = is_utran;
	afp->parent_event_success = parent_event_success;
	afp->parent_event_no_auth_info = parent_event_no_auth_info;
	afp->parent_event_failure = parent_event_failure;
	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;
}
