Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 14a87657afc7494ceef26e06acb514e7097e3a20 Mon Sep 17 00:00:00 2001
- From: Matteo Croce <mcroce@redhat.com>
- Date: Sun, 22 Apr 2018 12:24:30 +0200
- Subject: [PATCH] sha1sum: use AF_ALG when available
- Linux supports accessing kernel cryptographic API via AF_ALG since
- version 2.6.38. Coreutils uses libcrypto when available and fallbacks to
- generic C implementation of various hashing functions.
- Add a generic afalg_stream() function which uses AF_ALG to calculate the
- hash of a stream and use sendfile() when possible (regular file with size
- less or equal than 0x7ffff000 (2,147,479,552) bytes, AKA MAX_RW_COUNT).
- USe afalg_stream() only in sha1sum for now, but other hashes are possible.
- Signed-off-by: Matteo Croce <mcroce@redhat.com>
- ---
- lib/af_alg.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- lib/af_alg.h | 46 ++++++++++++++++++++++++
- lib/sha1.c | 14 +++++++-
- modules/crypto/sha1 | 5 ++-
- 4 files changed, 165 insertions(+), 2 deletions(-)
- create mode 100644 lib/af_alg.c
- create mode 100644 lib/af_alg.h
- diff --git a/lib/af_alg.c b/lib/af_alg.c
- new file mode 100644
- index 000000000..0a1437d6c
- --- /dev/null
- +++ b/lib/af_alg.c
- @@ -0,0 +1,102 @@
- +/* AF_ALG support
- +
- + This program is free software; you can redistribute it and/or modify it
- + under the terms of the GNU General Public License as published by the
- + Free Software Foundation; either version 2, or (at your option) any
- + later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, see <https://www.gnu.org/licenses/>. */
- +
- +#include <config.h>
- +
- +#include "af_alg.h"
- +
- +/* from linux/include/linux/fs.h: (INT_MAX & PAGE_MASK) */
- +#define MAX_RW_COUNT 0x7FFFF000
- +#define BLOCKSIZE 32768
- +
- +int
- +afalg_stream (FILE * stream, void *resblock, const char *alg, int hashlen)
- +{
- + struct sockaddr_alg salg = {
- + .salg_family = AF_ALG,
- + .salg_type = "hash",
- + };
- + int ret, cfd, ofd;
- + static char buf[BLOCKSIZE];
- + ssize_t size;
- + struct stat st;
- +
- + strcpy((char *)salg.salg_name, alg);
- + cfd = socket (AF_ALG, SOCK_SEQPACKET, 0);
- + if (cfd < 0)
- + return -EAFNOSUPPORT;
- +
- + ret = bind (cfd, (struct sockaddr *) &salg, sizeof (salg));
- + if (ret < 0)
- + {
- + ret = -EAFNOSUPPORT;
- + goto out_cfd;
- + }
- +
- + ofd = accept (cfd, NULL, 0);
- + if (ofd < 0)
- + {
- + ret = -EAFNOSUPPORT;
- + goto out_ofd;
- + }
- +
- + /* if file is a regular file, attempt sendfile() to pipe the data */
- + if (!fstat(fileno(stream), &st) && S_ISREG(st.st_mode) &&
- + st.st_size <= MAX_RW_COUNT)
- + {
- + if (sendfile(ofd, fileno(stream), NULL, st.st_size) == -1)
- + ret = -EIO;
- + else
- + ret = 0;
- + } else {
- + /* sendfile() not possible, do a classic read-write loop */
- + while ((size = fread (buf, 1, sizeof (buf), stream)))
- + {
- + if (send (ofd, buf, size, size == sizeof (buf) ? MSG_MORE : 0) == -1)
- + {
- + ret = -EIO;
- + goto out_ofd;
- + }
- + }
- + }
- +
- + size = read (ofd, resblock, hashlen);
- + if (size != hashlen)
- + {
- + fprintf (stderr, "Error from read (%zd vs %d bytes): %s\n",
- + size, hashlen, strerror (errno));
- + ret = -EIO;
- + }
- + else
- + {
- + ret = 0;
- + }
- +out_ofd:
- + close (ofd);
- +out_cfd:
- + close (cfd);
- + return ret;
- +}
- +
- +# ifdef __cplusplus
- +}
- +# endif
- +
- +/*
- + * Hey Emacs!
- + * Local Variables:
- + * coding: utf-8
- + * End:
- + */
- diff --git a/lib/af_alg.h b/lib/af_alg.h
- new file mode 100644
- index 000000000..678c03aad
- --- /dev/null
- +++ b/lib/af_alg.h
- @@ -0,0 +1,46 @@
- +/* AF_ALG support
- +
- + This program is free software; you can redistribute it and/or modify it
- + under the terms of the GNU General Public License as published by the
- + Free Software Foundation; either version 2, or (at your option) any
- + later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, see <https://www.gnu.org/licenses/>. */
- +
- +#ifndef AF_ALG_H
- +# define AF_ALG_H 1
- +
- +# include <unistd.h>
- +# include <stdio.h>
- +# include <string.h>
- +# include <errno.h>
- +# include <linux/if_alg.h>
- +# include <sys/socket.h>
- +# include <sys/stat.h>
- +# include <sys/sendfile.h>
- +
- +# ifdef __cplusplus
- +extern "C" {
- +# endif
- +
- +int
- +afalg_stream (FILE * stream, void *resblock, const char *alg, int hashlen);
- +
- +# ifdef __cplusplus
- +}
- +# endif
- +
- +#endif
- +
- +/*
- + * Hey Emacs!
- + * Local Variables:
- + * coding: utf-8
- + * End:
- + */
- diff --git a/lib/sha1.c b/lib/sha1.c
- index 37d46b68e..db85e6ffd 100644
- --- a/lib/sha1.c
- +++ b/lib/sha1.c
- @@ -23,6 +23,8 @@
- #include <config.h>
- +#include "af_alg.h"
- +
- #if HAVE_OPENSSL_SHA1
- # define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
- #endif
- @@ -122,6 +124,7 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
- }
- #endif
- +
- /* Compute SHA1 message digest for bytes read from STREAM. The
- resulting message digest number will be written into the 16 bytes
- beginning at RESBLOCK. */
- @@ -130,8 +133,17 @@ sha1_stream (FILE *stream, void *resblock)
- {
- struct sha1_ctx ctx;
- size_t sum;
- + int ret;
- + char *buffer;
- +
- + ret = afalg_stream(stream, resblock, "sha1", SHA1_DIGEST_SIZE);
- + if (!ret)
- + return 0;
- +
- + if (ret == -EIO)
- + return 1;
- - char *buffer = malloc (BLOCKSIZE + 72);
- + buffer = malloc (BLOCKSIZE + 72);
- if (!buffer)
- return 1;
- diff --git a/modules/crypto/sha1 b/modules/crypto/sha1
- index d65f99418..a2b7df211 100644
- --- a/modules/crypto/sha1
- +++ b/modules/crypto/sha1
- @@ -5,6 +5,8 @@ Files:
- lib/gl_openssl.h
- lib/sha1.h
- lib/sha1.c
- +lib/af_alg.h
- +lib/af_alg.c
- m4/gl-openssl.m4
- m4/sha1.m4
- @@ -17,10 +19,11 @@ configure.ac:
- gl_SHA1
- Makefile.am:
- -lib_SOURCES += sha1.c
- +lib_SOURCES += sha1.c af_alg.c
- Include:
- "sha1.h"
- +"af_alg.h"
- Link:
- $(LIB_CRYPTO)
- --
- 2.14.3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement