/* GSM/GPRS/3G authentication core infrastructure */

/* (C) 2011 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 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <osmocom/crypt/auth.h>
#include <osmocom/core/bits.h>
#include "milenage/common.h"
#include "milenage/milenage.h"

static int milenage_gen_vec(struct osmo_auth_vector *vec,
			    struct osmo_sub_auth_data *aud,
			    const uint8_t *_rand)
{
	size_t res_len = sizeof(vec->res);
	uint64_t next_sqn;
	uint8_t sqn[6];
	uint64_t ind_mask;
	uint64_t seq_1;
	int rc;

	/* 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 > 28)
		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);
	milenage_generate(aud->u.umts.opc, aud->u.umts.amf, aud->u.umts.k,
			  sqn, _rand,
			  vec->autn, vec->ik, vec->ck, vec->res, &res_len);
	vec->res_len = res_len;
	rc = gsm_milenage(aud->u.umts.opc, aud->u.umts.k, _rand, vec->sres, vec->kc);
	if (rc < 0)
		return rc;

	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 milenage_gen_vec_auts(struct osmo_auth_vector *vec,
				 struct osmo_sub_auth_data *aud,
				 const uint8_t *auts, const uint8_t *rand_auts,
				 const uint8_t *_rand)
{
	uint8_t sqn_out[6];
	uint8_t gen_opc[16];
	uint8_t *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 = milenage_opc_gen(gen_opc, aud->u.umts.k,
				      aud->u.umts.opc);
		if (rc < 0)
			return rc;
		opc = gen_opc;
	} else
		opc = aud->u.umts.opc;

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

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

	return milenage_gen_vec(vec, aud, _rand);
}

static struct osmo_auth_impl milenage_alg = {
	.algo = OSMO_AUTH_ALG_MILENAGE,
	.name = "MILENAGE (libosmogsm built-in)",
	.priority = 1000,
	.gen_vec = &milenage_gen_vec,
	.gen_vec_auts = &milenage_gen_vec_auts,
};

static __attribute__((constructor)) void on_dso_load_milenage(void)
{
	osmo_auth_register(&milenage_alg);
}
