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
42CC_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
53struct cc_ws;
54typedef struct cc_ws cc_ws, *cc_ws_t;
55
56struct 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
67void cc_ws_alloc_debug(const void *p, const char *file, int line, const char *func);
68void 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(). */
75void *cc_malloc_clear(size_t s);
76void cc_free(void *p, size_t size);
77
78/* Generic workspace functions. */
79cc_unit *cc_counted_by(n) cc_ws_alloc(cc_ws_t ws, cc_size n);
80void cc_ws_free(cc_ws_t ws);
81
82/* Stack-based workspace functions. */
83void cc_ws_free_stack(cc_ws_t ws);
84
85/* Null workspace functions. */
86void 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