/** @file * IPRT - Memory Allocate for Sensitive Data. */ /* * Copyright (C) 2006-2024 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included * in the VirtualBox distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. * * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 */ #ifndef IPRT_INCLUDED_memsafer_h #define IPRT_INCLUDED_memsafer_h #ifndef RT_WITHOUT_PRAGMA_ONCE # pragma once #endif #include /* RTMEM_TAG */ RT_C_DECLS_BEGIN /** @defgroup grp_rt_memsafer RTMemSafer - Memory Allocator for Sensitive Data * @ingroup grp_rt * * This API doesn't provide 100% secure storage, it only provider more secure * and safer storage. Thus the API isn't called RTMemSafe because you cannot * assume the data is safe against all kinds of extraction methods. * * The API guarantee that the memory won't be returned to the system containing * any of the information you put there. It will be repeatedly wiped after use. * * The API tries to isolate your data from other information stored in the * process/system. How well this is done depends on the implementation. The * more complicated implementations will provide protection against heartbleed * like bugs where pieces of the heap is copied onto the wire. * * The more hardened implementations of the API will also do their best to * prevent the memory from ending up in process dumps or being readable by * debuggers. * * Finally, two functions are provided for scrambling the sensitive memory while * it's not in use. * * @{ */ /** @name RTMEMSAFER_F_XXX * @{ */ /** Require the memory to not hit the page file. * @remarks Makes not guarantees with regards to hibernation / * suspend-to-disk. */ #define RTMEMSAFER_F_REQUIRE_NOT_PAGABLE RT_BIT_32(0) /** Do not use the SUPLib allocator. * The SUPLib allocator may be terminated earlier than IPRT, * automatically rendering the allocations inaccessible. */ #define RTMEMSAFER_F_NO_SUPLIB_ALLOC RT_BIT_32(1) /** Mask of valid bits. */ #define RTMEMSAFER_F_VALID_MASK UINT32_C(0x00000003) /** @} */ /** * Scrambles memory allocated by RTMemSaferAllocZEx and associates after use. * * Call this when the sensitive data isn't actively being used. It will at a * minimum make sure the data is slightly scrambled, how hard it is to unbutton * is dependent on which implementation is used and available host support. * * The user must synchronize calls to RTMemSaferScramble and * RTMemSaferUnscramble, this memory allocator provides no help and keeps no * state information around. * * @returns IPRT status code. * @param pv The pointer returned by the allocation function. * @param cb The exact size given to the allocation function. */ RTDECL(int) RTMemSaferScramble(void *pv, size_t cb); /** * Unscrambles memory allocated by RTMemSaferAllocZEx and associates before use. * * This undoes the effect of RTMemSaferScramble. * * @returns IPRT status code. * @param pv The pointer returned by the allocation function. * @param cb The exact size given to the allocation function. */ RTDECL(int) RTMemSaferUnscramble(void *pv, size_t cb); /** * Allocates memory for sensitive data. * * Some effort will be taken to isolate the data from other memory allocation. * Memory is always zeroed. * * @returns IPRT status code. * @param ppvNew Where to return the pointer to the memory. * @param cb Number of bytes to allocate. * @param fFlags Flags for controlling the allocation, see * RTMEMSAFER_F_XXX. * @param pszTag Allocation tag used for statistics and such. */ RTDECL(int) RTMemSaferAllocZExTag(void **ppvNew, size_t cb, uint32_t fFlags, const char *pszTag) RT_NO_THROW_PROTO; /** * Allocates memory for sensitive data. * * Some effort will be taken to isolate the data from other memory allocation. * Memory is always zeroed. * * @returns IPRT status code. * @param a_ppvNew Where to return the pointer to the memory. * @param a_cb Number of bytes to allocate. * @param a_fFlags Flags for controlling the allocation, see * RTMEMSAFER_F_XXX. */ #define RTMemSaferAllocZEx(a_ppvNew, a_cb, a_fFlags) RTMemSaferAllocZExTag(a_ppvNew, a_cb, a_fFlags, RTMEM_TAG) /** * Allocates memory for sensitive data. * * Some effort will be taken to isolate the data from other memory allocation. * Memory is always zeroed. * * @returns Pointer to the allocated memory. * @param cb Number of bytes to allocate. * @param pszTag Allocation tag used for statistics and such. */ RTDECL(void *) RTMemSaferAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO; /** * Allocates memory for sensitive data. * * Some effort will be taken to isolate the data from other memory allocation. * Memory is always zeroed. * * @returns Pointer to the allocated memory. * @param a_cb Number of bytes to allocate. */ #define RTMemSaferAllocZ(a_cb) RTMemSaferAllocZTag(a_cb, RTMEM_TAG) /** * Reallocates memory allocated by RTMemSaferAllocZEx, RTMemSaferAllocZ, * RTMemSaferAllocZExTag, or RTMemSaferAllocZTag. * * When extending the allocation, the new memory will be zeroed. When shrinking * the allocation the left over memory will be wiped clean using * RTMemWipeThorougly. * * The function follows the standard realloc behavior. * * @returns IPRT status code. * @param cbOld The current allocation size. * @param pvOld The current allocation. * @param cbNew The size of the new allocation. * @param ppvNew Where to return the pointer to the new memory. * @param fFlags Flags for controlling the allocation, see * RTMEMSAFER_F_XXX. It is not permitted to drop saftely * requirments after the initial allocation. * @param pszTag Allocation tag used for statistics and such. */ RTDECL(int) RTMemSaferReallocZExTag(size_t cbOld, void *pvOld, size_t cbNew, void **ppvNew, uint32_t fFlags, const char *pszTag) RT_NO_THROW_PROTO; /** * Reallocates memory allocated by RTMemSaferAllocZEx, RTMemSaferAllocZ, * RTMemSaferAllocZExTag, or RTMemSaferAllocZTag. * * When extending the allocation, the new memory will be zeroed. When shrinking * the allocation the left over memory will be wiped clean using * RTMemWipeThorougly. * * The function follows the standard realloc behavior. * * @returns IPRT status code. * @param a_cbOld The current allocation size. * @param a_pvOld The current allocation. * @param a_cbNew The size of the new allocation. * @param a_ppvNew Where to return the pointer to the new memory. * @param a_fFlags Flags for controlling the allocation. See RTMEMSAFER_ALLOC_EX_FLAGS_* defines, * this takes only effect when allocating completely new memory, for extending or * shrinking existing allocations the flags of the allocation take precedence. */ #define RTMemSaferReallocZEx(a_cbOld, a_pvOld, a_cbNew, a_ppvNew, a_fFlags) \ RTMemSaferReallocZExTag(a_cbOld, a_pvOld, a_cbNew, a_ppvNew, a_fFlags, RTMEM_TAG) /** * Reallocates memory allocated by RTMemSaferAllocZ or RTMemSaferAllocZTag. * * When extending the allocation, the new memory will be zeroed. When shrinking * the allocation the left over memory will be wiped clean using * RTMemWipeThorougly. * * The function follows the standard realloc behavior. * * @returns Pointer to the allocated memory. * @param cbOld The current allocation size. * @param pvOld The current allocation. * @param cbNew The size of the new allocation. * @param pszTag Allocation tag used for statistics and such. */ RTDECL(void *) RTMemSaferReallocZTag(size_t cbOld, void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW_PROTO; /** * Reallocates memory allocated by RTMemSaferAllocZ or RTMemSaferAllocZTag. * * When extending the allocation, the new memory will be zeroed. When shrinking * the allocation the left over memory will be wiped clean using * RTMemWipeThorougly. * * The function follows the standard realloc behavior. * * @returns Pointer to the allocated memory. * @param a_cbOld The current allocation size. * @param a_pvOld The current allocation. * @param a_cbNew The size of the new allocation. */ #define RTMemSaferReallocZ(a_cbOld, a_pvOld, a_cbNew) RTMemSaferReallocZTag(a_cbOld, a_pvOld, a_cbNew, RTMEM_TAG) /** * Frees memory allocated by RTMemSaferAllocZ* or RTMemSaferReallocZ*. * * Before freeing the allocated memory, it will be wiped clean using * RTMemWipeThorougly. * * @param pv The allocation. * @param cb The allocation size. */ RTDECL(void) RTMemSaferFree(void *pv, size_t cb) RT_NO_THROW_PROTO; /** * Gets the amount of memory allocated at @a pv. * * This can be used to check if the allocation was made using an RTMemSafer API. * * @returns Allocation size in bytes, 0 if not a RTMemSafer allocation. * @param pv The alleged RTMemSafer allocation. * * @note Not supported in all contexts and implementations of the API. */ RTDECL(size_t) RTMemSaferGetSize(void *pv) RT_NO_THROW_PROTO; /** @} */ RT_C_DECLS_END #endif /* !IPRT_INCLUDED_memsafer_h */