asherah 1.3.18 → 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 +168 -460
- package/src/cobhan_napi_interop.cc +10 -2
- package/src/cobhan_napi_interop.h +219 -36
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,13 +36,12 @@ 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>();
|
|
45
42
|
Napi::String service_name = config_json.Get("ServiceName").As<Napi::String>();
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
*est_intermediate_key_overhead_ptr =
|
|
48
45
|
product_id.Utf8Value().length() + service_name.Utf8Value().length();
|
|
49
46
|
|
|
50
47
|
Napi::Value verbose = config_json.Get("Verbose");
|
|
@@ -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,24 +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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
101
|
+
ALLOCATE_OUTPUT_CBUFFER(output_cobhan_buffer, asherah_output_size_bytes,
|
|
102
|
+
"encrypt_to_json");
|
|
103
|
+
|
|
104
|
+
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
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");
|
|
109
|
+
}
|
|
110
|
+
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
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");
|
|
146
114
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
115
|
+
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
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");
|
|
150
119
|
}
|
|
151
120
|
|
|
152
121
|
if (unlikely(verbose_flag)) {
|
|
@@ -162,16 +131,32 @@ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
162
131
|
debug_log("encrypt_to_json", "Returning from asherah-cobhan EncryptToJson");
|
|
163
132
|
}
|
|
164
133
|
|
|
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");
|
|
138
|
+
}
|
|
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");
|
|
143
|
+
}
|
|
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");
|
|
148
|
+
}
|
|
149
|
+
|
|
165
150
|
if (unlikely(result < 0)) {
|
|
166
151
|
// TODO: Convert this to a proper error message
|
|
167
|
-
|
|
152
|
+
log_error_and_throw(env, "encrypt_to_json", std::to_string(result));
|
|
168
153
|
}
|
|
169
154
|
|
|
170
|
-
Napi::
|
|
155
|
+
Napi::String output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
171
156
|
return output;
|
|
172
157
|
}
|
|
173
158
|
|
|
174
|
-
Napi::
|
|
159
|
+
Napi::String encrypt(const Napi::CallbackInfo &info) {
|
|
175
160
|
Napi::Env env = info.Env();
|
|
176
161
|
|
|
177
162
|
if (unlikely(verbose_flag)) {
|
|
@@ -179,102 +164,32 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
179
164
|
}
|
|
180
165
|
|
|
181
166
|
if (unlikely(setup_state == 0)) {
|
|
182
|
-
|
|
167
|
+
log_error_and_throw(env, "encrypt", "setup() not called");
|
|
183
168
|
}
|
|
184
169
|
|
|
185
170
|
if (unlikely(info.Length() < 2)) {
|
|
186
|
-
|
|
171
|
+
log_error_and_throw(env, "encrypt", "Wrong number of arguments");
|
|
187
172
|
}
|
|
188
173
|
|
|
189
174
|
if (unlikely(!info[0].IsString() || !info[1].IsBuffer())) {
|
|
190
|
-
|
|
175
|
+
log_error_and_throw(env, "encrypt", "Wrong argument types");
|
|
191
176
|
}
|
|
192
177
|
|
|
193
|
-
// Determine size
|
|
194
|
-
size_t partition_utf8_byte_length;
|
|
195
178
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
196
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
197
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
198
|
-
return log_error_and_throw(env, "encrypt",
|
|
199
|
-
"Failed to get partition_id utf8 length");
|
|
200
|
-
}
|
|
201
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
202
|
-
return log_error_and_throw(env, "encrypt", "partition_id is empty");
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Allocate
|
|
206
179
|
char *partition_id_cobhan_buffer;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
211
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
212
|
-
debug_log_alloca("encrypt", "partition_id_cobhan_buffer",
|
|
213
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
214
|
-
partition_id_cobhan_buffer =
|
|
215
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
216
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
217
|
-
} else {
|
|
218
|
-
// Otherwise, allocate it on the heap
|
|
219
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
220
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
221
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
222
|
-
}
|
|
223
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
224
|
-
return log_error_and_throw(env, "encrypt",
|
|
225
|
-
"Failed to allocate partitionId cobhan buffer");
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Copy
|
|
229
|
-
size_t partition_copied_bytes;
|
|
230
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
231
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
232
|
-
&partition_copied_bytes);
|
|
233
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
234
|
-
return log_error_and_throw(env, "encrypt",
|
|
235
|
-
"Failed to copy partitionId to cobhan buffer");
|
|
236
|
-
}
|
|
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");
|
|
237
183
|
|
|
238
|
-
// Determine size
|
|
239
184
|
Napi::Buffer<unsigned char> input_napi_buffer =
|
|
240
185
|
info[1].As<Napi::Buffer<unsigned char>>();
|
|
241
|
-
size_t input_byte_length = input_napi_buffer.ByteLength();
|
|
242
|
-
if (unlikely(input_byte_length == 0)) {
|
|
243
|
-
return log_error_and_throw(env, "encrypt", "input is empty");
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Allocate
|
|
247
186
|
char *input_cobhan_buffer;
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
252
|
-
calculate_cobhan_buffer_size_bytes(input_byte_length);
|
|
253
|
-
debug_log_alloca("encrypt", "input_cobhan_buffer",
|
|
254
|
-
input_cobhan_buffer_size_bytes);
|
|
255
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
256
|
-
configure_cbuffer(input_cobhan_buffer, input_byte_length);
|
|
257
|
-
} else {
|
|
258
|
-
// Otherwise, allocate it on the heap
|
|
259
|
-
input_buffer_unique_ptr =
|
|
260
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_byte_length);
|
|
261
|
-
input_cobhan_buffer = input_buffer_unique_ptr.get();
|
|
262
|
-
}
|
|
263
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
264
|
-
return log_error_and_throw(
|
|
265
|
-
env, "encrypt", "Failed to allocate cobhan buffer for input buffer");
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Copy
|
|
269
|
-
input_cobhan_buffer =
|
|
270
|
-
copy_nbuffer_to_cbuffer(env, input_napi_buffer, input_cobhan_buffer);
|
|
271
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
272
|
-
return log_error_and_throw(env, "encrypt",
|
|
273
|
-
"Failed to copy input buffer to cobhan buffer");
|
|
274
|
-
}
|
|
187
|
+
size_t input_copied_bytes = 0;
|
|
188
|
+
NAPI_BUFFER_TO_CBUFFER(input_napi_buffer, input_cobhan_buffer,
|
|
189
|
+
input_copied_bytes, "encrypt");
|
|
275
190
|
|
|
276
|
-
Napi::
|
|
277
|
-
encrypt_to_json(env,
|
|
191
|
+
Napi::String output =
|
|
192
|
+
encrypt_to_json(env, partition_id_copied_bytes, input_copied_bytes,
|
|
278
193
|
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
279
194
|
|
|
280
195
|
if (unlikely(verbose_flag)) {
|
|
@@ -284,7 +199,7 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
284
199
|
return output;
|
|
285
200
|
}
|
|
286
201
|
|
|
287
|
-
Napi::
|
|
202
|
+
Napi::String encrypt_string(const Napi::CallbackInfo &info) {
|
|
288
203
|
Napi::Env env = info.Env();
|
|
289
204
|
|
|
290
205
|
if (unlikely(verbose_flag)) {
|
|
@@ -292,109 +207,31 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
292
207
|
}
|
|
293
208
|
|
|
294
209
|
if (unlikely(setup_state == 0)) {
|
|
295
|
-
|
|
210
|
+
log_error_and_throw(env, "encrypt_string", "setup() not called");
|
|
296
211
|
}
|
|
297
212
|
|
|
298
213
|
if (unlikely(info.Length() < 2)) {
|
|
299
|
-
|
|
300
|
-
"Wrong number of arguments");
|
|
214
|
+
log_error_and_throw(env, "encrypt_string", "Wrong number of arguments");
|
|
301
215
|
}
|
|
302
216
|
|
|
303
217
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
304
|
-
|
|
218
|
+
log_error_and_throw(env, "encrypt_string", "Wrong argument types");
|
|
305
219
|
}
|
|
306
220
|
|
|
307
|
-
// Determine size
|
|
308
|
-
size_t partition_utf8_byte_length;
|
|
309
221
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
310
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
311
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
312
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
313
|
-
"Failed to get partition_id utf8 length");
|
|
314
|
-
}
|
|
315
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
316
|
-
return log_error_and_throw(env, "encrypt_string", "partition_id is empty");
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Allocate
|
|
320
222
|
char *partition_id_cobhan_buffer;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
325
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
326
|
-
debug_log_alloca("encrypt_string", "partition_id_cobhan_buffer",
|
|
327
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
328
|
-
partition_id_cobhan_buffer =
|
|
329
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
330
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
331
|
-
} else {
|
|
332
|
-
// Otherwise, allocate it on the heap
|
|
333
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
334
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
335
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
336
|
-
}
|
|
337
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
338
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
339
|
-
"Failed to allocate partitionId cobhan buffer");
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Copy
|
|
343
|
-
size_t partition_copied_bytes;
|
|
344
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
345
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
346
|
-
&partition_copied_bytes);
|
|
347
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
348
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
349
|
-
"Failed to copy partitionId to cobhan buffer");
|
|
350
|
-
}
|
|
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");
|
|
351
226
|
|
|
352
|
-
// Determine size
|
|
353
|
-
size_t input_utf8_byte_length;
|
|
354
227
|
Napi::String input = info[1].As<Napi::String>();
|
|
355
|
-
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
356
|
-
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
357
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
358
|
-
"Failed to get input utf8 length");
|
|
359
|
-
}
|
|
360
|
-
if (unlikely(input_utf8_byte_length == 0)) {
|
|
361
|
-
return log_error_and_throw(env, "encrypt_string", "input is empty");
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// Allocate
|
|
365
228
|
char *input_cobhan_buffer;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
370
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
371
|
-
debug_log_alloca("encrypt_string", "input_cobhan_buffer",
|
|
372
|
-
input_cobhan_buffer_size_bytes);
|
|
373
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
374
|
-
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
375
|
-
} else {
|
|
376
|
-
// Otherwise, allocate it on the heap
|
|
377
|
-
input_cobhan_buffer_unique_ptr =
|
|
378
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_utf8_byte_length);
|
|
379
|
-
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
380
|
-
}
|
|
381
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
382
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
383
|
-
"Failed to allocate input cobhan buffer");
|
|
384
|
-
}
|
|
229
|
+
size_t input_copied_bytes = 0;
|
|
230
|
+
NAPI_STRING_TO_CBUFFER(input, input_cobhan_buffer, input_copied_bytes,
|
|
231
|
+
"encrypt_string");
|
|
385
232
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
input_cobhan_buffer =
|
|
389
|
-
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
390
|
-
input_cobhan_buffer, &input_copied_bytes);
|
|
391
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
392
|
-
return log_error_and_throw(env, "encrypt_string",
|
|
393
|
-
"Failed to copy input to cobhan buffer");
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
Napi::Value output =
|
|
397
|
-
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,
|
|
398
235
|
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
399
236
|
|
|
400
237
|
if (unlikely(verbose_flag)) {
|
|
@@ -404,7 +241,7 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
404
241
|
return output;
|
|
405
242
|
}
|
|
406
243
|
|
|
407
|
-
Napi::
|
|
244
|
+
Napi::Buffer<unsigned char> decrypt(const Napi::CallbackInfo &info) {
|
|
408
245
|
Napi::Env env = info.Env();
|
|
409
246
|
|
|
410
247
|
if (unlikely(verbose_flag)) {
|
|
@@ -412,129 +249,47 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
412
249
|
}
|
|
413
250
|
|
|
414
251
|
if (unlikely(setup_state == 0)) {
|
|
415
|
-
|
|
252
|
+
log_error_and_throw(env, "decrypt", "setup() not called");
|
|
416
253
|
}
|
|
417
254
|
|
|
418
255
|
if (unlikely(info.Length() < 2)) {
|
|
419
|
-
|
|
256
|
+
log_error_and_throw(env, "decrypt", "Wrong number of arguments");
|
|
420
257
|
}
|
|
421
258
|
|
|
422
259
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
423
|
-
|
|
260
|
+
log_error_and_throw(env, "decrypt", "Wrong argument types");
|
|
424
261
|
}
|
|
425
262
|
|
|
426
|
-
// Determine size
|
|
427
|
-
size_t partition_utf8_byte_length, partition_copied_bytes;
|
|
428
263
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
429
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
430
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
431
|
-
return log_error_and_throw(env, "decrypt",
|
|
432
|
-
"Failed to get partition_id utf8 length");
|
|
433
|
-
}
|
|
434
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
435
|
-
return log_error_and_throw(env, "decrypt", "partition_id is empty");
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// Allocate
|
|
439
264
|
char *partition_id_cobhan_buffer;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
444
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
445
|
-
debug_log_alloca("decrypt", "partition_id_cobhan_buffer",
|
|
446
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
447
|
-
partition_id_cobhan_buffer =
|
|
448
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
449
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
450
|
-
} else {
|
|
451
|
-
// Otherwise, allocate it on the heap
|
|
452
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
453
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
454
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
455
|
-
}
|
|
456
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
457
|
-
return log_error_and_throw(env, "decrypt",
|
|
458
|
-
"Failed to allocate partition_id cobhan buffer");
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// Copy
|
|
462
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
463
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
464
|
-
&partition_copied_bytes);
|
|
465
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
466
|
-
return log_error_and_throw(env, "decrypt",
|
|
467
|
-
"Failed to copy partition_id to cobhan buffer");
|
|
468
|
-
}
|
|
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");
|
|
469
268
|
|
|
470
|
-
// Determine size
|
|
471
|
-
size_t input_utf8_byte_length;
|
|
472
269
|
Napi::String input = info[1].As<Napi::String>();
|
|
473
|
-
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
474
|
-
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
475
|
-
return log_error_and_throw(env, "decrypt",
|
|
476
|
-
"Failed to get input utf8 length");
|
|
477
|
-
}
|
|
478
|
-
if (unlikely(input_utf8_byte_length == 0)) {
|
|
479
|
-
return log_error_and_throw(env, "decrypt", "input is empty");
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
if (unlikely(verbose_flag)) {
|
|
483
|
-
debug_log("decrypt",
|
|
484
|
-
"input size " + std::to_string(input_utf8_byte_length));
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Allocate
|
|
488
270
|
char *input_cobhan_buffer;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
493
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
494
|
-
debug_log_alloca("decrypt", "input_cobhan_buffer",
|
|
495
|
-
input_cobhan_buffer_size_bytes);
|
|
496
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
497
|
-
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
498
|
-
} else {
|
|
499
|
-
// Otherwise, allocate it on the heap
|
|
500
|
-
input_cobhan_buffer_unique_ptr =
|
|
501
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_utf8_byte_length);
|
|
502
|
-
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
503
|
-
}
|
|
504
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
505
|
-
return log_error_and_throw(env, "decrypt",
|
|
506
|
-
"Failed to allocate input cobhan buffer");
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
// Copy
|
|
510
|
-
size_t input_copied_bytes;
|
|
511
|
-
input_cobhan_buffer =
|
|
512
|
-
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
513
|
-
input_cobhan_buffer, &input_copied_bytes);
|
|
514
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
515
|
-
return log_error_and_throw(env, "decrypt",
|
|
516
|
-
"Failed to copy input to cobhan buffer");
|
|
517
|
-
}
|
|
271
|
+
size_t input_copied_bytes = 0;
|
|
272
|
+
NAPI_STRING_TO_CBUFFER(input, input_cobhan_buffer, input_copied_bytes,
|
|
273
|
+
"decrypt");
|
|
518
274
|
|
|
519
275
|
char *output_cobhan_buffer;
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
heap_allocate_cbuffer("output_cobhan_buffer", input_utf8_byte_length);
|
|
533
|
-
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
276
|
+
ALLOCATE_OUTPUT_CBUFFER(output_cobhan_buffer, input_copied_bytes, "decrypt");
|
|
277
|
+
|
|
278
|
+
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
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");
|
|
283
|
+
}
|
|
284
|
+
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
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");
|
|
534
288
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
289
|
+
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
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");
|
|
538
293
|
}
|
|
539
294
|
|
|
540
295
|
if (unlikely(verbose_flag)) {
|
|
@@ -550,12 +305,29 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
550
305
|
debug_log("decrypt", "Returned from asherah-cobhan DecryptFromJson");
|
|
551
306
|
}
|
|
552
307
|
|
|
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");
|
|
312
|
+
}
|
|
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");
|
|
317
|
+
}
|
|
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");
|
|
322
|
+
}
|
|
323
|
+
|
|
553
324
|
if (unlikely(result < 0)) {
|
|
554
325
|
// TODO: Convert this to a proper error message
|
|
555
|
-
|
|
326
|
+
log_error_and_throw(env, "decrypt", std::to_string(result));
|
|
556
327
|
}
|
|
557
328
|
|
|
558
|
-
Napi::
|
|
329
|
+
Napi::Buffer<unsigned char> output =
|
|
330
|
+
cbuffer_to_nbuffer(env, output_cobhan_buffer);
|
|
559
331
|
|
|
560
332
|
if (unlikely(verbose_flag)) {
|
|
561
333
|
debug_log("decrypt", "finished");
|
|
@@ -564,7 +336,7 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
564
336
|
return output;
|
|
565
337
|
}
|
|
566
338
|
|
|
567
|
-
Napi::
|
|
339
|
+
Napi::String decrypt_string(const Napi::CallbackInfo &info) {
|
|
568
340
|
Napi::Env env = info.Env();
|
|
569
341
|
|
|
570
342
|
if (unlikely(verbose_flag)) {
|
|
@@ -572,126 +344,48 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
572
344
|
}
|
|
573
345
|
|
|
574
346
|
if (unlikely(setup_state == 0)) {
|
|
575
|
-
|
|
347
|
+
log_error_and_throw(env, "decrypt_string", "setup() not called");
|
|
576
348
|
}
|
|
577
349
|
|
|
578
350
|
if (unlikely(info.Length() < 2)) {
|
|
579
|
-
|
|
580
|
-
"Wrong number of arguments");
|
|
351
|
+
log_error_and_throw(env, "decrypt_string", "Wrong number of arguments");
|
|
581
352
|
}
|
|
582
353
|
|
|
583
354
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
584
|
-
|
|
355
|
+
log_error_and_throw(env, "decrypt_string", "Wrong argument types");
|
|
585
356
|
}
|
|
586
357
|
|
|
587
|
-
// Determine size
|
|
588
|
-
size_t partition_utf8_byte_length;
|
|
589
358
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
590
|
-
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
591
|
-
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
592
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
593
|
-
"Failed to get partition_id utf8 length");
|
|
594
|
-
}
|
|
595
|
-
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
596
|
-
return log_error_and_throw(env, "decrypt_string", "partition_id is empty");
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// Allocate
|
|
600
359
|
char *partition_id_cobhan_buffer;
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
size_t partition_id_cobhan_buffer_size_bytes =
|
|
605
|
-
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
606
|
-
debug_log_alloca("decrypt_string", "partition_id_cobhan_buffer",
|
|
607
|
-
partition_id_cobhan_buffer_size_bytes);
|
|
608
|
-
partition_id_cobhan_buffer =
|
|
609
|
-
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
610
|
-
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
611
|
-
} else {
|
|
612
|
-
// Otherwise, allocate it on the heap
|
|
613
|
-
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
614
|
-
"partition_id_cobhan_buffer", partition_utf8_byte_length);
|
|
615
|
-
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
616
|
-
}
|
|
617
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
618
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
619
|
-
"Failed to allocate partitionId cobhan buffer");
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
// Copy
|
|
623
|
-
size_t partition_copied_bytes;
|
|
624
|
-
partition_id_cobhan_buffer = copy_nstring_to_cbuffer(
|
|
625
|
-
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
626
|
-
&partition_copied_bytes);
|
|
627
|
-
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
628
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
629
|
-
"Failed to copy partitionId to cobhan buffer");
|
|
630
|
-
}
|
|
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");
|
|
631
363
|
|
|
632
|
-
// Determine size
|
|
633
|
-
size_t input_utf8_byte_length;
|
|
634
364
|
Napi::String input = info[1].As<Napi::String>();
|
|
635
|
-
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
636
|
-
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
637
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
638
|
-
"Failed to get input utf8 length");
|
|
639
|
-
}
|
|
640
|
-
if (unlikely(input_utf8_byte_length == 0)) {
|
|
641
|
-
return log_error_and_throw(env, "decrypt_string", "input is empty");
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// Allocate
|
|
645
365
|
char *input_cobhan_buffer;
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
size_t input_cobhan_buffer_size_bytes =
|
|
650
|
-
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
651
|
-
debug_log_alloca("decrypt_string", "input_cobhan_buffer",
|
|
652
|
-
input_cobhan_buffer_size_bytes);
|
|
653
|
-
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
654
|
-
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
655
|
-
} else {
|
|
656
|
-
// Otherwise, allocate it on the heap
|
|
657
|
-
input_cobhan_buffer_unique_ptr =
|
|
658
|
-
heap_allocate_cbuffer("input_cobhan_buffer", input_utf8_byte_length);
|
|
659
|
-
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
660
|
-
}
|
|
661
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
662
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
663
|
-
"Failed to allocate input cobhan buffer");
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// Copy
|
|
667
|
-
size_t input_copied_bytes;
|
|
668
|
-
input_cobhan_buffer =
|
|
669
|
-
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
670
|
-
input_cobhan_buffer, &input_copied_bytes);
|
|
671
|
-
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
672
|
-
return log_error_and_throw(env, "decrypt_string",
|
|
673
|
-
"Failed to copy input to cobhan buffer");
|
|
674
|
-
}
|
|
366
|
+
size_t input_copied_bytes = 0;
|
|
367
|
+
NAPI_STRING_TO_CBUFFER(input, input_cobhan_buffer, input_copied_bytes,
|
|
368
|
+
"decrypt_string");
|
|
675
369
|
|
|
676
370
|
char *output_cobhan_buffer;
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
371
|
+
ALLOCATE_OUTPUT_CBUFFER(output_cobhan_buffer, input_copied_bytes,
|
|
372
|
+
"decrypt_string");
|
|
373
|
+
|
|
374
|
+
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
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");
|
|
379
|
+
}
|
|
380
|
+
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
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");
|
|
691
384
|
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
385
|
+
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
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");
|
|
695
389
|
}
|
|
696
390
|
|
|
697
391
|
if (unlikely(verbose_flag)) {
|
|
@@ -707,12 +401,28 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
707
401
|
debug_log("decrypt_string", "Returned from asherah-cobhan DecryptFromJson");
|
|
708
402
|
}
|
|
709
403
|
|
|
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");
|
|
408
|
+
}
|
|
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");
|
|
413
|
+
}
|
|
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");
|
|
418
|
+
}
|
|
419
|
+
|
|
710
420
|
if (unlikely(result < 0)) {
|
|
711
421
|
// TODO: Convert this to a proper error message
|
|
712
|
-
|
|
422
|
+
log_error_and_throw(env, "decrypt_string", std::to_string(result));
|
|
713
423
|
}
|
|
714
424
|
|
|
715
|
-
Napi::
|
|
425
|
+
Napi::String output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
716
426
|
|
|
717
427
|
if (unlikely(verbose_flag)) {
|
|
718
428
|
debug_log("decrypt_string", "finished");
|
|
@@ -750,7 +460,6 @@ void set_max_stack_alloc_item_size(const Napi::CallbackInfo &info) {
|
|
|
750
460
|
if (unlikely(info.Length() < 1)) {
|
|
751
461
|
log_error_and_throw(env, "set_max_stack_alloc_item_size",
|
|
752
462
|
"Wrong number of arguments");
|
|
753
|
-
return;
|
|
754
463
|
}
|
|
755
464
|
|
|
756
465
|
Napi::Number item_size = info[0].ToNumber();
|
|
@@ -768,12 +477,11 @@ void set_safety_padding_overhead(const Napi::CallbackInfo &info) {
|
|
|
768
477
|
if (unlikely(info.Length() < 1)) {
|
|
769
478
|
log_error_and_throw(env, "set_safety_padding_overhead",
|
|
770
479
|
"Wrong number of arguments");
|
|
771
|
-
return;
|
|
772
480
|
}
|
|
773
481
|
|
|
774
482
|
Napi::Number safety_padding_number = info[0].ToNumber();
|
|
775
483
|
|
|
776
|
-
|
|
484
|
+
*safety_padding_bytes_ptr = (size_t)safety_padding_number.Int32Value();
|
|
777
485
|
}
|
|
778
486
|
|
|
779
487
|
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
#include <stddef.h>
|
|
2
|
-
size_t est_intermediate_key_overhead = 0;
|
|
3
|
-
size_t safety_padding_bytes = 0;
|
|
2
|
+
static size_t est_intermediate_key_overhead = 0;
|
|
3
|
+
static size_t safety_padding_bytes = 0;
|
|
4
|
+
|
|
5
|
+
size_t* get_est_intermediate_key_overhead_ptr() {
|
|
6
|
+
return &est_intermediate_key_overhead;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
size_t* get_safety_padding_bytes_ptr() {
|
|
10
|
+
return &safety_padding_bytes;
|
|
11
|
+
}
|
|
@@ -2,17 +2,24 @@
|
|
|
2
2
|
#define COBHAN_NAPI_INTEROP_H
|
|
3
3
|
#include "hints.h"
|
|
4
4
|
#include "logging.h"
|
|
5
|
-
#include <string>
|
|
6
5
|
#include <napi.h>
|
|
6
|
+
#include <string>
|
|
7
|
+
|
|
8
|
+
// Stupid hack to get around extern issues
|
|
9
|
+
size_t *get_est_intermediate_key_overhead_ptr();
|
|
10
|
+
size_t *get_safety_padding_bytes_ptr();
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
size_t *est_intermediate_key_overhead_ptr =
|
|
13
|
+
get_est_intermediate_key_overhead_ptr();
|
|
14
|
+
size_t *safety_padding_bytes_ptr = get_safety_padding_bytes_ptr();
|
|
10
15
|
|
|
11
16
|
const size_t est_encryption_overhead = 48;
|
|
12
17
|
const size_t est_envelope_overhead = 185;
|
|
13
18
|
const double base64_overhead = 1.34;
|
|
14
19
|
|
|
15
20
|
const size_t cobhan_header_size_bytes = 64 / 8;
|
|
21
|
+
const size_t canary_size = sizeof(int32_t) * 2;
|
|
22
|
+
const int32_t canary_constant = 0xdeadbeef;
|
|
16
23
|
|
|
17
24
|
std::string napi_status_to_string(napi_status status) {
|
|
18
25
|
switch (status) {
|
|
@@ -70,19 +77,20 @@ cbuffer_byte_length(char *cobhan_buffer) {
|
|
|
70
77
|
return *((int32_t *)cobhan_buffer);
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
__attribute__((always_inline)) inline
|
|
80
|
+
__attribute__((always_inline)) inline void
|
|
74
81
|
log_error_and_throw(Napi::Env &env, const char *function_name,
|
|
75
82
|
std::string error_msg) {
|
|
76
83
|
error_log(function_name, error_msg);
|
|
77
84
|
Napi::Error::New(env, function_name + (": " + error_msg))
|
|
78
85
|
.ThrowAsJavaScriptException();
|
|
79
|
-
return env.Null();
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
__attribute__((always_inline)) inline size_t
|
|
83
|
-
|
|
84
|
-
return data_len_bytes + cobhan_header_size_bytes +
|
|
85
|
-
1
|
|
89
|
+
calculate_cobhan_buffer_allocation_size(size_t data_len_bytes) {
|
|
90
|
+
return data_len_bytes + cobhan_header_size_bytes +
|
|
91
|
+
1 + // Add one for possible NULL delimiter due to Node string functions
|
|
92
|
+
canary_size // Add space for canary value
|
|
93
|
+
+ *safety_padding_bytes_ptr; // Add safety padding if configured
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
__attribute__((always_inline)) inline size_t
|
|
@@ -92,9 +100,9 @@ estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
|
92
100
|
double est_data_byte_len =
|
|
93
101
|
(double(data_byte_len + est_encryption_overhead) * base64_overhead) + 1;
|
|
94
102
|
|
|
95
|
-
size_t asherah_output_size_bytes =
|
|
96
|
-
|
|
97
|
-
|
|
103
|
+
size_t asherah_output_size_bytes = size_t(
|
|
104
|
+
est_envelope_overhead + *est_intermediate_key_overhead_ptr +
|
|
105
|
+
partition_byte_len + est_data_byte_len + *safety_padding_bytes_ptr);
|
|
98
106
|
if (unlikely(verbose_flag)) {
|
|
99
107
|
std::string log_msg =
|
|
100
108
|
"estimate_asherah_output_size(" + std::to_string(data_byte_len) + ", " +
|
|
@@ -107,56 +115,113 @@ estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
|
107
115
|
return asherah_output_size_bytes;
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
__attribute__((always_inline)) inline char *
|
|
119
|
+
cbuffer_data_ptr(char *cobhan_buffer) {
|
|
120
|
+
return cobhan_buffer + cobhan_header_size_bytes;
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
__attribute__((always_inline)) inline void configure_cbuffer(char *buffer,
|
|
111
124
|
size_t length) {
|
|
125
|
+
if (verbose_flag) {
|
|
126
|
+
debug_log("configure_cbuffer", "configure_cbuffer(" +
|
|
127
|
+
std::to_string((intptr_t)buffer) + ", " +
|
|
128
|
+
std::to_string(length) + ")");
|
|
129
|
+
}
|
|
130
|
+
|
|
112
131
|
*((int32_t *)buffer) = length;
|
|
113
132
|
// Reserved for future use
|
|
114
133
|
*((int32_t *)(buffer + sizeof(int32_t))) = 0;
|
|
134
|
+
|
|
135
|
+
// Write canary values
|
|
136
|
+
char *data_ptr = cbuffer_data_ptr(buffer);
|
|
137
|
+
if (verbose_flag) {
|
|
138
|
+
debug_log("configure_cbuffer",
|
|
139
|
+
"Writing first canary at " +
|
|
140
|
+
std::to_string((intptr_t)(data_ptr + length + 1)));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// First canary value is a int32_t 0 which gives us four NULLs
|
|
144
|
+
*((int32_t *)(data_ptr + length + 1)) = 0;
|
|
145
|
+
|
|
146
|
+
if (verbose_flag) {
|
|
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
|
+
}
|
|
152
|
+
|
|
153
|
+
// Second canary value is a int32_t 0xdeadbeef
|
|
154
|
+
*((int32_t *)(data_ptr + length + 1 + sizeof(int32_t))) = canary_constant;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
__attribute__((always_inline)) inline char *
|
|
158
|
+
get_canary_ptr(char *cobhan_buffer) {
|
|
159
|
+
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
160
|
+
return cbuffer_data_ptr(cobhan_buffer) + cobhan_buffer_size_bytes + 1;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
__attribute__((always_inline)) inline bool check_canary_ptr(char *canary_ptr) {
|
|
164
|
+
int32_t zero_value = *((int32_t *)(canary_ptr));
|
|
165
|
+
if (zero_value != 0) {
|
|
166
|
+
std::string error_msg =
|
|
167
|
+
"Canary check failed: " + std::to_string(zero_value) + " != 0";
|
|
168
|
+
error_log("canary_check_cbuffer", error_msg);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
int32_t canary_value = *((int32_t *)(canary_ptr + sizeof(int32_t)));
|
|
172
|
+
if (canary_value != canary_constant) {
|
|
173
|
+
std::string error_msg =
|
|
174
|
+
"Canary check failed: " + std::to_string(canary_value) +
|
|
175
|
+
" != " + std::to_string(canary_constant);
|
|
176
|
+
error_log("canary_check_cbuffer", error_msg);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
115
180
|
}
|
|
116
181
|
|
|
117
182
|
__attribute__((always_inline)) inline std::unique_ptr<char[]>
|
|
118
183
|
heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
119
|
-
size_t
|
|
120
|
-
|
|
184
|
+
size_t cobhan_buffer_allocation_size =
|
|
185
|
+
calculate_cobhan_buffer_allocation_size(size_bytes);
|
|
121
186
|
if (unlikely(verbose_flag)) {
|
|
122
187
|
std::string log_msg =
|
|
123
188
|
"heap_allocate_cbuffer(" + std::to_string(size_bytes) +
|
|
124
|
-
") (heap)
|
|
125
|
-
std::to_string(
|
|
189
|
+
") (heap) cobhan_buffer_allocation_size: " +
|
|
190
|
+
std::to_string(cobhan_buffer_allocation_size) + " for " + variable_name;
|
|
126
191
|
debug_log("allocate_cbuffer", log_msg);
|
|
127
192
|
}
|
|
128
193
|
|
|
129
|
-
char *cobhan_buffer = new (std::nothrow) char[
|
|
194
|
+
char *cobhan_buffer = new (std::nothrow) char[cobhan_buffer_allocation_size];
|
|
130
195
|
if (unlikely(cobhan_buffer == nullptr)) {
|
|
131
|
-
std::string error_msg =
|
|
132
|
-
|
|
196
|
+
std::string error_msg = "new[" +
|
|
197
|
+
std::to_string(cobhan_buffer_allocation_size) +
|
|
198
|
+
"] returned null";
|
|
133
199
|
error_log("allocate_cbuffer", error_msg);
|
|
134
200
|
return nullptr;
|
|
135
201
|
}
|
|
136
202
|
std::unique_ptr<char[]> cobhan_buffer_unique_ptr(cobhan_buffer);
|
|
137
|
-
configure_cbuffer(cobhan_buffer, size_bytes +
|
|
203
|
+
configure_cbuffer(cobhan_buffer, size_bytes + *safety_padding_bytes_ptr);
|
|
138
204
|
return cobhan_buffer_unique_ptr;
|
|
139
205
|
}
|
|
140
206
|
|
|
141
|
-
__attribute__((always_inline)) inline Napi::
|
|
207
|
+
__attribute__((always_inline)) inline Napi::String
|
|
142
208
|
cbuffer_to_nstring(Napi::Env &env, char *cobhan_buffer) {
|
|
143
209
|
napi_value output;
|
|
144
210
|
|
|
145
211
|
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
146
212
|
if (cobhan_buffer_size_bytes <= 0) {
|
|
147
|
-
|
|
148
|
-
|
|
213
|
+
log_error_and_throw(env, "cbuffer_to_nstring",
|
|
214
|
+
"Invalid cobhan buffer byte length");
|
|
149
215
|
}
|
|
150
216
|
|
|
151
217
|
// Using C function because it allows length delimited input
|
|
152
218
|
napi_status status = napi_create_string_utf8(
|
|
153
|
-
env, (
|
|
154
|
-
cobhan_buffer_size_bytes, &output);
|
|
219
|
+
env, cbuffer_data_ptr(cobhan_buffer), cobhan_buffer_size_bytes, &output);
|
|
155
220
|
|
|
156
221
|
if (unlikely(status != napi_ok)) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
222
|
+
log_error_and_throw(env, "cbuffer_to_nstring",
|
|
223
|
+
"napi_create_string_utf8 failed: " +
|
|
224
|
+
napi_status_to_string(status));
|
|
160
225
|
}
|
|
161
226
|
|
|
162
227
|
return Napi::String(env, output);
|
|
@@ -196,13 +261,21 @@ copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
|
196
261
|
return nullptr;
|
|
197
262
|
}
|
|
198
263
|
|
|
264
|
+
if (unlikely(verbose_flag)) {
|
|
265
|
+
debug_log("copy_nstring_to_cbuffer",
|
|
266
|
+
"Copying " + std::to_string(str_utf8_byte_length) + " bytes to " +
|
|
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)));
|
|
271
|
+
}
|
|
272
|
+
|
|
199
273
|
napi_status status;
|
|
200
274
|
size_t copied_bytes;
|
|
201
275
|
// NOTE: This implementation relies on the additional byte that is reserved
|
|
202
276
|
// upon allocation for a NULL delimiter as methods like
|
|
203
277
|
// napi_get_value_string_utf8 append a NULL delimiter
|
|
204
|
-
status = napi_get_value_string_utf8(env, str,
|
|
205
|
-
cobhan_buffer + cobhan_header_size_bytes,
|
|
278
|
+
status = napi_get_value_string_utf8(env, str, cbuffer_data_ptr(cobhan_buffer),
|
|
206
279
|
str_utf8_byte_length + 1, &copied_bytes);
|
|
207
280
|
if (unlikely(status != napi_ok)) {
|
|
208
281
|
log_error_and_throw(env, "copy_nstring_to_cbuffer",
|
|
@@ -244,18 +317,17 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
244
317
|
"Buffer too large for cobhan buffer");
|
|
245
318
|
return nullptr;
|
|
246
319
|
}
|
|
247
|
-
memcpy(cobhan_buffer
|
|
248
|
-
nbuffer_byte_length);
|
|
320
|
+
memcpy(cbuffer_data_ptr(cobhan_buffer), nbuffer.Data(), nbuffer_byte_length);
|
|
249
321
|
configure_cbuffer(cobhan_buffer, nbuffer_byte_length);
|
|
250
322
|
return cobhan_buffer;
|
|
251
323
|
}
|
|
252
324
|
|
|
253
|
-
__attribute__((always_inline)) inline Napi::
|
|
325
|
+
__attribute__((always_inline)) inline Napi::Buffer<unsigned char>
|
|
254
326
|
cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
255
327
|
int32_t cobhan_buffer_byte_length = cbuffer_byte_length(cobhan_buffer);
|
|
256
328
|
if (unlikely(cobhan_buffer_byte_length <= 0)) {
|
|
257
|
-
|
|
258
|
-
|
|
329
|
+
log_error_and_throw(env, "cbuffer_to_nbuffer",
|
|
330
|
+
"Invalid cobhan buffer byte length");
|
|
259
331
|
}
|
|
260
332
|
|
|
261
333
|
if (unlikely(verbose_flag)) {
|
|
@@ -269,8 +341,8 @@ cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
|
269
341
|
"Invalid cobhan buffer byte length");
|
|
270
342
|
}
|
|
271
343
|
|
|
272
|
-
Napi::Buffer nbuffer = Napi::Buffer<unsigned char>::Copy(
|
|
273
|
-
env, (
|
|
344
|
+
Napi::Buffer<unsigned char> nbuffer = Napi::Buffer<unsigned char>::Copy(
|
|
345
|
+
env, (const unsigned char *)cbuffer_data_ptr(cobhan_buffer),
|
|
274
346
|
cobhan_buffer_byte_length);
|
|
275
347
|
|
|
276
348
|
if (unlikely(verbose_flag)) {
|
|
@@ -281,4 +353,115 @@ cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
|
281
353
|
return nbuffer;
|
|
282
354
|
}
|
|
283
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
|
+
|
|
284
467
|
#endif
|