asherah 1.3.22 → 1.3.23
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/binding.gyp +0 -1
- package/package.json +1 -2
- package/src/asherah.cc +153 -93
- package/src/cobhan.h +12 -25
- package/src/cobhan_napi_interop.h +31 -60
- package/src/logging.h +10 -0
- package/src/cobhan_napi_interop.cc +0 -2
package/binding.gyp
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asherah",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.23",
|
|
4
4
|
"description": "Asherah envelope encryption and key rotation library",
|
|
5
5
|
"exports": {
|
|
6
6
|
"node-addons": "./dist/asherah.node"
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"src/logging.h",
|
|
28
28
|
"src/logging.cc",
|
|
29
29
|
"src/cobhan_napi_interop.h",
|
|
30
|
-
"src/cobhan_napi_interop.cc",
|
|
31
30
|
"src/cobhan.h",
|
|
32
31
|
"src/cobhan.cc",
|
|
33
32
|
"src/asherah.d.ts",
|
package/src/asherah.cc
CHANGED
|
@@ -6,23 +6,90 @@
|
|
|
6
6
|
#include <mutex>
|
|
7
7
|
#include <napi.h>
|
|
8
8
|
|
|
9
|
-
size_t
|
|
9
|
+
size_t est_intermediate_key_overhead;
|
|
10
|
+
size_t maximum_stack_alloc_size = 2048;
|
|
11
|
+
|
|
10
12
|
int32_t setup_state = 0;
|
|
11
13
|
std::mutex asherah_lock;
|
|
12
14
|
|
|
15
|
+
__attribute__((always_inline)) inline size_t
|
|
16
|
+
estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
17
|
+
size_t partition_byte_len) {
|
|
18
|
+
const size_t est_encryption_overhead = 48;
|
|
19
|
+
const size_t est_envelope_overhead = 185;
|
|
20
|
+
const double base64_overhead = 1.34;
|
|
21
|
+
|
|
22
|
+
// Add one rather than using std::ceil to round up
|
|
23
|
+
double est_data_byte_len =
|
|
24
|
+
(double(data_byte_len + est_encryption_overhead) * base64_overhead) + 1;
|
|
25
|
+
|
|
26
|
+
size_t asherah_output_size_bytes =
|
|
27
|
+
size_t(est_envelope_overhead + est_intermediate_key_overhead +
|
|
28
|
+
partition_byte_len + est_data_byte_len);
|
|
29
|
+
if (unlikely(verbose_flag)) {
|
|
30
|
+
std::string log_msg =
|
|
31
|
+
"estimate_asherah_output_size(" + std::to_string(data_byte_len) + ", " +
|
|
32
|
+
std::to_string(partition_byte_len) +
|
|
33
|
+
") est_data_byte_len: " + std::to_string(est_data_byte_len) +
|
|
34
|
+
" asherah_output_size_bytes: " +
|
|
35
|
+
std::to_string(asherah_output_size_bytes);
|
|
36
|
+
debug_log(__func__, log_msg);
|
|
37
|
+
}
|
|
38
|
+
return asherah_output_size_bytes;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
__attribute__((always_inline)) inline const char* asherah_cobhan_error_to_string(int32_t error) {
|
|
42
|
+
switch(error) {
|
|
43
|
+
case 0:
|
|
44
|
+
return "Success";
|
|
45
|
+
case -1:
|
|
46
|
+
return "Cobhan error: NULL pointer";
|
|
47
|
+
case -2:
|
|
48
|
+
return "Cobhan error: Buffer too large";
|
|
49
|
+
case -3:
|
|
50
|
+
return "Cobhan error: Buffer too small";
|
|
51
|
+
case -4:
|
|
52
|
+
return "Cobhan error: Copy failed";
|
|
53
|
+
case -5:
|
|
54
|
+
return "Cobhan error: JSON decode failed";
|
|
55
|
+
case -6:
|
|
56
|
+
return "Cobhan error: JSON encode failed";
|
|
57
|
+
case -7:
|
|
58
|
+
return "Cobhan error: Invalid UTF-8";
|
|
59
|
+
case -8:
|
|
60
|
+
return "Cobhan error: Read temp file failed";
|
|
61
|
+
case -9:
|
|
62
|
+
return "Cobhan error: Write temp file failed";
|
|
63
|
+
case -100:
|
|
64
|
+
return "Asherah error: Not initialized";
|
|
65
|
+
case -101:
|
|
66
|
+
return "Asherah error: Already initialized";
|
|
67
|
+
case -102:
|
|
68
|
+
return "Asherah error: Failed to get session";
|
|
69
|
+
case -103:
|
|
70
|
+
return "Asherah error: Encrypt operation failed";
|
|
71
|
+
case -104:
|
|
72
|
+
return "Asherah error: Decrypt operation failed";
|
|
73
|
+
case -105:
|
|
74
|
+
return "Asherah error: Invalid configuration";
|
|
75
|
+
default:
|
|
76
|
+
return "Unknown error";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
13
80
|
void setup(const Napi::CallbackInfo &info) {
|
|
14
81
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
15
82
|
|
|
16
83
|
if (unlikely(verbose_flag)) {
|
|
17
|
-
debug_log(
|
|
84
|
+
debug_log(__func__, "called");
|
|
18
85
|
}
|
|
19
86
|
|
|
20
87
|
if (unlikely(setup_state == 1)) {
|
|
21
|
-
log_error_and_throw(
|
|
88
|
+
log_error_and_throw(__func__, "setup called twice");
|
|
22
89
|
}
|
|
23
90
|
|
|
24
91
|
if (unlikely(info.Length() < 1)) {
|
|
25
|
-
log_error_and_throw(
|
|
92
|
+
log_error_and_throw(__func__, "Wrong number of arguments");
|
|
26
93
|
}
|
|
27
94
|
|
|
28
95
|
Napi::String config;
|
|
@@ -38,7 +105,7 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
38
105
|
Napi::Function parse = json.Get("parse").As<Napi::Function>();
|
|
39
106
|
config_json = parse.Call(json, {config}).As<Napi::Object>();
|
|
40
107
|
} else {
|
|
41
|
-
log_error_and_throw(
|
|
108
|
+
log_error_and_throw(__func__, "Wrong argument type");
|
|
42
109
|
}
|
|
43
110
|
|
|
44
111
|
Napi::String product_id = config_json.Get("ProductID").As<Napi::String>();
|
|
@@ -50,20 +117,20 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
50
117
|
Napi::Value verbose = config_json.Get("Verbose");
|
|
51
118
|
if (likely(verbose.IsBoolean())) {
|
|
52
119
|
verbose_flag = verbose.As<Napi::Boolean>().Value();
|
|
53
|
-
debug_log(
|
|
120
|
+
debug_log(__func__, "verbose_flag: " + std::to_string(verbose_flag));
|
|
54
121
|
} else {
|
|
55
122
|
verbose_flag = 0;
|
|
56
|
-
debug_log(
|
|
123
|
+
debug_log(__func__, "verbose_flag: defaulting to false");
|
|
57
124
|
}
|
|
58
125
|
|
|
59
126
|
char *config_cobhan_buffer;
|
|
60
127
|
size_t config_copied_bytes;
|
|
61
128
|
NAPI_STRING_TO_CBUFFER(env, config, config_cobhan_buffer, config_copied_bytes,
|
|
62
|
-
|
|
129
|
+
maximum_stack_alloc_size, __func__);
|
|
63
130
|
|
|
64
131
|
char *config_canary_ptr = get_canary_ptr(config_cobhan_buffer);
|
|
65
132
|
if (unlikely(!check_canary_ptr(config_canary_ptr))) {
|
|
66
|
-
log_error_and_throw(
|
|
133
|
+
log_error_and_throw(__func__,
|
|
67
134
|
"Failed initial canary check for config_cobhan_buffer");
|
|
68
135
|
}
|
|
69
136
|
|
|
@@ -71,18 +138,17 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
71
138
|
GoInt32 result = SetupJson(config_cobhan_buffer);
|
|
72
139
|
|
|
73
140
|
if (unlikely(verbose_flag)) {
|
|
74
|
-
debug_log(
|
|
141
|
+
debug_log(__func__, "Returned from asherah-cobhan SetupJson");
|
|
75
142
|
}
|
|
76
143
|
|
|
77
144
|
if (unlikely(!check_canary_ptr(config_canary_ptr))) {
|
|
78
145
|
log_error_and_throw(
|
|
79
|
-
|
|
146
|
+
__func__,
|
|
80
147
|
"Failed post-call canary check for config_cobhan_buffer");
|
|
81
148
|
}
|
|
82
149
|
|
|
83
150
|
if (unlikely(result < 0)) {
|
|
84
|
-
|
|
85
|
-
log_error_and_throw("setup", std::to_string(result));
|
|
151
|
+
log_error_and_throw(__func__, asherah_cobhan_error_to_string(result));
|
|
86
152
|
}
|
|
87
153
|
setup_state = 1;
|
|
88
154
|
}
|
|
@@ -96,33 +162,32 @@ Napi::String encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
96
162
|
estimate_asherah_output_size_bytes(data_bytes, partition_bytes);
|
|
97
163
|
|
|
98
164
|
if (unlikely(verbose_flag)) {
|
|
99
|
-
debug_log(
|
|
165
|
+
debug_log(__func__, " asherah_output_size_bytes " +
|
|
100
166
|
std::to_string(asherah_output_size_bytes));
|
|
101
167
|
}
|
|
102
168
|
|
|
103
169
|
char *output_cobhan_buffer;
|
|
104
170
|
ALLOCATE_CBUFFER(output_cobhan_buffer, asherah_output_size_bytes,
|
|
105
|
-
|
|
171
|
+
maximum_stack_alloc_size, __func__);
|
|
106
172
|
|
|
107
173
|
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
108
174
|
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
109
|
-
log_error_and_throw(
|
|
110
|
-
"encrypt_to_json",
|
|
175
|
+
log_error_and_throw(__func__,
|
|
111
176
|
"Failed initial canary check for partition_id_cobhan_buffer");
|
|
112
177
|
}
|
|
113
178
|
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
114
179
|
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
115
|
-
log_error_and_throw(
|
|
180
|
+
log_error_and_throw(__func__,
|
|
116
181
|
"Failed initial canary check for input_cobhan_buffer");
|
|
117
182
|
}
|
|
118
183
|
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
119
184
|
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
120
|
-
log_error_and_throw(
|
|
185
|
+
log_error_and_throw(__func__,
|
|
121
186
|
"Failed initial canary check for output_cobhan_buffer");
|
|
122
187
|
}
|
|
123
188
|
|
|
124
189
|
if (unlikely(verbose_flag)) {
|
|
125
|
-
debug_log(
|
|
190
|
+
debug_log(__func__, "Calling asherah-cobhan EncryptToJson");
|
|
126
191
|
}
|
|
127
192
|
|
|
128
193
|
// extern GoInt32 EncryptToJson(void* partitionIdPtr, void* dataPtr, void*
|
|
@@ -131,28 +196,24 @@ Napi::String encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
131
196
|
input_cobhan_buffer, output_cobhan_buffer);
|
|
132
197
|
|
|
133
198
|
if (unlikely(verbose_flag)) {
|
|
134
|
-
debug_log(
|
|
199
|
+
debug_log(__func__, "Returning from asherah-cobhan EncryptToJson");
|
|
135
200
|
}
|
|
136
201
|
|
|
137
202
|
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
138
|
-
log_error_and_throw(
|
|
139
|
-
"encrypt_to_json",
|
|
203
|
+
log_error_and_throw(__func__,
|
|
140
204
|
"Failed post-call canary check for partition_id_cobhan_buffer");
|
|
141
205
|
}
|
|
142
206
|
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
143
|
-
log_error_and_throw(
|
|
144
|
-
"encrypt_to_json",
|
|
207
|
+
log_error_and_throw(__func__,
|
|
145
208
|
"Failed post-call canary check for input_cobhan_buffer");
|
|
146
209
|
}
|
|
147
210
|
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
148
|
-
log_error_and_throw(
|
|
149
|
-
"encrypt_to_json",
|
|
211
|
+
log_error_and_throw(__func__,
|
|
150
212
|
"Failed post-call canary check for output_cobhan_buffer");
|
|
151
213
|
}
|
|
152
214
|
|
|
153
215
|
if (unlikely(result < 0)) {
|
|
154
|
-
|
|
155
|
-
log_error_and_throw("encrypt_to_json", std::to_string(result));
|
|
216
|
+
log_error_and_throw(__func__, asherah_cobhan_error_to_string(result));
|
|
156
217
|
}
|
|
157
218
|
|
|
158
219
|
Napi::String output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
@@ -163,19 +224,19 @@ Napi::String encrypt(const Napi::CallbackInfo &info) {
|
|
|
163
224
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
164
225
|
|
|
165
226
|
if (unlikely(verbose_flag)) {
|
|
166
|
-
debug_log(
|
|
227
|
+
debug_log(__func__, "called");
|
|
167
228
|
}
|
|
168
229
|
|
|
169
230
|
if (unlikely(setup_state == 0)) {
|
|
170
|
-
log_error_and_throw(
|
|
231
|
+
log_error_and_throw(__func__, "setup() not called");
|
|
171
232
|
}
|
|
172
233
|
|
|
173
234
|
if (unlikely(info.Length() < 2)) {
|
|
174
|
-
log_error_and_throw(
|
|
235
|
+
log_error_and_throw(__func__, "Wrong number of arguments");
|
|
175
236
|
}
|
|
176
237
|
|
|
177
238
|
if (unlikely(!info[0].IsString() || !info[1].IsBuffer())) {
|
|
178
|
-
log_error_and_throw(
|
|
239
|
+
log_error_and_throw(__func__, "Wrong argument types");
|
|
179
240
|
}
|
|
180
241
|
|
|
181
242
|
Napi::Env env = info.Env();
|
|
@@ -184,21 +245,23 @@ Napi::String encrypt(const Napi::CallbackInfo &info) {
|
|
|
184
245
|
char *partition_id_cobhan_buffer;
|
|
185
246
|
size_t partition_id_copied_bytes;
|
|
186
247
|
NAPI_STRING_TO_CBUFFER(env, partition_id, partition_id_cobhan_buffer,
|
|
187
|
-
partition_id_copied_bytes,
|
|
248
|
+
partition_id_copied_bytes, maximum_stack_alloc_size,
|
|
249
|
+
__func__);
|
|
188
250
|
|
|
189
251
|
Napi::Buffer<unsigned char> input_napi_buffer =
|
|
190
252
|
info[1].As<Napi::Buffer<unsigned char>>();
|
|
191
253
|
char *input_cobhan_buffer;
|
|
192
254
|
size_t input_copied_bytes;
|
|
193
255
|
NAPI_BUFFER_TO_CBUFFER(env, input_napi_buffer, input_cobhan_buffer,
|
|
194
|
-
input_copied_bytes,
|
|
256
|
+
input_copied_bytes, maximum_stack_alloc_size,
|
|
257
|
+
__func__);
|
|
195
258
|
|
|
196
259
|
Napi::String output =
|
|
197
260
|
encrypt_to_json(env, partition_id_copied_bytes, input_copied_bytes,
|
|
198
261
|
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
199
262
|
|
|
200
263
|
if (unlikely(verbose_flag)) {
|
|
201
|
-
debug_log(
|
|
264
|
+
debug_log(__func__, "finished");
|
|
202
265
|
}
|
|
203
266
|
|
|
204
267
|
return output;
|
|
@@ -208,19 +271,19 @@ Napi::String encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
208
271
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
209
272
|
|
|
210
273
|
if (unlikely(verbose_flag)) {
|
|
211
|
-
debug_log(
|
|
274
|
+
debug_log(__func__, "called");
|
|
212
275
|
}
|
|
213
276
|
|
|
214
277
|
if (unlikely(setup_state == 0)) {
|
|
215
|
-
log_error_and_throw(
|
|
278
|
+
log_error_and_throw(__func__, "setup() not called");
|
|
216
279
|
}
|
|
217
280
|
|
|
218
281
|
if (unlikely(info.Length() < 2)) {
|
|
219
|
-
log_error_and_throw(
|
|
282
|
+
log_error_and_throw(__func__, "Wrong number of arguments");
|
|
220
283
|
}
|
|
221
284
|
|
|
222
285
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
223
|
-
log_error_and_throw(
|
|
286
|
+
log_error_and_throw(__func__, "Wrong argument types");
|
|
224
287
|
}
|
|
225
288
|
|
|
226
289
|
Napi::Env env = info.Env();
|
|
@@ -229,20 +292,21 @@ Napi::String encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
229
292
|
char *partition_id_cobhan_buffer;
|
|
230
293
|
size_t partition_id_copied_bytes;
|
|
231
294
|
NAPI_STRING_TO_CBUFFER(env, partition_id, partition_id_cobhan_buffer,
|
|
232
|
-
partition_id_copied_bytes,
|
|
295
|
+
partition_id_copied_bytes, maximum_stack_alloc_size,
|
|
296
|
+
__func__);
|
|
233
297
|
|
|
234
298
|
Napi::String input = info[1].As<Napi::String>();
|
|
235
299
|
char *input_cobhan_buffer;
|
|
236
300
|
size_t input_copied_bytes;
|
|
237
301
|
NAPI_STRING_TO_CBUFFER(env, input, input_cobhan_buffer, input_copied_bytes,
|
|
238
|
-
|
|
302
|
+
maximum_stack_alloc_size, __func__);
|
|
239
303
|
|
|
240
304
|
Napi::String output =
|
|
241
305
|
encrypt_to_json(env, partition_id_copied_bytes, input_copied_bytes,
|
|
242
306
|
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
243
307
|
|
|
244
308
|
if (unlikely(verbose_flag)) {
|
|
245
|
-
debug_log(
|
|
309
|
+
debug_log(__func__, "finished");
|
|
246
310
|
}
|
|
247
311
|
|
|
248
312
|
return output;
|
|
@@ -252,19 +316,19 @@ Napi::Buffer<unsigned char> decrypt(const Napi::CallbackInfo &info) {
|
|
|
252
316
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
253
317
|
|
|
254
318
|
if (unlikely(verbose_flag)) {
|
|
255
|
-
debug_log(
|
|
319
|
+
debug_log(__func__, "called");
|
|
256
320
|
}
|
|
257
321
|
|
|
258
322
|
if (unlikely(setup_state == 0)) {
|
|
259
|
-
log_error_and_throw(
|
|
323
|
+
log_error_and_throw(__func__, "setup() not called");
|
|
260
324
|
}
|
|
261
325
|
|
|
262
326
|
if (unlikely(info.Length() < 2)) {
|
|
263
|
-
log_error_and_throw(
|
|
327
|
+
log_error_and_throw(__func__, "Wrong number of arguments");
|
|
264
328
|
}
|
|
265
329
|
|
|
266
330
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
267
|
-
log_error_and_throw(
|
|
331
|
+
log_error_and_throw(__func__, "Wrong argument types");
|
|
268
332
|
}
|
|
269
333
|
|
|
270
334
|
Napi::Env env = info.Env();
|
|
@@ -273,36 +337,38 @@ Napi::Buffer<unsigned char> decrypt(const Napi::CallbackInfo &info) {
|
|
|
273
337
|
char *partition_id_cobhan_buffer;
|
|
274
338
|
size_t partition_id_copied_bytes;
|
|
275
339
|
NAPI_STRING_TO_CBUFFER(env, partition_id, partition_id_cobhan_buffer,
|
|
276
|
-
partition_id_copied_bytes,
|
|
340
|
+
partition_id_copied_bytes, maximum_stack_alloc_size,
|
|
341
|
+
__func__);
|
|
277
342
|
|
|
278
343
|
Napi::String input = info[1].As<Napi::String>();
|
|
279
344
|
char *input_cobhan_buffer;
|
|
280
345
|
size_t input_copied_bytes;
|
|
281
346
|
NAPI_STRING_TO_CBUFFER(env, input, input_cobhan_buffer, input_copied_bytes,
|
|
282
|
-
|
|
347
|
+
maximum_stack_alloc_size, __func__);
|
|
283
348
|
|
|
284
349
|
char *output_cobhan_buffer;
|
|
285
|
-
ALLOCATE_CBUFFER(output_cobhan_buffer, input_copied_bytes,
|
|
350
|
+
ALLOCATE_CBUFFER(output_cobhan_buffer, input_copied_bytes,
|
|
351
|
+
maximum_stack_alloc_size, __func__);
|
|
286
352
|
|
|
287
353
|
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
288
354
|
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
289
355
|
log_error_and_throw(
|
|
290
|
-
|
|
356
|
+
__func__,
|
|
291
357
|
"Failed initial canary check for partition_id_cobhan_buffer");
|
|
292
358
|
}
|
|
293
359
|
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
294
360
|
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
295
|
-
log_error_and_throw(
|
|
361
|
+
log_error_and_throw(__func__,
|
|
296
362
|
"Failed initial canary check for input_cobhan_buffer");
|
|
297
363
|
}
|
|
298
364
|
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
299
365
|
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
300
|
-
log_error_and_throw(
|
|
366
|
+
log_error_and_throw(__func__,
|
|
301
367
|
"Failed initial canary check for output_cobhan_buffer");
|
|
302
368
|
}
|
|
303
369
|
|
|
304
370
|
if (unlikely(verbose_flag)) {
|
|
305
|
-
debug_log(
|
|
371
|
+
debug_log(__func__, "Calling asherah-cobhan DecryptFromJson");
|
|
306
372
|
}
|
|
307
373
|
|
|
308
374
|
// extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void*
|
|
@@ -311,35 +377,31 @@ Napi::Buffer<unsigned char> decrypt(const Napi::CallbackInfo &info) {
|
|
|
311
377
|
input_cobhan_buffer, output_cobhan_buffer);
|
|
312
378
|
|
|
313
379
|
if (unlikely(verbose_flag)) {
|
|
314
|
-
debug_log(
|
|
380
|
+
debug_log(__func__, "Returned from asherah-cobhan DecryptFromJson");
|
|
315
381
|
}
|
|
316
382
|
|
|
317
383
|
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
318
|
-
log_error_and_throw(
|
|
319
|
-
"encrypt_to_json",
|
|
384
|
+
log_error_and_throw(__func__,
|
|
320
385
|
"Failed post-call canary check for partition_id_cobhan_buffer");
|
|
321
386
|
}
|
|
322
387
|
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
323
|
-
log_error_and_throw(
|
|
324
|
-
"encrypt_to_json",
|
|
388
|
+
log_error_and_throw(__func__,
|
|
325
389
|
"Failed post-call canary check for input_cobhan_buffer");
|
|
326
390
|
}
|
|
327
391
|
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
328
|
-
log_error_and_throw(
|
|
329
|
-
"encrypt_to_json",
|
|
392
|
+
log_error_and_throw(__func__,
|
|
330
393
|
"Failed post-call canary check for output_cobhan_buffer");
|
|
331
394
|
}
|
|
332
395
|
|
|
333
396
|
if (unlikely(result < 0)) {
|
|
334
|
-
|
|
335
|
-
log_error_and_throw("decrypt", std::to_string(result));
|
|
397
|
+
log_error_and_throw(__func__, asherah_cobhan_error_to_string(result));
|
|
336
398
|
}
|
|
337
399
|
|
|
338
400
|
Napi::Buffer<unsigned char> output =
|
|
339
401
|
cbuffer_to_nbuffer(env, output_cobhan_buffer);
|
|
340
402
|
|
|
341
403
|
if (unlikely(verbose_flag)) {
|
|
342
|
-
debug_log(
|
|
404
|
+
debug_log(__func__, "finished");
|
|
343
405
|
}
|
|
344
406
|
|
|
345
407
|
return output;
|
|
@@ -349,19 +411,19 @@ Napi::String decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
349
411
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
350
412
|
|
|
351
413
|
if (unlikely(verbose_flag)) {
|
|
352
|
-
debug_log(
|
|
414
|
+
debug_log(__func__, "called");
|
|
353
415
|
}
|
|
354
416
|
|
|
355
417
|
if (unlikely(setup_state == 0)) {
|
|
356
|
-
log_error_and_throw(
|
|
418
|
+
log_error_and_throw(__func__, "setup() not called");
|
|
357
419
|
}
|
|
358
420
|
|
|
359
421
|
if (unlikely(info.Length() < 2)) {
|
|
360
|
-
log_error_and_throw(
|
|
422
|
+
log_error_and_throw(__func__, "Wrong number of arguments");
|
|
361
423
|
}
|
|
362
424
|
|
|
363
425
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
364
|
-
log_error_and_throw(
|
|
426
|
+
log_error_and_throw(__func__, "Wrong argument types");
|
|
365
427
|
}
|
|
366
428
|
|
|
367
429
|
Napi::Env env = info.Env();
|
|
@@ -370,36 +432,38 @@ Napi::String decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
370
432
|
char *partition_id_cobhan_buffer;
|
|
371
433
|
size_t partition_id_copied_bytes;
|
|
372
434
|
NAPI_STRING_TO_CBUFFER(env, partition_id, partition_id_cobhan_buffer,
|
|
373
|
-
partition_id_copied_bytes,
|
|
435
|
+
partition_id_copied_bytes, maximum_stack_alloc_size,
|
|
436
|
+
__func__);
|
|
374
437
|
|
|
375
438
|
Napi::String input = info[1].As<Napi::String>();
|
|
376
439
|
char *input_cobhan_buffer;
|
|
377
440
|
size_t input_copied_bytes;
|
|
378
441
|
NAPI_STRING_TO_CBUFFER(env, input, input_cobhan_buffer, input_copied_bytes,
|
|
379
|
-
|
|
442
|
+
maximum_stack_alloc_size, __func__);
|
|
380
443
|
|
|
381
444
|
char *output_cobhan_buffer;
|
|
382
|
-
ALLOCATE_CBUFFER(output_cobhan_buffer, input_copied_bytes,
|
|
445
|
+
ALLOCATE_CBUFFER(output_cobhan_buffer, input_copied_bytes,
|
|
446
|
+
maximum_stack_alloc_size, __func__);
|
|
383
447
|
|
|
384
448
|
char *partition_id_canary_ptr = get_canary_ptr(partition_id_cobhan_buffer);
|
|
385
449
|
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
386
450
|
log_error_and_throw(
|
|
387
|
-
|
|
451
|
+
__func__,
|
|
388
452
|
"Failed initial canary check for partition_id_cobhan_buffer");
|
|
389
453
|
}
|
|
390
454
|
char *input_canary_ptr = get_canary_ptr(input_cobhan_buffer);
|
|
391
455
|
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
392
|
-
log_error_and_throw(
|
|
456
|
+
log_error_and_throw(__func__,
|
|
393
457
|
"Failed initial canary check for input_cobhan_buffer");
|
|
394
458
|
}
|
|
395
459
|
char *output_canary_ptr = get_canary_ptr(output_cobhan_buffer);
|
|
396
460
|
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
397
|
-
log_error_and_throw(
|
|
461
|
+
log_error_and_throw(__func__,
|
|
398
462
|
"Failed initial canary check for output_cobhan_buffer");
|
|
399
463
|
}
|
|
400
464
|
|
|
401
465
|
if (unlikely(verbose_flag)) {
|
|
402
|
-
debug_log(
|
|
466
|
+
debug_log(__func__, "Calling asherah-cobhan DecryptFromJson");
|
|
403
467
|
}
|
|
404
468
|
|
|
405
469
|
// extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void*
|
|
@@ -408,34 +472,30 @@ Napi::String decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
408
472
|
input_cobhan_buffer, output_cobhan_buffer);
|
|
409
473
|
|
|
410
474
|
if (unlikely(verbose_flag)) {
|
|
411
|
-
debug_log(
|
|
475
|
+
debug_log(__func__, "Returned from asherah-cobhan DecryptFromJson");
|
|
412
476
|
}
|
|
413
477
|
|
|
414
478
|
if (unlikely(!check_canary_ptr(partition_id_canary_ptr))) {
|
|
415
|
-
log_error_and_throw(
|
|
416
|
-
"encrypt_to_json",
|
|
479
|
+
log_error_and_throw(__func__,
|
|
417
480
|
"Failed post-call canary check for partition_id_cobhan_buffer");
|
|
418
481
|
}
|
|
419
482
|
if (unlikely(!check_canary_ptr(input_canary_ptr))) {
|
|
420
|
-
log_error_and_throw(
|
|
421
|
-
"encrypt_to_json",
|
|
483
|
+
log_error_and_throw(__func__,
|
|
422
484
|
"Failed post-call canary check for input_cobhan_buffer");
|
|
423
485
|
}
|
|
424
486
|
if (unlikely(!check_canary_ptr(output_canary_ptr))) {
|
|
425
|
-
log_error_and_throw(
|
|
426
|
-
"encrypt_to_json",
|
|
487
|
+
log_error_and_throw(__func__,
|
|
427
488
|
"Failed post-call canary check for output_cobhan_buffer");
|
|
428
489
|
}
|
|
429
490
|
|
|
430
491
|
if (unlikely(result < 0)) {
|
|
431
|
-
|
|
432
|
-
log_error_and_throw("decrypt_string", std::to_string(result));
|
|
492
|
+
log_error_and_throw(__func__, asherah_cobhan_error_to_string(result));
|
|
433
493
|
}
|
|
434
494
|
|
|
435
495
|
Napi::String output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
436
496
|
|
|
437
497
|
if (unlikely(verbose_flag)) {
|
|
438
|
-
debug_log(
|
|
498
|
+
debug_log(__func__, "finished");
|
|
439
499
|
}
|
|
440
500
|
|
|
441
501
|
return output;
|
|
@@ -445,20 +505,20 @@ void shutdown(const Napi::CallbackInfo &info) {
|
|
|
445
505
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
446
506
|
|
|
447
507
|
if (unlikely(verbose_flag)) {
|
|
448
|
-
debug_log(
|
|
508
|
+
debug_log(__func__, "called");
|
|
449
509
|
}
|
|
450
510
|
|
|
451
511
|
setup_state = 0;
|
|
452
512
|
|
|
453
513
|
if (unlikely(verbose_flag)) {
|
|
454
|
-
debug_log(
|
|
514
|
+
debug_log(__func__, "Calling asherah-cobhan Shutdown");
|
|
455
515
|
}
|
|
456
516
|
|
|
457
517
|
// extern void Shutdown();
|
|
458
518
|
Shutdown();
|
|
459
519
|
|
|
460
520
|
if (unlikely(verbose_flag)) {
|
|
461
|
-
debug_log(
|
|
521
|
+
debug_log(__func__, "Returned from asherah-cobhan Shutdown");
|
|
462
522
|
}
|
|
463
523
|
}
|
|
464
524
|
|
|
@@ -466,28 +526,28 @@ void set_max_stack_alloc_item_size(const Napi::CallbackInfo &info) {
|
|
|
466
526
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
467
527
|
|
|
468
528
|
if (unlikely(verbose_flag)) {
|
|
469
|
-
debug_log(
|
|
529
|
+
debug_log(__func__, "called");
|
|
470
530
|
}
|
|
471
531
|
|
|
472
532
|
if (unlikely(info.Length() < 1)) {
|
|
473
|
-
log_error_and_throw(
|
|
533
|
+
log_error_and_throw(__func__,
|
|
474
534
|
"Wrong number of arguments");
|
|
475
535
|
}
|
|
476
536
|
|
|
477
537
|
Napi::Number item_size = info[0].ToNumber();
|
|
478
538
|
|
|
479
|
-
|
|
539
|
+
maximum_stack_alloc_size = (size_t)item_size.Int32Value();
|
|
480
540
|
}
|
|
481
541
|
|
|
482
542
|
void set_safety_padding_overhead(const Napi::CallbackInfo &info) {
|
|
483
543
|
std::lock_guard<std::mutex> lock(asherah_lock);
|
|
484
544
|
|
|
485
545
|
if (unlikely(verbose_flag)) {
|
|
486
|
-
debug_log(
|
|
546
|
+
debug_log(__func__, "called");
|
|
487
547
|
}
|
|
488
548
|
|
|
489
549
|
if (unlikely(info.Length() < 1)) {
|
|
490
|
-
log_error_and_throw(
|
|
550
|
+
log_error_and_throw(__func__,
|
|
491
551
|
"Wrong number of arguments");
|
|
492
552
|
}
|
|
493
553
|
|
package/src/cobhan.h
CHANGED
|
@@ -37,7 +37,7 @@ calculate_cobhan_buffer_allocation_size(size_t data_len_bytes) {
|
|
|
37
37
|
__attribute__((always_inline)) inline void
|
|
38
38
|
configure_cbuffer(char *cobhan_buffer, size_t length) {
|
|
39
39
|
if (unlikely(verbose_flag)) {
|
|
40
|
-
debug_log(
|
|
40
|
+
debug_log(__func__, "configure_cbuffer(" +
|
|
41
41
|
format_ptr(cobhan_buffer) + ", " +
|
|
42
42
|
std::to_string(length) + ")");
|
|
43
43
|
}
|
|
@@ -48,22 +48,9 @@ configure_cbuffer(char *cobhan_buffer, size_t length) {
|
|
|
48
48
|
|
|
49
49
|
// Write canary values
|
|
50
50
|
char *data_ptr = cbuffer_data_ptr(cobhan_buffer);
|
|
51
|
-
#ifdef LOG_CANARY_WRITES
|
|
52
|
-
if (unlikely(verbose_flag)) {
|
|
53
|
-
debug_log("configure_cbuffer",
|
|
54
|
-
"Writing first canary at " + format_ptr(data_ptr + length + 1));
|
|
55
|
-
}
|
|
56
|
-
#endif
|
|
57
51
|
|
|
58
52
|
// First canary value is a int32_t 0 which gives us four NULLs
|
|
59
53
|
*((int32_t *)(data_ptr + length + 1)) = 0;
|
|
60
|
-
#ifdef LOG_CANARY_WRITES
|
|
61
|
-
if (unlikely(verbose_flag)) {
|
|
62
|
-
debug_log("configure_cbuffer",
|
|
63
|
-
"Writing second canary at " +
|
|
64
|
-
format_ptr(data_ptr + length + 1 + sizeof(int32_t)));
|
|
65
|
-
}
|
|
66
|
-
#endif
|
|
67
54
|
|
|
68
55
|
// Second canary value is a int32_t 0xdeadbeef
|
|
69
56
|
*((int32_t *)(data_ptr + length + 1 + sizeof(int32_t))) = canary_constant;
|
|
@@ -80,7 +67,7 @@ __attribute__((always_inline)) inline bool check_canary_ptr(char *canary_ptr) {
|
|
|
80
67
|
if (zero_value != 0) {
|
|
81
68
|
std::string error_msg =
|
|
82
69
|
"Canary check failed: " + std::to_string(zero_value) + " != 0";
|
|
83
|
-
error_log(
|
|
70
|
+
error_log(__func__, error_msg);
|
|
84
71
|
return false;
|
|
85
72
|
}
|
|
86
73
|
int32_t canary_value = *((int32_t *)(canary_ptr + sizeof(int32_t)));
|
|
@@ -88,7 +75,7 @@ __attribute__((always_inline)) inline bool check_canary_ptr(char *canary_ptr) {
|
|
|
88
75
|
std::string error_msg =
|
|
89
76
|
"Canary check failed: " + std::to_string(canary_value) +
|
|
90
77
|
" != " + std::to_string(canary_constant);
|
|
91
|
-
error_log(
|
|
78
|
+
error_log(__func__, error_msg);
|
|
92
79
|
return false;
|
|
93
80
|
}
|
|
94
81
|
return true;
|
|
@@ -98,12 +85,10 @@ __attribute__((always_inline)) inline std::unique_ptr<char[]>
|
|
|
98
85
|
heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
99
86
|
size_t cobhan_buffer_allocation_size =
|
|
100
87
|
calculate_cobhan_buffer_allocation_size(size_bytes);
|
|
88
|
+
|
|
101
89
|
if (unlikely(verbose_flag)) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
") (heap) cobhan_buffer_allocation_size: " +
|
|
105
|
-
std::to_string(cobhan_buffer_allocation_size) + " for " + variable_name;
|
|
106
|
-
debug_log("allocate_cbuffer", log_msg);
|
|
90
|
+
debug_log_new(__func__, variable_name,
|
|
91
|
+
cobhan_buffer_allocation_size);
|
|
107
92
|
}
|
|
108
93
|
|
|
109
94
|
char *cobhan_buffer = new (std::nothrow) char[cobhan_buffer_allocation_size];
|
|
@@ -111,7 +96,7 @@ heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
|
111
96
|
std::string error_msg = "new[" +
|
|
112
97
|
std::to_string(cobhan_buffer_allocation_size) +
|
|
113
98
|
"] returned null";
|
|
114
|
-
error_log(
|
|
99
|
+
error_log(__func__, error_msg);
|
|
115
100
|
return nullptr;
|
|
116
101
|
}
|
|
117
102
|
std::unique_ptr<char[]> cobhan_buffer_unique_ptr(cobhan_buffer);
|
|
@@ -120,7 +105,7 @@ heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
|
120
105
|
}
|
|
121
106
|
|
|
122
107
|
#define ALLOCATE_CBUFFER_UNIQUE_PTR(cobhan_buffer, buffer_size, unique_ptr, \
|
|
123
|
-
function_name)
|
|
108
|
+
max_stack_alloc_size, function_name) \
|
|
124
109
|
do { \
|
|
125
110
|
if (buffer_size < max_stack_alloc_size) { \
|
|
126
111
|
/* If the buffer is small enough, allocate it on the stack */ \
|
|
@@ -142,9 +127,11 @@ heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
|
142
127
|
} \
|
|
143
128
|
} while (0);
|
|
144
129
|
|
|
145
|
-
#define ALLOCATE_CBUFFER(cobhan_buffer, buffer_size,
|
|
130
|
+
#define ALLOCATE_CBUFFER(cobhan_buffer, buffer_size, max_stack_alloc_size, \
|
|
131
|
+
function_name) \
|
|
146
132
|
std::unique_ptr<char[]> cobhan_buffer##_unique_ptr; \
|
|
147
133
|
ALLOCATE_CBUFFER_UNIQUE_PTR(cobhan_buffer, buffer_size, \
|
|
148
|
-
cobhan_buffer##_unique_ptr,
|
|
134
|
+
cobhan_buffer##_unique_ptr, \
|
|
135
|
+
max_stack_alloc_size, function_name);
|
|
149
136
|
|
|
150
137
|
#endif
|
|
@@ -6,12 +6,6 @@
|
|
|
6
6
|
#include <napi.h>
|
|
7
7
|
#include <string>
|
|
8
8
|
|
|
9
|
-
extern size_t est_intermediate_key_overhead;
|
|
10
|
-
|
|
11
|
-
const size_t est_encryption_overhead = 48;
|
|
12
|
-
const size_t est_envelope_overhead = 185;
|
|
13
|
-
const double base64_overhead = 1.34;
|
|
14
|
-
|
|
15
9
|
std::string napi_status_to_string(napi_status status) {
|
|
16
10
|
switch (status) {
|
|
17
11
|
case napi_ok:
|
|
@@ -63,28 +57,6 @@ std::string napi_status_to_string(napi_status status) {
|
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
59
|
|
|
66
|
-
__attribute__((always_inline)) inline size_t
|
|
67
|
-
estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
68
|
-
size_t partition_byte_len) {
|
|
69
|
-
// Add one rather than using std::ceil to round up
|
|
70
|
-
double est_data_byte_len =
|
|
71
|
-
(double(data_byte_len + est_encryption_overhead) * base64_overhead) + 1;
|
|
72
|
-
|
|
73
|
-
size_t asherah_output_size_bytes =
|
|
74
|
-
size_t(est_envelope_overhead + est_intermediate_key_overhead +
|
|
75
|
-
partition_byte_len + est_data_byte_len);
|
|
76
|
-
if (unlikely(verbose_flag)) {
|
|
77
|
-
std::string log_msg =
|
|
78
|
-
"estimate_asherah_output_size(" + std::to_string(data_byte_len) + ", " +
|
|
79
|
-
std::to_string(partition_byte_len) +
|
|
80
|
-
") est_data_byte_len: " + std::to_string(est_data_byte_len) +
|
|
81
|
-
" asherah_output_size_bytes: " +
|
|
82
|
-
std::to_string(asherah_output_size_bytes);
|
|
83
|
-
debug_log("estimate_asherah_output_size", log_msg);
|
|
84
|
-
}
|
|
85
|
-
return asherah_output_size_bytes;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
60
|
__attribute__((always_inline)) inline size_t
|
|
89
61
|
nstring_utf8_byte_length(Napi::Env &env, Napi::String &str) {
|
|
90
62
|
napi_status status;
|
|
@@ -92,7 +64,7 @@ nstring_utf8_byte_length(Napi::Env &env, Napi::String &str) {
|
|
|
92
64
|
|
|
93
65
|
status = napi_get_value_string_utf8(env, str, nullptr, 0, &utf8_length);
|
|
94
66
|
if (unlikely(status != napi_ok)) {
|
|
95
|
-
error_log(
|
|
67
|
+
error_log(__func__,
|
|
96
68
|
"napi_get_value_string_utf8 length check failed: " +
|
|
97
69
|
napi_status_to_string(status));
|
|
98
70
|
return (size_t)(-1);
|
|
@@ -104,21 +76,21 @@ nstring_utf8_byte_length(Napi::Env &env, Napi::String &str) {
|
|
|
104
76
|
__attribute__((always_inline)) inline char *
|
|
105
77
|
copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
106
78
|
size_t str_utf8_byte_length, char *cobhan_buffer,
|
|
107
|
-
size_t *byte_length
|
|
79
|
+
size_t *byte_length) {
|
|
108
80
|
|
|
109
81
|
size_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
110
82
|
if (unlikely(cobhan_buffer_size_bytes <= 0)) {
|
|
111
|
-
error_log(
|
|
83
|
+
error_log(__func__, "Invalid cobhan buffer byte length");
|
|
112
84
|
return nullptr;
|
|
113
85
|
}
|
|
114
86
|
|
|
115
87
|
if (cobhan_buffer_size_bytes < str_utf8_byte_length) {
|
|
116
|
-
error_log(
|
|
88
|
+
error_log(__func__, "String too large for cobhan buffer");
|
|
117
89
|
return nullptr;
|
|
118
90
|
}
|
|
119
91
|
|
|
120
92
|
if (unlikely(verbose_flag)) {
|
|
121
|
-
debug_log(
|
|
93
|
+
debug_log(__func__,
|
|
122
94
|
"Copying " + std::to_string(str_utf8_byte_length) + " bytes to " +
|
|
123
95
|
format_ptr(cbuffer_data_ptr(cobhan_buffer)) + " - " +
|
|
124
96
|
format_ptr((cbuffer_data_ptr(cobhan_buffer) +
|
|
@@ -133,14 +105,14 @@ copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
|
133
105
|
status = napi_get_value_string_utf8(env, str, cbuffer_data_ptr(cobhan_buffer),
|
|
134
106
|
str_utf8_byte_length + 1, &copied_bytes);
|
|
135
107
|
if (unlikely(status != napi_ok)) {
|
|
136
|
-
error_log(
|
|
108
|
+
error_log(__func__,
|
|
137
109
|
"Napi utf8 string conversion failure: " +
|
|
138
110
|
napi_status_to_string(status));
|
|
139
111
|
return nullptr;
|
|
140
112
|
}
|
|
141
113
|
|
|
142
114
|
if (unlikely(copied_bytes != str_utf8_byte_length)) {
|
|
143
|
-
error_log(
|
|
115
|
+
error_log(__func__,
|
|
144
116
|
"Did not copy expected number of bytes " +
|
|
145
117
|
std::to_string(str_utf8_byte_length) + " copied " +
|
|
146
118
|
std::to_string(copied_bytes));
|
|
@@ -149,8 +121,7 @@ copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
|
149
121
|
|
|
150
122
|
configure_cbuffer(cobhan_buffer, copied_bytes);
|
|
151
123
|
|
|
152
|
-
|
|
153
|
-
*byte_length = copied_bytes;
|
|
124
|
+
*byte_length = copied_bytes;
|
|
154
125
|
return cobhan_buffer;
|
|
155
126
|
}
|
|
156
127
|
|
|
@@ -160,7 +131,7 @@ cbuffer_to_nstring(Napi::Env &env, char *cobhan_buffer) {
|
|
|
160
131
|
|
|
161
132
|
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
162
133
|
if (cobhan_buffer_size_bytes <= 0) {
|
|
163
|
-
log_error_and_throw(
|
|
134
|
+
log_error_and_throw(__func__,
|
|
164
135
|
"Invalid cobhan buffer byte length");
|
|
165
136
|
}
|
|
166
137
|
|
|
@@ -169,7 +140,7 @@ cbuffer_to_nstring(Napi::Env &env, char *cobhan_buffer) {
|
|
|
169
140
|
env, cbuffer_data_ptr(cobhan_buffer), cobhan_buffer_size_bytes, &output);
|
|
170
141
|
|
|
171
142
|
if (unlikely(status != napi_ok)) {
|
|
172
|
-
log_error_and_throw(
|
|
143
|
+
log_error_and_throw(__func__,
|
|
173
144
|
"napi_create_string_utf8 failed: " +
|
|
174
145
|
napi_status_to_string(status));
|
|
175
146
|
}
|
|
@@ -181,18 +152,7 @@ __attribute__((always_inline)) inline Napi::Buffer<unsigned char>
|
|
|
181
152
|
cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
182
153
|
int32_t cobhan_buffer_byte_length = cbuffer_byte_length(cobhan_buffer);
|
|
183
154
|
if (unlikely(cobhan_buffer_byte_length <= 0)) {
|
|
184
|
-
log_error_and_throw(
|
|
185
|
-
"Invalid cobhan buffer byte length");
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (unlikely(verbose_flag)) {
|
|
189
|
-
debug_log("cbuffer_to_nbuffer",
|
|
190
|
-
"cbuffer_byte_length: " +
|
|
191
|
-
std::to_string(cobhan_buffer_byte_length));
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (unlikely(cobhan_buffer_byte_length <= 0)) {
|
|
195
|
-
log_error_and_throw("cbuffer_to_nbuffer",
|
|
155
|
+
log_error_and_throw(__func__,
|
|
196
156
|
"Invalid cobhan buffer byte length");
|
|
197
157
|
}
|
|
198
158
|
|
|
@@ -200,9 +160,9 @@ cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
|
200
160
|
env, (const unsigned char *)cbuffer_data_ptr(cobhan_buffer),
|
|
201
161
|
cobhan_buffer_byte_length);
|
|
202
162
|
|
|
203
|
-
if (unlikely(
|
|
204
|
-
|
|
205
|
-
|
|
163
|
+
if (unlikely(nbuffer.ByteLength() != (size_t)cobhan_buffer_byte_length)) {
|
|
164
|
+
log_error_and_throw(__func__,
|
|
165
|
+
"Failed to copy cobhan buffer to napi buffer");
|
|
206
166
|
}
|
|
207
167
|
|
|
208
168
|
return nbuffer;
|
|
@@ -214,16 +174,25 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
214
174
|
|
|
215
175
|
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
216
176
|
if (unlikely(cobhan_buffer_size_bytes <= 0)) {
|
|
217
|
-
error_log(
|
|
177
|
+
error_log(__func__, "Invalid cobhan buffer byte length");
|
|
218
178
|
return nullptr;
|
|
219
179
|
}
|
|
220
180
|
|
|
221
181
|
size_t nbuffer_byte_length = nbuffer.ByteLength();
|
|
222
182
|
if (nbuffer_byte_length > INT32_MAX ||
|
|
223
183
|
cobhan_buffer_size_bytes < (int32_t)nbuffer_byte_length) {
|
|
224
|
-
error_log(
|
|
184
|
+
error_log(__func__, "Buffer too large for cobhan buffer");
|
|
225
185
|
return nullptr;
|
|
226
186
|
}
|
|
187
|
+
|
|
188
|
+
if (unlikely(verbose_flag)) {
|
|
189
|
+
debug_log(__func__,
|
|
190
|
+
"Copying " + std::to_string(nbuffer_byte_length) + " bytes to " +
|
|
191
|
+
format_ptr(cbuffer_data_ptr(cobhan_buffer)) + " - " +
|
|
192
|
+
format_ptr((cbuffer_data_ptr(cobhan_buffer) +
|
|
193
|
+
nbuffer_byte_length)));
|
|
194
|
+
}
|
|
195
|
+
|
|
227
196
|
memcpy(cbuffer_data_ptr(cobhan_buffer), nbuffer.Data(), nbuffer_byte_length);
|
|
228
197
|
configure_cbuffer(cobhan_buffer, nbuffer_byte_length);
|
|
229
198
|
return cobhan_buffer;
|
|
@@ -232,7 +201,7 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
232
201
|
// These are macros due to the use of alloca()
|
|
233
202
|
|
|
234
203
|
#define NAPI_STRING_TO_CBUFFER(env, napi_string, cobhan_buffer, bytes_copied, \
|
|
235
|
-
function_name)
|
|
204
|
+
max_stack_alloc_size, function_name) \
|
|
236
205
|
std::unique_ptr<char[]> napi_string##_unique_ptr; \
|
|
237
206
|
do { \
|
|
238
207
|
/* Determine size */ \
|
|
@@ -247,7 +216,8 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
247
216
|
} \
|
|
248
217
|
/* Allocate */ \
|
|
249
218
|
ALLOCATE_CBUFFER_UNIQUE_PTR(cobhan_buffer, napi_string##_utf8_byte_length, \
|
|
250
|
-
napi_string##_unique_ptr,
|
|
219
|
+
napi_string##_unique_ptr, \
|
|
220
|
+
max_stack_alloc_size, function_name); \
|
|
251
221
|
/* Copy */ \
|
|
252
222
|
cobhan_buffer = copy_nstring_to_cbuffer(env, napi_string, \
|
|
253
223
|
napi_string##_utf8_byte_length, \
|
|
@@ -259,7 +229,7 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
259
229
|
} while (0);
|
|
260
230
|
|
|
261
231
|
#define NAPI_BUFFER_TO_CBUFFER(env, napi_buffer, cobhan_buffer, bytes_copied, \
|
|
262
|
-
function_name)
|
|
232
|
+
max_stack_alloc_size, function_name) \
|
|
263
233
|
std::unique_ptr<char[]> napi_buffer##_unique_ptr; \
|
|
264
234
|
do { \
|
|
265
235
|
/* Determine size */ \
|
|
@@ -269,7 +239,8 @@ copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
|
269
239
|
} \
|
|
270
240
|
/* Allocate */ \
|
|
271
241
|
ALLOCATE_CBUFFER_UNIQUE_PTR(cobhan_buffer, napi_buffer##_byte_length, \
|
|
272
|
-
napi_buffer##_unique_ptr,
|
|
242
|
+
napi_buffer##_unique_ptr, \
|
|
243
|
+
max_stack_alloc_size, function_name); \
|
|
273
244
|
/* Copy */ \
|
|
274
245
|
cobhan_buffer = copy_nbuffer_to_cbuffer(env, napi_buffer, cobhan_buffer); \
|
|
275
246
|
if (unlikely(cobhan_buffer == nullptr)) { \
|
package/src/logging.h
CHANGED
|
@@ -38,6 +38,16 @@ debug_log_alloca(const char *function_name, const char *variable_name,
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
__attribute__((always_inline)) inline void
|
|
42
|
+
debug_log_new(const char *function_name, const char *variable_name,
|
|
43
|
+
size_t length) {
|
|
44
|
+
if (unlikely(verbose_flag)) {
|
|
45
|
+
std::cerr << "asherah-node: [DEBUG] " << function_name << ": Calling new["
|
|
46
|
+
<< length << "] (heap) for " << variable_name << std::endl
|
|
47
|
+
<< std::flush;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
__attribute__((always_inline)) inline void error_log(const char *function_name,
|
|
42
52
|
const char *message) {
|
|
43
53
|
if (unlikely(verbose_flag)) {
|