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