Date: Mon, 4 Feb 2008 23:08:11 GMT From: chargen <chargen@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: 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 Message-ID: <200802042308.m14N8BYQ058532@www.freebsd.org> Resent-Message-ID: <200802042320.m14NK282082433@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802042308.m14N8BYQ058532>