nfqws: fixes backport from z2

This commit is contained in:
bol-van
2026-02-16 12:46:22 +03:00
parent 0f0e748adb
commit 5ef01d14a9
7 changed files with 62 additions and 67 deletions

View File

@@ -5,6 +5,8 @@ int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_
int ret = 0; int ret = 0;
gcm_context ctx; gcm_context ctx;
gcm_initialize();
if (!(ret = gcm_setkey(&ctx, key, (const uint)key_len))) if (!(ret = gcm_setkey(&ctx, key, (const uint)key_len)))
{ {
ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len); ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len);

View File

@@ -391,7 +391,9 @@ int gcm_finish(gcm_context *ctx, // pointer to user-provided GCM context
uint64_t orig_add_len = ctx->add_len * 8; uint64_t orig_add_len = ctx->add_len * 8;
size_t i; size_t i;
if (tag_len != 0) memcpy(tag, ctx->base_ectr, tag_len); if (tag_len>16) return -1;
if (tag_len) memcpy(tag, ctx->base_ectr, tag_len);
if (orig_len || orig_add_len) { if (orig_len || orig_add_len) {
memset(work_buf, 0x00, 16); memset(work_buf, 0x00, 16);
@@ -443,10 +445,12 @@ int gcm_crypt_and_tag(
prepare the gcm context with the keying material, we simply prepare the gcm context with the keying material, we simply
invoke each of the three GCM sub-functions in turn... invoke each of the three GCM sub-functions in turn...
*/ */
gcm_start(ctx, mode, iv, iv_len, add, add_len); if (tag_len>16) return -1;
gcm_update(ctx, length, input, output);
gcm_finish(ctx, tag, tag_len); int ret;
return(0); if ((ret=gcm_start(ctx, mode, iv, iv_len, add, add_len))) return ret;
if ((ret=gcm_update(ctx, length, input, output))) return ret;
return gcm_finish(ctx, tag, tag_len);
} }
@@ -477,23 +481,28 @@ int gcm_auth_decrypt(
uchar check_tag[16]; // the tag generated and returned by decryption uchar check_tag[16]; // the tag generated and returned by decryption
int diff; // an ORed flag to detect authentication errors int diff; // an ORed flag to detect authentication errors
size_t i; // our local iterator size_t i; // our local iterator
int ret;
if (tag_len>16) return -1;
/* /*
we use GCM_DECRYPT_AND_TAG (above) to perform our decryption we use GCM_DECRYPT_AND_TAG (above) to perform our decryption
(which is an identical XORing to reverse the previous one) (which is an identical XORing to reverse the previous one)
and also to re-generate the matching authentication tag and also to re-generate the matching authentication tag
*/ */
gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len, if ((ret = gcm_crypt_and_tag(ctx, AES_DECRYPT, iv, iv_len, add, add_len, input, output, length, check_tag, tag_len))) return ret;
input, output, length, check_tag, tag_len);
// now we verify the authentication tag in 'constant time' // now we verify the authentication tag in 'constant time'
for (diff = 0, i = 0; i < tag_len; i++) for (diff = 0, i = 0; i < tag_len; i++)
diff |= tag[i] ^ check_tag[i]; diff |= tag[i] ^ check_tag[i];
if (diff != 0) { // see whether any bits differed? if (diff)
{
// see whether any bits differed?
memset(output, 0, length); // if so... wipe the output data memset(output, 0, length); // if so... wipe the output data
return(GCM_AUTH_FAILURE); // return GCM_AUTH_FAILURE return(GCM_AUTH_FAILURE); // return GCM_AUTH_FAILURE
} }
return(0); return 0;
} }
/****************************************************************************** /******************************************************************************

View File

@@ -60,9 +60,9 @@ int hkdf(SHAversion whichSha,
uint8_t okm[], size_t okm_len) uint8_t okm[], size_t okm_len)
{ {
uint8_t prk[USHAMaxHashSize]; uint8_t prk[USHAMaxHashSize];
return hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk) || int ret;
hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, if ((ret=hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk))) return ret;
info_len, okm, okm_len); return hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, info_len, okm, okm_len);
} }
/* /*
@@ -103,9 +103,6 @@ int hkdfExtract(SHAversion whichSha,
salt_len = USHAHashSize(whichSha); salt_len = USHAHashSize(whichSha);
memset(nullSalt, '\0', salt_len); memset(nullSalt, '\0', salt_len);
} }
else if (salt_len < 0) {
return shaBadParam;
}
return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk); return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk);
} }
@@ -149,16 +146,13 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
size_t hash_len, N; size_t hash_len, N;
unsigned char T[USHAMaxHashSize]; unsigned char T[USHAMaxHashSize];
size_t Tlen, where, i; size_t Tlen, where, i;
int ret;
if (info == 0) { if (info == 0) {
info = (const unsigned char *)""; info = (const unsigned char *)"";
info_len = 0; info_len = 0;
} }
else if (info_len < 0) { if (!okm || !okm_len) return shaBadParam;
return shaBadParam;
}
if (okm_len <= 0) return shaBadParam;
if (!okm) return shaBadParam;
hash_len = USHAHashSize(whichSha); hash_len = USHAHashSize(whichSha);
if (prk_len < hash_len) return shaBadParam; if (prk_len < hash_len) return shaBadParam;
@@ -171,12 +165,11 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
for (i = 1; i <= N; i++) { for (i = 1; i <= N; i++) {
HMACContext context; HMACContext context;
unsigned char c = i; unsigned char c = i;
int ret = hmacReset(&context, whichSha, prk, prk_len) || if ((ret=hmacReset(&context, whichSha, prk, prk_len))) return ret;
hmacInput(&context, T, Tlen) || if ((ret=hmacInput(&context, T, Tlen))) return ret;
hmacInput(&context, info, info_len) || if ((ret=hmacInput(&context, info, info_len))) return ret;
hmacInput(&context, &c, 1) || if ((ret=hmacInput(&context, &c, 1))) return ret;
hmacResult(&context, T); if ((ret=hmacResult(&context, T))) return ret;
if (ret != shaSuccess) return ret;
memcpy(okm + where, T, memcpy(okm + where, T,
(i != N) ? hash_len : (okm_len - where)); (i != N) ? hash_len : (okm_len - where));
where += hash_len; where += hash_len;
@@ -328,9 +321,8 @@ int hkdfResult(HKDFContext *context,
if (!okm) return context->Corrupted = shaBadParam; if (!okm) return context->Corrupted = shaBadParam;
if (!prk) prk = prkbuf; if (!prk) prk = prkbuf;
ret = hmacResult(&context->hmacContext, prk) || if (!(ret = hmacResult(&context->hmacContext, prk)))
hkdfExpand(context->whichSha, prk, context->hashSize, info, ret = hkdfExpand(context->whichSha, prk, context->hashSize, info, info_len, okm, okm_len);
info_len, okm, okm_len);
context->Computed = 1; context->Computed = 1;
return context->Corrupted = ret; return context->Corrupted = ret;
} }

View File

@@ -49,9 +49,10 @@ int hmac(SHAversion whichSha,
uint8_t digest[USHAMaxHashSize]) uint8_t digest[USHAMaxHashSize])
{ {
HMACContext context; HMACContext context;
return hmacReset(&context, whichSha, key, key_len) || int ret;
hmacInput(&context, message_array, length) || if ((ret=hmacReset(&context, whichSha, key, key_len))) return ret;
hmacResult(&context, digest); if ((ret=hmacInput(&context, message_array, length))) return ret;
return hmacResult(&context, digest);
} }
/* /*
@@ -101,10 +102,8 @@ int hmacReset(HMACContext *context, enum SHAversion whichSha,
*/ */
if (key_len > blocksize) { if (key_len > blocksize) {
USHAContext tcontext; USHAContext tcontext;
int err = USHAReset(&tcontext, whichSha) || if ((ret=USHAReset(&tcontext, whichSha)) || (ret=USHAInput(&tcontext, key, key_len)) || (ret=USHAResult(&tcontext, tempkey)))
USHAInput(&tcontext, key, key_len) || return ret;
USHAResult(&tcontext, tempkey);
if (err != shaSuccess) return err;
key = tempkey; key = tempkey;
key_len = hashsize; key_len = hashsize;
@@ -134,9 +133,9 @@ int hmacReset(HMACContext *context, enum SHAversion whichSha,
/* perform inner hash */ /* perform inner hash */
/* init context for 1st pass */ /* init context for 1st pass */
ret = USHAReset(&context->shaContext, whichSha) || if (!(ret = USHAReset(&context->shaContext, whichSha)))
/* and start with inner pad */ /* and start with inner pad */
USHAInput(&context->shaContext, k_ipad, blocksize); ret = USHAInput(&context->shaContext, k_ipad, blocksize);
return context->Corrupted = ret; return context->Corrupted = ret;
} }
@@ -197,8 +196,7 @@ int hmacFinalBits(HMACContext *context,
if (context->Corrupted) return context->Corrupted; if (context->Corrupted) return context->Corrupted;
if (context->Computed) return context->Corrupted = shaStateError; if (context->Computed) return context->Corrupted = shaStateError;
/* then final bits of datagram */ /* then final bits of datagram */
return context->Corrupted = return context->Corrupted = USHAFinalBits(&context->shaContext, bits, bit_count);
USHAFinalBits(&context->shaContext, bits, bit_count);
} }
/* /*
@@ -229,21 +227,16 @@ int hmacResult(HMACContext *context, uint8_t *digest)
/* finish up 1st pass */ /* finish up 1st pass */
/* (Use digest here as a temporary buffer.) */ /* (Use digest here as a temporary buffer.) */
ret = if (!(ret=USHAResult(&context->shaContext, digest)) &&
USHAResult(&context->shaContext, digest) ||
/* perform outer SHA */ /* perform outer SHA */
/* init context for 2nd pass */ /* init context for 2nd pass */
USHAReset(&context->shaContext, context->whichSha) || !(ret=USHAReset(&context->shaContext, context->whichSha)) &&
/* start with outer pad */ /* start with outer pad */
USHAInput(&context->shaContext, context->k_opad, !(ret=USHAInput(&context->shaContext, context->k_opad, context->blockSize)) &&
context->blockSize) ||
/* then results of 1st hash */ /* then results of 1st hash */
USHAInput(&context->shaContext, digest, context->hashSize) || !(ret=USHAInput(&context->shaContext, digest, context->hashSize)))
/* finish up 2nd pass */ /* finish up 2nd pass */
USHAResult(&context->shaContext, digest); ret=USHAResult(&context->shaContext, digest);
context->Computed = 1; context->Computed = 1;
return context->Corrupted = ret; return context->Corrupted = ret;

