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 +1 -1
- package/binding.gyp +12 -2
- package/dist/asherah.d.ts +2 -2
- package/dist/asherah.js +6 -2
- package/package.json +2 -3
- package/src/napiasherah.cc +737 -297
package/.asherah-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ASHERAH_VERSION=v0.4.
|
|
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):
|
|
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,
|
|
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.
|
|
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",
|
package/src/napiasherah.cc
CHANGED
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
21
|
-
|
|
22
|
-
return
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
152
|
+
__attribute__((always_inline)) inline Napi::Value
|
|
153
|
+
cbuffer_to_nstring(Napi::Env &env, char *cobhanBuffer) {
|
|
43
154
|
napi_value output;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
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,
|
|
59
|
-
if(status != napi_ok) {
|
|
60
|
-
|
|
61
|
-
|
|
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
|
|
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 +
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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 !=
|
|
214
|
+
if (length != nullptr)
|
|
87
215
|
*length = copied_bytes;
|
|
88
216
|
return cbuffer;
|
|
89
217
|
}
|
|
90
218
|
|
|
91
|
-
__attribute__((always_inline)) inline
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
226
|
+
Napi::Value Napi_SetupJson(const Napi::CallbackInfo &info) {
|
|
227
|
+
Napi::Env env = info.Env();
|
|
98
228
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
delete[] cobhanBuffer;
|
|
229
|
+
if(unlikely(verbose_flag)) {
|
|
230
|
+
debug_log("SetupJson called");
|
|
102
231
|
}
|
|
103
|
-
return output;
|
|
104
|
-
}
|
|
105
232
|
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
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() ||
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
123
|
-
if (
|
|
124
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
135
|
-
if
|
|
136
|
-
|
|
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
|
|
143
|
-
|
|
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
|
-
|
|
146
|
-
|
|
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
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
335
|
+
cobhanOutputBufferPtr = allocate_cbuffer(asherah_output_size);
|
|
336
|
+
cobhanOutputBuffer = cobhanOutputBufferPtr.get();
|
|
168
337
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
177
|
-
|
|
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
|
-
|
|
348
|
+
// extern GoInt32 EncryptToJson(void* partitionIdPtr, void* dataPtr, void*
|
|
349
|
+
// jsonPtr);
|
|
350
|
+
GoInt32 result = EncryptToJson(partitionIdCobhanBuffer, dataCobhanBuffer,
|
|
351
|
+
cobhanOutputBuffer);
|
|
185
352
|
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
|
366
|
+
Napi::Value Napi_EncryptFromBufferToJson(const Napi::CallbackInfo &info) {
|
|
213
367
|
Napi::Env env = info.Env();
|
|
214
368
|
|
|
215
|
-
if
|
|
216
|
-
|
|
217
|
-
.ThrowAsJavaScriptException();
|
|
218
|
-
return env.Null();
|
|
369
|
+
if(unlikely(verbose_flag)) {
|
|
370
|
+
debug_log("EncryptFromBufferToJson called");
|
|
219
371
|
}
|
|
220
372
|
|
|
221
|
-
if (
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
439
|
+
inputBufferPtr = allocate_cbuffer(input_byte_length);
|
|
440
|
+
inputBuffer = inputBufferPtr.get();
|
|
238
441
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
256
|
-
|
|
465
|
+
if (unlikely(setup_state == 0)) {
|
|
466
|
+
return LogErrorAndThrow(env, encrypt_failed_message +
|
|
467
|
+
std::string("SetupJson not called"));
|
|
468
|
+
}
|
|
257
469
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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&
|
|
559
|
+
Napi::Value Napi_DecryptFromJsonToBuffer(const Napi::CallbackInfo &info) {
|
|
285
560
|
Napi::Env env = info.Env();
|
|
286
561
|
|
|
287
|
-
if
|
|
288
|
-
|
|
289
|
-
.ThrowAsJavaScriptException();
|
|
290
|
-
return env.Null();
|
|
562
|
+
if(unlikely(verbose_flag)) {
|
|
563
|
+
debug_log("DecryptFromJsonToBuffer called");
|
|
291
564
|
}
|
|
292
565
|
|
|
293
|
-
if (
|
|
294
|
-
|
|
295
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
599
|
+
partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
|
|
600
|
+
partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
|
|
310
601
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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&
|
|
699
|
+
Napi::Value Napi_DecryptFromJsonToString(const Napi::CallbackInfo &info) {
|
|
360
700
|
Napi::Env env = info.Env();
|
|
361
701
|
|
|
362
|
-
if
|
|
363
|
-
|
|
364
|
-
.ThrowAsJavaScriptException();
|
|
365
|
-
return env.Null();
|
|
702
|
+
if(unlikely(verbose_flag)) {
|
|
703
|
+
debug_log("DecryptFromJsonToString called");
|
|
366
704
|
}
|
|
367
705
|
|
|
368
|
-
if (
|
|
369
|
-
|
|
370
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
739
|
+
partitionIdCobhanBufferPtr = allocate_cbuffer(partition_utf8_length);
|
|
740
|
+
partitionIdCobhanBuffer = partitionIdCobhanBufferPtr.get();
|
|
385
741
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
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
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
return
|
|
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
|
-
|
|
404
|
-
|
|
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
|
-
|
|
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
|
-
|
|
410
|
-
|
|
411
|
-
|
|
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&
|
|
836
|
+
Napi::Value Napi_Shutdown(const Napi::CallbackInfo &info) {
|
|
429
837
|
Napi::Env env = info.Env();
|
|
430
|
-
|
|
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&
|
|
859
|
+
Napi::Value Napi_SetMaxStackAllocItemSize(const Napi::CallbackInfo &info) {
|
|
436
860
|
Napi::Env env = info.Env();
|
|
437
861
|
|
|
438
|
-
if
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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&
|
|
877
|
+
Napi::Value Napi_SetSafetyPaddingOverhead(const Napi::CallbackInfo &info) {
|
|
451
878
|
Napi::Env env = info.Env();
|
|
452
879
|
|
|
453
|
-
if
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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
|
|
889
|
+
Napi::Number safety_padding_number = info[0].As<Napi::Number>();
|
|
460
890
|
|
|
461
|
-
|
|
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"),
|
|
467
|
-
|
|
468
|
-
exports.Set(Napi::String::New(env, "
|
|
469
|
-
|
|
470
|
-
exports.Set(Napi::String::New(env, "
|
|
471
|
-
|
|
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
|
|