asherah 1.3.12 → 1.3.14
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 +6 -1
- package/package.json +8 -3
- package/src/asherah.cc +145 -329
- package/src/cobhan_napi_interop.cc +3 -0
- package/src/cobhan_napi_interop.h +285 -0
- package/src/hints.h +7 -0
- package/src/logging.cc +2 -0
- package/src/logging.h +38 -0
package/binding.gyp
CHANGED
|
@@ -18,7 +18,12 @@
|
|
|
18
18
|
'defines': [ 'NAPI_CPP_EXCEPTIONS', 'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS' ],
|
|
19
19
|
'sources': [
|
|
20
20
|
'lib/libasherah.h',
|
|
21
|
-
'src/asherah.cc'
|
|
21
|
+
'src/asherah.cc',
|
|
22
|
+
'src/logging.cc',
|
|
23
|
+
'src/logging.h',
|
|
24
|
+
'src/cobhan_napi_interop.cc',
|
|
25
|
+
'src/cobhan_napi_interop.h',
|
|
26
|
+
'src/hints.h'
|
|
22
27
|
],
|
|
23
28
|
'libraries': [ '../lib/libasherah.a' ]
|
|
24
29
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asherah",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.14",
|
|
4
4
|
"description": "Asherah envelope encryption and key rotation library",
|
|
5
5
|
"exports": {
|
|
6
6
|
"node-addons": "./dist/asherah.node"
|
|
7
7
|
},
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/
|
|
10
|
+
"url": "https://github.com/godaddy/asherah-node.git"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"preinstall": "scripts/download-libraries.sh",
|
|
14
|
-
"install": "
|
|
14
|
+
"install": "scripts/build.sh",
|
|
15
15
|
"test:mocha": "mocha",
|
|
16
16
|
"test": "nyc npm run test:mocha",
|
|
17
17
|
"posttest": "npm run lint",
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"files": [
|
|
24
24
|
"binding.gyp",
|
|
25
25
|
"src/asherah.cc",
|
|
26
|
+
"src/hints.h",
|
|
27
|
+
"src/logging.h",
|
|
28
|
+
"src/logging.cc",
|
|
29
|
+
"src/cobhan_napi_interop.h",
|
|
30
|
+
"src/cobhan_napi_interop.cc",
|
|
26
31
|
"src/asherah.d.ts",
|
|
27
32
|
"scripts/download-libraries.sh",
|
|
28
33
|
"SHA256SUMS",
|
package/src/asherah.cc
CHANGED
|
@@ -1,242 +1,13 @@
|
|
|
1
1
|
#include "../lib/libasherah.h"
|
|
2
2
|
#include <iostream>
|
|
3
3
|
#define NODE_ADDON_API_DISABLE_DEPRECATED
|
|
4
|
+
#include "cobhan_napi_interop.h"
|
|
5
|
+
#include "hints.h"
|
|
6
|
+
#include "logging.h"
|
|
4
7
|
#include <napi.h>
|
|
5
8
|
|
|
6
|
-
#define unlikely(expr) __builtin_expect(!!(expr), 0)
|
|
7
|
-
#define likely(expr) __builtin_expect(!!(expr), 1)
|
|
8
|
-
|
|
9
|
-
const size_t cobhan_header_size_bytes = 64 / 8;
|
|
10
|
-
const size_t est_encryption_overhead = 48;
|
|
11
|
-
const size_t est_envelope_overhead = 185;
|
|
12
|
-
const double base64_overhead = 1.34;
|
|
13
|
-
|
|
14
|
-
size_t est_intermediate_key_overhead = 0;
|
|
15
|
-
size_t safety_padding_bytes = 0;
|
|
16
9
|
size_t max_stack_alloc_size = 2048;
|
|
17
|
-
|
|
18
10
|
int32_t setup_state = 0;
|
|
19
|
-
int32_t verbose_flag = 0;
|
|
20
|
-
|
|
21
|
-
__attribute__((always_inline)) inline void debug_log(const char *function_name,
|
|
22
|
-
std::string message) {
|
|
23
|
-
if (unlikely(verbose_flag)) {
|
|
24
|
-
std::cerr << "asherah-node: [DEBUG] " << function_name << ": " << message
|
|
25
|
-
<< std::endl
|
|
26
|
-
<< std::flush;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
__attribute__((always_inline)) inline void
|
|
31
|
-
debug_log_alloca(const char *function_name, const char *variable_name,
|
|
32
|
-
size_t length) {
|
|
33
|
-
if (unlikely(verbose_flag)) {
|
|
34
|
-
std::cerr << "asherah-node: [DEBUG] " << function_name
|
|
35
|
-
<< ": Calling alloca(" << length << ") (stack) for "
|
|
36
|
-
<< variable_name << std::endl
|
|
37
|
-
<< std::flush;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
__attribute__((always_inline)) inline void error_log(const char *function_name,
|
|
42
|
-
std::string message) {
|
|
43
|
-
if (unlikely(verbose_flag)) {
|
|
44
|
-
std::cerr << "asherah-node: [ERROR] " << function_name << ": " << message
|
|
45
|
-
<< std::endl
|
|
46
|
-
<< std::flush;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
std::string napi_status_to_string(napi_status status) {
|
|
51
|
-
switch (status) {
|
|
52
|
-
case napi_ok:
|
|
53
|
-
return "napi_ok";
|
|
54
|
-
case napi_invalid_arg:
|
|
55
|
-
return "napi_invalid_arg";
|
|
56
|
-
case napi_object_expected:
|
|
57
|
-
return "napi_object_expected";
|
|
58
|
-
case napi_string_expected:
|
|
59
|
-
return "napi_string_expected";
|
|
60
|
-
case napi_name_expected:
|
|
61
|
-
return "napi_name_expected";
|
|
62
|
-
case napi_function_expected:
|
|
63
|
-
return "napi_function_expected";
|
|
64
|
-
case napi_number_expected:
|
|
65
|
-
return "napi_number_expected";
|
|
66
|
-
case napi_boolean_expected:
|
|
67
|
-
return "napi_boolean_expected";
|
|
68
|
-
case napi_array_expected:
|
|
69
|
-
return "napi_array_expected";
|
|
70
|
-
case napi_generic_failure:
|
|
71
|
-
return "napi_generic_failure";
|
|
72
|
-
case napi_pending_exception:
|
|
73
|
-
return "napi_pending_exception";
|
|
74
|
-
case napi_cancelled:
|
|
75
|
-
return "napi_cancelled";
|
|
76
|
-
case napi_escape_called_twice:
|
|
77
|
-
return "napi_escape_called_twice";
|
|
78
|
-
case napi_handle_scope_mismatch:
|
|
79
|
-
return "napi_handle_scope_mismatch";
|
|
80
|
-
case napi_callback_scope_mismatch:
|
|
81
|
-
return "napi_callback_scope_mismatch";
|
|
82
|
-
case napi_queue_full:
|
|
83
|
-
return "napi_queue_full";
|
|
84
|
-
case napi_closing:
|
|
85
|
-
return "napi_closing";
|
|
86
|
-
case napi_bigint_expected:
|
|
87
|
-
return "napi_bigint_expected";
|
|
88
|
-
case napi_date_expected:
|
|
89
|
-
return "napi_date_expected";
|
|
90
|
-
case napi_arraybuffer_expected:
|
|
91
|
-
return "napi_arraybuffer_expected";
|
|
92
|
-
case napi_detachable_arraybuffer_expected:
|
|
93
|
-
return "napi_detachable_arraybuffer_expected";
|
|
94
|
-
case napi_would_deadlock:
|
|
95
|
-
return "napi_would_deadlock";
|
|
96
|
-
default:
|
|
97
|
-
return "Unknown napi_status";
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
__attribute__((always_inline)) inline Napi::Value
|
|
102
|
-
LogErrorAndThrow(Napi::Env &env, const char *function_name,
|
|
103
|
-
std::string error_msg) {
|
|
104
|
-
error_log(function_name, error_msg);
|
|
105
|
-
Napi::Error::New(env, function_name + (": " + error_msg))
|
|
106
|
-
.ThrowAsJavaScriptException();
|
|
107
|
-
return env.Null();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
__attribute__((always_inline)) inline size_t
|
|
111
|
-
calculate_cobhan_buffer_size_bytes(size_t data_len_bytes) {
|
|
112
|
-
return data_len_bytes + cobhan_header_size_bytes + safety_padding_bytes +
|
|
113
|
-
1; // Add one for possible NULL delimiter due to Node string functions
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
__attribute__((always_inline)) inline size_t
|
|
117
|
-
estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
118
|
-
size_t partition_byte_len) {
|
|
119
|
-
// Add one rather than using std::ceil to round up
|
|
120
|
-
double est_data_byte_len =
|
|
121
|
-
(double(data_byte_len + est_encryption_overhead) * base64_overhead) + 1;
|
|
122
|
-
|
|
123
|
-
size_t asherah_output_size_bytes =
|
|
124
|
-
size_t(est_envelope_overhead + est_intermediate_key_overhead +
|
|
125
|
-
partition_byte_len + est_data_byte_len + safety_padding_bytes);
|
|
126
|
-
if (unlikely(verbose_flag)) {
|
|
127
|
-
std::string log_msg =
|
|
128
|
-
"estimate_asherah_output_size(" + std::to_string(data_byte_len) + ", " +
|
|
129
|
-
std::to_string(partition_byte_len) +
|
|
130
|
-
") est_data_byte_len: " + std::to_string(est_data_byte_len) +
|
|
131
|
-
" asherah_output_size_bytes: " +
|
|
132
|
-
std::to_string(asherah_output_size_bytes);
|
|
133
|
-
debug_log("estimate_asherah_output_size", log_msg);
|
|
134
|
-
}
|
|
135
|
-
return asherah_output_size_bytes;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
__attribute__((always_inline)) inline void configure_cbuffer(char *buffer,
|
|
139
|
-
size_t length) {
|
|
140
|
-
*((int32_t *)buffer) = length;
|
|
141
|
-
// Reserved for future use
|
|
142
|
-
*((int32_t *)(buffer + sizeof(int32_t))) = 0;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
__attribute__((always_inline)) inline std::unique_ptr<char[]>
|
|
146
|
-
heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
147
|
-
size_t cobhan_buffer_size_bytes =
|
|
148
|
-
calculate_cobhan_buffer_size_bytes(size_bytes);
|
|
149
|
-
if (unlikely(verbose_flag)) {
|
|
150
|
-
std::string log_msg =
|
|
151
|
-
"heap_allocate_cbuffer(" + std::to_string(size_bytes) +
|
|
152
|
-
") (heap) cobhan_buffer_size_bytes: " +
|
|
153
|
-
std::to_string(cobhan_buffer_size_bytes) + " for " + variable_name;
|
|
154
|
-
debug_log("allocate_cbuffer", log_msg);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
char *cobhan_buffer = new (std::nothrow) char[cobhan_buffer_size_bytes];
|
|
158
|
-
if (unlikely(cobhan_buffer == nullptr)) {
|
|
159
|
-
std::string error_msg =
|
|
160
|
-
"new[" + std::to_string(cobhan_buffer_size_bytes) + " returned null";
|
|
161
|
-
error_log("allocate_cbuffer", error_msg);
|
|
162
|
-
return nullptr;
|
|
163
|
-
}
|
|
164
|
-
std::unique_ptr<char[]> cobhan_buffer_unique_ptr(cobhan_buffer);
|
|
165
|
-
configure_cbuffer(cobhan_buffer, size_bytes + safety_padding_bytes);
|
|
166
|
-
return cobhan_buffer_unique_ptr;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
__attribute__((always_inline)) inline Napi::Value
|
|
170
|
-
cbuffer_to_nstring(Napi::Env &env, char *cobhan_buffer) {
|
|
171
|
-
napi_value output;
|
|
172
|
-
|
|
173
|
-
// Using C function because it allows length delimited input
|
|
174
|
-
napi_status status = napi_create_string_utf8(
|
|
175
|
-
env, ((const char *)cobhan_buffer) + cobhan_header_size_bytes,
|
|
176
|
-
*((int *)cobhan_buffer), &output);
|
|
177
|
-
|
|
178
|
-
if (unlikely(status != napi_ok)) {
|
|
179
|
-
return LogErrorAndThrow(env, "cbuffer_to_nstring",
|
|
180
|
-
"napi_create_string_utf8 failed: " +
|
|
181
|
-
napi_status_to_string(status));
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return Napi::String(env, output);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
__attribute__((always_inline)) inline size_t
|
|
188
|
-
nstring_utf8_byte_length(Napi::Env &env, Napi::String &str) {
|
|
189
|
-
napi_status status;
|
|
190
|
-
size_t utf8_length;
|
|
191
|
-
|
|
192
|
-
status = napi_get_value_string_utf8(env, str, nullptr, 0, &utf8_length);
|
|
193
|
-
if (unlikely(status != napi_ok)) {
|
|
194
|
-
LogErrorAndThrow(env, "nstring_utf8_length",
|
|
195
|
-
"napi_get_value_string_utf8 length check failed: " +
|
|
196
|
-
napi_status_to_string(status));
|
|
197
|
-
return (size_t)(-1);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return utf8_length;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
__attribute__((always_inline)) inline char *
|
|
204
|
-
copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
205
|
-
size_t utf8_byte_length, char *cobhan_buffer,
|
|
206
|
-
size_t *byte_length = nullptr) {
|
|
207
|
-
napi_status status;
|
|
208
|
-
size_t copied_bytes;
|
|
209
|
-
status = napi_get_value_string_utf8(env, str,
|
|
210
|
-
cobhan_buffer + cobhan_header_size_bytes,
|
|
211
|
-
utf8_byte_length + 1, &copied_bytes);
|
|
212
|
-
if (unlikely(status != napi_ok)) {
|
|
213
|
-
LogErrorAndThrow(env, "copy_nstring_to_cbuffer",
|
|
214
|
-
"Napi utf8 string conversion failure: " +
|
|
215
|
-
napi_status_to_string(status));
|
|
216
|
-
return nullptr;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (unlikely(copied_bytes != utf8_byte_length)) {
|
|
220
|
-
LogErrorAndThrow(env, "copy_nstring_to_cbuffer",
|
|
221
|
-
"Did not copy expected number of bytes " +
|
|
222
|
-
std::to_string(utf8_byte_length) + " copied " +
|
|
223
|
-
std::to_string(copied_bytes));
|
|
224
|
-
return nullptr;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
configure_cbuffer(cobhan_buffer, copied_bytes);
|
|
228
|
-
|
|
229
|
-
if (byte_length != nullptr)
|
|
230
|
-
*byte_length = copied_bytes;
|
|
231
|
-
return cobhan_buffer;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
__attribute__((always_inline)) inline Napi::Buffer<unsigned char>
|
|
235
|
-
cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
236
|
-
return Napi::Buffer<unsigned char>::Copy(
|
|
237
|
-
env, ((unsigned char *)cobhan_buffer) + cobhan_header_size_bytes,
|
|
238
|
-
*((int *)cobhan_buffer));
|
|
239
|
-
}
|
|
240
11
|
|
|
241
12
|
void setup(const Napi::CallbackInfo &info) {
|
|
242
13
|
Napi::Env env = info.Env();
|
|
@@ -246,12 +17,12 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
246
17
|
}
|
|
247
18
|
|
|
248
19
|
if (unlikely(setup_state == 1)) {
|
|
249
|
-
|
|
20
|
+
log_error_and_throw(env, "setup", "setup called twice");
|
|
250
21
|
return;
|
|
251
22
|
}
|
|
252
23
|
|
|
253
24
|
if (unlikely(info.Length() < 1)) {
|
|
254
|
-
|
|
25
|
+
log_error_and_throw(env, "setup", "Wrong number of arguments");
|
|
255
26
|
return;
|
|
256
27
|
}
|
|
257
28
|
|
|
@@ -267,7 +38,7 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
267
38
|
Napi::Function parse = json.Get("parse").As<Napi::Function>();
|
|
268
39
|
config_json = parse.Call(json, {config}).As<Napi::Object>();
|
|
269
40
|
} else {
|
|
270
|
-
|
|
41
|
+
log_error_and_throw(env, "setup", "Wrong argument type");
|
|
271
42
|
return;
|
|
272
43
|
}
|
|
273
44
|
|
|
@@ -290,7 +61,7 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
290
61
|
size_t config_utf8_byte_length;
|
|
291
62
|
config_utf8_byte_length = nstring_utf8_byte_length(env, config);
|
|
292
63
|
if (unlikely(config_utf8_byte_length == (size_t)(-1))) {
|
|
293
|
-
|
|
64
|
+
log_error_and_throw(env, "setup", "Failed to get config utf8 length");
|
|
294
65
|
return;
|
|
295
66
|
}
|
|
296
67
|
|
|
@@ -301,8 +72,10 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
301
72
|
// If the buffer is small enough, allocate it on the stack
|
|
302
73
|
size_t config_cobhan_buffer_size_bytes =
|
|
303
74
|
calculate_cobhan_buffer_size_bytes(config_utf8_byte_length);
|
|
304
|
-
debug_log_alloca("setup", "config_cobhan_buffer",
|
|
75
|
+
debug_log_alloca("setup", "config_cobhan_buffer",
|
|
76
|
+
config_cobhan_buffer_size_bytes);
|
|
305
77
|
config_cobhan_buffer = (char *)alloca(config_cobhan_buffer_size_bytes);
|
|
78
|
+
configure_cbuffer(config_cobhan_buffer, config_utf8_byte_length);
|
|
306
79
|
} else {
|
|
307
80
|
// Otherwise, allocate it on the heap
|
|
308
81
|
config_cobhan_buffer_unique_ptr =
|
|
@@ -310,7 +83,8 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
310
83
|
config_cobhan_buffer = config_cobhan_buffer_unique_ptr.get();
|
|
311
84
|
}
|
|
312
85
|
if (unlikely(config_cobhan_buffer == nullptr)) {
|
|
313
|
-
|
|
86
|
+
log_error_and_throw(env, "setup",
|
|
87
|
+
"Failed to allocate config cobhan buffer");
|
|
314
88
|
return;
|
|
315
89
|
}
|
|
316
90
|
|
|
@@ -320,7 +94,7 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
320
94
|
copy_nstring_to_cbuffer(env, config, config_utf8_byte_length,
|
|
321
95
|
config_cobhan_buffer, &config_copied_bytes);
|
|
322
96
|
if (unlikely(config_cobhan_buffer == nullptr)) {
|
|
323
|
-
|
|
97
|
+
log_error_and_throw(env, "setup", "Failed to copy config to cobhan buffer");
|
|
324
98
|
return;
|
|
325
99
|
}
|
|
326
100
|
|
|
@@ -337,7 +111,7 @@ void setup(const Napi::CallbackInfo &info) {
|
|
|
337
111
|
|
|
338
112
|
if (unlikely(result < 0)) {
|
|
339
113
|
// TODO: Convert this to a proper error message
|
|
340
|
-
|
|
114
|
+
log_error_and_throw(env, "setup", std::to_string(result));
|
|
341
115
|
return;
|
|
342
116
|
}
|
|
343
117
|
setup_state = 1;
|
|
@@ -364,8 +138,7 @@ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
364
138
|
debug_log_alloca("encrypt_to_json", "output_cobhan_buffer",
|
|
365
139
|
output_cobhan_buffer_size_bytes);
|
|
366
140
|
output_cobhan_buffer = (char *)alloca(output_cobhan_buffer_size_bytes);
|
|
367
|
-
configure_cbuffer(output_cobhan_buffer,
|
|
368
|
-
asherah_output_size_bytes + safety_padding_bytes);
|
|
141
|
+
configure_cbuffer(output_cobhan_buffer, asherah_output_size_bytes);
|
|
369
142
|
} else {
|
|
370
143
|
// Otherwise, allocate it on the heap
|
|
371
144
|
output_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
@@ -373,8 +146,8 @@ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
373
146
|
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
374
147
|
}
|
|
375
148
|
if (unlikely(output_cobhan_buffer == nullptr)) {
|
|
376
|
-
return
|
|
377
|
-
|
|
149
|
+
return log_error_and_throw(env, "encrypt_to_json",
|
|
150
|
+
"Failed to allocate cobhan output buffer");
|
|
378
151
|
}
|
|
379
152
|
|
|
380
153
|
if (unlikely(verbose_flag)) {
|
|
@@ -392,7 +165,7 @@ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
|
|
|
392
165
|
|
|
393
166
|
if (unlikely(result < 0)) {
|
|
394
167
|
// TODO: Convert this to a proper error message
|
|
395
|
-
return
|
|
168
|
+
return log_error_and_throw(env, "encrypt_to_json", std::to_string(result));
|
|
396
169
|
}
|
|
397
170
|
|
|
398
171
|
Napi::Value output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
@@ -407,15 +180,15 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
407
180
|
}
|
|
408
181
|
|
|
409
182
|
if (unlikely(setup_state == 0)) {
|
|
410
|
-
return
|
|
183
|
+
return log_error_and_throw(env, "encrypt", "setup() not called");
|
|
411
184
|
}
|
|
412
185
|
|
|
413
186
|
if (unlikely(info.Length() < 2)) {
|
|
414
|
-
return
|
|
187
|
+
return log_error_and_throw(env, "encrypt", "Wrong number of arguments");
|
|
415
188
|
}
|
|
416
189
|
|
|
417
190
|
if (unlikely(!info[0].IsString() || !info[1].IsBuffer())) {
|
|
418
|
-
return
|
|
191
|
+
return log_error_and_throw(env, "encrypt", "Wrong argument types");
|
|
419
192
|
}
|
|
420
193
|
|
|
421
194
|
// Determine size
|
|
@@ -423,11 +196,11 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
423
196
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
424
197
|
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
425
198
|
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
426
|
-
return
|
|
427
|
-
|
|
199
|
+
return log_error_and_throw(env, "encrypt",
|
|
200
|
+
"Failed to get partition_id utf8 length");
|
|
428
201
|
}
|
|
429
202
|
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
430
|
-
return
|
|
203
|
+
return log_error_and_throw(env, "encrypt", "partition_id is empty");
|
|
431
204
|
}
|
|
432
205
|
|
|
433
206
|
// Allocate
|
|
@@ -437,8 +210,11 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
437
210
|
// If the buffer is small enough, allocate it on the stack
|
|
438
211
|
size_t partition_id_cobhan_buffer_size_bytes =
|
|
439
212
|
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
440
|
-
debug_log_alloca("encrypt", "partition_id_cobhan_buffer",
|
|
441
|
-
|
|
213
|
+
debug_log_alloca("encrypt", "partition_id_cobhan_buffer",
|
|
214
|
+
partition_id_cobhan_buffer_size_bytes);
|
|
215
|
+
partition_id_cobhan_buffer =
|
|
216
|
+
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
217
|
+
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
442
218
|
} else {
|
|
443
219
|
// Otherwise, allocate it on the heap
|
|
444
220
|
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
@@ -446,8 +222,8 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
446
222
|
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
447
223
|
}
|
|
448
224
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
449
|
-
return
|
|
450
|
-
|
|
225
|
+
return log_error_and_throw(env, "encrypt",
|
|
226
|
+
"Failed to allocate partitionId cobhan buffer");
|
|
451
227
|
}
|
|
452
228
|
|
|
453
229
|
// Copy
|
|
@@ -456,8 +232,8 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
456
232
|
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
457
233
|
&partition_copied_bytes);
|
|
458
234
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
459
|
-
return
|
|
460
|
-
|
|
235
|
+
return log_error_and_throw(env, "encrypt",
|
|
236
|
+
"Failed to copy partitionId to cobhan buffer");
|
|
461
237
|
}
|
|
462
238
|
|
|
463
239
|
// Determine size
|
|
@@ -465,7 +241,7 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
465
241
|
info[1].As<Napi::Buffer<unsigned char>>();
|
|
466
242
|
size_t input_byte_length = input_napi_buffer.ByteLength();
|
|
467
243
|
if (unlikely(input_byte_length == 0)) {
|
|
468
|
-
return
|
|
244
|
+
return log_error_and_throw(env, "encrypt", "input is empty");
|
|
469
245
|
}
|
|
470
246
|
|
|
471
247
|
// Allocate
|
|
@@ -478,6 +254,7 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
478
254
|
debug_log_alloca("encrypt", "input_cobhan_buffer",
|
|
479
255
|
input_cobhan_buffer_size_bytes);
|
|
480
256
|
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
257
|
+
configure_cbuffer(input_cobhan_buffer, input_byte_length);
|
|
481
258
|
} else {
|
|
482
259
|
// Otherwise, allocate it on the heap
|
|
483
260
|
input_buffer_unique_ptr =
|
|
@@ -485,17 +262,27 @@ Napi::Value encrypt(const Napi::CallbackInfo &info) {
|
|
|
485
262
|
input_cobhan_buffer = input_buffer_unique_ptr.get();
|
|
486
263
|
}
|
|
487
264
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
488
|
-
return
|
|
265
|
+
return log_error_and_throw(
|
|
489
266
|
env, "encrypt", "Failed to allocate cobhan buffer for input buffer");
|
|
490
267
|
}
|
|
491
268
|
|
|
492
269
|
// Copy
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
270
|
+
input_cobhan_buffer =
|
|
271
|
+
copy_nbuffer_to_cbuffer(env, input_napi_buffer, input_cobhan_buffer);
|
|
272
|
+
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
273
|
+
return log_error_and_throw(env, "encrypt",
|
|
274
|
+
"Failed to copy input buffer to cobhan buffer");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
Napi::Value output =
|
|
278
|
+
encrypt_to_json(env, partition_copied_bytes, input_byte_length,
|
|
279
|
+
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
280
|
+
|
|
281
|
+
if (unlikely(verbose_flag)) {
|
|
282
|
+
debug_log("encrypt", "finished");
|
|
283
|
+
}
|
|
496
284
|
|
|
497
|
-
return
|
|
498
|
-
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
285
|
+
return output;
|
|
499
286
|
}
|
|
500
287
|
|
|
501
288
|
Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
@@ -506,15 +293,16 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
506
293
|
}
|
|
507
294
|
|
|
508
295
|
if (unlikely(setup_state == 0)) {
|
|
509
|
-
return
|
|
296
|
+
return log_error_and_throw(env, "encrypt_string", "setup() not called");
|
|
510
297
|
}
|
|
511
298
|
|
|
512
299
|
if (unlikely(info.Length() < 2)) {
|
|
513
|
-
return
|
|
300
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
301
|
+
"Wrong number of arguments");
|
|
514
302
|
}
|
|
515
303
|
|
|
516
304
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
517
|
-
return
|
|
305
|
+
return log_error_and_throw(env, "encrypt_string", "Wrong argument types");
|
|
518
306
|
}
|
|
519
307
|
|
|
520
308
|
// Determine size
|
|
@@ -522,11 +310,11 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
522
310
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
523
311
|
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
524
312
|
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
525
|
-
return
|
|
526
|
-
|
|
313
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
314
|
+
"Failed to get partition_id utf8 length");
|
|
527
315
|
}
|
|
528
316
|
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
529
|
-
return
|
|
317
|
+
return log_error_and_throw(env, "encrypt_string", "partition_id is empty");
|
|
530
318
|
}
|
|
531
319
|
|
|
532
320
|
// Allocate
|
|
@@ -538,7 +326,9 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
538
326
|
calculate_cobhan_buffer_size_bytes(partition_utf8_byte_length);
|
|
539
327
|
debug_log_alloca("encrypt_string", "partition_id_cobhan_buffer",
|
|
540
328
|
partition_id_cobhan_buffer_size_bytes);
|
|
541
|
-
partition_id_cobhan_buffer =
|
|
329
|
+
partition_id_cobhan_buffer =
|
|
330
|
+
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
331
|
+
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
542
332
|
} else {
|
|
543
333
|
// Otherwise, allocate it on the heap
|
|
544
334
|
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
@@ -546,8 +336,8 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
546
336
|
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
547
337
|
}
|
|
548
338
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
549
|
-
return
|
|
550
|
-
|
|
339
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
340
|
+
"Failed to allocate partitionId cobhan buffer");
|
|
551
341
|
}
|
|
552
342
|
|
|
553
343
|
// Copy
|
|
@@ -556,8 +346,8 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
556
346
|
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
557
347
|
&partition_copied_bytes);
|
|
558
348
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
559
|
-
return
|
|
560
|
-
|
|
349
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
350
|
+
"Failed to copy partitionId to cobhan buffer");
|
|
561
351
|
}
|
|
562
352
|
|
|
563
353
|
// Determine size
|
|
@@ -565,11 +355,11 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
565
355
|
Napi::String input = info[1].As<Napi::String>();
|
|
566
356
|
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
567
357
|
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
568
|
-
return
|
|
569
|
-
|
|
358
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
359
|
+
"Failed to get input utf8 length");
|
|
570
360
|
}
|
|
571
361
|
if (unlikely(input_utf8_byte_length == 0)) {
|
|
572
|
-
return
|
|
362
|
+
return log_error_and_throw(env, "encrypt_string", "input is empty");
|
|
573
363
|
}
|
|
574
364
|
|
|
575
365
|
// Allocate
|
|
@@ -579,8 +369,10 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
579
369
|
// If the buffer is small enough, allocate it on the stack
|
|
580
370
|
size_t input_cobhan_buffer_size_bytes =
|
|
581
371
|
calculate_cobhan_buffer_size_bytes(input_utf8_byte_length);
|
|
582
|
-
debug_log_alloca("encrypt_string", "input_cobhan_buffer",
|
|
372
|
+
debug_log_alloca("encrypt_string", "input_cobhan_buffer",
|
|
373
|
+
input_cobhan_buffer_size_bytes);
|
|
583
374
|
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
375
|
+
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
584
376
|
} else {
|
|
585
377
|
// Otherwise, allocate it on the heap
|
|
586
378
|
input_cobhan_buffer_unique_ptr =
|
|
@@ -588,8 +380,8 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
588
380
|
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
589
381
|
}
|
|
590
382
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
591
|
-
return
|
|
592
|
-
|
|
383
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
384
|
+
"Failed to allocate input cobhan buffer");
|
|
593
385
|
}
|
|
594
386
|
|
|
595
387
|
// Copy
|
|
@@ -598,12 +390,19 @@ Napi::Value encrypt_string(const Napi::CallbackInfo &info) {
|
|
|
598
390
|
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
599
391
|
input_cobhan_buffer, &input_copied_bytes);
|
|
600
392
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
601
|
-
return
|
|
602
|
-
|
|
393
|
+
return log_error_and_throw(env, "encrypt_string",
|
|
394
|
+
"Failed to copy input to cobhan buffer");
|
|
603
395
|
}
|
|
604
396
|
|
|
605
|
-
|
|
606
|
-
|
|
397
|
+
Napi::Value output =
|
|
398
|
+
encrypt_to_json(env, partition_copied_bytes, input_utf8_byte_length,
|
|
399
|
+
partition_id_cobhan_buffer, input_cobhan_buffer);
|
|
400
|
+
|
|
401
|
+
if (unlikely(verbose_flag)) {
|
|
402
|
+
debug_log("encrypt_string", "finished");
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return output;
|
|
607
406
|
}
|
|
608
407
|
|
|
609
408
|
Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
@@ -614,15 +413,15 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
614
413
|
}
|
|
615
414
|
|
|
616
415
|
if (unlikely(setup_state == 0)) {
|
|
617
|
-
return
|
|
416
|
+
return log_error_and_throw(env, "decrypt", "setup() not called");
|
|
618
417
|
}
|
|
619
418
|
|
|
620
419
|
if (unlikely(info.Length() < 2)) {
|
|
621
|
-
return
|
|
420
|
+
return log_error_and_throw(env, "decrypt", "Wrong number of arguments");
|
|
622
421
|
}
|
|
623
422
|
|
|
624
423
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
625
|
-
return
|
|
424
|
+
return log_error_and_throw(env, "decrypt", "Wrong argument types");
|
|
626
425
|
}
|
|
627
426
|
|
|
628
427
|
// Determine size
|
|
@@ -630,11 +429,11 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
630
429
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
631
430
|
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
632
431
|
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
633
|
-
return
|
|
634
|
-
|
|
432
|
+
return log_error_and_throw(env, "decrypt",
|
|
433
|
+
"Failed to get partition_id utf8 length");
|
|
635
434
|
}
|
|
636
435
|
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
637
|
-
return
|
|
436
|
+
return log_error_and_throw(env, "decrypt", "partition_id is empty");
|
|
638
437
|
}
|
|
639
438
|
|
|
640
439
|
// Allocate
|
|
@@ -648,6 +447,7 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
648
447
|
partition_id_cobhan_buffer_size_bytes);
|
|
649
448
|
partition_id_cobhan_buffer =
|
|
650
449
|
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
450
|
+
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
651
451
|
} else {
|
|
652
452
|
// Otherwise, allocate it on the heap
|
|
653
453
|
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
@@ -655,8 +455,8 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
655
455
|
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
656
456
|
}
|
|
657
457
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
658
|
-
return
|
|
659
|
-
|
|
458
|
+
return log_error_and_throw(env, "decrypt",
|
|
459
|
+
"Failed to allocate partition_id cobhan buffer");
|
|
660
460
|
}
|
|
661
461
|
|
|
662
462
|
// Copy
|
|
@@ -664,8 +464,8 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
664
464
|
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
665
465
|
&partition_copied_bytes);
|
|
666
466
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
667
|
-
return
|
|
668
|
-
|
|
467
|
+
return log_error_and_throw(env, "decrypt",
|
|
468
|
+
"Failed to copy partition_id to cobhan buffer");
|
|
669
469
|
}
|
|
670
470
|
|
|
671
471
|
// Determine size
|
|
@@ -673,10 +473,11 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
673
473
|
Napi::String input = info[1].As<Napi::String>();
|
|
674
474
|
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
675
475
|
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
676
|
-
return
|
|
476
|
+
return log_error_and_throw(env, "decrypt",
|
|
477
|
+
"Failed to get input utf8 length");
|
|
677
478
|
}
|
|
678
479
|
if (unlikely(input_utf8_byte_length == 0)) {
|
|
679
|
-
return
|
|
480
|
+
return log_error_and_throw(env, "decrypt", "input is empty");
|
|
680
481
|
}
|
|
681
482
|
|
|
682
483
|
if (unlikely(verbose_flag)) {
|
|
@@ -694,6 +495,7 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
694
495
|
debug_log_alloca("decrypt", "input_cobhan_buffer",
|
|
695
496
|
input_cobhan_buffer_size_bytes);
|
|
696
497
|
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
498
|
+
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
697
499
|
} else {
|
|
698
500
|
// Otherwise, allocate it on the heap
|
|
699
501
|
input_cobhan_buffer_unique_ptr =
|
|
@@ -701,8 +503,8 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
701
503
|
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
702
504
|
}
|
|
703
505
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
704
|
-
return
|
|
705
|
-
|
|
506
|
+
return log_error_and_throw(env, "decrypt",
|
|
507
|
+
"Failed to allocate input cobhan buffer");
|
|
706
508
|
}
|
|
707
509
|
|
|
708
510
|
// Copy
|
|
@@ -711,8 +513,8 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
711
513
|
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
712
514
|
input_cobhan_buffer, &input_copied_bytes);
|
|
713
515
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
714
|
-
return
|
|
715
|
-
|
|
516
|
+
return log_error_and_throw(env, "decrypt",
|
|
517
|
+
"Failed to copy input to cobhan buffer");
|
|
716
518
|
}
|
|
717
519
|
|
|
718
520
|
char *output_cobhan_buffer;
|
|
@@ -732,8 +534,8 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
732
534
|
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
733
535
|
}
|
|
734
536
|
if (unlikely(output_cobhan_buffer == nullptr)) {
|
|
735
|
-
return
|
|
736
|
-
|
|
537
|
+
return log_error_and_throw(env, "decrypt",
|
|
538
|
+
"Failed to allocate cobhan output buffer");
|
|
737
539
|
}
|
|
738
540
|
|
|
739
541
|
if (unlikely(verbose_flag)) {
|
|
@@ -751,10 +553,16 @@ Napi::Value decrypt(const Napi::CallbackInfo &info) {
|
|
|
751
553
|
|
|
752
554
|
if (unlikely(result < 0)) {
|
|
753
555
|
// TODO: Convert this to a proper error message
|
|
754
|
-
return
|
|
556
|
+
return log_error_and_throw(env, "decrypt", std::to_string(result));
|
|
755
557
|
}
|
|
756
558
|
|
|
757
|
-
|
|
559
|
+
Napi::Value output = cbuffer_to_nbuffer(env, output_cobhan_buffer);
|
|
560
|
+
|
|
561
|
+
if (unlikely(verbose_flag)) {
|
|
562
|
+
debug_log("decrypt", "finished");
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return output;
|
|
758
566
|
}
|
|
759
567
|
|
|
760
568
|
Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
@@ -765,15 +573,16 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
765
573
|
}
|
|
766
574
|
|
|
767
575
|
if (unlikely(setup_state == 0)) {
|
|
768
|
-
return
|
|
576
|
+
return log_error_and_throw(env, "decrypt_string", "setup() not called");
|
|
769
577
|
}
|
|
770
578
|
|
|
771
579
|
if (unlikely(info.Length() < 2)) {
|
|
772
|
-
return
|
|
580
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
581
|
+
"Wrong number of arguments");
|
|
773
582
|
}
|
|
774
583
|
|
|
775
584
|
if (unlikely(!info[0].IsString() || !info[1].IsString())) {
|
|
776
|
-
return
|
|
585
|
+
return log_error_and_throw(env, "decrypt_string", "Wrong argument types");
|
|
777
586
|
}
|
|
778
587
|
|
|
779
588
|
// Determine size
|
|
@@ -781,11 +590,11 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
781
590
|
Napi::String partition_id = info[0].As<Napi::String>();
|
|
782
591
|
partition_utf8_byte_length = nstring_utf8_byte_length(env, partition_id);
|
|
783
592
|
if (unlikely(partition_utf8_byte_length == (size_t)(-1))) {
|
|
784
|
-
return
|
|
785
|
-
|
|
593
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
594
|
+
"Failed to get partition_id utf8 length");
|
|
786
595
|
}
|
|
787
596
|
if (unlikely(partition_utf8_byte_length == 0)) {
|
|
788
|
-
return
|
|
597
|
+
return log_error_and_throw(env, "decrypt_string", "partition_id is empty");
|
|
789
598
|
}
|
|
790
599
|
|
|
791
600
|
// Allocate
|
|
@@ -799,6 +608,7 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
799
608
|
partition_id_cobhan_buffer_size_bytes);
|
|
800
609
|
partition_id_cobhan_buffer =
|
|
801
610
|
(char *)alloca(partition_id_cobhan_buffer_size_bytes);
|
|
611
|
+
configure_cbuffer(partition_id_cobhan_buffer, partition_utf8_byte_length);
|
|
802
612
|
} else {
|
|
803
613
|
// Otherwise, allocate it on the heap
|
|
804
614
|
partition_id_cobhan_buffer_unique_ptr = heap_allocate_cbuffer(
|
|
@@ -806,8 +616,8 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
806
616
|
partition_id_cobhan_buffer = partition_id_cobhan_buffer_unique_ptr.get();
|
|
807
617
|
}
|
|
808
618
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
809
|
-
return
|
|
810
|
-
|
|
619
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
620
|
+
"Failed to allocate partitionId cobhan buffer");
|
|
811
621
|
}
|
|
812
622
|
|
|
813
623
|
// Copy
|
|
@@ -816,8 +626,8 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
816
626
|
env, partition_id, partition_utf8_byte_length, partition_id_cobhan_buffer,
|
|
817
627
|
&partition_copied_bytes);
|
|
818
628
|
if (unlikely(partition_id_cobhan_buffer == nullptr)) {
|
|
819
|
-
return
|
|
820
|
-
|
|
629
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
630
|
+
"Failed to copy partitionId to cobhan buffer");
|
|
821
631
|
}
|
|
822
632
|
|
|
823
633
|
// Determine size
|
|
@@ -825,11 +635,11 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
825
635
|
Napi::String input = info[1].As<Napi::String>();
|
|
826
636
|
input_utf8_byte_length = nstring_utf8_byte_length(env, input);
|
|
827
637
|
if (unlikely(input_utf8_byte_length == (size_t)(-1))) {
|
|
828
|
-
return
|
|
829
|
-
|
|
638
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
639
|
+
"Failed to get input utf8 length");
|
|
830
640
|
}
|
|
831
641
|
if (unlikely(input_utf8_byte_length == 0)) {
|
|
832
|
-
return
|
|
642
|
+
return log_error_and_throw(env, "decrypt_string", "input is empty");
|
|
833
643
|
}
|
|
834
644
|
|
|
835
645
|
// Allocate
|
|
@@ -842,6 +652,7 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
842
652
|
debug_log_alloca("decrypt_string", "input_cobhan_buffer",
|
|
843
653
|
input_cobhan_buffer_size_bytes);
|
|
844
654
|
input_cobhan_buffer = (char *)alloca(input_cobhan_buffer_size_bytes);
|
|
655
|
+
configure_cbuffer(input_cobhan_buffer, input_utf8_byte_length);
|
|
845
656
|
} else {
|
|
846
657
|
// Otherwise, allocate it on the heap
|
|
847
658
|
input_cobhan_buffer_unique_ptr =
|
|
@@ -849,8 +660,8 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
849
660
|
input_cobhan_buffer = input_cobhan_buffer_unique_ptr.get();
|
|
850
661
|
}
|
|
851
662
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
852
|
-
return
|
|
853
|
-
|
|
663
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
664
|
+
"Failed to allocate input cobhan buffer");
|
|
854
665
|
}
|
|
855
666
|
|
|
856
667
|
// Copy
|
|
@@ -859,8 +670,8 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
859
670
|
copy_nstring_to_cbuffer(env, input, input_utf8_byte_length,
|
|
860
671
|
input_cobhan_buffer, &input_copied_bytes);
|
|
861
672
|
if (unlikely(input_cobhan_buffer == nullptr)) {
|
|
862
|
-
return
|
|
863
|
-
|
|
673
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
674
|
+
"Failed to copy input to cobhan buffer");
|
|
864
675
|
}
|
|
865
676
|
|
|
866
677
|
char *output_cobhan_buffer;
|
|
@@ -880,8 +691,8 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
880
691
|
output_cobhan_buffer = output_cobhan_buffer_unique_ptr.get();
|
|
881
692
|
}
|
|
882
693
|
if (unlikely(output_cobhan_buffer == nullptr)) {
|
|
883
|
-
return
|
|
884
|
-
|
|
694
|
+
return log_error_and_throw(env, "decrypt_string",
|
|
695
|
+
"Failed to allocate cobhan output buffer");
|
|
885
696
|
}
|
|
886
697
|
|
|
887
698
|
if (unlikely(verbose_flag)) {
|
|
@@ -899,10 +710,15 @@ Napi::Value decrypt_string(const Napi::CallbackInfo &info) {
|
|
|
899
710
|
|
|
900
711
|
if (unlikely(result < 0)) {
|
|
901
712
|
// TODO: Convert this to a proper error message
|
|
902
|
-
return
|
|
713
|
+
return log_error_and_throw(env, "decrypt_string", std::to_string(result));
|
|
903
714
|
}
|
|
904
715
|
|
|
905
716
|
Napi::Value output = cbuffer_to_nstring(env, output_cobhan_buffer);
|
|
717
|
+
|
|
718
|
+
if (unlikely(verbose_flag)) {
|
|
719
|
+
debug_log("decrypt_string", "finished");
|
|
720
|
+
}
|
|
721
|
+
|
|
906
722
|
return output;
|
|
907
723
|
}
|
|
908
724
|
|
|
@@ -933,8 +749,8 @@ void set_max_stack_alloc_item_size(const Napi::CallbackInfo &info) {
|
|
|
933
749
|
}
|
|
934
750
|
|
|
935
751
|
if (unlikely(info.Length() < 1)) {
|
|
936
|
-
|
|
937
|
-
|
|
752
|
+
log_error_and_throw(env, "set_max_stack_alloc_item_size",
|
|
753
|
+
"Wrong number of arguments");
|
|
938
754
|
return;
|
|
939
755
|
}
|
|
940
756
|
|
|
@@ -951,8 +767,8 @@ void set_safety_padding_overhead(const Napi::CallbackInfo &info) {
|
|
|
951
767
|
}
|
|
952
768
|
|
|
953
769
|
if (unlikely(info.Length() < 1)) {
|
|
954
|
-
|
|
955
|
-
|
|
770
|
+
log_error_and_throw(env, "set_safety_padding_overhead",
|
|
771
|
+
"Wrong number of arguments");
|
|
956
772
|
return;
|
|
957
773
|
}
|
|
958
774
|
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#ifndef COBHAN_NAPI_INTEROP_H
|
|
2
|
+
#define COBHAN_NAPI_INTEROP_H
|
|
3
|
+
#include <string>
|
|
4
|
+
#define NODE_ADDON_API_DISABLE_DEPRECATED
|
|
5
|
+
#include "hints.h"
|
|
6
|
+
#include "logging.h"
|
|
7
|
+
#include <napi.h>
|
|
8
|
+
|
|
9
|
+
extern size_t est_intermediate_key_overhead;
|
|
10
|
+
extern size_t safety_padding_bytes;
|
|
11
|
+
|
|
12
|
+
const size_t est_encryption_overhead = 48;
|
|
13
|
+
const size_t est_envelope_overhead = 185;
|
|
14
|
+
const double base64_overhead = 1.34;
|
|
15
|
+
|
|
16
|
+
const size_t cobhan_header_size_bytes = 64 / 8;
|
|
17
|
+
|
|
18
|
+
std::string napi_status_to_string(napi_status status) {
|
|
19
|
+
switch (status) {
|
|
20
|
+
case napi_ok:
|
|
21
|
+
return "napi_ok";
|
|
22
|
+
case napi_invalid_arg:
|
|
23
|
+
return "napi_invalid_arg";
|
|
24
|
+
case napi_object_expected:
|
|
25
|
+
return "napi_object_expected";
|
|
26
|
+
case napi_string_expected:
|
|
27
|
+
return "napi_string_expected";
|
|
28
|
+
case napi_name_expected:
|
|
29
|
+
return "napi_name_expected";
|
|
30
|
+
case napi_function_expected:
|
|
31
|
+
return "napi_function_expected";
|
|
32
|
+
case napi_number_expected:
|
|
33
|
+
return "napi_number_expected";
|
|
34
|
+
case napi_boolean_expected:
|
|
35
|
+
return "napi_boolean_expected";
|
|
36
|
+
case napi_array_expected:
|
|
37
|
+
return "napi_array_expected";
|
|
38
|
+
case napi_generic_failure:
|
|
39
|
+
return "napi_generic_failure";
|
|
40
|
+
case napi_pending_exception:
|
|
41
|
+
return "napi_pending_exception";
|
|
42
|
+
case napi_cancelled:
|
|
43
|
+
return "napi_cancelled";
|
|
44
|
+
case napi_escape_called_twice:
|
|
45
|
+
return "napi_escape_called_twice";
|
|
46
|
+
case napi_handle_scope_mismatch:
|
|
47
|
+
return "napi_handle_scope_mismatch";
|
|
48
|
+
case napi_callback_scope_mismatch:
|
|
49
|
+
return "napi_callback_scope_mismatch";
|
|
50
|
+
case napi_queue_full:
|
|
51
|
+
return "napi_queue_full";
|
|
52
|
+
case napi_closing:
|
|
53
|
+
return "napi_closing";
|
|
54
|
+
case napi_bigint_expected:
|
|
55
|
+
return "napi_bigint_expected";
|
|
56
|
+
case napi_date_expected:
|
|
57
|
+
return "napi_date_expected";
|
|
58
|
+
case napi_arraybuffer_expected:
|
|
59
|
+
return "napi_arraybuffer_expected";
|
|
60
|
+
case napi_detachable_arraybuffer_expected:
|
|
61
|
+
return "napi_detachable_arraybuffer_expected";
|
|
62
|
+
case napi_would_deadlock:
|
|
63
|
+
return "napi_would_deadlock";
|
|
64
|
+
default:
|
|
65
|
+
return "Unknown napi_status";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
__attribute__((always_inline)) inline int32_t
|
|
70
|
+
cbuffer_byte_length(char *cobhan_buffer) {
|
|
71
|
+
return *((int32_t *)cobhan_buffer);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
__attribute__((always_inline)) inline Napi::Value
|
|
75
|
+
log_error_and_throw(Napi::Env &env, const char *function_name,
|
|
76
|
+
std::string error_msg) {
|
|
77
|
+
error_log(function_name, error_msg);
|
|
78
|
+
Napi::Error::New(env, function_name + (": " + error_msg))
|
|
79
|
+
.ThrowAsJavaScriptException();
|
|
80
|
+
return env.Null();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
__attribute__((always_inline)) inline size_t
|
|
84
|
+
calculate_cobhan_buffer_size_bytes(size_t data_len_bytes) {
|
|
85
|
+
return data_len_bytes + cobhan_header_size_bytes + safety_padding_bytes +
|
|
86
|
+
1; // Add one for possible NULL delimiter due to Node string functions
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
__attribute__((always_inline)) inline size_t
|
|
90
|
+
estimate_asherah_output_size_bytes(size_t data_byte_len,
|
|
91
|
+
size_t partition_byte_len) {
|
|
92
|
+
// Add one rather than using std::ceil to round up
|
|
93
|
+
double est_data_byte_len =
|
|
94
|
+
(double(data_byte_len + est_encryption_overhead) * base64_overhead) + 1;
|
|
95
|
+
|
|
96
|
+
size_t asherah_output_size_bytes =
|
|
97
|
+
size_t(est_envelope_overhead + est_intermediate_key_overhead +
|
|
98
|
+
partition_byte_len + est_data_byte_len + safety_padding_bytes);
|
|
99
|
+
if (unlikely(verbose_flag)) {
|
|
100
|
+
std::string log_msg =
|
|
101
|
+
"estimate_asherah_output_size(" + std::to_string(data_byte_len) + ", " +
|
|
102
|
+
std::to_string(partition_byte_len) +
|
|
103
|
+
") est_data_byte_len: " + std::to_string(est_data_byte_len) +
|
|
104
|
+
" asherah_output_size_bytes: " +
|
|
105
|
+
std::to_string(asherah_output_size_bytes);
|
|
106
|
+
debug_log("estimate_asherah_output_size", log_msg);
|
|
107
|
+
}
|
|
108
|
+
return asherah_output_size_bytes;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
__attribute__((always_inline)) inline void configure_cbuffer(char *buffer,
|
|
112
|
+
size_t length) {
|
|
113
|
+
*((int32_t *)buffer) = length;
|
|
114
|
+
// Reserved for future use
|
|
115
|
+
*((int32_t *)(buffer + sizeof(int32_t))) = 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
__attribute__((always_inline)) inline std::unique_ptr<char[]>
|
|
119
|
+
heap_allocate_cbuffer(const char *variable_name, size_t size_bytes) {
|
|
120
|
+
size_t cobhan_buffer_size_bytes =
|
|
121
|
+
calculate_cobhan_buffer_size_bytes(size_bytes);
|
|
122
|
+
if (unlikely(verbose_flag)) {
|
|
123
|
+
std::string log_msg =
|
|
124
|
+
"heap_allocate_cbuffer(" + std::to_string(size_bytes) +
|
|
125
|
+
") (heap) cobhan_buffer_size_bytes: " +
|
|
126
|
+
std::to_string(cobhan_buffer_size_bytes) + " for " + variable_name;
|
|
127
|
+
debug_log("allocate_cbuffer", log_msg);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
char *cobhan_buffer = new (std::nothrow) char[cobhan_buffer_size_bytes];
|
|
131
|
+
if (unlikely(cobhan_buffer == nullptr)) {
|
|
132
|
+
std::string error_msg =
|
|
133
|
+
"new[" + std::to_string(cobhan_buffer_size_bytes) + " returned null";
|
|
134
|
+
error_log("allocate_cbuffer", error_msg);
|
|
135
|
+
return nullptr;
|
|
136
|
+
}
|
|
137
|
+
std::unique_ptr<char[]> cobhan_buffer_unique_ptr(cobhan_buffer);
|
|
138
|
+
configure_cbuffer(cobhan_buffer, size_bytes + safety_padding_bytes);
|
|
139
|
+
return cobhan_buffer_unique_ptr;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
__attribute__((always_inline)) inline Napi::Value
|
|
143
|
+
cbuffer_to_nstring(Napi::Env &env, char *cobhan_buffer) {
|
|
144
|
+
napi_value output;
|
|
145
|
+
|
|
146
|
+
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
147
|
+
if (cobhan_buffer_size_bytes <= 0) {
|
|
148
|
+
return log_error_and_throw(env, "cbuffer_to_nstring",
|
|
149
|
+
"Invalid cobhan buffer byte length");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Using C function because it allows length delimited input
|
|
153
|
+
napi_status status = napi_create_string_utf8(
|
|
154
|
+
env, ((const char *)cobhan_buffer) + cobhan_header_size_bytes,
|
|
155
|
+
cobhan_buffer_size_bytes, &output);
|
|
156
|
+
|
|
157
|
+
if (unlikely(status != napi_ok)) {
|
|
158
|
+
return log_error_and_throw(env, "cbuffer_to_nstring",
|
|
159
|
+
"napi_create_string_utf8 failed: " +
|
|
160
|
+
napi_status_to_string(status));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return Napi::String(env, output);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
__attribute__((always_inline)) inline size_t
|
|
167
|
+
nstring_utf8_byte_length(Napi::Env &env, Napi::String &str) {
|
|
168
|
+
napi_status status;
|
|
169
|
+
size_t utf8_length;
|
|
170
|
+
|
|
171
|
+
status = napi_get_value_string_utf8(env, str, nullptr, 0, &utf8_length);
|
|
172
|
+
if (unlikely(status != napi_ok)) {
|
|
173
|
+
log_error_and_throw(env, "nstring_utf8_length",
|
|
174
|
+
"napi_get_value_string_utf8 length check failed: " +
|
|
175
|
+
napi_status_to_string(status));
|
|
176
|
+
return (size_t)(-1);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return utf8_length;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
__attribute__((always_inline)) inline char *
|
|
183
|
+
copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str,
|
|
184
|
+
size_t str_utf8_byte_length, char *cobhan_buffer,
|
|
185
|
+
size_t *byte_length = nullptr) {
|
|
186
|
+
|
|
187
|
+
size_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
188
|
+
if (unlikely(cobhan_buffer_size_bytes <= 0)) {
|
|
189
|
+
log_error_and_throw(env, "copy_nstring_to_cbuffer",
|
|
190
|
+
"Invalid cobhan buffer byte length");
|
|
191
|
+
return nullptr;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (cobhan_buffer_size_bytes < str_utf8_byte_length) {
|
|
195
|
+
log_error_and_throw(env, "copy_nstring_to_cbuffer",
|
|
196
|
+
"String too large for cobhan buffer");
|
|
197
|
+
return nullptr;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
napi_status status;
|
|
201
|
+
size_t copied_bytes;
|
|
202
|
+
// NOTE: This implementation relies on the additional byte that is reserved
|
|
203
|
+
// upon allocation for a NULL delimiter as methods like
|
|
204
|
+
// napi_get_value_string_utf8 append a NULL delimiter
|
|
205
|
+
status = napi_get_value_string_utf8(env, str,
|
|
206
|
+
cobhan_buffer + cobhan_header_size_bytes,
|
|
207
|
+
str_utf8_byte_length + 1, &copied_bytes);
|
|
208
|
+
if (unlikely(status != napi_ok)) {
|
|
209
|
+
log_error_and_throw(env, "copy_nstring_to_cbuffer",
|
|
210
|
+
"Napi utf8 string conversion failure: " +
|
|
211
|
+
napi_status_to_string(status));
|
|
212
|
+
return nullptr;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (unlikely(copied_bytes != str_utf8_byte_length)) {
|
|
216
|
+
log_error_and_throw(env, "copy_nstring_to_cbuffer",
|
|
217
|
+
"Did not copy expected number of bytes " +
|
|
218
|
+
std::to_string(str_utf8_byte_length) + " copied " +
|
|
219
|
+
std::to_string(copied_bytes));
|
|
220
|
+
return nullptr;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
configure_cbuffer(cobhan_buffer, copied_bytes);
|
|
224
|
+
|
|
225
|
+
if (byte_length != nullptr)
|
|
226
|
+
*byte_length = copied_bytes;
|
|
227
|
+
return cobhan_buffer;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
__attribute__((always_inline)) inline char *
|
|
231
|
+
copy_nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &nbuffer,
|
|
232
|
+
char *cobhan_buffer) {
|
|
233
|
+
|
|
234
|
+
int32_t cobhan_buffer_size_bytes = cbuffer_byte_length(cobhan_buffer);
|
|
235
|
+
if (unlikely(cobhan_buffer_size_bytes <= 0)) {
|
|
236
|
+
log_error_and_throw(env, "copy_nbuffer_to_cbuffer",
|
|
237
|
+
"Invalid cobhan buffer byte length");
|
|
238
|
+
return nullptr;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
size_t nbuffer_byte_length = nbuffer.ByteLength();
|
|
242
|
+
if (nbuffer_byte_length > INT32_MAX ||
|
|
243
|
+
cobhan_buffer_size_bytes < (int32_t)nbuffer_byte_length) {
|
|
244
|
+
log_error_and_throw(env, "copy_nbuffer_to_cbuffer",
|
|
245
|
+
"Buffer too large for cobhan buffer");
|
|
246
|
+
return nullptr;
|
|
247
|
+
}
|
|
248
|
+
memcpy(cobhan_buffer + cobhan_header_size_bytes, nbuffer.Data(),
|
|
249
|
+
nbuffer_byte_length);
|
|
250
|
+
configure_cbuffer(cobhan_buffer, nbuffer_byte_length);
|
|
251
|
+
return cobhan_buffer;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
__attribute__((always_inline)) inline Napi::Value
|
|
255
|
+
cbuffer_to_nbuffer(Napi::Env &env, char *cobhan_buffer) {
|
|
256
|
+
int32_t cobhan_buffer_byte_length = cbuffer_byte_length(cobhan_buffer);
|
|
257
|
+
if (unlikely(cobhan_buffer_byte_length <= 0)) {
|
|
258
|
+
return log_error_and_throw(env, "cbuffer_to_nbuffer",
|
|
259
|
+
"Invalid cobhan buffer byte length");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (unlikely(verbose_flag)) {
|
|
263
|
+
debug_log("cbuffer_to_nbuffer",
|
|
264
|
+
"cbuffer_byte_length: " +
|
|
265
|
+
std::to_string(cobhan_buffer_byte_length));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (unlikely(cobhan_buffer_byte_length <= 0)) {
|
|
269
|
+
log_error_and_throw(env, "cbuffer_to_nbuffer",
|
|
270
|
+
"Invalid cobhan buffer byte length");
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
Napi::Buffer nbuffer = Napi::Buffer<unsigned char>::Copy(
|
|
274
|
+
env, ((unsigned char *)cobhan_buffer) + cobhan_header_size_bytes,
|
|
275
|
+
cobhan_buffer_byte_length);
|
|
276
|
+
|
|
277
|
+
if (unlikely(verbose_flag)) {
|
|
278
|
+
debug_log("cbuffer_to_nbuffer",
|
|
279
|
+
"nbuffer.ByteLength(): " + std::to_string(nbuffer.ByteLength()));
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return nbuffer;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
#endif
|
package/src/hints.h
ADDED
package/src/logging.cc
ADDED
package/src/logging.h
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#ifndef LOGGING_H
|
|
2
|
+
#define LOGGING_H
|
|
3
|
+
#include "hints.h"
|
|
4
|
+
#include <cstdint>
|
|
5
|
+
#include <string>
|
|
6
|
+
|
|
7
|
+
extern int32_t verbose_flag;
|
|
8
|
+
|
|
9
|
+
__attribute__((always_inline)) inline void debug_log(const char *function_name,
|
|
10
|
+
std::string message) {
|
|
11
|
+
if (unlikely(verbose_flag)) {
|
|
12
|
+
std::cerr << "asherah-node: [DEBUG] " << function_name << ": " << message
|
|
13
|
+
<< std::endl
|
|
14
|
+
<< std::flush;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
__attribute__((always_inline)) inline void
|
|
19
|
+
debug_log_alloca(const char *function_name, const char *variable_name,
|
|
20
|
+
size_t length) {
|
|
21
|
+
if (unlikely(verbose_flag)) {
|
|
22
|
+
std::cerr << "asherah-node: [DEBUG] " << function_name
|
|
23
|
+
<< ": Calling alloca(" << length << ") (stack) for "
|
|
24
|
+
<< variable_name << std::endl
|
|
25
|
+
<< std::flush;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
__attribute__((always_inline)) inline void error_log(const char *function_name,
|
|
30
|
+
std::string message) {
|
|
31
|
+
if (unlikely(verbose_flag)) {
|
|
32
|
+
std::cerr << "asherah-node: [ERROR] " << function_name << ": " << message
|
|
33
|
+
<< std::endl
|
|
34
|
+
<< std::flush;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#endif
|