srsue/extnas: handle (U)SIM GenAuthResp.Request
This commit is contained in:
parent
27344af7f0
commit
b594b15e79
|
@ -90,6 +90,10 @@ private:
|
|||
void handle_rrctl_data(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
|
||||
void handle_rrctl_param(rrctl::proto::msg_disc disc, const uint8_t* msg, size_t len);
|
||||
|
||||
void handle_rrctl_ext_usim(const uint8_t* msg, size_t len);
|
||||
void handle_usim_gen_auth_resp_req(const struct rrctl::proto::ext_usim_msg* msg, size_t len);
|
||||
void handle_usim_gen_nas_keys_req(const struct rrctl::proto::ext_usim_msg* msg, size_t len);
|
||||
|
||||
void rrctl_send_confirm(rrctl::proto::msg_type type);
|
||||
void rrctl_send_error(rrctl::proto::msg_type type);
|
||||
};
|
||||
|
|
|
@ -85,6 +85,8 @@ void nas_ext::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interf
|
|||
break;
|
||||
case rrctl::proto::RRCTL_SEC_MODE:
|
||||
case rrctl::proto::RRCTL_EXT_USIM:
|
||||
handle_rrctl_ext_usim(payload, length);
|
||||
break;
|
||||
case rrctl::proto::RRCTL_CONN_RELEASE:
|
||||
default:
|
||||
nas_log->warning("%s is not handled\n", desc.c_str());
|
||||
|
@ -213,6 +215,110 @@ void nas_ext::handle_rrctl_param(rrctl::proto::msg_disc disc, const uint8_t* msg
|
|||
}
|
||||
}
|
||||
|
||||
void nas_ext::handle_rrctl_ext_usim(const uint8_t* _msg, size_t len)
|
||||
{
|
||||
enum rrctl::proto::ext_usim_msg_type msg_type;
|
||||
const struct rrctl::proto::ext_usim_msg* msg;
|
||||
std::string msg_desc;
|
||||
|
||||
if (len < 4) { /* XXX: type + padding */
|
||||
nas_log->error("Received too short (U)SIM specific message (len=%zu)\n", len);
|
||||
rrctl_send_error(rrctl::proto::RRCTL_EXT_USIM);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Skip the header */
|
||||
len -= 4;
|
||||
|
||||
msg = reinterpret_cast<const struct rrctl::proto::ext_usim_msg*> (_msg);
|
||||
msg_type = static_cast<rrctl::proto::ext_usim_msg_type> (msg->type);
|
||||
|
||||
switch (msg_type) {
|
||||
case rrctl::proto::EXT_USIM_GEN_AUTH_RESP:
|
||||
handle_usim_gen_auth_resp_req(msg, len);
|
||||
break;
|
||||
case rrctl::proto::EXT_USIM_RAW_APDU:
|
||||
case rrctl::proto::EXT_USIM_READ_FILE:
|
||||
case rrctl::proto::EXT_USIM_UPDATE_FILE:
|
||||
case rrctl::proto::EXT_USIM_RESERVED:
|
||||
default:
|
||||
nas_log->warning("(U)SIM specific message 0x%02x is not handled\n", msg->type);
|
||||
}
|
||||
}
|
||||
|
||||
void nas_ext::handle_usim_gen_auth_resp_req(const struct rrctl::proto::ext_usim_msg* msg, size_t len)
|
||||
{
|
||||
const struct rrctl::proto::ext_usim_gen_auth_resp_req* req;
|
||||
struct rrctl::proto::ext_usim_gen_auth_resp_rsp* rsp;
|
||||
struct rrctl::proto::ext_usim_msg* rsp_msg;
|
||||
std::pair<uint16_t, uint16_t> mcc_mnc;
|
||||
struct rrctl::proto::msg_hdr* hdr;
|
||||
srslte::byte_buffer_t pdu;
|
||||
|
||||
/* Allocate the response message in advance */
|
||||
hdr = rrctl::codec::enc_hdr(pdu, rrctl::proto::RRCTL_EXT_USIM, rrctl::proto::RRCTL_CNF, 4);
|
||||
rsp_msg = reinterpret_cast<struct rrctl::proto::ext_usim_msg*> (&pdu.msg[pdu.N_bytes]);
|
||||
rsp_msg->type = msg->type;
|
||||
pdu.N_bytes += 4;
|
||||
|
||||
if (len < sizeof(*req)) {
|
||||
nas_log->error("Received too short (U)SIM GenAuthResp.req (len=%zu)\n", len);
|
||||
hdr->disc = (uint8_t) rrctl::proto::RRCTL_ERR;
|
||||
iface->write(pdu);
|
||||
return;
|
||||
}
|
||||
|
||||
rsp = &rsp_msg->u.gen_auth_resp_rsp;
|
||||
req = &msg->u.gen_auth_resp_req;
|
||||
|
||||
// Parse PLMN ID
|
||||
try {
|
||||
/* HACK: generalize this function */
|
||||
rrctl::codec::dec_plmn_select_req(mcc_mnc, &req->mcc[0], len);
|
||||
} catch (const rrctl::codec::error& e) {
|
||||
nas_log->warning("Failed to parse MCC/MNC: %s\n", e.what());
|
||||
hdr->disc = (uint8_t) rrctl::proto::RRCTL_ERR;
|
||||
iface->write(pdu);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t k_asme[32];
|
||||
uint8_t res[16];
|
||||
int res_len;
|
||||
|
||||
/* NOTE: this is a blocking call => no other RRCTL messages can be processed in parallel?
|
||||
* FIXME: the authors of srsUE apparently are not aware of 'const', so we have to cast. */
|
||||
auth_result_t auth_res = usim->generate_authentication_response((uint8_t*) &req->rand[0],
|
||||
(uint8_t*) &req->autn[0],
|
||||
mcc_mnc.first, mcc_mnc.second,
|
||||
&res[0], &res_len, &k_asme[0]);
|
||||
switch (auth_res) {
|
||||
case AUTH_OK:
|
||||
nas_log->info("Authentication vector has been generated successfully\n");
|
||||
|
||||
pdu.N_bytes += sizeof(*rsp);
|
||||
pdu.append_bytes(&k_asme[0], sizeof(k_asme));
|
||||
pdu.append_bytes(&res[0], res_len);
|
||||
rsp->res_len = (uint8_t) res_len;
|
||||
break;
|
||||
case AUTH_SYNCH_FAILURE:
|
||||
nas_log->warning("Synchronization is required to generate an authentication vector\n");
|
||||
|
||||
pdu.N_bytes += sizeof(*rsp);
|
||||
pdu.append_bytes(&res[0], res_len);
|
||||
rsp->res_len = (uint8_t) res_len;
|
||||
rsp->out_of_sync = true;
|
||||
break;
|
||||
case AUTH_FAILED:
|
||||
default:
|
||||
nas_log->warning("Could not generate an authentication vector\n");
|
||||
hdr->disc = (uint8_t) rrctl::proto::RRCTL_ERR;
|
||||
}
|
||||
|
||||
hdr->len = htons(pdu.N_bytes - sizeof(*hdr));
|
||||
iface->write(pdu);
|
||||
}
|
||||
|
||||
void nas_ext::get_metrics(nas_metrics_t* m)
|
||||
{
|
||||
nas_metrics_t metrics = {};
|
||||
|
|
Loading…
Reference in New Issue