]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-SIM peer: Allow external SIM processing to be used
authorJouni Malinen <j@w1.fi>
Sat, 19 Oct 2013 15:36:12 +0000 (18:36 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 20 Oct 2013 10:12:04 +0000 (13:12 +0300)
This allows the new external_sim=1 case to be used to perform GSM
authentication step in EAP-SIM peer process. Following control interface
event is used to request the operation:

CTRL-REQ-SIM-<network id>:GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>] needed
for SSID <SSID>

For example:
<3>CTRL-REQ-SIM-0:GSM-AUTH:5e3496ce7d5863b3b09f97f565513bc3:
73f0f0bc5c47bcbed6f572d07ab74056:447b784f08de80bdc2b1e100fccbb534
needed for SSID test

Response from external processing is returned with
CTRL-RSP-SIM-<network id> GSM-AUTH:<Kc1>:<SRES1>:<Kc2>:<SRES2>
[:<Kc3>:<SRES3>]

For example:
wpa_cli sim 0 GSM-AUTH:d41c76e0079247aa:2709ebfb:43baa77cfc8bcd6c:
0fa98dc1:a8ad1f6e30e

Signed-hostap: Jouni Malinen <j@w1.fi>

src/eap_peer/eap_sim.c

index 82ea18de4ecd404d05cc1ec6787d415ce94b0125..d8560543fa262e515b4253777c1bfdb81cb1f87c 100644 (file)
@@ -145,6 +145,80 @@ static void eap_sim_deinit(struct eap_sm *sm, void *priv)
 }
 
 
+static int eap_sim_ext_sim_req(struct eap_sm *sm, struct eap_sim_data *data)
+{
+       char req[200], *pos, *end;
+       size_t i;
+
+       wpa_printf(MSG_DEBUG, "EAP-SIM: Use external SIM processing");
+       pos = req;
+       end = pos + sizeof(req);
+       pos += os_snprintf(pos, end - pos, "GSM-AUTH");
+       for (i = 0; i < data->num_chal; i++) {
+               pos += os_snprintf(pos, end - pos, ":");
+               pos += wpa_snprintf_hex(pos, end - pos, data->rand[i],
+                                       GSM_RAND_LEN);
+       }
+
+       eap_sm_request_sim(sm, req);
+       return 1;
+}
+
+
+static int eap_sim_ext_sim_result(struct eap_sm *sm, struct eap_sim_data *data,
+                                 struct eap_peer_config *conf)
+{
+       char *resp, *pos;
+       size_t i;
+
+       wpa_printf(MSG_DEBUG,
+                  "EAP-SIM: Use result from external SIM processing");
+
+       resp = conf->external_sim_resp;
+       conf->external_sim_resp = NULL;
+
+       if (os_strncmp(resp, "GSM-AUTH:", 9) != 0) {
+               wpa_printf(MSG_DEBUG, "EAP-SIM: Unrecognized external SIM processing response");
+               os_free(resp);
+               return -1;
+       }
+
+       pos = resp + 9;
+       for (i = 0; i < data->num_chal; i++) {
+               wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND",
+                           data->rand[i], GSM_RAND_LEN);
+
+               if (hexstr2bin(pos, data->kc[i], EAP_SIM_KC_LEN) < 0)
+                       goto invalid;
+               wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc",
+                               data->kc[i], EAP_SIM_KC_LEN);
+               pos += EAP_SIM_KC_LEN * 2;
+               if (*pos != ':')
+                       goto invalid;
+               pos++;
+
+               if (hexstr2bin(pos, data->sres[i], EAP_SIM_SRES_LEN) < 0)
+                       goto invalid;
+               wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES",
+                               data->sres[i], EAP_SIM_SRES_LEN);
+               pos += EAP_SIM_SRES_LEN * 2;
+               if (i + 1 < data->num_chal) {
+                       if (*pos != ':')
+                               goto invalid;
+                       pos++;
+               }
+       }
+
+       os_free(resp);
+       return 0;
+
+invalid:
+       wpa_printf(MSG_DEBUG, "EAP-SIM: Invalid external SIM processing GSM-AUTH response");
+       os_free(resp);
+       return -1;
+}
+
+
 static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data)
 {
        struct eap_peer_config *conf;
@@ -154,6 +228,14 @@ static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data)
        conf = eap_get_config(sm);
        if (conf == NULL)
                return -1;
+
+       if (sm->external_sim) {
+               if (conf->external_sim_resp)
+                       return eap_sim_ext_sim_result(sm, data, conf);
+               else
+                       return eap_sim_ext_sim_req(sm, data);
+       }
+
        if (conf->pcsc) {
                if (scard_gsm_auth(sm->scard_ctx, data->rand[0],
                                   data->sres[0], data->kc[0]) ||
@@ -605,6 +687,7 @@ static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
        const u8 *identity;
        size_t identity_len;
        struct eap_sim_attrs eattr;
+       int res;
 
        wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge");
        data->reauth = 0;
@@ -648,8 +731,13 @@ static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
 
        os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN);
        data->num_chal = attr->num_chal;
-               
-       if (eap_sim_gsm_auth(sm, data)) {
+
+       res = eap_sim_gsm_auth(sm, data);
+       if (res > 0) {
+               wpa_printf(MSG_DEBUG, "EAP-SIM: Wait for external SIM processing");
+               return NULL;
+       }
+       if (res) {
                wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed");
                return eap_sim_client_error(data, id,
                                            EAP_SIM_UNABLE_TO_PROCESS_PACKET);