/* Portability glue for libcrypt.
Copyright 2007-2017 Thorsten Kukuk and Zack Weinberg
Copyright 2018-2019 Björn Esser
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
This library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see
. */
#ifndef _CRYPT_PORT_H
#define _CRYPT_PORT_H 1
#ifndef HAVE_CONFIG_H
#error "Run configure before compiling; see INSTALL for instructions"
#endif
#include "config.h"
#undef NDEBUG
#include
#include
#include
#include
#include
#include
#ifdef HAVE_SYS_TYPES_H
#include
#endif
#ifdef HAVE_SYS_CDEFS_H
#include
#endif
#ifdef HAVE_ENDIAN_H
#include
#endif
#ifdef HAVE_SYS_ENDIAN_H
#include
#endif
#ifdef HAVE_SYS_PARAM_H
#include
#endif
#ifndef HAVE_SYS_CDEFS_THROW
#define __THROW /* nothing */
#endif
/* Suppression of unused-argument warnings. */
#if defined __GNUC__ && __GNUC__ >= 3
# define ARG_UNUSED(x) x __attribute__ ((__unused__))
#else
# define ARG_UNUSED(x) x
#endif
/* C99 Static array indices in function parameter declarations. Syntax
such as: void bar(int myArray[static 10]); is allowed in C99, but
not all compiler support it properly. Define MIN_SIZE appropriately
so headers using it can be compiled using any compiler.
Use like this: void bar(int myArray[MIN_SIZE(10)]); */
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) && \
((defined __GNUC__ && __GNUC__ > 4) || defined __clang__)
#define MIN_SIZE(x) static (x)
#else
#define MIN_SIZE(x) (x)
#endif
/* Detect system endianness. */
#if ENDIANNESS_IS_BIG
# define XCRYPT_USE_BIGENDIAN 1
#elif ENDIANNESS_IS_LITTLE
# define XCRYPT_USE_BIGENDIAN 0
#elif ENDIANNESS_IS_PDP
# error "Byte-order sensitive code in libxcrypt does not support PDP-endianness"
#else
# error "Unable to determine byte ordering"
#endif
/* static_assert shim. */
#ifdef HAVE_STATIC_ASSERT_IN_ASSERT_H
/* nothing to do */
#elif defined HAVE__STATIC_ASSERT
# define static_assert(expr, message) _Static_assert(expr, message)
#else
/* This fallback is known to work with most C99-compliant compilers.
See verify.h in gnulib for extensive discussion. */
# define static_assert(expr, message) \
extern int (*xcrypt_static_assert_fn (void)) \
[!!sizeof (struct { int xcrypt_error_if_negative: (expr) ? 2 : -1; })]
#endif
/* max_align_t shim. In the absence of official word from the
compiler, we guess that one of long double, uintmax_t, void *, and
void (*)(void) will have the maximum alignment. This is probably
not true in the presence of vector types, but we currently don't
use vector types, and hopefully any compiler with extra-aligned
vector types will provide max_align_t. */
#ifndef HAVE_MAX_ALIGN_T
typedef union
{
long double ld;
uintmax_t ui;
void *vp;
void (*vpf)(void);
} max_align_t;
#endif
/* Several files expect the traditional definitions of these macros.
(We don't trust sys/param.h to define them correctly.) */
#undef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/* ARRAY_SIZE is used in tests. */
#define ARRAY_SIZE(a_) (sizeof (a_) / sizeof ((a_)[0]))
/* Provide a guaranteed way to erase sensitive memory at the best we
can, given the possibilities of the system. */
#if defined HAVE_MEMSET_S
/* Will never be optimized out. */
#define XCRYPT_SECURE_MEMSET(s, len) \
memset_s (s, len, 0x00, len)
#elif defined HAVE_EXPLICIT_BZERO
/* explicit_bzero() should give us enough guarantees. */
#define XCRYPT_SECURE_MEMSET(s, len) \
explicit_bzero(s, len)
#elif defined HAVE_EXPLICIT_MEMSET
/* Same guarantee goes for explicit_memset(). */
#define XCRYPT_SECURE_MEMSET(s, len) \
explicit_memset (s, 0x00, len)
#else
/* The best hope we have in this case. */
#define INCLUDE_XCRYPT_SECURE_MEMSET 1
extern void _crypt_secure_memset (void *, size_t);
#define XCRYPT_SECURE_MEMSET(s, len) \
_crypt_secure_memset (s, len)
#endif
#ifndef INCLUDE_XCRYPT_SECURE_MEMSET
#define INCLUDE_XCRYPT_SECURE_MEMSET 0
#endif
/* Provide a safe way to copy strings with the guarantee src,
including its terminating '\0', will fit d_size bytes.
The trailing bytes of d_size will be filled with '\0'.
dst and src must not be NULL. Returns strlen (src). */
extern size_t
_crypt_strcpy_or_abort (void *, const size_t, const void *);
#define XCRYPT_STRCPY_OR_ABORT(dst, d_size, src) \
_crypt_strcpy_or_abort (dst, d_size, src)
/* Define ALIASNAME as a strong alias for NAME. */
#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
/* Darwin (Mach-O) doesn't support alias attributes or symbol versioning.
It does, however, support symbol aliasing at the object file level. */
#ifdef __APPLE__
# define _strong_alias(name, aliasname) \
__asm__(".globl _" #aliasname); \
__asm__(".set _" #aliasname ", _" #name); \
extern __typeof(name) aliasname __THROW
# define symver_set(extstr, intname, version, mode) \
__asm__(".globl _" extstr); \
__asm__(".set _" extstr ", _" #intname)
#elif defined __GNUC__ && __GNUC__ >= 3
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __THROW __attribute__ ((alias (#name)))
/* Set the symbol version for EXTNAME, which uses INTNAME as its
implementation. */
# define symver_set(extstr, intname, version, mode) \
__asm__ (".symver " #intname "," extstr mode #version)
#else
# error "Don't know how to do symbol versioning with this compiler"
#endif
/* A construct with the same syntactic role as the expansion of symver_set,
but which does nothing. */
#define symver_nop() __asm__ ("")
/* The macros for versioned symbols work differently in this library
than they do in glibc. They are mostly auto-generated (see gen-vers.awk),
and we currently don't support compatibility symbols that need a different
definition from the default version.
Each definition of a public symbol should look like this:
#if INCLUDE_foo
int foo(arguments)
{
body
}
SYMVER_foo;
#endif
and the macros take care of the rest. Normally, to call a public
symbol you do nothing special. The macro symver_ref() forces
all uses of a particular name (in the file where it's used) to refer
to a particular version of a public symbol, e.g. for testing. */
#ifdef IN_LIBCRYPT
#include "crypt-symbol-vers.h"
#ifdef PIC
#define symver_compat(n, extstr, extname, intname, version) \
strong_alias (intname, extname ## __ ## n); \
symver_set (extstr, extname ## __ ## n, version, "@")
#define symver_compat0(extstr, intname, version) \
symver_set (extstr, intname, version, "@")
#define symver_default(extstr, intname, version) \
symver_set (extstr, intname, version, "@@")
#else
/* When not building the shared library, don't do any of this. */
#define symver_compat(n, extstr, extname, intname, version) symver_nop ()
#define symver_compat0(extstr, intname, version) symver_nop ()
#define symver_default(extstr, intname, version) symver_nop ()
#endif
#endif
/* Tests may need to _refer_ to compatibility symbols, but should never need
to _define_ them. */
#define symver_ref(extstr, intname, version) \
symver_set(extstr, intname, version, "@")
/* Define configuration macros used during compile-time by the
GOST R 34.11-2012 "Streebog" hash function. */
#if XCRYPT_USE_BIGENDIAN
#define __GOST3411_BIG_ENDIAN__ 1
#else
#define __GOST3411_LITTLE_ENDIAN__ 1
#endif
/* Get the set of hash algorithms to be included and some related
definitions. */
#include "crypt-hashes.h"
/* Rename all of the internal-but-global symbols with a _crypt_ prefix
so that they do not interfere with other people's code when linking
statically. This list cannot be autogenerated, but is validated by
test-symbols.sh. */
#define ascii64 _crypt_ascii64
#define get_random_bytes _crypt_get_random_bytes
#define make_failure_token _crypt_make_failure_token
#if INCLUDE_descrypt || INCLUDE_bsdicrypt || INCLUDE_bigcrypt
#define des_crypt_block _crypt_des_crypt_block
#define des_set_key _crypt_des_set_key
#define des_set_salt _crypt_des_set_salt
#define comp_maskl _crypt_comp_maskl
#define comp_maskr _crypt_comp_maskr
#define fp_maskl _crypt_fp_maskl
#define fp_maskr _crypt_fp_maskr
#define ip_maskl _crypt_ip_maskl
#define ip_maskr _crypt_ip_maskr
#define key_perm_maskl _crypt_key_perm_maskl
#define key_perm_maskr _crypt_key_perm_maskr
#define m_sbox _crypt_m_sbox
#define psbox _crypt_psbox
#endif
#if INCLUDE_nt
#define MD4_Init _crypt_MD4_Init
#define MD4_Update _crypt_MD4_Update
#define MD4_Final _crypt_MD4_Final
#endif
#if INCLUDE_md5crypt || INCLUDE_sunmd5
#define MD5_Init _crypt_MD5_Init
#define MD5_Update _crypt_MD5_Update
#define MD5_Final _crypt_MD5_Final
#endif
#if INCLUDE_sha1crypt
#define hmac_sha1_process_data _crypt_hmac_sha1_process_data
#define sha1_finish_ctx _crypt_sha1_finish_ctx
#define sha1_init_ctx _crypt_sha1_init_ctx
#define sha1_process_bytes _crypt_sha1_process_bytes
#endif
#if INCLUDE_sha512crypt
#define libcperciva_SHA512_Init _crypt_SHA512_Init
#define libcperciva_SHA512_Update _crypt_SHA512_Update
#define libcperciva_SHA512_Final _crypt_SHA512_Final
#define libcperciva_SHA512_Buf _crypt_SHA512_Buf
#endif
#if INCLUDE_md5crypt || INCLUDE_sha256crypt || INCLUDE_sha512crypt
#define gensalt_sha_rn _crypt_gensalt_sha_rn
#endif
#if INCLUDE_yescrypt || INCLUDE_scrypt || INCLUDE_gost_yescrypt
#define PBKDF2_SHA256 _crypt_PBKDF2_SHA256
#define crypto_scrypt _crypt_crypto_scrypt
#define yescrypt _crypt_yescrypt
#define yescrypt_decode64 _crypt_yescrypt_decode64
#define yescrypt_digest_shared _crypt_yescrypt_digest_shared
#define yescrypt_encode64 _crypt_yescrypt_encode64
#define yescrypt_encode_params _crypt_yescrypt_encode_params
#define yescrypt_encode_params_r _crypt_yescrypt_encode_params_r
#define yescrypt_free_local _crypt_yescrypt_free_local
#define yescrypt_free_shared _crypt_yescrypt_free_shared
#define yescrypt_init_local _crypt_yescrypt_init_local
#define yescrypt_init_shared _crypt_yescrypt_init_shared
#define yescrypt_kdf _crypt_yescrypt_kdf
#define yescrypt_r _crypt_yescrypt_r
#define yescrypt_reencrypt _crypt_yescrypt_reencrypt
#define libcperciva_HMAC_SHA256_Init _crypt_HMAC_SHA256_Init
#define libcperciva_HMAC_SHA256_Update _crypt_HMAC_SHA256_Update
#define libcperciva_HMAC_SHA256_Final _crypt_HMAC_SHA256_Final
#define libcperciva_HMAC_SHA256_Buf _crypt_HMAC_SHA256_Buf
#endif
#if INCLUDE_sha256crypt || INCLUDE_scrypt || INCLUDE_yescrypt || \
INCLUDE_gost_yescrypt
#define libcperciva_SHA256_Init _crypt_SHA256_Init
#define libcperciva_SHA256_Update _crypt_SHA256_Update
#define libcperciva_SHA256_Final _crypt_SHA256_Final
#define libcperciva_SHA256_Buf _crypt_SHA256_Buf
#endif
#if INCLUDE_gost_yescrypt
#define GOST34112012Init _crypt_GOST34112012_Init
#define GOST34112012Update _crypt_GOST34112012_Update
#define GOST34112012Final _crypt_GOST34112012_Final
#define GOST34112012Cleanup _crypt_GOST34112012_Cleanup
#define gost_hash256 _crypt_gost_hash256
#define gost_hmac256 _crypt_gost_hmac256
/* Those are not present, if gost-yescrypt is selected,
but yescrypt is not. */
#if !INCLUDE_yescrypt
#define gensalt_yescrypt_rn _crypt_gensalt_yescrypt_rn
extern void gensalt_yescrypt_rn
(unsigned long, const uint8_t *, size_t, uint8_t *, size_t);
#endif
#endif
/* Those are not present, if des-big is selected, but des is not. */
#if INCLUDE_bigcrypt && !INCLUDE_descrypt
#define gensalt_descrypt_rn _crypt_gensalt_descrypt_rn
extern void gensalt_descrypt_rn
(unsigned long, const uint8_t *, size_t, uint8_t *, size_t);
#endif
/* Those are not present, if scrypt is selected, but yescrypt is not. */
#if INCLUDE_scrypt && !INCLUDE_yescrypt
#define crypt_yescrypt_rn _crypt_crypt_yescrypt_rn
extern void crypt_yescrypt_rn (const char *, size_t, const char *,
size_t, uint8_t *, size_t, void *, size_t);
#endif
/* We need a prototype for fcrypt for some tests. */
#if ENABLE_OBSOLETE_API
extern char *fcrypt (const char *key, const char *setting);
#endif
/* Utility functions */
extern bool get_random_bytes (void *buf, size_t buflen);
extern void gensalt_sha_rn (char tag, size_t maxsalt, unsigned long defcount,
unsigned long mincount, unsigned long maxcount,
unsigned long count,
const uint8_t *rbytes, size_t nrbytes,
uint8_t *output, size_t output_size);
/* Calculate the size of a base64 encoding of N bytes:
6 bits per output byte, rounded up. */
#define BASE64_LEN(bytes) ((((bytes) * 8) + 5) / 6)
/* The "scratch" area passed to each of the individual hash functions is
this big. */
#define ALG_SPECIFIC_SIZE 8192
#include "crypt.h"
#include "crypt-common.h"
#endif /* crypt-port.h */