/*! \file auth_tuak.c
 * GSM/GPRS/3G authentication core infrastructure */
/*
 * (C) 2023 by Harald Welte <laforge@osmocom.org>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 */

/* NOTE: TUAK offers a lot of size variability in terms of size of length of MAC_A, MAC_S,
 * but this is not used within 3GPP.  The different sizes of Kc and RES are handled via
 * osmo_sub_auth_data2. */

#include <errno.h>
#include <osmocom/crypt/auth.h>
#include <osmocom/core/bits.h>
#include "tuak/tuak.h"

/*! \addtogroup auth
 *  @{
 */

static const uint8_t *gen_opc_if_needed(const struct osmo_sub_auth_data2 *aud, uint8_t *gen_opc)
{
	int rc;

	/* Check if we only know OP and compute OPC if required */
	if (aud->type == OSMO_AUTH_TYPE_UMTS && aud->u.umts.opc_is_op) {
		rc = tuak_opc_gen(gen_opc, aud->u.umts.k, aud->u.umts.k_len, aud->u.umts.opc);
		if (rc < 0)
			return NULL;
		return gen_opc;
	}

	return aud->u.umts.opc;
}

static int tuak_gen_vec(struct osmo_auth_vector *vec,
			struct osmo_sub_auth_data2 *aud,
			const uint8_t *_rand)
{
	size_t res_len = vec->res_len;
	uint64_t next_sqn;
	uint8_t gen_opc[32];
	const uint8_t *opc;
	uint8_t sqn[6];
	uint64_t ind_mask;
	uint64_t seq_1;

	switch (vec->res_len) {
	case 4:
	case 8:
	case 16:
		break;
	default:
		return -EINVAL;
	}

	OSMO_ASSERT(aud->algo == OSMO_AUTH_ALG_TUAK);

	if (aud->u.umts.k_len != 16 && aud->u.umts.k_len != 32)
		return -EINVAL;
	if (aud->u.umts.opc_len != 32)
		return -EINVAL;

	opc = gen_opc_if_needed(aud, gen_opc);
	if (!opc)
		return -1;

	/* Determine next SQN, according to 3GPP TS 33.102:
	 * SQN consists of SEQ and a lower significant part of IND bits:
	 *
	 * |----------SEQ------------|
	 * |------------------------SQN-----------|
	 *                           |-----IND----|
	 *
	 * The IND part is used as "slots": e.g. a given HLR client will always
	 * get the same IND part, called ind here, with incrementing SEQ. In
	 * the USIM, each IND slot enforces that its SEQ are used in ascending
	 * order -- as long as that constraint is satisfied, the SQN may jump
	 * forwards and backwards. For example, for ind_bitlen == 5, asking the
	 * USIM for SQN = 32, 64, 33 is allowed, because 32 and 64 are
	 * SEQ || (ind == 0), and though 33 is below 64, it is ind == 1 and
	 * allowed.  Not allowed would be 32, 96, 64, because 64 would go
	 * backwards after 96, both being ind == 0.
	 *
	 * From the last used SQN, we want to increment SEQ + 1, and then pick
	 * the matching IND part.
	 *
	 * IND size is suggested in TS 33.102 as 5 bits. SQN is 48 bits long.
	 * If ind_bitlen is passed too large here, the algorithms will break
	 * down. But at which point should we return an error? A sane limit
	 * seems to be ind_bitlen == 10, but to protect against failure,
	 * limiting ind_bitlen to 28 is enough, 28 being the number of bits
	 * suggested for the delta in 33.102, which is discussed to still
	 * require 2^15 > 32000 authentications to wrap the SQN back to the
	 * start.
	 *
	 * Note that if a caller with ind == 1 generates N vectors, the SQN
	 * stored after this will reflect SEQ + N. If then another caller with
	 * ind == 2 generates another N vectors, this will then use SEQ + N
	 * onwards and end up with SEQ + N + N. In other words, most of each
	 * SEQ's IND slots will remain unused. When looking at SQN being 48
	 * bits wide, after dropping ind_bitlen (say 5) from it, we will still
	 * have a sequence range of 2^43 = 8.8e12, eight trillion sequences,
	 * which is large enough to not bother further. With the maximum
	 * ind_bitlen of 28 enforced below, we still get more than 1 million
	 * sequences, which is also sufficiently large.
	 *
	 * An ind_bitlen of zero may be passed from legacy callers that are not
	 * aware of the IND extension. For these, below algorithm works out as
	 * before, simply incrementing SQN by 1.
	 *
	 * This is also a mechanism for tools like the osmo-auc-gen to directly
	 * request a given SQN to be used. With ind_bitlen == 0 the caller can
	 * be sure that this code will increment SQN by exactly one before
	 * generating a tuple, thus a caller would simply pass
	 * { .ind_bitlen = 0, .ind = 0, .sqn = (desired_sqn - 1) }
	 */

	if (aud->u.umts.ind_bitlen > OSMO_MILENAGE_IND_BITLEN_MAX)
		return -2;

	seq_1 = 1LL << aud->u.umts.ind_bitlen;
	ind_mask = ~(seq_1 - 1);

	/* the ind index must not affect the SEQ part */
	if (aud->u.umts.ind >= seq_1)
		return -3;

	/* keep the incremented SQN local until gsm_milenage() succeeded. */
	next_sqn = ((aud->u.umts.sqn + seq_1) & ind_mask) + aud->u.umts.ind;

	osmo_store64be_ext(next_sqn, sqn, 6);

	tuak_generate(opc, aud->u.umts.amf, aud->u.umts.k, aud->u.umts.k_len,
		      sqn, _rand, vec->autn, vec->ik, vec->ck, vec->res, &res_len);

	/* generate the GSM Kc + SRES values using C2 + C3 functions */
	osmo_auth_c3(vec->kc, vec->ck, vec->ik);
	osmo_auth_c2(vec->sres, vec->res, vec->res_len, 1);

	vec->auth_types = OSMO_AUTH_TYPE_UMTS | OSMO_AUTH_TYPE_GSM;

	/* for storage in the caller's AUC database */
	aud->u.umts.sqn = next_sqn;

	return 0;
}

