asherah 1.3.22 → 1.3.24

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