Make UTRAN encryption algorithms configurable

Allow the user fine-grained control over which UMTS encryption
algorithms are permitted, rather than always permitting UEA1 and UEA2
or neither.

This brings the handling of UEA in line with the handling of A5 for
GERAN.

Change-Id: I91f9e50f9c1439aa19528f887b83ae9de628fcfd
Closes: OS#4144
Depends: osmo-iuh.git I6d2d033b0427bdc84fee61e0f3cb7b29935214bf
This commit is contained in:
Harald Welte 2021-02-06 17:12:20 +01:00 committed by Alexander Couzens
parent 274b70f1a8
commit 505a94a610
9 changed files with 38 additions and 64 deletions

View File

@ -155,10 +155,8 @@ struct gsm_network {
bool authentication_required; bool authentication_required;
int send_mm_info; int send_mm_info;
/* Whether to use encryption on UTRAN. /* bit-mask of permitted encryption algorithms. LSB=UEA0, MSB=UEA7 */
* TODO: we should offer a choice of UEA1 and/or UEA2, and probably replace this bool with a bit-mask of uint8_t uea_encryption_mask;
* permitted Iu encryption algorithms. See also OS#4143 and the 'encryption uea' vty command. */
bool uea_encryption;
struct rate_ctr_group *msc_ctrs; struct rate_ctr_group *msc_ctrs;
struct osmo_stat_item_group *statg; struct osmo_stat_item_group *statg;

View File

@ -103,7 +103,7 @@ struct ran_cipher_mode_command {
struct geran_encr *chosen_key; struct geran_encr *chosen_key;
} geran; } geran;
struct { struct {
bool uea_encryption; uint8_t uea_encryption_mask;
} utran; } utran;
}; };

View File

@ -414,7 +414,7 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
net->vlr, msc_a, vlr_lu_type, tmsi, imsi, net->vlr, msc_a, vlr_lu_type, tmsi, imsi,
&old_lai, &msc_a->via_cell.lai, &old_lai, &msc_a->via_cell.lai,
is_utran || net->authentication_required, is_utran || net->authentication_required,
is_utran ? net->uea_encryption : net->a5_encryption_mask > 0x01, is_utran ? net->uea_encryption_mask > 0x01 : net->a5_encryption_mask > 0x01,
lu->key_seq, lu->key_seq,
osmo_gsm48_classmark1_is_r99(&lu->classmark1), osmo_gsm48_classmark1_is_r99(&lu->classmark1),
is_utran, is_utran,
@ -805,7 +805,7 @@ int gsm48_rx_mm_serv_req(struct msc_a *msc_a, struct msgb *msg)
req->cm_service_type, req->cm_service_type,
&mi, &msc_a->via_cell.lai, &mi, &msc_a->via_cell.lai,
is_utran || net->authentication_required, is_utran || net->authentication_required,
is_utran ? net->uea_encryption : net->a5_encryption_mask > 0x01, is_utran ? net->uea_encryption_mask > 0x01 : net->a5_encryption_mask > 0x01,
req->cipher_key_seq, req->cipher_key_seq,
osmo_gsm48_classmark2_is_r99(cm2, cm2_len), osmo_gsm48_classmark2_is_r99(cm2, cm2_len),
is_utran); is_utran);
@ -931,7 +931,7 @@ static int gsm48_rx_cm_reest_req(struct msc_a *msc_a, struct msgb *msg)
VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ, 0, VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ, 0,
&mi, &msc_a->via_cell.lai, &mi, &msc_a->via_cell.lai,
is_utran || net->authentication_required, is_utran || net->authentication_required,
is_utran ? net->uea_encryption : net->a5_encryption_mask > 0x01, is_utran ? net->uea_encryption_mask > 0x01 : net->a5_encryption_mask > 0x01,
req->cipher_key_seq, req->cipher_key_seq,
osmo_gsm48_classmark2_is_r99(cm2, cm2_len), osmo_gsm48_classmark2_is_r99(cm2, cm2_len),
is_utran); is_utran);
@ -1293,7 +1293,7 @@ static int gsm48_rx_rr_pag_resp(struct msc_a *msc_a, struct msgb *msg)
net->vlr, msc_a, net->vlr, msc_a,
VLR_PR_ARQ_T_PAGING_RESP, 0, &mi, &msc_a->via_cell.lai, VLR_PR_ARQ_T_PAGING_RESP, 0, &mi, &msc_a->via_cell.lai,
is_utran || net->authentication_required, is_utran || net->authentication_required,
is_utran ? net->uea_encryption : net->a5_encryption_mask > 0x01, is_utran ? net->uea_encryption_mask > 0x01 : net->a5_encryption_mask > 0x01,
pr->key_seq, pr->key_seq,
osmo_gsm48_classmark2_is_r99(cm2, classmark2_len), osmo_gsm48_classmark2_is_r99(cm2, classmark2_len),
is_utran); is_utran);

View File

@ -349,8 +349,8 @@ static int msc_a_ran_enc_ciphering(struct msc_a *msc_a, bool umts_aka, bool retr
.chosen_key = &msc_a->geran_encr, .chosen_key = &msc_a->geran_encr,
}, },
.utran = { .utran = {
.uea_encryption = net->uea_encryption .uea_encryption_mask = net->uea_encryption_mask,
} },
}, },
}; };

