asherah 1.3.21 → 1.3.23

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