420-eng_devcrypto-add-command-to-dump-driver-info.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. From 78e7b1cc7119622645bc5a8542c55b6c95dc7868 Mon Sep 17 00:00:00 2001
  2. From: Eneas U de Queiroz <[email protected]>
  3. Date: Tue, 6 Nov 2018 22:54:07 -0200
  4. Subject: eng_devcrypto: add command to dump driver info
  5. This is useful to determine the kernel driver running each algorithm.
  6. Signed-off-by: Eneas U de Queiroz <[email protected]>
  7. Reviewed-by: Matthias St. Pierre <[email protected]>
  8. Reviewed-by: Richard Levitte <[email protected]>
  9. (Merged from https://github.com/openssl/openssl/pull/7585)
  10. diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c
  11. index 5ec38ca8f3..64dc6b891d 100644
  12. --- a/crypto/engine/eng_devcrypto.c
  13. +++ b/crypto/engine/eng_devcrypto.c
  14. @@ -50,16 +50,20 @@ static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
  15. */
  16. struct driver_info_st {
  17. enum devcrypto_status_t {
  18. - DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */
  19. - DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
  20. - DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
  21. + DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
  22. + DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
  23. + DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
  24. + DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
  25. + DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
  26. } status;
  27. enum devcrypto_accelerated_t {
  28. - DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
  29. - DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
  30. - DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
  31. + DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
  32. + DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
  33. + DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
  34. } accelerated;
  35. +
  36. + char *driver_name;
  37. };
  38. static int clean_devcrypto_session(struct session_op *sess) {
  39. @@ -415,7 +419,7 @@ static void prepare_cipher_methods(void)
  40. sess.cipher = cipher_data[i].devcryptoid;
  41. sess.keylen = cipher_data[i].keylen;
  42. if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
  43. - cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
  44. + cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
  45. continue;
  46. }
  47. @@ -443,19 +447,24 @@ static void prepare_cipher_methods(void)
  48. cipher_cleanup)
  49. || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
  50. sizeof(struct cipher_ctx))) {
  51. - cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
  52. + cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
  53. EVP_CIPHER_meth_free(known_cipher_methods[i]);
  54. known_cipher_methods[i] = NULL;
  55. } else {
  56. cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
  57. #ifdef CIOCGSESSINFO
  58. siop.ses = sess.ses;
  59. - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
  60. + if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
  61. cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
  62. - else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
  63. - cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
  64. - else
  65. - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
  66. + } else {
  67. + cipher_driver_info[i].driver_name =
  68. + OPENSSL_strndup(siop.cipher_info.cra_driver_name,
  69. + CRYPTODEV_MAX_ALG_NAME);
  70. + if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
  71. + cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
  72. + else
  73. + cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
  74. + }
  75. #endif /* CIOCGSESSINFO */
  76. }
  77. ioctl(cfd, CIOCFSESSION, &sess.ses);
  78. @@ -505,8 +514,11 @@ static void destroy_all_cipher_methods(void)
  79. {
  80. size_t i;
  81. - for (i = 0; i < OSSL_NELEM(cipher_data); i++)
  82. + for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
  83. destroy_cipher_method(cipher_data[i].nid);
  84. + OPENSSL_free(cipher_driver_info[i].driver_name);
  85. + cipher_driver_info[i].driver_name = NULL;
  86. + }
  87. }
  88. static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
  89. @@ -550,6 +562,40 @@ static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
  90. return 1;
  91. }
  92. +static void dump_cipher_info(void)
  93. +{
  94. + size_t i;
  95. + const char *name;
  96. +
  97. + fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
  98. + " engine:\n");
  99. +#ifndef CIOCGSESSINFO
  100. + fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
  101. +#endif
  102. + for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
  103. + name = OBJ_nid2sn(cipher_data[i].nid);
  104. + fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
  105. + name ? name : "unknown", cipher_data[i].nid,
  106. + cipher_data[i].devcryptoid);
  107. + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
  108. + fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
  109. + continue;
  110. + }
  111. + fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
  112. + cipher_driver_info[i].driver_name : "unknown");
  113. + if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
  114. + fprintf(stderr, "(hw accelerated)");
  115. + else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
  116. + fprintf(stderr, "(software)");
  117. + else
  118. + fprintf(stderr, "(acceleration status unknown)");
  119. + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
  120. + fprintf (stderr, ". Cipher setup failed");
  121. + fprintf(stderr, "\n");
  122. + }
  123. + fprintf(stderr, "\n");
  124. +}
  125. +
  126. /*
  127. * We only support digests if the cryptodev implementation supports multiple
  128. * data updates and session copying. Otherwise, we would be forced to maintain
  129. @@ -812,31 +858,36 @@ static void prepare_digest_methods(void)
  130. sess1.mac = digest_data[i].devcryptoid;
  131. sess2.ses = 0;
  132. if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
  133. - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
  134. + digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
  135. goto finish;
  136. }
  137. #ifdef CIOCGSESSINFO
  138. /* gather hardware acceleration info from the driver */
  139. siop.ses = sess1.ses;
  140. - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
  141. + if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
  142. digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
  143. - else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
  144. - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
  145. - else
  146. - digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
  147. + } else {
  148. + digest_driver_info[i].driver_name =
  149. + OPENSSL_strndup(siop.hash_info.cra_driver_name,
  150. + CRYPTODEV_MAX_ALG_NAME);
  151. + if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
  152. + digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
  153. + else
  154. + digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
  155. + }
  156. #endif
  157. /* digest must be capable of hash state copy */
  158. sess2.mac = sess1.mac;
  159. if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
  160. - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
  161. + digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
  162. goto finish;
  163. }
  164. cphash.src_ses = sess1.ses;
  165. cphash.dst_ses = sess2.ses;
  166. if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
  167. - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
  168. + digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
  169. goto finish;
  170. }
  171. if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
  172. @@ -852,7 +903,7 @@ static void prepare_digest_methods(void)
  173. || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
  174. || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
  175. sizeof(struct digest_ctx))) {
  176. - digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
  177. + digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
  178. EVP_MD_meth_free(known_digest_methods[i]);
  179. known_digest_methods[i] = NULL;
  180. goto finish;
  181. @@ -894,8 +945,11 @@ static void destroy_all_digest_methods(void)
  182. {
  183. size_t i;
  184. - for (i = 0; i < OSSL_NELEM(digest_data); i++)
  185. + for (i = 0; i < OSSL_NELEM(digest_data); i++) {
  186. destroy_digest_method(digest_data[i].nid);
  187. + OPENSSL_free(digest_driver_info[i].driver_name);
  188. + digest_driver_info[i].driver_name = NULL;
  189. + }
  190. }
  191. static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
  192. @@ -939,6 +993,43 @@ static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
  193. return 1;
  194. }
  195. +static void dump_digest_info(void)
  196. +{
  197. + size_t i;
  198. + const char *name;
  199. +
  200. + fprintf (stderr, "Information about digests supported by the /dev/crypto"
  201. + " engine:\n");
  202. +#ifndef CIOCGSESSINFO
  203. + fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
  204. +#endif
  205. +
  206. + for (i = 0; i < OSSL_NELEM(digest_data); i++) {
  207. + name = OBJ_nid2sn(digest_data[i].nid);
  208. + fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
  209. + name ? name : "unknown", digest_data[i].nid,
  210. + digest_data[i].devcryptoid,
  211. + digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
  212. + if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
  213. + fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
  214. + continue;
  215. + }
  216. + if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
  217. + fprintf(stderr, " (hw accelerated)");
  218. + else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
  219. + fprintf(stderr, " (software)");
  220. + else
  221. + fprintf(stderr, " (acceleration status unknown)");
  222. + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
  223. + fprintf (stderr, ". Cipher setup failed\n");
  224. + else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
  225. + fprintf(stderr, ", CIOCCPHASH failed\n");
  226. + else
  227. + fprintf(stderr, ", CIOCCPHASH capable\n");
  228. + }
  229. + fprintf(stderr, "\n");
  230. +}
  231. +
  232. #endif
  233. /******************************************************************************
  234. @@ -983,6 +1074,11 @@ static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
  235. ENGINE_CMD_FLAG_STRING},
  236. #endif
  237. + {DEVCRYPTO_CMD_DUMP_INFO,
  238. + "DUMP_INFO",
  239. + "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
  240. + ENGINE_CMD_FLAG_NO_INPUT},
  241. +
  242. {0, NULL, NULL, 0}
  243. };
  244. @@ -1051,6 +1147,13 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
  245. return 1;
  246. #endif /* IMPLEMENT_DIGEST */
  247. + case DEVCRYPTO_CMD_DUMP_INFO:
  248. + dump_cipher_info();
  249. +#ifdef IMPLEMENT_DIGEST
  250. + dump_digest_info();
  251. +#endif
  252. + return 1;
  253. +
  254. default:
  255. break;
  256. }