+static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
+{
+ EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
+ struct cipher_ctx *cipher_ctx;
+
+ if (type == EVP_CTRL_COPY) {
+ /* when copying the context, a new session needs to be initialized */
+ cipher_ctx = (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
+ return (cipher_ctx == NULL)
+ || cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
+ (cipher_ctx->op == COP_ENCRYPT));
+ }
+
+ return -1;
+}
+