From 47479c474f42774ae38f63bac788acb2d171621b Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Mon, 3 Aug 2026 00:16:20 +0200 Subject: [PATCH] verify functions always set stat=0 before any other return --- src/encauth/eax/eax_decrypt_verify_memory.c | 6 +++--- src/encauth/ocb3/ocb3_decrypt_verify_memory.c | 3 +-- src/pk/dsa/dsa_verify_hash.c | 11 ++++++----- src/pk/dsa/dsa_verify_key.c | 9 ++++++--- src/pk/ecc/ecc_verify_hash.c | 2 ++ src/pk/ecc/ecc_verify_hash_eth27.c | 4 ++++ src/pk/ecc/ecc_verify_hash_internal.c | 8 ++++---- src/pk/ecc/ecc_verify_hash_rfc5656.c | 4 ++++ src/pk/ecc/ecc_verify_hash_rfc7518.c | 4 ++++ src/pk/ecc/ecc_verify_hash_x962.c | 4 ++++ src/pk/ed25519/ed25519_verify.c | 15 ++++++++++++--- src/pk/ed448/ed448_verify.c | 19 ++++++++++++++++--- src/pk/pkcs1/pkcs_1_oaep_decode.c | 8 ++++---- src/pk/pkcs1/pkcs_1_pss_decode.c | 8 ++++---- src/pk/pkcs1/pkcs_1_v1_5_decode.c | 3 ++- src/pk/rsa/rsa_decrypt_key.c | 8 ++++---- src/pk/rsa/rsa_verify_hash.c | 8 ++++---- 17 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/encauth/eax/eax_decrypt_verify_memory.c b/src/encauth/eax/eax_decrypt_verify_memory.c index e00233b38..9c4203a00 100644 --- a/src/encauth/eax/eax_decrypt_verify_memory.c +++ b/src/encauth/eax/eax_decrypt_verify_memory.c @@ -40,15 +40,15 @@ int eax_decrypt_verify_memory(int cipher, unsigned char *buf; unsigned long buflen; + /* stat is cleared before anything else can return, it stays 0 unless the tag is good */ LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(key != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); - /* default to zero */ - *stat = 0; - if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } diff --git a/src/encauth/ocb3/ocb3_decrypt_verify_memory.c b/src/encauth/ocb3/ocb3_decrypt_verify_memory.c index 03d33b204..93c63a28a 100644 --- a/src/encauth/ocb3/ocb3_decrypt_verify_memory.c +++ b/src/encauth/ocb3/ocb3_decrypt_verify_memory.c @@ -40,9 +40,8 @@ int ocb3_decrypt_verify_memory(int cipher, unsigned char *buf; unsigned long buflen; + /* stat is cleared before anything else can return, it stays 0 unless the tag is good */ LTC_ARGCHK(stat != NULL); - - /* default to zero */ *stat = 0; /* limit taglen */ diff --git a/src/pk/dsa/dsa_verify_hash.c b/src/pk/dsa/dsa_verify_hash.c index 230041a5a..7e79a5bb4 100644 --- a/src/pk/dsa/dsa_verify_hash.c +++ b/src/pk/dsa/dsa_verify_hash.c @@ -27,14 +27,14 @@ int dsa_verify_hash_raw( void *r, void *s, void *w, *v, *u1, *u2; int err; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(r != NULL); LTC_ARGCHK(s != NULL); - LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); - /* default to invalid signature */ - *stat = 0; - /* init our variables */ if ((err = ltc_mp_init_multi(&w, &v, &u1, &u2, LTC_NULL)) != CRYPT_OK) { return err; @@ -95,8 +95,9 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, ltc_asn1_list sig_seq[2]; unsigned long reallen = 0; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ LTC_ARGCHK(stat != NULL); - *stat = 0; /* must be set before the first return */ + *stat = 0; if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) { return err; diff --git a/src/pk/dsa/dsa_verify_key.c b/src/pk/dsa/dsa_verify_key.c index 9beae6c66..80ae68564 100644 --- a/src/pk/dsa/dsa_verify_key.c +++ b/src/pk/dsa/dsa_verify_key.c @@ -43,9 +43,10 @@ int dsa_int_validate_pqg(const dsa_key *key, int *stat) void *tmp1, *tmp2; int err; - LTC_ARGCHK(key != NULL); + /* stat is cleared before anything else can return, it stays 0 unless the params are valid */ LTC_ARGCHK(stat != NULL); *stat = 0; + LTC_ARGCHK(key != NULL); /* check q-order */ if ( key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || @@ -96,9 +97,10 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat) { int err, res; + /* stat is cleared before anything else can return, it stays 0 unless the primes are valid */ + LTC_ARGCHK(stat != NULL); *stat = 0; LTC_ARGCHK(key != NULL); - LTC_ARGCHK(stat != NULL); /* key->q prime? */ if ((err = ltc_mp_prime_is_prime(key->q, LTC_MILLER_RABIN_REPS, &res)) != CRYPT_OK) { @@ -132,9 +134,10 @@ int dsa_int_validate_xy(const dsa_key *key, int *stat) void *tmp; int err; + /* stat is cleared before anything else can return, it stays 0 unless the key is valid */ + LTC_ARGCHK(stat != NULL); *stat = 0; LTC_ARGCHK(key != NULL); - LTC_ARGCHK(stat != NULL); /* 1 < y < p-1 */ if ((err = ltc_mp_init(&tmp)) != CRYPT_OK) { diff --git a/src/pk/ecc/ecc_verify_hash.c b/src/pk/ecc/ecc_verify_hash.c index 3a38d46d6..b7a3fb89f 100644 --- a/src/pk/ecc/ecc_verify_hash.c +++ b/src/pk/ecc/ecc_verify_hash.c @@ -46,8 +46,10 @@ int ecc_verify_hash_v2(const unsigned char *sig, int *stat, const ecc_key *key) { + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ LTC_ARGCHK(stat != NULL); *stat = 0; + LTC_ARGCHK(opts != NULL); if (opts->type < 0 || opts->type >= LTC_ARRAY_SIZE(s_ecc_verify_hash)) return CRYPT_PK_INVALID_TYPE; if (s_ecc_verify_hash[opts->type] == NULL) diff --git a/src/pk/ecc/ecc_verify_hash_eth27.c b/src/pk/ecc/ecc_verify_hash_eth27.c index 4f6394f7f..d3802d465 100644 --- a/src/pk/ecc/ecc_verify_hash_eth27.c +++ b/src/pk/ecc/ecc_verify_hash_eth27.c @@ -27,6 +27,10 @@ int ecc_verify_hash_eth27(const unsigned char *sig, unsigned long siglen, void *r, *s; int err; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(sig != NULL); LTC_ARGCHK(key != NULL); diff --git a/src/pk/ecc/ecc_verify_hash_internal.c b/src/pk/ecc/ecc_verify_hash_internal.c index ae666110d..13be42cb8 100644 --- a/src/pk/ecc/ecc_verify_hash_internal.c +++ b/src/pk/ecc/ecc_verify_hash_internal.c @@ -17,15 +17,15 @@ int ecc_verify_hash_internal(void *r, void *s, unsigned long pbits, pbytes, i, shift_right; unsigned char ch, buf[MAXBLOCKSIZE]; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(r != NULL); LTC_ARGCHK(s != NULL); LTC_ARGCHK(hash != NULL); - LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); - /* default to invalid signature */ - *stat = 0; - /* allocate ints */ if ((err = ltc_mp_init_multi(&v, &w, &u1, &u2, &e, &a_plus3, LTC_NULL)) != CRYPT_OK) { return err; diff --git a/src/pk/ecc/ecc_verify_hash_rfc5656.c b/src/pk/ecc/ecc_verify_hash_rfc5656.c index 027e4a70b..1ad02e29a 100644 --- a/src/pk/ecc/ecc_verify_hash_rfc5656.c +++ b/src/pk/ecc/ecc_verify_hash_rfc5656.c @@ -31,6 +31,10 @@ int ecc_verify_hash_rfc5656(const unsigned char *sig, unsigned long siglen, unsigned long name2len = sizeof(name2); unsigned long slen = siglen; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(sig != NULL); LTC_ARGCHK(key != NULL); diff --git a/src/pk/ecc/ecc_verify_hash_rfc7518.c b/src/pk/ecc/ecc_verify_hash_rfc7518.c index ce2aa673f..51922a40b 100644 --- a/src/pk/ecc/ecc_verify_hash_rfc7518.c +++ b/src/pk/ecc/ecc_verify_hash_rfc7518.c @@ -18,6 +18,10 @@ int ecc_verify_hash_rfc7518_internal(const unsigned char *sig, unsigned long si int err; unsigned long i; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(sig != NULL); LTC_ARGCHK(key != NULL); diff --git a/src/pk/ecc/ecc_verify_hash_x962.c b/src/pk/ecc/ecc_verify_hash_x962.c index fc63632dc..477d798b1 100644 --- a/src/pk/ecc/ecc_verify_hash_x962.c +++ b/src/pk/ecc/ecc_verify_hash_x962.c @@ -17,6 +17,10 @@ int ecc_verify_hash_x962(const unsigned char *sig, unsigned long siglen, void *r, *s; int err; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(sig != NULL); if ((err = ltc_mp_init_multi(&r, &s, NULL)) != CRYPT_OK) return err; diff --git a/src/pk/ed25519/ed25519_verify.c b/src/pk/ed25519/ed25519_verify.c index 2a16e30c5..033b3932e 100644 --- a/src/pk/ed25519/ed25519_verify.c +++ b/src/pk/ed25519/ed25519_verify.c @@ -19,13 +19,14 @@ static int s_ed25519_verify(const unsigned char *msg, unsigned long msglen, unsigned long long mlen; int err; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(msg != NULL); LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(stat != NULL); LTC_ARGCHK(public_key != NULL); - *stat = 0; - if (find_hash("sha512") == -1) return CRYPT_INVALID_HASH; if (siglen != 64uL) return CRYPT_INVALID_ARG; if (public_key->pka != LTC_PKA_ED25519) return CRYPT_PK_INVALID_TYPE; @@ -74,6 +75,10 @@ int ed25519ctx_verify(const unsigned char *msg, unsigned long msglen, unsigned char ctx_prefix[292]; unsigned long ctx_prefix_size = sizeof(ctx_prefix); + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(ctx != NULL); if (ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen) != CRYPT_OK) @@ -105,6 +110,10 @@ int ed25519ph_verify(const unsigned char *msg, unsigned long msglen, unsigned char ctx_prefix[292]; unsigned long ctx_prefix_size = sizeof(ctx_prefix); + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK) return err; diff --git a/src/pk/ed448/ed448_verify.c b/src/pk/ed448/ed448_verify.c index b39d5185a..be04c76d0 100644 --- a/src/pk/ed448/ed448_verify.c +++ b/src/pk/ed448/ed448_verify.c @@ -19,13 +19,14 @@ static int s_ed448_verify(const unsigned char *msg, unsigned long msglen, unsigned long long mlen; int err; + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(msg != NULL); LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(stat != NULL); LTC_ARGCHK(public_key != NULL); - *stat = 0; - if (siglen != 114uL) return CRYPT_INVALID_ARG; if (public_key->pka != LTC_PKA_ED448) return CRYPT_PK_INVALID_TYPE; @@ -74,6 +75,10 @@ int ed448ctx_verify(const unsigned char *msg, unsigned long msglen, unsigned char ctx_prefix[266]; unsigned long ctx_prefix_size = sizeof(ctx_prefix); + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(ctx != NULL); if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen)) != CRYPT_OK) @@ -105,6 +110,10 @@ int ed448ph_verify(const unsigned char *msg, unsigned long msglen, unsigned char ctx_prefix[266]; unsigned long ctx_prefix_size = sizeof(ctx_prefix); + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK) return err; @@ -133,6 +142,10 @@ int ed448_verify(const unsigned char *msg, unsigned long msglen, unsigned char ctx_prefix[266]; unsigned long ctx_prefix_size = sizeof(ctx_prefix); + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + /* Pure Ed448 still uses DOM4 with flag=0 and empty context */ if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, NULL, 0)) != CRYPT_OK) return err; diff --git a/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/pk/pkcs1/pkcs_1_oaep_decode.c index 4a2c405fd..f0f0deca9 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -30,18 +30,18 @@ int ltc_pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, int err, ret; ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); + /* res is cleared before anything else can return, it stays 0 unless the padding is valid */ + LTC_ARGCHK(res != NULL); + *res = 0; + LTC_ARGCHK(msg != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(res != NULL); if ((err = rsa_key_valid_op(LTC_PKCS1_DECRYPT, &op_checked)) != CRYPT_OK) { return err; } - /* default to invalid packet */ - *res = 0; - hLen = hash_descriptor[op_checked.hash_alg].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); diff --git a/src/pk/pkcs1/pkcs_1_pss_decode.c b/src/pk/pkcs1/pkcs_1_pss_decode.c index 3fae71bbc..185dff129 100644 --- a/src/pk/pkcs1/pkcs_1_pss_decode.c +++ b/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -31,13 +31,13 @@ int ltc_pkcs_1_pss_decode_mgf1(const unsigned char *msghash, unsigned long msgh hash_state md; ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); + /* res is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(res != NULL); + *res = 0; + LTC_ARGCHK(msghash != NULL); LTC_ARGCHK(sig != NULL); LTC_ARGCHK(params != NULL); - LTC_ARGCHK(res != NULL); - - /* default to invalid */ - *res = 0; if ((err = rsa_key_valid_op(LTC_PKCS1_VERIFY, &op_checked)) != CRYPT_OK) { return err; diff --git a/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/src/pk/pkcs1/pkcs_1_v1_5_decode.c index f52b8c013..ed1bd7295 100644 --- a/src/pk/pkcs1/pkcs_1_v1_5_decode.c +++ b/src/pk/pkcs1/pkcs_1_v1_5_decode.c @@ -32,7 +32,8 @@ int ltc_pkcs_1_v1_5_decode(const unsigned char *msg, unsigned long modulus_len, ps_len, i; int result; - /* default to invalid packet */ + /* is_valid is cleared before anything else can return, it stays 0 unless the padding is valid */ + LTC_ARGCHK(is_valid != NULL); *is_valid = 0; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); diff --git a/src/pk/rsa/rsa_decrypt_key.c b/src/pk/rsa/rsa_decrypt_key.c index 6cdb55362..b4cbc88b3 100644 --- a/src/pk/rsa/rsa_decrypt_key.c +++ b/src/pk/rsa/rsa_decrypt_key.c @@ -30,13 +30,13 @@ int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen unsigned long modulus_bitlen, modulus_bytelen, x; ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); + /* stat is cleared before anything else can return, it stays 0 unless the padding is valid */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(stat != NULL); - - /* default to invalid */ - *stat = 0; /* valid padding? */ if ((err = rsa_key_valid_op(LTC_RSA_DECRYPT, &op_checked)) != CRYPT_OK) { diff --git a/src/pk/rsa/rsa_verify_hash.c b/src/pk/rsa/rsa_verify_hash.c index 39666d642..2337186fc 100644 --- a/src/pk/rsa/rsa_verify_hash.c +++ b/src/pk/rsa/rsa_verify_hash.c @@ -30,14 +30,14 @@ int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen, unsigned char *tmpbuf; ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); + /* stat is cleared before anything else can return, it stays 0 unless the signature is good */ + LTC_ARGCHK(stat != NULL); + *stat = 0; + LTC_ARGCHK(hash != NULL); LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); - /* default to invalid */ - *stat = 0; - if ((err = rsa_key_valid_op(LTC_RSA_VERIFY, &op_checked)) != CRYPT_OK) { return err; }