asherah 1.3.0 → 1.3.3

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.25
1
+ ASHERAH_VERSION=v0.4.26
package/binding.gyp CHANGED
@@ -1,13 +1,23 @@
1
1
  {
2
2
  'targets': [
3
- {
3
+ {
4
4
  'target_name': 'napiasherah',
5
5
  'include_dirs': ["<!(node -p \"require('node-addon-api').include_dir\")"],
6
+ "cflags": ["-fexceptions", "-g"],
7
+ "cflags_cc": ["-fexceptions", "-g"],
8
+ "cflags!": [ "-fno-exceptions"],
9
+ "cflags_cc!": [ "-fno-exceptions" ],
10
+ 'xcode_settings': {
11
+ 'OTHER_CFLAGS': [
12
+ '-fexceptions',
13
+ '-g'
14
+ ],
15
+ },
16
+ 'defines': [ 'NAPI_CPP_EXCEPTIONS', 'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS' ],
6
17
  'sources': [
7
18
  'lib/libasherah.h',
8
19
  'src/napiasherah.cc'
9
20
  ],
10
- 'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
11
21
  'libraries': [ '../lib/libasherah.a' ]
12
22
  }
13
23
  ]
package/dist/asherah.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="ref-napi" />
3
2
  export type AsherahConfig = {
4
3
  /** The name of this service (Required) */
5
4
  ServiceName: string;
@@ -46,4 +45,5 @@ export declare function decrypt(partitionId: string, dataRowRecord: string): Buf
46
45
  export declare function encrypt(partitionId: string, data: Buffer): string;
47
46
  export declare function decrypt_string(partitionId: string, dataRowRecord: string): string;
48
47
  export declare function encrypt_string(partitionId: string, data: string): string;
49
- export declare function set_max_stack_alloc_item_size(max_item_size: number): any;
48
+ export declare function set_max_stack_alloc_item_size(max_item_size: number): void;
49
+ export declare function set_safety_padding_overhead(safety_padding_overhead: number): void;
package/dist/asherah.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.set_max_stack_alloc_item_size = exports.encrypt_string = exports.decrypt_string = exports.encrypt = exports.decrypt = exports.shutdown = exports.setup = void 0;
3
+ exports.set_safety_padding_overhead = exports.set_max_stack_alloc_item_size = exports.encrypt_string = exports.decrypt_string = exports.encrypt = exports.decrypt = exports.shutdown = exports.setup = void 0;
4
4
  const napi_asherah = require('../build/Release/napiasherah.node');
5
5
  function setup(config) {
6
6
  const configStr = JSON.stringify(config);
7
- napi_asherah.Napi_SetupJson(configStr, config.ProductID.length, config.ServiceName.length, configStr.length);
7
+ napi_asherah.Napi_SetupJson(configStr, config.ProductID.length, config.ServiceName.length, config.Verbose);
8
8
  }
9
9
  exports.setup = setup;
10
10
  function shutdown() {
@@ -31,3 +31,7 @@ function set_max_stack_alloc_item_size(max_item_size) {
31
31
  return napi_asherah.Napi_SetMaxStackAllocItemSize(max_item_size);
32
32
  }
33
33
  exports.set_max_stack_alloc_item_size = set_max_stack_alloc_item_size;
34
+ function set_safety_padding_overhead(safety_padding_overhead) {
35
+ return napi_asherah.Napi_SetSafetyPaddingOverhead(safety_padding_overhead);
36
+ }
37
+ exports.set_safety_padding_overhead = set_safety_padding_overhead;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asherah",
3
- "version": "1.3.0",
3
+ "version": "1.3.3",
4
4
  "description": "Asherah envelope encryption and key rotation library",
5
5
  "main": "dist/asherah.js",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  "scripts": {
11
11
  "build": "npx tsc",
12
12
  "preinstall": "scripts/download-libraries.sh",
13
- "install": "node-gyp rebuild",
13
+ "install": "CFLAGS=-fexceptions CXXFLAGS=-fexceptions node-gyp rebuild",
14
14
  "test:mocha": "mocha",
15
15
  "test": "nyc npm run test:mocha",
16
16
  "posttest": "npm run lint",
@@ -34,7 +34,6 @@
34
34
  "@types/chai": "^4.3.0",
35
35
  "@types/mocha": "^9.1.0",
36
36
  "@types/node": "^17.0.22",
37
- "@types/ref-napi": "^3.0.4",
38
37
  "@typescript-eslint/eslint-plugin": "^5.16.0",
39
38
  "@typescript-eslint/parser": "^5.16.0",
40
39
  "benchmark": "^2.1.4",
@@ -1,444 +1,871 @@
1
- #include <napi.h>
2
1
  #include "../lib/libasherah.h"
2
+ #include <iostream>
3
+ #include <napi.h>
4
+
5
+ #define unlikely(expr) __builtin_expect(!!(expr), 0)
6
+ #define likely(expr) __builtin_expect(!!(expr), 1)
7
+
8
+ const size_t cobhan_header_size = 64 / 8;
9
+ const size_t est_encryption_overhead = 48;
10
+ const size_t est_envelope_overhead = 185;
11
+ const double base64_overhead = 1.34;
12
+
13
+ size_t est_intermediate_key_overhead = 0;
14
+ size_t safety_padding = 0;
15
+ size_t max_stack_alloc_size = 2048;
16
+
17
+ const char *setupjson_failed_message = "SetupJson failed: ";
18
+ const char *decrypt_failed_message = "Decrypt failed: ";
19
+ const char *encrypt_failed_message = "Encrypt failed: ";
20
+
21
+ int32_t setup_state = 0;
22
+ int32_t verbose_flag = 0;
23
+
24
+ __attribute__((always_inline)) inline void debug_log(std::string message) {
25
+ if (unlikely(verbose_flag)) {
26
+ std::cerr << "asherah-node:" << message << std::endl << std::flush;
27
+ }
28
+ }
29
+
30
+ __attribute__((always_inline)) inline void debug_log_alloca(size_t length) {
31
+ if (unlikely(verbose_flag)) {
32
+ std::cerr << "asherah-node:" << "Calling alloca(" << length << ") (stack)" << std::endl << std::flush;
33
+ }
34
+ }
35
+
36
+ __attribute__((always_inline)) inline void error_log(std::string message) {
37
+ if (unlikely(verbose_flag)) {
38
+ std::cerr << "asherah-node:" << message << std::endl << std::flush;
39
+ }
40
+ }
41
+
42
+ std::string napi_status_to_string(napi_status status) {
43
+ switch (status) {
44
+ case napi_ok:
45
+ return "napi_ok";
46
+ case napi_invalid_arg:
47
+ return "napi_invalid_arg";
48
+ case napi_object_expected:
49
+ return "napi_object_expected";
50
+ case napi_string_expected:
51
+ return "napi_string_expected";
52
+ case napi_name_expected:
53
+ return "napi_name_expected";
54
+ case napi_function_expected:
55
+ return "napi_function_expected";
56
+ case napi_number_expected:
57
+ return "napi_number_expected";
58
+ case napi_boolean_expected:
59
+ return "napi_boolean_expected";
60
+ case napi_array_expected:
61
+ return "napi_array_expected";
62
+ case napi_generic_failure:
63
+ return "napi_generic_failure";
64
+ case napi_pending_exception:
65
+ return "napi_pending_exception";
66
+ case napi_cancelled:
67
+ return "napi_cancelled";
68
+ case napi_escape_called_twice:
69
+ return "napi_escape_called_twice";
70
+ case napi_handle_scope_mismatch:
71
+ return "napi_handle_scope_mismatch";
72
+ case napi_callback_scope_mismatch:
73
+ return "napi_callback_scope_mismatch";
74
+ case napi_queue_full:
75
+ return "napi_queue_full";
76
+ case napi_closing:
77
+ return "napi_closing";
78
+ case napi_bigint_expected:
79
+ return "napi_bigint_expected";
80
+ case napi_date_expected:
81
+ return "napi_date_expected";
82
+ case napi_arraybuffer_expected:
83
+ return "napi_arraybuffer_expected";
84
+ case napi_detachable_arraybuffer_expected:
85
+ return "napi_detachable_arraybuffer_expected";
86
+ case napi_would_deadlock:
87
+ return "napi_would_deadlock";
88
+ default:
89
+ return "Unknown napi_status";
90
+ }
91
+ }
3
92
 
4
- const size_t EstimatedEncryptionOverhead = 48;
5
- const size_t EstimatedEnvelopeOverhead = 185;
6
- const double Base64Overhead = 1.34;
7
- size_t EstimatedIntermediateKeyOverhead = 0;
8
- size_t SafetyPaddingOverhead = 0;
9
- const size_t header_size = 64 / 8;
10
- size_t max_stack_alloc_size = 4096;
11
- const char* SetupJsonFailedMessage = "SetupJson failed: ";
12
- const char* DecryptFailedMessage = "Decrypt failed: ";
13
- const char* EncryptFailedMessage = "Encrypt failed: ";
14
-
15
- void finalize_cbuffer(napi_env env, void* finalize_data) {
16
- char* buffer = ((char*) finalize_data) - header_size;
17
- delete[] buffer;
93
+ __attribute__((always_inline)) inline Napi::Value
94
+ LogErrorAndThrow(Napi::Env &env, std::string error_msg) {
95
+ error_log(error_msg);
96
+ Napi::Error::New(env, error_msg).ThrowAsJavaScriptException();
97
+ return env.Null();
18
98
  }
19
99
 
20
- __attribute__((always_inline)) inline size_t estimate_buffer(size_t dataLen, size_t partitionLen) {
21
- double estimatedDataLen = double(dataLen + EstimatedEncryptionOverhead) * Base64Overhead;
22
- return size_t(EstimatedEnvelopeOverhead + EstimatedIntermediateKeyOverhead + partitionLen + estimatedDataLen + SafetyPaddingOverhead);
100
+ __attribute__((always_inline)) inline size_t
101
+ cobhan_buffer_size(size_t dataLen) {
102
+ return dataLen + cobhan_header_size + safety_padding +
103
+ 1; // Add one for possible NULL delimiter due to Node string functions
23
104
  }
24
- __attribute__((always_inline)) inline char* configure_cbuffer(char *buffer, size_t length) {
25
- *((int32_t*)buffer) = length;
26
- *((int32_t*)(buffer+sizeof(int32_t))) = 0;
27
- return buffer;
105
+
106
+ __attribute__((always_inline)) inline size_t
107
+ estimate_asherah_output_size(size_t dataLen, size_t partitionLen) {
108
+ double estimatedDataLen =
109
+ double(dataLen + est_encryption_overhead) * base64_overhead;
110
+ if(unlikely(verbose_flag)) {
111
+ std::string log_msg = "estimate_asherah_output_size(" + std::to_string(dataLen) + ", " + std::to_string(partitionLen) + ") estimatedDataLen: " + std::to_string(estimatedDataLen) + " base64_overhead: " + std::to_string(base64_overhead) + " est_encryption_overhead: " + std::to_string(est_encryption_overhead);
112
+ debug_log(log_msg);
113
+ }
114
+ size_t asherah_output_size = size_t(est_envelope_overhead + est_intermediate_key_overhead +
115
+ partitionLen + estimatedDataLen + safety_padding);
116
+ if(unlikely(verbose_flag)) {
117
+ std::string log_msg = "estimate_asherah_output_size(" + std::to_string(dataLen) + ", " + std::to_string(partitionLen) + ") estimatedDataLen: " + std::to_string(estimatedDataLen) + " asherah_output_size: " + std::to_string(asherah_output_size);
118
+ debug_log(log_msg);
119
+ }
120
+ return asherah_output_size;
28
121
  }
29
122
 
30
- __attribute__((always_inline)) inline char* allocate_cbuffer(size_t length) {
31
- char *cobhanBuffer = new char[length + header_size + SafetyPaddingOverhead];
32
- return configure_cbuffer(cobhanBuffer, length);
123
+ __attribute__((always_inline)) inline void configure_cbuffer(char *buffer,
124
+ size_t length) {
125
+ *((int32_t *)buffer) = length;
126
+ // Reserved for future use
127
+ *((int32_t *)(buffer + sizeof(int32_t))) = 0;
33
128
  }
34
129
 
35
- __attribute__((always_inline)) inline char* nbuffer_to_cbuffer(Napi::Env &env, Napi::Buffer<unsigned char> &buffer) {
36
- size_t bufferLength = buffer.ByteLength();
37
- char *cobhanBuffer = new char[bufferLength + header_size + SafetyPaddingOverhead];
38
- memcpy(cobhanBuffer + header_size, buffer.Data(), bufferLength);
39
- return configure_cbuffer(cobhanBuffer, bufferLength);
130
+ __attribute__((always_inline)) inline std::unique_ptr<char[]>
131
+ allocate_cbuffer(size_t length) {
132
+ size_t cobhanBufferSize = cobhan_buffer_size(length);
133
+ if (unlikely(verbose_flag)) {
134
+ std::string log_msg =
135
+ "allocate_cbuffer(" + std::to_string(length) +
136
+ ") (heap) cobhanBufferSize: " + std::to_string(cobhanBufferSize);
137
+ debug_log(log_msg);
138
+ }
139
+
140
+ char *cobhanBuffer = new (std::nothrow) char[cobhanBufferSize];
141
+ if (unlikely(cobhanBuffer == nullptr)) {
142
+ std::string error_msg = "allocate_cbuffer: new[" +
143
+ std::to_string(cobhanBufferSize) + " returned null";
144
+ error_log(error_msg);
145
+ return nullptr;
146
+ }
147
+ std::unique_ptr<char[]> cobhanBufferPtr(cobhanBuffer);
148
+ configure_cbuffer(cobhanBuffer, length + safety_padding);
149
+ return cobhanBufferPtr;
40
150
  }
41
151
 
42
- __attribute__((always_inline)) inline Napi::Value cbuffer_to_nstring(Napi::Env &env, char *cobhanBuffer) {
152
+ __attribute__((always_inline)) inline Napi::Value
153
+ cbuffer_to_nstring(Napi::Env &env, char *cobhanBuffer) {
43
154
  napi_value output;
44
- //Using C function because it allows length delimited input
45
- napi_status status = napi_create_string_utf8(env, ((const char*) cobhanBuffer) + header_size, *((int*) cobhanBuffer), &output);
46
- if(status != napi_ok) {
47
- Napi::Error::New(env, "cbuffer_to_nstring failed")
48
- .ThrowAsJavaScriptException();
49
- return env.Null();
155
+
156
+ // Using C function because it allows length delimited input
157
+ napi_status status = napi_create_string_utf8(
158
+ env, ((const char *)cobhanBuffer) + cobhan_header_size,
159
+ *((int *)cobhanBuffer), &output);
160
+
161
+ if (unlikely(status != napi_ok)) {
162
+ return LogErrorAndThrow(
163
+ env, "cbuffer_to_nstring: napi_create_string_utf8 failed: " +
164
+ napi_status_to_string(status));
50
165
  }
166
+
51
167
  return Napi::String(env, output);
52
168
  }
53
169
 
54
- __attribute__((always_inline)) inline size_t nstring_utf8_length(Napi::Env &env, Napi::String &str) {
170
+ __attribute__((always_inline)) inline size_t
171
+ nstring_utf8_length(Napi::Env &env, Napi::String &str) {
55
172
  napi_status status;
56
173
  size_t utf8_length;
57
174
 
58
- status = napi_get_value_string_utf8(env, str, NULL, 0, &utf8_length);
59
- if(status != napi_ok) {
60
- Napi::Error::New(env, "nstring_to_cbuffer: Napi utf8 string conversion failure (length check): " + std::to_string(status))
61
- .ThrowAsJavaScriptException();
175
+ status = napi_get_value_string_utf8(env, str, nullptr, 0, &utf8_length);
176
+ if (unlikely(status != napi_ok)) {
177
+ LogErrorAndThrow(
178
+ env,
179
+ "nstring_utf8_length: napi_get_value_string_utf8 length check failed" +
180
+ napi_status_to_string(status));
62
181
  return (size_t)(-1);
63
182
  }
183
+
64
184
  return utf8_length;
65
185
  }
66
186
 
67
- __attribute__((always_inline)) inline char* copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str, size_t utf8_length, char *cbuffer, size_t *length = NULL) {
187
+ __attribute__((always_inline)) inline char *
188
+ copy_nstring_to_cbuffer(Napi::Env &env, Napi::String &str, size_t utf8_length,
189
+ char *cbuffer, size_t *length = nullptr) {
68
190
  napi_status status;
69
191
  size_t copied_bytes;
70
- status = napi_get_value_string_utf8(env, str, cbuffer + header_size, utf8_length + 1, &copied_bytes);
71
- if(status != napi_ok) {
72
- Napi::Error::New(env, "nstring_to_cbuffer: Napi utf8 string conversion failure: " + std::to_string(status))
73
- .ThrowAsJavaScriptException();
74
- return NULL;
192
+ status = napi_get_value_string_utf8(env, str, cbuffer + cobhan_header_size,
193
+ utf8_length + 1, &copied_bytes);
194
+ if (unlikely(status != napi_ok)) {
195
+ LogErrorAndThrow(env,
196
+ "copy_nstring_to_cbuffer: Napi utf8 string conversion "
197
+ "failure: " +
198
+ napi_status_to_string(status));
199
+ return nullptr;
75
200
  }
76
201
 
77
- if(copied_bytes != utf8_length) {
78
- Napi::Error::New(env, "nstring_to_cbuffer: Did not copy expected number of bytes " + std::to_string(utf8_length) + " copied " + std::to_string(copied_bytes))
79
- .ThrowAsJavaScriptException();
80
- return NULL;
202
+ if (unlikely(copied_bytes != utf8_length)) {
203
+ LogErrorAndThrow(env,
204
+ "copy_nstring_to_cbuffer: Did not copy expected number "
205
+ "of bytes " +
206
+ std::to_string(utf8_length) + " copied " +
207
+ std::to_string(copied_bytes));
208
+ return nullptr;
81
209
  }
82
210
 
83
- *((int*)cbuffer) = copied_bytes;
84
- *((int*)(cbuffer+sizeof(int32_t))) = 0;
211
+ *((int *)cbuffer) = copied_bytes;
212
+ *((int *)(cbuffer + sizeof(int32_t))) = 0;
85
213
 
86
- if(length != NULL)
214
+ if (length != nullptr)
87
215
  *length = copied_bytes;
88
216
  return cbuffer;
89
217
  }
90
218
 
91
- __attribute__((always_inline)) inline char* nstring_to_cbuffer(Napi::Env &env, Napi::String &str, size_t *length = NULL) {
92
- size_t utf8_length = nstring_utf8_length(env, str);
93
- if(utf8_length == (size_t)(-1)) {
94
- return NULL;
95
- }
219
+ __attribute__((always_inline)) inline Napi::Buffer<unsigned char>
220
+ cbuffer_to_nbuffer(Napi::Env &env, char *cobhanBuffer) {
221
+ return Napi::Buffer<unsigned char>::Copy(
222
+ env, ((unsigned char *)cobhanBuffer) + cobhan_header_size,
223
+ *((int *)cobhanBuffer));
224
+ }
96
225
 
97
- char *cobhanBuffer = new char[utf8_length + 1 + header_size + SafetyPaddingOverhead];
226
+ Napi::Value Napi_SetupJson(const Napi::CallbackInfo &info) {
227
+ Napi::Env env = info.Env();
98
228
 
99
- char *output = copy_nstring_to_cbuffer(env, str, utf8_length, cobhanBuffer, length);
100
- if(output == NULL) {
101
- delete[] cobhanBuffer;
229
+ if(unlikely(verbose_flag)) {
230
+ debug_log("SetupJson called");
102
231
  }
103
- return output;
104
- }
105
232
 
106
- Napi::Value Napi_SetupJson(const Napi::CallbackInfo& info) {
107
- Napi::Env env = info.Env();
233
+ if (unlikely(setup_state == 1)) {
234
+ return LogErrorAndThrow(env, setupjson_failed_message +
235
+ std::string("SetupJson called twice"));
236
+ }
108
237
 
109
- if (info.Length() < 3) {
110
- Napi::TypeError::New(env, "SetupJson: Wrong number of arguments")
111
- .ThrowAsJavaScriptException();
112
- return env.Null();
238
+ if (unlikely(info.Length() < 3)) {
239
+ return LogErrorAndThrow(env, "SetupJson: Wrong number of arguments");
113
240
  }
114
241
 
115
- if (!info[0].IsString() || !info[1].IsNumber() || !info[2].IsNumber()) {
116
- Napi::TypeError::New(env, "SetupJson: Wrong argument types")
117
- .ThrowAsJavaScriptException();
118
- return env.Null();
242
+ if (unlikely(!info[0].IsString() || !info[1].IsNumber() ||
243
+ !info[2].IsNumber() || !info[3].IsBoolean())) {
244
+ return LogErrorAndThrow(env, "SetupJson: Wrong argument types");
119
245
  }
120
246
 
247
+ Napi::Boolean verbose = info[3].As<Napi::Boolean>();
248
+ verbose.Value() ? verbose_flag = 1 : verbose_flag = 0;
249
+ debug_log("SetupJson: verbose_flag: " + std::to_string(verbose_flag) +
250
+ " verbose.Value(): " + std::to_string(verbose.Value()));
251
+
252
+ // Determine size
253
+ size_t config_utf8_length;
121
254
  Napi::String configJson = info[0].As<Napi::String>();
122
- char *configJsonCobhanBuffer = nstring_to_cbuffer(env, configJson);
123
- if (configJsonCobhanBuffer == NULL) {
124
- return env.Null();
255
+ config_utf8_length = nstring_utf8_length(env, configJson);
256
+ if (unlikely(config_utf8_length == (size_t)(-1))) {
257
+ return LogErrorAndThrow(
258
+ env, encrypt_failed_message +
259
+ std::string(" failed to get configJson utf8 length"));
260
+ }
261
+
262
+ // Allocate
263
+ char *configJsonCobhanBuffer;
264
+ std::unique_ptr<char[]> configJsonCobhanBufferPtr;
265
+ if (config_utf8_length < max_stack_alloc_size) {
266
+ size_t cobhan_buf_size = cobhan_buffer_size(config_utf8_length);
267
+ debug_log_alloca(cobhan_buf_size);
268
+ configJsonCobhanBuffer = (char *)alloca(cobhan_buf_size);
269
+ } else {
270
+ configJsonCobhanBufferPtr = allocate_cbuffer(config_utf8_length);
271
+ configJsonCobhanBuffer = configJsonCobhanBufferPtr.get();
272
+ }
273
+ if (unlikely(configJsonCobhanBuffer == nullptr)) {
274
+ return LogErrorAndThrow(
275
+ env, encrypt_failed_message +
276
+ std::string(" failed to allocate configJson cobhan buffer"));
277
+ }
278
+
279
+ // Copy
280
+ size_t config_copied_bytes;
281
+ configJsonCobhanBuffer =
282
+ copy_nstring_to_cbuffer(env, configJson, config_utf8_length,
283
+ configJsonCobhanBuffer, &config_copied_bytes);
284
+ if (unlikely(configJsonCobhanBuffer == nullptr)) {
285
+ return LogErrorAndThrow(
286
+ env, encrypt_failed_message +
287
+ std::string(" failed to copy configJson to cobhan buffer"));
125
288
  }
126
289
 
127
290
  Napi::Number productIdLength = info[1].As<Napi::Number>();
128
291
  Napi::Number serviceNameLength = info[2].As<Napi::Number>();
129
292
 
130
- EstimatedIntermediateKeyOverhead = productIdLength.Int32Value() + serviceNameLength.Int32Value();
293
+ est_intermediate_key_overhead =
294
+ productIdLength.Int32Value() + serviceNameLength.Int32Value();
295
+
296
+ if(unlikely(verbose_flag)) {
297
+ debug_log("Calling asherah-cobhan SetupJson");
298
+ }
131
299
 
132
- //extern GoInt32 SetupJson(void* configJson);
300
+ // extern GoInt32 SetupJson(void* configJson);
133
301
  GoInt32 result = SetupJson(configJsonCobhanBuffer);
134
- delete[] configJsonCobhanBuffer;
135
- if (result < 0) {
136
- Napi::TypeError::New(env, SetupJsonFailedMessage + std::to_string(result))
137
- .ThrowAsJavaScriptException();
302
+
303
+ if(unlikely(verbose_flag)) {
304
+ debug_log("Returned from asherah-cobhan SetupJson");
138
305
  }
306
+
307
+ if (unlikely(result < 0)) {
308
+ return LogErrorAndThrow(env,
309
+ setupjson_failed_message + std::to_string(result));
310
+ }
311
+ setup_state = 1;
139
312
  return env.Null();
140
313
  }
141
314
 
142
- Napi::Value Napi_EncryptFromBufferToJson(const Napi::CallbackInfo& info) {
143
- Napi::Env env = info.Env();
315
+ Napi::Value encrypt_to_json(Napi::Env &env, size_t partition_bytes,
316
+ size_t data_bytes, char *partitionIdCobhanBuffer,
317
+ char *dataCobhanBuffer) {
144
318
 
145
- if (info.Length() < 2) {
146
- Napi::TypeError::New(env, "EncryptFromBufferToJson: Wrong number of arguments")
147
- .ThrowAsJavaScriptException();
148
- return env.Null();
149
- }
319
+ size_t asherah_output_size =
320
+ estimate_asherah_output_size(data_bytes, partition_bytes);
150
321
 
151
- if (!info[0].IsString() || !info[1].IsBuffer()) {
152
- Napi::TypeError::New(env, "EncryptFromBufferToJson: Wrong argument types")
153
- .ThrowAsJavaScriptException();
154
- return env.Null();
322
+ if(unlikely(verbose_flag)) {
323
+ debug_log("encrypt_to_json asherah_output_size " +
324
+ std::to_string(asherah_output_size));
155
325
  }
156
326
 
157
- size_t partition_utf8_length, partition_copied_bytes;
158
- Napi::String partitionId = info[0].As<Napi::String>();
159
- partition_utf8_length = nstring_utf8_length(env, partitionId);
160
- if(partition_utf8_length == (size_t)(-1)) {
161
- return env.Null();
162
- }
163
- char *partitionIdCobhanBuffer;
164
- if (partition_utf8_length < max_stack_alloc_size) {
165
- partitionIdCobhanBuffer = (char*)alloca(partition_utf8_length + 1 + header_size + SafetyPaddingOverhead);
327
+ char *cobhanOutputBuffer;
328
+ std::unique_ptr<char[]> cobhanOutputBufferPtr;
329
+ if (asherah_output_size < max_stack_alloc_size) {
330
+ size_t cobhan_ouput_buffer_size = cobhan_buffer_size(asherah_output_size);
331
+ debug_log_alloca(cobhan_ouput_buffer_size);
332
+ cobhanOutputBuffer = (char *)alloca(cobhan_ouput_buffer_size);
333
+ configure_cbuffer(cobhanOutputBuffer, asherah_output_size + safety_padding);
166
334
  } else {
167
- partitionIdCobhanBuffer = new char[partition_utf8_length + 1 + header_size + SafetyPaddingOverhead];
335
+ cobhanOutputBufferPtr = allocate_cbuffer(asherah_output_size);
336
+ cobhanOutputBuffer = cobhanOutputBufferPtr.get();
168
337
  }
169
- partitionIdCobhanBuffer = copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length, partitionIdCobhanBuffer, &partition_copied_bytes);
170
- if (partitionIdCobhanBuffer == NULL) {
171
- if (partition_utf8_length >= max_stack_alloc_size)
172
- delete[] partitionIdCobhanBuffer;
173
- return env.Null();
338
+ if (unlikely(cobhanOutputBuffer == nullptr)) {
339
+ return LogErrorAndThrow(
340
+ env, encrypt_failed_message +
341
+ std::string(" failed to allocate cobhan output buffer"));
174
342
  }
175
343
 
176
- Napi::Buffer<unsigned char> data = info[1].As<Napi::Buffer<unsigned char>>();
177
- char *dataCobhanBuffer = nbuffer_to_cbuffer(env, data);
178
- if (dataCobhanBuffer == NULL) {
179
- if (partition_utf8_length >= max_stack_alloc_size)
180
- delete[] partitionIdCobhanBuffer;
181
- return env.Null();
344
+ if(unlikely(verbose_flag)) {
345
+ debug_log("Calling asherah-cobhan EncryptToJson");
182
346
  }
183
347
 
184
- size_t bufferSize = estimate_buffer(partition_copied_bytes, data.ByteLength());
348
+ // extern GoInt32 EncryptToJson(void* partitionIdPtr, void* dataPtr, void*
349
+ // jsonPtr);
350
+ GoInt32 result = EncryptToJson(partitionIdCobhanBuffer, dataCobhanBuffer,
351
+ cobhanOutputBuffer);
185
352
 
186
- char *cobhanOutputBuffer;
187
- if (bufferSize < max_stack_alloc_size) {
188
- cobhanOutputBuffer = configure_cbuffer((char*)alloca(bufferSize + header_size + SafetyPaddingOverhead), bufferSize);
189
- } else {
190
- cobhanOutputBuffer = allocate_cbuffer(bufferSize);
353
+ if(unlikely(verbose_flag)) {
354
+ debug_log("Returning from asherah-cobhan EncryptToJson");
191
355
  }
192
356
 
193
- //extern GoInt32 EncryptToJson(void* partitionIdPtr, void* dataPtr, void* jsonPtr);
194
- GoInt32 result = EncryptToJson(partitionIdCobhanBuffer, dataCobhanBuffer, cobhanOutputBuffer);
195
- if (partition_utf8_length >= max_stack_alloc_size)
196
- delete[] partitionIdCobhanBuffer;
197
- delete[] dataCobhanBuffer;
198
- if (result < 0) {
199
- if (bufferSize >= max_stack_alloc_size)
200
- delete[] cobhanOutputBuffer;
201
- Napi::TypeError::New(env, EncryptFailedMessage + std::to_string(result))
202
- .ThrowAsJavaScriptException();
203
- return env.Null();
357
+ if (unlikely(result < 0)) {
358
+ return LogErrorAndThrow(env,
359
+ encrypt_failed_message + std::to_string(result));
204
360
  }
205
361
 
206
362
  Napi::Value output = cbuffer_to_nstring(env, cobhanOutputBuffer);
207
- if (bufferSize >= max_stack_alloc_size)
208
- delete[] cobhanOutputBuffer;
209
363
  return output;
210
364
  }
211
365
 
212
- Napi::Value Napi_EncryptFromStringToJson(const Napi::CallbackInfo& info) {
366
+ Napi::Value Napi_EncryptFromBufferToJson(const Napi::CallbackInfo &info) {
213
367
  Napi::Env env = info.Env();
214
368
 
215
- if (info.Length() < 2) {
216
- Napi::TypeError::New(env, "EncryptFromStringToJson: Wrong number of arguments")
217
- .ThrowAsJavaScriptException();
218
- return env.Null();
369
+ if(unlikely(verbose_flag)) {
370
+ debug_log("EncryptFromBufferToJson called");
219
371
  }
220
372
 
221
- if (!info[0].IsString() || !info[1].IsString()) {
222
- Napi::TypeError::New(env, "EncryptFromStringToJson: Wrong argument types")
223
- .ThrowAsJavaScriptException();
224
- return env.Null();
373
+ if (unlikely(setup_state == 0)) {
374
+ return LogErrorAndThrow(env, encrypt_failed_message +
375
+ std::string("SetupJson not called"));
225
376
  }
226
377
 
227
- size_t partition_utf8_length, partition_copied_bytes;
378
+ if (unlikely(info.Length() < 2)) {
379
+ return LogErrorAndThrow(
380
+ env, "EncryptFromBufferToJson: Wrong number of arguments");
381
+ }
382
+
383
+ if (unlikely(!info[0].IsString() || !info[1].IsBuffer())) {
384
+ return LogErrorAndThrow(env,
385
+ "EncryptFromBufferToJson: Wrong argument types");
386
+ }
387
+
388
+ // Determine size
389
+ size_t partition_utf8_length;
228
390
  Napi::String partitionId = info[0].As<Napi::String>();
229
391
  partition_utf8_length = nstring_utf8_length(env, partitionId);
230
- if(partition_utf8_length == (size_t)(-1)) {
231
- return env.Null();
392
+ if (unlikely(partition_utf8_length == (size_t)(-1))) {
393
+ return LogErrorAndThrow(
394
+ env, encrypt_failed_message +
395
+ std::string(" failed to get partitionId utf8 length"));
232
396
  }
397
+
398
+ // Allocate
233
399
  char *partitionIdCobhanBuffer;
400
+ std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
234
401
  if (partition_utf8_length < max_stack_alloc_size) {
235
- partitionIdCobhanBuffer = (char*)alloca(partition_utf8_length + 1 + header_size + SafetyPaddingOverhead);
402
+ size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
403
+ debug_log_alloca(cobhan_buf_size);
404
+ partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
405
+ } else {
406
+ partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
407
+ partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
408
+ }
409
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
410
+ return LogErrorAndThrow(
411
+ env, encrypt_failed_message +
412
+ std::string(" failed to allocate partitionId cobhan buffer"));
413
+ }
414
+
415
+ // Copy
416
+ size_t partition_copied_bytes;
417
+ partitionIdCobhanBuffer =
418
+ copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
419
+ partitionIdCobhanBuffer, &partition_copied_bytes);
420
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
421
+ return LogErrorAndThrow(
422
+ env, encrypt_failed_message +
423
+ std::string(" failed to copy partitionId to cobhan buffer"));
424
+ }
425
+
426
+ // Determine size
427
+ Napi::Buffer<unsigned char> inputNapiBuffer =
428
+ info[1].As<Napi::Buffer<unsigned char>>();
429
+ size_t input_byte_length = inputNapiBuffer.ByteLength();
430
+
431
+ // Allocate
432
+ char *inputBuffer;
433
+ std::unique_ptr<char[]> inputBufferPtr;
434
+ if (input_byte_length < max_stack_alloc_size) {
435
+ size_t cobhan_buf_size = cobhan_buffer_size(input_byte_length);
436
+ debug_log_alloca(cobhan_buf_size);
437
+ inputBuffer = (char *)alloca(cobhan_buf_size);
236
438
  } else {
237
- partitionIdCobhanBuffer = new char[partition_utf8_length + 1 + header_size + SafetyPaddingOverhead];
439
+ inputBufferPtr = allocate_cbuffer(input_byte_length);
440
+ inputBuffer = inputBufferPtr.get();
238
441
  }
239
- partitionIdCobhanBuffer = copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length, partitionIdCobhanBuffer, &partition_copied_bytes);
240
- if (partitionIdCobhanBuffer == NULL) {
241
- if (partition_utf8_length >= max_stack_alloc_size)
242
- delete[] partitionIdCobhanBuffer;
243
- return env.Null();
442
+ if (unlikely(inputBuffer == nullptr)) {
443
+ return LogErrorAndThrow(
444
+ env,
445
+ encrypt_failed_message +
446
+ std::string(" failed to allocate cobhan buffer for input buffer"));
244
447
  }
245
448
 
246
- size_t input_utf8_length;
247
- Napi::String input = info[1].As<Napi::String>();
248
- char *inputCobhanBuffer = nstring_to_cbuffer(env, input, &input_utf8_length);
249
- if (inputCobhanBuffer == NULL) {
250
- if (partition_utf8_length >= max_stack_alloc_size)
251
- delete[] partitionIdCobhanBuffer;
252
- return env.Null();
449
+ // Copy
450
+ memcpy(inputBuffer + cobhan_header_size, inputNapiBuffer.Data(),
451
+ input_byte_length);
452
+ configure_cbuffer(inputBuffer, input_byte_length);
453
+
454
+ return encrypt_to_json(env, partition_copied_bytes, input_byte_length,
455
+ partitionIdCobhanBuffer, inputBuffer);
456
+ }
457
+
458
+ Napi::Value Napi_EncryptFromStringToJson(const Napi::CallbackInfo &info) {
459
+ Napi::Env env = info.Env();
460
+
461
+ if(unlikely(verbose_flag)) {
462
+ debug_log("EncryptFromStringToJson called");
253
463
  }
254
464
 
255
- //Call estimate_buffer to determine Cobhan output buffer length
256
- size_t bufferSize = estimate_buffer(partition_utf8_length, input_utf8_length);
465
+ if (unlikely(setup_state == 0)) {
466
+ return LogErrorAndThrow(env, encrypt_failed_message +
467
+ std::string("SetupJson not called"));
468
+ }
257
469
 
258
- char *cobhanOutputBuffer;
259
- if (bufferSize < max_stack_alloc_size) {
260
- cobhanOutputBuffer = configure_cbuffer((char*)alloca(bufferSize + header_size + SafetyPaddingOverhead), bufferSize);
470
+ if (unlikely(info.Length() < 2)) {
471
+ return LogErrorAndThrow(
472
+ env, "EncryptFromStringToJson: Wrong number of arguments");
473
+ }
474
+
475
+ if (unlikely(!info[0].IsString() || !info[1].IsString())) {
476
+ return LogErrorAndThrow(env,
477
+ "EncryptFromStringToJson: Wrong argument types");
478
+ }
479
+
480
+ // Determine size
481
+ size_t partition_utf8_length;
482
+ Napi::String partitionId = info[0].As<Napi::String>();
483
+ partition_utf8_length = nstring_utf8_length(env, partitionId);
484
+ if (unlikely(partition_utf8_length == (size_t)(-1))) {
485
+ return LogErrorAndThrow(
486
+ env, encrypt_failed_message +
487
+ std::string(" failed to get partitionId utf8 length"));
488
+ }
489
+
490
+ // Allocate
491
+ char *partitionIdCobhanBuffer;
492
+ std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
493
+ if (partition_utf8_length < max_stack_alloc_size) {
494
+ size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
495
+ debug_log_alloca(cobhan_buf_size);
496
+ partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
261
497
  } else {
262
- cobhanOutputBuffer = allocate_cbuffer(bufferSize);
498
+ partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
499
+ partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
500
+ }
501
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
502
+ return LogErrorAndThrow(
503
+ env, encrypt_failed_message +
504
+ std::string(" failed to allocate partitionId cobhan buffer"));
263
505
  }
264
506
 
265
- //extern GoInt32 EncryptToJson(void* partitionIdPtr, void* dataPtr, void* jsonPtr);
266
- GoInt32 result = EncryptToJson(partitionIdCobhanBuffer, inputCobhanBuffer, cobhanOutputBuffer);
267
- if (partition_utf8_length >= max_stack_alloc_size)
268
- delete[] partitionIdCobhanBuffer;
269
- delete[] inputCobhanBuffer;
270
- if (result < 0) {
271
- if (bufferSize >= max_stack_alloc_size)
272
- delete[] cobhanOutputBuffer;
273
- Napi::TypeError::New(env, EncryptFailedMessage + std::to_string(result))
274
- .ThrowAsJavaScriptException();
275
- return env.Null();
507
+ // Copy
508
+ size_t partition_copied_bytes;
509
+ partitionIdCobhanBuffer =
510
+ copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
511
+ partitionIdCobhanBuffer, &partition_copied_bytes);
512
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
513
+ return LogErrorAndThrow(
514
+ env, encrypt_failed_message +
515
+ std::string(" failed to copy partitionId to cobhan buffer"));
276
516
  }
277
517
 
278
- Napi::Value output = cbuffer_to_nstring(env, cobhanOutputBuffer);
279
- if (bufferSize >= max_stack_alloc_size)
280
- delete[] cobhanOutputBuffer;
281
- return output;
518
+ // Determine size
519
+ size_t input_utf8_length;
520
+ Napi::String input = info[1].As<Napi::String>();
521
+ input_utf8_length = nstring_utf8_length(env, input);
522
+ if (unlikely(input_utf8_length == (size_t)(-1))) {
523
+ return LogErrorAndThrow(
524
+ env, encrypt_failed_message +
525
+ std::string(" failed to get input utf8 length"));
526
+ }
527
+
528
+ // Allocate
529
+ char *inputCobhanBuffer;
530
+ std::unique_ptr<char[]> inputCobhanBufferPtr;
531
+ if (input_utf8_length < max_stack_alloc_size) {
532
+ size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
533
+ debug_log_alloca(cobhan_buf_size);
534
+ inputCobhanBuffer = (char *)alloca(cobhan_buf_size);
535
+ } else {
536
+ inputCobhanBufferPtr = allocate_cbuffer(input_utf8_length);
537
+ inputCobhanBuffer = inputCobhanBufferPtr.get();
538
+ }
539
+ if (unlikely(inputCobhanBuffer == nullptr)) {
540
+ return LogErrorAndThrow(
541
+ env, encrypt_failed_message +
542
+ std::string(" failed to allocate input cobhan buffer"));
543
+ }
544
+
545
+ // Copy
546
+ size_t input_copied_bytes;
547
+ inputCobhanBuffer = copy_nstring_to_cbuffer(
548
+ env, input, input_utf8_length, inputCobhanBuffer, &input_copied_bytes);
549
+ if (unlikely(inputCobhanBuffer == nullptr)) {
550
+ return LogErrorAndThrow(
551
+ env, encrypt_failed_message +
552
+ std::string(" failed to copy input to cobhan buffer"));
553
+ }
554
+
555
+ return encrypt_to_json(env, partition_copied_bytes, input_utf8_length,
556
+ partitionIdCobhanBuffer, inputCobhanBuffer);
282
557
  }
283
558
 
284
- Napi::Value Napi_DecryptFromJsonToBuffer(const Napi::CallbackInfo& info) {
559
+ Napi::Value Napi_DecryptFromJsonToBuffer(const Napi::CallbackInfo &info) {
285
560
  Napi::Env env = info.Env();
286
561
 
287
- if (info.Length() < 2) {
288
- Napi::TypeError::New(env, "DecryptFromJsonToBuffer: Wrong number of arguments")
289
- .ThrowAsJavaScriptException();
290
- return env.Null();
562
+ if(unlikely(verbose_flag)) {
563
+ debug_log("DecryptFromJsonToBuffer called");
291
564
  }
292
565
 
293
- if (!info[0].IsString() || !info[1].IsString()) {
294
- Napi::TypeError::New(env, "DecryptFromJsonToBuffer: Wrong argument types")
295
- .ThrowAsJavaScriptException();
296
- return env.Null();
566
+ if (unlikely(setup_state == 0)) {
567
+ return LogErrorAndThrow(env, decrypt_failed_message +
568
+ std::string("SetupJson not called"));
297
569
  }
298
570
 
571
+ if (unlikely(info.Length() < 2)) {
572
+ return LogErrorAndThrow(
573
+ env, "DecryptFromJsonToBuffer: Wrong number of arguments");
574
+ }
575
+
576
+ if (unlikely(!info[0].IsString() || !info[1].IsString())) {
577
+ return LogErrorAndThrow(env,
578
+ "DecryptFromJsonToBuffer: Wrong argument types");
579
+ }
580
+
581
+ // Determine size
299
582
  size_t partition_utf8_length, partition_copied_bytes;
300
583
  Napi::String partitionId = info[0].As<Napi::String>();
301
584
  partition_utf8_length = nstring_utf8_length(env, partitionId);
302
- if(partition_utf8_length == (size_t)(-1)) {
303
- return env.Null();
585
+ if (unlikely(partition_utf8_length == (size_t)(-1))) {
586
+ return LogErrorAndThrow(
587
+ env, decrypt_failed_message +
588
+ std::string(" failed to get partitionId utf8 length"));
304
589
  }
590
+
591
+ // Allocate
305
592
  char *partitionIdCobhanBuffer;
593
+ std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
306
594
  if (partition_utf8_length < max_stack_alloc_size) {
307
- partitionIdCobhanBuffer = (char*)alloca(partition_utf8_length + 1 + header_size + SafetyPaddingOverhead);
595
+ size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
596
+ debug_log_alloca(cobhan_buf_size);
597
+ partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
308
598
  } else {
309
- partitionIdCobhanBuffer = new char[partition_utf8_length + 1 + header_size + SafetyPaddingOverhead];
599
+ partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
600
+ partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
310
601
  }
311
- partitionIdCobhanBuffer = copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length, partitionIdCobhanBuffer, &partition_copied_bytes);
312
- if (partitionIdCobhanBuffer == NULL) {
313
- if (partition_utf8_length >= max_stack_alloc_size)
314
- delete[] partitionIdCobhanBuffer;
315
- return env.Null();
602
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
603
+ return LogErrorAndThrow(
604
+ env, decrypt_failed_message +
605
+ std::string(" failed to allocate partitionId cobhan buffer"));
316
606
  }
317
607
 
318
- size_t utf8_length;
319
- Napi::String inputJson = info[1].As<Napi::String>();
320
- char *inputJsonCobhanBuffer = nstring_to_cbuffer(env, inputJson, &utf8_length);
321
- if (inputJsonCobhanBuffer == NULL) {
322
- if (partition_utf8_length >= max_stack_alloc_size)
323
- delete[] partitionIdCobhanBuffer;
324
- return env.Null();
608
+ // Copy
609
+ partitionIdCobhanBuffer =
610
+ copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
611
+ partitionIdCobhanBuffer, &partition_copied_bytes);
612
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
613
+ return LogErrorAndThrow(
614
+ env, decrypt_failed_message +
615
+ std::string(" failed to copy partitionId to cobhan buffer"));
325
616
  }
326
617
 
327
- char *cobhanOutputBuffer;
328
- if (utf8_length < max_stack_alloc_size) {
329
- cobhanOutputBuffer = configure_cbuffer((char*)alloca(utf8_length + header_size + SafetyPaddingOverhead), utf8_length);
618
+ // Determine size
619
+ size_t input_utf8_length;
620
+ Napi::String input = info[1].As<Napi::String>();
621
+ input_utf8_length = nstring_utf8_length(env, input);
622
+ if (unlikely(input_utf8_length == (size_t)(-1))) {
623
+ return LogErrorAndThrow(
624
+ env, decrypt_failed_message +
625
+ std::string(" failed to get input utf8 length"));
626
+ }
627
+
628
+ if(unlikely(verbose_flag)) {
629
+ debug_log("DecryptFromJsonToBuffer input size " +
630
+ std::to_string(input_utf8_length));
631
+ }
632
+
633
+ // Allocate
634
+ char *inputJsonCobhanBuffer;
635
+ std::unique_ptr<char[]> inputJsonCobhanBufferPtr;
636
+ if (input_utf8_length < max_stack_alloc_size) {
637
+ size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
638
+ debug_log_alloca(cobhan_buf_size);
639
+ inputJsonCobhanBuffer = (char *)alloca(cobhan_buf_size);
330
640
  } else {
331
- cobhanOutputBuffer = allocate_cbuffer(utf8_length);
332
- }
333
-
334
- //extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void* dataPtr);
335
- GoInt32 result = DecryptFromJson(partitionIdCobhanBuffer, inputJsonCobhanBuffer, cobhanOutputBuffer);
336
- if (partition_utf8_length >= max_stack_alloc_size)
337
- delete[] partitionIdCobhanBuffer;
338
- delete[] inputJsonCobhanBuffer;
339
- if (result < 0) {
340
- delete[] cobhanOutputBuffer;
341
- Napi::TypeError::New(env, DecryptFailedMessage + std::to_string(result))
342
- .ThrowAsJavaScriptException();
343
- return env.Null();
344
- }
345
-
346
- //Wrap the Cobhan output buffer with a NAPI buffer with finalizer
347
- if (utf8_length < max_stack_alloc_size) {
348
- return Napi::Buffer<unsigned char>::Copy(env,
349
- ((unsigned char*) cobhanOutputBuffer) + header_size,
350
- *((int*) cobhanOutputBuffer));
641
+ inputJsonCobhanBufferPtr = allocate_cbuffer(input_utf8_length);
642
+ inputJsonCobhanBuffer = inputJsonCobhanBufferPtr.get();
643
+ }
644
+ if (unlikely(inputJsonCobhanBuffer == nullptr)) {
645
+ return LogErrorAndThrow(
646
+ env, decrypt_failed_message +
647
+ std::string(" failed to allocate input cobhan buffer"));
648
+ }
649
+
650
+ // Copy
651
+ size_t input_copied_bytes;
652
+ inputJsonCobhanBuffer =
653
+ copy_nstring_to_cbuffer(env, input, input_utf8_length,
654
+ inputJsonCobhanBuffer, &input_copied_bytes);
655
+ if (unlikely(inputJsonCobhanBuffer == nullptr)) {
656
+ return LogErrorAndThrow(
657
+ env, decrypt_failed_message +
658
+ std::string(" failed to copy inputJson to cobhan buffer"));
659
+ }
660
+
661
+ char *cobhanOutputBuffer;
662
+ std::unique_ptr<char[]> cobhanOutputBufferPtr;
663
+ if (input_utf8_length < max_stack_alloc_size) {
664
+ size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
665
+ debug_log_alloca(cobhan_buf_size);
666
+ cobhanOutputBuffer = (char *)alloca(cobhan_buf_size);
667
+ configure_cbuffer(cobhanOutputBuffer, input_utf8_length);
351
668
  } else {
352
- return Napi::Buffer<unsigned char>::New(env,
353
- ((unsigned char*) cobhanOutputBuffer) + header_size,
354
- *((int*) cobhanOutputBuffer),
355
- &finalize_cbuffer);
669
+ cobhanOutputBufferPtr = allocate_cbuffer(input_utf8_length);
670
+ cobhanOutputBuffer = cobhanOutputBufferPtr.get();
671
+ }
672
+ if (unlikely(cobhanOutputBuffer == nullptr)) {
673
+ return LogErrorAndThrow(
674
+ env, decrypt_failed_message +
675
+ std::string(" failed to allocate cobhan output buffer"));
676
+ }
677
+
678
+ if(unlikely(verbose_flag)) {
679
+ debug_log("Calling asherah-cobhan DecryptFromJson");
680
+ }
681
+
682
+ // extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void*
683
+ // dataPtr);
684
+ GoInt32 result = DecryptFromJson(partitionIdCobhanBuffer,
685
+ inputJsonCobhanBuffer, cobhanOutputBuffer);
686
+
687
+ if(unlikely(verbose_flag)) {
688
+ debug_log("Returned from asherah-cobhan DecryptFromJson");
689
+ }
690
+
691
+ if (unlikely(result < 0)) {
692
+ return LogErrorAndThrow(env,
693
+ decrypt_failed_message + std::to_string(result));
356
694
  }
695
+
696
+ return cbuffer_to_nbuffer(env, cobhanOutputBuffer);
357
697
  }
358
698
 
359
- Napi::Value Napi_DecryptFromJsonToString(const Napi::CallbackInfo& info) {
699
+ Napi::Value Napi_DecryptFromJsonToString(const Napi::CallbackInfo &info) {
360
700
  Napi::Env env = info.Env();
361
701
 
362
- if (info.Length() < 2) {
363
- Napi::TypeError::New(env, "DecryptFromJsonToString: Wrong number of arguments")
364
- .ThrowAsJavaScriptException();
365
- return env.Null();
702
+ if(unlikely(verbose_flag)) {
703
+ debug_log("DecryptFromJsonToString called");
366
704
  }
367
705
 
368
- if (!info[0].IsString() || !info[1].IsString()) {
369
- Napi::TypeError::New(env, "DecryptFromJsonToString: Wrong argument types")
370
- .ThrowAsJavaScriptException();
371
- return env.Null();
706
+ if (unlikely(setup_state == 0)) {
707
+ return LogErrorAndThrow(env, decrypt_failed_message +
708
+ std::string("SetupJson not called"));
372
709
  }
373
710
 
374
- size_t partition_utf8_length, partition_copied_bytes;
711
+ if (unlikely(info.Length() < 2)) {
712
+ return LogErrorAndThrow(
713
+ env, "DecryptFromJsonToString: Wrong number of arguments");
714
+ }
715
+
716
+ if (unlikely(!info[0].IsString() || !info[1].IsString())) {
717
+ return LogErrorAndThrow(env,
718
+ "DecryptFromJsonToString: Wrong argument types");
719
+ }
720
+
721
+ // Determine size
722
+ size_t partition_utf8_length;
375
723
  Napi::String partitionId = info[0].As<Napi::String>();
376
724
  partition_utf8_length = nstring_utf8_length(env, partitionId);
377
- if(partition_utf8_length == (size_t)(-1)) {
378
- return env.Null();
725
+ if (unlikely(partition_utf8_length == (size_t)(-1))) {
726
+ return LogErrorAndThrow(
727
+ env, decrypt_failed_message +
728
+ std::string(" failed to get partitionId utf8 length"));
379
729
  }
730
+
731
+ // Allocate
380
732
  char *partitionIdCobhanBuffer;
733
+ std::unique_ptr<char[]> partitionIdCobhanBufferPtr;
381
734
  if (partition_utf8_length < max_stack_alloc_size) {
382
- partitionIdCobhanBuffer = (char*)alloca(partition_utf8_length + 1 + header_size + SafetyPaddingOverhead);
735
+ size_t cobhan_buf_size = cobhan_buffer_size(partition_utf8_length);
736
+ debug_log_alloca(cobhan_buf_size);
737
+ partitionIdCobhanBuffer = (char *)alloca(cobhan_buf_size);
383
738
  } else {
384
- partitionIdCobhanBuffer = new char[partition_utf8_length + 1 + header_size + SafetyPaddingOverhead];
739
+ partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
740
+ partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
385
741
  }
386
- partitionIdCobhanBuffer = copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length, partitionIdCobhanBuffer, &partition_copied_bytes);
387
- if (partitionIdCobhanBuffer == NULL) {
388
- if (partition_utf8_length >= max_stack_alloc_size)
389
- delete[] partitionIdCobhanBuffer;
390
- return env.Null();
742
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
743
+ return LogErrorAndThrow(
744
+ env, decrypt_failed_message +
745
+ std::string(" failed to allocate partitionId cobhan buffer"));
391
746
  }
392
747
 
393
- size_t utf8_length;
394
- Napi::String inputJson = info[1].As<Napi::String>();
395
- char *inputJsonCobhanBuffer = nstring_to_cbuffer(env, inputJson, &utf8_length);
396
- if (inputJsonCobhanBuffer == NULL) {
397
- if (partition_utf8_length >= max_stack_alloc_size)
398
- delete[] partitionIdCobhanBuffer;
399
- return env.Null();
748
+ // Copy
749
+ size_t partition_copied_bytes;
750
+ partitionIdCobhanBuffer =
751
+ copy_nstring_to_cbuffer(env, partitionId, partition_utf8_length,
752
+ partitionIdCobhanBuffer, &partition_copied_bytes);
753
+ if (unlikely(partitionIdCobhanBuffer == nullptr)) {
754
+ return LogErrorAndThrow(
755
+ env, decrypt_failed_message +
756
+ std::string(" failed to copy partitionId to cobhan buffer"));
757
+ }
758
+
759
+ // Determine size
760
+ size_t input_utf8_length;
761
+ Napi::String input = info[1].As<Napi::String>();
762
+ input_utf8_length = nstring_utf8_length(env, input);
763
+ if (unlikely(input_utf8_length == (size_t)(-1))) {
764
+ return LogErrorAndThrow(
765
+ env, decrypt_failed_message +
766
+ std::string(" failed to get input utf8 length"));
767
+ }
768
+
769
+ // Allocate
770
+ char *inputJsonCobhanBuffer;
771
+ std::unique_ptr<char[]> inputJsonCobhanBufferPtr;
772
+ if (input_utf8_length < max_stack_alloc_size) {
773
+ size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
774
+ debug_log_alloca(cobhan_buf_size);
775
+ inputJsonCobhanBuffer = (char *)alloca(cobhan_buf_size);
776
+ } else {
777
+ inputJsonCobhanBufferPtr = allocate_cbuffer(input_utf8_length);
778
+ inputJsonCobhanBuffer = inputJsonCobhanBufferPtr.get();
779
+ }
780
+ if (unlikely(inputJsonCobhanBuffer == nullptr)) {
781
+ return LogErrorAndThrow(
782
+ env, decrypt_failed_message +
783
+ std::string(" failed to allocate input cobhan buffer"));
784
+ }
785
+
786
+ // Copy
787
+ size_t input_copied_bytes;
788
+ inputJsonCobhanBuffer =
789
+ copy_nstring_to_cbuffer(env, input, input_utf8_length,
790
+ inputJsonCobhanBuffer, &input_copied_bytes);
791
+ if (unlikely(inputJsonCobhanBuffer == nullptr)) {
792
+ return LogErrorAndThrow(
793
+ env, decrypt_failed_message +
794
+ std::string(" failed to copy inputJson to cobhan buffer"));
400
795
  }
401
796
 
402
797
  char *cobhanOutputBuffer;
403
- if (utf8_length < max_stack_alloc_size) {
404
- cobhanOutputBuffer = configure_cbuffer((char*)alloca(utf8_length + header_size + SafetyPaddingOverhead), utf8_length);
798
+ std::unique_ptr<char[]> cobhanOutputBufferPtr;
799
+ if (input_utf8_length < max_stack_alloc_size) {
800
+ size_t cobhan_buf_size = cobhan_buffer_size(input_utf8_length);
801
+ debug_log_alloca(cobhan_buf_size);
802
+ cobhanOutputBuffer = (char *)alloca(cobhan_buf_size);
803
+ configure_cbuffer(cobhanOutputBuffer, input_utf8_length);
405
804
  } else {
406
- cobhanOutputBuffer = allocate_cbuffer(utf8_length);
805
+ cobhanOutputBufferPtr = allocate_cbuffer(input_utf8_length);
806
+ cobhanOutputBuffer = cobhanOutputBufferPtr.get();
807
+ }
808
+ if (unlikely(cobhanOutputBuffer == nullptr)) {
809
+ return LogErrorAndThrow(
810
+ env, decrypt_failed_message +
811
+ std::string(" failed to allocate cobhan output buffer"));
812
+ }
813
+
814
+ if(unlikely(verbose_flag)) {
815
+ debug_log("Calling asherah-cobhan DecryptFromJson");
816
+ }
817
+
818
+ // extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void*
819
+ // dataPtr);
820
+ GoInt32 result = DecryptFromJson(partitionIdCobhanBuffer,
821
+ inputJsonCobhanBuffer, cobhanOutputBuffer);
822
+
823
+ if(unlikely(verbose_flag)) {
824
+ debug_log("Returned from asherah-cobhan DecryptFromJson");
407
825
  }
408
826
 
409
- //extern GoInt32 DecryptFromJson(void* partitionIdPtr, void* jsonPtr, void* dataPtr);
410
- GoInt32 result = DecryptFromJson(partitionIdCobhanBuffer, inputJsonCobhanBuffer, cobhanOutputBuffer);
411
- if (partition_utf8_length >= max_stack_alloc_size)
412
- delete[] partitionIdCobhanBuffer;
413
- delete[] inputJsonCobhanBuffer;
414
- if (result < 0) {
415
- if (utf8_length >= max_stack_alloc_size)
416
- delete[] cobhanOutputBuffer;
417
- Napi::TypeError::New(env, DecryptFailedMessage + std::to_string(result))
418
- .ThrowAsJavaScriptException();
419
- return env.Null();
827
+ if (unlikely(result < 0)) {
828
+ return LogErrorAndThrow(env,
829
+ decrypt_failed_message + std::to_string(result));
420
830
  }
421
831
 
422
832
  Napi::Value output = cbuffer_to_nstring(env, cobhanOutputBuffer);
423
- if (utf8_length >= max_stack_alloc_size)
424
- delete[] cobhanOutputBuffer;
425
833
  return output;
426
834
  }
427
835
 
428
- Napi::Value Napi_Shutdown(const Napi::CallbackInfo& info) {
836
+ Napi::Value Napi_Shutdown(const Napi::CallbackInfo &info) {
429
837
  Napi::Env env = info.Env();
430
- //extern void Shutdown();
838
+
839
+ if(unlikely(verbose_flag)) {
840
+ debug_log("Shutdown called");
841
+ }
842
+
843
+ setup_state = 0;
844
+ // extern void Shutdown();
845
+
846
+ if(unlikely(verbose_flag)) {
847
+ debug_log("Calling asherah-cobhan Shutdown");
848
+ }
849
+
431
850
  Shutdown();
851
+
852
+ if(unlikely(verbose_flag)) {
853
+ debug_log("Returned from asherah-cobhan Shutdown");
854
+ }
855
+
432
856
  return env.Null();
433
857
  }
434
858
 
435
- Napi::Value Napi_SetMaxStackAllocItemSize(const Napi::CallbackInfo& info) {
859
+ Napi::Value Napi_SetMaxStackAllocItemSize(const Napi::CallbackInfo &info) {
436
860
  Napi::Env env = info.Env();
437
861
 
438
- if (info.Length() < 1) {
439
- Napi::TypeError::New(env, "SetMaxStackAllocItemSize: Wrong number of arguments")
440
- .ThrowAsJavaScriptException();
441
- return env.Null();
862
+ if(unlikely(verbose_flag)) {
863
+ debug_log("SetMaxStackAllocItemSize called");
864
+ }
865
+
866
+ if (unlikely(info.Length() < 1)) {
867
+ return LogErrorAndThrow(
868
+ env, "SetMaxStackAllocItemSize: Wrong number of arguments");
442
869
  }
443
870
 
444
871
  Napi::Number item_size = info[0].As<Napi::Number>();
@@ -447,28 +874,41 @@ Napi::Value Napi_SetMaxStackAllocItemSize(const Napi::CallbackInfo& info) {
447
874
  return env.Null();
448
875
  }
449
876
 
450
- Napi::Value Napi_SetSafetyPaddingOverhead(const Napi::CallbackInfo& info) {
877
+ Napi::Value Napi_SetSafetyPaddingOverhead(const Napi::CallbackInfo &info) {
451
878
  Napi::Env env = info.Env();
452
879
 
453
- if (info.Length() < 1) {
454
- Napi::TypeError::New(env, "SetSafetyPaddingOverhead: Wrong number of arguments")
455
- .ThrowAsJavaScriptException();
456
- return env.Null();
880
+ if(unlikely(verbose_flag)) {
881
+ debug_log("SetSafetyPaddingOverhead called");
882
+ }
883
+
884
+ if (unlikely(info.Length() < 1)) {
885
+ return LogErrorAndThrow(
886
+ env, "SetSafetyPaddingOverhead: Wrong number of arguments");
457
887
  }
458
888
 
459
- Napi::Number safety_padding = info[0].As<Napi::Number>();
889
+ Napi::Number safety_padding_number = info[0].As<Napi::Number>();
460
890
 
461
- SafetyPaddingOverhead = (size_t)safety_padding.Int32Value();
891
+ safety_padding = (size_t)safety_padding_number.Int32Value();
462
892
  return env.Null();
463
893
  }
464
894
 
465
895
  Napi::Object Init(Napi::Env env, Napi::Object exports) {
466
- exports.Set(Napi::String::New(env, "Napi_SetupJson"), Napi::Function::New(env, Napi_SetupJson));
467
- exports.Set(Napi::String::New(env, "Napi_EncryptFromBufferToJson"), Napi::Function::New(env, Napi_EncryptFromBufferToJson));
468
- exports.Set(Napi::String::New(env, "Napi_EncryptFromStringToJson"), Napi::Function::New(env, Napi_EncryptFromStringToJson));
469
- exports.Set(Napi::String::New(env, "Napi_DecryptFromJsonToBuffer"), Napi::Function::New(env, Napi_DecryptFromJsonToBuffer));
470
- exports.Set(Napi::String::New(env, "Napi_DecryptFromJsonToString"), Napi::Function::New(env, Napi_DecryptFromJsonToString));
471
- exports.Set(Napi::String::New(env, "Napi_Shutdown"), Napi::Function::New(env, Napi_Shutdown));
896
+ exports.Set(Napi::String::New(env, "Napi_SetupJson"),
897
+ Napi::Function::New(env, Napi_SetupJson));
898
+ exports.Set(Napi::String::New(env, "Napi_EncryptFromBufferToJson"),
899
+ Napi::Function::New(env, Napi_EncryptFromBufferToJson));
900
+ exports.Set(Napi::String::New(env, "Napi_EncryptFromStringToJson"),
901
+ Napi::Function::New(env, Napi_EncryptFromStringToJson));
902
+ exports.Set(Napi::String::New(env, "Napi_DecryptFromJsonToBuffer"),
903
+ Napi::Function::New(env, Napi_DecryptFromJsonToBuffer));
904
+ exports.Set(Napi::String::New(env, "Napi_DecryptFromJsonToString"),
905
+ Napi::Function::New(env, Napi_DecryptFromJsonToString));
906
+ exports.Set(Napi::String::New(env, "Napi_SetSafetyPaddingOverhead"),
907
+ Napi::Function::New(env, Napi_SetSafetyPaddingOverhead));
908
+ exports.Set(Napi::String::New(env, "Napi_SetMaxStackAllocItemSize"),
909
+ Napi::Function::New(env, Napi_SetMaxStackAllocItemSize));
910
+ exports.Set(Napi::String::New(env, "Napi_Shutdown"),
911
+ Napi::Function::New(env, Napi_Shutdown));
472
912
  return exports;
473
913
  }
474
914