mirror of
https://github.com/bol-van/zapret.git
synced 2026-03-08 06:15:26 +00:00
nfqws: fixes backport from z2
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user