OCF相关(三)

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调用不正常...)

猜你喜欢

转载自blog.csdn.net/u012385733/article/details/81135288