]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Start plumbing in rlm_sim fast reauthentication
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 15 Dec 2017 23:51:21 +0000 (23:51 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 15 Dec 2017 23:51:28 +0000 (23:51 +0000)
src/modules/rlm_eap/types/rlm_eap_sim/eap_sim.h
src/modules/rlm_eap/types/rlm_eap_sim/rlm_eap_sim.c

index 1c7644e1eab1cfd3bab2d37897366ce66c5f982c..110b5ed5b2260c4a617c56070c4e2a87878d433c 100644 (file)
@@ -35,6 +35,7 @@ RCSIDH(rlm_eap_sim_eap_sim_h, "$Id$")
 typedef enum {
        EAP_SIM_SERVER_START = 0,
        EAP_SIM_SERVER_CHALLENGE,
+       EAP_SIM_SERVER_REAUTHENTICATE,
        EAP_SIM_SERVER_SUCCESS_NOTIFICATION,
        EAP_SIM_SERVER_SUCCESS,
        EAP_SIM_SERVER_FAILURE_NOTIFICATION,
index 2dfa4c114317091dc479f518415e03974bcb8cb0..e364a85a622fd528d417e4983e152beec49a2080 100644 (file)
@@ -42,6 +42,7 @@ RCSID("$Id$")
 FR_NAME_NUMBER const sim_state_table[] = {
        { "START",                              EAP_SIM_SERVER_START                            },
        { "CHALLENGE",                          EAP_SIM_SERVER_CHALLENGE                        },
+       { "REAUTHENTICATE",                     EAP_SIM_SERVER_REAUTHENTICATE                   },
        { "SUCCESS-NOTIFICATION",               EAP_SIM_SERVER_SUCCESS_NOTIFICATION             },
        { "SUCCESS",                            EAP_SIM_SERVER_SUCCESS                          },
        { "FAILURE-NOTIFICATION",               EAP_SIM_SERVER_FAILURE_NOTIFICATION             },
@@ -301,34 +302,19 @@ static int eap_sim_send_challenge(eap_session_t *eap_session)
        return 0;
 }
 
+/** Send NONCE_S and re-key
+ *
+ */
 static int eap_sim_send_reauthentication(eap_session_t *eap_session)
 {
        REQUEST                 *request = eap_session->request;
        eap_sim_session_t       *eap_sim_session = talloc_get_type_abort(eap_session->opaque, eap_sim_session_t);
-       VALUE_PAIR              **to_peer, *vp;
+       VALUE_PAIR              **to_peer, *vp, *mk, *counter;
        RADIUS_PACKET           *packet;
-       fr_sim_vector_src_t     src = SIM_VECTOR_SRC_AUTO;
 
        rad_assert(eap_session->request != NULL);
        rad_assert(eap_session->request->reply);
 
-       RDEBUG2("Acquiring GSM vector(s)");
-       if ((fr_sim_vector_gsm_from_attrs(eap_session, request->control, 0, &eap_sim_session->keys, &src) != 0) ||
-           (fr_sim_vector_gsm_from_attrs(eap_session, request->control, 1, &eap_sim_session->keys, &src) != 0) ||
-           (fr_sim_vector_gsm_from_attrs(eap_session, request->control, 2, &eap_sim_session->keys, &src) != 0)) {
-               REDEBUG("Failed retrieving SIM vectors");
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      All set, calculate keys!
-        */
-       fr_sim_crypto_kdf_0_gsm(&eap_sim_session->keys);
-       if (RDEBUG_ENABLED3) fr_sim_crypto_keys_log(request, &eap_sim_session->keys);
-
-       RDEBUG2("Sending SIM-Challenge");
-       eap_session->this_round->request->code = FR_EAP_CODE_REQUEST;
-
        /*
         *      to_peer is the data to the client
         */
@@ -336,25 +322,48 @@ static int eap_sim_send_reauthentication(eap_session_t *eap_session)
        to_peer = &packet->vps;
 
        /*
-        *      Okay, we got the challenges! Put them into attributes.
+        *      If any of the session resumption inputs (on our side)
+        *      are missing or malformed, return an error code
+        *      and the state machine will jump to the start state.
         */
-       MEM(vp = fr_pair_afrom_child_num(packet, dict_sim_root, FR_EAP_SIM_RAND));
-       fr_pair_value_memcpy(vp, eap_sim_session->keys.gsm.vector[0].rand, SIM_VECTOR_GSM_RAND_SIZE);
-       fr_pair_add(to_peer, vp);
+       mk = fr_pair_find_by_child_num(request->control, dict_sim_root, FR_EAP_SIM_MK, TAG_ANY);
+       if (!mk) {
+               RWDEBUG2("Missing &control:EAP-SIM-MK, skipping session resumption");
+               return -1;
+       }
+       if (mk->vp_length != SIM_MK_SIZE) {
+               RWDEBUG("&control:EAP-SIM-MK has incorrect length, expected %u bytes got %zu bytes",
+                       SIM_MK_SIZE, mk->vp_length);
+               return -1;
+       }
+       counter = fr_pair_find_by_child_num(request->control, dict_sim_root, FR_EAP_SIM_COUNTER, TAG_ANY);
+       if (!counter) {
+               RWDEBUG2("Missing &control:EAP-SIM-Counter, skipping session resumption");
+               return -1;
+       }
 
-       MEM(vp = fr_pair_afrom_child_num(packet, dict_sim_root, FR_EAP_SIM_RAND));
-       fr_pair_value_memcpy(vp, eap_sim_session->keys.gsm.vector[1].rand, SIM_VECTOR_GSM_RAND_SIZE);
-       fr_pair_add(to_peer, vp);
+       /*
+        *      All set, calculate keys!
+        */
+       fr_sim_crypto_keys_init_kdf_0_reauth(&eap_sim_session->keys, mk->vp_octets, counter->vp_uint16);
+       fr_sim_crypto_kdf_0_reauth(&eap_sim_session->keys);
+       if (RDEBUG_ENABLED3) fr_sim_crypto_keys_log(request, &eap_sim_session->keys);
 
-       MEM(vp = fr_pair_afrom_child_num(packet, dict_sim_root, FR_EAP_SIM_RAND));
-       fr_pair_value_memcpy(vp, eap_sim_session->keys.gsm.vector[2].rand, SIM_VECTOR_GSM_RAND_SIZE);
-       fr_pair_add(to_peer, vp);
+       RDEBUG2("Sending SIM-Reauthentication");
+       eap_session->this_round->request->code = FR_EAP_CODE_REQUEST;
 
        /*
         *      Set subtype to challenge.
         */
        vp = fr_pair_afrom_child_num(packet, dict_sim_root, FR_EAP_SIM_SUBTYPE);
-       vp->vp_uint16 = EAP_SIM_CHALLENGE;
+       vp->vp_uint16 = EAP_SIM_REAUTH;
+       fr_pair_replace(to_peer, vp);
+
+       /*
+        *      Add nonce_s
+        */
+       MEM(vp = fr_pair_afrom_child_num(packet, dict_sim_root, FR_EAP_SIM_NONCE_S));
+       fr_pair_value_memcpy(vp, eap_sim_session->keys.reauth.nonce_s, sizeof(eap_sim_session->keys.reauth.nonce_s));
        fr_pair_replace(to_peer, vp);
 
        /*
@@ -382,8 +391,7 @@ static int eap_sim_send_reauthentication(eap_session_t *eap_session)
        /*
         *      Encode the packet
         */
-       if (eap_sim_compose(eap_session,
-                           eap_sim_session->keys.gsm.nonce_mt, sizeof(eap_sim_session->keys.gsm.nonce_mt)) < 0) {
+       if (eap_sim_compose(eap_session, NULL, 0) < 0) {
                fr_pair_list_free(&packet->vps);
                return -1;
        }
@@ -558,6 +566,7 @@ static void eap_sim_state_enter(eap_session_t *eap_session, eap_sim_server_state
         *      Send our version list
         */
        case EAP_SIM_SERVER_START:
+       start:
                if (eap_sim_send_start(eap_session) < 0) {
                notify_failure:
                        eap_sim_state_enter(eap_session, EAP_SIM_SERVER_FAILURE_NOTIFICATION);
@@ -572,6 +581,10 @@ static void eap_sim_state_enter(eap_session_t *eap_session, eap_sim_server_state
                if (eap_sim_send_challenge(eap_session) < 0) goto notify_failure;
                break;
 
+       case EAP_SIM_SERVER_REAUTHENTICATE:
+               if (eap_sim_send_reauthentication(eap_session) < 0) goto start;
+               break;
+
        /*
         *      Sent a protected success notification
         */