Skip to content

Commit

Permalink
Add new SHAKE EVP_ tests
Browse files Browse the repository at this point in the history
Add new checks Test Update after Squeeze and Test Final XOF after Squeeze

Digest functions restrict the calls to |update| and |final| after |final| is called via |ctx->digest == NULL| check. Digest |final| functions cleanse the |ctx->md_data|, thus, the check on |ctx->digest| would prevent calling |update| or |final| once |final| has been processed; XOF Squeeze, however, does not finalize the squeeze step, thus, does not cleanse the |ctx->md_digest| (as the final digest functions do) since the XOF Squeeze could be called arbitrary number of times. Therefore, the |update| (SHAKE_Squeeze) and |finalXOF| (SHAKE_Final) return 1 on success and 0 on failure, based on the return value of the underlying SHAKE_ function. Internally, the check is performed via the |ctx->state| flag.

The change in the |update| XOF function return value (int, instead of void), all digest |update| functions require a return value. They would always return 1 since a failure would be cought by the higer level EVP_Digest function (i.e., cleansed |ctx| variable
  • Loading branch information
manastasova committed Feb 5, 2025
1 parent 672a67a commit 1280353
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 101 deletions.
5 changes: 3 additions & 2 deletions crypto/digest_extra/digest_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,9 @@ const EVP_MD *EVP_get_digestbyname(const char *name) {

static void blake2b256_init(EVP_MD_CTX *ctx) { BLAKE2B256_Init(ctx->md_data); }

static void blake2b256_update(EVP_MD_CTX *ctx, const void *data, size_t len) {
static int blake2b256_update(EVP_MD_CTX *ctx, const void *data, size_t len) {
BLAKE2B256_Update(ctx->md_data, data, len);
return 1;
}

static void blake2b256_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -279,7 +280,7 @@ const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; }

static void null_init(EVP_MD_CTX *ctx) {}

static void null_update(EVP_MD_CTX *ctx, const void *data, size_t count) {}
static int null_update(EVP_MD_CTX *ctx, const void *data, size_t count) { return 1;}

static void null_final(EVP_MD_CTX *ctx, unsigned char *md) {}

Expand Down
11 changes: 7 additions & 4 deletions crypto/fipsmodule/digest/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { EVP_MD_CTX_free(ctx); }

// EVP_DigestFinalXOF is a single-shot XOF output generation function
// It can be called once. On sequential calls, it returns 0.
// The |ctx->digest| check prevents calling EVP_DigestFinalXOF consecutively.
// To catch single-shot XOF EVP_DigestFinalXOF calls after |EVP_DigestSqueeze|,
// the return |SHAKE_Final| value is used (the check is internally performed via
// the |KECCAK1600_CTX *ctx| state flag).
int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, size_t len) {
if (ctx->digest == NULL) {
return 0;
Expand All @@ -145,9 +149,9 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, size_t len) {
OPENSSL_PUT_ERROR(DIGEST, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
ctx->digest->finalXOF(ctx, out, len);
int ok = ctx->digest->finalXOF(ctx, out, len);
EVP_MD_CTX_cleanse(ctx);
return 1;
return ok;
}

// EVP_DigestSqueeze is a streaming XOF output generation function
Expand Down Expand Up @@ -290,8 +294,7 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
if (ctx->update == NULL) {
return 0;
}
ctx->update(ctx, data, len);
return 1;
return ctx->update(ctx, data, len);;
}

int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) {
Expand Down
80 changes: 56 additions & 24 deletions crypto/fipsmodule/digest/digests.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ static void md4_init(EVP_MD_CTX *ctx) {
CHECK(MD4_Init(ctx->md_data));
}

static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(MD4_Update(ctx->md_data, data, count));
return 1;
}

static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) {
Expand All @@ -106,8 +107,9 @@ static void md5_init(EVP_MD_CTX *ctx) {
CHECK(MD5_Init(ctx->md_data));
}

static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(MD5_Update(ctx->md_data, data, count));
return 1;
}

