4
4
#include < napi.h>
5
5
#include < vector>
6
6
7
- using ustring = std::vector<uint8_t >;
8
-
9
- static ustring from_buffer (const Napi::Value &value) {
10
- const auto &buf = value.As <Napi::Buffer<uint8_t >>();
11
- const auto &data = buf.Data ();
12
- return {data, data + buf.Length ()};
13
- }
14
-
15
- struct Options {
16
- ustring secret;
17
- ustring ad;
18
-
19
- uint32_t hash_length;
20
- uint32_t time_cost;
21
- uint32_t memory_cost;
22
- uint32_t parallelism;
23
- uint32_t version;
24
-
25
- argon2_type type;
26
- };
27
-
28
- static argon2_context make_context (uint8_t *buf, ustring &plain, ustring &salt,
29
- Options &opts) {
30
- argon2_context ctx;
31
-
32
- ctx.out = buf;
33
- ctx.outlen = opts.hash_length ;
34
- ctx.pwd = plain.data ();
35
- ctx.pwdlen = static_cast <uint32_t >(plain.size ());
36
- ctx.salt = salt.data ();
37
- ctx.saltlen = static_cast <uint32_t >(salt.size ());
38
- ctx.secret = opts.secret .empty () ? nullptr : opts.secret .data ();
39
- ctx.secretlen = static_cast <uint32_t >(opts.secret .size ());
40
- ctx.ad = opts.ad .empty () ? nullptr : opts.ad .data ();
41
- ctx.adlen = static_cast <uint32_t >(opts.ad .size ());
42
- ctx.t_cost = opts.time_cost ;
43
- ctx.m_cost = opts.memory_cost ;
44
- ctx.lanes = opts.parallelism ;
45
- ctx.threads = opts.parallelism ;
46
- ctx.allocate_cbk = nullptr ;
47
- ctx.free_cbk = nullptr ;
48
- ctx.flags = ARGON2_FLAG_CLEAR_PASSWORD | ARGON2_FLAG_CLEAR_SECRET;
49
- ctx.version = opts.version ;
50
-
51
- return ctx;
52
- }
7
+ namespace {
53
8
54
9
class HashWorker final : public Napi::AsyncWorker {
55
10
public:
56
- HashWorker (const Napi::Env &env, ustring &&plain, ustring &&salt,
57
- Options &&opts)
11
+ HashWorker (const Napi::Env &env, const Napi::Buffer<uint8_t > &plain,
12
+ const Napi::Buffer<uint8_t > &salt,
13
+ const Napi::Buffer<uint8_t > &secret,
14
+ const Napi::Buffer<uint8_t > &ad, uint32_t hash_length,
15
+ uint32_t memory_cost, uint32_t time_cost, uint32_t parallelism,
16
+ uint32_t version, uint32_t type)
58
17
: AsyncWorker{env, " argon2:HashWorker" }, deferred{env},
59
- plain{std::move (plain)}, salt{std::move (salt)},
60
- opts{std::move (opts)} {}
18
+ plain{plain.Data (), plain.Data () + plain.ByteLength ()},
19
+ salt{salt.Data (), salt.Data () + salt.ByteLength ()},
20
+ secret{secret.Data (), secret.Data () + secret.ByteLength ()},
21
+ ad{ad.Data (), ad.Data () + ad.ByteLength ()}, hash_length{hash_length},
22
+ memory_cost{memory_cost}, time_cost{time_cost},
23
+ parallelism{parallelism}, version{version},
24
+ type{static_cast <argon2_type>(type)} {}
61
25
62
26
Napi::Promise GetPromise () { return deferred.Promise (); }
63
27
64
28
protected:
65
29
void Execute () override {
66
- hash = std::make_unique<uint8_t []>(opts.hash_length );
67
-
68
- auto ctx = make_context (hash.get (), plain, salt, opts);
69
- int result = argon2_ctx (&ctx, opts.type );
70
-
71
- if (result != ARGON2_OK) {
30
+ hash.resize (hash_length);
31
+
32
+ argon2_context ctx;
33
+ ctx.out = hash.data ();
34
+ ctx.outlen = static_cast <uint32_t >(hash.size ());
35
+ ctx.pwd = plain.data ();
36
+ ctx.pwdlen = static_cast <uint32_t >(plain.size ());
37
+ ctx.salt = salt.data ();
38
+ ctx.saltlen = static_cast <uint32_t >(salt.size ());
39
+ ctx.secret = secret.empty () ? nullptr : secret.data ();
40
+ ctx.secretlen = static_cast <uint32_t >(secret.size ());
41
+ ctx.ad = ad.empty () ? nullptr : ad.data ();
42
+ ctx.adlen = static_cast <uint32_t >(ad.size ());
43
+ ctx.m_cost = memory_cost;
44
+ ctx.t_cost = time_cost;
45
+ ctx.lanes = parallelism;
46
+ ctx.threads = parallelism;
47
+ ctx.allocate_cbk = nullptr ;
48
+ ctx.free_cbk = nullptr ;
49
+ ctx.flags = ARGON2_FLAG_CLEAR_PASSWORD | ARGON2_FLAG_CLEAR_SECRET;
50
+ ctx.version = version;
51
+
52
+ if (int result = argon2_ctx (&ctx, type); result != ARGON2_OK) {
72
53
/* LCOV_EXCL_START */
73
54
SetError (argon2_error_message (result));
74
55
/* LCOV_EXCL_STOP */
@@ -77,43 +58,48 @@ class HashWorker final : public Napi::AsyncWorker {
77
58
78
59
void OnOK () override {
79
60
deferred.Resolve (
80
- Napi::Buffer<uint8_t >::Copy (Env (), hash.get (), opts. hash_length ));
61
+ Napi::Buffer<uint8_t >::Copy (Env (), hash.data (), hash. size () ));
81
62
}
82
63
83
64
void OnError (const Napi::Error &err) override {
84
65
deferred.Reject (err.Value ());
85
66
}
86
67
87
68
private:
69
+ using ustring = std::basic_string<uint8_t >;
70
+
88
71
Napi::Promise::Deferred deferred;
72
+ ustring hash;
73
+
89
74
ustring plain;
90
75
ustring salt;
91
- Options opts;
76
+ ustring secret;
77
+ ustring ad;
92
78
93
- std::unique_ptr<uint8_t []> hash;
94
- };
79
+ uint32_t hash_length;
80
+ uint32_t memory_cost;
81
+ uint32_t time_cost;
82
+ uint32_t parallelism;
83
+ uint32_t version;
95
84
96
- static Options extract_opts (const Napi::Object &opts) {
97
- return {
98
- opts.Has (" secret" ) ? from_buffer (opts[" secret" ]) : ustring{},
99
- opts.Has (" associatedData" ) ? from_buffer (opts[" associatedData" ])
100
- : ustring{},
101
- opts[" hashLength" ].ToNumber (),
102
- opts[" timeCost" ].ToNumber (),
103
- opts[" memoryCost" ].ToNumber (),
104
- opts[" parallelism" ].ToNumber (),
105
- opts[" version" ].ToNumber (),
106
- argon2_type (int (opts[" type" ].ToNumber ())),
107
- };
108
- }
85
+ argon2_type type;
86
+ };
109
87
110
88
static Napi::Value Hash (const Napi::CallbackInfo &info) {
111
- assert (info.Length () == 4 && info[0 ].IsBuffer () && info[1 ].IsBuffer () &&
112
- info[2 ].IsObject ());
113
-
114
- auto worker =
115
- new HashWorker{info.Env (), from_buffer (info[0 ]), from_buffer (info[1 ]),
116
- extract_opts (info[2 ].As <Napi::Object>())};
89
+ NAPI_CHECK (info.Length () == 1 , " Hash" , " expected 1 argument" );
90
+
91
+ const auto &args = info[0 ].As <Napi::Object>();
92
+ auto worker = new HashWorker{info.Env (),
93
+ args[" password" ].As <Napi::Buffer<uint8_t >>(),
94
+ args[" salt" ].As <Napi::Buffer<uint8_t >>(),
95
+ args[" secret" ].As <Napi::Buffer<uint8_t >>(),
96
+ args[" data" ].As <Napi::Buffer<uint8_t >>(),
97
+ args[" hashLength" ].ToNumber (),
98
+ args[" m" ].ToNumber (),
99
+ args[" t" ].ToNumber (),
100
+ args[" p" ].ToNumber (),
101
+ args[" version" ].ToNumber (),
102
+ args[" type" ].ToNumber ()};
117
103
118
104
worker->Queue ();
119
105
return worker->GetPromise ();
@@ -124,4 +110,6 @@ static Napi::Object init(Napi::Env env, Napi::Object exports) {
124
110
return exports;
125
111
}
126
112
113
+ } // namespace
114
+
127
115
NODE_API_MODULE (argon2_lib, init)
0 commit comments