Starting EAP sequence

Michel Verhagen mike at guruce.com
Tue Mar 30 05:53:40 BST 2021


Issue resolved; problem was missing call to eloop_init.

Regards,

Michel Verhagen

On 30/03/2021 17:04, Michel Verhagen wrote:.
> We are running into an issue where calling eapol_sm_init results in a 
> write to a null pointer in dl_list_add:
>
>    static inline void dl_list_add(struct dl_list *list, struct dl_list
>    *item)
>    {
>         item->next = list->next;
>         item->prev = list;
>         list->next->prev = item;
>         list->next = item;
>    }
>
> item->next is null in the above when called from function 
> eloop_register_timeout through macro dl_list_for_each in line 273:
>
>         /* Maintain timeouts in order of increasing time */
>         dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, 
> list) {
>             if (os_reltime_before(&timeout->time, &tmp->time)) {
>                 dl_list_add(tmp->list.prev, &timeout->list);
>                 return 0;
>             }
>         }
>
>    #define dl_list_for_each(item, list, type, member) \
>         for (item = dl_list_entry((list)->next, type, member); \
>              &item->member != (list); \
>              item = dl_list_entry(item->member.next, type, member))
>
>
> So, the code is:
>
>    for (tmp = dl_list_entry((&loop.timeout)->next, struct
>    eloop_timeout, list); \
>              &tmp->list != (&loop.timeout); \
>              tmp = dl_list_entry(tmp->list.next, struct eloop_timeout,
>    list))
>
>
> And eloop.timeout.next is NULL.
>
> We are implementing EAPOL authentication using the hostap eap library 
> and eapol state machine code. We only need EAPOL over wired LAN, so no 
> WPA or WPS needed. Our initialization looks like this:
>
>             if (ERROR_SUCCESS != EAPRegisterMethods())
>                 break;
>
>             os_memset(&_eap_ctx, 0, sizeof(_eap_ctx));
>
>             _eap_ctx.eap_config.identity = (u8 *)os_strdup("Identity");
>             _eap_ctx.eap_config.identity_len = strlen((const
>    char*)_eap_ctx.eap_config.identity);
>             _eap_ctx.eap_config.password = (u8 *)os_strdup("password");
>             _eap_ctx.eap_config.password_len = strlen((const
>    char*)_eap_ctx.eap_config.password);
>             _eap_ctx.eap_config.ca_cert = os_strdup("\\Windows\\ca.pem");
>             //_eap_ctx.eap_config.ca_path = os_strdup("\\Windows");
>             _eap_ctx.eap_config.fragment_size = 1398;
>
>             os_memset(&_eap_cb, 0, sizeof(_eap_cb));
>             _eap_cb.get_config = peer_get_config;
>             _eap_cb.get_bool = (Boolean(__cdecl *)(void *,
>    eapol_bool_var))peer_get_bool;
>             _eap_cb.set_bool = (void(__cdecl *)(void *, eapol_bool_var,
>    Boolean))peer_set_bool;
>             _eap_cb.get_int = peer_get_int;
>             _eap_cb.set_int = peer_set_int;
>             _eap_cb.get_eapReqData = peer_get_eapReqData;
>             _eap_cb.set_config_blob = peer_set_config_blob;
>             _eap_cb.get_config_blob = peer_get_config_blob;
>             _eap_cb.notify_pending = peer_notify_pending;
>
>             os_memset(&_eap_conf, 0, sizeof(_eap_conf));
>             _eap_ctx.eap = eap_peer_sm_init(&_eap_ctx, &_eap_cb,
>    &_eap_ctx, &_eap_conf);
>             if (_eap_ctx.eap == NULL)
>                 break;
>
>             /* Enable "port" to allow authentication */
>             _eap_ctx.portEnabled = true;
>
>             os_memset(&_eapol_ctx, 0, sizeof(_eapol_ctx));
>             _eapol_ctx.ctx = this;                  // This can be
>    pointing to any structure we define as context
>             _eapol_ctx.preauth = 0;                 // Not using IEEE
>    802.11i/RSN pre-authentication
>             _eapol_ctx.cb = NULL;                   // Not using IEEE
>    802.11i/RSN pre-authentication, so no need for this callback
>             _eapol_ctx.cb_ctx = NULL;               // Not using IEEE
>    802.11i/RSN pre-authentication, so no need for context
>             _eapol_ctx.msg_ctx = this;              // Callback context
>    for wpa_msg() calls
>             _eapol_ctx.scard_ctx = NULL;            // Callback context
>    for PC/SC scard_*() function calls
>             _eapol_ctx.eapol_send_ctx = this;       // Callback context
>    for eapol_send() calls
>             _eapol_ctx.eapol_done_cb = eapol_done_cb;
>             _eapol_ctx.eapol_send = eapol_send;
>             _eapol_ctx.set_wep_key = NULL;          // Not using WEP
>             _eapol_ctx.set_config_blob = NULL;
>             _eapol_ctx.get_config_blob = NULL;
>             _eapol_ctx.aborted_cached = NULL;
>
>             _eapol_ctx.opensc_engine_path = NULL;   // No idea what to
>    set here
>             _eapol_ctx.pkcs11_engine_path = NULL;   // No idea what to
>    set here
>             _eapol_ctx.pkcs11_module_path = NULL;   // No idea what to
>    set here
>             _eapol_ctx.openssl_ciphers = NULL;      // No idea what to
>    set here
>
>             _eapol_ctx.wps = NULL;                  // Not using WPS
>
>             _eapol_ctx.eap_param_needed = NULL;     // Not using WEP
>
>             _eapol_ctx.port_cb = port_cb;
>             _eapol_ctx.cert_cb = cert_cb;
>             _eapol_ctx.cert_in_cb = 1;
>             _eapol_ctx.status_cb = status_cb;
>             _eapol_ctx.eap_error_cb = eap_error_cb;
>
>             _eapol_ctx.set_anon_id = NULL;          // Not sure this is
>    needed
>             _eapol_ctx.confirm_auth_cb = NULL;      // Not sure this is
>    needed
>
>             _peapol_sm = eapol_sm_init(&_eapol_ctx);
>             if (!_peapol_sm)
>                 break;
>
>             os_memset(&_eapol_conf, 0, sizeof(_eapol_conf));
>             _eapol_conf.accept_802_1x_keys = 0;
>             _eapol_conf.required_keys = 0;          //
>    EAPOL_REQUIRE_KEY_UNICAST | EAPOL_REQUIRE_KEY_BROADCAST
>             _eapol_conf.fast_reauth = 1;
>             _eapol_conf.workaround = 0;
>             _eapol_conf.eap_disabled = 0;
>             _eapol_conf.external_sim = 0;
>             _eapol_conf.wps = 0;
>             eapol_sm_notify_config(_peapol_sm, &_eap_ctx.eap_config,
>    &_eapol_conf);
>
>    eapol_sm_notify_portValid(_peapol_sm, false);
>    eapol_sm_notify_portEnabled(_peapol_sm, true);
>
>
> As you can see, not everything is clear so I'm probably just missing 
> something. In the above code we don't get past the call to 
> eapol_sm_init. Hope somebody can shed some light or point me in the 
> right direction...
>
> Many thanks in advance!
>
> Regards,
>
> Michel Verhagen
>
> On 12/03/2021 10:10, Michel Verhagen wrote:
>> Thanks Alan!
>>
>> That does make sense indeed. I'll try to use eapol_supp for better 
>> handling of the EAPOL layer on top of EAP. I hope this code can be 
>> used with just the code I ported for the EAP library to compile.
>>
>> Is there any documentation explaining what all the context parameters 
>> do (see test_eapol function in eapol_test.c), which are required and 
>> for which functionality etc? All I need is to implement an EAPOL 
>> client with certificates, so no WPA/WEP or any of the wireless stuff.
>>
>> I'll come back with more questions probably, thanks for pointing me 
>> in the right direction!
>>
>>
>> On 12/03/2021 01:23, Alan DeKok wrote:
>>> On Mar 10, 2021, at 11:56 PM, Michel Verhagen <mike at guruce.com> wrote:
>>>> I'm using the EAP library to implement EAPOL on an embedded device. 
>>>> Got it to go, with EAP-MD5 and EAP-TTLS and certificates, so all 
>>>> good. However, I'm trying to get the library to prepare me an EAPOL 
>>>> START packet. I'd like to initiate the start of the EAP handshake, 
>>>> because depending on the settings of the authenticator, it can take 
>>>> a long time before the EAP handshake sequence is initiated.
>>>    I haven't used the library myself, but the problem, here is 
>>> likely layering.
>>>
>>>    i.e. you're using an EAP library.  EAP runs on EAPoL, PPP, PANA, 
>>> RADIUS, Diameter, ..., where the library just does EAP.
>>>
>>>    EAPoL is managed by the IEEE 802.1X state machine.  Which uses 
>>> EAP, but isn't part of the EAP library.
>>>
>>>> I thought setting _eap_ctx.eapRestart to 1 (true) or even 
>>>> eapTriggerStart to 1 and calling eap_peer_step would get me the 
>>>> packet data to send, but I can't see eapTriggerStart used anywhere 
>>>> in the code.
>>>    See src/eapol_supp/eapol_supp_sm.c, which runs the EAPoL 
>>> supplicant state machine.  It checks eapTriggerStart, and ends up 
>>> calling eapol_sm_txStart().
>>>
>>>> Does anybody know how to get the EAP library to prepare an EAP 
>>>> Start packet?
>>>    You can't.  EAP isn't the same as the Ethernet layer EAPoL state 
>>> machine.
>>>
>>>> I can of course prepare and send that packet myself, but it looks 
>>>> like the EAP library should be able to do this as well...
>>>    No.  The EAP library does EAP.  The 802.1X / supplicant state 
>>> machine does Ethernet, and EAPoL.
>>>
>>>    Alan DeKok.
>>>
>>
>>
>> _______________________________________________
>> Hostap mailing list
>> Hostap at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap
>
>
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap





More information about the Hostap mailing list