/* 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/vlr/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 ? gsm48_reject_value_name(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;

	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;
	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, vlr_gmm_cause_to_reject_cause_domain(gsup->cause, true));
		break;
	case VLR_AUTH_E_HLR_SAI_ABORT:
		auth_fsm_term(fi, AUTH_FSM_FAILURE, vlr_gmm_cause_to_reject_cause_domain(gsup->cause, true));
		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;
}