View File

@@ -64,12 +64,12 @@
* Add "length" to the length. * Add "length" to the length.
* Set Corrupted when overflow has occurred. * Set Corrupted when overflow has occurred.
*/ */
static uint32_t addTemp; static int SHA224_256AddLength(SHA256Context *context, uint32_t length)
#define SHA224_256AddLength(context, length) \ {
(addTemp = (context)->Length_Low, (context)->Corrupted = \ uint32_t addTemp = context->Length_Low;
(((context)->Length_Low += (length)) < addTemp) && \ if (((context->Length_Low += length) < addTemp) && (++(context)->Length_High == 0)) context->Corrupted = shaInputTooLong;
(++(context)->Length_High == 0) ? shaInputTooLong : \ return context->Corrupted;
(context)->Corrupted ) }
/* Local Function Prototypes */ /* Local Function Prototypes */
static int SHA224_256Reset(SHA256Context *context, uint32_t *H0); static int SHA224_256Reset(SHA256Context *context, uint32_t *H0);

View File

@@ -2304,6 +2304,7 @@ int main(int argc, char **argv)
#endif #endif
srandom(time(NULL)); srandom(time(NULL));
aes_init_keygen_tables(); // required for aes
PRINT_VER; PRINT_VER;

View File

@@ -795,21 +795,19 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
return false; return false;
} }
uint64_t payload_len,token_len; uint64_t payload_len,token_len,pn_offset;
size_t pn_offset;
pn_offset = 1 + 4 + 1 + data[5]; pn_offset = 1 + 4 + 1 + data[5];
if (pn_offset >= data_len) return false; if (pn_offset >= data_len) return false;
// SCID length
pn_offset += 1 + data[pn_offset]; pn_offset += 1 + data[pn_offset];
if ((pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false; if (pn_offset >= data_len || (pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
// token length
pn_offset += tvb_get_varint(data + pn_offset, &token_len); pn_offset += tvb_get_varint(data + pn_offset, &token_len);
pn_offset += token_len; pn_offset += token_len;
if (pn_offset >= data_len) return false; if (pn_offset >= data_len || (pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
if ((pn_offset + tvb_get_size(data[pn_offset])) >= data_len) return false;
pn_offset += tvb_get_varint(data + pn_offset, &payload_len); pn_offset += tvb_get_varint(data + pn_offset, &payload_len);
if (payload_len<20 || (pn_offset + payload_len)>data_len) return false; if (payload_len<20 || (pn_offset + payload_len)>data_len) return false;
aes_init_keygen_tables();
uint8_t sample_enc[16]; uint8_t sample_enc[16];
aes_context ctx; aes_context ctx;
if (aes_setkey(&ctx, 1, aeshp, sizeof(aeshp)) || aes_cipher(&ctx, data + pn_offset + 4, sample_enc)) return false; if (aes_setkey(&ctx, 1, aeshp, sizeof(aeshp)) || aes_cipher(&ctx, data + pn_offset + 4, sample_enc)) return false;
@@ -827,13 +825,13 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si
phton64(aesiv + sizeof(aesiv) - 8, pntoh64(aesiv + sizeof(aesiv) - 8) ^ pkn); phton64(aesiv + sizeof(aesiv) - 8, pntoh64(aesiv + sizeof(aesiv) - 8) ^ pkn);
size_t cryptlen = payload_len - pkn_len - 16; uint64_t cryptlen = payload_len - pkn_len - 16;
if (cryptlen > *clean_len) return false; if (cryptlen > *clean_len) return false;
*clean_len = cryptlen; *clean_len = (size_t)cryptlen;
const uint8_t *decrypt_begin = data + pn_offset + pkn_len; const uint8_t *decrypt_begin = data + pn_offset + pkn_len;
uint8_t atag[16],header[256]; uint8_t atag[16],header[2048];
size_t header_len = pn_offset + pkn_len; uint64_t header_len = pn_offset + pkn_len;
if (header_len > sizeof(header)) return false; // not likely header will be so large if (header_len > sizeof(header)) return false; // not likely header will be so large
memcpy(header, data, header_len); memcpy(header, data, header_len);
header[0] = packet0; header[0] = packet0;