misc/120270: OPENSSL: AES-192 and AES-256 support for HW-accellerators ie. Hifn 795x / and OpenSSL engine 0.9.8e to _default_ use Cryptodev

chargen chargen at gmail.com
Mon Feb 4 15:20:02 PST 2008


>Number:         120270
>Category:       misc
>Synopsis:       OPENSSL: AES-192 and AES-256 support for HW-accellerators ie. Hifn 795x /  and OpenSSL engine 0.9.8e to _default_ use Cryptodev
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 04 23:20:02 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     chargen
>Release:        7.0-PRERELEASE
>Organization:
none
>Environment:
FreeBSD packetstorm 7.0-PRERELEASE FreeBSD 7.0-PRERELEASE #0: Sun Feb  3 01:06:38 CET 2008     root at packetstorm:/usr/src/sys/i386/compile/PACKETSTORM  i386
p
>Description:
1. currently there's no support for AES-192 and AES-256 ciphers in 7CUR (OpenSSL 0.9.8e)

2. previous fixes fail to evaluate the __freebsd__ version, do not default the cryptodev engine.

I hereby propose several changes to the OpenSSL 0.9.8e engine in 7CUR (incl. works 

- AES-192 and AES-256  support for hardware accellerators like HIFN 795X
- OpenSSL engine defaults to use cryptodev if enabled


>How-To-Repeat:

>Fix:
submitted unified diffs against the following files:

/usr/src/crypto/openssl/crypto/evp/openbsd_hw.c
/usr/src/crypto/openssl/crypto/evp/c_all.c
/usr/src/crypto/openssl/crypto/engine/eng_all.c
/usr/src/crypto/openssl/crypto/engine/eng_cryptodev.c
/usr/src/crypto/openssl/crypto/engine/engine.h




Patch attached with submission follows:

--- /usr/src/crypto/openssl/crypto/evp/openbsd_hw.c	2003-01-28 22:24:39.000000000 +0100
+++ openbsd_hw.c	2008-01-30 22:40:16.000000000 +0100
@@ -109,7 +109,10 @@
 	    dev_failed=1;
 	    return 0;
 	    }
-	close(cryptodev_fd);
+	if (fd == -1)
+		fd = cryptodev_fd;
+	else
+		close(cryptodev_fd);
 	}
     assert(ses);
     memset(ses,'\0',sizeof *ses);
--- /usr/src/crypto/openssl/crypto/evp/c_all.c	2006-07-29 21:10:18.000000000 +0200
+++ c_all.c	2008-01-30 22:42:49.000000000 +0100
@@ -83,7 +83,7 @@
 	OpenSSL_add_all_ciphers();
 	OpenSSL_add_all_digests();
 #ifndef OPENSSL_NO_ENGINE
-# if defined(__OpenBSD__) || defined(__FreeBSD__)
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 	ENGINE_setup_bsd_cryptodev();
 # endif
 #endif
--- /usr/src/crypto/openssl/crypto/engine/eng_all.c	2007-03-15 21:07:26.000000000 +0100
+++ eng_all.c	2008-01-31 01:30:57.000000000 +0100
@@ -105,12 +105,15 @@
 #endif
 #ifndef OPENSSL_NO_HW
 #if defined(__OpenBSD__) || defined(__FreeBSD__)
-	ENGINE_load_cryptodev();
+#define HAVE_CRYPTODEV
 #endif
 #endif
