Advertisement
teknoraver

sha1sum af_alg

Feb 28th, 2018
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 6.47 KB | None | 0 0
  1. From 14a87657afc7494ceef26e06acb514e7097e3a20 Mon Sep 17 00:00:00 2001
  2. From: Matteo Croce <mcroce@redhat.com>
  3. Date: Sun, 22 Apr 2018 12:24:30 +0200
  4. Subject: [PATCH] sha1sum: use AF_ALG when available
  5.  
  6. Linux supports accessing kernel cryptographic API via AF_ALG since
  7. version 2.6.38. Coreutils uses libcrypto when available and fallbacks to
  8. generic C implementation of various hashing functions.
  9. Add a generic afalg_stream() function which uses AF_ALG to calculate the
  10. hash of a stream and use sendfile() when possible (regular file with size
  11. less or equal than 0x7ffff000 (2,147,479,552) bytes, AKA MAX_RW_COUNT).
  12. USe afalg_stream() only in sha1sum for now, but other hashes are possible.
  13.  
  14. Signed-off-by: Matteo Croce <mcroce@redhat.com>
  15. ---
  16. lib/af_alg.c        | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
  17.  lib/af_alg.h        |  46 ++++++++++++++++++++++++
  18.  lib/sha1.c          |  14 +++++++-
  19.  modules/crypto/sha1 |   5 ++-
  20.  4 files changed, 165 insertions(+), 2 deletions(-)
  21.  create mode 100644 lib/af_alg.c
  22.  create mode 100644 lib/af_alg.h
  23.  
  24. diff --git a/lib/af_alg.c b/lib/af_alg.c
  25. new file mode 100644
  26. index 000000000..0a1437d6c
  27. --- /dev/null
  28. +++ b/lib/af_alg.c
  29. @@ -0,0 +1,102 @@
  30. +/* AF_ALG support
  31. +
  32. +   This program is free software; you can redistribute it and/or modify it
  33. +   under the terms of the GNU General Public License as published by the
  34. +   Free Software Foundation; either version 2, or (at your option) any
  35. +   later version.
  36. +
  37. +   This program is distributed in the hope that it will be useful,
  38. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  39. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  40. +   GNU General Public License for more details.
  41. +
  42. +   You should have received a copy of the GNU General Public License
  43. +   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
  44. +
  45. +#include <config.h>
  46. +
  47. +#include "af_alg.h"
  48. +
  49. +/* from linux/include/linux/fs.h: (INT_MAX & PAGE_MASK) */
  50. +#define MAX_RW_COUNT 0x7FFFF000
  51. +#define BLOCKSIZE 32768
  52. +
  53. +int
  54. +afalg_stream (FILE * stream, void *resblock, const char *alg, int hashlen)
  55. +{
  56. +  struct sockaddr_alg salg = {
  57. +    .salg_family = AF_ALG,
  58. +    .salg_type = "hash",
  59. +  };
  60. +  int ret, cfd, ofd;
  61. +  static char buf[BLOCKSIZE];
  62. +  ssize_t size;
  63. +  struct stat st;
  64. +
  65. +  strcpy((char *)salg.salg_name, alg);
  66. +  cfd = socket (AF_ALG, SOCK_SEQPACKET, 0);
  67. +  if (cfd < 0)
  68. +      return -EAFNOSUPPORT;
  69. +
  70. +  ret = bind (cfd, (struct sockaddr *) &salg, sizeof (salg));
  71. +  if (ret < 0)
  72. +    {
  73. +      ret = -EAFNOSUPPORT;
  74. +      goto out_cfd;
  75. +    }
  76. +
  77. +  ofd = accept (cfd, NULL, 0);
  78. +  if (ofd < 0)
  79. +    {
  80. +      ret = -EAFNOSUPPORT;
  81. +      goto out_ofd;
  82. +    }
  83. +
  84. +  /* if file is a regular file, attempt sendfile() to pipe the data */
  85. +  if (!fstat(fileno(stream), &st) && S_ISREG(st.st_mode) &&
  86. +      st.st_size <= MAX_RW_COUNT)
  87. +    {
  88. +      if (sendfile(ofd, fileno(stream), NULL, st.st_size) == -1)
  89. +        ret = -EIO;
  90. +      else
  91. +        ret = 0;
  92. +    } else {
  93. +      /* sendfile() not possible, do a classic read-write loop */
  94. +      while ((size = fread (buf, 1, sizeof (buf), stream)))
  95. +        {
  96. +          if (send (ofd, buf, size, size == sizeof (buf) ? MSG_MORE : 0) == -1)
  97. +            {
  98. +              ret = -EIO;
  99. +              goto out_ofd;
  100. +            }
  101. +        }
  102. +  }
  103. +
  104. +  size = read (ofd, resblock, hashlen);
  105. +  if (size != hashlen)
  106. +    {
  107. +      fprintf (stderr, "Error from read (%zd vs %d bytes): %s\n",
  108. +               size, hashlen, strerror (errno));
  109. +      ret = -EIO;
  110. +    }
  111. +  else
  112. +    {
  113. +      ret = 0;
  114. +    }
  115. +out_ofd:
  116. +  close (ofd);
  117. +out_cfd:
  118. +  close (cfd);
  119. +  return ret;
  120. +}
  121. +
  122. +# ifdef __cplusplus
  123. +}
  124. +# endif
  125. +
  126. +/*
  127. + * Hey Emacs!
  128. + * Local Variables:
  129. + * coding: utf-8
  130. + * End:
  131. + */
  132. diff --git a/lib/af_alg.h b/lib/af_alg.h
  133. new file mode 100644
  134. index 000000000..678c03aad
  135. --- /dev/null
  136. +++ b/lib/af_alg.h
  137. @@ -0,0 +1,46 @@
  138. +/* AF_ALG support
  139. +
  140. +   This program is free software; you can redistribute it and/or modify it
  141. +   under the terms of the GNU General Public License as published by the
  142. +   Free Software Foundation; either version 2, or (at your option) any
  143. +   later version.
  144. +
  145. +   This program is distributed in the hope that it will be useful,
  146. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  147. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  148. +   GNU General Public License for more details.
  149. +
  150. +   You should have received a copy of the GNU General Public License
  151. +   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
  152. +
  153. +#ifndef AF_ALG_H
  154. +# define AF_ALG_H 1
  155. +
  156. +# include <unistd.h>
  157. +# include <stdio.h>
  158. +# include <string.h>
  159. +# include <errno.h>
  160. +# include <linux/if_alg.h>
  161. +# include <sys/socket.h>
  162. +# include <sys/stat.h>
  163. +# include <sys/sendfile.h>
  164. +
  165. +# ifdef __cplusplus
  166. +extern "C" {
  167. +# endif
  168. +
  169. +int
  170. +afalg_stream (FILE * stream, void *resblock, const char *alg, int hashlen);
  171. +
  172. +# ifdef __cplusplus
  173. +}
  174. +# endif
  175. +
  176. +#endif
  177. +
  178. +/*
  179. + * Hey Emacs!
  180. + * Local Variables:
  181. + * coding: utf-8
  182. + * End:
  183. + */
  184. diff --git a/lib/sha1.c b/lib/sha1.c
  185. index 37d46b68e..db85e6ffd 100644
  186. --- a/lib/sha1.c
  187. +++ b/lib/sha1.c
  188. @@ -23,6 +23,8 @@
  189.  
  190.  #include <config.h>
  191.  
  192. +#include "af_alg.h"
  193. +
  194.  #if HAVE_OPENSSL_SHA1
  195.  # define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
  196.  #endif
  197. @@ -122,6 +124,7 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
  198.  }
  199.  #endif
  200.  
  201. +
  202.  /* Compute SHA1 message digest for bytes read from STREAM.  The
  203.     resulting message digest number will be written into the 16 bytes
  204.     beginning at RESBLOCK.  */
  205. @@ -130,8 +133,17 @@ sha1_stream (FILE *stream, void *resblock)
  206.  {
  207.    struct sha1_ctx ctx;
  208.    size_t sum;
  209. +  int ret;
  210. +  char *buffer;
  211. +
  212. +  ret = afalg_stream(stream, resblock, "sha1", SHA1_DIGEST_SIZE);
  213. +  if (!ret)
  214. +      return 0;
  215. +
  216. +  if (ret == -EIO)
  217. +      return 1;
  218.  
  219. -  char *buffer = malloc (BLOCKSIZE + 72);
  220. +  buffer = malloc (BLOCKSIZE + 72);
  221.    if (!buffer)
  222.      return 1;
  223.  
  224. diff --git a/modules/crypto/sha1 b/modules/crypto/sha1
  225. index d65f99418..a2b7df211 100644
  226. --- a/modules/crypto/sha1
  227. +++ b/modules/crypto/sha1
  228. @@ -5,6 +5,8 @@ Files:
  229.  lib/gl_openssl.h
  230.  lib/sha1.h
  231.  lib/sha1.c
  232. +lib/af_alg.h
  233. +lib/af_alg.c
  234.  m4/gl-openssl.m4
  235.  m4/sha1.m4
  236.  
  237. @@ -17,10 +19,11 @@ configure.ac:
  238.  gl_SHA1
  239.  
  240.  Makefile.am:
  241. -lib_SOURCES += sha1.c
  242. +lib_SOURCES += sha1.c af_alg.c
  243.  
  244.  Include:
  245.  "sha1.h"
  246. +"af_alg.h"
  247.  
  248.  Link:
  249.  $(LIB_CRYPTO)
  250. --
  251. 2.14.3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement