-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 181b17b
Showing
9 changed files
with
1,020 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2019-2023 Sebastian Ramacher, AIT Austrian Institute of Technology | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
this software and associated documentation files (the ""Software""), to deal in | ||
the Software without restriction, including without limitation the rights to | ||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
of the Software, and to permit persons to whom the Software is furnished to do | ||
so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#ifdef HAVE_CONFIG_H | ||
#include <config.h> | ||
#else | ||
#include "macros.h" | ||
|
||
/* define HAVE_* for more known good configurations */ | ||
#if !defined(HAVE_POSIX_MEMALIGN) && \ | ||
((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || defined(__APPLE__)) | ||
/* defined in POSIX and available on OS X */ | ||
#define HAVE_POSIX_MEMALIGN | ||
#endif /* HAVE_POSIX_MEMALIGN */ | ||
|
||
#if !defined(HAVE_MEMALIGN) && defined(__linux__) | ||
/* always available on Linux */ | ||
#define HAVE_MEMALIGN | ||
#endif /* HAVE_MEMALIGN */ | ||
|
||
#if !defined(HAVE_CONSTTIME_MEMEQUAL) && NETBSD_CHECK(7, 0) | ||
/* consttime_memequal was introduced in NetBSD 7.0 */ | ||
#define HAVE_CONSTTIME_MEMEQUAL | ||
#endif /* HAVE_CONSTTIME_MEMEQUAL */ | ||
#endif /* HAVE_CONFIG_H */ | ||
|
||
#include "compat.h" | ||
|
||
#if !defined(HAVE_ALIGNED_ALLOC) | ||
#include <errno.h> | ||
#include <limits.h> | ||
#include <stdlib.h> | ||
#if !defined(HAVE_POSIX_MEMALIGN) || defined(__MING32__) || defined(__MING64__) || defined(_MSC_VER) | ||
#include <malloc.h> | ||
#endif | ||
|
||
#if defined(HAVE_POSIX_MEMALIGN) | ||
static_assert((sizeof(void*) & (sizeof(void*) - 1)) == 0, "sizeof void* is not a power of 2"); | ||
#endif | ||
|
||
/* The fallback implementation tries to be as generic as possible. While all callers in this code | ||
* base satisfy all requirements, we still check them. Thereby, the fallback implementation may be | ||
* of use for others as well. */ | ||
void* faest_aligned_alloc(size_t alignment, size_t size) { | ||
/* check alignment (power of 2) and size (multiple of alignment) */ | ||
if (alignment & (alignment - 1) || size & (alignment - 1)) { | ||
errno = EINVAL; | ||
return NULL; | ||
} | ||
|
||
#if defined(HAVE_POSIX_MEMALIGN) | ||
/* check alignment (needs to be multiple of sizeof(void*)); posix_memalign has this additional | ||
* requirement */ | ||
if (alignment < sizeof(void*)) { | ||
alignment = sizeof(void*); | ||
/* fix up size; needs to be a multiple of alignment, i.e., sizeof(void*) */ | ||
size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); | ||
} | ||
|
||
void* ptr = NULL; | ||
const int err = posix_memalign(&ptr, alignment, size); | ||
if (err) { | ||
errno = err; | ||
} | ||
return ptr; | ||
#elif defined(HAVE_MEMALIGN) | ||
return memalign(alignment, size); | ||
#elif defined(__MINGW32__) || defined(__MINGW64__) | ||
return __mingw_aligned_malloc(size, alignment); | ||
#elif defined(_MSC_VER) | ||
return _aligned_malloc(size, alignment); | ||
#else | ||
if (!size) { | ||
return NULL; | ||
} | ||
const size_t offset = alignment - 1 + sizeof(uint8_t); | ||
uint8_t* buffer = malloc(size + offset); | ||
if (!buffer) { | ||
return NULL; | ||
} | ||
|
||
uint8_t* ptr = (uint8_t*)(((uintptr_t)(buffer) + offset) & ~(alignment - 1)); | ||
ptrdiff_t diff = ptr - buffer; | ||
if (diff > UINT8_MAX) { | ||
/* this should never happen in our code, but just to be safe */ | ||
free(buffer); | ||
errno = EINVAL; | ||
return NULL; | ||
} | ||
ptr[-1] = diff; | ||
return ptr; | ||
#endif | ||
} | ||
|
||
void faest_aligned_free(void* ptr) { | ||
#if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN) | ||
free(ptr); | ||
#elif defined(__MINGW32__) || defined(__MINGW64__) | ||
__mingw_aligned_free(ptr); | ||
#elif defined(_MSC_VER) | ||
_aligned_free(ptr); | ||
#else | ||
if (ptr) { | ||
uint8_t* u8ptr = ptr; | ||
free(u8ptr - u8ptr[-1]); | ||
} | ||
#endif | ||
} | ||
#endif /* HAVE_ALIGNED_ALLOC */ | ||
|
||
#if !defined(HAVE_TIMINGSAFE_BCMP) | ||
int faest_timingsafe_bcmp(const void* a, const void* b, size_t len) { | ||
#if defined(HAVE_CONSTTIME_MEMEQUAL) | ||
return !consttime_memequal(a, b, len); | ||
#else | ||
const unsigned char* p1 = a; | ||
const unsigned char* p2 = b; | ||
|
||
unsigned int res = 0; | ||
for (; len; --len, ++p1, ++p2) { | ||
res |= *p1 ^ *p2; | ||
} | ||
return res; | ||
#endif | ||
} | ||
#endif /* HAVE_TIMINGSAFE_BCMP */ | ||
|
||
#if !defined(HAVE_EXPLICIT_BZERO) | ||
#if defined(_WIN32) | ||
#include <windows.h> | ||
#endif | ||
|
||
void faest_explicit_bzero(void* a, size_t len) { | ||
#if defined(_WIN32) | ||
SecureZeroMemory(a, len); | ||
#else | ||
volatile char* p = a; | ||
for (; len; ++p, --len) { | ||
*p = 0; | ||
} | ||
#endif | ||
} | ||
#endif /* HAVE_EXPLICIT_BZERO */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#ifndef FAEST_COMPAT_H | ||
#define FAEST_COMPAT_H | ||
|
||
#if defined(HAVE_CONFIG_H) | ||
#include <config.h> | ||
#endif | ||
|
||
#include "macros.h" | ||
|
||
#include <stddef.h> | ||
|
||
#if !defined(HAVE_CONFIG_H) && !defined(OQS) | ||
/* In case cmake checks were not run, define HAVE_* for known good configurations. We skip those if | ||
* building for OQS, as the compat functions from there can be used instead. */ | ||
#if defined(__OpenBSD__) | ||
#include <sys/param.h> | ||
#endif /* __OpenBSD__ */ | ||
|
||
#if !defined(HAVE_ALIGNED_ALLOC) && !defined(__APPLE__) && !defined(__MINGW32__) && \ | ||
!defined(__MINGW64__) && !defined(_MSC_VER) && !defined(__ANDROID__) && \ | ||
(defined(_ISOC11_SOURCE) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)) | ||
/* aligned_alloc was introduced in ISO C 2011. Even if building with -std=c11, some toolchains do | ||
* not provide aligned_alloc, including toolchains for Android, OS X, MinGW, and others. */ | ||
#define HAVE_ALIGNED_ALLOC | ||
#endif /* HAVE_ALIGNED_ALLOC */ | ||
|
||
#if !defined(HAVE_EXPLICIT_BZERO) && \ | ||
(GLIBC_CHECK(2, 25) || (defined(__OpenBSD__) && OpenBSD >= 201405) || FREEBSD_CHECK(11, 0) || \ | ||
NETBSD_CHECK(8, 0)) | ||
/* explicit_bzero was introduced in glibc 2.35, OpenBSD 5.5, FreeBSD 11.0 and NetBSD 8.0 */ | ||
#define HAVE_EXPLICIT_BZERO | ||
#endif /* HAVE_EXPLICIT_BZERO */ | ||
|
||
#if !defined(HAVE_TIMINGSAFE_BCMP) && ((defined(__OpenBSD__) && OpenBSD >= 201105) || \ | ||
FREEBSD_CHECK(12, 0) || MACOSX_CHECK(10, 12, 1)) | ||
/* timingsafe_bcmp was introduced in OpenBSD 4.9, FreeBSD 12.0, and MacOS X 10.12 */ | ||
#define HAVE_TIMINGSAFE_BCMP | ||
#endif /* HAVE_TIMINGSAFE_BCMP */ | ||
#endif /* !HAVE_CONFIG_H && !OQS */ | ||
|
||
#if defined(HAVE_ALIGNED_ALLOC) | ||
#include <stdlib.h> | ||
|
||
#define faest_aligned_alloc(alignment, size) aligned_alloc((alignment), (size)) | ||
#define faest_aligned_free(ptr) free((ptr)) | ||
#else | ||
FAEST_BEGIN_C_DECL | ||
|
||
/** | ||
* Some aligned_alloc compatbility implementations require custom free | ||
* functions, so we provide one too. | ||
*/ | ||
void faest_aligned_free(void* ptr); | ||
/** | ||
* Compatibility implementation of aligned_alloc from ISO C 2011. | ||
*/ | ||
void* faest_aligned_alloc(size_t alignment, size_t size) ATTR_MALLOC(faest_aligned_free) | ||
ATTR_ALLOC_ALIGN(1) ATTR_ALLOC_SIZE(2); | ||
|
||
FAEST_END_C_DECL | ||
#endif /* HAVE_ALIGNED_ALLOC */ | ||
|
||
#include "endian_compat.h" | ||
|
||
#if defined(HAVE_TIMINGSAFE_BCMP) | ||
#define faest_timingsafe_bcmp(a, b, len) timingsafe_bcmp((a), (b), (len)) | ||
#else | ||
FAEST_BEGIN_C_DECL | ||
|
||
/** | ||
* Compatibility implementation of timingsafe_bcmp from OpenBSD 4.9 and FreeBSD 12.0. | ||
*/ | ||
int faest_timingsafe_bcmp(const void* a, const void* b, size_t len); | ||
|
||
FAEST_END_C_DECL | ||
#endif /* HAVE_TIMINGSAFE_BCMP */ | ||
|
||
#if defined(HAVE_EXPLICIT_BZERO) | ||
#define faest_explicit_bzero(ptr, len) explicit_bzero((ptr), (len)) | ||
#else | ||
FAEST_BEGIN_C_DECL | ||
|
||
/** | ||
* Compatibility implementation of explicit_bzero | ||
*/ | ||
void faest_explicit_bzero(void* a, size_t len); | ||
|
||
FAEST_END_C_DECL | ||
#endif /* HAVE_EXPLICIT_BZERO */ | ||
|
||
#if defined(OQS) | ||
#define faest_aligned_alloc(alignment, size) OQS_MEM_aligned_alloc((alignment), (size)) | ||
#define faest_aligned_free(ptr) OQS_MEM_aligned_free((ptr)) | ||
#define faest_timingsafe_bcmp(a, b, len) OQS_MEM_secure_bcmp((a), (b), (len)) | ||
#define faest_explicit_bzero(ptr, len) OQS_MEM_cleanse(ptr, len) | ||
#endif | ||
|
||
/* helper macros/functions for checked integer subtraction */ | ||
#if GNUC_CHECK(5, 0) || __has_builtin(__builtin_add_overflow) | ||
#define sub_overflow_size_t(x, y, diff) __builtin_sub_overflow(x, y, diff) | ||
#else | ||
#include <stdbool.h> | ||
#include <stddef.h> | ||
|
||
ATTR_ARTIFICIAL | ||
static inline bool sub_overflow_size_t(const size_t x, const size_t y, size_t* diff) { | ||
*diff = x - y; | ||
return x < y; | ||
} | ||
#endif | ||
|
||
#include <stdint.h> | ||
|
||
/* helper functions for parity computations */ | ||
#if GNUC_CHECK(4, 9) || __has_builtin(__builtin_parity) | ||
ATTR_CONST ATTR_ARTIFICIAL static inline uint64_t parity64_uint64(uint64_t in) { | ||
return __builtin_parityll(in); | ||
} | ||
#else | ||
/* byte parity from: https://graphics.stanford.edu/~seander/bithacks.html#ParityWith64Bits */ | ||
ATTR_CONST ATTR_ARTIFICIAL static inline uint64_t parity64_uint64(uint64_t in) { | ||
in ^= in >> 1; | ||
in ^= in >> 2; | ||
in = (in & 0x1111111111111111) * 0x1111111111111111; | ||
return (in >> 60) & 1; | ||
} | ||
#endif | ||
|
||
/* helper functions to compute number of leading zeroes */ | ||
#if GNUC_CHECK(4, 7) || __has_builtin(__builtin_clz) | ||
ATTR_CONST ATTR_ARTIFICIAL static inline uint32_t clz(uint32_t x) { | ||
return x ? __builtin_clz(x) : 32; | ||
} | ||
#elif defined(_MSC_VER) | ||
#include <intrin.h> | ||
ATTR_CONST ATTR_ARTIFICIAL static inline uint32_t clz(uint32_t x) { | ||
unsigned long index = 0; | ||
if (_BitScanReverse(&index, x)) { | ||
return 31 - index; | ||
} | ||
return 32; | ||
} | ||
#else | ||
/* Number of leading zeroes of x. | ||
* From the book | ||
* H.S. Warren, *Hacker's Delight*, Pearson Education, 2003. | ||
* http://www.hackersdelight.org/hdcodetxt/nlz.c.txt | ||
*/ | ||
ATTR_CONST ATTR_ARTIFICIAL static inline uint32_t clz(uint32_t x) { | ||
if (!x) { | ||
return 32; | ||
} | ||
|
||
uint32_t n = 1; | ||
if (!(x >> 16)) { | ||
n = n + 16; | ||
x = x << 16; | ||
} | ||
if (!(x >> 24)) { | ||
n = n + 8; | ||
x = x << 8; | ||
} | ||
if (!(x >> 28)) { | ||
n = n + 4; | ||
x = x << 4; | ||
} | ||
if (!(x >> 30)) { | ||
n = n + 2; | ||
x = x << 2; | ||
} | ||
n = n - (x >> 31); | ||
|
||
return n; | ||
} | ||
#endif | ||
|
||
ATTR_CONST ATTR_ARTIFICIAL static inline uint32_t ceil_log2(uint32_t x) { | ||
if (!x) { | ||
return 0; | ||
} | ||
return 32 - clz(x - 1); | ||
} | ||
|
||
#if !defined(__cplusplus) | ||
#include <assert.h> | ||
|
||
/* static_assert fallback */ | ||
#if !defined(_MSC_VER) && !defined(static_assert) | ||
#define static_assert _Static_assert | ||
#endif | ||
#endif | ||
|
||
#endif |
Oops, something went wrong.