Add mode that uses libsodium AES if the CPU supports it but falls back to OpenSSL AES if not
This commit is contained in:
parent
53b1fbb689
commit
d42539da59
@ -14,6 +14,8 @@ make clean all PEGH_LIBSODIUM=1 CC=clang LDFLAGS="-static -lsodium" || clang peg
|
||||
mv pegh pegh.static.libsodium
|
||||
make clean all PEGH_OPENSSL=1 CC=clang LDFLAGS="-static -lcrypto" || clang pegh.c -DPEGH_OPENSSL -static -lcrypto -O3 -o pegh
|
||||
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-universal-aes
|
||||
|
||||
ls -lah pegh.static.*
|
||||
|
||||
@ -31,11 +33,11 @@ if ./pegh.static.libsodium -h 2>&1 >/dev/null | grep '^Error: libsodium'
|
||||
then
|
||||
echo "CPU does not have AES support so can't run libsodium version"
|
||||
# no aes support
|
||||
export TEST_BINS="./pegh.static.openssl ./pegh.openssl"
|
||||
export TEST_BINS="./pegh.static.openssl ./pegh.openssl ./pegh.static.libsodium-universal-aes ./pegh.libsodium-universal-aes"
|
||||
else
|
||||
echo "CPU has AES support so can run libsodium version"
|
||||
# we can test everything
|
||||
export TEST_BINS="./pegh.static.openssl ./pegh.openssl ./pegh.libsodium ./pegh.static.libsodium"
|
||||
export TEST_BINS="./pegh.static.openssl ./pegh.openssl ./pegh.static.libsodium-universal-aes ./pegh.libsodium-universal-aes ./pegh.libsodium ./pegh.static.libsodium"
|
||||
fi
|
||||
set -e
|
||||
|
||||
|
@ -14,6 +14,7 @@ docker run --rm -v "$BUILD_DIR":/tmp "$DOCKER_IMAGE" /tmp/build.sh || exit 1
|
||||
|
||||
mv "$BUILD_DIR"pegh.static.openssl "./pegh-$ARCH-openssl"
|
||||
mv "$BUILD_DIR"pegh.static.libsodium "./pegh-$ARCH-libsodium"
|
||||
mv "$BUILD_DIR"pegh.static.libsodium-universal-aes "./pegh-$ARCH-libsodium-universal-aes"
|
||||
rm -rf "$BUILD_DIR" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
pegh
|
||||
pegh.exe
|
||||
pegh.libsodium
|
||||
pegh.libsodium*
|
||||
pegh.openssl
|
||||
bla.txt
|
||||
|
||||
|
11
Makefile
11
Makefile
@ -9,13 +9,24 @@ CFLAGS += -Wall -Wextra -Werror -std=c89 -pedantic \
|
||||
-O3
|
||||
|
||||
ifdef PEGH_OPENSSL
|
||||
|
||||
ifdef PEGH_LIBSODIUM
|
||||
# both libsodium and openssl
|
||||
CFLAGS += -DPEGH_LIBSODIUM -DPEGH_OPENSSL
|
||||
LDFLAGS += -lsodium -lcrypto
|
||||
else
|
||||
# only openssl
|
||||
CFLAGS += -DPEGH_OPENSSL
|
||||
LDFLAGS += -lcrypto
|
||||
endif
|
||||
|
||||
else
|
||||
ifdef PEGH_LIBSODIUM
|
||||
# only libsodium
|
||||
CFLAGS += -DPEGH_LIBSODIUM
|
||||
LDFLAGS += -lsodium
|
||||
else
|
||||
# default of only openssl
|
||||
CFLAGS += -DPEGH_OPENSSL
|
||||
LDFLAGS += -lcrypto
|
||||
endif
|
||||
|
45
pegh.c
45
pegh.c
@ -76,6 +76,12 @@
|
||||
#define IV_LEN 12
|
||||
#define GCM_TAG_LEN 16
|
||||
|
||||
/* libsodium only supports AES on specific platforms, this jazz is to fallback to openssl impls in those cases */
|
||||
typedef int (*gcm_func)(const unsigned char *, const size_t,
|
||||
const unsigned char *, const unsigned char *,
|
||||
unsigned char *, unsigned char *
|
||||
);
|
||||
|
||||
/* default of OpenSSL for now... */
|
||||
#if !defined(PEGH_OPENSSL) && !defined(PEGH_LIBSODIUM)
|
||||
#define PEGH_OPENSSL 1
|
||||
@ -104,7 +110,7 @@ static const size_t CHUNK_SIZE_MAX = INT_MAX;
|
||||
* ciphertext must have the capacity of at least plaintext_len
|
||||
* tag must have the capacity of at least GCM_TAG_LEN
|
||||
*/
|
||||
int gcm_encrypt(const unsigned char *plaintext, const size_t plaintext_len,
|
||||
int gcm_encrypt_openssl(const unsigned char *plaintext, const size_t plaintext_len,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
unsigned char *ciphertext,
|
||||
@ -178,7 +184,7 @@ int gcm_encrypt(const unsigned char *plaintext, const size_t plaintext_len,
|
||||
* these will be written into:
|
||||
* plaintext must have the capacity of at least ciphertext_len
|
||||
*/
|
||||
int gcm_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len,
|
||||
int gcm_decrypt_openssl(const unsigned char *ciphertext, const size_t ciphertext_len,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
unsigned char *tag,
|
||||
@ -239,6 +245,10 @@ int gcm_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* if both PEGH_OPENSSL and PEGH_LIBSODIUM are defined, we only want the AES funcs from OpenSSL */
|
||||
|
||||
#ifndef PEGH_LIBSODIUM
|
||||
|
||||
/* returns 1 on success, 0 on error */
|
||||
int scrypt_derive_key(char *password, size_t password_len,
|
||||
uint32_t scrypt_max_mem, uint32_t N,
|
||||
@ -269,11 +279,16 @@ void wipe_memory(void * const ptr, const size_t len) {
|
||||
OPENSSL_cleanse(ptr, len);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* PEGH_LIBSODIUM */
|
||||
|
||||
#endif /* PEGH_OPENSSL */
|
||||
|
||||
#ifdef PEGH_LIBSODIUM
|
||||
|
||||
#include <sodium.h>
|
||||
|
||||
/* 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???
|
||||
@ -281,6 +296,7 @@ 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 */
|
||||
|
||||
/*
|
||||
* returns 1 on success, 0 on failure
|
||||
@ -295,7 +311,7 @@ static const size_t CHUNK_SIZE_MAX = UINT_MAX;
|
||||
* ciphertext must have the capacity of at least plaintext_len
|
||||
* tag must have the capacity of at least GCM_TAG_LEN
|
||||
*/
|
||||
int gcm_encrypt(const unsigned char *plaintext, const size_t plaintext_len,
|
||||
int gcm_encrypt_libsodium(const unsigned char *plaintext, const size_t plaintext_len,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
unsigned char *ciphertext,
|
||||
@ -323,7 +339,7 @@ int gcm_encrypt(const unsigned char *plaintext, const size_t plaintext_len,
|
||||
* these will be written into:
|
||||
* plaintext must have the capacity of at least ciphertext_len
|
||||
*/
|
||||
int gcm_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len,
|
||||
int gcm_decrypt_libsodium(const unsigned char *ciphertext, const size_t ciphertext_len,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv,
|
||||
unsigned char *tag,
|
||||
@ -382,6 +398,15 @@ void wipe_memory(void * const ptr, const size_t len) {
|
||||
sodium_memzero(ptr, len);
|
||||
}
|
||||
|
||||
#endif /* PEGH_LIBSODIUM */
|
||||
|
||||
/* 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;
|
||||
#elif PEGH_OPENSSL
|
||||
gcm_func gcm_encrypt = gcm_encrypt_openssl;
|
||||
gcm_func gcm_decrypt = gcm_decrypt_openssl;
|
||||
#endif
|
||||
|
||||
/* returns 1 on success, 0 on failure */
|
||||
@ -738,10 +763,18 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
if (crypto_aead_aes256gcm_is_available() == 0) {
|
||||
#ifdef PEGH_OPENSSL
|
||||
/* swap to OpenSSL AES which is always supported */
|
||||
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;
|
||||
#else
|
||||
/* nothing we can do */
|
||||
fprintf(stderr, "Error: libsodium does not support AES-256-GCM on this CPU, compile/use openssl version?\n");
|
||||
return 2;
|
||||
#endif /* PEGH_OPENSSL */
|
||||
}
|
||||
#endif
|
||||
#endif /* PEGH_LIBSODIUM */
|
||||
|
||||
for (optind = 1; optind < argc; ++optind) {
|
||||
if(strlen(argv[optind]) == 2 && argv[optind][0] == '-') {
|
||||
|
6
test.sh
6
test.sh
@ -7,7 +7,7 @@ export dummy_mb="$1"
|
||||
[ "$dummy_file" = "" ] && export dummy_file='/tmp/randombytes'
|
||||
[ "$dummy_mb" = "" ] && export dummy_mb='100'
|
||||
|
||||
[ "$TEST_BINS" = "" ] && TEST_BINS="./pegh.openssl ./pegh.libsodium"
|
||||
[ "$TEST_BINS" = "" ] && TEST_BINS="./pegh.openssl ./pegh.libsodium ./pegh.libsodium-universal-aes"
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
@ -25,6 +25,10 @@ mv pegh pegh.openssl
|
||||
make PEGH_LIBSODIUM=1 || cc pegh.c -DPEGH_LIBSODIUM -lsodium -O3 -o pegh
|
||||
mv pegh pegh.libsodium
|
||||
|
||||
# compile against both libsodium and openssl as a fallback for CPUs libsodium doesn't support
|
||||
make PEGH_LIBSODIUM=1 PEGH_OPENSSL=1 || cc pegh.c -DPEGH_LIBSODIUM -DPEGH_OPENSSL -lsodium -lcrypto -O3 -o pegh
|
||||
mv pegh pegh.libsodium-universal-aes
|
||||
|
||||
export key="$(< /dev/urandom tr -dc 'a-z0-9' | head -c12)"
|
||||
|
||||
echo "key: $key"
|
||||
|
Loading…
Reference in New Issue
Block a user