eap-pwd: update to use ELL ECC API's
This commit is contained in:
parent
12189fcf39
commit
1d66ee0dd5
233
src/eap-pwd.c
233
src/eap-pwd.c
|
@ -24,13 +24,14 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <ell/ell.h>
|
#include <ell/ell.h>
|
||||||
|
|
||||||
#include "eap.h"
|
#include "eap.h"
|
||||||
#include "eap-private.h"
|
#include "eap-private.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ecc.h"
|
|
||||||
|
|
||||||
#define EAP_PWD_GROUP_DESC 19
|
#define EAP_PWD_GROUP_DESC 19
|
||||||
#define EAP_PWD_RAND_FN 0x01
|
#define EAP_PWD_RAND_FN 0x01
|
||||||
|
@ -66,13 +67,14 @@ struct eap_pwd_handle {
|
||||||
enum eap_pwd_prep prep;
|
enum eap_pwd_prep prep;
|
||||||
char *identity;
|
char *identity;
|
||||||
char *password;
|
char *password;
|
||||||
struct ecc_point pwe;
|
const struct l_ecc_curve *curve;
|
||||||
struct ecc_point element_s;
|
struct l_ecc_point *pwe;
|
||||||
struct ecc_point element_p;
|
struct l_ecc_point *element_s;
|
||||||
|
struct l_ecc_point *element_p;
|
||||||
uint32_t ciphersuite;
|
uint32_t ciphersuite;
|
||||||
uint64_t scalar_s[NUM_ECC_DIGITS];
|
struct l_ecc_scalar *scalar_s;
|
||||||
uint64_t scalar_p[NUM_ECC_DIGITS];
|
struct l_ecc_scalar *scalar_p;
|
||||||
uint64_t p_rand[NUM_ECC_DIGITS];
|
struct l_ecc_scalar *p_rand;
|
||||||
uint8_t *rx_frag_buf;
|
uint8_t *rx_frag_buf;
|
||||||
uint16_t rx_frag_total;
|
uint16_t rx_frag_total;
|
||||||
uint16_t rx_frag_count;
|
uint16_t rx_frag_count;
|
||||||
|
@ -81,8 +83,6 @@ struct eap_pwd_handle {
|
||||||
uint16_t tx_frag_remaining;
|
uint16_t tx_frag_remaining;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint64_t curve_p[NUM_ECC_DIGITS] = CURVE_P_32;
|
|
||||||
|
|
||||||
/* RFC 5931, Section 2.5 - Key Derivation Function */
|
/* RFC 5931, Section 2.5 - Key Derivation Function */
|
||||||
static bool kdf(uint8_t *key, size_t key_len, const char *label,
|
static bool kdf(uint8_t *key, size_t key_len, const char *label,
|
||||||
size_t label_len, void *out, size_t olen)
|
size_t label_len, void *out, size_t olen)
|
||||||
|
@ -144,13 +144,20 @@ static bool eap_pwd_reset_state(struct eap_state *eap)
|
||||||
pwd->rx_frag_total = 0;
|
pwd->rx_frag_total = 0;
|
||||||
|
|
||||||
pwd->prep = EAP_PWD_PREP_NONE;
|
pwd->prep = EAP_PWD_PREP_NONE;
|
||||||
memset(&pwd->pwe, 0, sizeof(struct ecc_point));
|
|
||||||
memset(&pwd->element_s, 0, sizeof(struct ecc_point));
|
|
||||||
memset(&pwd->element_p, 0, sizeof(struct ecc_point));
|
|
||||||
pwd->ciphersuite = 0;
|
pwd->ciphersuite = 0;
|
||||||
memset(pwd->scalar_s, 0, sizeof(pwd->scalar_s));
|
|
||||||
memset(pwd->scalar_p, 0, sizeof(pwd->scalar_p));
|
l_ecc_point_free(pwd->pwe);
|
||||||
memset(pwd->p_rand, 0, sizeof(pwd->p_rand));
|
pwd->pwe = NULL;
|
||||||
|
l_ecc_point_free(pwd->element_p);
|
||||||
|
pwd->element_p = NULL;
|
||||||
|
l_ecc_point_free(pwd->element_s);
|
||||||
|
pwd->element_s = NULL;
|
||||||
|
l_ecc_scalar_free(pwd->scalar_p);
|
||||||
|
pwd->scalar_p = NULL;
|
||||||
|
l_ecc_scalar_free(pwd->scalar_s);
|
||||||
|
pwd->scalar_s = NULL;
|
||||||
|
l_ecc_scalar_free(pwd->p_rand);
|
||||||
|
pwd->p_rand = NULL;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -225,9 +232,8 @@ static void eap_pwd_handle_id(struct eap_state *eap,
|
||||||
uint8_t counter = 1;
|
uint8_t counter = 1;
|
||||||
uint8_t resp[15 + strlen(pwd->identity)];
|
uint8_t resp[15 + strlen(pwd->identity)];
|
||||||
uint8_t *pos;
|
uint8_t *pos;
|
||||||
uint8_t pwd_seed[ECC_BYTES];
|
uint8_t pwd_seed[32];
|
||||||
uint64_t pwd_value[NUM_ECC_DIGITS]; /* used as X value */
|
uint8_t pwd_value[32]; /* used as X value */
|
||||||
uint64_t y_value[NUM_ECC_DIGITS];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Group desc (2) + Random func (1) + prf (1) + token (4) + prep (1) +
|
* Group desc (2) + Random func (1) + prf (1) + token (4) + prep (1) +
|
||||||
|
@ -246,7 +252,12 @@ static void eap_pwd_handle_id(struct eap_state *eap,
|
||||||
pwd->state = EAP_PWD_STATE_ID;
|
pwd->state = EAP_PWD_STATE_ID;
|
||||||
|
|
||||||
group = l_get_be16(pkt);
|
group = l_get_be16(pkt);
|
||||||
if (group != EAP_PWD_GROUP_DESC) {
|
/* TODO: for now, lets only allow group 19 */
|
||||||
|
if (group != EAP_PWD_GROUP_DESC)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
pwd->curve = l_ecc_curve_get(group);
|
||||||
|
if (!pwd->curve) {
|
||||||
l_error("group %d not supported", group);
|
l_error("group %d not supported", group);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -295,23 +306,17 @@ static void eap_pwd_handle_id(struct eap_state *eap,
|
||||||
strlen("EAP-pwd Hunting And Pecking"),
|
strlen("EAP-pwd Hunting And Pecking"),
|
||||||
pwd_value, 32);
|
pwd_value, 32);
|
||||||
|
|
||||||
ecc_be2native(pwd_value);
|
if (!(pwd_seed[31] & 1))
|
||||||
|
pwd->pwe = l_ecc_point_from_data(pwd->curve,
|
||||||
if (ecc_compute_y(y_value, pwd_value)) {
|
L_ECC_POINT_TYPE_COMPRESSED_BIT1,
|
||||||
l_info("computed y in %u tries", counter);
|
pwd_value, 32);
|
||||||
|
else
|
||||||
/* unambiguously choose Y coordinate */
|
pwd->pwe = l_ecc_point_from_data(pwd->curve,
|
||||||
if ((y_value[0] & 1) != (pwd_seed[31] & 1))
|
L_ECC_POINT_TYPE_COMPRESSED_BIT0,
|
||||||
vli_mod_sub(y_value, curve_p, y_value, curve_p);
|
pwd_value, 32);
|
||||||
|
|
||||||
memcpy(pwd->pwe.x, pwd_value, 32);
|
|
||||||
memcpy(pwd->pwe.y, y_value, 32);
|
|
||||||
|
|
||||||
if (!ecc_valid_point(&pwd->pwe))
|
|
||||||
goto invalid_point;
|
|
||||||
|
|
||||||
|
if (pwd->pwe)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
@ -332,8 +337,6 @@ static void eap_pwd_handle_id(struct eap_state *eap,
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
invalid_point:
|
|
||||||
l_error("point not on curve");
|
|
||||||
error:
|
error:
|
||||||
eap_method_error(eap);
|
eap_method_error(eap);
|
||||||
}
|
}
|
||||||
|
@ -344,9 +347,8 @@ static void eap_pwd_handle_commit(struct eap_state *eap,
|
||||||
struct eap_pwd_handle *pwd = eap_get_data(eap);
|
struct eap_pwd_handle *pwd = eap_get_data(eap);
|
||||||
uint8_t resp[102];
|
uint8_t resp[102];
|
||||||
uint8_t *pos;
|
uint8_t *pos;
|
||||||
uint64_t p_mask[NUM_ECC_DIGITS];
|
struct l_ecc_scalar *p_mask;
|
||||||
uint64_t one[NUM_ECC_DIGITS] = { 1 };
|
struct l_ecc_scalar *order;
|
||||||
uint64_t curve_n[NUM_ECC_DIGITS] = CURVE_N_32;
|
|
||||||
|
|
||||||
if (len != 96) {
|
if (len != 96) {
|
||||||
l_error("bad packet length, expected 96, got %zu", len);
|
l_error("bad packet length, expected 96, got %zu", len);
|
||||||
|
@ -366,68 +368,37 @@ static void eap_pwd_handle_commit(struct eap_state *eap,
|
||||||
* 32 bytes in length (total of 64), leaving the remainder for the
|
* 32 bytes in length (total of 64), leaving the remainder for the
|
||||||
* scalar value (32).
|
* scalar value (32).
|
||||||
*/
|
*/
|
||||||
memcpy(pwd->element_s.x, pkt, ECC_BYTES);
|
pwd->element_s = l_ecc_point_from_data(pwd->curve,
|
||||||
memcpy(pwd->element_s.y, pkt + ECC_BYTES, ECC_BYTES);
|
L_ECC_POINT_TYPE_FULL, pkt, 64);
|
||||||
memcpy(pwd->scalar_s, pkt + 64, ECC_BYTES);
|
if (!pwd->element_s)
|
||||||
|
|
||||||
ecc_be2native(pwd->element_s.x);
|
|
||||||
ecc_be2native(pwd->element_s.y);
|
|
||||||
ecc_be2native(pwd->scalar_s);
|
|
||||||
|
|
||||||
if (!ecc_valid_point(&pwd->element_s))
|
|
||||||
goto invalid_point;
|
goto invalid_point;
|
||||||
|
|
||||||
/*
|
pwd->scalar_s = l_ecc_scalar_new(pwd->curve, (uint8_t *)pkt + 64, 32);
|
||||||
* RFC 5931 Section 2.8.4.1
|
|
||||||
*
|
|
||||||
* chose two random numbers, 1 < s_rand, s_mask < r
|
|
||||||
* compute Scalar_P and Element_P
|
|
||||||
* Scalar_P = (p_rand + p_mask) mod r
|
|
||||||
* Element_P = inv(p_mask * PWE)
|
|
||||||
*/
|
|
||||||
l_getrandom(pwd->p_rand, ECC_BYTES);
|
|
||||||
|
|
||||||
/* ensure 1 < p_rand < r */
|
pwd->p_rand = l_ecc_scalar_new_random(pwd->curve);
|
||||||
while (!((vli_cmp(pwd->p_rand, one) > 0) &&
|
p_mask = l_ecc_scalar_new_random(pwd->curve);
|
||||||
(vli_cmp(pwd->p_rand, curve_n) < 0)))
|
pwd->scalar_p = l_ecc_scalar_new(pwd->curve, NULL, 0);
|
||||||
l_getrandom(pwd->p_rand, ECC_BYTES);
|
|
||||||
|
|
||||||
l_getrandom(p_mask, ECC_BYTES);
|
order = l_ecc_curve_get_order(pwd->curve);
|
||||||
|
|
||||||
/* ensure 1 < p_mask < r */
|
l_ecc_scalar_add(pwd->scalar_p, pwd->p_rand, p_mask, order);
|
||||||
while (!((vli_cmp(p_mask, one) > 0) &&
|
|
||||||
(vli_cmp(p_mask, curve_n) < 0)))
|
|
||||||
l_getrandom(p_mask, ECC_BYTES);
|
|
||||||
|
|
||||||
vli_mod_add(pwd->scalar_p, pwd->p_rand, p_mask, curve_n);
|
l_ecc_scalar_free(order);
|
||||||
|
|
||||||
|
pwd->element_p = l_ecc_point_new(pwd->curve);
|
||||||
/* p_mask * PWE */
|
/* p_mask * PWE */
|
||||||
ecc_point_mult(&pwd->element_p, &pwd->pwe, p_mask, NULL,
|
l_ecc_point_multiply(pwd->element_p, p_mask, pwd->pwe);
|
||||||
vli_num_bits(p_mask));
|
|
||||||
|
|
||||||
if (!ecc_valid_point(&pwd->element_p))
|
l_ecc_scalar_free(p_mask);
|
||||||
goto invalid_point;
|
|
||||||
|
|
||||||
/* inv(p_mask * PWE) */
|
/* inv(p_mask * PWE) */
|
||||||
vli_sub(pwd->element_p.y, curve_p, pwd->element_p.y);
|
l_ecc_point_inverse(pwd->element_p);
|
||||||
|
|
||||||
if (!ecc_valid_point(&pwd->element_p))
|
|
||||||
goto invalid_point;
|
|
||||||
|
|
||||||
/* change peer into to MSB first byte ordering before sending back */
|
|
||||||
ecc_native2be(pwd->element_p.x);
|
|
||||||
ecc_native2be(pwd->element_p.y);
|
|
||||||
ecc_native2be(pwd->scalar_p);
|
|
||||||
|
|
||||||
/* send element_p and scalar_p */
|
/* send element_p and scalar_p */
|
||||||
pos = resp + 5; /* header */
|
pos = resp + 5; /* header */
|
||||||
*pos++ = EAP_PWD_EXCH_COMMIT;
|
*pos++ = EAP_PWD_EXCH_COMMIT;
|
||||||
memcpy(pos, pwd->element_p.x, ECC_BYTES);
|
pos += l_ecc_point_get_data(pwd->element_p, pos, 64);
|
||||||
pos += ECC_BYTES;
|
pos += l_ecc_scalar_get_data(pwd->scalar_p, pos, 32);
|
||||||
memcpy(pos, pwd->element_p.y, ECC_BYTES);
|
|
||||||
pos += ECC_BYTES;
|
|
||||||
memcpy(pos, pwd->scalar_p, ECC_BYTES);
|
|
||||||
pos += ECC_BYTES;
|
|
||||||
|
|
||||||
eap_pwd_send_response(eap, resp, pos - resp);
|
eap_pwd_send_response(eap, resp, pos - resp);
|
||||||
|
|
||||||
|
@ -439,18 +410,26 @@ error:
|
||||||
eap_method_error(eap);
|
eap_method_error(eap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void eap_pwd_handle_confirm(struct eap_state *eap,
|
static void eap_pwd_handle_confirm(struct eap_state *eap,
|
||||||
const uint8_t *pkt, size_t len)
|
const uint8_t *pkt, size_t len)
|
||||||
{
|
{
|
||||||
struct eap_pwd_handle *pwd = eap_get_data(eap);
|
struct eap_pwd_handle *pwd = eap_get_data(eap);
|
||||||
struct ecc_point kp;
|
struct l_ecc_point *kp;
|
||||||
uint8_t resp[38];
|
uint8_t resp[38];
|
||||||
uint8_t *pos;
|
uint8_t *pos;
|
||||||
uint64_t confirm_s[NUM_ECC_DIGITS];
|
uint8_t confirm_s[32];
|
||||||
uint8_t confirm_p[ECC_BYTES];
|
uint8_t confirm_p[32];
|
||||||
uint8_t expected_confirm_s[ECC_BYTES];
|
uint8_t expected_confirm_s[32];
|
||||||
uint8_t mk[32];
|
uint8_t mk[32];
|
||||||
uint8_t msk_emsk[128], session_id[33];
|
uint8_t msk_emsk[128], session_id[33];
|
||||||
|
/* buffers used for the final hash */
|
||||||
|
uint8_t kpx[L_ECC_SCALAR_MAX_BYTES];
|
||||||
|
uint8_t scalar_s[L_ECC_SCALAR_MAX_BYTES];
|
||||||
|
uint8_t scalar_p[L_ECC_SCALAR_MAX_BYTES];
|
||||||
|
uint8_t element_s[L_ECC_POINT_MAX_BYTES];
|
||||||
|
uint8_t element_p[L_ECC_POINT_MAX_BYTES];
|
||||||
|
ssize_t plen, clen;
|
||||||
|
|
||||||
if (len != 32) {
|
if (len != 32) {
|
||||||
l_error("bad packet length");
|
l_error("bad packet length");
|
||||||
|
@ -464,59 +443,72 @@ static void eap_pwd_handle_confirm(struct eap_state *eap,
|
||||||
|
|
||||||
pwd->state = EAP_PWD_STATE_CONFIRM;
|
pwd->state = EAP_PWD_STATE_CONFIRM;
|
||||||
|
|
||||||
memcpy(confirm_s, pkt, ECC_BYTES);
|
memcpy(confirm_s, pkt, 32);
|
||||||
|
|
||||||
|
kp = l_ecc_point_new(pwd->curve);
|
||||||
|
|
||||||
/* compute KP = (p_rand * (Scalar_S * PWE + Element_S)) */
|
/* compute KP = (p_rand * (Scalar_S * PWE + Element_S)) */
|
||||||
ecc_point_mult(&kp, &pwd->pwe, pwd->scalar_s, NULL,
|
l_ecc_point_multiply(kp, pwd->scalar_s, pwd->pwe);
|
||||||
vli_num_bits(pwd->scalar_s));
|
|
||||||
|
|
||||||
if (!ecc_valid_point(&kp))
|
l_ecc_point_add(kp, kp, pwd->element_s);
|
||||||
|
|
||||||
|
l_ecc_point_multiply(kp, pwd->p_rand, kp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We just need to store clen/plen once. Since all these buffers are
|
||||||
|
* created with enough bytes in mind we know these wont fail. Also, all
|
||||||
|
* scalar/point objects were created with the same curve, so it can be
|
||||||
|
* safe to assume the return values will not change from what clen/plen
|
||||||
|
* already are.
|
||||||
|
*/
|
||||||
|
clen = l_ecc_point_get_x(kp, kpx, sizeof(kpx));
|
||||||
|
if (clen < 0)
|
||||||
goto invalid_point;
|
goto invalid_point;
|
||||||
|
|
||||||
ecc_point_add(&kp, &kp, &pwd->element_s);
|
plen = l_ecc_point_get_data(pwd->element_s, element_s,
|
||||||
|
sizeof(element_s));
|
||||||
if (!ecc_valid_point(&kp))
|
if (plen < 0)
|
||||||
goto invalid_point;
|
goto invalid_point;
|
||||||
|
|
||||||
ecc_point_mult(&kp, &kp, pwd->p_rand, NULL, vli_num_bits(pwd->p_rand));
|
if (l_ecc_point_get_data(pwd->element_p, element_p,
|
||||||
|
sizeof(element_p)) < 0)
|
||||||
if (!ecc_valid_point(&kp))
|
|
||||||
goto invalid_point;
|
goto invalid_point;
|
||||||
|
|
||||||
ecc_native2be(kp.x);
|
if (l_ecc_scalar_get_data(pwd->scalar_s, scalar_s,
|
||||||
ecc_native2be(pwd->element_s.x);
|
sizeof(scalar_s)) < 0)
|
||||||
ecc_native2be(pwd->element_s.y);
|
goto invalid_point;
|
||||||
ecc_native2be(pwd->scalar_s);
|
|
||||||
|
if (l_ecc_scalar_get_data(pwd->scalar_p, scalar_p,
|
||||||
|
sizeof(scalar_p)) < 0)
|
||||||
|
goto invalid_point;
|
||||||
|
|
||||||
|
l_ecc_point_free(kp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* compute Confirm_P = H(kp | Element_P | Scalar_P |
|
* compute Confirm_P = H(kp | Element_P | Scalar_P |
|
||||||
* Element_S | Scalar_S | Ciphersuite)
|
* Element_S | Scalar_S | Ciphersuite)
|
||||||
*/
|
*/
|
||||||
hkdf_extract_sha256(NULL, 0, 8, confirm_p, kp.x, ECC_BYTES,
|
hkdf_extract_sha256(NULL, 0, 6, confirm_p, kpx, clen, element_p, plen,
|
||||||
pwd->element_p.x, ECC_BYTES, pwd->element_p.y,
|
scalar_p, clen, element_s, plen, scalar_s,
|
||||||
ECC_BYTES, pwd->scalar_p, ECC_BYTES, pwd->element_s.x,
|
clen, &pwd->ciphersuite, 4);
|
||||||
ECC_BYTES, pwd->element_s.y, ECC_BYTES, pwd->scalar_s,
|
|
||||||
ECC_BYTES, &pwd->ciphersuite, 4);
|
|
||||||
|
|
||||||
hkdf_extract_sha256(NULL, 0, 8, expected_confirm_s, kp.x, ECC_BYTES,
|
hkdf_extract_sha256(NULL, 0, 6, expected_confirm_s, kpx, clen,
|
||||||
pwd->element_s.x, ECC_BYTES, pwd->element_s.y,
|
element_s, plen, scalar_s, clen, element_p,
|
||||||
ECC_BYTES, pwd->scalar_s, ECC_BYTES, pwd->element_p.x,
|
plen, scalar_p, clen, &pwd->ciphersuite, 4);
|
||||||
ECC_BYTES, pwd->element_p.y, ECC_BYTES,
|
|
||||||
pwd->scalar_p, ECC_BYTES, &pwd->ciphersuite, 4);
|
|
||||||
|
|
||||||
if (memcmp(confirm_s, expected_confirm_s, ECC_BYTES)) {
|
if (memcmp(confirm_s, expected_confirm_s, 32)) {
|
||||||
l_error("Confirm_S did not verify");
|
l_error("Confirm_S did not verify");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = resp + 5; /* header */
|
pos = resp + 5; /* header */
|
||||||
*pos++ = EAP_PWD_EXCH_CONFIRM;
|
*pos++ = EAP_PWD_EXCH_CONFIRM;
|
||||||
memcpy(pos, confirm_p, ECC_BYTES);
|
memcpy(pos, confirm_p, 32);
|
||||||
pos += 32;
|
pos += 32;
|
||||||
|
|
||||||
/* derive MK = H(kp | Confirm_P | Confirm_S ) */
|
/* derive MK = H(kp | Confirm_P | Confirm_S ) */
|
||||||
hkdf_extract_sha256(NULL, 0, 3, mk, kp.x, ECC_BYTES, confirm_p,
|
hkdf_extract_sha256(NULL, 0, 3, mk, kpx, clen, confirm_p,
|
||||||
ECC_BYTES, confirm_s, ECC_BYTES);
|
32, confirm_s, 32);
|
||||||
|
|
||||||
eap_pwd_send_response(eap, resp, pos - resp);
|
eap_pwd_send_response(eap, resp, pos - resp);
|
||||||
|
|
||||||
|
@ -524,13 +516,16 @@ static void eap_pwd_handle_confirm(struct eap_state *eap,
|
||||||
|
|
||||||
session_id[0] = 52;
|
session_id[0] = 52;
|
||||||
hkdf_extract_sha256(NULL, 0, 3, session_id + 1, &pwd->ciphersuite, 4,
|
hkdf_extract_sha256(NULL, 0, 3, session_id + 1, &pwd->ciphersuite, 4,
|
||||||
pwd->scalar_p, ECC_BYTES, pwd->scalar_s, ECC_BYTES);
|
scalar_p, clen, scalar_s, clen);
|
||||||
|
|
||||||
kdf(mk, 32, (const char *) session_id, 33, msk_emsk, 128);
|
kdf(mk, 32, (const char *) session_id, 33, msk_emsk, 128);
|
||||||
eap_set_key_material(eap, msk_emsk, 64, msk_emsk + 64, 64, NULL, 0);
|
eap_set_key_material(eap, msk_emsk, 64, msk_emsk + 64, 64, NULL, 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
invalid_point:
|
invalid_point:
|
||||||
|
l_ecc_point_free(kp);
|
||||||
|
|
||||||
l_error("invalid point during confirm exchange");
|
l_error("invalid point during confirm exchange");
|
||||||
error:
|
error:
|
||||||
eap_method_error(eap);
|
eap_method_error(eap);
|
||||||
|
|
Loading…
Reference in New Issue