110 lines
2.9 KiB
C++
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)
|