asherah 1.3.19 → 1.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/download-libraries.sh +4 -4
- package/src/asherah.cc +139 -518
- package/src/cobhan_napi_interop.h +146 -40
package/package.json
CHANGED
|
@@ -4,8 +4,8 @@ echo "Downloading Asherah libraries"
|
|
|
4
4
|
|
|
5
5
|
source .asherah-version
|
|
6
6
|
|
|
7
|
-
rm -rf lib
|
|
8
|
-
mkdir lib
|
|
7
|
+
#rm -rf lib
|
|
8
|
+
mkdir -p lib
|
|
9
9
|
cd lib || exit 1
|
|
10
10
|
|
|
11
11
|
OS=$(uname)
|
|
@@ -51,5 +51,5 @@ curl -s -L --fail -O --retry 999 --retry-max-time 0 "https://github.com/godaddy/
|
|
|
51
51
|
grep -e "${ARCHIVE}" -e "${HEADER}" "${SUMS}" > ./SHA256SUM
|
|
52
52
|
#shasum -a 256 -c ./SHA256SUM || (echo 'SHA256 mismatch!' ; rm -f ./*.a ./*.h ; exit 1)
|
|
53
53
|
|
|
54
|
-
mv "${ARCHIVE}" libasherah.a
|
|
55
|
-
mv "${HEADER}" libasherah.h
|
|
54
|
+
mv -f "${ARCHIVE}" libasherah.a
|
|
55
|
+
mv -f "${HEADER}" libasherah.h
|
package/src/asherah.cc
CHANGED
|
@@ -17,12 +17,10 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
17
17
|
|
|
18
18
|
if (unlikely(setup_state == 1)) {
|
|
19
19
|
log_error_and_throw(env, "setup", "setup called twice");
|
|
20
|
-
return;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
if (unlikely(info.Length() < 1)) {
|
|
24
23
|
log_error_and_throw(env, "setup", "Wrong number of arguments");
|
|
25
|
-
return;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
Napi::String config;
|
|
@@ -38,7 +36,6 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
38
36
|
config_json = parse.Call(json, {config}).As<Napi::Object>();
|
|
39
37
|
} else {
|
|
40
38
|
log_error_and_throw(env, "setup", "Wrong argument type");
|
|
41
|
-
return;
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
Napi::String product_id = config_json.Get("ProductID").As<Napi::String>();
|
|
@@ -56,49 +53,15 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
56
53
|
debug_log("setup", "verbose_flag: defaulting to false");
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
// Determine size
|
|
60
|
-
size_t config_utf8_byte_length;
|
|
61
|
-
config_utf8_byte_length = nstring_utf8_byte_length(env, config);
|
|
62
|
-
if (unlikely(config_utf8_byte_length == (size_t)(-1))) {
|
|
63
|
-
log_error_and_throw(env, "setup", "Failed to get config utf8 length");
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Allocate
|
|
68
56
|
char *config_cobhan_buffer;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
size_t config_cobhan_buffer_size_bytes =
|
|
73
|
-
calculate_cobhan_buffer_size_bytes(config_utf8_byte_length);
|
|
74
|
-
debug_log_alloca("setup", "config_cobhan_buffer",
|
|
75
|
-
config_cobhan_buffer_size_bytes);
|
|
76
|
-
config_cobhan_buffer = (char *)alloca(config_cobhan_buffer_size_bytes);
|
|
77
|
-
configure_cbuffer(config_cobhan_buffer, config_utf8_byte_length);
|
|
78
|
-
} else {
|
|
79
|
-
// Otherwise, allocate it on the heap
|
|
80
|
-
config_cobhan_buffer_unique_ptr =
|
|
81
|
-
heap_allocate_cbuffer("config_cobhan_buffer", config_utf8_byte_length);
|
|
82
|
-
config_cobhan_buffer = config_cobhan_buffer_unique_ptr.get();
|
|
83
|
-
}
|
|
84
|
-
if (unlikely(config_cobhan_buffer == nullptr)) {
|
|
85
|
-
log_error_and_throw(env, "setup",
|
|
86
|
-
"Failed to allocate config cobhan buffer");
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
57
|
+
size_t config_copied_bytes = 0;
|
|
58
|
+
NAPI_STRING_TO_CBUFFER(config, config_cobhan_buffer, config_copied_bytes,
|
|
59
|
+
"setup");
|
|
89
60
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
config_cobhan_buffer, &config_copied_bytes);
|
|
95
|
-
if (unlikely(config_cobhan_buffer == nullptr)) {
|
|
96
|
-
log_error_and_throw(env, "setup", "Failed to copy config to cobhan buffer");
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (unlikely(verbose_flag)) {
|
|
101
|
-
debug_log("setup", "Calling asherah-cobhan SetupJson");
|
|
61
|
+
char *config_canary_ptr = get_canary_ptr(config_cobhan_buffer);
|
|
62
|
+
if (unlikely(!check_canary_ptr(config_canary_ptr))) {
|
|
63
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
64
|
+
"Failed initial canary check for config_cobhan_buffer");
|
|
102
65
|
}
|
|
103
66
|
|
|
104
67
|
// extern GoInt32 SetupJson(void* configJson);
|
|
@@ -108,17 +71,23 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
108
71
|
debug_log("setup", "Returned from asherah-cobhan SetupJson");
|
|
109
72
|
}
|
|
110
73
|
|
|
74
|
+
if (unlikely(!check_canary_ptr(config_canary_ptr))) {
|
|
75
|
+
log_error_and_throw(
|
|
76
|
+
env, "encrypt_to_json",
|
|
77
|
+
"Failed post-call canary check for config_cobhan_buffer");
|
|
78
|
+
}
|
|
79
|
+
|
|
111
80
|
if (unlikely(result < 0)) {
|
|
112
81
|
// TODO: Convert this to a proper error message
|
|
113
82
|
log_error_and_throw(env, "setup", std::to_string(result));
|
|
114
|
-
return;
|
|
115
83
|
}
|
|
116
84
|
setup_state = 1;
|
|
117
85
|
}
|
|
118
86
|
|
|
119
|
-
Napi::
|
|
120
|
-
|
|
121
|
-
|
|
87
|
+
Napi::String encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
88
|
+
size_t data_bytes,
|
|
89
|
+
char *partition_id_cobhan_buffer,
|
|
90
|
+
char *input_cobhan_buffer) {
|
|
122
91
|
|
|
123
92
|
size_t asherah_output_size_bytes =
|
|
124
93
|
estimate_asherah_output_size_bytes(data_bytes, partition_bytes);
|
|
@@ -129,40 +98,24 @@ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
129
98
|
}
|
|
130
99
|
|
|
131
100
|
char *output_cobhan_buffer;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// If the buffer is small enough, allocate it on the stack
|
|
135
|
-
size_t output_cobhan_buffer_size_bytes =
|
|
136
|
-
calculate_cobhan_buffer_size_bytes(asherah_output_size_bytes);
|
|
137
|
-
debug_log_alloca("encrypt_to_json", "output_cobhan_buffer",
|
|
138
|
-
output_cobhan_buffer_size_bytes);
|
|
139
|
-
output_cobhan_buffer = (char *)alloca(output_cobhan_buffer_size_bytes);
|
|
140
|
-
configure_cbuffer(output_cobhan_buffer, asherah_output_size_bytes);
|
|
141
|
-
} else {
|
|
142
|
-
// Otherwise, allocate it on the heap
|
|
143
|
-
output_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
144
|
-
"output_cobhan_buffer", asherah_output_size_bytes);
|
|
145
|
-
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
146
|
-
}
|
|
147
|
-
if (unlikely(output_cobhan_buffer == nullptr)) {
|
|
148
|
-
return log_error_and_throw(env, "encrypt_to_json",
|
|
149
|
-
"Failed to allocate cobhan output buffer");
|
|
150
|
-
}
|
|
101
|
+
ALLOCATE_OUTPUT_CBUFFER(output_cobhan_buffer, asherah_output_size_bytes,
|
|
102
|
+
"encrypt_to_json");
|
|
151
103
|
|
|
152
104
|
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
153
|
-
if(!check_canary_ptr(partition_id_canary_ptr)) {
|
|
154
|
-
|
|
155
|
-
|
|
105
|
+
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
106
|
+
log_error_and_throw(
|
|
107
|
+
env, "encrypt_to_json",
|
|
108
|
+
"Failed initial canary check for partition_id_cobhan_buffer");
|
|
156
109
|
}
|
|
157
110
|
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
158
|
-
if(!check_canary_ptr(input_canary_ptr)) {
|
|
159
|
-
|
|
160
|
-
|
|
111
|
+
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
112
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
113
|
+
"Failed initial canary check for input_cobhan_buffer");
|
|
161
114
|
}
|
|
162
115
|
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
163
|
-
if(!check_canary_ptr(output_canary_ptr)) {
|
|
164
|
-
|
|
165
|
-
|
|
116
|
+
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
117
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
118
|
+
"Failed initial canary check for output_cobhan_buffer");
|
|
166
119
|
}
|
|
167
120
|
|
|
168
121
|
if (unlikely(verbose_flag)) {
|
|
@@ -178,29 +131,32 @@ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
178
131
|
debug_log("encrypt_to_json", "Returning from asherah-cobhan EncryptToJson");
|
|
179
132
|
}
|
|
180
133
|
|
|
181
|
-
if(!check_canary_ptr(partition_id_canary_ptr)) {
|
|
182
|
-
|
|
183
|
-
|
|
134
|
+
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
135
|
+
log_error_and_throw(
|
|
136
|
+
env, "encrypt_to_json",
|
|
137
|
+
"Failed post-call canary check for partition_id_cobhan_buffer");
|
|
184
138
|
}
|
|
185
|
-
if(!check_canary_ptr(input_canary_ptr)) {
|
|
186
|
-
|
|
187
|
-
|
|
139
|
+
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
140
|
+
log_error_and_throw(
|
|
141
|
+
env, "encrypt_to_json",
|
|
142
|
+
"Failed post-call canary check for input_cobhan_buffer");
|
|
188
143
|
}
|
|
189
|
-
if(!check_canary_ptr(output_canary_ptr)) {
|
|
190
|
-
|
|
191
|
-
|
|
144
|
+
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
145
|
+
log_error_and_throw(
|
|
146
|
+
env, "encrypt_to_json",
|
|
147
|
+
"Failed post-call canary check for output_cobhan_buffer");
|
|
192
148
|
}
|
|
193
149
|
|
|
194
150
|
if (unlikely(result < 0)) {
|
|
195
151
|
// TODO: Convert this to a proper error message
|
|
196
|
-
|
|
152
|
+
log_error_and_throw(env, "encrypt_to_json", std::to_string(result));
|
|
197
153
|
}
|
|
198
154
|
|
|
199
|
-
Napi::
|
|
155
|
+
Napi::String output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
200
156
|
return output;
|
|
201
157
|
}
|
|
202
158
|
|
|
203
|
-
Napi::
|
|
159
|
+
Napi::String encrypt(const Napi::CallbackInfo &info) {
|
|
204
160
|
Napi::Env env = info.Env();
|
|
205
161
|
|
|
206
162
|
if (unlikely(verbose_flag)) {
|
|
@@ -208,102 +164,32 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
208
164
|
}
|
|
209
165
|
|
|
210
166
|
if (unlikely(setup_state == 0)) {
|
|
211
|
-
|
|
167
|
+
log_error_and_throw(env, "encrypt", "setup() not called");
|
|
212
168
|
}
|
|
213
169
|
|
|
214
170
|
if (unlikely(info.Length() < 2)) {
|
|
215
|
-
|
|
171
|
+
log_error_and_throw(env, "encrypt", "Wrong number of arguments");
|
|
216
172
|
}
|
|
217
173
|
|
|
218
174
|
if (unlikely(!info[0].IsString() || !info[1].IsBuffer())) {
|
|
219
|
-
|
|
175
|
+
log_error_and_throw(env, "encrypt", "Wrong argument types");
|
|
220
176
|
}
|
|
221
177
|
|
|
222
|
-
// Determine size
|
|
223
|
-
size_t partition_utf8_byte_length;
|
|
224
178
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
225
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
226
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
227
|
-
return log_error_and_throw(env, "encrypt",
|
|
228
|
-
"Failed to get partition_id utf8 length");
|
|
229
|
-
}
|
|
230
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
231
|
-
return log_error_and_throw(env, "encrypt", "partition_id is empty");
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Allocate
|
|
235
179
|
char *partition_id_cobhan_buffer;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
240
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
241
|
-
debug_log_alloca("encrypt", "partition_id_cobhan_buffer",
|
|
242
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
243
|
-
partition_id_cobhan_buffer =
|
|
244
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
245
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
246
|
-
} else {
|
|
247
|
-
// Otherwise, allocate it on the heap
|
|
248
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
249
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
250
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
251
|
-
}
|
|
252
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
253
|
-
return log_error_and_throw(env, "encrypt",
|
|
254
|
-
"Failed to allocate partitionId cobhan buffer");
|
|
255
|
-
}
|
|
180
|
+
size_t partition_id_copied_bytes = 0;
|
|
181
|
+
NAPI_STRING_TO_CBUFFER(partition_id, partition_id_cobhan_buffer,
|
|
182
|
+
partition_id_copied_bytes, "encrypt");
|
|
256
183
|
|
|
257
|
-
// Copy
|
|
258
|
-
size_t partition_copied_bytes;
|
|
259
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
260
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
261
|
-
&partition_copied_bytes);
|
|
262
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
263
|
-
return log_error_and_throw(env, "encrypt",
|
|
264
|
-
"Failed to copy partitionId to cobhan buffer");
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Determine size
|
|
268
184
|
Napi::Buffer<unsigned char> input_napi_buffer =
|
|
269
185
|
info[1].As<Napi::Buffer<unsigned char>>();
|
|
270
|
-
size_t input_byte_length = input_napi_buffer.ByteLength();
|
|
271
|
-
if (unlikely(input_byte_length == 0)) {
|
|
272
|
-
return log_error_and_throw(env, "encrypt", "input is empty");
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Allocate
|
|
276
186
|
char *input_cobhan_buffer;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
281
|
-
calculate_cobhan_buffer_size_bytes(input_byte_length);
|
|
282
|
-
debug_log_alloca("encrypt", "input_cobhan_buffer",
|
|
283
|
-
input_cobhan_buffer_size_bytes);
|
|
284
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
285
|
-
configure_cbuffer(input_cobhan_buffer, input_byte_length);
|
|
286
|
-
} else {
|
|
287
|
-
// Otherwise, allocate it on the heap
|
|
288
|
-
input_buffer_unique_ptr =
|
|
289
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_byte_length);
|
|
290
|
-
input_cobhan_buffer = input_buffer_unique_ptr.get();
|
|
291
|
-
}
|
|
292
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
293
|
-
return log_error_and_throw(
|
|
294
|
-
env, "encrypt", "Failed to allocate cobhan buffer for input buffer");
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Copy
|
|
298
|
-
input_cobhan_buffer =
|
|
299
|
-
copy_nbuffer_to_cbuffer(env, input_napi_buffer, input_cobhan_buffer);
|
|
300
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
301
|
-
return log_error_and_throw(env, "encrypt",
|
|
302
|
-
"Failed to copy input buffer to cobhan buffer");
|
|
303
|
-
}
|
|
187
|
+
size_t input_copied_bytes = 0;
|
|
188
|
+
NAPI_BUFFER_TO_CBUFFER(input_napi_buffer, input_cobhan_buffer,
|
|
189
|
+
input_copied_bytes, "encrypt");
|
|
304
190
|
|
|
305
|
-
Napi::
|
|
306
|
-
encrypt_to_json(env,
|
|
191
|
+
Napi::String output =
|
|
192
|
+
encrypt_to_json(env, partition_id_copied_bytes, input_copied_bytes,
|
|
307
193
|
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
308
194
|
|
|
309
195
|
if (unlikely(verbose_flag)) {
|
|
@@ -313,7 +199,7 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
313
199
|
return output;
|
|
314
200
|
}
|
|
315
201
|
|
|
316
|
-
Napi::
|
|
202
|
+
Napi::String encrypt_string(const Napi::CallbackInfo &info) {
|
|
317
203
|
Napi::Env env = info.Env();
|
|
318
204
|
|
|
319
205
|
if (unlikely(verbose_flag)) {
|
|
@@ -321,109 +207,31 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
321
207
|
}
|
|
322
208
|
|
|
323
209
|
if (unlikely(setup_state == 0)) {
|
|
324
|
-
|
|
210
|
+
log_error_and_throw(env, "encrypt_string", "setup() not called");
|
|
325
211
|
}
|
|
326
212
|
|
|
327
213
|
if (unlikely(info.Length() < 2)) {
|
|
328
|
-
|
|
329
|
-
"Wrong number of arguments");
|
|
214
|
+
log_error_and_throw(env, "encrypt_string", "Wrong number of arguments");
|
|
330
215
|
}
|
|
331
216
|
|
|
332
217
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
333
|
-
|
|
218
|
+
log_error_and_throw(env, "encrypt_string", "Wrong argument types");
|
|
334
219
|
}
|
|
335
220
|
|
|
336
|
-
// Determine size
|
|
337
|
-
size_t partition_utf8_byte_length;
|
|
338
221
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
339
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
340
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
341
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
342
|
-
"Failed to get partition_id utf8 length");
|
|
343
|
-
}
|
|
344
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
345
|
-
return log_error_and_throw(env, "encrypt_string", "partition_id is empty");
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
// Allocate
|
|
349
222
|
char *partition_id_cobhan_buffer;
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
354
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
355
|
-
debug_log_alloca("encrypt_string", "partition_id_cobhan_buffer",
|
|
356
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
357
|
-
partition_id_cobhan_buffer =
|
|
358
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
359
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
360
|
-
} else {
|
|
361
|
-
// Otherwise, allocate it on the heap
|
|
362
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
363
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
364
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
365
|
-
}
|
|
366
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
367
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
368
|
-
"Failed to allocate partitionId cobhan buffer");
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Copy
|
|
372
|
-
size_t partition_copied_bytes;
|
|
373
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
374
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
375
|
-
&partition_copied_bytes);
|
|
376
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
377
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
378
|
-
"Failed to copy partitionId to cobhan buffer");
|
|
379
|
-
}
|
|
223
|
+
size_t partition_id_copied_bytes = 0;
|
|
224
|
+
NAPI_STRING_TO_CBUFFER(partition_id, partition_id_cobhan_buffer,
|
|
225
|
+
partition_id_copied_bytes, "encrypt_string");
|
|
380
226
|
|
|
381
|
-
// Determine size
|
|
382
|
-
size_t input_utf8_byte_length;
|
|
383
227
|
Napi::String input = info[1].As<Napi::String>();
|
|
384
|
-
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
385
|
-
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
386
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
387
|
-
"Failed to get input utf8 length");
|
|
388
|
-
}
|
|
389
|
-
if (unlikely(input_utf8_byte_length == 0)) {
|
|
390
|
-
return log_error_and_throw(env, "encrypt_string", "input is empty");
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Allocate
|
|
394
228
|
char *input_cobhan_buffer;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
399
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
400
|
-
debug_log_alloca("encrypt_string", "input_cobhan_buffer",
|
|
401
|
-
input_cobhan_buffer_size_bytes);
|
|
402
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
403
|
-
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
404
|
-
} else {
|
|
405
|
-
// Otherwise, allocate it on the heap
|
|
406
|
-
input_cobhan_buffer_unique_ptr =
|
|
407
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_utf8_byte_length);
|
|
408
|
-
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
409
|
-
}
|
|
410
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
411
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
412
|
-
"Failed to allocate input cobhan buffer");
|
|
413
|
-
}
|
|
229
|
+
size_t input_copied_bytes = 0;
|
|
230
|
+
NAPI_STRING_TO_CBUFFER(input, input_cobhan_buffer, input_copied_bytes,
|
|
231
|
+
"encrypt_string");
|
|
414
232
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
input_cobhan_buffer =
|
|
418
|
-
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
419
|
-
input_cobhan_buffer, &input_copied_bytes);
|
|
420
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
421
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
422
|
-
"Failed to copy input to cobhan buffer");
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
Napi::Value output =
|
|
426
|
-
encrypt_to_json(env, partition_copied_bytes, input_utf8_byte_length,
|
|
233
|
+
Napi::String output =
|
|
234
|
+
encrypt_to_json(env, partition_id_copied_bytes, input_copied_bytes,
|
|
427
235
|
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
428
236
|
|
|
429
237
|
if (unlikely(verbose_flag)) {
|
|
@@ -433,7 +241,7 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
433
241
|
return output;
|
|
434
242
|
}
|
|
435
243
|
|
|
436
|
-
Napi::
|
|
244
|
+
Napi::Buffer<unsigned char> decrypt(const Napi::CallbackInfo &info) {
|
|
437
245
|
Napi::Env env = info.Env();
|
|
438
246
|
|
|
439
247
|
if (unlikely(verbose_flag)) {
|
|
@@ -441,145 +249,47 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
441
249
|
}
|
|
442
250
|
|
|
443
251
|
if (unlikely(setup_state == 0)) {
|
|
444
|
-
|
|
252
|
+
log_error_and_throw(env, "decrypt", "setup() not called");
|
|
445
253
|
}
|
|
446
254
|
|
|
447
255
|
if (unlikely(info.Length() < 2)) {
|
|
448
|
-
|
|
256
|
+
log_error_and_throw(env, "decrypt", "Wrong number of arguments");
|
|
449
257
|
}
|
|
450
258
|
|
|
451
259
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
452
|
-
|
|
260
|
+
log_error_and_throw(env, "decrypt", "Wrong argument types");
|
|
453
261
|
}
|
|
454
262
|
|
|
455
|
-
// Determine size
|
|
456
|
-
size_t partition_utf8_byte_length, partition_copied_bytes;
|
|
457
263
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
458
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
459
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
460
|
-
return log_error_and_throw(env, "decrypt",
|
|
461
|
-
"Failed to get partition_id utf8 length");
|
|
462
|
-
}
|
|
463
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
464
|
-
return log_error_and_throw(env, "decrypt", "partition_id is empty");
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// Allocate
|
|
468
264
|
char *partition_id_cobhan_buffer;
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
473
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
474
|
-
debug_log_alloca("decrypt", "partition_id_cobhan_buffer",
|
|
475
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
476
|
-
partition_id_cobhan_buffer =
|
|
477
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
478
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
479
|
-
} else {
|
|
480
|
-
// Otherwise, allocate it on the heap
|
|
481
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
482
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
483
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
484
|
-
}
|
|
485
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
486
|
-
return log_error_and_throw(env, "decrypt",
|
|
487
|
-
"Failed to allocate partition_id cobhan buffer");
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Copy
|
|
491
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
492
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
493
|
-
&partition_copied_bytes);
|
|
494
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
495
|
-
return log_error_and_throw(env, "decrypt",
|
|
496
|
-
"Failed to copy partition_id to cobhan buffer");
|
|
497
|
-
}
|
|
265
|
+
size_t partition_id_copied_bytes = 0;
|
|
266
|
+
NAPI_STRING_TO_CBUFFER(partition_id, partition_id_cobhan_buffer,
|
|
267
|
+
partition_id_copied_bytes, "decrypt");
|
|
498
268
|
|
|
499
|
-
// Determine size
|
|
500
|
-
size_t input_utf8_byte_length;
|
|
501
269
|
Napi::String input = info[1].As<Napi::String>();
|
|
502
|
-
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
503
|
-
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
504
|
-
return log_error_and_throw(env, "decrypt",
|
|
505
|
-
"Failed to get input utf8 length");
|
|
506
|
-
}
|
|
507
|
-
if (unlikely(input_utf8_byte_length == 0)) {
|
|
508
|
-
return log_error_and_throw(env, "decrypt", "input is empty");
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
if (unlikely(verbose_flag)) {
|
|
512
|
-
debug_log("decrypt",
|
|
513
|
-
"input size " + std::to_string(input_utf8_byte_length));
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Allocate
|
|
517
270
|
char *input_cobhan_buffer;
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
522
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
523
|
-
debug_log_alloca("decrypt", "input_cobhan_buffer",
|
|
524
|
-
input_cobhan_buffer_size_bytes);
|
|
525
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
526
|
-
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
527
|
-
} else {
|
|
528
|
-
// Otherwise, allocate it on the heap
|
|
529
|
-
input_cobhan_buffer_unique_ptr =
|
|
530
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_utf8_byte_length);
|
|
531
|
-
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
532
|
-
}
|
|
533
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
534
|
-
return log_error_and_throw(env, "decrypt",
|
|
535
|
-
"Failed to allocate input cobhan buffer");
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// Copy
|
|
539
|
-
size_t input_copied_bytes;
|
|
540
|
-
input_cobhan_buffer =
|
|
541
|
-
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
542
|
-
input_cobhan_buffer, &input_copied_bytes);
|
|
543
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
544
|
-
return log_error_and_throw(env, "decrypt",
|
|
545
|
-
"Failed to copy input to cobhan buffer");
|
|
546
|
-
}
|
|
271
|
+
size_t input_copied_bytes = 0;
|
|
272
|
+
NAPI_STRING_TO_CBUFFER(input, input_cobhan_buffer, input_copied_bytes,
|
|
273
|
+
"decrypt");
|
|
547
274
|
|
|
548
275
|
char *output_cobhan_buffer;
|
|
549
|
-
|
|
550
|
-
if (input_utf8_byte_length < max_stack_alloc_size) {
|
|
551
|
-
// If the buffer is small enough, allocate it on the stack
|
|
552
|
-
size_t output_cobhan_buffer_size_bytes =
|
|
553
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
554
|
-
debug_log_alloca("decrypt", "output_cobhan_buffer",
|
|
555
|
-
output_cobhan_buffer_size_bytes);
|
|
556
|
-
output_cobhan_buffer = (char *)alloca(output_cobhan_buffer_size_bytes);
|
|
557
|
-
configure_cbuffer(output_cobhan_buffer, input_utf8_byte_length);
|
|
558
|
-
} else {
|
|
559
|
-
// Otherwise, allocate it on the heap
|
|
560
|
-
output_cobhan_buffer_unique_ptr =
|
|
561
|
-
heap_allocate_cbuffer("output_cobhan_buffer", input_utf8_byte_length);
|
|
562
|
-
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
563
|
-
}
|
|
564
|
-
if (unlikely(output_cobhan_buffer == nullptr)) {
|
|
565
|
-
return log_error_and_throw(env, "decrypt",
|
|
566
|
-
"Failed to allocate cobhan output buffer");
|
|
567
|
-
}
|
|
276
|
+
ALLOCATE_OUTPUT_CBUFFER(output_cobhan_buffer, input_copied_bytes, "decrypt");
|
|
568
277
|
|
|
569
278
|
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
570
|
-
if(!check_canary_ptr(partition_id_canary_ptr)) {
|
|
571
|
-
|
|
572
|
-
|
|
279
|
+
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
280
|
+
log_error_and_throw(
|
|
281
|
+
env, "encrypt_to_json",
|
|
282
|
+
"Failed initial canary check for partition_id_cobhan_buffer");
|
|
573
283
|
}
|
|
574
284
|
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
575
|
-
if(!check_canary_ptr(input_canary_ptr)) {
|
|
576
|
-
|
|
577
|
-
|
|
285
|
+
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
286
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
287
|
+
"Failed initial canary check for input_cobhan_buffer");
|
|
578
288
|
}
|
|
579
289
|
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
580
|
-
if(!check_canary_ptr(output_canary_ptr)) {
|
|
581
|
-
|
|
582
|
-
|
|
290
|
+
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
291
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
292
|
+
"Failed initial canary check for output_cobhan_buffer");
|
|
583
293
|
}
|
|
584
294
|
|
|
585
295
|
if (unlikely(verbose_flag)) {
|
|
@@ -595,25 +305,29 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
595
305
|
debug_log("decrypt", "Returned from asherah-cobhan DecryptFromJson");
|
|
596
306
|
}
|
|
597
307
|
|
|
598
|
-
if(!check_canary_ptr(partition_id_canary_ptr)) {
|
|
599
|
-
|
|
600
|
-
|
|
308
|
+
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
309
|
+
log_error_and_throw(
|
|
310
|
+
env, "encrypt_to_json",
|
|
311
|
+
"Failed post-call canary check for partition_id_cobhan_buffer");
|
|
601
312
|
}
|
|
602
|
-
if(!check_canary_ptr(input_canary_ptr)) {
|
|
603
|
-
|
|
604
|
-
|
|
313
|
+
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
314
|
+
log_error_and_throw(
|
|
315
|
+
env, "encrypt_to_json",
|
|
316
|
+
"Failed post-call canary check for input_cobhan_buffer");
|
|
605
317
|
}
|
|
606
|
-
if(!check_canary_ptr(output_canary_ptr)) {
|
|
607
|
-
|
|
608
|
-
|
|
318
|
+
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
319
|
+
log_error_and_throw(
|
|
320
|
+
env, "encrypt_to_json",
|
|
321
|
+
"Failed post-call canary check for output_cobhan_buffer");
|
|
609
322
|
}
|
|
610
323
|
|
|
611
324
|
if (unlikely(result < 0)) {
|
|
612
325
|
// TODO: Convert this to a proper error message
|
|
613
|
-
|
|
326
|
+
log_error_and_throw(env, "decrypt", std::to_string(result));
|
|
614
327
|
}
|
|
615
328
|
|
|
616
|
-
Napi::
|
|
329
|
+
Napi::Buffer<unsigned char> output =
|
|
330
|
+
cbuffer_to_nbuffer(env, output_cobhan_buffer);
|
|
617
331
|
|
|
618
332
|
if (unlikely(verbose_flag)) {
|
|
619
333
|
debug_log("decrypt", "finished");
|
|
@@ -622,7 +336,7 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
622
336
|
return output;
|
|
623
337
|
}
|
|
624
338
|
|
|
625
|
-
Napi::
|
|
339
|
+
Napi::String decrypt_string(const Napi::CallbackInfo &info) {
|
|
626
340
|
Napi::Env env = info.Env();
|
|
627
341
|
|
|
628
342
|
if (unlikely(verbose_flag)) {
|
|
@@ -630,142 +344,48 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
630
344
|
}
|
|
631
345
|
|
|
632
346
|
if (unlikely(setup_state == 0)) {
|
|
633
|
-
|
|
347
|
+
log_error_and_throw(env, "decrypt_string", "setup() not called");
|
|
634
348
|
}
|
|
635
349
|
|
|
636
350
|
if (unlikely(info.Length() < 2)) {
|
|
637
|
-
|
|
638
|
-
"Wrong number of arguments");
|
|
351
|
+
log_error_and_throw(env, "decrypt_string", "Wrong number of arguments");
|
|
639
352
|
}
|
|
640
353
|
|
|
641
354
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
642
|
-
|
|
355
|
+
log_error_and_throw(env, "decrypt_string", "Wrong argument types");
|
|
643
356
|
}
|
|
644
357
|
|
|
645
|
-
// Determine size
|
|
646
|
-
size_t partition_utf8_byte_length;
|
|
647
358
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
648
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
649
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
650
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
651
|
-
"Failed to get partition_id utf8 length");
|
|
652
|
-
}
|
|
653
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
654
|
-
return log_error_and_throw(env, "decrypt_string", "partition_id is empty");
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
// Allocate
|
|
658
359
|
char *partition_id_cobhan_buffer;
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
663
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
664
|
-
debug_log_alloca("decrypt_string", "partition_id_cobhan_buffer",
|
|
665
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
666
|
-
partition_id_cobhan_buffer =
|
|
667
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
668
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
669
|
-
} else {
|
|
670
|
-
// Otherwise, allocate it on the heap
|
|
671
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
672
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
673
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
674
|
-
}
|
|
675
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
676
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
677
|
-
"Failed to allocate partitionId cobhan buffer");
|
|
678
|
-
}
|
|
360
|
+
size_t partition_id_copied_bytes = 0;
|
|
361
|
+
NAPI_STRING_TO_CBUFFER(partition_id, partition_id_cobhan_buffer,
|
|
362
|
+
partition_id_copied_bytes, "decrypt_string");
|
|
679
363
|
|
|
680
|
-
// Copy
|
|
681
|
-
size_t partition_copied_bytes;
|
|
682
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
683
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
684
|
-
&partition_copied_bytes);
|
|
685
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
686
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
687
|
-
"Failed to copy partitionId to cobhan buffer");
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
// Determine size
|
|
691
|
-
size_t input_utf8_byte_length;
|
|
692
364
|
Napi::String input = info[1].As<Napi::String>();
|
|
693
|
-
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
694
|
-
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
695
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
696
|
-
"Failed to get input utf8 length");
|
|
697
|
-
}
|
|
698
|
-
if (unlikely(input_utf8_byte_length == 0)) {
|
|
699
|
-
return log_error_and_throw(env, "decrypt_string", "input is empty");
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
// Allocate
|
|
703
365
|
char *input_cobhan_buffer;
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
708
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
709
|
-
debug_log_alloca("decrypt_string", "input_cobhan_buffer",
|
|
710
|
-
input_cobhan_buffer_size_bytes);
|
|
711
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
712
|
-
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
713
|
-
} else {
|
|
714
|
-
// Otherwise, allocate it on the heap
|
|
715
|
-
input_cobhan_buffer_unique_ptr =
|
|
716
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_utf8_byte_length);
|
|
717
|
-
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
718
|
-
}
|
|
719
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
720
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
721
|
-
"Failed to allocate input cobhan buffer");
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
// Copy
|
|
725
|
-
size_t input_copied_bytes;
|
|
726
|
-
input_cobhan_buffer =
|
|
727
|
-
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
728
|
-
input_cobhan_buffer, &input_copied_bytes);
|
|
729
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
730
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
731
|
-
"Failed to copy input to cobhan buffer");
|
|
732
|
-
}
|
|
366
|
+
size_t input_copied_bytes = 0;
|
|
367
|
+
NAPI_STRING_TO_CBUFFER(input, input_cobhan_buffer, input_copied_bytes,
|
|
368
|
+
"decrypt_string");
|
|
733
369
|
|
|
734
370
|
char *output_cobhan_buffer;
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
// If the buffer is small enough, allocate it on the stack
|
|
738
|
-
size_t output_cobhan_buffer_size_bytes =
|
|
739
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
740
|
-
debug_log_alloca("decrypt_string", "output_cobhan_buffer",
|
|
741
|
-
output_cobhan_buffer_size_bytes);
|
|
742
|
-
output_cobhan_buffer = (char *)alloca(output_cobhan_buffer_size_bytes);
|
|
743
|
-
configure_cbuffer(output_cobhan_buffer, input_utf8_byte_length);
|
|
744
|
-
} else {
|
|
745
|
-
// Otherwise, allocate it on the heap
|
|
746
|
-
output_cobhan_buffer_unique_ptr =
|
|
747
|
-
heap_allocate_cbuffer("output_cobhan_buffer", input_utf8_byte_length);
|
|
748
|
-
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
749
|
-
}
|
|
750
|
-
if (unlikely(output_cobhan_buffer == nullptr)) {
|
|
751
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
752
|
-
"Failed to allocate cobhan output buffer");
|
|
753
|
-
}
|
|
371
|
+
ALLOCATE_OUTPUT_CBUFFER(output_cobhan_buffer, input_copied_bytes,
|
|
372
|
+
"decrypt_string");
|
|
754
373
|
|
|
755
374
|
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
756
|
-
if(!check_canary_ptr(partition_id_canary_ptr)) {
|
|
757
|
-
|
|
758
|
-
|
|
375
|
+
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
376
|
+
log_error_and_throw(
|
|
377
|
+
env, "encrypt_to_json",
|
|
378
|
+
"Failed initial canary check for partition_id_cobhan_buffer");
|
|
759
379
|
}
|
|
760
380
|
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
761
|
-
if(!check_canary_ptr(input_canary_ptr)) {
|
|
762
|
-
|
|
763
|
-
|
|
381
|
+
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
382
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
383
|
+
"Failed initial canary check for input_cobhan_buffer");
|
|
764
384
|
}
|
|
765
385
|
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
766
|
-
if(!check_canary_ptr(output_canary_ptr)) {
|
|
767
|
-
|
|
768
|
-
|
|
386
|
+
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
387
|
+
log_error_and_throw(env, "encrypt_to_json",
|
|
388
|
+
"Failed initial canary check for output_cobhan_buffer");
|
|
769
389
|
}
|
|
770
390
|
|
|
771
391
|
if (unlikely(verbose_flag)) {
|
|
@@ -781,25 +401,28 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
781
401
|
debug_log("decrypt_string", "Returned from asherah-cobhan DecryptFromJson");
|
|
782
402
|
}
|
|
783
403
|
|
|
784
|
-
if(!check_canary_ptr(partition_id_canary_ptr)) {
|
|
785
|
-
|
|
786
|
-
|
|
404
|
+
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
405
|
+
log_error_and_throw(
|
|
406
|
+
env, "encrypt_to_json",
|
|
407
|
+
"Failed post-call canary check for partition_id_cobhan_buffer");
|
|
787
408
|
}
|
|
788
|
-
if(!check_canary_ptr(input_canary_ptr)) {
|
|
789
|
-
|
|
790
|
-
|
|
409
|
+
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
410
|
+
log_error_and_throw(
|
|
411
|
+
env, "encrypt_to_json",
|
|
412
|
+
"Failed post-call canary check for input_cobhan_buffer");
|
|
791
413
|
}
|
|
792
|
-
if(!check_canary_ptr(output_canary_ptr)) {
|
|
793
|
-
|
|
794
|
-
|
|
414
|
+
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
415
|
+
log_error_and_throw(
|
|
416
|
+
env, "encrypt_to_json",
|
|
417
|
+
"Failed post-call canary check for output_cobhan_buffer");
|
|
795
418
|
}
|
|
796
419
|
|
|
797
420
|
if (unlikely(result < 0)) {
|
|
798
421
|
// TODO: Convert this to a proper error message
|
|
799
|
-
|
|
422
|
+
log_error_and_throw(env, "decrypt_string", std::to_string(result));
|
|
800
423
|
}
|
|
801
424
|
|
|
802
|
-
Napi::
|
|
425
|
+
Napi::String output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
803
426
|
|
|
804
427
|
if (unlikely(verbose_flag)) {
|
|
805
428
|
debug_log("decrypt_string", "finished");
|
|
@@ -837,7 +460,6 @@ void set_max_stack_alloc_item_size(const Napi::CallbackInfo &info) {
|
|
|
837
460
|
if (unlikely(info.Length() < 1)) {
|
|
838
461
|
log_error_and_throw(env, "set_max_stack_alloc_item_size",
|
|
839
462
|
"Wrong number of arguments");
|
|
840
|
-
return;
|
|
841
463
|
}
|
|
842
464
|
|
|
843
465
|
Napi::Number item_size = info[0].ToNumber();
|
|
@@ -855,7 +477,6 @@ void set_safety_padding_overhead(const Napi::CallbackInfo &info) {
|
|
|
855
477
|
if (unlikely(info.Length() < 1)) {
|
|
856
478
|
log_error_and_throw(env, "set_safety_padding_overhead",
|
|
857
479
|
"Wrong number of arguments");
|
|
858
|
-
return;
|
|
859
480
|
}
|
|
860
481
|
|
|
861
482
|
Napi::Number safety_padding_number = info[0].ToNumber();
|
|
@@ -77,17 +77,16 @@ cbuffer_byte_length(char *cobhan_buffer) {
|
|
|
77
77
|
return *((int32_t *)cobhan_buffer);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
__attribute__((always_inline)) inline
|
|
80
|
+
__attribute__((always_inline)) inline void
|
|
81
81
|
log_error_and_throw(Napi::Env &env, const char *function_name,
|
|
82
82
|
std::string error_msg) {
|
|
83
83
|
error_log(function_name, error_msg);
|
|
84
84
|
Napi::Error::New(env, function_name + (": " + error_msg))
|
|
85
85
|
.ThrowAsJavaScriptException();
|
|
86
|
-
return env.Null();
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
__attribute__((always_inline)) inline size_t
|
|
90
|
-
|
|
89
|
+
calculate_cobhan_buffer_allocation_size(size_t data_len_bytes) {
|
|
91
90
|
return data_len_bytes + cobhan_header_size_bytes +
|
|
92
91
|
1 + // Add one for possible NULL delimiter due to Node string functions
|
|
93
92
|
canary_size // Add space for canary value
|
|
@@ -116,7 +115,8 @@ estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
|
116
115
|
return asherah_output_size_bytes;
|
|
117
116
|
}
|
|
118
117
|
|
|
119
|
-
__attribute__((always_inline)) inline char
|
|
118
|
+
__attribute__((always_inline)) inline char *
|
|
119
|
+
cbuffer_data_ptr(char *cobhan_buffer) {
|
|
120
120
|
return cobhan_buffer + cobhan_header_size_bytes;
|
|
121
121
|
}
|
|
122
122
|
|
|
@@ -144,10 +144,10 @@ __attribute__((always_inline)) inline void configure_cbuffer(char *buffer,
|
|
|
144
144
|
*((int32_t *)(data_ptr + length + 1)) = 0;
|
|
145
145
|
|
|
146
146
|
if (verbose_flag) {
|
|
147
|
-
debug_log(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
debug_log("configure_cbuffer",
|
|
148
|
+
"Writing second canary at " +
|
|
149
|
+
std::to_string(
|
|
150
|
+
(intptr_t)(data_ptr + length + 1 + sizeof(int32_t))));
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// Second canary value is a int32_t 0xdeadbeef
|
|
@@ -160,8 +160,7 @@ get_canary_ptr(char *cobhan_buffer) {
|
|
|
160
160
|
return cbuffer_data_ptr(cobhan_buffer) + cobhan_buffer_size_bytes + 1;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
__attribute__((always_inline)) inline bool
|
|
164
|
-
check_canary_ptr(char *canary_ptr) {
|
|
163
|
+
__attribute__((always_inline)) inline bool check_canary_ptr(char *canary_ptr) {
|
|
165
164
|
int32_t zero_value = *((int32_t *)(canary_ptr));
|
|
166
165
|
if (zero_value != 0) {
|
|
167
166
|
std::string error_msg =
|
|
@@ -182,20 +181,21 @@ check_canary_ptr(char *canary_ptr) {
|
|
|
182
181
|
|
|
183
182
|
__attribute__((always_inline)) inline std::unique_ptr<char[]>
|
|
184
183
|
heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
185
|
-
size_t
|
|
186
|
-
|
|
184
|
+
size_t cobhan_buffer_allocation_size =
|
|
185
|
+
calculate_cobhan_buffer_allocation_size(size_bytes);
|
|
187
186
|
if (unlikely(verbose_flag)) {
|
|
188
187
|
std::string log_msg =
|
|
189
188
|
"heap_allocate_cbuffer(" + std::to_string(size_bytes) +
|
|
190
|
-
") (heap)
|
|
191
|
-
std::to_string(
|
|
189
|
+
") (heap) cobhan_buffer_allocation_size: " +
|
|
190
|
+
std::to_string(cobhan_buffer_allocation_size) + " for " + variable_name;
|
|
192
191
|
debug_log("allocate_cbuffer", log_msg);
|
|
193
192
|
}
|
|
194
193
|
|
|
195
|
-
char *cobhan_buffer = new (std::nothrow) char[
|
|
194
|
+
char *cobhan_buffer = new (std::nothrow) char[cobhan_buffer_allocation_size];
|
|
196
195
|
if (unlikely(cobhan_buffer == nullptr)) {
|
|
197
|
-
std::string error_msg =
|
|
198
|
-
|
|
196
|
+
std::string error_msg = "new[" +
|
|
197
|
+
std::to_string(cobhan_buffer_allocation_size) +
|
|
198
|
+
"] returned null";
|
|
199
199
|
error_log("allocate_cbuffer", error_msg);
|
|
200
200
|
return nullptr;
|
|
201
201
|
}
|
|
@@ -204,25 +204,24 @@ heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
|
204
204
|
return cobhan_buffer_unique_ptr;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
__attribute__((always_inline)) inline Napi::
|
|
207
|
+
__attribute__((always_inline)) inline Napi::String
|
|
208
208
|
cbuffer_to_nstring(Napi::Env &env, char *cobhan_buffer) {
|
|
209
209
|
napi_value output;
|
|
210
210
|
|
|
211
211
|
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
212
212
|
if (cobhan_buffer_size_bytes <= 0) {
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
log_error_and_throw(env, "cbuffer_to_nstring",
|
|
214
|
+
"Invalid cobhan buffer byte length");
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
// Using C function because it allows length delimited input
|
|
218
218
|
napi_status status = napi_create_string_utf8(
|
|
219
|
-
env, (
|
|
220
|
-
cobhan_buffer_size_bytes, &output);
|
|
219
|
+
env, cbuffer_data_ptr(cobhan_buffer), cobhan_buffer_size_bytes, &output);
|
|
221
220
|
|
|
222
221
|
if (unlikely(status != napi_ok)) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
log_error_and_throw(env, "cbuffer_to_nstring",
|
|
223
|
+
"napi_create_string_utf8 failed: " +
|
|
224
|
+
napi_status_to_string(status));
|
|
226
225
|
}
|
|
227
226
|
|
|
228
227
|
return Napi::String(env, output);
|
|
@@ -265,12 +264,10 @@ copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
|
265
264
|
if (unlikely(verbose_flag)) {
|
|
266
265
|
debug_log("copy_nstring_to_cbuffer",
|
|
267
266
|
"Copying " + std::to_string(str_utf8_byte_length) + " bytes to " +
|
|
268
|
-
std::to_string(
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
cobhan_header_size_bytes +
|
|
273
|
-
str_utf8_byte_length)));
|
|
267
|
+
std::to_string((intptr_t)cbuffer_data_ptr(cobhan_buffer)) +
|
|
268
|
+
"-" +
|
|
269
|
+
std::to_string((intptr_t)(cbuffer_data_ptr(cobhan_buffer) +
|
|
270
|
+
str_utf8_byte_length)));
|
|
274
271
|
}
|
|
275
272
|
|
|
276
273
|
napi_status status;
|
|
@@ -278,8 +275,7 @@ copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
|
278
275
|
// NOTE: This implementation relies on the additional byte that is reserved
|
|
279
276
|
// upon allocation for a NULL delimiter as methods like
|
|
280
277
|
// napi_get_value_string_utf8 append a NULL delimiter
|
|
281
|
-
status = napi_get_value_string_utf8(env, str,
|
|
282
|
-
cobhan_buffer + cobhan_header_size_bytes,
|
|
278
|
+
status = napi_get_value_string_utf8(env, str, cbuffer_data_ptr(cobhan_buffer),
|
|
283
279
|
str_utf8_byte_length + 1, &copied_bytes);
|
|
284
280
|
if (unlikely(status != napi_ok)) {
|
|
285
281
|
log_error_and_throw(env, "copy_nstring_to_cbuffer",
|
|
@@ -321,18 +317,17 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
321
317
|
"Buffer too large for cobhan buffer");
|
|
322
318
|
return nullptr;
|
|
323
319
|
}
|
|
324
|
-
memcpy(cobhan_buffer
|
|
325
|
-
nbuffer_byte_length);
|
|
320
|
+
memcpy(cbuffer_data_ptr(cobhan_buffer), nbuffer.Data(), nbuffer_byte_length);
|
|
326
321
|
configure_cbuffer(cobhan_buffer, nbuffer_byte_length);
|
|
327
322
|
return cobhan_buffer;
|
|
328
323
|
}
|
|
329
324
|
|
|
330
|
-
__attribute__((always_inline)) inline Napi::
|
|
325
|
+
__attribute__((always_inline)) inline Napi::Buffer<unsigned char>
|
|
331
326
|
cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
332
327
|
int32_t cobhan_buffer_byte_length = cbuffer_byte_length(cobhan_buffer);
|
|
333
328
|
if (unlikely(cobhan_buffer_byte_length <= 0)) {
|
|
334
|
-
|
|
335
|
-
|
|
329
|
+
log_error_and_throw(env, "cbuffer_to_nbuffer",
|
|
330
|
+
"Invalid cobhan buffer byte length");
|
|
336
331
|
}
|
|
337
332
|
|
|
338
333
|
if (unlikely(verbose_flag)) {
|
|
@@ -346,8 +341,8 @@ cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
|
346
341
|
"Invalid cobhan buffer byte length");
|
|
347
342
|
}
|
|
348
343
|
|
|
349
|
-
Napi::Buffer nbuffer = Napi::Buffer<unsigned char>::Copy(
|
|
350
|
-
env, (
|
|
344
|
+
Napi::Buffer<unsigned char> nbuffer = Napi::Buffer<unsigned char>::Copy(
|
|
345
|
+
env, (const unsigned char *)cbuffer_data_ptr(cobhan_buffer),
|
|
351
346
|
cobhan_buffer_byte_length);
|
|
352
347
|
|
|
353
348
|
if (unlikely(verbose_flag)) {
|
|
@@ -358,4 +353,115 @@ cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
|
358
353
|
return nbuffer;
|
|
359
354
|
}
|
|
360
355
|
|
|
356
|
+
// These are macros due to the use of alloca()
|
|
357
|
+
|
|
358
|
+
#define NAPI_STRING_TO_CBUFFER(napi_string, cobhan_buffer, bytes_copied, \
|
|
359
|
+
function_name) \
|
|
360
|
+
std::unique_ptr<char[]> napi_string##_cobhan_buffer_unique_ptr; \
|
|
361
|
+
do { \
|
|
362
|
+
/* Determine size */ \
|
|
363
|
+
size_t napi_string##_utf8_byte_length = \
|
|
364
|
+
nstring_utf8_byte_length(env, napi_string); \
|
|
365
|
+
if (unlikely(napi_string##_utf8_byte_length == (size_t)(-1))) { \
|
|
366
|
+
log_error_and_throw(env, function_name, \
|
|
367
|
+
"Failed to get " #napi_string " utf8 length"); \
|
|
368
|
+
} \
|
|
369
|
+
if (unlikely(napi_string##_utf8_byte_length == 0)) { \
|
|
370
|
+
log_error_and_throw(env, function_name, #napi_string " is empty"); \
|
|
371
|
+
} \
|
|
372
|
+
/* Allocate */ \
|
|
373
|
+
if (napi_string##_utf8_byte_length < max_stack_alloc_size) { \
|
|
374
|
+
/* If the buffer is small enough, allocate it on the stack */ \
|
|
375
|
+
size_t napi_string##_cobhan_buffer_allocation_size = \
|
|
376
|
+
calculate_cobhan_buffer_allocation_size( \
|
|
377
|
+
napi_string##_utf8_byte_length); \
|
|
378
|
+
debug_log_alloca(function_name, #napi_string "_cobhan_buffer", \
|
|
379
|
+
napi_string##_cobhan_buffer_allocation_size); \
|
|
380
|
+
cobhan_buffer = \
|
|
381
|
+
(char *)alloca(napi_string##_cobhan_buffer_allocation_size); \
|
|
382
|
+
configure_cbuffer(cobhan_buffer, napi_string##_utf8_byte_length); \
|
|
383
|
+
} else { \
|
|
384
|
+
/* Otherwise, allocate it on the heap */ \
|
|
385
|
+
napi_string##_cobhan_buffer_unique_ptr = heap_allocate_cbuffer( \
|
|
386
|
+
#cobhan_buffer, napi_string##_utf8_byte_length); \
|
|
387
|
+
cobhan_buffer = napi_string##_cobhan_buffer_unique_ptr.get(); \
|
|
388
|
+
} \
|
|
389
|
+
if (unlikely(cobhan_buffer == nullptr)) { \
|
|
390
|
+
log_error_and_throw(env, function_name, \
|
|
391
|
+
"Failed to allocate " #napi_string \
|
|
392
|
+
" cobhan buffer"); \
|
|
393
|
+
} \
|
|
394
|
+
/* Copy */ \
|
|
395
|
+
cobhan_buffer = copy_nstring_to_cbuffer(env, napi_string, \
|
|
396
|
+
napi_string##_utf8_byte_length, \
|
|
397
|
+
cobhan_buffer, &bytes_copied); \
|
|
398
|
+
if (unlikely(cobhan_buffer == nullptr)) { \
|
|
399
|
+
log_error_and_throw(env, function_name, \
|
|
400
|
+
"Failed to copy " #napi_string " to cobhan buffer"); \
|
|
401
|
+
} \
|
|
402
|
+
} while (0);
|
|
403
|
+
|
|
404
|
+
#define NAPI_BUFFER_TO_CBUFFER(napi_buffer, cobhan_buffer, bytes_copied, \
|
|
405
|
+
function_name) \
|
|
406
|
+
std::unique_ptr<char[]> napi_buffer##_unique_ptr; \
|
|
407
|
+
do { \
|
|
408
|
+
/* Determine size */ \
|
|
409
|
+
size_t napi_buffer##_byte_length = napi_buffer.ByteLength(); \
|
|
410
|
+
if (unlikely(napi_buffer##_byte_length == 0)) { \
|
|
411
|
+
log_error_and_throw(env, function_name, #napi_buffer " is empty"); \
|
|
412
|
+
} \
|
|
413
|
+
/* Allocate */ \
|
|
414
|
+
if (napi_buffer##_byte_length < max_stack_alloc_size) { \
|
|
415
|
+
/* If the buffer is small enough, allocate it on the stack */ \
|
|
416
|
+
size_t napi_buffer##_cobhan_buffer_allocation_size = \
|
|
417
|
+
calculate_cobhan_buffer_allocation_size(napi_buffer##_byte_length); \
|
|
418
|
+
debug_log_alloca(function_name, #cobhan_buffer, \
|
|
419
|
+
napi_buffer##_cobhan_buffer_allocation_size); \
|
|
420
|
+
cobhan_buffer = \
|
|
421
|
+
(char *)alloca(napi_buffer##_cobhan_buffer_allocation_size); \
|
|
422
|
+
configure_cbuffer(cobhan_buffer, napi_buffer##_byte_length); \
|
|
423
|
+
} else { \
|
|
424
|
+
/* Otherwise, allocate it on the heap */ \
|
|
425
|
+
napi_buffer##_unique_ptr = \
|
|
426
|
+
heap_allocate_cbuffer(#cobhan_buffer, napi_buffer##_byte_length); \
|
|
427
|
+
cobhan_buffer = napi_buffer##_unique_ptr.get(); \
|
|
428
|
+
} \
|
|
429
|
+
if (unlikely(cobhan_buffer == nullptr)) { \
|
|
430
|
+
log_error_and_throw( \
|
|
431
|
+
env, function_name, \
|
|
432
|
+
"Failed to allocate cobhan buffer for " #napi_buffer); \
|
|
433
|
+
} \
|
|
434
|
+
/* Copy */ \
|
|
435
|
+
cobhan_buffer = copy_nbuffer_to_cbuffer(env, napi_buffer, cobhan_buffer); \
|
|
436
|
+
if (unlikely(cobhan_buffer == nullptr)) { \
|
|
437
|
+
log_error_and_throw(env, function_name, \
|
|
438
|
+
"Failed to copy " #napi_buffer " to cobhan buffer"); \
|
|
439
|
+
} \
|
|
440
|
+
bytes_copied = napi_buffer##_byte_length; \
|
|
441
|
+
} while (0);
|
|
442
|
+
|
|
443
|
+
#define ALLOCATE_OUTPUT_CBUFFER(cobhan_buffer, buffer_size, function_name) \
|
|
444
|
+
std::unique_ptr<char[]> cobhan_buffer##_unique_ptr; \
|
|
445
|
+
do { \
|
|
446
|
+
if (buffer_size < max_stack_alloc_size) { \
|
|
447
|
+
/* If the buffer is small enough, allocate it on the stack */ \
|
|
448
|
+
size_t cobhan_buffer##_cobhan_buffer_allocation_size = \
|
|
449
|
+
calculate_cobhan_buffer_allocation_size(buffer_size); \
|
|
450
|
+
debug_log_alloca(function_name, #cobhan_buffer, \
|
|
451
|
+
cobhan_buffer##_cobhan_buffer_allocation_size); \
|
|
452
|
+
cobhan_buffer = \
|
|
453
|
+
(char *)alloca(cobhan_buffer##_cobhan_buffer_allocation_size); \
|
|
454
|
+
configure_cbuffer(cobhan_buffer, buffer_size); \
|
|
455
|
+
} else { \
|
|
456
|
+
/* Otherwise, allocate it on the heap */ \
|
|
457
|
+
cobhan_buffer##_unique_ptr = \
|
|
458
|
+
heap_allocate_cbuffer(#cobhan_buffer, buffer_size); \
|
|
459
|
+
cobhan_buffer = output_cobhan_buffer_unique_ptr.get(); \
|
|
460
|
+
} \
|
|
461
|
+
if (unlikely(cobhan_buffer == nullptr)) { \
|
|
462
|
+
log_error_and_throw(env, function_name, \
|
|
463
|
+
"Failed to allocate " #cobhan_buffer); \
|
|
464
|
+
} \
|
|
465
|
+
} while (0);
|
|
466
|
+
|
|
361
467
|
#endif
|