X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fprotocol_auth.c;fp=src%2Fprotocol_auth.c;h=8288847e5ec1823ff7896a48513fd75405630b74;hp=96e6b6e2953ccc39d34944aa9e22f87425010e3b;hb=5c8a2a840a648b65b1396efbb0ddb84151ddc7e3;hpb=6af82260ba2d6bbf296932aa95dddec0be5abcbb diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 96e6b6e2..8288847e 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -113,6 +113,21 @@ bool id_h(connection_t *c) { return send_metakey(c); } +static uint64_t byte_budget(const EVP_CIPHER *cipher) { + /* Hopefully some failsafe way to calculate the maximum amount of bytes to + send/receive with a given cipher before we might run into birthday paradox + attacks. Because we might use different modes, the block size of the mode + might be 1 byte. In that case, use the IV length. Ensure the whole thing + is limited to what can be represented with a 64 bits integer. + */ + + int ivlen = EVP_CIPHER_iv_length(cipher); + int blklen = EVP_CIPHER_block_size(cipher); + int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8; + int bits = len * 4 - 1; + return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX; +} + bool send_metakey(connection_t *c) { bool x; @@ -195,7 +210,7 @@ bool send_metakey(connection_t *c) { return false; } - c->outbudget = (uint64_t)1 << EVP_CIPHER_key_length(c->outcipher) * 4; + c->outbudget = byte_budget(c->outcipher); c->status.encryptout = true; } @@ -274,7 +289,7 @@ bool metakey_h(connection_t *c) { return false; } - c->inbudget = (uint64_t)1 << EVP_CIPHER_key_length(c->incipher) * 4; + c->inbudget = byte_budget(c->incipher); c->status.decryptin = true; } else { c->incipher = NULL;