From 3f85f694920562d04bd9c45085810f6c10e4b6ec Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 30 Dec 2019 00:33:05 -0500 Subject: [PATCH] Set CHUNK_SIZE_MAX better for 32-bit systems --- .ci/build.sh | 2 ++ pegh.c | 39 +++++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index ec9df5a..61103a3 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -24,6 +24,8 @@ mv pegh pegh.static.openssl make clean all PEGH_LIBSODIUM=1 PEGH_OPENSSL=1 CC=clang LDFLAGS="-static -lcrypto" || clang pegh.c -DPEGH_LIBSODIUM -DPEGH_OPENSSL -static -lsodium -lcrypto -O3 -o pegh mv pegh pegh.static.libsodium-openssl +./pegh.static.libsodium-openssl -h + ls -lah pegh.static.* strip pegh.static.* diff --git a/pegh.c b/pegh.c index d34e0a6..b9287f7 100644 --- a/pegh.c +++ b/pegh.c @@ -95,7 +95,7 @@ typedef int (*gcm_func)(const unsigned char *, const size_t, #include /* this is because we read up to buffer_size at once, and then send that value to openssl which uses int instead of size_t, limit of 2gb */ -static const size_t CHUNK_SIZE_MAX = INT_MAX; +static const size_t CHUNK_SIZE_MAX_OPENSSL = INT_MAX; /* * returns 1 on success, 0 on failure @@ -287,16 +287,15 @@ void wipe_memory(void * const ptr, const size_t len) { #include -/* for now in hybrid mode lazily use OPENSSL's CHUNK_SIZE_MAX which is smaller, solution to make them the same coming soon */ -#ifndef PEGH_OPENSSL -/* unlike openssl, libsodium uses proper types, so we can go all the way up to the "aes-gcm-256 is still secure" limit of around 32gb */ /* -// actually this is breaking on x86 and aarch64 where size_t is `unsigned int` and this overflows, how to handle??? -static const size_t CHUNK_SIZE_MAX = 1024UL * 1024 * 1024 * 32; -// for now, 4gb will do? -*/ -static const size_t CHUNK_SIZE_MAX = UINT_MAX; -#endif /* PEGH_OPENSSL */ + * unlike openssl, libsodium uses proper types, so we can go all the way up to the "aes-gcm-256 is still secure" limit of around 32gb + * but 32-bit systems have SIZE_MAX smaller than that, so special case that here + */ +#if (1024UL * 1024 * 1024 * 32) > SIZE_MAX +static const size_t CHUNK_SIZE_MAX_LIBSODIUM = SIZE_MAX; +#else +static const size_t CHUNK_SIZE_MAX_LIBSODIUM = 1024UL * 1024 * 1024 * 32; +#endif /* * returns 1 on success, 0 on failure @@ -402,11 +401,22 @@ void wipe_memory(void * const ptr, const size_t len) { /* always prefer libsodium AES if possible because it's faster */ #ifdef PEGH_LIBSODIUM -gcm_func gcm_encrypt = gcm_encrypt_libsodium; -gcm_func gcm_decrypt = gcm_decrypt_libsodium; + +/* if PEGH_OPENSSL is defined, these can be redefined at runtime depending on CPU, otherwise const */ +#ifndef PEGH_OPENSSL +#define PEGH_CONST const +#else +#define PEGH_CONST +#endif + +static PEGH_CONST gcm_func gcm_encrypt = gcm_encrypt_libsodium; +static PEGH_CONST gcm_func gcm_decrypt = gcm_decrypt_libsodium; +static PEGH_CONST size_t CHUNK_SIZE_MAX = CHUNK_SIZE_MAX_LIBSODIUM; + #elif PEGH_OPENSSL -gcm_func gcm_encrypt = gcm_encrypt_openssl; -gcm_func gcm_decrypt = gcm_decrypt_openssl; +static const gcm_func gcm_encrypt = gcm_encrypt_openssl; +static const gcm_func gcm_decrypt = gcm_decrypt_openssl; +static const size_t CHUNK_SIZE_MAX = CHUNK_SIZE_MAX_OPENSSL; #endif /* returns 1 on success, 0 on failure */ @@ -768,6 +778,7 @@ int main(int argc, char **argv) fprintf(stderr, "Warning: libsodium does not support AES-256-GCM on this CPU, falling back to openssl version instead...\n"); gcm_encrypt = gcm_encrypt_openssl; gcm_decrypt = gcm_decrypt_openssl; + CHUNK_SIZE_MAX = CHUNK_SIZE_MAX_OPENSSL; #else /* nothing we can do */ fprintf(stderr, "Error: libsodium does not support AES-256-GCM on this CPU, compile/use openssl version?\n");