mirror of https://github.com/openssl/openssl.git
Move the open-coded aligned alloc in a separate file and use it in FIPS module
Factor the open-coded aligned allocation implementation in a separate file and use it instead of just returning NULL in CRYPTO_aligned_alloc implementation in the FIPS provider. Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org> Reviewed-by: Neil Horman <nhorman@openssl.org> Reviewed-by: Saša Nedvědický <sashan@openssl.org> (Merged from https://github.com/openssl/openssl/pull/28295)
This commit is contained in:
parent
1be238a972
commit
8e28f5c0b9
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -100,7 +100,7 @@ $UTIL_COMMON=\
|
|||
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 \
|
||||
|
|
43
crypto/mem.c
43
crypto/mem.c
|
@ -231,9 +231,6 @@ void *CRYPTO_zalloc(size_t num, const char *file, int line)
|
|||
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 */
|
||||
|
@ -246,6 +243,7 @@ void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
|
|||
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 *))
|
||||
|
@ -267,44 +265,7 @@ void *CRYPTO_aligned_alloc(size_t num, size_t alignment, void **freeptr,
|
|||
#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)
|
||||
|
|
|
@ -26,6 +26,15 @@
|
|||
|
||||
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,
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#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";
|
||||
|
@ -1183,7 +1184,7 @@ int CRYPTO_secure_allocated(const void *ptr)
|
|||
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, ...)
|
||||
|
|
Loading…
Reference in New Issue