View File

@ -67,7 +67,8 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
/* Permit a compile-time default of A5/3 and A5/1 */ /* Permit a compile-time default of A5/3 and A5/1 */
net->a5_encryption_mask = (1 << 3) | (1 << 1); net->a5_encryption_mask = (1 << 3) | (1 << 1);
net->uea_encryption = true; /* Permit a compile-time default of UEA2 and UEA1 */
net->uea_encryption_mask = (1 << 2) | (1 << 1);
net->mncc_guard_timeout = 180; net->mncc_guard_timeout = 180;
net->ncss_guard_timeout = 30; net->ncss_guard_timeout = 30;

View File

@ -169,41 +169,21 @@ DEFUN(cfg_net_encryption,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
/* So far just a boolean switch, a future patch might add individual config for UEA1 and UEA2, see OS#4143 */
DEFUN(cfg_net_encryption_uea, DEFUN(cfg_net_encryption_uea,
cfg_net_encryption_uea_cmd, cfg_net_encryption_uea_cmd,
"encryption uea <0-2> [<0-2>] [<0-2>]", "encryption uea <0-2> [<0-2>] [<0-2>]",
ENCRYPTION_STR ENCRYPTION_STR
"UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2." "UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2.\n"
" NOTE: the current implementation does not allow free choice of combining encryption algorithms yet."
" The only valid settings are either 'encryption uea 0' or 'encryption uea 1 2'.\n"
"UEAn Algorithm Number\n" "UEAn Algorithm Number\n"
"UEAn Algorithm Number\n" "UEAn Algorithm Number\n"
"UEAn Algorithm Number\n" "UEAn Algorithm Number\n"
) )
{ {
unsigned int i; unsigned int i;
uint8_t mask = 0;
gsmnet->uea_encryption_mask = 0;
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
mask |= (1 << atoi(argv[i])); gsmnet->uea_encryption_mask |= (1 << atoi(argv[i]));
if (mask == (1 << 0)) {
/* UEA0. Disable encryption. */
gsmnet->uea_encryption = false;
} else if (mask == ((1 << 1) | (1 << 2))) {
/* UEA1 and UEA2. Enable encryption. */
gsmnet->uea_encryption = true;
} else {
vty_out(vty,
"%% Error: the current implementation does not allow free choice of combining%s"
"%% encryption algorithms yet. The only valid settings are either%s"
"%% encryption uea 0%s"
"%% or%s"
"%% encryption uea 1 2%s",
VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -386,10 +366,12 @@ static int config_write_net(struct vty *vty)
} }
vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, "%s", VTY_NEWLINE);
if (!gsmnet->uea_encryption) vty_out(vty, " encryption uea");
vty_out(vty, " encryption uea 0%s", VTY_NEWLINE); for (i = 0; i < 8; i++) {
else if (gsmnet->uea_encryption_mask & (1 << i))
vty_out(vty, " encryption uea 1 2%s", VTY_NEWLINE); vty_out(vty, " %u", i);
}
vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, " authentication %s%s", vty_out(vty, " authentication %s%s",
gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE); gsmnet->authentication_required ? "required" : "optional", VTY_NEWLINE);
vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode), vty_out(vty, " rrlp mode %s%s", msc_rrlp_mode_name(gsmnet->rrlp.mode),

View File

@ -367,9 +367,13 @@ static struct msgb *ran_iu_make_security_mode_command(struct osmo_fsm_inst *call
const struct ran_cipher_mode_command *cm) const struct ran_cipher_mode_command *cm)
{ {
LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Tx RANAP SECURITY MODE COMMAND to RNC, ik %s\n", LOG_RAN_IU_ENC(caller_fi, LOGL_DEBUG, "Tx RANAP SECURITY MODE COMMAND to RNC, IK=%s, CK=%s\n",
osmo_hexdump_nospc(cm->vec->ik, 16)); osmo_hexdump_nospc(cm->vec->ik, 16),
return ranap_new_msg_sec_mod_cmd(cm->vec->ik, cm->utran.uea_encryption ? cm->vec->ck : NULL, RANAP_KeyStatus_new); cm->utran.uea_encryption_mask > 0x01 ? osmo_hexdump_nospc(cm->vec->ck, 16) : "NONE");
/* TODO: Do we need to check if the UE supports all of the algorithms and build an intersection like
* in the case of A5? */
return ranap_new_msg_sec_mod_cmd2(cm->vec->ik, cm->utran.uea_encryption_mask > 0x01 ? cm->vec->ck : NULL,
RANAP_KeyStatus_new, 0x06, cm->utran.uea_encryption_mask);
} }

View File

