-bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
- if((size_t)RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len) {
- return true;
+#if OPENSSL_VERSION_MAJOR >= 3
+// Initialize encryption or decryption context. Must return >0 on success, ≤0 on failure.
+typedef int (enc_init_t)(EVP_PKEY_CTX *ctx);
+
+// Encrypt or decrypt data. Must return >0 on success, ≤0 on failure.
+typedef int (enc_process_t)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);
+
+static bool rsa_encrypt_decrypt(rsa_t *rsa, const void *in, size_t len, void *out,
+ enc_init_t init, enc_process_t process) {
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(rsa, NULL);
+
+ if(ctx) {
+ size_t outlen = len;
+
+ bool ok = init(ctx) > 0
+ && EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING) > 0
+ && process(ctx, out, &outlen, in, len) > 0
+ && outlen == len;
+
+ EVP_PKEY_CTX_free(ctx);
+
+ if(ok) {
+ return true;
+ }