+#ifdef HAVE_CRYPTODEV
+	ENGINE_load_cryptodev();
+#endif
 	}
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void) {
 	static int bsd_cryptodev_default_loaded = 0;
 	if (!bsd_cryptodev_default_loaded) {
--- /usr/src/crypto/openssl/crypto/engine/eng_cryptodev.c	2006-07-29 21:10:18.000000000 +0200
+++ eng_cryptodev.c	2008-01-31 01:13:30.000000000 +0100
@@ -31,16 +31,7 @@
 #include <openssl/evp.h>
 #include <openssl/bn.h>
 
-#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
-	(defined(OpenBSD) || defined(__FreeBSD_version))
-#include <sys/param.h>
-# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
-#  define HAVE_CRYPTODEV
-# endif
-# if (OpenBSD >= 200110)
-#  define HAVE_SYSLOG_R
-# endif
-#endif
+#define HAVE_CRYPTODEV
 
 #ifndef HAVE_CRYPTODEV
 
@@ -70,14 +61,19 @@
 	int d_fd;
 };
 
+struct dev_crypto_cipher {
+	int	c_id;
+	int	c_nid;
+	int	c_ivmax;
+	int	c_keylen;
+};
+
 static u_int32_t cryptodev_asymfeat = 0;
 
 static int get_asym_dev_crypto(void);
 static int open_dev_crypto(void);
 static int get_dev_crypto(void);
-static int cryptodev_max_iv(int cipher);
-static int cryptodev_key_length_valid(int cipher, int len);
-static int cipher_nid_to_cryptodev(int nid);
+static struct dev_crypto_cipher *cipher_nid_to_cryptodev(int nid);
 static int get_cryptodev_ciphers(const int **cnids);
 static int get_cryptodev_digests(const int **cnids);
 static int cryptodev_usable_ciphers(const int **nids);
@@ -124,15 +120,12 @@
 	{ 0, NULL, NULL, 0 }
 };
 
-static struct {
-	int	id;
-	int	nid;
-	int	ivmax;
-	int	keylen;
-} ciphers[] = {
+static struct dev_crypto_cipher ciphers[] = {
 	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
 	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
 	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
+	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
+	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
 	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
 	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
 	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
@@ -142,14 +135,15 @@
 static struct {
 	int	id;
 	int	nid;
+	int	keylen;
 } digests[] = {
-	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	},
-	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		},
-	{ CRYPTO_MD5_KPDK,		NID_undef,		},
-	{ CRYPTO_SHA1_KPDK,		NID_undef,		},
-	{ CRYPTO_MD5,			NID_md5,		},
-	{ CRYPTO_SHA1,			NID_undef,		},
-	{ 0,				NID_undef,		},
+	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20 },
+	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		20 },
+	{ CRYPTO_MD5_KPDK,		NID_undef,		0  },
+	{ CRYPTO_SHA1_KPDK,		NID_undef,		0  },
+	{ CRYPTO_MD5,			NID_md5,		16 },
+	{ CRYPTO_SHA1,			NID_undef,		20 },
+	{ 0,				NID_undef,		0  },
 };
 
 /*
@@ -202,48 +196,16 @@
 	return fd;
 }
 
-/*
- * XXXX this needs to be set for each alg - and determined from
- * a running card.
- */
-static int
-cryptodev_max_iv(int cipher)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].id == cipher)
-			return (ciphers[i].ivmax);
-	return (0);
-}
-
-/*
- * XXXX this needs to be set for each alg - and determined from
- * a running card. For now, fake it out - but most of these
- * for real devices should return 1 for the supported key
- * sizes the device can handle.
- */
-static int
-cryptodev_key_length_valid(int cipher, int len)
-{
-	int i;
-
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].id == cipher)
-			return (ciphers[i].keylen == len);
-	return (0);
-}
-
 /* convert libcrypto nids to cryptodev */
