1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#pragma once
/*! \defgroup auth GSM/GPRS/3G Authentication
* @{
* \file auth.h */
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
#define OSMO_A5_MAX_KEY_LEN_BYTES (128/8)
#define OSMO_MILENAGE_IND_BITLEN_MAX 28
/*! Authentication Type (GSM/UMTS) */
enum osmo_sub_auth_type {
OSMO_AUTH_TYPE_NONE = 0x00,
OSMO_AUTH_TYPE_GSM = 0x01,
OSMO_AUTH_TYPE_UMTS = 0x02,
};
extern const struct value_string osmo_sub_auth_type_names[];
static inline const char *osmo_sub_auth_type_name(enum osmo_sub_auth_type val)
{ return get_value_string(osmo_sub_auth_type_names, val); }
/*! Authentication Algorithm.
* See also osmo_auth_alg_name() and osmo_auth_alg_parse(). */
enum osmo_auth_algo {
OSMO_AUTH_ALG_NONE,
OSMO_AUTH_ALG_COMP128v1,
OSMO_AUTH_ALG_COMP128v2,
OSMO_AUTH_ALG_COMP128v3,
OSMO_AUTH_ALG_XOR_3G,
OSMO_AUTH_ALG_MILENAGE,
OSMO_AUTH_ALG_XOR_2G,
OSMO_AUTH_ALG_TUAK,
_OSMO_AUTH_ALG_NUM,
};
/* Backwards-compatibility. We used to call XOR-3G just "XOR" which became ambiguous when
* we started to add XOR-2G support. */
#define OSMO_AUTH_ALG_XOR OSMO_AUTH_ALG_XOR_3G
/*! permanent (secret) subscriber auth data */
struct osmo_sub_auth_data2 {
enum osmo_sub_auth_type type;
enum osmo_auth_algo algo;
union {
struct {
/* See 3GPP TS 33.102 Section 9.3.7 Length of authentication parameters */
uint8_t opc[32]; /*!< operator invariant value */
uint8_t opc_len; /*!< OPc length (in bytes): 16 or 32 */
uint8_t k[32]; /*!< secret key of the subscriber */
uint8_t k_len; /*!< K length (in bytes): 16 or 32 */
uint8_t amf[2];
uint64_t sqn; /*!< sequence number (in: prev sqn; out: used sqn) */
int opc_is_op; /*!< is the OPC field OPC (0) or OP (1) ? */
unsigned int ind_bitlen; /*!< nr of bits not in SEQ, only SQN */
unsigned int ind; /*!< which IND slot to use an SQN from */
uint64_t sqn_ms; /*!< sqn from AUTS (output value only) */
} umts;
struct {
uint8_t ki[OSMO_A5_MAX_KEY_LEN_BYTES]; /*!< secret key */
} gsm;
} u;
};
/* deprecated older structure without support for 32-byte K/OP[c] */
struct osmo_sub_auth_data {
enum osmo_sub_auth_type type;
enum osmo_auth_algo algo;
union {
struct {
uint8_t opc[16]; /*!< operator invariant value */
uint8_t k[OSMO_A5_MAX_KEY_LEN_BYTES]; /*!< secret key of the subscriber */
uint8_t amf[2];
uint64_t sqn; /*!< sequence number (in: prev sqn; out: used sqn) */
int opc_is_op; /*!< is the OPC field OPC (0) or OP (1) ? */
unsigned int ind_bitlen; /*!< nr of bits not in SEQ, only SQN */
unsigned int ind; /*!< which IND slot to use an SQN from */
uint64_t sqn_ms; /*!< sqn from AUTS (output value only) */
} umts;
struct {
uint8_t ki[OSMO_A5_MAX_KEY_LEN_BYTES]; /*!< secret key */
} gsm;
} u;
};
/* data structure describing a computed auth vector, generated by AuC */
struct osmo_auth_vector {
uint8_t rand[16]; /*!< random challenge */
uint8_t autn[16]; /*!< authentication nonce */
uint8_t ck[OSMO_A5_MAX_KEY_LEN_BYTES]; /*!< ciphering key */
uint8_t ik[OSMO_A5_MAX_KEY_LEN_BYTES]; /*!< integrity key */
uint8_t res[16]; /*!< authentication result */
uint8_t res_len; /*!< length (in bytes) of res: 4..16 bytes */
uint8_t kc[8]; /*!< Kc for GSM encryption (A5) */
uint8_t sres[4]; /*!< authentication result for GSM */
uint32_t auth_types; /*!< bitmask of OSMO_AUTH_TYPE_* */
};
/* An implementation of an authentication algorithm */
struct osmo_auth_impl {
struct llist_head list;
enum osmo_auth_algo algo; /*!< algorithm we implement */
const char *name; /*!< name of the implementation */
unsigned int priority; /*!< priority value (resp. othe implementations */
/*! callback for generate authentication vectors */
int (*gen_vec)(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data2 *aud,
const uint8_t *_rand);
/*! callback for generating auth vectors + re-sync */
int (*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);
};
int osmo_auth_gen_vec(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data *aud, const uint8_t *_rand)
OSMO_DEPRECATED_OUTSIDE("Use osmo_auth_gen_vec2 instead");
int osmo_auth_gen_vec2(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data2 *aud, const uint8_t *_rand);
int osmo_auth_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)
OSMO_DEPRECATED_OUTSIDE("Use osmo_auth_gen_vec_auts2 instead");
int osmo_auth_gen_vec_auts2(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data2 *aud,
const uint8_t *auts, const uint8_t *rand_auts,
const uint8_t *_rand);
int osmo_auth_register(struct osmo_auth_impl *impl);
int osmo_auth_load(const char *path);
int osmo_auth_supported(enum osmo_auth_algo algo);
void osmo_c4(uint8_t *ck, const uint8_t *kc);
const char *osmo_auth_alg_name(enum osmo_auth_algo alg);
enum osmo_auth_algo osmo_auth_alg_parse(const char *name);
void osmo_auth_c3(uint8_t kc[], const uint8_t ck[], const uint8_t ik[]);
void osmo_auth_c2(uint8_t sres[4], const uint8_t *res, size_t res_len, uint8_t sres_deriv_func);
/* @} */
|