1 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002-2024 Free Software Foundation, Inc.
4 * This file is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of the
7 * License, or (at your option) any later version.
9 * This file is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 /* Note: This file is only built if GC uses internal functions. */
33 #include <sys/random.h>
58 #if GNULIB_GC_HMAC_MD5 || GNULIB_GC_HMAC_SHA1 || GNULIB_GC_HMAC_SHA256 || GNULIB_GC_HMAC_SHA512
72 #if GNULIB_GC_RIJNDAEL
73 # include "rijndael-api-fst.h"
90 /* Overwrite BUFFER with random data, under the control of getrandom
91 FLAGS. BUFFER contains LENGTH bytes. Inspired by getentropy,
92 however LENGTH is not restricted to 256. Return 0 on success, -1
93 (setting errno) on failure. */
95 randomize (void *buffer
, size_t length
, unsigned int flags
)
104 while ((bytes
= getrandom (buf
, length
, flags
)) < 0)
106 return GC_RANDOM_ERROR
;
113 return GC_RANDOM_ERROR
;
117 gc_nonce (char *data
, size_t datalen
)
119 return randomize (data
, datalen
, 0);
123 gc_pseudo_random (char *data
, size_t datalen
)
125 return randomize (data
, datalen
, 0);
129 gc_random (char *data
, size_t datalen
)
131 return randomize (data
, datalen
, GRND_RANDOM
);
136 /* Memory allocation. */
139 gc_set_allocators (gc_malloc_t func_malloc
,
140 gc_malloc_t secure_malloc
,
141 gc_secure_check_t secure_check
,
142 gc_realloc_t func_realloc
, gc_free_t func_free
)
149 typedef struct _gc_cipher_ctx
154 arctwo_context arctwoContext
;
155 char arctwoIV
[ARCTWO_BLOCK_SIZE
];
157 #if GNULIB_GC_ARCFOUR
158 arcfour_context arcfourContext
;
161 gl_des_ctx desContext
;
163 #if GNULIB_GC_RIJNDAEL
164 rijndaelKeyInstance aesEncKey
;
165 rijndaelKeyInstance aesDecKey
;
166 rijndaelCipherInstance aesContext
;
171 gc_cipher_open (Gc_cipher alg
, Gc_cipher_mode mode
,
172 gc_cipher_handle
* outhandle
)
177 ctx
= calloc (sizeof (*ctx
), 1);
179 return GC_MALLOC_ERROR
;
195 rc
= GC_INVALID_CIPHER
;
200 #if GNULIB_GC_ARCFOUR
209 rc
= GC_INVALID_CIPHER
;
222 rc
= GC_INVALID_CIPHER
;
227 #if GNULIB_GC_RIJNDAEL
238 rc
= GC_INVALID_CIPHER
;
244 rc
= GC_INVALID_CIPHER
;
256 gc_cipher_setkey (gc_cipher_handle handle
, size_t keylen
, const char *key
)
258 _gc_cipher_ctx
*ctx
= handle
;
264 arctwo_setkey (&ctx
->arctwoContext
, keylen
, key
);
268 #if GNULIB_GC_ARCFOUR
271 arcfour_setkey (&ctx
->arcfourContext
, key
, keylen
);
278 return GC_INVALID_CIPHER
;
279 gl_des_setkey (&ctx
->desContext
, key
);
283 #if GNULIB_GC_RIJNDAEL
290 char keyMaterial
[RIJNDAEL_MAX_KEY_SIZE
+ 1];
292 for (i
= 0; i
< keylen
; i
++)
293 sprintf (&keyMaterial
[2 * i
], "%02x", key
[i
] & 0xFF);
295 rc
= rijndaelMakeKey (&ctx
->aesEncKey
, RIJNDAEL_DIR_ENCRYPT
,
296 keylen
* 8, keyMaterial
);
298 return GC_INVALID_CIPHER
;
300 rc
= rijndaelMakeKey (&ctx
->aesDecKey
, RIJNDAEL_DIR_DECRYPT
,
301 keylen
* 8, keyMaterial
);
303 return GC_INVALID_CIPHER
;
305 rc
= rijndaelCipherInit (&ctx
->aesContext
, RIJNDAEL_MODE_ECB
, NULL
);
307 return GC_INVALID_CIPHER
;
313 return GC_INVALID_CIPHER
;
320 gc_cipher_setiv (gc_cipher_handle handle
, size_t ivlen
, const char *iv
)
322 _gc_cipher_ctx
*ctx
= handle
;
328 if (ivlen
!= ARCTWO_BLOCK_SIZE
)
329 return GC_INVALID_CIPHER
;
330 memcpy (ctx
->arctwoIV
, iv
, ivlen
);
334 #if GNULIB_GC_RIJNDAEL
341 /* Doesn't use IV. */
348 char ivMaterial
[2 * RIJNDAEL_MAX_IV_SIZE
+ 1];
350 for (i
= 0; i
< ivlen
; i
++)
351 sprintf (&ivMaterial
[2 * i
], "%02x", iv
[i
] & 0xFF);
353 rc
= rijndaelCipherInit (&ctx
->aesContext
, RIJNDAEL_MODE_CBC
,
356 return GC_INVALID_CIPHER
;
361 return GC_INVALID_CIPHER
;
367 return GC_INVALID_CIPHER
;
374 gc_cipher_encrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
376 _gc_cipher_ctx
*ctx
= handle
;
385 arctwo_encrypt (&ctx
->arctwoContext
, data
, data
, len
);
389 for (; len
>= ARCTWO_BLOCK_SIZE
; len
-= ARCTWO_BLOCK_SIZE
,
390 data
+= ARCTWO_BLOCK_SIZE
)
393 for (i
= 0; i
< ARCTWO_BLOCK_SIZE
; i
++)
394 data
[i
] ^= ctx
->arctwoIV
[i
];
395 arctwo_encrypt (&ctx
->arctwoContext
, data
, data
,
397 memcpy (ctx
->arctwoIV
, data
, ARCTWO_BLOCK_SIZE
);
402 return GC_INVALID_CIPHER
;
407 #if GNULIB_GC_ARCFOUR
410 arcfour_stream (&ctx
->arcfourContext
, data
, data
, len
);
416 for (; len
>= 8; len
-= 8, data
+= 8)
417 gl_des_ecb_encrypt (&ctx
->desContext
, data
, data
);
421 #if GNULIB_GC_RIJNDAEL
428 nblocks
= rijndaelBlockEncrypt (&ctx
->aesContext
, &ctx
->aesEncKey
,
429 data
, 8 * len
, data
);
431 return GC_INVALID_CIPHER
;
437 return GC_INVALID_CIPHER
;
444 gc_cipher_decrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
446 _gc_cipher_ctx
*ctx
= handle
;
455 arctwo_decrypt (&ctx
->arctwoContext
, data
, data
, len
);
459 for (; len
>= ARCTWO_BLOCK_SIZE
; len
-= ARCTWO_BLOCK_SIZE
,
460 data
+= ARCTWO_BLOCK_SIZE
)
462 char tmpIV
[ARCTWO_BLOCK_SIZE
];
464 memcpy (tmpIV
, data
, ARCTWO_BLOCK_SIZE
);
465 arctwo_decrypt (&ctx
->arctwoContext
, data
, data
,
467 for (i
= 0; i
< ARCTWO_BLOCK_SIZE
; i
++)
468 data
[i
] ^= ctx
->arctwoIV
[i
];
469 memcpy (ctx
->arctwoIV
, tmpIV
, ARCTWO_BLOCK_SIZE
);
474 return GC_INVALID_CIPHER
;
479 #if GNULIB_GC_ARCFOUR
482 arcfour_stream (&ctx
->arcfourContext
, data
, data
, len
);
488 for (; len
>= 8; len
-= 8, data
+= 8)
489 gl_des_ecb_decrypt (&ctx
->desContext
, data
, data
);
493 #if GNULIB_GC_RIJNDAEL
500 nblocks
= rijndaelBlockDecrypt (&ctx
->aesContext
, &ctx
->aesDecKey
,
501 data
, 8 * len
, data
);
503 return GC_INVALID_CIPHER
;
509 return GC_INVALID_CIPHER
;
516 gc_cipher_close (gc_cipher_handle handle
)
518 _gc_cipher_ctx
*ctx
= handle
;
527 #define MAX_DIGEST_SIZE 64
529 typedef struct _gc_hash_ctx
533 char hash
[MAX_DIGEST_SIZE
];
535 struct md2_ctx md2Context
;
538 struct md4_ctx md4Context
;
541 struct md5_ctx md5Context
;
544 struct sha1_ctx sha1Context
;
547 struct sha256_ctx sha256Context
;
550 struct sha512_ctx sha512Context
;
553 struct sm3_ctx sm3Context
;
558 gc_hash_open (Gc_hash hash
, Gc_hash_mode mode
, gc_hash_handle
* outhandle
)
564 return GC_INVALID_HASH
;
566 ctx
= calloc (sizeof (*ctx
), 1);
568 return GC_MALLOC_ERROR
;
577 /* Not needed, because ctx is already zero-initialized. */
578 /*md2_init_ctx (&ctx->md2Context);*/
584 md4_init_ctx (&ctx
->md4Context
);
590 md5_init_ctx (&ctx
->md5Context
);
596 sha1_init_ctx (&ctx
->sha1Context
);
602 sha256_init_ctx (&ctx
->sha256Context
);
608 sha512_init_ctx (&ctx
->sha512Context
);
614 sm3_init_ctx (&ctx
->sm3Context
);
619 rc
= GC_INVALID_HASH
;
632 gc_hash_clone (gc_hash_handle handle
, gc_hash_handle
* outhandle
)
634 _gc_hash_ctx
*in
= handle
;
637 *outhandle
= out
= calloc (sizeof (*out
), 1);
639 return GC_MALLOC_ERROR
;
641 memcpy (out
, in
, sizeof (*out
));
647 gc_hash_digest_length (Gc_hash hash
)
654 len
= GC_MD2_DIGEST_SIZE
;
658 len
= GC_MD4_DIGEST_SIZE
;
662 len
= GC_MD5_DIGEST_SIZE
;
666 len
= GC_RMD160_DIGEST_SIZE
;
670 len
= GC_SHA1_DIGEST_SIZE
;
674 len
= GC_SHA256_DIGEST_SIZE
;
678 len
= GC_SHA512_DIGEST_SIZE
;
682 len
= GC_SM3_DIGEST_SIZE
;
693 gc_hash_write (gc_hash_handle handle
, size_t len
, const char *data
)
695 _gc_hash_ctx
*ctx
= handle
;
701 md2_process_bytes (data
, len
, &ctx
->md2Context
);
707 md4_process_bytes (data
, len
, &ctx
->md4Context
);
713 md5_process_bytes (data
, len
, &ctx
->md5Context
);
719 sha1_process_bytes (data
, len
, &ctx
->sha1Context
);
725 sha256_process_bytes (data
, len
, &ctx
->sha256Context
);
731 sha512_process_bytes (data
, len
, &ctx
->sha512Context
);
737 sm3_process_bytes (data
, len
, &ctx
->sm3Context
);
747 gc_hash_read (gc_hash_handle handle
)
749 _gc_hash_ctx
*ctx
= handle
;
750 const char *ret
= NULL
;
756 md2_finish_ctx (&ctx
->md2Context
, ctx
->hash
);
763 md4_finish_ctx (&ctx
->md4Context
, ctx
->hash
);
770 md5_finish_ctx (&ctx
->md5Context
, ctx
->hash
);
777 sha1_finish_ctx (&ctx
->sha1Context
, ctx
->hash
);
784 sha256_finish_ctx (&ctx
->sha256Context
, ctx
->hash
);
791 sha512_finish_ctx (&ctx
->sha512Context
, ctx
->hash
);
798 sm3_finish_ctx (&ctx
->sm3Context
, ctx
->hash
);
811 gc_hash_close (gc_hash_handle handle
)
813 _gc_hash_ctx
*ctx
= handle
;
819 gc_hash_buffer (Gc_hash hash
, const void *in
, size_t inlen
, char *resbuf
)
825 md2_buffer (in
, inlen
, resbuf
);
831 md4_buffer (in
, inlen
, resbuf
);
837 md5_buffer (in
, inlen
, resbuf
);
843 sha1_buffer (in
, inlen
, resbuf
);
849 sha256_buffer (in
, inlen
, resbuf
);
855 sha512_buffer (in
, inlen
, resbuf
);
861 sm3_buffer (in
, inlen
, resbuf
);
866 return GC_INVALID_HASH
;
874 gc_md2 (const void *in
, size_t inlen
, void *resbuf
)
876 md2_buffer (in
, inlen
, resbuf
);
883 gc_md4 (const void *in
, size_t inlen
, void *resbuf
)
885 md4_buffer (in
, inlen
, resbuf
);
892 gc_md5 (const void *in
, size_t inlen
, void *resbuf
)
894 md5_buffer (in
, inlen
, resbuf
);
901 gc_sha1 (const void *in
, size_t inlen
, void *resbuf
)
903 sha1_buffer (in
, inlen
, resbuf
);
910 gc_sha256 (const void *in
, size_t inlen
, void *resbuf
)
912 sha256_buffer (in
, inlen
, resbuf
);
919 gc_sha512 (const void *in
, size_t inlen
, void *resbuf
)
921 sha512_buffer (in
, inlen
, resbuf
);
928 gc_sm3 (const void *in
, size_t inlen
, void *resbuf
)
930 sm3_buffer (in
, inlen
, resbuf
);
935 #if GNULIB_GC_HMAC_MD5
937 gc_hmac_md5 (const void *key
, size_t keylen
,
938 const void *in
, size_t inlen
, char *resbuf
)
940 hmac_md5 (key
, keylen
, in
, inlen
, resbuf
);
945 #if GNULIB_GC_HMAC_SHA1
947 gc_hmac_sha1 (const void *key
, size_t keylen
,
948 const void *in
, size_t inlen
, char *resbuf
)
950 hmac_sha1 (key
, keylen
, in
, inlen
, resbuf
);
955 #if GNULIB_GC_HMAC_SHA256
957 gc_hmac_sha256 (const void *key
, size_t keylen
,
958 const void *in
, size_t inlen
, char *resbuf
)
960 hmac_sha256 (key
, keylen
, in
, inlen
, resbuf
);
965 #if GNULIB_GC_HMAC_SHA512
967 gc_hmac_sha512 (const void *key
, size_t keylen
,
968 const void *in
, size_t inlen
, char *resbuf
)
970 hmac_sha512 (key
, keylen
, in
, inlen
, resbuf
);