-static int
+static struct dev_crypto_cipher *
 cipher_nid_to_cryptodev(int nid)
 {
 	int i;
 
-	for (i = 0; ciphers[i].id; i++)
-		if (ciphers[i].nid == nid)
-			return (ciphers[i].id);
-	return (0);
+	for (i = 0; ciphers[i].c_id; i++)
+		if (ciphers[i].c_nid == nid)
+			return (&ciphers[i]);
+	return (NULL);
 }
 
 /*
@@ -264,17 +226,16 @@
 		return (0);
 	}
 	memset(&sess, 0, sizeof(sess));
-	sess.key = (caddr_t)"123456781234567812345678";
-
-	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
-		if (ciphers[i].nid == NID_undef)
+        sess.key = (caddr_t)"123456789abcdefghijklmno";
+	for (i = 0; ciphers[i].c_id && count < CRYPTO_ALGORITHM_MAX; i++) {
+		if (ciphers[i].c_nid == NID_undef)
 			continue;
-		sess.cipher = ciphers[i].id;
-		sess.keylen = ciphers[i].keylen;
+		sess.cipher = ciphers[i].c_id;
+		sess.keylen = ciphers[i].c_keylen;
 		sess.mac = 0;
 		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
 		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
-			nids[count++] = ciphers[i].nid;
+			nids[count++] = ciphers[i].c_nid;
 	}
 	close(fd);
 
@@ -303,10 +264,12 @@
 		return (0);
 	}
 	memset(&sess, 0, sizeof(sess));
+        sess.mackey = (caddr_t)"123456789abcdefghijklmno";
 	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (digests[i].nid == NID_undef)
 			continue;
 		sess.mac = digests[i].id;
+                sess.mackeylen = digests[i].keylen;
 		sess.cipher = 0;
 		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
 		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
@@ -427,15 +390,15 @@
 {
 	struct dev_crypto_state *state = ctx->cipher_data;
 	struct session_op *sess = &state->d_sess;
-	int cipher;
+	struct dev_crypto_cipher *cipher;
 
-	if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
+	if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NULL)
 		return (0);
 
-	if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
+	if (ctx->cipher->iv_len > cipher->c_ivmax)
 		return (0);
 
-	if (!cryptodev_key_length_valid(cipher, ctx->key_len))
+	if (ctx->key_len != cipher->c_keylen)
 		return (0);
 
 	memset(sess, 0, sizeof(struct session_op));
@@ -445,7 +408,7 @@
 
 	sess->key = (unsigned char *)key;
 	sess->keylen = ctx->key_len;
-	sess->cipher = cipher;
+	sess->cipher = cipher->c_id;
 
 	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
 		close(state->d_fd);
@@ -550,7 +513,7 @@
 	NULL
 };
 
-const EVP_CIPHER cryptodev_aes_cbc = {
+const EVP_CIPHER cryptodev_aes_128_cbc = {
 	NID_aes_128_cbc,
 	16, 16, 16,
 	EVP_CIPH_CBC_MODE,
@@ -563,6 +526,32 @@
 	NULL
 };
 
+const EVP_CIPHER cryptodev_aes_192_cbc = {
+	NID_aes_192_cbc,
+	16, 24, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
+const EVP_CIPHER cryptodev_aes_256_cbc = {
+	NID_aes_256_cbc,
+	16, 32, 16,
+	EVP_CIPH_CBC_MODE,
+	cryptodev_init_key,
+	cryptodev_cipher,
+	cryptodev_cleanup,
+	sizeof(struct dev_crypto_state),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+};
+
 /*
  * Registered by the ENGINE when used to find out how to deal with
  * a particular NID in the ENGINE. this says what we'll do at the
@@ -589,7 +578,13 @@
 		*cipher = &cryptodev_cast_cbc;
 		break;
 	case NID_aes_128_cbc:
-		*cipher = &cryptodev_aes_cbc;
+		*cipher = &cryptodev_aes_128_cbc;
+		break;
+	case NID_aes_192_cbc:
+		*cipher = &cryptodev_aes_192_cbc;
+		break;
+	case NID_aes_256_cbc:
+		*cipher = &cryptodev_aes_256_cbc;
 		break;
 	default:
 		*cipher = NULL;
@@ -1126,6 +1121,7 @@
 	}
 
 	ENGINE_add(engine);
+        ENGINE_set_default_ciphers(engine);
 	ENGINE_free(engine);
 	ERR_clear_error();
 }
--- /usr/src/crypto/openssl/crypto/engine/engine.h	2006-07-29 21:10:18.000000000 +0200
+++ engine.h	2008-01-30 22:56:51.000000000 +0100
@@ -688,7 +688,7 @@
  * values. */
 void *ENGINE_get_static_state(void);
 
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
 void ENGINE_setup_bsd_cryptodev(void);
 #endif
 


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list