Add support for OpenSSL 3.0+
[tinc] / src / openssl / cipher.c
index 974fbeb..77747f1 100644 (file)
@@ -1,6 +1,6 @@
 /*
     cipher.c -- Symmetric block cipher handling
-    Copyright (C) 2007-2017 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 
 #include "../system.h"
 
-#include <openssl/rand.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 
+#include "log.h"
+#include "cipher.h"
 #include "../cipher.h"
 #include "../logger.h"
-#include "../xalloc.h"
 
-struct cipher {
-       EVP_CIPHER_CTX *ctx;
-       const EVP_CIPHER *cipher;
-};
-
-static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) {
-       cipher_t *cipher = xzalloc(sizeof(*cipher));
+static void cipher_open(cipher_t *cipher, const EVP_CIPHER *evp_cipher) {
        cipher->cipher = evp_cipher;
        cipher->ctx = EVP_CIPHER_CTX_new();
 
        if(!cipher->ctx) {
                abort();
        }
-
-       return cipher;
 }
 
-cipher_t *cipher_open_by_name(const char *name) {
+bool cipher_open_by_name(cipher_t *cipher, const char *name) {
        const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name);
 
        if(!evp_cipher) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name);
-               return NULL;
+               return false;
        }
 
-       return cipher_open(evp_cipher);
+       cipher_open(cipher, evp_cipher);
+       return true;
 }
 
-cipher_t *cipher_open_by_nid(int nid) {
+bool cipher_open_by_nid(cipher_t *cipher, int nid) {
        const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid);
 
        if(!evp_cipher) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid);
-               return NULL;
+               return false;
        }
 
-       return cipher_open(evp_cipher);
+       cipher_open(cipher, evp_cipher);
+       return true;
 }
 
 void cipher_close(cipher_t *cipher) {
@@ -71,8 +65,11 @@ void cipher_close(cipher_t *cipher) {
                return;
        }
 
-       EVP_CIPHER_CTX_free(cipher->ctx);
-       free(cipher);
+       if(cipher->ctx) {
+               EVP_CIPHER_CTX_free(cipher->ctx);
+       }
+
+       memset(cipher, 0, sizeof(*cipher));
 }
 
 size_t cipher_keylength(const cipher_t *cipher) {
@@ -123,7 +120,7 @@ bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) {
                return true;
        }
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL));
+       openssl_err("set key");
        return false;
 }
 
@@ -140,7 +137,7 @@ bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encry
                return true;
        }
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL));
+       openssl_err("set key");
        return false;
 }
 
@@ -149,7 +146,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
                int len, pad;
 
                if(EVP_EncryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL)
-                               && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen)
+                               && EVP_EncryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, (int)inlen)
                                && EVP_EncryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) {
                        if(outlen) {
                                *outlen = len + pad;
@@ -160,7 +157,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
        } else {
                int len;
 
-               if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) {
+               if(EVP_EncryptUpdate(cipher->ctx, outdata, &len, indata, (int)inlen)) {
                        if(outlen) {
                                *outlen = len;
                        }
@@ -169,7 +166,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
                }
        }
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL));
+       openssl_err("encrypt data");
        return false;
 }
 
@@ -178,7 +175,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
                int len, pad;
 
                if(EVP_DecryptInit_ex(cipher->ctx, NULL, NULL, NULL, NULL)
-                               && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, inlen)
+                               && EVP_DecryptUpdate(cipher->ctx, (unsigned char *)outdata, &len, indata, (int)inlen)
                                && EVP_DecryptFinal_ex(cipher->ctx, (unsigned char *)outdata + len, &pad)) {
                        if(outlen) {
                                *outlen = len + pad;
@@ -189,7 +186,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
        } else {
                int len;
 
-               if(EVP_DecryptUpdate(cipher->ctx, outdata, &len, indata, inlen)) {
+               if(EVP_DecryptUpdate(cipher->ctx, outdata, &len, indata, (int)inlen)) {
                        if(outlen) {
                                *outlen = len;
                        }
@@ -198,7 +195,7 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
                }
        }
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL));
+       openssl_err("decrypt data");
        return false;
 }