diff --git a/core/openssl/PKGBUILD b/core/openssl/PKGBUILD
index db8b80155..599ff449a 100644
--- a/core/openssl/PKGBUILD
+++ b/core/openssl/PKGBUILD
@@ -23,12 +23,14 @@ source=("https://www.openssl.org/source/${pkgname}-${_ver}.tar.gz"
         "https://www.openssl.org/source/${pkgname}-${_ver}.tar.gz.asc"
         'fix-manpages.patch'
         'no-rpath.patch'
-        'ca-dir.patch')
+        'ca-dir.patch'
+	'openssl-digests.patch')
 md5sums=('07ecbe4324f140d157478637d6beccf1'
          '34315cf0fbbd1d18435948eb9712fcdf'
          '5bbc0655bda2af95bc8eb568963ce8ba'
          'dc78d3d06baffc16217519242ce92478'
-         '3bf51be3a1bbd262be46dc619f92aa90')
+         '3bf51be3a1bbd262be46dc619f92aa90'
+	 '8c36b135ec9c2573ca987f252df41e5d')
 
 # keep an upgrade path for older installations
 PKGEXT='.pkg.tar.gz'
@@ -51,9 +53,12 @@ build() {
 	patch -p0 -i $srcdir/no-rpath.patch
 	# set ca dir to /etc/ssl by default
 	patch -p0 -i $srcdir/ca-dir.patch
+        # fix cryptodev digest support
+	patch -p0 -i $srcdir/openssl-digests.patch
 	# mark stack as non-executable: http://bugs.archlinux.org/task/12434
 	./Configure --prefix=/usr --openssldir=/etc/ssl --libdir=lib \
-		shared zlib enable-md2 \
+		-DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DHASH_MAX_LEN=64 \
+		shared threads zlib enable-md2 \
 		"${openssltarget}" \
 		-Wa,--noexecstack "${CFLAGS}"
 
diff --git a/core/openssl/openssl-digests.patch b/core/openssl/openssl-digests.patch
new file mode 100644
index 000000000..c81bf7f63
--- /dev/null
+++ b/core/openssl/openssl-digests.patch
@@ -0,0 +1,191 @@
+Index: ./crypto/engine/eng_cryptodev.c
+===================================================================
+RCS file: /v/openssl/cvs/openssl/crypto/engine/eng_cryptodev.c,v
+retrieving revision 1.23
+diff -u -r1.23 eng_cryptodev.c
+--- ./crypto/engine/eng_cryptodev.c	3 Mar 2010 15:30:42 -0000	1.23
++++ ./crypto/engine/eng_cryptodev.c	24 Feb 2012 23:41:51 -0000
+@@ -79,8 +79,6 @@
+ 	unsigned char digest_res[HASH_MAX_LEN];
+ 	char *mac_data;
+ 	int mac_len;
+-
+-	int copy;
+ #endif
+ };
+ 
+@@ -200,6 +198,7 @@
+ 
+ 	if ((fd = open_dev_crypto()) == -1)
+ 		return (-1);
++#ifndef CRIOGET_NOT_NEEDED
+ 	if (ioctl(fd, CRIOGET, &retfd) == -1)
+ 		return (-1);
+ 
+@@ -208,9 +207,19 @@
+ 		close(retfd);
+ 		return (-1);
+ 	}
++#else
++        retfd = fd;
++#endif
+ 	return (retfd);
+ }
+ 
++static void put_dev_crypto(int fd)
++{
++#ifndef CRIOGET_NOT_NEEDED
++	close(fd);
++#endif
++}
++
+ /* Caching version for asym operations */
+ static int
+ get_asym_dev_crypto(void)
+@@ -252,7 +261,7 @@
+ 		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+ 			nids[count++] = ciphers[i].nid;
+ 	}
+-	close(fd);
++	put_dev_crypto(fd);
+ 
+ 	if (count > 0)
+ 		*cnids = nids;
+@@ -291,7 +300,7 @@
+ 		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+ 			nids[count++] = digests[i].nid;
+ 	}
+-	close(fd);
++	put_dev_crypto(fd);
+ 
+ 	if (count > 0)
+ 		*cnids = nids;
+@@ -436,7 +445,7 @@
+ 	sess->cipher = cipher;
+ 
+ 	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
+-		close(state->d_fd);
++		put_dev_crypto(state->d_fd);
+ 		state->d_fd = -1;
+ 		return (0);
+ 	}
+@@ -473,7 +482,7 @@
+ 	} else {
+ 		ret = 1;
+ 	}
+-	close(state->d_fd);
++	put_dev_crypto(state->d_fd);
+ 	state->d_fd = -1;
+ 
+ 	return (ret);
+@@ -686,7 +695,7 @@
+ 	sess->mac = digest;
+ 
+ 	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+-		close(state->d_fd);
++		put_dev_crypto(state->d_fd);
+ 		state->d_fd = -1;
+ 		printf("cryptodev_digest_init: Open session failed\n");
+ 		return (0);
+@@ -758,14 +767,12 @@
+ 	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
+ 		/* if application doesn't support one buffer */
+ 		memset(&cryp, 0, sizeof(cryp));
+-
+ 		cryp.ses = sess->ses;
+ 		cryp.flags = 0;
+ 		cryp.len = state->mac_len;
+ 		cryp.src = state->mac_data;
+ 		cryp.dst = NULL;
+ 		cryp.mac = (caddr_t)md;
+-
+ 		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+ 			printf("cryptodev_digest_final: digest failed\n");
+ 			return (0);
+@@ -786,6 +793,9 @@
+ 	struct dev_crypto_state *state = ctx->md_data;
+ 	struct session_op *sess = &state->d_sess;
+ 
++	if (state == NULL)
++	  return 0;
++
+ 	if (state->d_fd < 0) {
+ 		printf("cryptodev_digest_cleanup: illegal input\n");
+ 		return (0);
+@@ -797,16 +807,13 @@
+ 		state->mac_len = 0;
+ 	}
+ 
+-	if (state->copy)
+-		return 1;
+-
+ 	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
+ 		printf("cryptodev_digest_cleanup: failed to close session\n");
+ 		ret = 0;
+ 	} else {
+ 		ret = 1;
+ 	}
+-	close(state->d_fd);	
++	put_dev_crypto(state->d_fd);	
+ 	state->d_fd = -1;
+ 
+ 	return (ret);
+@@ -816,15 +823,39 @@
+ {
+ 	struct dev_crypto_state *fstate = from->md_data;
+ 	struct dev_crypto_state *dstate = to->md_data;
++	struct session_op *sess;
++	int digest;
+ 
+-	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
++	if (dstate == NULL || fstate == NULL)
++	  return 1;
+ 
+-	if (fstate->mac_len != 0) {
+-		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+-		memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
++       	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
++
++	sess = &dstate->d_sess;
++
++	digest = digest_nid_to_cryptodev(to->digest->type);
++
++	sess->mackey = dstate->dummy_mac_key;
++	sess->mackeylen = digest_key_length(to->digest->type);
++	sess->mac = digest;
++
++	dstate->d_fd = get_dev_crypto();
++
++	if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
++		put_dev_crypto(dstate->d_fd);
++		dstate->d_fd = -1;
++		printf("cryptodev_digest_init: Open session failed\n");
++		return (0);
+ 	}
+ 
+-	dstate->copy = 1;
++	if (fstate->mac_len != 0) {
++	        if (fstate->mac_data != NULL)
++	                {
++        		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
++	        	memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
++           		dstate->mac_len = fstate->mac_len;
++	        	}
++	}
+ 
+ 	return 1;
+ }
+@@ -1347,11 +1378,11 @@
+ 	 * find out what asymmetric crypto algorithms we support
+ 	 */
+ 	if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
+-		close(fd);
++		put_dev_crypto(fd);
+ 		ENGINE_free(engine);
+ 		return;
+ 	}
+-	close(fd);
++	put_dev_crypto(fd);
+ 
+ 	if (!ENGINE_set_id(engine, "cryptodev") ||
+ 	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||