static int tuak_gen_vec_auts(struct osmo_auth_vector *vec,
			     struct osmo_sub_auth_data2 *aud,
			     const uint8_t *auts, const uint8_t *rand_auts,
			     const uint8_t *_rand)
{
	uint8_t sqn_out[6];
	uint8_t gen_opc[32];
	const uint8_t *opc;
	int rc;

	OSMO_ASSERT(aud->algo == OSMO_AUTH_ALG_TUAK);

	if (aud->u.umts.k_len != 16 && aud->u.umts.k_len != 32)
		return -EINVAL;
	if (aud->u.umts.opc_len != 32)
		return -EINVAL;

	opc = gen_opc_if_needed(aud, gen_opc);

	rc = tuak_auts(opc, aud->u.umts.k, sizeof(aud->u.umts.k), rand_auts, auts, sqn_out);
	if (rc < 0)
		return rc;

	aud->u.umts.sqn_ms = osmo_load64be_ext(sqn_out, 6) >> 16;
	/* Update our "largest used SQN" from the USIM -- milenage_gen_vec()
	 * below will increment SQN. */
	aud->u.umts.sqn = aud->u.umts.sqn_ms;

	return tuak_gen_vec(vec, aud, _rand);
}

static struct osmo_auth_impl tuak_alg = {
	.algo = OSMO_AUTH_ALG_TUAK,
	.name = "TUAK (libosmogsm built-in)",
	.priority = 1000,
	.gen_vec = &tuak_gen_vec,
	.gen_vec_auts = &tuak_gen_vec_auts,
};

static __attribute__((constructor)) void on_dso_load_tuak(void)
{
	osmo_auth_register(&tuak_alg);
}

/*! @} */
