/*
zip_crypto_openssl.c -- OpenSSL wrapper.
- Copyright (C) 2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2018-2021 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
#include "zip_crypto.h"
+#include <limits.h>
#include <openssl/rand.h>
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
#define USE_OPENSSL_1_0_API
#endif
_zip_crypto_aes_t *
_zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error) {
_zip_crypto_aes_t *aes;
+ const EVP_CIPHER* cipher_type;
+
+ switch (key_size) {
+ case 128:
+ cipher_type = EVP_aes_128_ecb();
+ break;
+ case 192:
+ cipher_type = EVP_aes_192_ecb();
+ break;
+ case 256:
+ cipher_type = EVP_aes_256_ecb();
+ break;
+ default:
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return NULL;
+ }
+#ifdef USE_OPENSSL_1_0_API
if ((aes = (_zip_crypto_aes_t *)malloc(sizeof(*aes))) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
}
+ memset(aes, 0, sizeof(*aes));
+#else
+ if ((aes = EVP_CIPHER_CTX_new()) == NULL) {
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
+ }
+#endif
- AES_set_encrypt_key(key, key_size, aes);
+ if (EVP_EncryptInit_ex(aes, cipher_type, NULL, key, NULL) != 1) {
+#ifdef USE_OPENSSL_1_0_API
+ free(aes);
+#else
+ EVP_CIPHER_CTX_free(aes);
+#endif
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ return NULL;
+ }
return aes;
}
void
_zip_crypto_aes_free(_zip_crypto_aes_t *aes) {
if (aes == NULL) {
- return;
+ return;
}
+#ifdef USE_OPENSSL_1_0_API
+ EVP_CIPHER_CTX_cleanup(aes);
_zip_crypto_clear(aes, sizeof(*aes));
free(aes);
+#else
+ EVP_CIPHER_CTX_free(aes);
+#endif
+}
+
+
+bool
+_zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out) {
+ int len;
+ if (EVP_EncryptUpdate(aes, out, &len, in, ZIP_CRYPTO_AES_BLOCK_LENGTH) != 1) {
+ return false;
+ }
+ return true;
}
_zip_crypto_hmac_t *hmac;
if (secret_length > INT_MAX) {
- zip_error_set(error, ZIP_ER_INVAL, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_INVAL, 0);
+ return NULL;
}
#ifdef USE_OPENSSL_1_0_API
if ((hmac = (_zip_crypto_hmac_t *)malloc(sizeof(*hmac))) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
}
HMAC_CTX_init(hmac);
#else
if ((hmac = HMAC_CTX_new()) == NULL) {
- zip_error_set(error, ZIP_ER_MEMORY, 0);
- return NULL;
+ zip_error_set(error, ZIP_ER_MEMORY, 0);
+ return NULL;
}
#endif
if (HMAC_Init_ex(hmac, secret, (int)secret_length, EVP_sha1(), NULL) != 1) {
- zip_error_set(error, ZIP_ER_INTERNAL, 0);
+ zip_error_set(error, ZIP_ER_INTERNAL, 0);
#ifdef USE_OPENSSL_1_0_API
- free(hmac);
+ free(hmac);
#else
- HMAC_CTX_free(hmac);
+ HMAC_CTX_free(hmac);
#endif
- return NULL;
+ return NULL;
}
return hmac;
void
_zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
if (hmac == NULL) {
- return;
+ return;
}
#ifdef USE_OPENSSL_1_0_API
ZIP_EXTERN bool
-zip_random(zip_uint8_t *buffer, zip_uint16_t length) {
+zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length) {
return RAND_bytes(buffer, length) == 1;
}