asherah 1.3.23 → 1.3.25

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