proc = fopen("/proc/crypto", "r"); if (!proc) {
printf("Unable to open /proc/crypto\n"); returnfalse;
}
driver_name = NULL;
is_shash = false;
match = false;
/* Look through /proc/crypto for a driver with kernel mode FP usage */ while (!match) {
c = fgets(buf, sizeof(buf), proc); if (!c) { if (feof(proc)) {
printf("Nothing found in /proc/crypto\n"); returnfalse;
} continue;
}
/* Algorithm descriptions are separated by a blank line */ if (*c == '\n') { if (is_shash && driver_name) { for (i = 0; i < ARRAY_SIZE(drivers); i++) { if (strcmp(drivers[i],
driver_name) == 0) {
match = true;
}
}
}
if (!match) {
digest_len = 0;
free(driver_name);
driver_name = NULL;
free(alg_name);
alg_name = NULL;
is_shash = false;
} continue;
}
/* Remove trailing newline */
c = strchr(buf, '\n'); if (c)
*c = '\0';
/* Find the field/value separator and start of the value */
c = strchr(buf, ':'); if (!c) continue;
c += 2;
if (strncmp(buf, "digestsize", strlen("digestsize")) == 0)
sscanf(c, "%d", &digest_len);
if (strncmp(buf, "name", strlen("name")) == 0)
alg_name = strdup(c);
if (strncmp(buf, "driver", strlen("driver")) == 0)
driver_name = strdup(c);
if (strncmp(buf, "type", strlen("type")) == 0) if (strncmp(c, "shash", strlen("shash")) == 0)
is_shash = true;
}
ret = bind(base, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) {
printf("Failed to bind %s: %s (%d)\n",
addr.salg_name, strerror(errno), errno); returnfalse;
}
ret = accept(base, NULL, 0); if (ret < 0) {
printf("Failed to accept %s: %s (%d)\n",
addr.salg_name, strerror(errno), errno); returnfalse;
}
sock = ret;
ret = pipe(zerocopy); if (ret != 0) {
printf("Failed to create zerocopy pipe: %s (%d)\n",
strerror(errno), errno); returnfalse;
}
ref = malloc(digest_len); if (!ref) {
printf("Failed to allocated %d byte reference\n", digest_len); returnfalse;
}
digest = malloc(digest_len); if (!digest) {
printf("Failed to allocated %d byte digest\n", digest_len); returnfalse;
}
returntrue;
}
staticbool compute_digest(void *buf)
{ struct iovec iov; int ret, wrote;
iov = data_iov; while (iov.iov_len) {
ret = vmsplice(zerocopy[1], &iov, 1, SPLICE_F_GIFT); if (ret < 0) {
printf("Failed to send buffer: %s (%d)\n",
strerror(errno), errno); returnfalse;
}
wrote = ret;
ret = splice(zerocopy[0], NULL, sock, NULL, wrote, 0); if (ret < 0) {
printf("Failed to splice buffer: %s (%d)\n",
strerror(errno), errno);
} elseif (ret != wrote) {
printf("Short splice: %d < %d\n", ret, wrote);
}
iov.iov_len -= wrote;
iov.iov_base += wrote;
}
reread:
ret = recv(sock, buf, digest_len, 0); if (ret == 0) {
printf("No digest returned\n"); returnfalse;
} if (ret != digest_len) { if (errno == -EAGAIN) goto reread;
printf("Failed to get digest: %s (%d)\n",
strerror(errno), errno); returnfalse;
}
returntrue;
}
int main(void)
{ char *data; struct sigaction sa; int ret;
/* Ensure we have unbuffered output */
setvbuf(stdout, NULL, _IOLBF, 0);
/* The parent will communicate with us via signals */
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handle_exit_signal;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigemptyset(&sa.sa_mask);
ret = sigaction(SIGTERM, &sa, NULL); if (ret < 0)
printf("Failed to install SIGTERM handler: %s (%d)\n",
strerror(errno), errno);
sa.sa_sigaction = handle_kick_signal;
ret = sigaction(SIGUSR1, &sa, NULL); if (ret < 0)
printf("Failed to install SIGUSR1 handler: %s (%d)\n",
strerror(errno), errno);
ret = sigaction(SIGUSR2, &sa, NULL); if (ret < 0)
printf("Failed to install SIGUSR2 handler: %s (%d)\n",
strerror(errno), errno);
data = malloc(DATA_SIZE); if (!data) {
printf("Failed to allocate data buffer\n"); return EXIT_FAILURE;
}
memset(data, 0, DATA_SIZE);
/* * If we can't create a socket assume it's a lack of system * support and fall back to a basic FPSIMD test for the * benefit of fp-stress.
*/ if (!create_socket()) {
execl("./fpsimd-test", "./fpsimd-test", NULL);
printf("Failed to fall back to fspimd-test: %d (%s)\n",
errno, strerror(errno)); return EXIT_FAILURE;
}
/* * Compute a reference digest we hope is repeatable, we do * this at runtime partly to make it easier to play with * parameters.
*/ if (!compute_digest(ref)) {
printf("Failed to compute reference digest\n"); return EXIT_FAILURE;
}
printf("AF_ALG using %s\n", alg_name);
while (true) { if (!compute_digest(digest)) {
printf("Failed to compute digest, iter=%d\n", iter); return EXIT_FAILURE;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.