static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) {
Expand All @@ -132,8 +134,9 @@ static void ripemd160_init(EVP_MD_CTX *ctx) {
CHECK(RIPEMD160_Init(ctx->md_data));
}

static void ripemd160_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int ripemd160_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(RIPEMD160_Update(ctx->md_data, data, count));
return 1;
}

static void ripemd160_final(EVP_MD_CTX *ctx, uint8_t *out) {
Expand All @@ -158,8 +161,9 @@ static void sha1_init(EVP_MD_CTX *ctx) {
CHECK(SHA1_Init(ctx->md_data));
}

static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA1_Update(ctx->md_data, data, count));
return 1;
}

static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -184,8 +188,9 @@ static void sha224_init(EVP_MD_CTX *ctx) {
CHECK(SHA224_Init(ctx->md_data));
}

static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA224_Update(ctx->md_data, data, count));
return 1;
}

static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -210,8 +215,9 @@ static void sha256_init(EVP_MD_CTX *ctx) {
CHECK(SHA256_Init(ctx->md_data));
}

static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA256_Update(ctx->md_data, data, count));
return 1;
}

static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -236,8 +242,9 @@ static void sha384_init(EVP_MD_CTX *ctx) {
CHECK(SHA384_Init(ctx->md_data));
}

static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA384_Update(ctx->md_data, data, count));
return 1;
}

static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -262,8 +269,9 @@ static void sha512_init(EVP_MD_CTX *ctx) {
CHECK(SHA512_Init(ctx->md_data));
}

static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA512_Update(ctx->md_data, data, count));
return 1;
}

static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -288,8 +296,9 @@ static void sha512_224_init(EVP_MD_CTX *ctx) {
CHECK(SHA512_224_Init(ctx->md_data));
}

static void sha512_224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha512_224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA512_224_Update(ctx->md_data, data, count));
return 1;
}

static void sha512_224_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -312,8 +321,9 @@ static void sha512_256_init(EVP_MD_CTX *ctx) {
CHECK(SHA512_256_Init(ctx->md_data));
}

static void sha512_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha512_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA512_256_Update(ctx->md_data, data, count));
return 1;
}

static void sha512_256_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -338,8 +348,9 @@ static void sha3_224_init(EVP_MD_CTX *ctx) {
CHECK(SHA3_Init(ctx->md_data, SHA3_224_DIGEST_BITLENGTH));
}

static void sha3_224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha3_224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA3_Update(ctx->md_data, data, count));
return 1;
}

static void sha3_224_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -364,8 +375,9 @@ static void sha3_256_init(EVP_MD_CTX *ctx) {
CHECK(SHA3_Init(ctx->md_data, SHA3_256_DIGEST_BITLENGTH));
}

static void sha3_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha3_256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA3_Update(ctx->md_data, data, count));
return 1;
}

static void sha3_256_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -390,8 +402,9 @@ static void sha3_384_init(EVP_MD_CTX *ctx) {
CHECK(SHA3_Init(ctx->md_data, SHA3_384_DIGEST_BITLENGTH));
}

static void sha3_384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha3_384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA3_Update(ctx->md_data, data, count));
return 1;
}

static void sha3_384_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -416,8 +429,9 @@ static void sha3_512_init(EVP_MD_CTX *ctx) {
CHECK(SHA3_Init(ctx->md_data, SHA3_512_DIGEST_BITLENGTH));
}

static void sha3_512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int sha3_512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHA3_Update(ctx->md_data, data, count));
return 1;
}

static void sha3_512_final(EVP_MD_CTX *ctx, uint8_t *md) {
Expand All @@ -442,12 +456,21 @@ static void shake128_init(EVP_MD_CTX *ctx) {
CHECK(SHAKE_Init(ctx->md_data, SHAKE128_BLOCKSIZE));
}

static void shake128_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHAKE_Absorb(ctx->md_data, data, count));
// Digest XOF functions return 1 on seccess and 0 on failure, returned
// from |SHAKE_Absorb|, to restrict update calls after |squeezeXOF|.
static int shake128_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
int ok;
CHECK((ok = SHAKE_Absorb(ctx->md_data, data, count)));
return ok;
}

static void shake128_final(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
CHECK(SHAKE_Final(md, ctx->md_data, len));
// Digest XOF functions return 1 on seccess and 0 on failure,
// returned from |SHAKE_Final|, to restrict Signle-Shot SHAKE_Final
// calls after |squeezeXOF|.
static int shake128_final(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
int ok;
CHECK((ok = SHAKE_Final(md, ctx->md_data, len)));
return ok;
}

static void shake128_squeeze(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
Expand All @@ -467,17 +490,25 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_shake128) {
out->ctx_size = sizeof(KECCAK1600_CTX);
}


static void shake256_init(EVP_MD_CTX *ctx) {
CHECK(SHAKE_Init(ctx->md_data, SHAKE256_BLOCKSIZE));
}

static void shake256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
CHECK(SHAKE_Absorb(ctx->md_data, data, count));
// Digest XOF functions return 1 on seccess and 0 on failure, returned
// from |SHAKE_Absorb|, to restrict update calls after |squeezeXOF|.
static int shake256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
int ok;
CHECK((ok = SHAKE_Absorb(ctx->md_data, data, count)));
return ok;
}

static void shake256_final(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
CHECK(SHAKE_Final(md, ctx->md_data, len));
// Digest XOF functions return 1 on seccess and 0 on failure,
// returned from |SHAKE_Final|, to restrict Signle-Shot SHAKE_Final
// calls after |squeezeXOF|.
static int shake256_final(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
int ok;
CHECK((ok = SHAKE_Final(md, ctx->md_data, len)));
return ok;
}

static void shake256_squeeze(EVP_MD_CTX *ctx, uint8_t *md, size_t len) {
Expand Down Expand Up @@ -507,11 +538,12 @@ static void md5_sha1_init(EVP_MD_CTX *md_ctx) {
CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1));
}

static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data,
static int md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data,
size_t count) {
MD5_SHA1_CTX *ctx = md_ctx->md_data;
CHECK(MD5_Update(&ctx->md5, data, count) &&
SHA1_Update(&ctx->sha1, data, count));
return 1;
}

static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) {
Expand Down
11 changes: 8 additions & 3 deletions crypto/fipsmodule/digest/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ struct env_md_st {
void (*init)(EVP_MD_CTX *ctx);

// update hashes |len| bytes of |data| into the state in |ctx->md_data|.
void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
// Digest functions always return 1. update calls after |final| are
// via checking the |ctx| (|final| cleanses the |ctx|).
// Digest XOF functions return 1 on seccess and 0 on failure,
// returned from |SHAKE_Absorb|, to restrict update calls after |squeezeXOF|.
int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);

// final completes the hash and writes |md_size| bytes of digest to |out|.
void (*final)(EVP_MD_CTX *ctx, uint8_t *out);
Expand All @@ -91,8 +95,9 @@ struct env_md_st {
unsigned ctx_size;

// finalXOF completes the hash and writes |len| bytes of digest extended output
// to |out|.
void (*finalXOF)(EVP_MD_CTX *ctx, uint8_t *out, size_t len);
// to |out|. Returns 1 on seccess and 0 on failure, returned from |SHAKE_Final|,
// to restrict Signle-Shot finalXOF calls after |squeezeXOF|.
int (*finalXOF)(EVP_MD_CTX *ctx, uint8_t *out, size_t len);

// squeezeXOF incrementally generates |len| bytes of digest extended output
// to |out|.
Expand Down
3 changes: 2 additions & 1 deletion crypto/fipsmodule/evp/digestsign.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ static int uses_prehash(EVP_MD_CTX *ctx, enum evp_sign_verify_t op) {
: (ctx->pctx->pmeth->verify != NULL);
}

static void hmac_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
static int hmac_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
HMAC_PKEY_CTX *hctx = ctx->pctx->data;
CHECK(HMAC_Update(&hctx->ctx, data, count));
return 1;
}

static int HMAC_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *out_sig,
Expand Down
Loading

0 comments on commit 1280353

Please sign in to comment.