Message ID | 20231012200150.338401-13-prestwoj@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | DPP PKEX Changes | expand |
Hi James, On 10/12/23 15:01, James Prestwood wrote: > --- > src/dpp-util.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++ > src/dpp-util.h | 32 ++++++++ > 2 files changed, 240 insertions(+) > You may want to add some references to the code? i.e. which part corresponds to what section in the spec. > diff --git a/src/dpp-util.c b/src/dpp-util.c > index 0406a4dc..b0556917 100644 > --- a/src/dpp-util.c > +++ b/src/dpp-util.c > @@ -39,6 +39,32 @@ > #include "ell/asn1-private.h" > #include "src/ie.h" > <snip> > + > +struct l_ecc_point *dpp_derive_q(const struct l_ecc_curve *curve, > + bool responder, > + const char *key, > + const char *identifier, > + const uint8_t *mac) Should this use the [static 6] syntax? Or I guess not since mac can be NULL. Why can mac be NULL? We have derive_l_responder and derive_l_initiator, but derive_q has a boolean parameter? Lets be consistent. > +{ > + _auto_(l_ecc_scalar_free) struct l_ecc_scalar *scalar = NULL; > + _auto_(l_ecc_point_free) struct l_ecc_point *ret = NULL; > + uint8_t hash[L_ECC_SCALAR_MAX_BYTES]; > + unsigned int bytes = l_ecc_curve_get_scalar_bytes(curve); > + enum l_checksum_type type = dpp_sha_from_key_len(bytes); > + _auto_(l_ecc_point_free) struct l_ecc_point *p = NULL; > + const uint8_t *p_data = responder ? dpp_pkex_responder_p256 : > + dpp_pkex_initiator_p256; > + struct l_checksum *sha = l_checksum_new(type); > + > + if (mac) > + l_checksum_update(sha, mac, 6); > + > + if (identifier) > + l_checksum_update(sha, identifier, strlen(identifier)); > + > + l_checksum_update(sha, key, strlen(key)); > + l_checksum_get_digest(sha, hash, bytes); > + l_checksum_free(sha); > + > + /* Unlikely but can happen */ > + scalar = l_ecc_scalar_new(curve, hash, bytes); > + if (!scalar) > + return NULL; > + > + p = l_ecc_point_from_data(curve, L_ECC_POINT_TYPE_FULL, > + p_data, bytes * 2); > + if (!p) > + return NULL; > + > + ret = l_ecc_point_new(curve); > + > + if (!l_ecc_point_multiply(ret, scalar, p)) > + return NULL; > + > + return l_steal_ptr(ret); > +} > + > +bool dpp_derive_z(const uint8_t *mac_i, const uint8_t *mac_r, [static 6]? > + const struct l_ecc_point *n, > + const struct l_ecc_point *m, > + const struct l_ecc_point *k, > + const char *key, > + const char *identifier, > + void *z_out, size_t *z_len) > +{ > + const struct l_ecc_curve *curve = l_ecc_point_get_curve(n); > + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); > + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); > + uint8_t k_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t m_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t n_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t prk[L_ECC_SCALAR_MAX_BYTES]; > + > + l_ecc_point_get_x(k, k_x, sizeof(k_x)); > + l_ecc_point_get_x(m, m_x, sizeof(m_x)); > + l_ecc_point_get_x(n, n_x, sizeof(n_x)); > + > + hkdf_extract(sha, NULL, 0, 1, prk, k_x, bytes); > + > + /* HKDF-Extract (since it doesn't take non-string arguments)*/ > + prf_plus(sha, prk, bytes, z_out, bytes, 5, mac_i, 6, mac_r, 6, m_x, > + bytes, n_x, bytes, key, strlen(key)); > + > + *z_len = bytes; > + > + return true; > +} > + > +bool dpp_derive_u(const struct l_ecc_point *j, > + const uint8_t *mac_i, [static 6]? > + const struct l_ecc_point *a, > + const struct l_ecc_point *y, > + const struct l_ecc_point *x, > + void *u_out, size_t *u_len) > +{ > + const struct l_ecc_curve *curve = l_ecc_point_get_curve(y); > + uint8_t j_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t a_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t y_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t x_x[L_ECC_SCALAR_MAX_BYTES]; > + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); > + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); > + struct l_checksum *hmac; > + > + l_ecc_point_get_x(j, j_x, bytes); > + l_ecc_point_get_x(a, a_x, bytes); > + l_ecc_point_get_x(y, y_x, bytes); > + l_ecc_point_get_x(x, x_x, bytes); > + > + /* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x)*/ > + hmac = l_checksum_new_hmac(sha, j_x, bytes); > + l_checksum_update(hmac, mac_i, 6); > + l_checksum_update(hmac, a_x, bytes); > + l_checksum_update(hmac, y_x, bytes); > + l_checksum_update(hmac, x_x, bytes); > + l_checksum_get_digest(hmac, u_out, bytes); > + l_checksum_free(hmac); > + > + *u_len = bytes; > + > + return true; > +} > + > +bool dpp_derive_v(const struct l_ecc_point *l, const uint8_t *mac, And here? > + const struct l_ecc_point *b, > + const struct l_ecc_point *x, > + const struct l_ecc_point *y, > + uint8_t *v_out, size_t *v_len) > +{ > + const struct l_ecc_curve *curve = l_ecc_point_get_curve(l); > + uint8_t l_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t b_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t x_x[L_ECC_SCALAR_MAX_BYTES]; > + uint8_t y_x[L_ECC_SCALAR_MAX_BYTES]; > + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); > + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); > + struct l_checksum *hmac; > + > + l_ecc_point_get_x(l, l_x, sizeof(l_x)); > + l_ecc_point_get_x(b, b_x, sizeof(b_x)); > + l_ecc_point_get_x(x, x_x, sizeof(x_x)); > + l_ecc_point_get_x(y, y_x, sizeof(y_x)); > + > + hmac = l_checksum_new_hmac(sha, l_x, bytes); > + > + if (mac) > + l_checksum_update(hmac, mac, 6); > + > + l_checksum_update(hmac, b_x, bytes); > + l_checksum_update(hmac, x_x, bytes); > + l_checksum_update(hmac, y_x, bytes); > + l_checksum_get_digest(hmac, v_out, bytes); > + l_checksum_free(hmac); > + > + *v_len = bytes; > + > + return true; > +} <snip> Unit tests? Regards, -Denis
Hi Denis, On 10/19/23 8:13 AM, Denis Kenzior wrote: > Hi James, > > On 10/12/23 15:01, James Prestwood wrote: >> --- >> src/dpp-util.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++ >> src/dpp-util.h | 32 ++++++++ >> 2 files changed, 240 insertions(+) >> > > You may want to add some references to the code? i.e. which part > corresponds to what section in the spec. > >> diff --git a/src/dpp-util.c b/src/dpp-util.c >> index 0406a4dc..b0556917 100644 >> --- a/src/dpp-util.c >> +++ b/src/dpp-util.c >> @@ -39,6 +39,32 @@ >> #include "ell/asn1-private.h" >> #include "src/ie.h" > > <snip> > >> + >> +struct l_ecc_point *dpp_derive_q(const struct l_ecc_curve *curve, >> + bool responder, >> + const char *key, >> + const char *identifier, >> + const uint8_t *mac) > > Should this use the [static 6] syntax? Or I guess not since mac can be > NULL. Why can mac be NULL? I'll leave some spec section comments, but PKEX versions use slightly different derivations. I only wanted to support PKEXv1 for now but was more less future proofing to avoid an API change later. > > We have derive_l_responder and derive_l_initiator, but derive_q has a > boolean parameter? Lets be consistent. I'll make a common function and add dpp_derive_q_{responder,initiator}. The original reason for the to "derive_l" APIs was because the derivation is vastly different, where 'q' is basically the same just different ECC points. But I agree, its not consistent. > >> +{ >> + _auto_(l_ecc_scalar_free) struct l_ecc_scalar *scalar = NULL; >> + _auto_(l_ecc_point_free) struct l_ecc_point *ret = NULL; >> + uint8_t hash[L_ECC_SCALAR_MAX_BYTES]; >> + unsigned int bytes = l_ecc_curve_get_scalar_bytes(curve); >> + enum l_checksum_type type = dpp_sha_from_key_len(bytes); >> + _auto_(l_ecc_point_free) struct l_ecc_point *p = NULL; >> + const uint8_t *p_data = responder ? dpp_pkex_responder_p256 : >> + dpp_pkex_initiator_p256; >> + struct l_checksum *sha = l_checksum_new(type); >> + >> + if (mac) >> + l_checksum_update(sha, mac, 6); >> + >> + if (identifier) >> + l_checksum_update(sha, identifier, strlen(identifier)); >> + >> + l_checksum_update(sha, key, strlen(key)); >> + l_checksum_get_digest(sha, hash, bytes); >> + l_checksum_free(sha); >> + >> + /* Unlikely but can happen */ >> + scalar = l_ecc_scalar_new(curve, hash, bytes); >> + if (!scalar) >> + return NULL; >> + >> + p = l_ecc_point_from_data(curve, L_ECC_POINT_TYPE_FULL, >> + p_data, bytes * 2); >> + if (!p) >> + return NULL; >> + >> + ret = l_ecc_point_new(curve); >> + >> + if (!l_ecc_point_multiply(ret, scalar, p)) >> + return NULL; >> + >> + return l_steal_ptr(ret); >> +} >> + >> +bool dpp_derive_z(const uint8_t *mac_i, const uint8_t *mac_r, > > [static 6]? > >> + const struct l_ecc_point *n, >> + const struct l_ecc_point *m, >> + const struct l_ecc_point *k, >> + const char *key, >> + const char *identifier, >> + void *z_out, size_t *z_len) >> +{ >> + const struct l_ecc_curve *curve = l_ecc_point_get_curve(n); >> + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); >> + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); >> + uint8_t k_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t m_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t n_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t prk[L_ECC_SCALAR_MAX_BYTES]; >> + >> + l_ecc_point_get_x(k, k_x, sizeof(k_x)); >> + l_ecc_point_get_x(m, m_x, sizeof(m_x)); >> + l_ecc_point_get_x(n, n_x, sizeof(n_x)); >> + >> + hkdf_extract(sha, NULL, 0, 1, prk, k_x, bytes); >> + >> + /* HKDF-Extract (since it doesn't take non-string arguments)*/ >> + prf_plus(sha, prk, bytes, z_out, bytes, 5, mac_i, 6, mac_r, 6, m_x, >> + bytes, n_x, bytes, key, strlen(key)); >> + >> + *z_len = bytes; >> + >> + return true; >> +} >> + >> +bool dpp_derive_u(const struct l_ecc_point *j, >> + const uint8_t *mac_i, > > [static 6]? > >> + const struct l_ecc_point *a, >> + const struct l_ecc_point *y, >> + const struct l_ecc_point *x, >> + void *u_out, size_t *u_len) >> +{ >> + const struct l_ecc_curve *curve = l_ecc_point_get_curve(y); >> + uint8_t j_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t a_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t y_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t x_x[L_ECC_SCALAR_MAX_BYTES]; >> + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); >> + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); >> + struct l_checksum *hmac; >> + >> + l_ecc_point_get_x(j, j_x, bytes); >> + l_ecc_point_get_x(a, a_x, bytes); >> + l_ecc_point_get_x(y, y_x, bytes); >> + l_ecc_point_get_x(x, x_x, bytes); >> + >> + /* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x)*/ >> + hmac = l_checksum_new_hmac(sha, j_x, bytes); >> + l_checksum_update(hmac, mac_i, 6); >> + l_checksum_update(hmac, a_x, bytes); >> + l_checksum_update(hmac, y_x, bytes); >> + l_checksum_update(hmac, x_x, bytes); >> + l_checksum_get_digest(hmac, u_out, bytes); >> + l_checksum_free(hmac); >> + >> + *u_len = bytes; >> + >> + return true; >> +} >> + >> +bool dpp_derive_v(const struct l_ecc_point *l, const uint8_t *mac, > > And here? > >> + const struct l_ecc_point *b, >> + const struct l_ecc_point *x, >> + const struct l_ecc_point *y, >> + uint8_t *v_out, size_t *v_len) >> +{ >> + const struct l_ecc_curve *curve = l_ecc_point_get_curve(l); >> + uint8_t l_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t b_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t x_x[L_ECC_SCALAR_MAX_BYTES]; >> + uint8_t y_x[L_ECC_SCALAR_MAX_BYTES]; >> + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); >> + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); >> + struct l_checksum *hmac; >> + >> + l_ecc_point_get_x(l, l_x, sizeof(l_x)); >> + l_ecc_point_get_x(b, b_x, sizeof(b_x)); >> + l_ecc_point_get_x(x, x_x, sizeof(x_x)); >> + l_ecc_point_get_x(y, y_x, sizeof(y_x)); >> + >> + hmac = l_checksum_new_hmac(sha, l_x, bytes); >> + >> + if (mac) >> + l_checksum_update(hmac, mac, 6); >> + >> + l_checksum_update(hmac, b_x, bytes); >> + l_checksum_update(hmac, x_x, bytes); >> + l_checksum_update(hmac, y_x, bytes); >> + l_checksum_get_digest(hmac, v_out, bytes); >> + l_checksum_free(hmac); >> + >> + *v_len = bytes; >> + >> + return true; >> +} > > <snip> > > Unit tests? > > Regards, > -Denis >
diff --git a/src/dpp-util.c b/src/dpp-util.c index 0406a4dc..b0556917 100644 --- a/src/dpp-util.c +++ b/src/dpp-util.c @@ -39,6 +39,32 @@ #include "ell/asn1-private.h" #include "src/ie.h" +static const uint8_t dpp_pkex_initiator_p256[64] = { + /* X */ + 0x56, 0x26, 0x12, 0xcf, 0x36, 0x48, 0xfe, 0x0b, + 0x07, 0x04, 0xbb, 0x12, 0x22, 0x50, 0xb2, 0x54, + 0xb1, 0x94, 0x64, 0x7e, 0x54, 0xce, 0x08, 0x07, + 0x2e, 0xec, 0xca, 0x74, 0x5b, 0x61, 0x2d, 0x25, + /* Y */ + 0x3e, 0x44, 0xc7, 0xc9, 0x8c, 0x1c, 0xa1, 0x0b, + 0x20, 0x09, 0x93, 0xb2, 0xfd, 0xe5, 0x69, 0xdc, + 0x75, 0xbc, 0xad, 0x33, 0xc1, 0xe7, 0xc6, 0x45, + 0x4d, 0x10, 0x1e, 0x6a, 0x3d, 0x84, 0x3c, 0xa4 +}; + +static const uint8_t dpp_pkex_responder_p256[64] = { + /* X */ + 0x1e, 0xa4, 0x8a, 0xb1, 0xa4, 0xe8, 0x42, 0x39, + 0xad, 0x73, 0x07, 0xf2, 0x34, 0xdf, 0x57, 0x4f, + 0xc0, 0x9d, 0x54, 0xbe, 0x36, 0x1b, 0x31, 0x0f, + 0x59, 0x91, 0x52, 0x33, 0xac, 0x19, 0x9d, 0x76, + /* Y */ + 0xd9, 0xfb, 0xf6, 0xb9, 0xf5, 0xfa, 0xdf, 0x19, + 0x58, 0xd8, 0x3e, 0xc9, 0x89, 0x7a, 0x35, 0xc1, + 0xbd, 0xe9, 0x0b, 0x77, 0x7a, 0xcb, 0x91, 0x2a, + 0xe8, 0x21, 0x3f, 0x47, 0x52, 0x02, 0x4d, 0x67 +}; + static void append_freqs(struct l_string *uri, const uint32_t *freqs, size_t len) { @@ -1134,3 +1160,185 @@ void dpp_free_uri_info(struct dpp_uri_info *info) l_free(info); } + +struct l_ecc_point *dpp_derive_l_initiator( + const struct l_ecc_point *boot_public, + const struct l_ecc_point *proto_public, + const struct l_ecc_scalar *boot_private) +{ + const struct l_ecc_curve *curve = l_ecc_point_get_curve(boot_public); + struct l_ecc_point *ret = l_ecc_point_new(curve); + + l_ecc_point_add(ret, boot_public, proto_public); + l_ecc_point_multiply(ret, boot_private, ret); + + return ret; +} + +struct l_ecc_point *dpp_derive_l_responder( + const struct l_ecc_scalar *boot_private, + const struct l_ecc_scalar *proto_private, + const struct l_ecc_point *peer_public) +{ + const struct l_ecc_curve *curve = l_ecc_point_get_curve(peer_public); + _auto_(l_ecc_scalar_free) struct l_ecc_scalar *order = + l_ecc_curve_get_order(curve); + _auto_(l_ecc_scalar_free) struct l_ecc_scalar *sum = + l_ecc_scalar_new(curve, NULL, 0); + _auto_(l_ecc_point_free) struct l_ecc_point *ret = + l_ecc_point_new(curve); + + if (!l_ecc_scalar_add(sum, boot_private, proto_private, order)) + return NULL; + + if (!l_ecc_point_multiply(ret, sum, peer_public)) + return NULL; + + return l_steal_ptr(ret); +} + +struct l_ecc_point *dpp_derive_q(const struct l_ecc_curve *curve, + bool responder, + const char *key, + const char *identifier, + const uint8_t *mac) +{ + _auto_(l_ecc_scalar_free) struct l_ecc_scalar *scalar = NULL; + _auto_(l_ecc_point_free) struct l_ecc_point *ret = NULL; + uint8_t hash[L_ECC_SCALAR_MAX_BYTES]; + unsigned int bytes = l_ecc_curve_get_scalar_bytes(curve); + enum l_checksum_type type = dpp_sha_from_key_len(bytes); + _auto_(l_ecc_point_free) struct l_ecc_point *p = NULL; + const uint8_t *p_data = responder ? dpp_pkex_responder_p256 : + dpp_pkex_initiator_p256; + struct l_checksum *sha = l_checksum_new(type); + + if (mac) + l_checksum_update(sha, mac, 6); + + if (identifier) + l_checksum_update(sha, identifier, strlen(identifier)); + + l_checksum_update(sha, key, strlen(key)); + l_checksum_get_digest(sha, hash, bytes); + l_checksum_free(sha); + + /* Unlikely but can happen */ + scalar = l_ecc_scalar_new(curve, hash, bytes); + if (!scalar) + return NULL; + + p = l_ecc_point_from_data(curve, L_ECC_POINT_TYPE_FULL, + p_data, bytes * 2); + if (!p) + return NULL; + + ret = l_ecc_point_new(curve); + + if (!l_ecc_point_multiply(ret, scalar, p)) + return NULL; + + return l_steal_ptr(ret); +} + +bool dpp_derive_z(const uint8_t *mac_i, const uint8_t *mac_r, + const struct l_ecc_point *n, + const struct l_ecc_point *m, + const struct l_ecc_point *k, + const char *key, + const char *identifier, + void *z_out, size_t *z_len) +{ + const struct l_ecc_curve *curve = l_ecc_point_get_curve(n); + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); + uint8_t k_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t m_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t n_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t prk[L_ECC_SCALAR_MAX_BYTES]; + + l_ecc_point_get_x(k, k_x, sizeof(k_x)); + l_ecc_point_get_x(m, m_x, sizeof(m_x)); + l_ecc_point_get_x(n, n_x, sizeof(n_x)); + + hkdf_extract(sha, NULL, 0, 1, prk, k_x, bytes); + + /* HKDF-Extract (since it doesn't take non-string arguments)*/ + prf_plus(sha, prk, bytes, z_out, bytes, 5, mac_i, 6, mac_r, 6, m_x, + bytes, n_x, bytes, key, strlen(key)); + + *z_len = bytes; + + return true; +} + +bool dpp_derive_u(const struct l_ecc_point *j, + const uint8_t *mac_i, + const struct l_ecc_point *a, + const struct l_ecc_point *y, + const struct l_ecc_point *x, + void *u_out, size_t *u_len) +{ + const struct l_ecc_curve *curve = l_ecc_point_get_curve(y); + uint8_t j_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t a_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t y_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t x_x[L_ECC_SCALAR_MAX_BYTES]; + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); + struct l_checksum *hmac; + + l_ecc_point_get_x(j, j_x, bytes); + l_ecc_point_get_x(a, a_x, bytes); + l_ecc_point_get_x(y, y_x, bytes); + l_ecc_point_get_x(x, x_x, bytes); + + /* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x)*/ + hmac = l_checksum_new_hmac(sha, j_x, bytes); + l_checksum_update(hmac, mac_i, 6); + l_checksum_update(hmac, a_x, bytes); + l_checksum_update(hmac, y_x, bytes); + l_checksum_update(hmac, x_x, bytes); + l_checksum_get_digest(hmac, u_out, bytes); + l_checksum_free(hmac); + + *u_len = bytes; + + return true; +} + +bool dpp_derive_v(const struct l_ecc_point *l, const uint8_t *mac, + const struct l_ecc_point *b, + const struct l_ecc_point *x, + const struct l_ecc_point *y, + uint8_t *v_out, size_t *v_len) +{ + const struct l_ecc_curve *curve = l_ecc_point_get_curve(l); + uint8_t l_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t b_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t x_x[L_ECC_SCALAR_MAX_BYTES]; + uint8_t y_x[L_ECC_SCALAR_MAX_BYTES]; + size_t bytes = l_ecc_curve_get_scalar_bytes(curve); + enum l_checksum_type sha = dpp_sha_from_key_len(bytes); + struct l_checksum *hmac; + + l_ecc_point_get_x(l, l_x, sizeof(l_x)); + l_ecc_point_get_x(b, b_x, sizeof(b_x)); + l_ecc_point_get_x(x, x_x, sizeof(x_x)); + l_ecc_point_get_x(y, y_x, sizeof(y_x)); + + hmac = l_checksum_new_hmac(sha, l_x, bytes); + + if (mac) + l_checksum_update(hmac, mac, 6); + + l_checksum_update(hmac, b_x, bytes); + l_checksum_update(hmac, x_x, bytes); + l_checksum_update(hmac, y_x, bytes); + l_checksum_get_digest(hmac, v_out, bytes); + l_checksum_free(hmac); + + *v_len = bytes; + + return true; +} diff --git a/src/dpp-util.h b/src/dpp-util.h index 96711c35..6b00796e 100644 --- a/src/dpp-util.h +++ b/src/dpp-util.h @@ -183,3 +183,35 @@ struct l_ecc_point *dpp_point_from_asn1(const uint8_t *asn1, size_t len); struct dpp_uri_info *dpp_parse_uri(const char *uri); void dpp_free_uri_info(struct dpp_uri_info *info); + +struct l_ecc_point *dpp_derive_q(const struct l_ecc_curve *curve, + bool responder, + const char *key, + const char *identifier, + const uint8_t *mac); +struct l_ecc_point *dpp_derive_l_initiator( + const struct l_ecc_point *boot_public, + const struct l_ecc_point *proto_public, + const struct l_ecc_scalar *boot_private); +struct l_ecc_point *dpp_derive_l_responder( + const struct l_ecc_scalar *boot_private, + const struct l_ecc_scalar *proto_private, + const struct l_ecc_point *peer_public); +bool dpp_derive_z(const uint8_t *mac_i, const uint8_t *mac_r, + const struct l_ecc_point *n, + const struct l_ecc_point *m, + const struct l_ecc_point *k, + const char *key, + const char *identifier, + void *z_out, size_t *z_len); +bool dpp_derive_u(const struct l_ecc_point *j, + const uint8_t *mac_i, + const struct l_ecc_point *a, + const struct l_ecc_point *y, + const struct l_ecc_point *x, + void *u_out, size_t *u_len); +bool dpp_derive_v(const struct l_ecc_point *l, const uint8_t *mac, + const struct l_ecc_point *b, + const struct l_ecc_point *x, + const struct l_ecc_point *y, + uint8_t *v_out, size_t *v_len);