+ /* Ensure a context left lying around from last time is cleared
+ * (the previous check attempted to avoid this if the same
+ * ENGINE and EVP_CIPHER could be used). */
+ EVP_CIPHER_CTX_cleanup(ctx);
+
+ /* Restore encrypt field: it is zeroed by cleanup */
+ ctx->encrypt = enc;
+ if(impl)
+ {
+ if (!ENGINE_init(impl))
+ {
+ EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ }
+ else
+ /* Ask if an ENGINE is reserved for this job */
+ impl = ENGINE_get_cipher_engine(cipher->nid);
+ if(impl)
+ {
+ /* There's an ENGINE for this job ... (apparently) */
+ const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
+ if(!c)
+ {
+ /* One positive side-effect of US's export
+ * control history, is that we should at least
+ * be able to avoid using US mispellings of
+ * "initialisation"? */
+ EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
+ /* We'll use the ENGINE's private cipher definition */
+ cipher = c;
+ /* Store the ENGINE functional reference so we know
+ * 'cipher' came from an ENGINE and we need to release
+ * it when done. */
+ ctx->engine = impl;
+ }
+ else
+ ctx->engine = NULL;
+