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