From 6d1f929a060201df18cac385477610f472a732a8 Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Sat, 31 Mar 2012 11:20:27 +0200 Subject: [PATCH] openssl: fix aes accleration via cryptodev. --- lfs/openssl | 7 +- src/patches/openssl-0.9.8u-cryptodev.patch | 882 +++++++++++++++++++++ 2 files changed, 884 insertions(+), 5 deletions(-) create mode 100644 src/patches/openssl-0.9.8u-cryptodev.patch diff --git a/lfs/openssl b/lfs/openssl index 3336cfb4bb..9d559e1549 100644 --- a/lfs/openssl +++ b/lfs/openssl @@ -70,15 +70,12 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/openssl-0.9.8n-cryptodev.diff -ifeq "$(PADLOCK)" "1" - cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/openssl-0.9.8g-engine-padlock.patch -endif + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/openssl-0.9.8u-cryptodev.patch @rm -rf /etc/ssl cd $(DIR_APP) && sed -i -e 's/mcpu/march/' config cd $(DIR_APP) && sed -i -e 's/-O3/-O2/' -e 's/-march=i486/-march=i586/' Configure cd $(DIR_APP) && ./Configure --openssldir=/etc/ssl --prefix=/usr shared linux-elf \ - zlib-dynamic no-asm 386 + zlib-dynamic no-asm 386 -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGEST cd $(DIR_APP) && make MANDIR=/usr/share/man cd $(DIR_APP) && make MANDIR=/usr/share/man install rm -rf /etc/ssl/lib diff --git a/src/patches/openssl-0.9.8u-cryptodev.patch b/src/patches/openssl-0.9.8u-cryptodev.patch new file mode 100644 index 0000000000..920648df65 --- /dev/null +++ b/src/patches/openssl-0.9.8u-cryptodev.patch @@ -0,0 +1,882 @@ +diff -Naur openssl-0.9.8u.org/crypto/engine/eng_all.c openssl-0.9.8u/crypto/engine/eng_all.c +--- openssl-0.9.8u.org/crypto/engine/eng_all.c 2010-03-01 01:30:11.000000000 +0100 ++++ openssl-0.9.8u/crypto/engine/eng_all.c 2012-03-27 14:07:11.000000000 +0200 +@@ -113,7 +113,6 @@ + #endif + } + +-#if defined(__OpenBSD__) || defined(__FreeBSD__) + void ENGINE_setup_bsd_cryptodev(void) { + static int bsd_cryptodev_default_loaded = 0; + if (!bsd_cryptodev_default_loaded) { +@@ -122,4 +121,3 @@ + } + bsd_cryptodev_default_loaded=1; + } +-#endif +diff -Naur openssl-0.9.8u.org/crypto/engine/eng_cryptodev.c openssl-0.9.8u/crypto/engine/eng_cryptodev.c +--- openssl-0.9.8u.org/crypto/engine/eng_cryptodev.c 2012-03-06 14:22:32.000000000 +0100 ++++ openssl-0.9.8u/crypto/engine/eng_cryptodev.c 2012-03-27 14:02:59.000000000 +0200 +@@ -2,6 +2,7 @@ + * Copyright (c) 2002 Bob Beck + * Copyright (c) 2002 Theo de Raadt + * Copyright (c) 2002 Markus Friedl ++ * Copyright (c) 2012 Nikos Mavrogiannopoulos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without +@@ -30,10 +31,6 @@ + #include + #include + #include +-#include +-#include +-#include +-#include + + #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ + (defined(OpenBSD) || defined(__FreeBSD__)) +@@ -59,6 +56,10 @@ + + #include + #include ++#include ++#include ++#include ++#include + #include + #include + #include +@@ -72,6 +73,12 @@ + struct dev_crypto_state { + struct session_op d_sess; + int d_fd; ++ ++#ifdef USE_CRYPTODEV_DIGESTS ++ unsigned char digest_res[HASH_MAX_LEN]; ++ char *mac_data; ++ int mac_len; ++#endif + }; + + static u_int32_t cryptodev_asymfeat = 0; +@@ -79,15 +86,14 @@ + 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 int get_cryptodev_ciphers(const int **cnids); +-/*static int get_cryptodev_digests(const int **cnids);*/ ++#ifdef USE_CRYPTODEV_DIGESTS ++static int get_cryptodev_digests(const int **cnids); ++#endif + static int cryptodev_usable_ciphers(const int **nids); + static int cryptodev_usable_digests(const int **nids); + static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, +- const unsigned char *in, unsigned int inl); ++ const unsigned char *in, size_t inl); + static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); +@@ -121,7 +127,7 @@ + static int cryptodev_dh_compute_key(unsigned char *key, + const BIGNUM *pub_key, DH *dh); + static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, +- void (*f)()); ++ void (*f)(void)); + void ENGINE_load_cryptodev(void); + + static const ENGINE_CMD_DEFN cryptodev_defns[] = { +@@ -134,27 +140,38 @@ + int ivmax; + int keylen; + } ciphers[] = { ++ { CRYPTO_ARC4, NID_rc4, 0, 16, }, + { 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, }, + { 0, NID_undef, 0, 0, }, + }; + +-#if 0 ++#ifdef USE_CRYPTODEV_DIGESTS + static struct { + int id; + int nid; ++ int digestlen; + } 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, }, ++#if 0 ++ /* HMAC is not supported */ ++ { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16}, ++ { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20}, ++ { CRYPTO_SHA2_256_HMAC, NID_hmacWithSHA256, 32}, ++ { CRYPTO_SHA2_384_HMAC, NID_hmacWithSHA384, 48}, ++ { CRYPTO_SHA2_512_HMAC, NID_hmacWithSHA512, 64}, ++#endif ++ { CRYPTO_MD5, NID_md5, 16}, ++ { CRYPTO_SHA1, NID_sha1, 20}, ++ { CRYPTO_SHA2_256, NID_sha256, 32}, ++ { CRYPTO_SHA2_384, NID_sha384, 48}, ++ { CRYPTO_SHA2_512, NID_sha512, 64}, ++ { 0, NID_undef, 0}, + }; + #endif + +@@ -186,6 +203,7 @@ + + if ((fd = open_dev_crypto()) == -1) + return (-1); ++#ifndef CRIOGET_NOT_NEEDED + if (ioctl(fd, CRIOGET, &retfd) == -1) + return (-1); + +@@ -194,9 +212,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) +@@ -209,50 +237,6 @@ + } + + /* +- * 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 +-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); +-} +- +-/* + * Find out what ciphers /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL +@@ -264,13 +248,14 @@ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int fd, i, count = 0; ++ unsigned char fake_key[CRYPTO_CIPHER_MAX_KEY_LEN]; + + if ((fd = get_dev_crypto()) < 0) { + *cnids = NULL; + return (0); + } + memset(&sess, 0, sizeof(sess)); +- sess.key = (caddr_t)"123456781234567812345678"; ++ sess.key = (void*)fake_key; + + for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (ciphers[i].nid == NID_undef) +@@ -282,7 +267,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 +276,7 @@ + return (count); + } + +-#if 0 /* unused */ ++#ifdef USE_CRYPTODEV_DIGESTS + /* + * Find out what digests /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! +@@ -302,6 +287,7 @@ + get_cryptodev_digests(const int **cnids) + { + static int nids[CRYPTO_ALGORITHM_MAX]; ++ unsigned char fake_key[CRYPTO_CIPHER_MAX_KEY_LEN]; + struct session_op sess; + int fd, i, count = 0; + +@@ -310,16 +296,18 @@ + return (0); + } + memset(&sess, 0, sizeof(sess)); ++ sess.mackey = fake_key; + 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 = 8; + sess.cipher = 0; + if (ioctl(fd, CIOCGSESSION, &sess) != -1 && + ioctl(fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = digests[i].nid; + } +- close(fd); ++ put_dev_crypto(fd); + + if (count > 0) + *cnids = nids; +@@ -327,8 +315,7 @@ + *cnids = NULL; + return (count); + } +- +-#endif ++#endif /* 0 */ + + /* + * Find the useable ciphers|digests from dev/crypto - this is the first +@@ -360,6 +347,9 @@ + static int + cryptodev_usable_digests(const int **nids) + { ++#ifdef USE_CRYPTODEV_DIGESTS ++ return (get_cryptodev_digests(nids)); ++#else + /* + * XXXX just disable all digests for now, because it sucks. + * we need a better way to decide this - i.e. I may not +@@ -374,11 +364,12 @@ + */ + *nids = NULL; + return (0); ++#endif + } + + static int + cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, +- const unsigned char *in, unsigned int inl) ++ const unsigned char *in, size_t inl) + { + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->cipher_data; +@@ -398,14 +389,14 @@ + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = inl; +- cryp.src = (caddr_t) in; +- cryp.dst = (caddr_t) out; ++ cryp.src = (void*) in; ++ cryp.dst = (void*) out; + cryp.mac = 0; + + cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + + if (ctx->cipher->iv_len) { +- cryp.iv = (caddr_t) ctx->iv; ++ cryp.iv = (void*) ctx->iv; + if (!ctx->encrypt) { + iiv = in + inl - ctx->cipher->iv_len; + memcpy(save_iv, iiv, ctx->cipher->iv_len); +@@ -436,28 +427,32 @@ + { + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; +- int cipher; ++ int cipher = -1, i; + +- if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) +- return (0); +- +- if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) +- return (0); ++ for (i = 0; ciphers[i].id; i++) ++ if (ctx->cipher->nid == ciphers[i].nid && ++ ctx->cipher->iv_len <= ciphers[i].ivmax && ++ ctx->key_len == ciphers[i].keylen) { ++ cipher = ciphers[i].id; ++ break; ++ } + +- if (!cryptodev_key_length_valid(cipher, ctx->key_len)) ++ if (!ciphers[i].id) { ++ state->d_fd = -1; + return (0); ++ } + + memset(sess, 0, sizeof(struct session_op)); + + if ((state->d_fd = get_dev_crypto()) < 0) + return (0); + +- sess->key = (char *)key; ++ sess->key = (void*)key; + sess->keylen = ctx->key_len; + 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); + } +@@ -494,7 +489,7 @@ + } else { + ret = 1; + } +- close(state->d_fd); ++ put_dev_crypto(state->d_fd); + state->d_fd = -1; + + return (ret); +@@ -505,6 +500,20 @@ + * gets called when libcrypto requests a cipher NID. + */ + ++/* RC4 */ ++const EVP_CIPHER cryptodev_rc4 = { ++ NID_rc4, ++ 1, 16, 0, ++ EVP_CIPH_VARIABLE_LENGTH, ++ cryptodev_init_key, ++ cryptodev_cipher, ++ cryptodev_cleanup, ++ sizeof(struct dev_crypto_state), ++ NULL, ++ NULL, ++ NULL ++}; ++ + /* DES CBC EVP */ + const EVP_CIPHER cryptodev_des_cbc = { + NID_des_cbc, +@@ -572,6 +581,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 +@@ -585,6 +620,9 @@ + return (cryptodev_usable_ciphers(nids)); + + switch (nid) { ++ case NID_rc4: ++ *cipher = &cryptodev_rc4; ++ break; + case NID_des_ede3_cbc: + *cipher = &cryptodev_3des_cbc; + break; +@@ -600,6 +638,12 @@ + case NID_aes_128_cbc: + *cipher = &cryptodev_aes_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; + break; +@@ -607,6 +651,286 @@ + return (*cipher != NULL); + } + ++ ++#ifdef USE_CRYPTODEV_DIGESTS ++ ++/* convert digest type to cryptodev */ ++static int ++digest_nid_to_cryptodev(int nid) ++{ ++ int i; ++ ++ for (i = 0; digests[i].id; i++) ++ if (digests[i].nid == nid) ++ return (digests[i].id); ++ return (0); ++} ++ ++ ++static int cryptodev_digest_init(EVP_MD_CTX *ctx) ++{ ++ struct dev_crypto_state *state = ctx->md_data; ++ struct session_op *sess = &state->d_sess; ++ int digest; ++ ++ if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){ ++ printf("cryptodev_digest_init: Can't get digest \n"); ++ return (0); ++ } ++ memset(state, 0, sizeof(struct dev_crypto_state)); ++ ++ if ((state->d_fd = get_dev_crypto()) < 0) { ++ printf("cryptodev_digest_init: Can't get Dev \n"); ++ return (0); ++ } ++ ++ sess->mackey = NULL; ++ sess->mackeylen = 0; ++ sess->mac = digest; ++ ++ if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { ++ put_dev_crypto(state->d_fd); ++ state->d_fd = -1; ++ printf("cryptodev_digest_init: Open session failed\n"); ++ return (0); ++ } ++ ++ return (1); ++} ++ ++static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, ++ size_t count) ++{ ++ struct dev_crypto_state *state = ctx->md_data; ++ struct crypt_op cryp; ++ struct session_op *sess = &state->d_sess; ++ ++ if (!data || state->d_fd < 0) { ++ printf("cryptodev_digest_update: illegal inputs \n"); ++ return (0); ++ } ++ ++ if (!count) { ++ return (1); ++ } ++ ++ if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { ++ /* if application doesn't support one buffer */ ++ state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); ++ ++ if (!state->mac_data) { ++ printf("cryptodev_digest_update: realloc failed\n"); ++ return (0); ++ } ++ ++ memcpy(state->mac_data + state->mac_len, data, count); ++ state->mac_len += count; ++ ++ return (1); ++ } ++ ++ memset(&cryp, 0, sizeof(cryp)); ++ ++ cryp.ses = sess->ses; ++ cryp.flags = 0; ++ cryp.len = count; ++ cryp.src = (void*) data; ++ cryp.dst = NULL; ++ cryp.mac = (void*) state->digest_res; ++ if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { ++ printf("cryptodev_digest_update: digest failed\n"); ++ return (0); ++ } ++ return (1); ++} ++ ++ ++static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) ++{ ++ struct crypt_op cryp; ++ struct dev_crypto_state *state = ctx->md_data; ++ struct session_op *sess = &state->d_sess; ++ ++ if (!md || state->d_fd < 0) { ++ printf("cryptodev_digest_final: illegal input\n"); ++ return(0); ++ } ++ ++ 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 = (void*)md; ++ if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { ++ printf("cryptodev_digest_final: digest failed\n"); ++ return (0); ++ } ++ ++ return 1; ++ } ++ ++ memcpy(md, state->digest_res, ctx->digest->md_size); ++ ++ return 1; ++} ++ ++ ++static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) ++{ ++ int ret = 1; ++ 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); ++ } ++ ++ if (state->mac_data) { ++ OPENSSL_free(state->mac_data); ++ state->mac_data = NULL; ++ state->mac_len = 0; ++ } ++ ++ if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { ++ printf("cryptodev_digest_cleanup: failed to close session\n"); ++ ret = 0; ++ } else { ++ ret = 1; ++ } ++ put_dev_crypto(state->d_fd); ++ state->d_fd = -1; ++ ++ return (ret); ++} ++ ++static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) ++{ ++ struct dev_crypto_state *fstate = from->md_data; ++ struct dev_crypto_state *dstate = to->md_data; ++ struct session_op *sess; ++ int digest; ++ ++ if (dstate == NULL || fstate == NULL) ++ return 1; ++ ++ memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); ++ ++ sess = &dstate->d_sess; ++ ++ digest = digest_nid_to_cryptodev(to->digest->type); ++ ++ sess->mackey = NULL; ++ sess->mackeylen = 0; ++ 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); ++ } ++ ++ 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; ++} ++ ++ ++static const EVP_MD cryptodev_sha1 = { ++ NID_sha1, ++ NID_sha1WithRSAEncryption, ++ SHA_DIGEST_LENGTH, ++ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT|EVP_MD_FLAG_ONESHOT, ++ cryptodev_digest_init, ++ cryptodev_digest_update, ++ cryptodev_digest_final, ++ cryptodev_digest_copy, ++ cryptodev_digest_cleanup, ++ EVP_PKEY_RSA_method, ++ SHA_CBLOCK, ++ sizeof(EVP_MD *)+sizeof(struct dev_crypto_state), ++}; ++ ++static const EVP_MD cryptodev_sha256 = { ++ NID_sha256, ++ NID_sha256WithRSAEncryption, ++ SHA256_DIGEST_LENGTH, ++ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT|EVP_MD_FLAG_ONESHOT, ++ cryptodev_digest_init, ++ cryptodev_digest_update, ++ cryptodev_digest_final, ++ cryptodev_digest_copy, ++ cryptodev_digest_cleanup, ++ EVP_PKEY_RSA_method, ++ SHA256_CBLOCK, ++ sizeof(EVP_MD *)+sizeof(struct dev_crypto_state), ++}; ++ ++static const EVP_MD cryptodev_sha384 = { ++ NID_sha384, ++ NID_sha384WithRSAEncryption, ++ SHA384_DIGEST_LENGTH, ++ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT|EVP_MD_FLAG_ONESHOT, ++ cryptodev_digest_init, ++ cryptodev_digest_update, ++ cryptodev_digest_final, ++ cryptodev_digest_copy, ++ cryptodev_digest_cleanup, ++ EVP_PKEY_RSA_method, ++ SHA512_CBLOCK, ++ sizeof(EVP_MD *)+sizeof(struct dev_crypto_state), ++}; ++ ++static const EVP_MD cryptodev_sha512 = { ++ NID_sha512, ++ NID_sha512WithRSAEncryption, ++ SHA512_DIGEST_LENGTH, ++ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT|EVP_MD_FLAG_ONESHOT, ++ cryptodev_digest_init, ++ cryptodev_digest_update, ++ cryptodev_digest_final, ++ cryptodev_digest_copy, ++ cryptodev_digest_cleanup, ++ EVP_PKEY_RSA_method, ++ SHA512_CBLOCK, ++ sizeof(EVP_MD *)+sizeof(struct dev_crypto_state), ++}; ++ ++static const EVP_MD cryptodev_md5 = { ++ NID_md5, ++ NID_md5WithRSAEncryption, ++ 16 /* MD5_DIGEST_LENGTH */, ++ EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT|EVP_MD_FLAG_ONESHOT, ++ cryptodev_digest_init, ++ cryptodev_digest_update, ++ cryptodev_digest_final, ++ cryptodev_digest_copy, ++ cryptodev_digest_cleanup, ++ EVP_PKEY_RSA_method, ++ 64 /* MD5_CBLOCK */, ++ sizeof(EVP_MD *)+sizeof(struct dev_crypto_state), ++}; ++ ++#endif /* USE_CRYPTODEV_DIGESTS */ ++ ++ + static int + cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +@@ -615,10 +939,24 @@ + return (cryptodev_usable_digests(nids)); + + switch (nid) { ++#ifdef USE_CRYPTODEV_DIGESTS + case NID_md5: +- *digest = NULL; /* need to make a clean md5 critter */ ++ *digest = &cryptodev_md5; + break; ++ case NID_sha1: ++ *digest = &cryptodev_sha1; ++ break; ++ case NID_sha256: ++ *digest = &cryptodev_sha256; ++ break; ++ case NID_sha384: ++ *digest = &cryptodev_sha384; ++ break; ++ case NID_sha512: ++ *digest = &cryptodev_sha512; ++ break; + default: ++#endif /* USE_CRYPTODEV_DIGESTS */ + *digest = NULL; + break; + } +@@ -646,8 +984,9 @@ + b = malloc(bytes); + if (b == NULL) + return (1); ++ memset(b, 0, bytes); + +- crp->crp_p = (char *)b; ++ crp->crp_p = (void*) b; + crp->crp_nbits = bits; + + for (i = 0, j = 0; i < a->top; i++) { +@@ -690,7 +1029,7 @@ + { + int i; + +- for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) { ++ for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { + if (kop->crk_param[i].crp_p) + free(kop->crk_param[i].crp_p); + kop->crk_param[i].crp_p = NULL; +@@ -776,8 +1115,9 @@ + cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) + { + int r; +- ++ ctx = BN_CTX_new(); + r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); ++ BN_CTX_free(ctx); + return (r); + } + +@@ -899,7 +1239,7 @@ + kop.crk_op = CRK_DSA_SIGN; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ +- kop.crk_param[0].crp_p = (caddr_t)dgst; ++ kop.crk_param[0].crp_p = (void*)dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; +@@ -939,7 +1279,7 @@ + kop.crk_op = CRK_DSA_VERIFY; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ +- kop.crk_param[0].crp_p = (caddr_t)dgst; ++ kop.crk_param[0].crp_p = (void*)dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; +@@ -1017,7 +1357,7 @@ + goto err; + kop.crk_iparams = 3; + +- kop.crk_param[3].crp_p = (char *)key; ++ kop.crk_param[3].crp_p = (void*) key; + kop.crk_param[3].crp_nbits = keylen * 8; + kop.crk_oparams = 1; + +@@ -1048,7 +1388,7 @@ + * but I expect we'll want some options soon. + */ + static int +-cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) ++cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) + { + #ifdef HAVE_SYSLOG_R + struct syslog_data sd = SYSLOG_DATA_INIT; +@@ -1084,14 +1424,14 @@ + * 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") || ++ !ENGINE_set_name(engine, "cryptodev engine") || + !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || + !ENGINE_set_digests(engine, cryptodev_engine_digests) || + !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || +diff -Naur openssl-0.9.8u.org/crypto/engine/engine.h openssl-0.9.8u/crypto/engine/engine.h +--- openssl-0.9.8u.org/crypto/engine/engine.h 2010-02-09 15:18:15.000000000 +0100 ++++ openssl-0.9.8u/crypto/engine/engine.h 2012-03-27 14:05:15.000000000 +0200 +@@ -705,9 +705,7 @@ + * values. */ + void *ENGINE_get_static_state(void); + +-#if defined(__OpenBSD__) || defined(__FreeBSD__) + void ENGINE_setup_bsd_cryptodev(void); +-#endif + + /* BEGIN ERROR CODES */ + /* The following lines are auto generated by the script mkerr.pl. Any changes +diff -Naur openssl-0.9.8u.org/crypto/evp/c_all.c openssl-0.9.8u/crypto/evp/c_all.c +--- openssl-0.9.8u.org/crypto/evp/c_all.c 2004-08-29 18:36:04.000000000 +0200 ++++ openssl-0.9.8u/crypto/evp/c_all.c 2012-03-27 14:05:15.000000000 +0200 +@@ -83,8 +83,6 @@ + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + #ifndef OPENSSL_NO_ENGINE +-# if defined(__OpenBSD__) || defined(__FreeBSD__) + ENGINE_setup_bsd_cryptodev(); +-# endif + #endif + } -- 2.39.2