Commit 2afebe0b authored by Eneas U de Queiroz's avatar Eneas U de Queiroz Committed by Richard Levitte
Browse files

e_devcrypto: make the /dev/crypto engine dynamic



Engine has been moved from crypto/engine/eng_devcrypto.c to
engines/e_devcrypto.c.

Signed-off-by: default avatarEneas U de Queiroz <cote2004-github@yahoo.com>

Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7859)
parent 9a18aae5
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\
        tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
        eng_openssl.c eng_cnf.c eng_dyn.c \
        eng_rdrand.c
IF[{- !$disabled{devcryptoeng} -}]
  SOURCE[../../libcrypto]=eng_devcrypto.c
ENDIF
+17 −17
Original line number Diff line number Diff line
@@ -353,18 +353,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
    engine_load_openssl_int();
    return 1;
}
# ifndef OPENSSL_NO_DEVCRYPTOENG
static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
{
#  ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
                    "engine_load_devcrypto_int()\n");
#  endif
    engine_load_devcrypto_int();
    return 1;
}
# endif

# ifndef OPENSSL_NO_RDRAND
static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
@@ -389,6 +377,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
    return 1;
}
# ifndef OPENSSL_NO_STATIC_ENGINE
#  ifndef OPENSSL_NO_DEVCRYPTOENG
static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
{
#   ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
                    "engine_load_devcrypto_int()\n");
#   endif
    engine_load_devcrypto_int();
    return 1;
}
#  endif
#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
@@ -747,11 +747,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
    if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
            && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
        return 0;
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
            && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
        return 0;
# endif
# ifndef OPENSSL_NO_RDRAND
    if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
            && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
@@ -761,6 +756,11 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
            && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
        return 0;
# ifndef OPENSSL_NO_STATIC_ENGINE
#  ifndef OPENSSL_NO_DEVCRYPTOENG
    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
            && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
        return 0;
#  endif
#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
    if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
            && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
+13 −0
Original line number Diff line number Diff line
@@ -10,6 +10,9 @@ IF[{- !$disabled{"engine"} -}]
    IF[{- !$disabled{afalgeng} -}]
      SOURCE[../libcrypto]=e_afalg.c
    ENDIF
    IF[{- !$disabled{"devcryptoeng"} -}]
      SOURCE[../libcrypto]=e_devcrypto.c
    ENDIF
  ELSE
    MODULES{engine}=padlock
    SOURCE[padlock]=e_padlock.c {- $target{padlock_asm_src} -}
@@ -39,6 +42,16 @@ IF[{- !$disabled{"engine"} -}]
        GENERATE[afalg.ld]=../util/engines.num
      ENDIF
    ENDIF
    IF[{- !$disabled{"devcryptoeng"} -}]
      ENGINES=devcrypto
      SOURCE[devcrypto]=e_devcrypto.c
      DEPEND[devcrypto]=../libcrypto
      INCLUDE[devcrypto]=../include
      IF[{- defined $target{shared_defflag} -}]
        SHARED_SOURCE[devcrypto]=devcrypto.ld
        GENERATE[devcrypto.ld]=../util/engines.num
      ENDIF
    ENDIF

    MODULES{noinst,engine}=ossltest dasync
    SOURCE[dasync]=e_dasync.c
+91 −43
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 * https://www.openssl.org/source/license.html
 */

#include "e_os.h"
#include "../e_os.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -23,20 +23,20 @@
#include <openssl/objects.h>
#include <crypto/cryptodev.h>

#include "internal/engine.h"

/* #define ENGINE_DEVCRYPTO_DEBUG */

#ifdef CRYPTO_ALGORITHM_MIN
# define CHECK_BSD_STYLE_MACROS
#endif

#define engine_devcrypto_id "devcrypto"

/*
 * ONE global file descriptor for all sessions.  This allows operations
 * such as digest session data copying (see digest_copy()), but is also
 * saner...  why re-open /dev/crypto for every session?
 */
static int cfd;
static int cfd = -1;
#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
#define DEVCRYPTO_USE_SOFTWARE        1 /* allow software drivers */
#define DEVCRYPTO_REJECT_SOFTWARE     2 /* only disallow confirmed software drivers */
@@ -66,6 +66,10 @@ struct driver_info_st {
    char *driver_name;
};

#ifdef OPENSSL_NO_DYNAMIC_ENGINE
void engine_load_devcrypto_int(void);
#endif

/******************************************************************************
 *
 * Ciphers
@@ -1138,55 +1142,67 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
 *
 *****/

static int devcrypto_unload(ENGINE *e)
{
    destroy_all_cipher_methods();
#ifdef IMPLEMENT_DIGEST
    destroy_all_digest_methods();
#endif

    close(cfd);

    return 1;
}
/*
 * This engine is always built into libcrypto, so it doesn't offer any
 * ability to be dynamically loadable.
 * Opens /dev/crypto
 */
void engine_load_devcrypto_int()
static int open_devcrypto(void)
{
    ENGINE *e = NULL;
    if (cfd >= 0)
        return 1;

    if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
#ifndef ENGINE_DEVCRYPTO_DEBUG
        if (errno != ENOENT)
#endif
            fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno));
        return;
        return 0;
    }

    if ((e = ENGINE_new()) == NULL
        || !ENGINE_set_destroy_function(e, devcrypto_unload)) {
        ENGINE_free(e);
        /*
         * We know that devcrypto_unload() won't be called when one of the
         * above two calls have failed, so we close cfd explicitly here to
         * avoid leaking resources.
         */
        close(cfd);
        return;
    return 1;
}

    prepare_cipher_methods();
static int close_devcrypto(void)
{
    if (cfd < 0)
        return 1;
    cfd = -1;
    if (close(cfd) == 0) {
        fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno));
        return 0;
    }
    return 1;
}

static int devcrypto_unload(ENGINE *e)
{
    destroy_all_cipher_methods();
#ifdef IMPLEMENT_DIGEST
    prepare_digest_methods();
    destroy_all_digest_methods();
#endif

    if (!ENGINE_set_id(e, "devcrypto")
    close_devcrypto();

    return 1;
}

static int bind_devcrypto(ENGINE *e) {

    if (!ENGINE_set_id(e, engine_devcrypto_id)
        || !ENGINE_set_name(e, "/dev/crypto engine")
        || !ENGINE_set_destroy_function(e, devcrypto_unload)
        || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
        || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)
        || !ENGINE_set_ctrl_function(e, devcrypto_ctrl))
        return 0;

    prepare_cipher_methods();
#ifdef IMPLEMENT_DIGEST
    prepare_digest_methods();
#endif

    return (ENGINE_set_ciphers(e, devcrypto_ciphers)
#ifdef IMPLEMENT_DIGEST
        && ENGINE_set_digests(e, devcrypto_digests)
#endif
/*
 * Asymmetric ciphers aren't well supported with /dev/crypto.  Among the BSD
 * implementations, it seems to only exist in FreeBSD, and regarding the
@@ -1209,23 +1225,36 @@ void engine_load_devcrypto_int()
 */
#if 0
# ifndef OPENSSL_NO_RSA
        || !ENGINE_set_RSA(e, devcrypto_rsa)
        && ENGINE_set_RSA(e, devcrypto_rsa)
# endif
# ifndef OPENSSL_NO_DSA
        || !ENGINE_set_DSA(e, devcrypto_dsa)
        && ENGINE_set_DSA(e, devcrypto_dsa)
# endif
# ifndef OPENSSL_NO_DH
        || !ENGINE_set_DH(e, devcrypto_dh)
        && ENGINE_set_DH(e, devcrypto_dh)
# endif
# ifndef OPENSSL_NO_EC
        || !ENGINE_set_EC(e, devcrypto_ec)
        && ENGINE_set_EC(e, devcrypto_ec)
# endif
#endif
        || !ENGINE_set_ciphers(e, devcrypto_ciphers)
#ifdef IMPLEMENT_DIGEST
        || !ENGINE_set_digests(e, devcrypto_digests)
#endif
        ) {
        );
}

#ifdef OPENSSL_NO_DYNAMIC_ENGINE
/*
 * In case this engine is built into libcrypto, then it doesn't offer any
 * ability to be dynamically loadable.
 */
void engine_load_devcrypto_int(void)
{
    ENGINE *e = NULL;

    if (!open_devcrypto())
        return;

    if ((e = ENGINE_new()) == NULL
        || !bind_devcrypto(e)) {
        close_devcrypto();
        ENGINE_free(e);
        return;
    }
@@ -1234,3 +1263,22 @@ void engine_load_devcrypto_int()
    ENGINE_free(e);          /* Loose our local reference */
    ERR_clear_error();
}

#else

static int bind_helper(ENGINE *e, const char *id)
{
    if ((id && (strcmp(id, engine_devcrypto_id) != 0))
        || !open_devcrypto())
        return 0;
    if (!bind_devcrypto(e)) {
        close_devcrypto();
        return 0;
    }
    return 1;
}

IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)

#endif