~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/crypto/getstat.c

Version: ~ [ linux-5.8-rc3 ] ~ [ linux-5.7.5 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.48 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.129 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.185 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.228 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.228 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* Heavily copied from libkcapi 2015 - 2017, Stephan Mueller <smueller@chronox.de> */
  2 #include <errno.h>
  3 #include <linux/cryptouser.h>
  4 #include <linux/netlink.h>
  5 #include <linux/rtnetlink.h>
  6 #include <sys/types.h>
  7 #include <sys/socket.h>
  8 #include <stdlib.h>
  9 #include <stdio.h>
 10 #include <string.h>
 11 #include <time.h>
 12 #include <unistd.h>
 13 
 14 #define CR_RTA(x)  ((struct rtattr *)(((char *)(x)) + NLMSG_ALIGN(sizeof(struct crypto_user_alg))))
 15 
 16 static int get_stat(const char *drivername)
 17 {
 18         struct {
 19                 struct nlmsghdr n;
 20                 struct crypto_user_alg cru;
 21         } req;
 22         struct sockaddr_nl nl;
 23         int sd = 0, ret;
 24         socklen_t addr_len;
 25         struct iovec iov;
 26         struct msghdr msg;
 27         char buf[4096];
 28         struct nlmsghdr *res_n = (struct nlmsghdr *)buf;
 29         struct crypto_user_alg *cru_res = NULL;
 30         int res_len = 0;
 31         struct rtattr *tb[CRYPTOCFGA_MAX + 1];
 32         struct rtattr *rta;
 33         struct nlmsgerr *errmsg;
 34 
 35         memset(&req, 0, sizeof(req));
 36         memset(&buf, 0, sizeof(buf));
 37         memset(&msg, 0, sizeof(msg));
 38 
 39         req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.cru));
 40         req.n.nlmsg_flags = NLM_F_REQUEST;
 41         req.n.nlmsg_type = CRYPTO_MSG_GETSTAT;
 42         req.n.nlmsg_seq = time(NULL);
 43 
 44         strncpy(req.cru.cru_driver_name, drivername, strlen(drivername));
 45 
 46         sd =  socket(AF_NETLINK, SOCK_RAW, NETLINK_CRYPTO);
 47         if (sd < 0) {
 48                 fprintf(stderr, "Netlink error: cannot open netlink socket");
 49                 return -errno;
 50         }
 51         memset(&nl, 0, sizeof(nl));
 52         nl.nl_family = AF_NETLINK;
 53         if (bind(sd, (struct sockaddr *)&nl, sizeof(nl)) < 0) {
 54                 ret = -errno;
 55                 fprintf(stderr, "Netlink error: cannot bind netlink socket");
 56                 goto out;
 57         }
 58 
 59         /* sanity check that netlink socket was successfully opened */
 60         addr_len = sizeof(nl);
 61         if (getsockname(sd, (struct sockaddr *)&nl, &addr_len) < 0) {
 62                 ret = -errno;
 63                 printf("Netlink error: cannot getsockname");
 64                 goto out;
 65         }
 66         if (addr_len != sizeof(nl)) {
 67                 ret = -errno;
 68                 printf("Netlink error: wrong address length %d", addr_len);
 69                 goto out;
 70         }
 71         if (nl.nl_family != AF_NETLINK) {
 72                 ret = -errno;
 73                 printf("Netlink error: wrong address family %d",
 74                                 nl.nl_family);
 75                 goto out;
 76         }
 77 
 78         memset(&nl, 0, sizeof(nl));
 79         nl.nl_family = AF_NETLINK;
 80         iov.iov_base = (void *)&req.n;
 81         iov.iov_len = req.n.nlmsg_len;
 82         msg.msg_name = &nl;
 83         msg.msg_namelen = sizeof(nl);
 84         msg.msg_iov = &iov;
 85         msg.msg_iovlen = 1;
 86         if (sendmsg(sd, &msg, 0) < 0) {
 87                 ret = -errno;
 88                 printf("Netlink error: sendmsg failed");
 89                 goto out;
 90         }
 91         memset(buf, 0, sizeof(buf));
 92         iov.iov_base = buf;
 93         while (1) {
 94                 iov.iov_len = sizeof(buf);
 95                 ret = recvmsg(sd, &msg, 0);
 96                 if (ret < 0) {
 97                         if (errno == EINTR || errno == EAGAIN)
 98                                 continue;
 99                         ret = -errno;
100                         printf("Netlink error: netlink receive error");
101                         goto out;
102                 }
103                 if (ret == 0) {
104                         ret = -errno;
105                         printf("Netlink error: no data");
106                         goto out;
107                 }
108                 if (ret > sizeof(buf)) {
109                         ret = -errno;
110                         printf("Netlink error: received too much data");
111                         goto out;
112                 }
113                 break;
114         }
115 
116         ret = -EFAULT;
117         res_len = res_n->nlmsg_len;
118         if (res_n->nlmsg_type == NLMSG_ERROR) {
119                 errmsg = NLMSG_DATA(res_n);
120                 fprintf(stderr, "Fail with %d\n", errmsg->error);
121                 ret = errmsg->error;
122                 goto out;
123         }
124 
125         if (res_n->nlmsg_type == CRYPTO_MSG_GETSTAT) {
126                 cru_res = NLMSG_DATA(res_n);
127                 res_len -= NLMSG_SPACE(sizeof(*cru_res));
128         }
129         if (res_len < 0) {
130                 printf("Netlink error: nlmsg len %d\n", res_len);
131                 goto out;
132         }
133 
134         if (!cru_res) {
135                 ret = -EFAULT;
136                 printf("Netlink error: no cru_res\n");
137                 goto out;
138         }
139 
140         rta = CR_RTA(cru_res);
141         memset(tb, 0, sizeof(struct rtattr *) * (CRYPTOCFGA_MAX + 1));
142         while (RTA_OK(rta, res_len)) {
143                 if ((rta->rta_type <= CRYPTOCFGA_MAX) && (!tb[rta->rta_type]))
144                         tb[rta->rta_type] = rta;
145                 rta = RTA_NEXT(rta, res_len);
146         }
147         if (res_len) {
148                 printf("Netlink error: unprocessed data %d",
149                                 res_len);
150                 goto out;
151         }
152 
153         if (tb[CRYPTOCFGA_STAT_HASH]) {
154                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_HASH];
155                 struct crypto_stat_hash *rhash =
156                         (struct crypto_stat_hash *)RTA_DATA(rta);
157                 printf("%s\tHash\n\tHash: %llu bytes: %llu\n\tErrors: %llu\n",
158                         drivername,
159                         rhash->stat_hash_cnt, rhash->stat_hash_tlen,
160                         rhash->stat_err_cnt);
161         } else if (tb[CRYPTOCFGA_STAT_COMPRESS]) {
162                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_COMPRESS];
163                 struct crypto_stat_compress *rblk =
164                         (struct crypto_stat_compress *)RTA_DATA(rta);
165                 printf("%s\tCompress\n\tCompress: %llu bytes: %llu\n\tDecompress: %llu bytes: %llu\n\tErrors: %llu\n",
166                         drivername,
167                         rblk->stat_compress_cnt, rblk->stat_compress_tlen,
168                         rblk->stat_decompress_cnt, rblk->stat_decompress_tlen,
169                         rblk->stat_err_cnt);
170         } else if (tb[CRYPTOCFGA_STAT_ACOMP]) {
171                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_ACOMP];
172                 struct crypto_stat_compress *rcomp =
173                         (struct crypto_stat_compress *)RTA_DATA(rta);
174                 printf("%s\tACompress\n\tCompress: %llu bytes: %llu\n\tDecompress: %llu bytes: %llu\n\tErrors: %llu\n",
175                         drivername,
176                         rcomp->stat_compress_cnt, rcomp->stat_compress_tlen,
177                         rcomp->stat_decompress_cnt, rcomp->stat_decompress_tlen,
178                         rcomp->stat_err_cnt);
179         } else if (tb[CRYPTOCFGA_STAT_AEAD]) {
180                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_AEAD];
181                 struct crypto_stat_aead *raead =
182                         (struct crypto_stat_aead *)RTA_DATA(rta);
183                 printf("%s\tAEAD\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tErrors: %llu\n",
184                         drivername,
185                         raead->stat_encrypt_cnt, raead->stat_encrypt_tlen,
186                         raead->stat_decrypt_cnt, raead->stat_decrypt_tlen,
187                         raead->stat_err_cnt);
188         } else if (tb[CRYPTOCFGA_STAT_BLKCIPHER]) {
189                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_BLKCIPHER];
190                 struct crypto_stat_cipher *rblk =
191                         (struct crypto_stat_cipher *)RTA_DATA(rta);
192                 printf("%s\tCipher\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tErrors: %llu\n",
193                         drivername,
194                         rblk->stat_encrypt_cnt, rblk->stat_encrypt_tlen,
195                         rblk->stat_decrypt_cnt, rblk->stat_decrypt_tlen,
196                         rblk->stat_err_cnt);
197         } else if (tb[CRYPTOCFGA_STAT_AKCIPHER]) {
198                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_AKCIPHER];
199                 struct crypto_stat_akcipher *rblk =
200                         (struct crypto_stat_akcipher *)RTA_DATA(rta);
201                 printf("%s\tAkcipher\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tSign: %llu\n\tVerify: %llu\n\tErrors: %llu\n",
202                         drivername,
203                         rblk->stat_encrypt_cnt, rblk->stat_encrypt_tlen,
204                         rblk->stat_decrypt_cnt, rblk->stat_decrypt_tlen,
205                         rblk->stat_sign_cnt, rblk->stat_verify_cnt,
206                         rblk->stat_err_cnt);
207         } else if (tb[CRYPTOCFGA_STAT_CIPHER]) {
208                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_CIPHER];
209                 struct crypto_stat_cipher *rblk =
210                         (struct crypto_stat_cipher *)RTA_DATA(rta);
211                 printf("%s\tcipher\n\tEncrypt: %llu bytes: %llu\n\tDecrypt: %llu bytes: %llu\n\tErrors: %llu\n",
212                         drivername,
213                         rblk->stat_encrypt_cnt, rblk->stat_encrypt_tlen,
214                         rblk->stat_decrypt_cnt, rblk->stat_decrypt_tlen,
215                         rblk->stat_err_cnt);
216         } else if (tb[CRYPTOCFGA_STAT_RNG]) {
217                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_RNG];
218                 struct crypto_stat_rng *rrng =
219                         (struct crypto_stat_rng *)RTA_DATA(rta);
220                 printf("%s\tRNG\n\tSeed: %llu\n\tGenerate: %llu bytes: %llu\n\tErrors: %llu\n",
221                         drivername,
222                         rrng->stat_seed_cnt,
223                         rrng->stat_generate_cnt, rrng->stat_generate_tlen,
224                         rrng->stat_err_cnt);
225         } else if (tb[CRYPTOCFGA_STAT_KPP]) {
226                 struct rtattr *rta = tb[CRYPTOCFGA_STAT_KPP];
227                 struct crypto_stat_kpp *rkpp =
228                         (struct crypto_stat_kpp *)RTA_DATA(rta);
229                 printf("%s\tKPP\n\tSetsecret: %llu\n\tGenerate public key: %llu\n\tCompute_shared_secret: %llu\n\tErrors: %llu\n",
230                         drivername,
231                         rkpp->stat_setsecret_cnt,
232                         rkpp->stat_generate_public_key_cnt,
233                         rkpp->stat_compute_shared_secret_cnt,
234                         rkpp->stat_err_cnt);
235         } else {
236                 fprintf(stderr, "%s is of an unknown algorithm\n", drivername);
237         }
238         ret = 0;
239 out:
240         close(sd);
241         return ret;
242 }
243 
244 int main(int argc, const char *argv[])
245 {
246         char buf[4096];
247         FILE *procfd;
248         int i, lastspace;
249         int ret;
250 
251         procfd = fopen("/proc/crypto", "r");
252         if (!procfd) {
253                 ret = errno;
254                 fprintf(stderr, "Cannot open /proc/crypto %s\n", strerror(errno));
255                 return ret;
256         }
257         if (argc > 1) {
258                 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
259                         printf("Usage: %s [-h|--help] display this help\n", argv[0]);
260                         printf("Usage: %s display all crypto statistics\n", argv[0]);
261                         printf("Usage: %s drivername1 drivername2 ... = display crypto statistics about drivername1 ...\n", argv[0]);
262                         return 0;
263                 }
264                 for (i = 1; i < argc; i++) {
265                         ret = get_stat(argv[i]);
266                         if (ret) {
267                                 fprintf(stderr, "Failed with %s\n", strerror(-ret));
268                                 return ret;
269                         }
270                 }
271                 return 0;
272         }
273 
274         while (fgets(buf, sizeof(buf), procfd)) {
275                 if (!strncmp(buf, "driver", 6)) {
276                         lastspace = 0;
277                         i = 0;
278                         while (i < strlen(buf)) {
279                                 i++;
280                                 if (buf[i] == ' ')
281                                         lastspace = i;
282                         }
283                         buf[strlen(buf) - 1] = '\0';
284                         ret = get_stat(buf + lastspace + 1);
285                         if (ret) {
286                                 fprintf(stderr, "Failed with %s\n", strerror(-ret));
287                                 goto out;
288                         }
289                 }
290         }
291 out:
292         fclose(procfd);
293         return ret;
294 }
295 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp