Imported Upstream version 1.9.0
[platform/upstream/libzip.git] / lib / zip_crypto_openssl.c
index a1766bf..f67faf7 100644 (file)
@@ -1,6 +1,6 @@
 /*
   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;
 }
@@ -61,11 +94,26 @@ _zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *
 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;
 }
 
 
@@ -74,32 +122,32 @@ _zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_
     _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;
@@ -109,7 +157,7 @@ _zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_
 void
 _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac) {
     if (hmac == NULL) {
-       return;
+        return;
     }
 
 #ifdef USE_OPENSSL_1_0_API
@@ -131,6 +179,6 @@ _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data) {
 
 
 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;
 }