lib: accept larger input to md5/hmac/sha256/sha512 functions

Avoid unchecked data conversions from size_t to unsigned int.

Reported-by: James Fuller
Closes #21174
This commit is contained in:
Daniel Stenberg 2026-03-31 11:22:34 +02:00
parent 1570091f10
commit dd7fcd581f
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
7 changed files with 41 additions and 20 deletions

View file

@ -57,14 +57,14 @@ struct HMAC_context {
struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams, struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
const unsigned char *key, const unsigned char *key,
unsigned int keylen); unsigned int keylen);
int Curl_HMAC_update(struct HMAC_context *ctxt, void Curl_HMAC_update(struct HMAC_context *ctxt,
const unsigned char *data, const unsigned char *data,
unsigned int len); unsigned int len);
int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output); int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output);
CURLcode Curl_hmacit(const struct HMAC_params *hashparams, CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
const unsigned char *key, const size_t keylen, const unsigned char *key, const size_t keylen,
const unsigned char *data, const size_t datalen, const unsigned char *data, size_t datalen,
unsigned char *output); unsigned char *output);
#endif #endif

View file

@ -54,7 +54,7 @@ extern const struct MD5_params Curl_DIGEST_MD5;
extern const struct HMAC_params Curl_HMAC_MD5; extern const struct HMAC_params Curl_HMAC_MD5;
CURLcode Curl_md5it(unsigned char *output, const unsigned char *input, CURLcode Curl_md5it(unsigned char *output, const unsigned char *input,
const size_t len); size_t len);
struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params); struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
CURLcode Curl_MD5_update(struct MD5_context *context, CURLcode Curl_MD5_update(struct MD5_context *context,

View file

@ -38,7 +38,7 @@ extern const struct HMAC_params Curl_HMAC_SHA256;
#endif #endif
CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input, CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input,
const size_t len); size_t len);
#endif #endif

View file

@ -202,8 +202,13 @@ static CURLcode Curl_sha512_256_update(void *ctx,
const unsigned char *data, const unsigned char *data,
size_t length) size_t length)
{ {
if(wc_Sha512_256Update(ctx, data, (word32)length)) do {
return CURLE_SSL_CIPHER; word32 ilen = (word32) CURLMIN(length, UINT_MAX);
if(wc_Sha512_256Update(ctx, data, ilen))
return CURLE_SSL_CIPHER;
length -= ilen;
data += ilen;
} while(length);
return CURLE_OK; return CURLE_OK;
} }

View file

@ -98,13 +98,12 @@ fail:
return NULL; return NULL;
} }
int Curl_HMAC_update(struct HMAC_context *ctxt, void Curl_HMAC_update(struct HMAC_context *ctxt,
const unsigned char *data, const unsigned char *data,
unsigned int len) unsigned int len)
{ {
/* Update first hash calculation. */ /* Update first hash calculation. */
ctxt->hash->hupdate(ctxt->hashctxt1, data, len); ctxt->hash->hupdate(ctxt->hashctxt1, data, len);
return 0;
} }
int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output) int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output)
@ -143,17 +142,24 @@ int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output)
*/ */
CURLcode Curl_hmacit(const struct HMAC_params *hashparams, CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
const unsigned char *key, const size_t keylen, const unsigned char *key, const size_t keylen,
const unsigned char *data, const size_t datalen, const unsigned char *data, size_t datalen,
unsigned char *output) unsigned char *output)
{ {
struct HMAC_context *ctxt = struct HMAC_context *ctxt;
Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen)); if(keylen > UINT_MAX) /* unlikely to ever happen */
return CURLE_BAD_FUNCTION_ARGUMENT;
ctxt = Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
if(!ctxt) if(!ctxt)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
/* Update the digest with the given challenge */ /* Update the digest with the given challenge */
Curl_HMAC_update(ctxt, data, curlx_uztoui(datalen)); do {
unsigned int ilen = (unsigned int) CURLMIN(datalen, UINT_MAX);
Curl_HMAC_update(ctxt, data, ilen);
datalen -= ilen;
data += ilen;
} while(datalen);
/* Finalise the digest */ /* Finalise the digest */
Curl_HMAC_final(ctxt, output); Curl_HMAC_final(ctxt, output);

View file

@ -540,14 +540,19 @@ const struct MD5_params Curl_DIGEST_MD5 = {
* Returns CURLE_OK on success. * Returns CURLE_OK on success.
*/ */
CURLcode Curl_md5it(unsigned char *output, CURLcode Curl_md5it(unsigned char *output,
const unsigned char *input, const size_t len) const unsigned char *input, size_t len)
{ {
CURLcode result; CURLcode result;
my_md5_ctx ctx; my_md5_ctx ctx;
result = my_md5_init(&ctx); result = my_md5_init(&ctx);
if(!result) { if(!result) {
my_md5_update(&ctx, input, curlx_uztoui(len)); do {
unsigned int ilen = (unsigned int) CURLMIN(len, UINT_MAX);
my_md5_update(&ctx, input, ilen);
input += ilen;
len -= len;
} while(len);
my_md5_final(output, &ctx); my_md5_final(output, &ctx);
} }
return result; return result;

View file

@ -478,14 +478,19 @@ static void my_sha256_final(unsigned char *out, void *ctx)
* Returns CURLE_OK on success. * Returns CURLE_OK on success.
*/ */
CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input, CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input,
const size_t len) size_t len)
{ {
CURLcode result; CURLcode result;
my_sha256_ctx ctx; my_sha256_ctx ctx;
result = my_sha256_init(&ctx); result = my_sha256_init(&ctx);
if(!result) { if(!result) {
my_sha256_update(&ctx, input, curlx_uztoui(len)); do {
unsigned int ilen = (unsigned int) CURLMIN(len, UINT_MAX);
my_sha256_update(&ctx, input, ilen);
len -= ilen;
input += ilen;
} while(len);
my_sha256_final(output, &ctx); my_sha256_final(output, &ctx);
} }
return result; return result;