@ -50,7 +50,7 @@ static void _test_umts_authen(enum osmo_rat_type via_ran)
"d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb" "d3d36ff71c949e83c22072799e9687c5ec32a81d96afcbf4b4fb"
"0c7ac3e9e9b7db05"; "0c7ac3e9e9b7db05";
bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1) bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1)
|| (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption); || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > 0x1);
net->authentication_required = true; net->authentication_required = true;
net->vlr->cfg.assign_tmsi = true; net->vlr->cfg.assign_tmsi = true;
@ -333,7 +333,7 @@ static void test_umts_authen_geran()
static void test_umts_authen_utran() static void test_umts_authen_utran()
{ {
comment_start(); comment_start();
net->uea_encryption = false; net->uea_encryption_mask = 0x01;
_test_umts_authen(OSMO_RAT_UTRAN_IU); _test_umts_authen(OSMO_RAT_UTRAN_IU);
comment_end(); comment_end();
} }
@ -341,7 +341,7 @@ static void test_umts_authen_utran()
static void test_umts_auth_ciph_utran() static void test_umts_auth_ciph_utran()
{ {
comment_start(); comment_start();
net->uea_encryption = true; net->uea_encryption_mask = 0x06;
_test_umts_authen(OSMO_RAT_UTRAN_IU); _test_umts_authen(OSMO_RAT_UTRAN_IU);
comment_end(); comment_end();
} }
@ -361,7 +361,7 @@ static void _test_umts_authen_resync(enum osmo_rat_type via_ran)
struct vlr_subscr *vsub; struct vlr_subscr *vsub;
const char *imsi = "901700000010650"; const char *imsi = "901700000010650";
bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1) bool encryption = (via_ran == OSMO_RAT_GERAN_A && net->a5_encryption_mask > 0x1)
|| (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption); || (via_ran == OSMO_RAT_UTRAN_IU && net->uea_encryption_mask > 0x1);
net->authentication_required = true; net->authentication_required = true;
net->vlr->cfg.assign_tmsi = true; net->vlr->cfg.assign_tmsi = true;
@ -588,7 +588,7 @@ static void test_umts_authen_resync_geran()
static void test_umts_authen_resync_utran() static void test_umts_authen_resync_utran()
{ {
comment_start(); comment_start();
net->uea_encryption = false; net->uea_encryption_mask = 0x01;
_test_umts_authen_resync(OSMO_RAT_UTRAN_IU); _test_umts_authen_resync(OSMO_RAT_UTRAN_IU);
comment_end(); comment_end();
} }
@ -596,7 +596,7 @@ static void test_umts_authen_resync_utran()
static void test_umts_auth_ciph_resync_utran() static void test_umts_auth_ciph_resync_utran()
{ {
comment_start(); comment_start();
net->uea_encryption = true; net->uea_encryption_mask = 0x06;
_test_umts_authen_resync(OSMO_RAT_UTRAN_IU); _test_umts_authen_resync(OSMO_RAT_UTRAN_IU);
comment_end(); comment_end();
} }

View File

@ -31,7 +31,7 @@ OsmoMSC(config-net)# encryption?
encryption Encryption options encryption Encryption options
OsmoMSC(config-net)# encryption ? OsmoMSC(config-net)# encryption ?
a5 GSM A5 Air Interface Encryption. a5 GSM A5 Air Interface Encryption.
uea UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2. NOTE: the current implementation does not allow free choice of combining encryption algorithms yet. The only valid settings are either 'encryption uea 0' or 'encryption uea 1 2'. uea UTRAN (3G) encryption algorithms to allow: 0 = UEA0 (no encryption), 1 = UEA1, 2 = UEA2.
OsmoMSC(config-net)# encryption uea ? OsmoMSC(config-net)# encryption uea ?
<0-2> UEAn Algorithm Number <0-2> UEAn Algorithm Number
@ -189,38 +189,27 @@ OsmoMSC(config-net)# show running-config
... ...
OsmoMSC(config-net)# encryption uea 1 OsmoMSC(config-net)# encryption uea 1
% Error: the current implementation does not allow free choice of combining
% encryption algorithms yet. The only valid settings are either
% encryption uea 0
% or
% encryption uea 1 2
OsmoMSC(config-net)# show running-config OsmoMSC(config-net)# show running-config
... ...
encryption uea 0 encryption uea 1
... ...
OsmoMSC(config-net)# encryption uea 2 OsmoMSC(config-net)# encryption uea 2
% Error: the current implementation does not allow free choice of combining
...
OsmoMSC(config-net)# show running-config OsmoMSC(config-net)# show running-config
... ...
encryption uea 0 encryption uea 2
... ...
OsmoMSC(config-net)# encryption uea 0 1 OsmoMSC(config-net)# encryption uea 0 1
% Error: the current implementation does not allow free choice of combining
...
OsmoMSC(config-net)# show running-config OsmoMSC(config-net)# show running-config
... ...
encryption uea 0 encryption uea 0 1
... ...
OsmoMSC(config-net)# encryption uea 0 2 OsmoMSC(config-net)# encryption uea 0 2
% Error: the current implementation does not allow free choice of combining
...
OsmoMSC(config-net)# show running-config OsmoMSC(config-net)# show running-config
... ...
encryption uea 0 encryption uea 0 2
... ...
OsmoMSC(config-net)# encryption uea 1 2 OsmoMSC(config-net)# encryption uea 1 2