aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/crypt
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2023-05-30 10:55:37 +0200
committerlaforge <laforge@osmocom.org>2023-06-02 08:29:55 +0000
commit08450c9ec6a2be9f58a9882e2ad0e78c61426254 (patch)
tree57a750061d7423dd65eda930f2314b2bf6dcbe8e /include/osmocom/crypt
parent5c7336ce889e267163d970f11e034e65c1c30624 (diff)
libosmogsm: Support authentication with 256-bit K and/or OP/OPc
3GPP TS 33.102 Section 6.3.7 states that K can be 128 or 256 bits, while our 'struct osmo_sub_auth_data' had a fixed-size 128bit field. This means we cannot use our auth_core for algorithms with larger key sizes, such as TUAK. Let's introduce osmo_sub_auth_data2 for larger (and variable) sized K and OP[c]. K and OP[c] can even have different sizes in TUAK, where OP[c] is always 256bit, but K can be 128 or 256 bits. So we need separate length fields for K and OP[c]. I'm adding backwards-compatibility API wrappers, so old applications just continue to work as they always did. However, I'm not adding compatibility wrappers for the plug-in API that can be used to register additional authentication implementations at runtime. We don't know of any user of that API outside of libosmocore, so the function signatures of the 'struct osmo_auth_impl' are modified in an incompatible way. Change-Id: Ie775fedba4a3fa12314c0f7c8a369662ef6a40df
Diffstat (limited to 'include/osmocom/crypt')
-rw-r--r--include/osmocom/crypt/auth.h46
1 files changed, 40 insertions, 6 deletions
diff --git a/include/osmocom/crypt/auth.h b/include/osmocom/crypt/auth.h
index d872f642..2833ed39 100644
--- a/include/osmocom/crypt/auth.h
+++ b/include/osmocom/crypt/auth.h
@@ -40,6 +40,30 @@ enum osmo_auth_algo {
#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;
@@ -58,7 +82,7 @@ struct osmo_sub_auth_data {
uint8_t ki[OSMO_A5_MAX_KEY_LEN_BYTES]; /*!< secret key */
} gsm;
} u;
-};
+} OSMO_DEPRECATED_OUTSIDE("Use osmo_sub_auth_data2 instead");
/* data structure describing a computed auth vector, generated by AuC */
struct osmo_auth_vector {
@@ -67,7 +91,7 @@ struct osmo_auth_vector {
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 */
+ uint8_t res_len; /*!< length (in bytes) of res: 8..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_* */
@@ -82,22 +106,32 @@ struct osmo_auth_impl {
/*! callback for generate authentication vectors */
int (*gen_vec)(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
+ struct osmo_sub_auth_data2 *aud,
const uint8_t *_rand);
- /* callback for generationg auth vectors + re-sync */
+ /*! callback for generating auth vectors + re-sync */
int (*gen_vec_auts)(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
+ 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);
+ 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);