[openssl] master update

kaduk at mit.edu kaduk at mit.edu
Wed Jan 6 00:32:47 UTC 2021


The branch master has been updated
       via  7fd1ca723a06739e76a17d1065ac94bcfcfc4f9f (commit)
       via  b39c215decf6e68c28cb64dcfaf5ae5a7e8d35b4 (commit)
      from  3497cc8776d50397ceefbd41bd3356a7f5d30c14 (commit)


- Log -----------------------------------------------------------------
commit 7fd1ca723a06739e76a17d1065ac94bcfcfc4f9f
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Fri Nov 20 17:45:48 2020 -0800

    Support session information on FreeBSD.
    
    FreeBSD's /dev/crypto does not provide a CIOCGSESSINFO ioctl, but it
    does provide other ioctls that can be used to provide similar
    functionality.
    
    First, FreeBSD's /dev/crypto defines a CIOCGESSION2 ioctl which accepts
    a 'struct session2_op'.  This structure extends 'struct session_op'
    with a 'crid' member which can be used to either request an individual
    driver by id, or a class of drivers via flags.
    
    To determine if the available drivers for a given algorithm are
    accelerated or not, use CIOCGESSION2 to first attempt to create an
    accelerated (hardware) session.  If that fails, fall back to
    attempting a software session.  In addition, when requesting a new
    cipher session, use the current setting of the 'use_softdrivers' flag
    to determine the value assigned to 'crid' when invoking CIOCGSESSION2.
    
    Finally, use the returned 'crid' value from CIOCGSESSION2 to look up
    the name of the associated driver via the CIOCFINDDEV ioctl.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Ben Kaduk <kaduk at mit.edu>
    (Merged from https://github.com/openssl/openssl/pull/13468)

commit b39c215decf6e68c28cb64dcfaf5ae5a7e8d35b4
Author: John Baldwin <jhb at FreeBSD.org>
Date:   Fri Nov 20 17:07:35 2020 -0800

    Use CRIOGET to fetch a crypto descriptor when present.
    
    FreeBSD's current /dev/crypto implementation requires that consumers
    clone a separate file descriptor via the CRIOGET ioctl that can then
    be used with other ioctls such as CIOCGSESSION.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Ben Kaduk <kaduk at mit.edu>
    (Merged from https://github.com/openssl/openssl/pull/13468)

-----------------------------------------------------------------------

Summary of changes:
 engines/e_devcrypto.c | 86 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 73 insertions(+), 13 deletions(-)

diff --git a/engines/e_devcrypto.c b/engines/e_devcrypto.c
index d54ca3bbc1..7f3768d36c 100644
--- a/engines/e_devcrypto.c
+++ b/engines/e_devcrypto.c
@@ -34,6 +34,16 @@
 
 #define engine_devcrypto_id "devcrypto"
 
+/*
+ * Use session2_op on FreeBSD which permits requesting specific
+ * drivers or classes of drivers at session creation time.
+ */
+#ifdef CIOCGSESSION2
+typedef struct session2_op session_op_t;
+#else
+typedef struct session_op session_op_t;
+#endif
+
 /*
  * ONE global file descriptor for all sessions.  This allows operations
  * such as digest session data copying (see digest_copy()), but is also
@@ -73,12 +83,12 @@ struct driver_info_st {
 void engine_load_devcrypto_int(void);
 #endif
 
-static int clean_devcrypto_session(struct session_op *sess) {
+static int clean_devcrypto_session(session_op_t *sess) {
     if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
         ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()");
         return 0;
     }
-    memset(sess, 0, sizeof(struct session_op));
+    memset(sess, 0, sizeof(*sess));
     return 1;
 }
 
@@ -93,7 +103,7 @@ static int clean_devcrypto_session(struct session_op *sess) {
  *****/
 
 struct cipher_ctx {
-    struct session_op sess;
+    session_op_t sess;
     int op;                      /* COP_ENCRYPT or COP_DECRYPT */
     unsigned long mode;          /* EVP_CIPH_*_MODE */
 
@@ -198,6 +208,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
         (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
     const struct cipher_data_st *cipher_d =
         get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
+    int ret;
 
     /* cleanup a previous session */
     if (cipher_ctx->sess.ses != 0 &&
@@ -210,7 +221,15 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
     cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
     cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
     cipher_ctx->blocksize = cipher_d->blocksize;
-    if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
+#ifdef CIOCGSESSION2
+    cipher_ctx->sess.crid = (use_softdrivers == DEVCRYPTO_USE_SOFTWARE) ?
+        CRYPTO_FLAG_SOFTWARE | CRYPTO_FLAG_HARDWARE :
+        CRYPTO_FLAG_HARDWARE;
+    ret = ioctl(cfd, CIOCGSESSION2, &cipher_ctx->sess);
+#else
+    ret = ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess);
+#endif
+    if (ret < 0) {
         ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()");
         return 0;
     }
@@ -406,9 +425,12 @@ static int devcrypto_test_cipher(size_t cipher_data_index)
 static void prepare_cipher_methods(void)
 {
     size_t i;
-    struct session_op sess;
+    session_op_t sess;
     unsigned long cipher_mode;
-#ifdef CIOCGSESSINFO
+#ifdef CIOCGSESSION2
+    struct crypt_find_op fop;
+    enum devcrypto_accelerated_t accelerated;
+#elif defined(CIOCGSESSINFO)
     struct session_info_op siop;
 #endif
 
@@ -426,10 +448,29 @@ static void prepare_cipher_methods(void)
          */
         sess.cipher = cipher_data[i].devcryptoid;
         sess.keylen = cipher_data[i].keylen;
+#ifdef CIOCGSESSION2
+        /*
+         * When using CIOCGSESSION2, first try to allocate a hardware
+         * ("accelerated") session.  If that fails, fall back to
+         * allocating a software session.
+         */
+        sess.crid = CRYPTO_FLAG_HARDWARE;
+        if (ioctl(cfd, CIOCGSESSION2, &sess) == 0) {
+            accelerated = DEVCRYPTO_ACCELERATED;
+        } else {
+            sess.crid = CRYPTO_FLAG_SOFTWARE;
+            if (ioctl(cfd, CIOCGSESSION2, &sess) < 0) {
+                cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
+                continue;
+            }
+            accelerated = DEVCRYPTO_NOT_ACCELERATED;
+        }
+#else
         if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
             cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
             continue;
         }
+#endif
 
         cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
 
@@ -460,7 +501,14 @@ static void prepare_cipher_methods(void)
             known_cipher_methods[i] = NULL;
         } else {
             cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
-#ifdef CIOCGSESSINFO
+#ifdef CIOCGSESSION2
+            cipher_driver_info[i].accelerated = accelerated;
+            fop.crid = sess.crid;
+            if (ioctl(cfd, CIOCFINDDEV, &fop) == 0) {
+                cipher_driver_info[i].driver_name =
+                    OPENSSL_strndup(fop.name, sizeof(fop.name));
+            }
+#elif defined(CIOCGSESSINFO)
             siop.ses = sess.ses;
             if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
                 cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
@@ -624,7 +672,7 @@ static void dump_cipher_info(void)
  *****/
 
 struct digest_ctx {
-    struct session_op sess;
+    session_op_t sess;
     /* This signals that the init function was called, not that it succeeded. */
     int init_called;
     unsigned char digest_res[HASH_MAX_LEN];
@@ -843,7 +891,7 @@ static void rebuild_known_digest_nids(ENGINE *e)
 static void prepare_digest_methods(void)
 {
     size_t i;
-    struct session_op sess1, sess2;
+    session_op_t sess1, sess2;
 #ifdef CIOCGSESSINFO
     struct session_info_op siop;
 #endif
@@ -1051,7 +1099,7 @@ static void dump_digest_info(void)
 #define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
 
 static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
-#ifdef CIOCGSESSINFO
+#if defined(CIOCGSESSINFO) || defined(CIOCGSESSION2)
    {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
     "USE_SOFTDRIVERS",
     "specifies whether to use software (not accelerated) drivers ("
@@ -1087,7 +1135,7 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
 {
     int *new_list;
     switch (cmd) {
-#ifdef CIOCGSESSINFO
+#if defined(CIOCGSESSINFO) || defined(CIOCGSESSION2)
     case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
         switch (i) {
         case DEVCRYPTO_REQUIRE_ACCELERATED:
@@ -1106,7 +1154,7 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
 #endif
         rebuild_known_cipher_nids(e);
         return 1;
-#endif /* CIOCGSESSINFO */
+#endif /* CIOCGSESSINFO || CIOCGSESSION2 */
 
     case DEVCRYPTO_CMD_CIPHERS:
         if (p == NULL)
@@ -1172,10 +1220,12 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
  */
 static int open_devcrypto(void)
 {
+    int fd;
+
     if (cfd >= 0)
         return 1;
 
-    if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
+    if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
 #ifndef ENGINE_DEVCRYPTO_DEBUG
         if (errno != ENOENT)
 #endif
@@ -1183,6 +1233,16 @@ static int open_devcrypto(void)
         return 0;
     }
 
+#ifdef CRIOGET
+    if (ioctl(fd, CRIOGET, &cfd) < 0) {
+        fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno));
+        cfd = -1;
+        return 0;
+    }
+#else
+    cfd = fd;
+#endif
+
     return 1;
 }
 


More information about the openssl-commits mailing list