eng_devcrypto: add cipher CTX copy function
authorEneas U de Queiroz <cote2004-github@yahoo.com>
Tue, 13 Nov 2018 11:23:22 +0000 (09:23 -0200)
committerRichard Levitte <levitte@openssl.org>
Mon, 10 Dec 2018 12:22:14 +0000 (13:22 +0100)
The engine needs a custom cipher context copy function to open a new
/dev/crypto session.

Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7585)

(cherry picked from commit 6d99e238397859f2df58c60e28905193b2dd6762)

crypto/engine/eng_devcrypto.c

index 1b87774c8a145a4b7b7efc6012df956d794f42fd..c882592554c284f79d0e1ec533b2f3be13561d1d 100644 (file)
@@ -207,6 +207,22 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     return 1;
 }
 
+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;
+}
+
 static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
 {
     struct cipher_ctx *cipher_ctx =
@@ -258,10 +274,12 @@ static void prepare_cipher_methods(void)
                                               cipher_data[i].ivlen)
             || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
                                           cipher_data[i].flags
+                                          | EVP_CIPH_CUSTOM_COPY
                                           | EVP_CIPH_FLAG_DEFAULT_ASN1)
             || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
             || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
                                               cipher_do_cipher)
+            || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
             || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
                                             cipher_cleanup)
             || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],