Hi Bruno, I refreshed the patches based on the latest master branch.
Basically the problem we discussed may still exist. But anyway we have a clear patch without the sm3 basis. Changelog: - fix the following 10 failures: [gc-gnulib.c] 8 failures lib/gc-gnulib.c: In function 'gc_init': lib/gc-gnulib.c:87:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_init (void) ^~~~~~~ lib/gc-gnulib.c: In function 'gc_done': lib/gc-gnulib.c:114:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_done (void) ^~~~~~~ lib/gc-gnulib.c: In function 'gc_set_allocators': lib/gc-gnulib.c:217:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_set_allocators (gc_malloc_t func_malloc, ^~~~~~~~~~~~~~~~~ lib/gc-gnulib.c: In function 'gc_cipher_setkey': lib/gc-gnulib.c:334:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) ^~~~~~~~~~~~~~~~ lib/gc-gnulib.c: In function 'gc_cipher_setiv': lib/gc-gnulib.c:398:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) ^~~~~~~~~~~~~~~ lib/gc-gnulib.c: In function 'gc_cipher_encrypt_inline': lib/gc-gnulib.c:452:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) ^~~~~~~~~~~~~~~~~~~~~~~~ lib/gc-gnulib.c: In function 'gc_cipher_decrypt_inline': lib/gc-gnulib.c:522:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) ^~~~~~~~~~~~~~~~~~~~~~~~ lib/gc-gnulib.c: In function 'gc_hash_digest_length': lib/gc-gnulib.c:706:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_hash_digest_length (Gc_hash hash) ^~~~~~~~~~~~~~~~~~~~~ [gc-libgcrypt.c] 2 failures lib/gc-libgcrypt.c: In function 'gc_done': lib/gc-libgcrypt.c:66:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_done (void) ^~~~~~~ lib/gc-libgcrypt.c: In function 'gc_hash_digest_length': lib/gc-libgcrypt.c:368:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_hash_digest_length (Gc_hash hash) ^~~~~~~~~~~~~~~~~~~~~ Thanks, Jia
From 8d10627e9371aadaf00771bcb29a73420b891cd4 Mon Sep 17 00:00:00 2001 From: Jia Zhang <qianyue...@alibaba-inc.com> Date: Sat, 28 Oct 2017 23:58:20 -0400 Subject: [PATCH 1/2] sm3: add the support for compiling with libgcrypt * lib/gc-gnulib.c: Support sm3 in internal functions. * lib/gc-libgcrypt.c: Support sm3 with libgcrypt. * lib/gc.h: Declear SM3-related stuffs. * m4/gc-sm3.m4: m4 file for gc-sm3 module. * modules/crypto/gc-sm3: Define gc-sm3 module. * modules/crypto/gc-sm3-tests: Define gc-sm3 test module. * tests/test-gc-sm3.c: Implement SM3 test case with libgcrypt. * MODULES.html.sh: List gc-sm3 module. --- MODULES.html.sh | 1 + lib/gc-gnulib.c | 44 +++++++++++++++ lib/gc-libgcrypt.c | 46 ++++++++++++++++ lib/gc.h | 5 +- m4/gc-sm3.m4 | 10 ++++ modules/crypto/gc-sm3 | 24 +++++++++ modules/crypto/gc-sm3-tests | 11 ++++ tests/test-gc-sm3.c | 129 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 m4/gc-sm3.m4 create mode 100644 modules/crypto/gc-sm3 create mode 100644 modules/crypto/gc-sm3-tests create mode 100644 tests/test-gc-sm3.c diff --git a/MODULES.html.sh b/MODULES.html.sh index 7729772ec..2cf7594a1 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1988,6 +1988,7 @@ func_all_modules () func_module crypto/gc-random func_module crypto/gc-rijndael func_module crypto/gc-sha1 + func_module crypto/gc-sm3 func_end_table element="Compiler warning management" diff --git a/lib/gc-gnulib.c b/lib/gc-gnulib.c index 61d5d980a..f888cf597 100644 --- a/lib/gc-gnulib.c +++ b/lib/gc-gnulib.c @@ -48,6 +48,9 @@ #ifdef GNULIB_GC_SHA1 # include "sha1.h" #endif +#ifdef GNULIB_GC_SM3 +# include "sm3.h" +#endif #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1) || defined(GNULIB_GC_HMAC_SHA256) || defined(GNULIB_GC_HMAC_SHA512) # include "hmac.h" #endif @@ -618,6 +621,9 @@ typedef struct _gc_hash_ctx #ifdef GNULIB_GC_SHA1 struct sha1_ctx sha1Context; #endif +#ifdef GNULIB_GC_SM3 + struct sm3_ctx sm3Context; +#endif } _gc_hash_ctx; Gc_rc @@ -662,6 +668,12 @@ gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) break; #endif +#ifdef GNULIB_GC_SM3 + case GC_SM3: + sm3_init_ctx (&ctx->sm3Context); + break; +#endif + default: rc = GC_INVALID_HASH; break; @@ -717,6 +729,10 @@ gc_hash_digest_length (Gc_hash hash) len = GC_SHA1_DIGEST_SIZE; break; + case GC_SM3: + len = GC_SM3_DIGEST_SIZE; + break; + default: return 0; } @@ -755,6 +771,12 @@ gc_hash_write (gc_hash_handle handle, size_t len, const char *data) break; #endif +#ifdef GNULIB_GC_SM3 + case GC_SM3: + sm3_process_bytes (data, len, &ctx->sm3Context); + break; +#endif + default: break; } @@ -796,6 +818,13 @@ gc_hash_read (gc_hash_handle handle) break; #endif +#ifdef GNULIB_GC_SM3 + case GC_SM3: + sm3_finish_ctx (&ctx->sm3Context, ctx->hash); + ret = ctx->hash; + break; +#endif + default: return NULL; } @@ -840,6 +869,12 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) break; #endif +#ifdef GNULIB_GC_SM3 + case GC_SM3: + sm3_buffer (in, inlen, resbuf); + break; +#endif + default: return GC_INVALID_HASH; } @@ -883,6 +918,15 @@ gc_sha1 (const void *in, size_t inlen, void *resbuf) } #endif +#ifdef GNULIB_GC_SM3 +Gc_rc +gc_sm3 (const void *in, size_t inlen, void *resbuf) +{ + sm3_buffer (in, inlen, resbuf); + return GC_OK; +} +#endif + #ifdef GNULIB_GC_HMAC_MD5 Gc_rc gc_hmac_md5 (const void *key, size_t keylen, diff --git a/lib/gc-libgcrypt.c b/lib/gc-libgcrypt.c index f0c8d8229..49ba0e13c 100644 --- a/lib/gc-libgcrypt.c +++ b/lib/gc-libgcrypt.c @@ -304,6 +304,10 @@ gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) gcryalg = GCRY_MD_RMD160; break; + case GC_SM3: + gcryalg = GCRY_MD_SM3; + break; + default: rc = GC_INVALID_HASH; } @@ -403,6 +407,10 @@ gc_hash_digest_length (Gc_hash hash) len = GC_SHA224_DIGEST_SIZE; break; + case GC_SM3: + len = GC_SM3_DIGEST_SIZE; + break; + default: return 0; } @@ -530,6 +538,12 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) break; #endif +#ifdef GNULIB_GC_SM3 + case GC_SM3: + gcryalg = GCRY_MD_SM3; + break; +#endif + default: return GC_INVALID_HASH; } @@ -646,6 +660,38 @@ gc_sha1 (const void *in, size_t inlen, void *resbuf) } #endif +#ifdef GNULIB_GC_SM3 +Gc_rc +gc_sm3 (const void *in, size_t inlen, void *resbuf) +{ + size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SM3); + gcry_md_hd_t hd; + gpg_error_t err; + unsigned char *p; + + assert (outlen == GC_SM3_DIGEST_SIZE); + + err = gcry_md_open (&hd, GCRY_MD_SM3, 0); + if (err != GPG_ERR_NO_ERROR) + return GC_INVALID_HASH; + + gcry_md_write (hd, in, inlen); + + p = gcry_md_read (hd, GCRY_MD_SM3); + if (p == NULL) + { + gcry_md_close (hd); + return GC_INVALID_HASH; + } + + memcpy (resbuf, p, outlen); + + gcry_md_close (hd); + + return GC_OK; +} +#endif + #ifdef GNULIB_GC_HMAC_MD5 Gc_rc gc_hmac_md5 (const void *key, size_t keylen, diff --git a/lib/gc.h b/lib/gc.h index a47cc8d0e..e65ba49a3 100644 --- a/lib/gc.h +++ b/lib/gc.h @@ -47,7 +47,8 @@ enum Gc_hash GC_SHA256, GC_SHA384, GC_SHA512, - GC_SHA224 + GC_SHA224, + GC_SM3 }; typedef enum Gc_hash Gc_hash; @@ -69,6 +70,7 @@ typedef void *gc_hash_handle; #define GC_SHA384_DIGEST_SIZE 48 #define GC_SHA512_DIGEST_SIZE 64 #define GC_SHA224_DIGEST_SIZE 24 +#define GC_SM3_DIGEST_SIZE 32 /* Cipher types. */ enum Gc_cipher @@ -156,6 +158,7 @@ extern Gc_rc gc_md2 (const void *in, size_t inlen, void *resbuf); extern Gc_rc gc_md4 (const void *in, size_t inlen, void *resbuf); extern Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf); extern Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf); +extern Gc_rc gc_sm3 (const void *in, size_t inlen, void *resbuf); extern Gc_rc gc_hmac_md5 (const void *key, size_t keylen, const void *in, size_t inlen, char *resbuf); extern Gc_rc gc_hmac_sha1 (const void *key, size_t keylen, diff --git a/m4/gc-sm3.m4 b/m4/gc-sm3.m4 new file mode 100644 index 000000000..3d0eb4710 --- /dev/null +++ b/m4/gc-sm3.m4 @@ -0,0 +1,10 @@ +# gc-sm3.m4 serial 1 +dnl Copyright (C) 2017 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_GC_SM3], +[ + AC_REQUIRE([gl_GC]) +]) diff --git a/modules/crypto/gc-sm3 b/modules/crypto/gc-sm3 new file mode 100644 index 000000000..de52e0454 --- /dev/null +++ b/modules/crypto/gc-sm3 @@ -0,0 +1,24 @@ +Description: +Generic crypto wrappers for SM3 functions. + +Files: +m4/gc-sm3.m4 + +Depends-on: +crypto/gc +crypto/sm3 [test "$ac_cv_libgcrypt" != yes] + +configure.ac: +gl_GC_SM3 +gl_MODULE_INDICATOR([gc-sm3]) + +Makefile.am: + +Include: +"gc.h" + +License: +LGPLv2+ + +Maintainer: +Jia Zhang diff --git a/modules/crypto/gc-sm3-tests b/modules/crypto/gc-sm3-tests new file mode 100644 index 000000000..21488df1c --- /dev/null +++ b/modules/crypto/gc-sm3-tests @@ -0,0 +1,11 @@ +Files: +tests/test-gc-sm3.c + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-gc-sm3 +check_PROGRAMS += test-gc-sm3 +test_gc_sm3_LDADD = $(LDADD) @LIB_CRYPTO@ $(LIBGCRYPT_LIBS) diff --git a/tests/test-gc-sm3.c b/tests/test-gc-sm3.c new file mode 100644 index 000000000..3e412c851 --- /dev/null +++ b/tests/test-gc-sm3.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2017 Free Software Foundation, Inc. + * Written by Jia Zhang <qianyue...@alibaba-inc.com> + * + * 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 3, 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 <stdio.h> +#include <string.h> +#include <gcrypt.h> +#include "gc.h" + +int +main (int argc, char *argv[]) +{ + Gc_rc rc; + gc_hash_handle h; + + rc = gc_init (); + if (rc != GC_OK) + { + printf ("gc_init() failed\n"); + return 1; + } + + /* Test vector from GM/T 004-2012. */ + + { + const char *in = "abc"; + size_t inlen = strlen (in); + const char *expect = "\x66\xc7\xf0\xf4\x62\xee\xed\xd9\xd1" + "\xf2\xd4\x6b\xdc\x10\xe4\xe2\x41\x67\xc4\x87\x5c" + "\xf2\xf7\xa2\x29\x7d\xa0\x2b\x8f\x4b\xa8\xe0"; + char out[32]; + const char *p; + + if (gc_sm3 (in, inlen, out) != 0) + { + printf ("gc_sm3 call failed\n"); + return 1; + } + + if (memcmp (out, expect, 32) != 0) + { + size_t i; + printf ("sm3 mismatch. expected:\n"); + for (i = 0; i < 32; i++) + printf ("%02x ", (unsigned int) expect[i] & 0xFF); + printf ("\ncomputed:\n"); + for (i = 0; i < 32; i++) + printf ("%02x ", (unsigned int) out[i] & 0xFF); + printf ("\n"); + return 1; + } + + rc = gc_hash_buffer (GC_SM3, "abc", 3, out); + if (rc != GC_OK) + { + printf ("gc_hash_buffer(sm3) call failed: %u\n", rc); + return 1; + } + + if (memcmp (out, expect, 32) != 0) + { + size_t i; + printf ("sm3' mismatch. expected:\n"); + for (i = 0; i < 32; i++) + printf ("%02x ", (unsigned int) expect[i] & 0xFF); + printf ("\ncomputed:\n"); + for (i = 0; i < 32; i++) + printf ("%02x ", (unsigned int) out[i] & 0xFF); + printf ("\n"); + return 1; + } + + if (gc_hash_digest_length (GC_SM3) != 32) + { + printf ("gc_hash_digest_length (GC_SM3) failed\n"); + return 1; + } + + if ((rc = gc_hash_open (GC_SM3, 0, &h)) != GC_OK) + { + printf ("gc_hash_open(GC_SM3) failed (%u)\n", rc); + return 1; + } + + gc_hash_write (h, inlen, in); + + p = gc_hash_read (h); + + if (!p) + { + printf ("gc_hash_read failed\n"); + return 1; + } + + if (memcmp (p, expect, 32) != 0) + { + size_t i; + printf ("sm3 mismatch. expected:\n"); + for (i = 0; i < 32; i++) + printf ("%02x ", (unsigned int) expect[i] & 0xFF); + printf ("\ncomputed:\n"); + for (i = 0; i < 32; i++) + printf ("%02x ", (unsigned int) p[i] & 0xFF); + printf ("\n"); + return 1; + } + + gc_hash_close (h); + } + + gc_done (); + + return 0; +} -- 2.14.1
From e66eb50781c8db99bc3d7589d8135adb451837b3 Mon Sep 17 00:00:00 2001 From: Jia Zhang <qianyue...@alibaba-inc.com> Date: Sat, 28 Oct 2017 10:05:31 -0400 Subject: [PATCH 2/2] gc-gnulib, gc-libgcrypt: fix ix build failure due to -Werror=suggest-attribute=const Mark the functions with _GL_ATTRIBUTE_CONST to resovle this sort of build failures: lib/gc-libgcrypt.c: In function 'gc_done': lib/gc-libgcrypt.c:66:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_done (void) ^~~~~~~ ... lib/gc-gnulib.c: In function 'gc_init': lib/gc-gnulib.c:87:1: error: function might be candidate for attribute 'const' [-Werror=suggest-attribute=const] gc_init (void) ^~~~~~~ ... * lib/gc.h: Mark the functions with _GL_ATTRIBUTE_CONST. * lib/gc-gnulib.c: Likewise. * lib/gc-libgcrypt.c: Likewise. --- lib/gc-gnulib.c | 16 ++++++++-------- lib/gc-libgcrypt.c | 16 ++++++++-------- lib/gc.h | 22 ++++++++++++++-------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/gc-gnulib.c b/lib/gc-gnulib.c index f888cf597..1be2d5f0a 100644 --- a/lib/gc-gnulib.c +++ b/lib/gc-gnulib.c @@ -83,7 +83,7 @@ HCRYPTPROV g_hProv = 0; # endif #endif -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_init (void) { #ifdef GNULIB_GC_RANDOM @@ -110,7 +110,7 @@ gc_init (void) return GC_OK; } -void +void _GL_ATTRIBUTE_CONST gc_done (void) { #ifdef GNULIB_GC_RANDOM @@ -213,7 +213,7 @@ gc_random (char *data, size_t datalen) /* Memory allocation. */ -void +void _GL_ATTRIBUTE_CONST gc_set_allocators (gc_malloc_t func_malloc, gc_malloc_t secure_malloc, gc_secure_check_t secure_check, @@ -330,7 +330,7 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, return rc; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) { _gc_cipher_ctx *ctx = handle; @@ -394,7 +394,7 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) { _gc_cipher_ctx *ctx = handle; @@ -448,7 +448,7 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) { _gc_cipher_ctx *ctx = handle; @@ -518,7 +518,7 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) { _gc_cipher_ctx *ctx = handle; @@ -702,7 +702,7 @@ gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle) return GC_OK; } -size_t +size_t _GL_ATTRIBUTE_CONST gc_hash_digest_length (Gc_hash hash) { size_t len; diff --git a/lib/gc-libgcrypt.c b/lib/gc-libgcrypt.c index 49ba0e13c..75dacf90e 100644 --- a/lib/gc-libgcrypt.c +++ b/lib/gc-libgcrypt.c @@ -40,7 +40,7 @@ /* Initialization. */ -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_init (void) { gcry_error_t err; @@ -62,7 +62,7 @@ gc_init (void) return GC_OK; } -void +void _GL_ATTRIBUTE_CONST gc_done (void) { return; @@ -97,7 +97,7 @@ gc_random (char *data, size_t datalen) /* Memory allocation. */ -void +void _GL_ATTRIBUTE_CONST gc_set_allocators (gc_malloc_t func_malloc, gc_malloc_t secure_malloc, gc_secure_check_t secure_check, @@ -187,7 +187,7 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) { gcry_error_t err; @@ -199,7 +199,7 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) { gcry_error_t err; @@ -211,7 +211,7 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) { if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle, @@ -221,7 +221,7 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) return GC_OK; } -Gc_rc +Gc_rc _GL_ATTRIBUTE_CONST gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) { if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle, @@ -364,7 +364,7 @@ gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle) return GC_OK; } -size_t +size_t _GL_ATTRIBUTE_CONST gc_hash_digest_length (Gc_hash hash) { size_t len; diff --git a/lib/gc.h b/lib/gc.h index e65ba49a3..91da872d1 100644 --- a/lib/gc.h +++ b/lib/gc.h @@ -99,8 +99,8 @@ typedef enum Gc_cipher_mode Gc_cipher_mode; typedef void *gc_cipher_handle; /* Call before respectively after any other functions. */ -extern Gc_rc gc_init (void); -extern void gc_done (void); +extern Gc_rc gc_init (void) _GL_ATTRIBUTE_CONST; +extern void gc_done (void) _GL_ATTRIBUTE_CONST; /* Memory allocation (avoid). */ typedef void *(*gc_malloc_t) (size_t n); @@ -111,7 +111,8 @@ extern void gc_set_allocators (gc_malloc_t func_malloc, gc_malloc_t secure_malloc, gc_secure_check_t secure_check, gc_realloc_t func_realloc, - gc_free_t func_free); + gc_free_t func_free) + _GL_ATTRIBUTE_CONST; /* Randomness. */ extern Gc_rc gc_nonce (char *data, size_t datalen); @@ -122,13 +123,17 @@ extern Gc_rc gc_random (char *data, size_t datalen); extern Gc_rc gc_cipher_open (Gc_cipher cipher, Gc_cipher_mode mode, gc_cipher_handle *outhandle); extern Gc_rc gc_cipher_setkey (gc_cipher_handle handle, - size_t keylen, const char *key); + size_t keylen, const char *key) + _GL_ATTRIBUTE_CONST; extern Gc_rc gc_cipher_setiv (gc_cipher_handle handle, - size_t ivlen, const char *iv); + size_t ivlen, const char *iv) + _GL_ATTRIBUTE_CONST; extern Gc_rc gc_cipher_encrypt_inline (gc_cipher_handle handle, - size_t len, char *data); + size_t len, char *data) + _GL_ATTRIBUTE_CONST; extern Gc_rc gc_cipher_decrypt_inline (gc_cipher_handle handle, - size_t len, char *data); + size_t len, char *data) + _GL_ATTRIBUTE_CONST; extern Gc_rc gc_cipher_close (gc_cipher_handle handle); /* Hashes. */ @@ -136,7 +141,8 @@ extern Gc_rc gc_cipher_close (gc_cipher_handle handle); extern Gc_rc gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle *outhandle); extern Gc_rc gc_hash_clone (gc_hash_handle handle, gc_hash_handle *outhandle); -extern size_t gc_hash_digest_length (Gc_hash hash); +extern size_t gc_hash_digest_length (Gc_hash hash) + _GL_ATTRIBUTE_CONST; extern void gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key); extern void gc_hash_write (gc_hash_handle handle, -- 2.14.1