mirror of https://gerrit.osmocom.org/osmo-tetra
108 lines
3.5 KiB
C
108 lines
3.5 KiB
C
#ifndef TETRA_CRYPTO_H
|
|
#define TETRA_CRYPTO_H
|
|
|
|
#include <inttypes.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "../tetra_prim.h"
|
|
#include "../tetra_tdma.h"
|
|
#include "../tetra_mac_pdu.h"
|
|
|
|
#define TCDB_ALLOC_BLOCK_SIZE 16
|
|
|
|
enum tetra_key_type {
|
|
KEYTYPE_UNDEFINED = 0x00,
|
|
|
|
/* Keytypes usable as ECK after applying TB5 */
|
|
KEYTYPE_DCK = 0x01,
|
|
KEYTYPE_MGCK = 0x02,
|
|
KEYTYPE_CCK_SCK = 0x04, /* SCK in class 2, CCK in class 3 networks */
|
|
|
|
/* Can be combined with SCK/CCK to get MGCK */
|
|
KEYTYPE_GCK = 0x20,
|
|
};
|
|
|
|
enum tetra_ksg_type {
|
|
UNKNOWN = 0,
|
|
KSG_TEA1 = 1, /* KSG number value 0 */
|
|
KSG_TEA2 = 2, /* KSG number value 1 */
|
|
KSG_TEA3 = 3, /* KSG number value 2 */
|
|
KSG_TEA4 = 4, /* KSG number value 3 */
|
|
KSG_TEA5 = 5, /* KSG number value 4 */
|
|
KSG_TEA6 = 6, /* KSG number value 5 */
|
|
KSG_TEA7 = 7, /* KSG number value 6 */
|
|
KSG_PROPRIETARY = 8, /* KSG number values 9-15 */
|
|
};
|
|
|
|
enum tetra_security_class {
|
|
NETWORK_CLASS_UNDEFINED = 0,
|
|
NETWORK_CLASS_1 = 1,
|
|
NETWORK_CLASS_2 = 2,
|
|
NETWORK_CLASS_3 = 3,
|
|
};
|
|
|
|
struct tetra_netinfo {
|
|
uint32_t mcc;
|
|
uint32_t mnc;
|
|
enum tetra_ksg_type ksg_type; /* KSG used in this network */
|
|
enum tetra_security_class security_class; /* Security class this network employs */
|
|
};
|
|
|
|
struct tetra_key {
|
|
uint32_t index; /* position in key list */
|
|
uint32_t mnc;
|
|
uint32_t mcc;
|
|
enum tetra_key_type key_type;
|
|
uint32_t key_num; /* key_vn or whatever key numbering system is relevant for this key type */
|
|
uint32_t addr; /* ISSI, GSSI, or whatever address is relevant for this key type */
|
|
uint8_t key[16]; /* Currently keys are 80 bits, but we may want to support 128-bit keys as well */
|
|
struct tetra_netinfo *network_info; /* Network with which the key is associated */
|
|
};
|
|
|
|
struct tetra_crypto_database {
|
|
uint32_t num_keys;
|
|
struct tetra_key *keys;
|
|
uint32_t num_nets;
|
|
struct tetra_netinfo *nets;
|
|
};
|
|
extern struct tetra_crypto_database *tcdb;
|
|
|
|
struct tetra_crypto_state {
|
|
int mnc; /* Network info for selecting keys */
|
|
int mcc; /* Network info for selecting keys */
|
|
int cck_id; /* CCK or SCK id used on network (from SYSINFO) */
|
|
int hn; /* Hyperframe number for IV (from SYSINFO) */
|
|
int la; /* location area for TB5 */
|
|
int cn; /* carrier number for TB5. WARNING: only set correctly if tuned to main control channel */
|
|
int cc; /* colour code for TB5 */
|
|
struct tetra_netinfo *network; /* pointer to network info struct loaded from file */
|
|
struct tetra_key *cck; /* pointer to CCK or SCK for this network and version (from SYSINFO) */
|
|
};
|
|
extern struct tetra_crypto_state *tcs;
|
|
|
|
const char *tetra_get_key_type_name(enum tetra_key_type);
|
|
const char *tetra_get_ksg_type_name(enum tetra_ksg_type);
|
|
const char *tetra_get_security_class_name(uint8_t pdut);
|
|
|
|
/* Key loading / unloading */
|
|
void tetra_crypto_init(void);
|
|
int load_keystore(char *filename);
|
|
void unload_keystore(void);
|
|
|
|
/* Keystream generation and decryption functions */
|
|
uint32_t tea_build_iv(struct tetra_tdma_time *tm, uint16_t hn, uint8_t dir);
|
|
int decrypt_identity(struct tetra_addr *addr);
|
|
int decrypt_mac_element(struct tetra_tmvsap_prim *tmvp, struct tetra_key *key, int l1_len, int tmpdu_offset);
|
|
int decrypt_voice_timeslot(struct tetra_tdma_time *tdma_time, int16_t *type1_bits);
|
|
|
|
/* Key selection and crypto state management */
|
|
struct tetra_key *get_ksg_key(int addr);
|
|
struct tetra_netinfo *get_network_info(int mcc, int mnc);
|
|
void update_current_network(int mcc, int mnc);
|
|
void update_current_cck(void);
|
|
|
|
char *dump_network_info(struct tetra_netinfo *network);
|
|
char *dump_key(struct tetra_key *k);
|
|
|
|
#endif /* TETRA_CRYPTO_H */
|