+
+const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx,
+ int nid,
+ const char *properties)
+{
+ /*
+ * If there is an Engine available for this cipher we use the "implicit"
+ * form to ensure we use that engine later.
+ */
+ if (ENGINE_get_cipher_engine(nid) != NULL)
+ return EVP_get_cipherbynid(nid);
+
+ /* Otherwise we do an explicit fetch */
+ return EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties);
+}
+
+
+int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher)
+{
+ /* Don't up-ref an implicit EVP_CIPHER */
+ if (EVP_CIPHER_provider(cipher) == NULL)
+ return 1;
+
+ /*
+ * The cipher was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ return EVP_CIPHER_up_ref((EVP_CIPHER *)cipher);
+}
+
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
+{
+ if (cipher == NULL)
+ return;
+
+ if (EVP_CIPHER_provider(cipher) != NULL) {
+ /*
+ * The cipher was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ EVP_CIPHER_free((EVP_CIPHER *)cipher);
+ }
+}
+
+const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx,
+ int nid,
+ const char *properties)
+{
+ /*
+ * If there is an Engine available for this digest we use the "implicit"
+ * form to ensure we use that engine later.
+ */
+ if (ENGINE_get_digest_engine(nid) != NULL)
+ return EVP_get_digestbynid(nid);
+
+ /* Otherwise we do an explicit fetch */
+ return EVP_MD_fetch(libctx, OBJ_nid2sn(nid), properties);
+}
+
+int ssl_evp_md_up_ref(const EVP_MD *md)
+{
+ /* Don't up-ref an implicit EVP_MD */
+ if (EVP_MD_provider(md) == NULL)
+ return 1;
+
+ /*
+ * The digest was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ return EVP_MD_up_ref((EVP_MD *)md);
+}
+
+void ssl_evp_md_free(const EVP_MD *md)
+{
+ if (md == NULL)
+ return;
+
+ if (EVP_MD_provider(md) != NULL) {
+ /*
+ * The digest was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ EVP_MD_free((EVP_MD *)md);
+ }
+}