mtcute/packages/crypto-node/lib/entry.cpp

110 lines
2.9 KiB
C++

#include <assert.h>
#define NAPI_VERSION 1
#include <node_api.h>
#include "ige256.h"
#ifndef NODE_GYP_MODULE_NAME
#define NODE_GYP_MODULE_NAME crypto
#endif
// maybe i love macros a bit too much
#define CALL_ASSERT_OK(code) \
status = code; \
assert(status == napi_ok);
#define THROW_WRONG_ARGS \
napi_throw_type_error(env, NULL, "Wrong arguments"); \
return NULL;
#define CHECK_ARG_COUNT(cnt) \
if (argc < cnt) { \
THROW_WRONG_ARGS \
}
#define CHECK_ARG_BUFFER(idx) \
CALL_ASSERT_OK(napi_is_buffer(env, args[idx], &is_buf)) \
if (!is_buf) { \
THROW_WRONG_ARGS \
}
#define READ_BUF_ARG(idx, out_buf, out_size) \
CALL_ASSERT_OK(napi_get_buffer_info(env, args[idx], (void**) out_buf, out_size))
#define READ_BOOL_ARG(idx, out) \
CALL_ASSERT_OK(napi_get_value_bool(env, args[idx], out))
#define READ_ARGS(n) \
size_t argc = n; \
napi_value args[n]; \
status = napi_get_cb_info(env, info, &argc, args, NULL, NULL); \
assert(status == napi_ok);
#define WRAP_KEY_IV_METHOD(name, ivSize) \
static napi_value node_##name(napi_env env, napi_callback_info info) { \
napi_status status; \
bool is_buf; \
\
uint8_t* input_buf; \
uint8_t* key_buf; \
uint8_t* iv_buf; \
uint8_t* output_buf; \
\
size_t size; \
\
READ_ARGS(3) \
\
CHECK_ARG_COUNT(3) \
CHECK_ARG_BUFFER(0) \
CHECK_ARG_BUFFER(1) \
CHECK_ARG_BUFFER(2) \
\
READ_BUF_ARG(1, &key_buf, &size); \
if (size != 32) { \
THROW_WRONG_ARGS \
} \
READ_BUF_ARG(2, &iv_buf, &size); \
if (size != ivSize) { \
THROW_WRONG_ARGS \
} \
READ_BUF_ARG(0, &input_buf, &size); \
if (size % 16 != 0) { \
THROW_WRONG_ARGS \
} \
\
napi_value ret; \
CALL_ASSERT_OK(napi_create_buffer(env, size, (void**) &output_buf, &ret)); \
\
name(env, input_buf, size, key_buf, iv_buf, output_buf); \
\
return ret; \
}
WRAP_KEY_IV_METHOD(ige256_encrypt, 32)
WRAP_KEY_IV_METHOD(ige256_decrypt, 32)
#define DECLARE_NAPI_METHOD(name, func) \
{ name, 0, func, 0, 0, 0, napi_default, 0 }
#define EXPORT_METHOD(name, func) \
desc = DECLARE_NAPI_METHOD(name, func); \
CALL_ASSERT_OK(napi_define_properties(env, exports, 1, &desc));
static napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor desc;
// nodejs is bundled with openssl, thus the only
// mode that it makes sense to implement in native code is
// IGE, since it is not implemented by openssl.
//
// benchmarks have shown that openssl is much faster
// than this implementation for cbc and ctr modes.
EXPORT_METHOD("ige256_encrypt", node_ige256_encrypt)
EXPORT_METHOD("ige256_decrypt", node_ige256_decrypt)
return exports;
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)