1 /* Copyright (c) (2014-2023) Apple Inc. All rights reserved. 2 * 3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which 4 * is contained in the License.txt file distributed with corecrypto) and only to 5 * people who accept that license. IMPORTANT: Any license rights granted to you by 6 * Apple Inc. (if any) are limited to internal use within your organization only on 7 * devices and computers you own or control, for the sole purpose of verifying the 8 * security characteristics and correct functioning of the Apple Software. You may 9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof. 10 * 11 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 12 * 13 * This file contains Original Code and/or Modifications of Original Code 14 * as defined in and that are subject to the Apple Public Source License 15 * Version 2.0 (the 'License'). You may not use this file except in 16 * compliance with the License. The rights granted to you under the License 17 * may not be used to create, or enable the creation or redistribution of, 18 * unlawful or unlicensed copies of an Apple operating system, or to 19 * circumvent, violate, or enable the circumvention or violation of, any 20 * terms of an Apple operating system software license agreement. 21 * 22 * Please obtain a copy of the License at 23 * http://www.opensource.apple.com/apsl/ and read it before using this file. 24 * 25 * The Original Code and all software distributed under the License are 26 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 27 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 28 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 29 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 30 * Please see the License for the specific language governing rights and 31 * limitations under the License. 32 * 33 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 34 */ 35 36 #include "cc_config.h" 37 #include "cc_debug.h" 38 #include "ccn_internal.h" 39 #include <corecrypto/cc_error.h> 40 #include <corecrypto/cc_priv.h> 41 42 CC_PTRCHECK_CAPABLE_HEADER() 43 44 #ifndef _CORECRYPTO_CC_MEMORY_H_ 45 #define _CORECRYPTO_CC_MEMORY_H_ 46 47 #if CORECRYPTO_DEBUG && !defined(_WIN32) && !defined(_WIN64) 48 #define CC_ALLOC_DEBUG 1 49 #else 50 #define CC_ALLOC_DEBUG 0 51 #endif 52 53 struct cc_ws; 54 typedef struct cc_ws cc_ws, *cc_ws_t; 55 56 struct cc_ws { 57 void *ctx; 58 cc_size nunits; 59 cc_size offset; 60 cc_unit *(*CC_SPTR(cc_ws, alloc))(cc_ws_t ws, cc_size n); 61 void(*CC_SPTR(cc_ws, free))(cc_ws_t ws); 62 }; 63 64 /* Workspace debugging. */ 65 66 #if CC_ALLOC_DEBUG 67 void cc_ws_alloc_debug(const void *p, const char *file, int line, const char *func); 68 void cc_ws_free_debug(const void *p); 69 #else 70 #define cc_ws_alloc_debug(...) 71 #define cc_ws_free_debug(...) 72 #endif 73 74 /* Generic heap malloc(). */ 75 void *cc_malloc_clear(size_t s); 76 void cc_free(void *p, size_t size); 77 78 /* Generic workspace functions. */ 79 cc_unit *cc_counted_by(n) cc_ws_alloc(cc_ws_t ws, cc_size n); 80 void cc_ws_free(cc_ws_t ws); 81 82 /* Stack-based workspace functions. */ 83 void cc_ws_free_stack(cc_ws_t ws); 84 85 /* Null workspace functions. */ 86 void cc_ws_free_null(cc_ws_t ws); 87 88 // Declare workspace with memory in HEAP. (FOR TESTING ONLY) 89 // This variant reserves a large workspace size in advance so 90 // we don't need to specify the exact requirement for tests. 91 #define CC_DECL_WORKSPACE_TEST(ws) \ 92 int ws##_rv; \ 93 CC_DECL_WORKSPACE_RV(ws, ccn_nof_size(1024 * 1024), ws##_rv); \ 94 cc_try_abort_if(ws##_rv != CCERR_OK, "alloc ws"); 95 96 #define CC_DECL_WORKSPACE_NULL(ws) \ 97 cc_ws ws##_ctx = { NULL, 0, 0, cc_ws_alloc, cc_ws_free_null }; \ 98 cc_ws_t ws = &ws##_ctx; \ 99 cc_ws_alloc_debug(&ws, __FILE__, __LINE__, __func__); 100 101 #if CC_USE_HEAP_FOR_WORKSPACE 102 103 // Declare workspace with memory in HEAP. 104 // This should be the preference for large memory allocations but it requires 105 // to propagate error in case of allocation failure. 106 #define CC_DECL_WORKSPACE_RV(ws, n, rv) \ 107 rv = CCERR_OK; \ 108 cc_unit *ws##_buf = (cc_unit *)cc_malloc_clear(ccn_sizeof_n(n)); \ 109 cc_ws ws##_ctx = { ws##_buf, n, 0, cc_ws_alloc, cc_ws_free }; \ 110 cc_ws_t ws = &ws##_ctx; \ 111 if (NULL == ws->ctx) \ 112 rv = CCERR_MEMORY_ALLOC_FAIL; \ 113 else \ 114 cc_ws_alloc_debug(&ws, __FILE__, __LINE__, __func__); 115 116 #else // !CC_USE_HEAP_FOR_WORKSPACE 117 118 // Declare workspace with memory in STACK. 119 // This is the least preferred option since most corecrypto client have 120 // small stack. 121 #define CC_DECL_WORKSPACE_RV(ws, n, rv) \ 122 rv = CCERR_OK; \ 123 _Pragma("GCC diagnostic push") \ 124 _Pragma("GCC diagnostic ignored \"-Wvla\"") \ 125 cc_unit ws##_buf[CC_MAX_EVAL((n), 1U)]; \ 126 _Pragma("GCC diagnostic pop") \ 127 cc_ws ws##_ctx = { ws##_buf, n, 0, cc_ws_alloc, cc_ws_free_stack }; \ 128 cc_ws_t ws = &ws##_ctx; \ 129 cc_ws_alloc_debug(&ws, __FILE__, __LINE__, __func__); 130 131 #endif // !CC_USE_HEAP_FOR_WORKSPACE 132 133 // ============================================================================= 134 // Common 135 // ============================================================================= 136 137 #define CC_DECL_WORKSPACE_OR_FAIL(ws, n) \ 138 int ws##_rv; \ 139 CC_DECL_WORKSPACE_RV(ws, n, ws##_rv); \ 140 if (ws##_rv != CCERR_OK) \ 141 return ws##_rv; 142 143 #define CC_FREE_WORKSPACE(ws) \ 144 cc_ws_free_debug(&ws); \ 145 ws->free(ws); 146 147 #define CC_CLEAR_AND_FREE_WORKSPACE CC_FREE_WORKSPACE 148 149 #define CC_DECL_BP_WS(ws, bp) cc_size _ws_offset = ws->offset; 150 #define CC_FREE_BP_WS(ws, bp) ws->offset = _ws_offset; 151 152 #define CC_CLEAR_BP_WS(ws, bp) \ 153 ccn_clear(ws->offset - _ws_offset, &((cc_unit *)ws->ctx)[_ws_offset]); 154 155 #define CC_ALLOC_WS(ws, n) ws->alloc(ws, n) 156 157 #if CC_KERNEL 158 #include <libkern/section_keywords.h> 159 #define CC_READ_ONLY_LATE(_t) SECURITY_READ_ONLY_LATE(_t) 160 #else 161 #define CC_READ_ONLY_LATE(_t) _t 162 #endif 163 164 165 #endif // _CORECRYPTO_CC_MEMORY_H_ 166