xref: /xnu-12377.41.6/osfmk/corecrypto/cc_memory.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
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