|
Packit |
13e0ca |
/* Portability glue for libcrypt.
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
Copyright 2007-2017 Thorsten Kukuk and Zack Weinberg
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
This library is free software; you can redistribute it and/or
|
|
Packit |
13e0ca |
modify it under the terms of the GNU Lesser General Public License
|
|
Packit |
13e0ca |
as published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
13e0ca |
the License, or (at your option) any later version.
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
This library is distributed in the hope that it will be useful,
|
|
Packit |
13e0ca |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
13e0ca |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
13e0ca |
GNU Lesser General Public License for more details.
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
13e0ca |
License along with this library; if not, see
|
|
Packit |
13e0ca |
<https://www.gnu.org/licenses/>. */
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#ifndef _CRYPT_PORT_H
|
|
Packit |
13e0ca |
#define _CRYPT_PORT_H 1
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#ifndef HAVE_CONFIG_H
|
|
Packit |
13e0ca |
#error "Run configure before compiling; see INSTALL for instructions"
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#include "config.h"
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#undef NDEBUG
|
|
Packit |
13e0ca |
#include <assert.h>
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#include <stdbool.h>
|
|
Packit |
13e0ca |
#include <stddef.h>
|
|
Packit |
13e0ca |
#include <stdint.h>
|
|
Packit |
13e0ca |
#include <string.h>
|
|
Packit |
13e0ca |
#ifdef HAVE_SYS_TYPES_H
|
|
Packit |
13e0ca |
#include <sys/types.h>
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
#ifdef HAVE_SYS_CDEFS_H
|
|
Packit |
13e0ca |
#include <sys/cdefs.h>
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#ifndef HAVE_SYS_CDEFS_THROW
|
|
Packit |
13e0ca |
#define __THROW /* nothing */
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* While actually compiling the library, suppress the __nonnull tags
|
|
Packit |
13e0ca |
on the functions in crypt-base.h, so that internal checks for NULL
|
|
Packit |
13e0ca |
are not deleted by the compiler. */
|
|
Packit |
13e0ca |
#undef __nonnull
|
|
Packit |
13e0ca |
#define __nonnull(param) /* nothing */
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Suppression of unused-argument warnings. */
|
|
Packit |
13e0ca |
#if defined __GNUC__ && __GNUC__ >= 3
|
|
Packit |
13e0ca |
# define ARG_UNUSED(x) x __attribute__ ((__unused__))
|
|
Packit |
13e0ca |
#else
|
|
Packit |
13e0ca |
# define ARG_UNUSED(x) x
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* static_assert shim. */
|
|
Packit |
13e0ca |
#ifdef HAVE_STATIC_ASSERT_IN_ASSERT_H
|
|
Packit |
13e0ca |
/* nothing to do */
|
|
Packit |
13e0ca |
#elif defined HAVE__STATIC_ASSERT
|
|
Packit |
13e0ca |
# define static_assert(expr, message) _Static_assert(expr, message)
|
|
Packit |
13e0ca |
#else
|
|
Packit |
13e0ca |
/* This fallback is known to work with most C99-compliant compilers.
|
|
Packit |
13e0ca |
See verify.h in gnulib for extensive discussion. */
|
|
Packit |
13e0ca |
# define static_assert(expr, message) \
|
|
Packit |
13e0ca |
extern int (*xcrypt_static_assert_fn (void)) \
|
|
Packit |
13e0ca |
[!!sizeof (struct { int xcrypt_error_if_negative: (expr) ? 2 : -1; })]
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* max_align_t shim. In the absence of official word from the
|
|
Packit |
13e0ca |
compiler, we guess that one of long double, uintmax_t, void *, and
|
|
Packit |
13e0ca |
void (*)(void) will have the maximum alignment. This is probably
|
|
Packit |
13e0ca |
not true in the presence of vector types, but we currently don't
|
|
Packit |
13e0ca |
use vector types, and hopefully any compiler with extra-aligned
|
|
Packit |
13e0ca |
vector types will provide max_align_t. */
|
|
Packit |
13e0ca |
#ifndef HAVE_MAX_ALIGN_T
|
|
Packit |
13e0ca |
typedef union
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
long double ld;
|
|
Packit |
13e0ca |
uintmax_t ui;
|
|
Packit |
13e0ca |
void *vp;
|
|
Packit |
13e0ca |
void (*vpf)(void);
|
|
Packit |
13e0ca |
} max_align_t;
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Several files expect the traditional definitions of these macros. */
|
|
Packit |
13e0ca |
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
Packit |
13e0ca |
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* ARRAY_SIZE is used in tests. */
|
|
Packit |
13e0ca |
#define ARRAY_SIZE(a_) (sizeof (a_) / sizeof ((a_)[0]))
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Provide a guaranteed way to erase sensitive memory at the best we
|
|
Packit |
13e0ca |
can, given the possibilities of the system. */
|
|
Packit |
13e0ca |
#if defined HAVE_MEMSET_S
|
|
Packit |
13e0ca |
/* Will never be optimized out. */
|
|
Packit |
13e0ca |
#define XCRYPT_SECURE_MEMSET(s, len) \
|
|
Packit |
13e0ca |
memset_s (s, len, 0x00, len)
|
|
Packit |
13e0ca |
#elif defined HAVE_EXPLICIT_BZERO
|
|
Packit |
13e0ca |
/* explicit_bzero() should give us enough guarantees. */
|
|
Packit |
13e0ca |
#define XCRYPT_SECURE_MEMSET(s, len) \
|
|
Packit |
13e0ca |
explicit_bzero(s, len)
|
|
Packit |
13e0ca |
#elif defined HAVE_EXPLICIT_MEMSET
|
|
Packit |
13e0ca |
/* Same guarantee goes for explicit_memset(). */
|
|
Packit |
13e0ca |
#define XCRYPT_SECURE_MEMSET(s, len) \
|
|
Packit |
13e0ca |
explicit_memset (s, 0x00, len)
|
|
Packit |
13e0ca |
#else
|
|
Packit |
13e0ca |
/* The best hope we have in this case. */
|
|
Packit |
13e0ca |
static inline
|
|
Packit |
13e0ca |
void _xcrypt_secure_memset (void *s, size_t len)
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
volatile unsigned char *c = s;
|
|
Packit |
13e0ca |
while (len--)
|
|
Packit |
13e0ca |
*c++ = 0x00;
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
#define XCRYPT_SECURE_MEMSET(s, len) \
|
|
Packit |
13e0ca |
_xcrypt_secure_memset (s, len)
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Per-symbol version tagging. Currently we only know how to do this
|
|
Packit |
13e0ca |
using GCC extensions. */
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if defined __GNUC__ && __GNUC__ >= 3
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Define ALIASNAME as a strong alias for NAME. */
|
|
Packit |
13e0ca |
#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
|
|
Packit |
13e0ca |
#define _strong_alias(name, aliasname) \
|
|
Packit |
13e0ca |
extern __typeof (name) aliasname __attribute__ ((alias (#name)))
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Set the symbol version for EXTNAME, which uses INTNAME as its
|
|
Packit |
13e0ca |
implementation. */
|
|
Packit |
13e0ca |
#define symver_set(extstr, intname, version, mode) \
|
|
Packit |
13e0ca |
__asm__ (".symver " #intname "," extstr mode #version)
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* A construct with the same syntactic role as the expansion of symver_set,
|
|
Packit |
13e0ca |
but which does nothing. */
|
|
Packit |
13e0ca |
#define symver_nop() __asm__ ("")
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#else
|
|
Packit |
13e0ca |
#error "Don't know how to do symbol versioning with this compiler"
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* The macros for versioned symbols work differently in this library
|
|
Packit |
13e0ca |
than they do in glibc. They are mostly auto-generated (see gen-vers.awk),
|
|
Packit |
13e0ca |
and we currently don't support compatibility symbols that need a different
|
|
Packit |
13e0ca |
definition from the default version.
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
Each definition of a public symbol should look like this:
|
|
Packit |
13e0ca |
#if INCLUDE_foo
|
|
Packit |
13e0ca |
int foo(arguments)
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
body
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
SYMVER_foo;
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
and the macros take care of the rest. Normally, to call a public
|
|
Packit |
13e0ca |
symbol you do nothing special. The macro symver_ref() forces
|
|
Packit |
13e0ca |
all uses of a particular name (in the file where it's used) to refer
|
|
Packit |
13e0ca |
to a particular version of a public symbol, e.g. for testing. */
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#ifdef IN_LIBCRYPT
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#include "crypt-symbol-vers.h"
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#ifdef PIC
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#define symver_compat(n, extstr, extname, intname, version) \
|
|
Packit |
13e0ca |
strong_alias (intname, extname ## __ ## n); \
|
|
Packit |
13e0ca |
symver_set (extstr, extname ## __ ## n, version, "@")
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#define symver_compat0(extstr, intname, version) \
|
|
Packit |
13e0ca |
symver_set (extstr, intname, version, "@")
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#define symver_default(extstr, intname, version) \
|
|
Packit |
13e0ca |
symver_set (extstr, intname, version, "@@")
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#else
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* When not building the shared library, don't do any of this. */
|
|
Packit |
13e0ca |
#define symver_compat(n, extstr, extname, intname, version) symver_nop ()
|
|
Packit |
13e0ca |
#define symver_compat0(extstr, intname, version) symver_nop ()
|
|
Packit |
13e0ca |
#define symver_default(extstr, intname, version) symver_nop ()
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Tests may need to _refer_ to compatibility symbols, but should never need
|
|
Packit |
13e0ca |
to _define_ them. */
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#define symver_ref(extstr, intname, version) \
|
|
Packit |
13e0ca |
symver_set(extstr, intname, version, "@")
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Get the set of hash algorithms to be included and some related
|
|
Packit |
13e0ca |
definitions. */
|
|
Packit |
13e0ca |
#include "crypt-hashes.h"
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Rename all of the internal-but-global symbols with a _crypt_ prefix
|
|
Packit |
13e0ca |
so that they do not interfere with other people's code when linking
|
|
Packit |
13e0ca |
statically. This list cannot be autogenerated, but is validated by
|
|
Packit |
13e0ca |
test-symbols.sh. */
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#define get_random_bytes _crypt_get_random_bytes
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_des || INCLUDE_des_xbsd || INCLUDE_des_big
|
|
Packit |
13e0ca |
#define des_crypt_block _crypt_des_crypt_block
|
|
Packit |
13e0ca |
#define des_set_key _crypt_des_set_key
|
|
Packit |
13e0ca |
#define des_set_salt _crypt_des_set_salt
|
|
Packit |
13e0ca |
#define comp_maskl _crypt_comp_maskl
|
|
Packit |
13e0ca |
#define comp_maskr _crypt_comp_maskr
|
|
Packit |
13e0ca |
#define fp_maskl _crypt_fp_maskl
|
|
Packit |
13e0ca |
#define fp_maskr _crypt_fp_maskr
|
|
Packit |
13e0ca |
#define ip_maskl _crypt_ip_maskl
|
|
Packit |
13e0ca |
#define ip_maskr _crypt_ip_maskr
|
|
Packit |
13e0ca |
#define key_perm_maskl _crypt_key_perm_maskl
|
|
Packit |
13e0ca |
#define key_perm_maskr _crypt_key_perm_maskr
|
|
Packit |
13e0ca |
#define m_sbox _crypt_m_sbox
|
|
Packit |
13e0ca |
#define psbox _crypt_psbox
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_nthash
|
|
Packit |
13e0ca |
#define md4_finish_ctx _crypt_md4_finish_ctx
|
|
Packit |
13e0ca |
#define md4_init_ctx _crypt_md4_init_ctx
|
|
Packit |
13e0ca |
#define md4_process_bytes _crypt_md4_process_bytes
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_md5 || INCLUDE_sunmd5
|
|
Packit |
13e0ca |
#define md5_finish_ctx _crypt_md5_finish_ctx
|
|
Packit |
13e0ca |
#define md5_init_ctx _crypt_md5_init_ctx
|
|
Packit |
13e0ca |
#define md5_process_bytes _crypt_md5_process_bytes
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_sha1
|
|
Packit |
13e0ca |
#define hmac_sha1_process_data _crypt_hmac_sha1_process_data
|
|
Packit |
13e0ca |
#define sha1_finish_ctx _crypt_sha1_finish_ctx
|
|
Packit |
13e0ca |
#define sha1_init_ctx _crypt_sha1_init_ctx
|
|
Packit |
13e0ca |
#define sha1_process_bytes _crypt_sha1_process_bytes
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_sha256
|
|
Packit |
13e0ca |
#define sha256_finish_ctx _crypt_sha256_finish_ctx
|
|
Packit |
13e0ca |
#define sha256_init_ctx _crypt_sha256_init_ctx
|
|
Packit |
13e0ca |
#define sha256_process_bytes _crypt_sha256_process_bytes
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_sha512
|
|
Packit |
13e0ca |
#define sha512_finish_ctx _crypt_sha512_finish_ctx
|
|
Packit |
13e0ca |
#define sha512_init_ctx _crypt_sha512_init_ctx
|
|
Packit |
13e0ca |
#define sha512_process_bytes _crypt_sha512_process_bytes
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_md5 || INCLUDE_sha256 || INCLUDE_sha512
|
|
Packit |
13e0ca |
#define gensalt_sha_rn _crypt_gensalt_sha_rn
|
|
Packit |
13e0ca |
#endif
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#endif /* crypt-port.h */
|