]> Savannah Git Hosting - gnulib.git/commitdiff
crypto/gc-sm3: Fix compilation error with --with-libgcrypt.
authorBruno Haible <bruno@clisp.org>
Sat, 24 Aug 2019 14:16:33 +0000 (16:16 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 24 Aug 2019 14:16:33 +0000 (16:16 +0200)
* m4/gc-sm3.m4 (gl_GC_SM3): Test whether libgcrypt supports SM3. Define
LIBGCRYPT_HAS_MD_SM3.
* lib/gc-libgcrypt.c: Include sm3.h.
(_gc_hash_ctx, gc_hash_open, gc_hash_hmac_setkey, gc_hash_write,
gc_hash_read, gc_hash_close, gc_hash_buffer, gc_sm3): Use the gnulib
implementation if libgcrypt does not support SM3.

ChangeLog
lib/gc-libgcrypt.c
m4/gc-sm3.m4

index 54802599bc9193f7b997792c27d68292069ac065..b126ba9a340de54bb33fa82b2752c2898ae97c4f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2019-08-24  Bruno Haible  <bruno@clisp.org>
+
+       crypto/gc-sm3: Fix compilation error with --with-libgcrypt.
+       * m4/gc-sm3.m4 (gl_GC_SM3): Test whether libgcrypt supports SM3. Define
+       LIBGCRYPT_HAS_MD_SM3.
+       * lib/gc-libgcrypt.c: Include sm3.h.
+       (_gc_hash_ctx, gc_hash_open, gc_hash_hmac_setkey, gc_hash_write,
+       gc_hash_read, gc_hash_close, gc_hash_buffer, gc_sm3): Use the gnulib
+       implementation if libgcrypt does not support SM3.
+
 2019-08-24  Bruno Haible  <bruno@clisp.org>
 
        crypto/gc-md2: Optimize and clarify code.
index fbfd0a138fa578c2e5f7bb9f4401c650c15453d9..3ca17c2639996b2d3a68555c27828946f495a805 100644 (file)
@@ -33,6 +33,9 @@
    MD2 algorithm.  Therefore take the implementation from gnulib.  */
 # include "md2.h"
 #endif
+#if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
+# include "sm3.h"
+#endif
 
 #include <assert.h>
 
@@ -243,14 +246,22 @@ gc_cipher_close (gc_cipher_handle handle)
 
 /* Hashes. */
 
+/* Maximum of GC_MD2_DIGEST_SIZE and GC_SM3_DIGEST_SIZE.  */
+#define MAX_DIGEST_SIZE 32
+
 typedef struct _gc_hash_ctx {
   Gc_hash alg;
   Gc_hash_mode mode;
   gcry_md_hd_t gch;
+#if GNULIB_GC_MD2 || (GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3)
+  char hash[MAX_DIGEST_SIZE];
+#endif
 #if GNULIB_GC_MD2
-  char hash[GC_MD2_DIGEST_SIZE];
   struct md2_ctx md2Context;
 #endif
+#if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
+  struct sm3_ctx sm3Context;
+#endif
 } _gc_hash_ctx;
 
 Gc_rc
@@ -312,7 +323,12 @@ gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
 
 #if GNULIB_GC_SM3
     case GC_SM3:
+# if LIBGCRYPT_HAS_MD_SM3
       gcryalg = GCRY_MD_SM3;
+# else
+      sm3_init_ctx (&ctx->sm3Context);
+      gcryalg = GCRY_MD_NONE;
+# endif
       break;
 #endif
 
@@ -433,7 +449,10 @@ gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
 #if GNULIB_GC_MD2
   if (ctx->alg != GC_MD2)
 #endif
-    gcry_md_setkey (ctx->gch, key, len);
+#if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
+    if (ctx->alg != GC_SM3)
+#endif
+      gcry_md_setkey (ctx->gch, key, len);
 }
 
 void
@@ -445,6 +464,11 @@ gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
   if (ctx->alg == GC_MD2)
     md2_process_bytes (data, len, &ctx->md2Context);
   else
+#endif
+#if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
+  if (ctx->alg == GC_SM3)
+    sm3_process_bytes (data, len, &ctx->sm3Context);
+  else
 #endif
     gcry_md_write (ctx->gch, data, len);
 }
@@ -462,6 +486,14 @@ gc_hash_read (gc_hash_handle handle)
       digest = ctx->hash;
     }
   else
+#endif
+#if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
+  if (ctx->alg == GC_SM3)
+    {
+      sm3_finish_ctx (&ctx->sm3Context, ctx->hash);
+      digest = ctx->hash;
+    }
+  else
 #endif
     {
       gcry_md_final (ctx->gch);
@@ -479,7 +511,10 @@ gc_hash_close (gc_hash_handle handle)
 #if GNULIB_GC_MD2
   if (ctx->alg != GC_MD2)
 #endif
-    gcry_md_close (ctx->gch);
+#if GNULIB_GC_SM3 && !LIBGCRYPT_HAS_MD_SM3
+    if (ctx->alg != GC_SM3)
+#endif
+      gcry_md_close (ctx->gch);
 
   free (ctx);
 }
@@ -495,7 +530,6 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
     case GC_MD2:
       md2_buffer (in, inlen, resbuf);
       return GC_OK;
-      break;
 #endif
 
 #if GNULIB_GC_MD4
@@ -548,8 +582,13 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
 
 #if GNULIB_GC_SM3
     case GC_SM3:
+# if !LIBGCRYPT_HAS_MD_SM3
+      sm3_buffer (in, inlen, resbuf);
+      return GC_OK;
+# else
       gcryalg = GCRY_MD_SM3;
       break;
+# endif
 #endif
 
     default:
@@ -672,6 +711,10 @@ gc_sha1 (const void *in, size_t inlen, void *resbuf)
 Gc_rc
 gc_sm3  (const void *in, size_t inlen, void *resbuf)
 {
+# if !LIBGCRYPT_HAS_MD_SM3
+  sm3_buffer (in, inlen, resbuf);
+  return GC_OK;
+# else
   size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SM3);
   gcry_md_hd_t hd;
   gpg_error_t err;
@@ -697,6 +740,7 @@ gc_sm3  (const void *in, size_t inlen, void *resbuf)
   gcry_md_close (hd);
 
   return GC_OK;
+# endif
 }
 #endif
 
index 7eac44818d850afa2b43ddaecaf07c3e0c3ca405..992217d9fe184059fab4f9c68187c37008f8dbd9 100644 (file)
@@ -1,4 +1,4 @@
-# gc-sm3.m4 serial 1
+# gc-sm3.m4 serial 2
 dnl Copyright (C) 2017-2019 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -7,4 +7,19 @@ dnl with or without modifications, as long as this notice is preserved.
 AC_DEFUN([gl_GC_SM3],
 [
   AC_REQUIRE([gl_GC])
+  AC_CACHE_CHECK([whether libgcrypt supports SM3],
+    [gl_cv_libcrypt_md_sm3],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+          #include <gcrypt.h>
+          int a = GCRY_MD_SM3;
+          ]], [[]])
+       ],
+       [gl_cv_libcrypt_md_sm3=yes],
+       [gl_cv_libcrypt_md_sm3=no])
+    ])
+  if test $gl_cv_libcrypt_md_sm3 = yes; then
+    AC_DEFINE([LIBGCRYPT_HAS_MD_SM3], [1],
+      [Define if libgcrypt supports the MD algorithm SM3.])
+  fi
 ])