| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- From 78e7b1cc7119622645bc5a8542c55b6c95dc7868 Mon Sep 17 00:00:00 2001
- From: Eneas U de Queiroz <[email protected]>
- Date: Tue, 6 Nov 2018 22:54:07 -0200
- Subject: eng_devcrypto: add command to dump driver info
- This is useful to determine the kernel driver running each algorithm.
- Signed-off-by: Eneas U de Queiroz <[email protected]>
- Reviewed-by: Matthias St. Pierre <[email protected]>
- Reviewed-by: Richard Levitte <[email protected]>
- (Merged from https://github.com/openssl/openssl/pull/7585)
- diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c
- index 5ec38ca8f3..64dc6b891d 100644
- --- a/crypto/engine/eng_devcrypto.c
- +++ b/crypto/engine/eng_devcrypto.c
- @@ -50,16 +50,20 @@ static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
- */
- struct driver_info_st {
- enum devcrypto_status_t {
- - DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */
- - DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
- - DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
- + DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
- + DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
- + DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
- + DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
- + DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
- } status;
-
- enum devcrypto_accelerated_t {
- - DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
- - DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
- - DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
- + DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
- + DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
- + DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
- } accelerated;
- +
- + char *driver_name;
- };
-
- static int clean_devcrypto_session(struct session_op *sess) {
- @@ -415,7 +419,7 @@ static void prepare_cipher_methods(void)
- sess.cipher = cipher_data[i].devcryptoid;
- sess.keylen = cipher_data[i].keylen;
- if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
- - cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- + cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
- continue;
- }
-
- @@ -443,19 +447,24 @@ static void prepare_cipher_methods(void)
- cipher_cleanup)
- || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
- sizeof(struct cipher_ctx))) {
- - cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- + cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
- EVP_CIPHER_meth_free(known_cipher_methods[i]);
- known_cipher_methods[i] = NULL;
- } else {
- cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
- #ifdef CIOCGSESSINFO
- siop.ses = sess.ses;
- - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
- + if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
- - else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
- - cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
- - else
- - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
- + } else {
- + cipher_driver_info[i].driver_name =
- + OPENSSL_strndup(siop.cipher_info.cra_driver_name,
- + CRYPTODEV_MAX_ALG_NAME);
- + if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
- + cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
- + else
- + cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
- + }
- #endif /* CIOCGSESSINFO */
- }
- ioctl(cfd, CIOCFSESSION, &sess.ses);
- @@ -505,8 +514,11 @@ static void destroy_all_cipher_methods(void)
- {
- size_t i;
-
- - for (i = 0; i < OSSL_NELEM(cipher_data); i++)
- + for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
- destroy_cipher_method(cipher_data[i].nid);
- + OPENSSL_free(cipher_driver_info[i].driver_name);
- + cipher_driver_info[i].driver_name = NULL;
- + }
- }
-
- static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
- @@ -550,6 +562,40 @@ static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
- return 1;
- }
-
- +static void dump_cipher_info(void)
- +{
- + size_t i;
- + const char *name;
- +
- + fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
- + " engine:\n");
- +#ifndef CIOCGSESSINFO
- + fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
- +#endif
- + for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
- + name = OBJ_nid2sn(cipher_data[i].nid);
- + fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
- + name ? name : "unknown", cipher_data[i].nid,
- + cipher_data[i].devcryptoid);
- + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
- + fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
- + continue;
- + }
- + fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
- + cipher_driver_info[i].driver_name : "unknown");
- + if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
- + fprintf(stderr, "(hw accelerated)");
- + else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
- + fprintf(stderr, "(software)");
- + else
- + fprintf(stderr, "(acceleration status unknown)");
- + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
- + fprintf (stderr, ". Cipher setup failed");
- + fprintf(stderr, "\n");
- + }
- + fprintf(stderr, "\n");
- +}
- +
- /*
- * We only support digests if the cryptodev implementation supports multiple
- * data updates and session copying. Otherwise, we would be forced to maintain
- @@ -812,31 +858,36 @@ static void prepare_digest_methods(void)
- sess1.mac = digest_data[i].devcryptoid;
- sess2.ses = 0;
- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
- - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- + digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
- goto finish;
- }
-
- #ifdef CIOCGSESSINFO
- /* gather hardware acceleration info from the driver */
- siop.ses = sess1.ses;
- - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
- + if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
- - else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
- - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
- - else
- - digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
- + } else {
- + digest_driver_info[i].driver_name =
- + OPENSSL_strndup(siop.hash_info.cra_driver_name,
- + CRYPTODEV_MAX_ALG_NAME);
- + if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
- + digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
- + else
- + digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
- + }
- #endif
-
- /* digest must be capable of hash state copy */
- sess2.mac = sess1.mac;
- if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
- - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- + digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
- goto finish;
- }
- cphash.src_ses = sess1.ses;
- cphash.dst_ses = sess2.ses;
- if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
- - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- + digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
- goto finish;
- }
- if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
- @@ -852,7 +903,7 @@ static void prepare_digest_methods(void)
- || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
- || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
- sizeof(struct digest_ctx))) {
- - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- + digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
- EVP_MD_meth_free(known_digest_methods[i]);
- known_digest_methods[i] = NULL;
- goto finish;
- @@ -894,8 +945,11 @@ static void destroy_all_digest_methods(void)
- {
- size_t i;
-
- - for (i = 0; i < OSSL_NELEM(digest_data); i++)
- + for (i = 0; i < OSSL_NELEM(digest_data); i++) {
- destroy_digest_method(digest_data[i].nid);
- + OPENSSL_free(digest_driver_info[i].driver_name);
- + digest_driver_info[i].driver_name = NULL;
- + }
- }
-
- static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
- @@ -939,6 +993,43 @@ static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
- return 1;
- }
-
- +static void dump_digest_info(void)
- +{
- + size_t i;
- + const char *name;
- +
- + fprintf (stderr, "Information about digests supported by the /dev/crypto"
- + " engine:\n");
- +#ifndef CIOCGSESSINFO
- + fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
- +#endif
- +
- + for (i = 0; i < OSSL_NELEM(digest_data); i++) {
- + name = OBJ_nid2sn(digest_data[i].nid);
- + fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
- + name ? name : "unknown", digest_data[i].nid,
- + digest_data[i].devcryptoid,
- + digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
- + if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
- + fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
- + continue;
- + }
- + if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
- + fprintf(stderr, " (hw accelerated)");
- + else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
- + fprintf(stderr, " (software)");
- + else
- + fprintf(stderr, " (acceleration status unknown)");
- + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
- + fprintf (stderr, ". Cipher setup failed\n");
- + else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
- + fprintf(stderr, ", CIOCCPHASH failed\n");
- + else
- + fprintf(stderr, ", CIOCCPHASH capable\n");
- + }
- + fprintf(stderr, "\n");
- +}
- +
- #endif
-
- /******************************************************************************
- @@ -983,6 +1074,11 @@ static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
- ENGINE_CMD_FLAG_STRING},
- #endif
-
- + {DEVCRYPTO_CMD_DUMP_INFO,
- + "DUMP_INFO",
- + "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
- + ENGINE_CMD_FLAG_NO_INPUT},
- +
- {0, NULL, NULL, 0}
- };
-
- @@ -1051,6 +1147,13 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
- return 1;
- #endif /* IMPLEMENT_DIGEST */
-
- + case DEVCRYPTO_CMD_DUMP_INFO:
- + dump_cipher_info();
- +#ifdef IMPLEMENT_DIGEST
- + dump_digest_info();
- +#endif
- + return 1;
- +
- default:
- break;
- }
|