openssl 1.0.2h cryptodev改为仅内核软件加解密
patch如下
--- openssl-1.0.2h/crypto/engine/eng_cryptodev.c 2016-05-03 21:44:42.000000000 +0800
+++ openssl-1.0.2h_lastest/crypto/engine/eng_cryptodev.c 2018-07-19 19:06:27.455562915 +0800
@@ -79,6 +79,12 @@
# endif
};
+#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
+#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
+#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
+#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
+
+
static u_int32_t cryptodev_asymfeat = 0;
static int get_asym_dev_crypto(void);
@@ -283,6 +289,13 @@
* returning them here is harmless, as long as we return NULL
* when asked for a handler in the cryptodev_engine_ciphers routine
*/
+
+/*
+* make openssl use the kernel software device to enc/dec data, replace hardware device support.
+* this is bug, the bug is kernel crypto engine issue.
+* modified by june on 2018-07-19
+*/
+#if 0
static int get_cryptodev_ciphers(const int **cnids)
{
static int nids[CRYPTO_ALGORITHM_MAX];
@@ -315,6 +328,46 @@
return (count);
}
+#else
+
+static int get_cryptodev_ciphers(const int **cnids)
+{
+ static int nids[CRYPTO_ALGORITHM_MAX];
+ struct session2_op sess;
+ int fd, i, count = 0;
+
+ if ((fd = get_dev_crypto()) < 0) {
+ *cnids = NULL;
+ return (0);
+ }
+ memset(&sess, 0, sizeof(sess));
+ sess.key = (caddr_t) "123456789abcdefghijklmno";
+ /*software implement inside kernel(may be hardware implemention)*/
+ sess.crid = CRYPTOCAP_F_SOFTWARE;
+
+ for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
+ if (ciphers[i].nid == NID_undef)
+ continue;
+ sess.cipher = ciphers[i].id;
+ sess.keylen = ciphers[i].keylen;
+ sess.mac = 0;
+ if (ioctl(fd, CIOCGSESSION2, &sess) != -1 &&
+ ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+ nids[count++] = ciphers[i].nid;
+ }
+ put_dev_crypto(fd);
+
+ if (count > 0)
+ *cnids = nids;
+ else
+ *cnids = NULL;
+ return (count);
+}
+
+
+
+#endif
+
# ifdef USE_CRYPTODEV_DIGESTS
/*
* Find out what digests /dev/crypto will let us have a session for.
@@ -457,6 +510,7 @@
return (1);
}
+#if 0
static int
cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
@@ -492,8 +546,64 @@
state->d_fd = -1;
return (0);
}
+ memcpy(sess, &tmp_sess, sizeof(struct session_op));
+ return (1);
+}
+
+
+#else
+/*
+*soft implement inside kernel
+* modified by june 2018-07-19
+*/
+static int
+cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ struct dev_crypto_state *state = ctx->cipher_data;
+ struct session_op *sess = &state->d_sess;
+ struct session2_op tmp_sess;
+ int cipher = -1, i;
+
+ 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 (!ciphers[i].id) {
+ state->d_fd = -1;
+ return (0);
+ }
+
+ memset(sess, 0, sizeof(struct session_op));
+ memset(&tmp_sess, 0, sizeof(struct session2_op));
+
+ if ((state->d_fd = get_dev_crypto()) < 0)
+ return (0);
+
+ sess->key = (caddr_t) key;
+ sess->keylen = ctx->key_len;
+ sess->cipher = cipher;
+
+ tmp_sess.key = (caddr_t) key;
+ tmp_sess.keylen = ctx->key_len;
+ tmp_sess.cipher = cipher;
+ tmp_sess.crid = CRYPTOCAP_F_SOFTWARE;
+
+
+ /*if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {*/
+ if (ioctl(state->d_fd, CIOCGSESSION2, &tmp_sess) == -1) {
+ put_dev_crypto(state->d_fd);
+ state->d_fd = -1;
+ return (0);
+ }
+ memcpy(sess, &tmp_sess, sizeof(struct session_op));
return (1);
}
+#endif
/*
* free anything we allocated earlier when initting a
上面只修了对称加密相关的部分,摘要加密没有修改
修改原理
将session_op 改为session2_op,因为session2_op比session_op多了一个crid,这个crid可以指定软件或者硬件加解密
crid = CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE; //软硬共存
or
crid = CRYPTO_FLAG_HARDWARE //仅硬件
or
crid = CRYPTO_FLAG_SOFTWARE //仅软件
/* NB: deprecated */
struct session_op {
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
u_int32_t keylen; /* cipher key */
caddr_t key;
int mackeylen; /* mac key */
caddr_t mackey;
u_int32_t ses; /* returns: session # */
};
struct session2_op {
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
u_int32_t keylen; /* cipher key */
caddr_t key;
int mackeylen; /* mac key */
caddr_t mackey;
u_int32_t ses; /* returns: session # */
int crid; /* driver id + flags (rw) */
int pad[4]; /* for future expansion */
};
(其实这样改,是因为高通的驱动写的有点不太通用,ipsec调用正常,而openssl调用不正常...)