{
BIO_OK_CTX *ctx;
EVP_MD_CTX *md;
- unsigned long tl = 0;
+ size_t tl = 0;
unsigned char tmp[EVP_MAX_MD_SIZE];
int md_size;
goto berr;
assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
- tl = ctx->buf[0];
- tl <<= 8;
- tl |= ctx->buf[1];
- tl <<= 8;
- tl |= ctx->buf[2];
- tl <<= 8;
- tl |= ctx->buf[3];
-
- if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
+ tl = ((size_t)ctx->buf[0] << 24)
+ | ((size_t)ctx->buf[1] << 16)
+ | ((size_t)ctx->buf[2] << 8)
+ | ((size_t)ctx->buf[3]);
+
+ if (tl > OK_BLOCK_SIZE)
+ goto berr;
+
+ if (tl > SIZE_MAX - OK_BLOCK_BLOCK - (size_t)md_size)
+ goto berr;
+
+ if (ctx->buf_len < tl + OK_BLOCK_BLOCK + (size_t)md_size)
return 1;
if (!EVP_DigestUpdate(md,
goto berr;
if (!EVP_DigestFinal_ex(md, tmp, NULL))
goto berr;
- if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
+ if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, (size_t)md_size) == 0) {
/* there might be parts from next block lurking around ! */
ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
ctx->buf_len_save = ctx->buf_len;