--- /dev/null
+/*
+ * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/e_os.h"
+#include "internal/cryptlib.h"
+#include "internal/mem_alloc_utils.h"
+#include "crypto/cryptlib.h"
+#include <stdlib.h>
+
+void *ossl_malloc_align(size_t num, size_t alignment, void **freeptr,
+ const char *file, int line)
+{
+ size_t alloc_bytes;
+ void *ret;
+
+ *freeptr = NULL;
+
+ /* Ensure that alignment is a power of two */
+ if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
+ ossl_report_alloc_err_inv(file, line);
+ return NULL;
+ }
+
+ /*
+ * Note: Windows supports an _aligned_malloc call, but we choose
+ * not to use it here, because allocations from that function
+ * require that they be freed via _aligned_free. Given that
+ * we can't differentiate plain malloc blocks from blocks obtained
+ * via _aligned_malloc, just avoid its use entirely
+ */
+
+ if (ossl_unlikely(!ossl_size_add(num, alignment, &alloc_bytes, file, line)))
+ return NULL;
+
+ /*
+ * Step 1: Allocate an amount of memory that is <alignment>
+ * bytes bigger than requested
+ */
+ *freeptr = CRYPTO_malloc(alloc_bytes, file, line);
+ if (*freeptr == NULL)
+ return NULL;
+
+ /*
+ * Step 2: Add <alignment - 1> bytes to the pointer
+ * This will cross the alignment boundary that is
+ * requested
+ */
+ ret = (void *)((char *)*freeptr + (alignment - 1));
+
+ /*
+ * Step 3: Use the alignment as a mask to translate the
+ * least significant bits of the allocation at the alignment
+ * boundary to 0. ret now holds a pointer to the memory
+ * buffer at the requested alignment
+ * NOTE: It is a documented requirement that alignment be a
+ * power of 2, which is what allows this to work
+ */
+ ret = (void *)((uintptr_t)ret & (uintptr_t)(~(alignment - 1)));
+
+ return ret;
+}
threads_pthread.c threads_win.c threads_none.c threads_common.c \
initthread.c context.c sparse_array.c asn1_dsa.c packet.c \
param_build.c param_build_set.c der_writer.c threads_lib.c \
- params_dup.c time.c array_alloc.c deterministic_nonce.c
+ params_dup.c time.c array_alloc.c aligned_alloc.c deterministic_nonce.c
SOURCE[../libcrypto]=$UTIL_COMMON \
mem.c mem_sec.c \
void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
const char *file, int line)
{
- size_t alloc_bytes;
- void *ret;
-
*freeptr = NULL;
/* Ensure that alignment is a power of two */
if (malloc_impl == CRYPTO_malloc) {
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
int memalign_ret;
+ void *ret;
/* posix_memalign() requires alignment to be at least sizeof(void *) */
if (alignment < sizeof(void *))
#endif
}
- /* we have to do this the hard way */
-
- /*
- * Note: Windows supports an _aligned_malloc call, but we choose
- * not to use it here, because allocations from that function
- * require that they be freed via _aligned_free. Given that
- * we can't differentiate plain malloc blocks from blocks obtained
- * via _aligned_malloc, just avoid its use entirely
- */
-
- if (ossl_unlikely(!ossl_size_add(num, alignment, &alloc_bytes, file, line)))
- return NULL;
-
- /*
- * Step 1: Allocate an amount of memory that is <alignment>
- * bytes bigger than requested
- */
- *freeptr = CRYPTO_malloc(alloc_bytes, file, line);
- if (*freeptr == NULL)
- return NULL;
-
- /*
- * Step 2: Add <alignment - 1> bytes to the pointer
- * This will cross the alignment boundary that is
- * requested
- */
- ret = (void *)((char *)*freeptr + (alignment - 1));
-
- /*
- * Step 3: Use the alignment as a mask to translate the
- * least significant bits of the allocation at the alignment
- * boundary to 0. ret now holds a pointer to the memory
- * buffer at the requested alignment
- * NOTE: It is a documented requirement that alignment be a
- * power of 2, which is what allows this to work
- */
- ret = (void *)((uintptr_t)ret & (uintptr_t)(~(alignment - 1)));
- return ret;
+ return ossl_malloc_align(num, alignment, freeptr, file, line);
}
void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)
+/*
+ * A helper open-coded aligned alloc implementation around CRYPTO_malloc(),
+ * for use in cases where non-standard malloc implementation is (or may be,
+ * as it is the case of the FIPS module) used, or posix_memalign
+ * is not available.
+ */
+void *ossl_malloc_align(size_t num, size_t alignment, void **freeptr,
+ const char *file, int line);
+
/*
* A helper routine to report memory allocation errors.
* Similar to the ERR_raise() macro, but accepts explicit file/line arguments,
#include "crypto/context.h"
#include "fipscommon.h"
#include "internal/core.h"
+#include "internal/mem_alloc_utils.h"
static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes";
static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no";
void *CRYPTO_aligned_alloc(size_t num, size_t align, void **freeptr,
const char *file, int line)
{
- return NULL;
+ return ossl_malloc_align(num, align, freeptr, file, line);
}
int BIO_snprintf(char *buf, size_t n, const char *format, ...)