diff --git a/crypto/includes/ngtcp2/ngtcp2_crypto.h b/crypto/includes/ngtcp2/ngtcp2_crypto.h index 99d2f68746d71583d070c87d08ea7eabd164c199..1368c368db823fe06fb04014d5e9fc951072918d 100644 --- a/crypto/includes/ngtcp2/ngtcp2_crypto.h +++ b/crypto/includes/ngtcp2/ngtcp2_crypto.h @@ -492,6 +492,21 @@ NGTCP2_EXTERN int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls, ngtcp2_crypto_side side); +/** + * @function + * + * `ngtcp2_crypto_generate_stateless_reset_token` generates a + * stateless reset token using HKDF extraction with |md| using the + * given |cid| and static key |secret| as input. The token will be + * written to the buffer pointed by |token| and it must have a + * capacity of at least NGTCP2_STATELESS_RESET_TOKENLEN bytes. + * + * This function returns 0 if it succeeds, or -1. + */ +NGTCP2_EXTERN int ngtcp2_crypto_generate_stateless_reset_token( + uint8_t *token, const ngtcp2_crypto_md *md, const uint8_t *secret, + size_t secretlen, const ngtcp2_cid *cid); + #ifdef __cplusplus } #endif diff --git a/crypto/shared.c b/crypto/shared.c index 9d5feb602b36b26b2198b0d68810f2f67359ca13..f12736ce6f921976cdf0c953a6bb6bb61e8e4adf 100644 --- a/crypto/shared.c +++ b/crypto/shared.c @@ -25,6 +25,7 @@ #include "shared.h" #include <string.h> +#include <assert.h> #include "ngtcp2_macro.h" @@ -419,3 +420,25 @@ int ngtcp2_crypto_update_key_cb(ngtcp2_conn *conn, uint8_t *rx_secret, } return 0; } + +int ngtcp2_crypto_generate_stateless_reset_token(uint8_t *token, + const ngtcp2_crypto_md *md, + const uint8_t *secret, + size_t secretlen, + const ngtcp2_cid *cid) { + uint8_t buf[64]; + int rv; + + assert(ngtcp2_crypto_md_hashlen(md) <= sizeof(buf)); + assert(NGTCP2_STATELESS_RESET_TOKENLEN <= sizeof(buf)); + + rv = ngtcp2_crypto_hkdf_extract(buf, md, secret, secretlen, cid->data, + cid->datalen); + if (rv != 0) { + return -1; + } + + memcpy(token, buf, NGTCP2_STATELESS_RESET_TOKENLEN); + + return 0; +}