/* Cryptography related helper, key management and wrapper functions */ /* * Copyright (C) 2023 Midnight Blue B.V. * * Author: Wouter Bokslag * * SPDX-License-Identifier: AGPL-3.0+ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * See the COPYING file in the main directory for details. */ #ifndef TETRA_CRYPTO_H #define TETRA_CRYPTO_H #include #include #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) */ }; 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_state_init(struct tetra_crypto_state *tcs); void tetra_crypto_db_init(void); int load_keystore(char *filename); /* 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_crypto_state *tcs, struct tetra_addr *addr); int decrypt_mac_element(struct tetra_crypto_state *tcs, struct tetra_tmvsap_prim *tmvp, struct tetra_key *key, int l1_len, int tmpdu_offset); int decrypt_voice_timeslot(struct tetra_crypto_state *tcs, struct tetra_tdma_time *tdma_time, int16_t *type1_bits); /* Key selection and crypto state management */ struct tetra_netinfo *get_network_info(int mcc, int mnc); struct tetra_key *get_ksg_key(struct tetra_crypto_state *tcs, int addr); void update_current_network(struct tetra_crypto_state *tcs, int mcc, int mnc); void update_current_cck(struct tetra_crypto_state *tcs); char *dump_network_info(struct tetra_netinfo *network); char *dump_key(struct tetra_key *k); #endif /* TETRA_CRYPTO_H */