bdy 1.23.6-dev → 1.23.7-dev

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.
Files changed (205) hide show
  1. package/distTs/package.json +10 -2
  2. package/distTs/src/agent/linux.js +53 -3
  3. package/distTs/src/agent/manager.js +3 -6
  4. package/distTs/src/agent/osx.js +51 -3
  5. package/distTs/src/agent/system.js +400 -21
  6. package/distTs/src/agent/windows.js +4 -7
  7. package/distTs/src/command/agent/debug.js +2 -2
  8. package/distTs/src/command/agent/install.js +37 -10
  9. package/distTs/src/command/agent/restart.js +2 -2
  10. package/distTs/src/command/agent/run.js +3 -0
  11. package/distTs/src/command/agent/start.js +2 -2
  12. package/distTs/src/command/agent/status.js +19 -0
  13. package/distTs/src/command/agent/stop.js +2 -2
  14. package/distTs/src/command/agent/uninstall.js +5 -8
  15. package/distTs/src/command/agent/update.js +2 -2
  16. package/distTs/src/command/artifact/publish.js +3 -1
  17. package/distTs/src/command/version.js +13 -5
  18. package/distTs/src/logger.js +40 -4
  19. package/distTs/src/texts.js +35 -19
  20. package/distTs/src/utils.js +98 -3
  21. package/node_modules/asn1/Jenkinsfile +65 -0
  22. package/node_modules/asn1/LICENSE +19 -0
  23. package/node_modules/asn1/README.md +50 -0
  24. package/node_modules/asn1/lib/ber/errors.js +13 -0
  25. package/node_modules/asn1/lib/ber/index.js +27 -0
  26. package/node_modules/asn1/lib/ber/reader.js +262 -0
  27. package/node_modules/asn1/lib/ber/types.js +36 -0
  28. package/node_modules/asn1/lib/ber/writer.js +317 -0
  29. package/node_modules/asn1/lib/index.js +20 -0
  30. package/node_modules/asn1/package.json +31 -0
  31. package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
  32. package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
  33. package/node_modules/bcrypt-pbkdf/README.md +45 -0
  34. package/node_modules/bcrypt-pbkdf/index.js +556 -0
  35. package/node_modules/bcrypt-pbkdf/package.json +15 -0
  36. package/node_modules/safer-buffer/LICENSE +21 -0
  37. package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  38. package/node_modules/safer-buffer/Readme.md +156 -0
  39. package/node_modules/safer-buffer/dangerous.js +58 -0
  40. package/node_modules/safer-buffer/package.json +34 -0
  41. package/node_modules/safer-buffer/safer.js +77 -0
  42. package/node_modules/safer-buffer/tests.js +406 -0
  43. package/node_modules/ssh2/.eslintignore +4 -0
  44. package/node_modules/ssh2/.eslintrc.js +5 -0
  45. package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
  46. package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
  47. package/node_modules/ssh2/LICENSE +19 -0
  48. package/node_modules/ssh2/README.md +1529 -0
  49. package/node_modules/ssh2/SFTP.md +413 -0
  50. package/node_modules/ssh2/examples/server-chat.js +238 -0
  51. package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
  52. package/node_modules/ssh2/install.js +27 -0
  53. package/node_modules/ssh2/lib/Channel.js +295 -0
  54. package/node_modules/ssh2/lib/agent.js +1123 -0
  55. package/node_modules/ssh2/lib/client.js +2176 -0
  56. package/node_modules/ssh2/lib/http-agents.js +84 -0
  57. package/node_modules/ssh2/lib/index.js +44 -0
  58. package/node_modules/ssh2/lib/keygen.js +582 -0
  59. package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
  60. package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
  61. package/node_modules/ssh2/lib/protocol/constants.js +356 -0
  62. package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
  63. package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
  64. package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
  65. package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
  66. package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
  67. package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
  68. package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
  69. package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
  70. package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
  71. package/node_modules/ssh2/lib/protocol/utils.js +356 -0
  72. package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
  73. package/node_modules/ssh2/lib/server.js +1380 -0
  74. package/node_modules/ssh2/lib/utils.js +336 -0
  75. package/node_modules/ssh2/package.json +49 -0
  76. package/node_modules/ssh2/test/common.js +316 -0
  77. package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
  78. package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
  79. package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
  80. package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
  81. package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
  82. package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
  83. package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
  84. package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
  85. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
  86. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
  87. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
  88. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
  89. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
  90. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
  91. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
  92. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
  93. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
  94. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
  95. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
  96. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
  97. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
  98. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
  99. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
  100. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
  101. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
  102. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
  103. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
  104. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
  105. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
  106. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
  107. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
  108. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
  109. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
  110. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
  111. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
  112. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
  113. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
  114. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
  115. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
  116. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
  117. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
  118. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
  119. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
  120. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
  121. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
  122. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
  123. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
  124. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
  125. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
  126. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
  127. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
  128. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
  129. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
  130. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
  131. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
  132. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
  133. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
  134. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
  135. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
  136. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
  137. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
  138. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
  139. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
  140. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
  141. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
  142. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
  143. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
  144. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
  145. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
  146. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
  147. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
  148. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
  149. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
  150. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
  151. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
  152. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
  153. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
  154. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
  155. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
  156. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
  157. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
  158. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
  159. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
  160. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
  161. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
  162. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
  163. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
  164. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
  165. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
  166. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
  167. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
  168. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
  169. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
  170. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
  171. package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
  172. package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
  173. package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
  174. package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
  175. package/node_modules/ssh2/test/test-exec.js +578 -0
  176. package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
  177. package/node_modules/ssh2/test/test-keygen.js +60 -0
  178. package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
  179. package/node_modules/ssh2/test/test-openssh.js +261 -0
  180. package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
  181. package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
  182. package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
  183. package/node_modules/ssh2/test/test-sftp.js +842 -0
  184. package/node_modules/ssh2/test/test-shell.js +109 -0
  185. package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
  186. package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
  187. package/node_modules/ssh2/test/test-userauth.js +611 -0
  188. package/node_modules/ssh2/test/test-worker-imports.js +25 -0
  189. package/node_modules/ssh2/test/test.js +20 -0
  190. package/node_modules/ssh2/util/build_pagent.bat +2 -0
  191. package/node_modules/ssh2/util/pagent.c +88 -0
  192. package/node_modules/ssh2/util/pagent.exe +0 -0
  193. package/node_modules/tweetnacl/.npmignore +4 -0
  194. package/node_modules/tweetnacl/AUTHORS.md +28 -0
  195. package/node_modules/tweetnacl/CHANGELOG.md +221 -0
  196. package/node_modules/tweetnacl/LICENSE +24 -0
  197. package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
  198. package/node_modules/tweetnacl/README.md +459 -0
  199. package/node_modules/tweetnacl/nacl-fast.js +2388 -0
  200. package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
  201. package/node_modules/tweetnacl/nacl.d.ts +98 -0
  202. package/node_modules/tweetnacl/nacl.js +1175 -0
  203. package/node_modules/tweetnacl/nacl.min.js +1 -0
  204. package/node_modules/tweetnacl/package.json +58 -0
  205. package/package.json +10 -2
@@ -0,0 +1,2300 @@
1
+ #if defined(__GNUC__) && __GNUC__ >= 8
2
+ #define DISABLE_WCAST_FUNCTION_TYPE _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"")
3
+ #define DISABLE_WCAST_FUNCTION_TYPE_END _Pragma("GCC diagnostic pop")
4
+ #else
5
+ #define DISABLE_WCAST_FUNCTION_TYPE
6
+ #define DISABLE_WCAST_FUNCTION_TYPE_END
7
+ #endif
8
+
9
+ #include <stdio.h>
10
+ #include <string.h>
11
+ #include <assert.h>
12
+
13
+ DISABLE_WCAST_FUNCTION_TYPE
14
+ #include <node.h>
15
+ #include <node_buffer.h>
16
+ #include <nan.h>
17
+ DISABLE_WCAST_FUNCTION_TYPE_END
18
+
19
+ #if NODE_MAJOR_VERSION >= 17
20
+ # include <openssl/configuration.h>
21
+ #endif
22
+
23
+ #include <openssl/err.h>
24
+ #include <openssl/evp.h>
25
+ #include <openssl/hmac.h>
26
+
27
+ #ifndef _WIN32
28
+ # include <dlfcn.h>
29
+ #endif
30
+
31
+ typedef int (*ctx_iv_len_func)(const EVP_CIPHER_CTX*);
32
+ typedef int (*ctx_key_len_func)(const EVP_CIPHER_CTX*);
33
+ typedef int (*ctx_get_block_size_func)(const EVP_CIPHER_CTX*);
34
+ typedef int (*cipher_flags_func)(const EVP_CIPHER*);
35
+ ctx_iv_len_func ctx_iv_len = nullptr;
36
+ ctx_key_len_func ctx_key_len = nullptr;
37
+ ctx_get_block_size_func ctx_get_block_size = nullptr;
38
+ cipher_flags_func cipher_flags = nullptr;
39
+
40
+ #if REAL_OPENSSL_MAJOR < 3
41
+ # undef EVP_DigestSignUpdate
42
+ # define EVP_DigestSignUpdate EVP_DigestUpdate
43
+ # undef EVP_PKEY_OP_SIGNCTX
44
+ # define EVP_PKEY_OP_SIGNCTX (1 << 6)
45
+ #endif
46
+
47
+ using namespace node;
48
+ using namespace v8;
49
+ using namespace std;
50
+
51
+ struct MarkPopErrorOnReturn {
52
+ MarkPopErrorOnReturn() { ERR_set_mark(); }
53
+ ~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
54
+ };
55
+
56
+ enum ErrorType {
57
+ kErrNone,
58
+ kErrOpenSSL,
59
+ kErrBadIVLen,
60
+ kErrBadKeyLen,
61
+ kErrAADFailure,
62
+ kErrTagFailure,
63
+ kErrPartialEncrypt,
64
+ kErrBadCipherName,
65
+ kErrBadHMACName,
66
+ kErrBadHMACLen,
67
+ kErrBadInit,
68
+ kErrPartialDecrypt,
69
+ kErrInvalidMAC,
70
+ kErrBadBlockLen
71
+ };
72
+
73
+ #define MAX_MAC_LEN 64
74
+
75
+ #define POLY1305_KEYLEN 32
76
+ #define POLY1305_TAGLEN 16
77
+ class ChaChaPolyCipher : public ObjectWrap {
78
+ public:
79
+ static NAN_MODULE_INIT(Init) {
80
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
81
+ tpl->SetClassName(Nan::New("ChaChaPolyCipher").ToLocalChecked());
82
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
83
+
84
+ SetPrototypeMethod(tpl, "encrypt", Encrypt);
85
+ SetPrototypeMethod(tpl, "free", Free);
86
+
87
+ Local<Function> func = Nan::GetFunction(tpl).ToLocalChecked();
88
+ Local<Context> context = Nan::GetCurrentContext();
89
+ v8::Isolate* isolate = context->GetIsolate();
90
+
91
+ constructor().Set(isolate, func);
92
+
93
+ Nan::Set(target,
94
+ Nan::New("ChaChaPolyCipher").ToLocalChecked(),
95
+ func);
96
+ }
97
+
98
+ private:
99
+ explicit ChaChaPolyCipher()
100
+ : ctx_main_(nullptr),
101
+ ctx_pktlen_(nullptr),
102
+ #if REAL_OPENSSL_MAJOR >= 3
103
+ mac_(nullptr),
104
+ mac_ctx_(nullptr) {}
105
+ #else
106
+ md_ctx_(nullptr),
107
+ polykey_(nullptr),
108
+ polykey_ctx_(nullptr) {}
109
+ #endif
110
+
111
+ ~ChaChaPolyCipher() {
112
+ clear();
113
+ }
114
+
115
+ void clear() {
116
+ if (ctx_pktlen_) {
117
+ EVP_CIPHER_CTX_free(ctx_pktlen_);
118
+ ctx_pktlen_ = nullptr;
119
+ }
120
+ if (ctx_main_) {
121
+ EVP_CIPHER_CTX_free(ctx_main_);
122
+ ctx_main_ = nullptr;
123
+ }
124
+ #if REAL_OPENSSL_MAJOR >= 3
125
+ if (mac_ctx_) {
126
+ EVP_MAC_CTX_free(mac_ctx_);
127
+ mac_ctx_ = nullptr;
128
+ }
129
+ if (mac_) {
130
+ EVP_MAC_free(mac_);
131
+ mac_ = nullptr;
132
+ }
133
+ #else
134
+ if (polykey_) {
135
+ EVP_PKEY_free(polykey_);
136
+ polykey_ = nullptr;
137
+ }
138
+ if (md_ctx_) {
139
+ EVP_MD_CTX_free(md_ctx_);
140
+ md_ctx_ = nullptr;
141
+ }
142
+ // `polykey_ctx_` is not explicitly freed as it is freed implicitly when
143
+ // `md_ctx_` is freed
144
+ #endif
145
+ }
146
+
147
+ ErrorType init(unsigned char* keys, size_t keys_len) {
148
+ ErrorType r = kErrNone;
149
+ const EVP_CIPHER* const cipher = EVP_get_cipherbyname("chacha20");
150
+
151
+ if (keys_len != 64) {
152
+ r = kErrBadKeyLen;
153
+ goto out;
154
+ }
155
+
156
+ if (cipher == nullptr) {
157
+ r = kErrOpenSSL;
158
+ goto out;
159
+ }
160
+
161
+ if ((ctx_pktlen_ = EVP_CIPHER_CTX_new()) == nullptr
162
+ || (ctx_main_ = EVP_CIPHER_CTX_new()) == nullptr
163
+ #if REAL_OPENSSL_MAJOR >= 3
164
+ || (mac_ = EVP_MAC_fetch(nullptr,
165
+ "POLY1305",
166
+ "provider=default")) == nullptr
167
+ || (mac_ctx_ = EVP_MAC_CTX_new(mac_)) == nullptr
168
+ #else
169
+ || (md_ctx_ = EVP_MD_CTX_new()) == nullptr
170
+ #endif
171
+ || EVP_EncryptInit_ex(ctx_pktlen_,
172
+ cipher,
173
+ nullptr,
174
+ keys + 32,
175
+ nullptr) != 1
176
+ || EVP_EncryptInit_ex(ctx_main_,
177
+ cipher,
178
+ nullptr,
179
+ keys,
180
+ nullptr) != 1) {
181
+ r = kErrOpenSSL;
182
+ goto out;
183
+ }
184
+ if (ctx_iv_len(ctx_pktlen_) != 16) {
185
+ r = kErrBadIVLen;
186
+ goto out;
187
+ }
188
+
189
+ out:
190
+ return r;
191
+ }
192
+
193
+ ErrorType encrypt(unsigned char* packet,
194
+ uint32_t packet_len,
195
+ uint32_t seqno) {
196
+ ErrorType r = kErrNone;
197
+ size_t sig_len = 16;
198
+ int outlen = 0;
199
+
200
+ // `packet` layout:
201
+ // <packet length> <padding length> <payload> <padding> <poly1305 mac>
202
+ uint32_t data_len = packet_len - POLY1305_TAGLEN;
203
+
204
+ unsigned char polykey[POLY1305_KEYLEN] = {0};
205
+
206
+ uint8_t seqbuf[16] = {0};
207
+ ((uint8_t*)(seqbuf))[12] = (seqno >> 24) & 0xff;
208
+ ((uint8_t*)(seqbuf))[13] = (seqno >> 16) & 0xff;
209
+ ((uint8_t*)(seqbuf))[14] = (seqno >> 8) & 0xff;
210
+ ((uint8_t*)(seqbuf))[15] = seqno & 0xff;
211
+
212
+ // Generate Poly1305 key
213
+ if (EVP_EncryptInit_ex(ctx_main_, nullptr, nullptr, nullptr, seqbuf) != 1) {
214
+ r = kErrOpenSSL;
215
+ goto out;
216
+ }
217
+ if (EVP_EncryptUpdate(ctx_main_,
218
+ polykey,
219
+ &outlen,
220
+ polykey,
221
+ sizeof(polykey)) != 1) {
222
+ r = kErrOpenSSL;
223
+ goto out;
224
+ }
225
+ if (static_cast<size_t>(outlen) != sizeof(polykey)) {
226
+ r = kErrPartialEncrypt;
227
+ goto out;
228
+ }
229
+
230
+ // Encrypt packet length
231
+ if (EVP_EncryptInit_ex(ctx_pktlen_,
232
+ nullptr,
233
+ nullptr,
234
+ nullptr,
235
+ seqbuf) != 1) {
236
+ r = kErrOpenSSL;
237
+ goto out;
238
+ }
239
+ if (EVP_EncryptUpdate(ctx_pktlen_, packet, &outlen, packet, 4) != 1) {
240
+ r = kErrOpenSSL;
241
+ goto out;
242
+ }
243
+ if (static_cast<size_t>(outlen) != 4) {
244
+ r = kErrPartialEncrypt;
245
+ goto out;
246
+ }
247
+
248
+ // Encrypt rest of packet
249
+ seqbuf[0] = 1;
250
+ if (EVP_EncryptInit_ex(ctx_main_, nullptr, nullptr, nullptr, seqbuf) != 1) {
251
+ r = kErrOpenSSL;
252
+ goto out;
253
+ }
254
+ if (EVP_EncryptUpdate(ctx_main_,
255
+ packet + 4,
256
+ &outlen,
257
+ packet + 4,
258
+ data_len - 4) != 1) {
259
+ r = kErrOpenSSL;
260
+ goto out;
261
+ }
262
+ if (static_cast<size_t>(outlen) != data_len - 4) {
263
+ r = kErrPartialEncrypt;
264
+ goto out;
265
+ }
266
+
267
+ // Poly1305 over ciphertext
268
+ #if REAL_OPENSSL_MAJOR >= 3
269
+ // TODO: check if dup()'ing a "base" context instead of calling init() with
270
+ // the key each time is faster
271
+ if (EVP_MAC_init(mac_ctx_, polykey, sizeof(polykey), nullptr) != 1
272
+ || EVP_MAC_update(mac_ctx_, packet, data_len) != 1
273
+ || EVP_MAC_final(mac_ctx_, packet + data_len, &sig_len, sig_len) != 1) {
274
+ r = kErrOpenSSL;
275
+ goto out;
276
+ }
277
+ #else
278
+ if (polykey_) {
279
+ if (EVP_PKEY_CTX_ctrl(polykey_ctx_,
280
+ -1,
281
+ EVP_PKEY_OP_SIGNCTX,
282
+ EVP_PKEY_CTRL_SET_MAC_KEY,
283
+ sizeof(polykey),
284
+ (void*)polykey) <= 0) {
285
+ r = kErrOpenSSL;
286
+ goto out;
287
+ }
288
+ } else {
289
+ polykey_ = EVP_PKEY_new_raw_private_key(EVP_PKEY_POLY1305,
290
+ nullptr,
291
+ polykey,
292
+ sizeof(polykey));
293
+ if (polykey_ == nullptr) {
294
+ r = kErrOpenSSL;
295
+ goto out;
296
+ }
297
+
298
+ if (!EVP_DigestSignInit(md_ctx_,
299
+ &polykey_ctx_,
300
+ nullptr,
301
+ nullptr,
302
+ polykey_)) {
303
+ r = kErrOpenSSL;
304
+ goto out;
305
+ }
306
+ }
307
+
308
+ // Generate and write Poly1305 tag
309
+ if (EVP_DigestSign(md_ctx_,
310
+ packet + data_len,
311
+ &sig_len,
312
+ packet,
313
+ data_len) != 1) {
314
+ r = kErrOpenSSL;
315
+ goto out;
316
+ }
317
+ #endif
318
+
319
+ out:
320
+ return r;
321
+ }
322
+
323
+ static NAN_METHOD(New) {
324
+ MarkPopErrorOnReturn mark_pop_error_on_return;
325
+
326
+ if (!Buffer::HasInstance(info[0]))
327
+ return Nan::ThrowTypeError("Missing/Invalid keys");
328
+
329
+ ChaChaPolyCipher* obj = new ChaChaPolyCipher();
330
+ ErrorType r = obj->init(
331
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
332
+ Buffer::Length(info[0])
333
+ );
334
+ if (r != kErrNone) {
335
+ if (r == kErrOpenSSL) {
336
+ char msg_buf[128] = {0};
337
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
338
+ ERR_clear_error();
339
+ obj->clear();
340
+ delete obj;
341
+ return Nan::ThrowError(msg_buf);
342
+ }
343
+ obj->clear();
344
+ delete obj;
345
+ switch (r) {
346
+ case kErrBadKeyLen:
347
+ return Nan::ThrowError("Invalid keys length");
348
+ case kErrBadIVLen:
349
+ return Nan::ThrowError("Invalid IV length");
350
+ default:
351
+ return Nan::ThrowError("Unknown init failure");
352
+ }
353
+ }
354
+
355
+ obj->Wrap(info.This());
356
+ info.GetReturnValue().Set(info.This());
357
+ }
358
+
359
+ static NAN_METHOD(Encrypt) {
360
+ MarkPopErrorOnReturn mark_pop_error_on_return;
361
+
362
+ ChaChaPolyCipher* obj = ObjectWrap::Unwrap<ChaChaPolyCipher>(info.Holder());
363
+
364
+ if (!Buffer::HasInstance(info[0]))
365
+ return Nan::ThrowTypeError("Missing/Invalid packet");
366
+
367
+ if (!info[1]->IsUint32())
368
+ return Nan::ThrowTypeError("Missing/Invalid sequence number");
369
+
370
+ ErrorType r = obj->encrypt(
371
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
372
+ Buffer::Length(info[0]),
373
+ Nan::To<uint32_t>(info[1]).FromJust()
374
+ );
375
+ switch (r) {
376
+ case kErrNone:
377
+ return;
378
+ case kErrOpenSSL: {
379
+ char msg_buf[128] = {0};
380
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
381
+ ERR_clear_error();
382
+ return Nan::ThrowError(msg_buf);
383
+ }
384
+ default:
385
+ return Nan::ThrowError("Unknown encrypt failure");
386
+ }
387
+ }
388
+
389
+ static NAN_METHOD(Free) {
390
+ ChaChaPolyCipher* obj = ObjectWrap::Unwrap<ChaChaPolyCipher>(info.Holder());
391
+ obj->clear();
392
+ }
393
+
394
+ static inline v8::Eternal<v8::Function> & constructor() {
395
+ static v8::Eternal<v8::Function> my_constructor;
396
+ return my_constructor;
397
+ }
398
+
399
+ EVP_CIPHER_CTX* ctx_main_;
400
+ EVP_CIPHER_CTX* ctx_pktlen_;
401
+ #if REAL_OPENSSL_MAJOR >= 3
402
+ EVP_MAC* mac_;
403
+ EVP_MAC_CTX* mac_ctx_;
404
+ #else
405
+ EVP_MD_CTX* md_ctx_;
406
+ EVP_PKEY* polykey_;
407
+ EVP_PKEY_CTX* polykey_ctx_;
408
+ #endif
409
+ };
410
+
411
+ class AESGCMCipher : public ObjectWrap {
412
+ public:
413
+ static NAN_MODULE_INIT(Init) {
414
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
415
+ tpl->SetClassName(Nan::New("AESGCMCipher").ToLocalChecked());
416
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
417
+
418
+ SetPrototypeMethod(tpl, "encrypt", Encrypt);
419
+ SetPrototypeMethod(tpl, "free", Free);
420
+
421
+ Local<Function> func = Nan::GetFunction(tpl).ToLocalChecked();
422
+ Local<Context> context = Nan::GetCurrentContext();
423
+ v8::Isolate* isolate = context->GetIsolate();
424
+
425
+ constructor().Set(isolate, func);
426
+
427
+ Nan::Set(target,
428
+ Nan::New("AESGCMCipher").ToLocalChecked(),
429
+ func);
430
+ }
431
+
432
+ private:
433
+ explicit AESGCMCipher() : ctx_(nullptr) {}
434
+
435
+ ~AESGCMCipher() {
436
+ clear();
437
+ }
438
+
439
+ void clear() {
440
+ if (ctx_) {
441
+ EVP_CIPHER_CTX_free(ctx_);
442
+ ctx_ = nullptr;
443
+ }
444
+ }
445
+
446
+ ErrorType init(const char* name,
447
+ unsigned char* key,
448
+ size_t key_len,
449
+ unsigned char* iv,
450
+ size_t iv_len) {
451
+ ErrorType r = kErrNone;
452
+
453
+ const EVP_CIPHER* const cipher = EVP_get_cipherbyname(name);
454
+ if (cipher == nullptr) {
455
+ r = kErrOpenSSL;
456
+ goto out;
457
+ }
458
+
459
+ if (cipher != EVP_aes_128_gcm() && cipher != EVP_aes_256_gcm()) {
460
+ r = kErrBadCipherName;
461
+ goto out;
462
+ }
463
+
464
+ if ((ctx_ = EVP_CIPHER_CTX_new()) == nullptr
465
+ || EVP_EncryptInit_ex(ctx_, cipher, nullptr, nullptr, nullptr) != 1) {
466
+ r = kErrOpenSSL;
467
+ goto out;
468
+ }
469
+
470
+ if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr)) {
471
+ r = kErrOpenSSL;
472
+ goto out;
473
+ }
474
+
475
+ if (key_len != static_cast<size_t>(ctx_key_len(ctx_))) {
476
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
477
+ r = kErrBadKeyLen;
478
+ goto out;
479
+ }
480
+ }
481
+
482
+ // Set key and IV
483
+ if (EVP_EncryptInit_ex(ctx_, nullptr, nullptr, key, iv) != 1) {
484
+ r = kErrOpenSSL;
485
+ goto out;
486
+ }
487
+ if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) {
488
+ r = kErrOpenSSL;
489
+ goto out;
490
+ }
491
+
492
+ // Disable padding
493
+ EVP_CIPHER_CTX_set_padding(ctx_, 0);
494
+
495
+ out:
496
+ return r;
497
+ }
498
+
499
+ ErrorType encrypt(unsigned char* packet, uint32_t packet_len) {
500
+ ErrorType r = kErrNone;
501
+
502
+ // `packet` layout:
503
+ // <packet length> <padding length> <payload> <padding> <mac>
504
+ uint32_t data_len = packet_len - 16;
505
+
506
+ int outlen = 0;
507
+
508
+ // Increment IV
509
+ unsigned char lastiv[1];
510
+ if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) {
511
+ r = kErrOpenSSL;
512
+ goto out;
513
+ }
514
+
515
+ // Set AAD (the packet length)
516
+ if (!EVP_EncryptUpdate(ctx_, nullptr, &outlen, packet, 4)) {
517
+ r = kErrOpenSSL;
518
+ goto out;
519
+ }
520
+ if (outlen != 4) {
521
+ r = kErrAADFailure;
522
+ goto out;
523
+ }
524
+
525
+ // Encrypt everything but the packet length
526
+ if (EVP_EncryptUpdate(ctx_,
527
+ packet + 4,
528
+ &outlen,
529
+ packet + 4,
530
+ data_len - 4) != 1) {
531
+ r = kErrOpenSSL;
532
+ goto out;
533
+ }
534
+ if (static_cast<size_t>(outlen) != data_len - 4) {
535
+ r = kErrPartialEncrypt;
536
+ goto out;
537
+ }
538
+
539
+ // Generate authentication tag
540
+ if (!EVP_EncryptFinal_ex(ctx_, nullptr, &outlen)) {
541
+ r = kErrOpenSSL;
542
+ goto out;
543
+ }
544
+
545
+ // Write authentication tag
546
+ if (EVP_CIPHER_CTX_ctrl(ctx_,
547
+ EVP_CTRL_AEAD_GET_TAG,
548
+ 16,
549
+ packet + data_len) != 1) {
550
+ r = kErrOpenSSL;
551
+ goto out;
552
+ }
553
+
554
+ out:
555
+ return r;
556
+ }
557
+
558
+ static NAN_METHOD(New) {
559
+ MarkPopErrorOnReturn mark_pop_error_on_return;
560
+
561
+ if (!info[0]->IsString())
562
+ return Nan::ThrowTypeError("Missing/Invalid OpenSSL cipher name");
563
+
564
+ if (!Buffer::HasInstance(info[1]))
565
+ return Nan::ThrowTypeError("Missing/Invalid key");
566
+
567
+ if (!Buffer::HasInstance(info[2]))
568
+ return Nan::ThrowTypeError("Missing/Invalid iv");
569
+
570
+ const Nan::Utf8String cipher_name(info[0]);
571
+
572
+ AESGCMCipher* obj = new AESGCMCipher();
573
+ ErrorType r = obj->init(
574
+ *cipher_name,
575
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[1])),
576
+ Buffer::Length(info[1]),
577
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[2])),
578
+ Buffer::Length(info[2])
579
+ );
580
+ if (r != kErrNone) {
581
+ if (r == kErrOpenSSL) {
582
+ char msg_buf[128] = {0};
583
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
584
+ ERR_clear_error();
585
+ obj->clear();
586
+ delete obj;
587
+ return Nan::ThrowError(msg_buf);
588
+ }
589
+ obj->clear();
590
+ delete obj;
591
+ switch (r) {
592
+ case kErrBadKeyLen:
593
+ return Nan::ThrowError("Invalid keys length");
594
+ case kErrBadIVLen:
595
+ return Nan::ThrowError("Invalid IV length");
596
+ case kErrBadCipherName:
597
+ return Nan::ThrowError("Invalid AES GCM cipher name");
598
+ default:
599
+ return Nan::ThrowError("Unknown init failure");
600
+ }
601
+ }
602
+
603
+ obj->Wrap(info.This());
604
+ info.GetReturnValue().Set(info.This());
605
+ }
606
+
607
+ static NAN_METHOD(Encrypt) {
608
+ MarkPopErrorOnReturn mark_pop_error_on_return;
609
+
610
+ AESGCMCipher* obj = ObjectWrap::Unwrap<AESGCMCipher>(info.Holder());
611
+
612
+ if (!Buffer::HasInstance(info[0]))
613
+ return Nan::ThrowTypeError("Missing/Invalid packet");
614
+
615
+ ErrorType r = obj->encrypt(
616
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
617
+ Buffer::Length(info[0])
618
+ );
619
+ switch (r) {
620
+ case kErrNone:
621
+ return;
622
+ case kErrAADFailure:
623
+ return Nan::ThrowError("Error setting AAD");
624
+ case kErrPartialEncrypt:
625
+ return Nan::ThrowError("Failed to completely encrypt packet");
626
+ case kErrTagFailure:
627
+ return Nan::ThrowError("Error generating authentication tag");
628
+ case kErrOpenSSL: {
629
+ char msg_buf[128] = {0};
630
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
631
+ ERR_clear_error();
632
+ return Nan::ThrowError(msg_buf);
633
+ }
634
+ default:
635
+ return Nan::ThrowError("Unknown encrypt failure");
636
+ }
637
+ }
638
+
639
+ static NAN_METHOD(Free) {
640
+ AESGCMCipher* obj = ObjectWrap::Unwrap<AESGCMCipher>(info.Holder());
641
+ obj->clear();
642
+ }
643
+
644
+ static inline v8::Eternal<v8::Function> & constructor() {
645
+ static v8::Eternal<v8::Function> my_constructor;
646
+ return my_constructor;
647
+ }
648
+
649
+ EVP_CIPHER_CTX* ctx_;
650
+ };
651
+
652
+ class GenericCipher : public ObjectWrap {
653
+ public:
654
+ static NAN_MODULE_INIT(Init) {
655
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
656
+ tpl->SetClassName(Nan::New("GenericCipher").ToLocalChecked());
657
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
658
+
659
+ SetPrototypeMethod(tpl, "encrypt", Encrypt);
660
+ SetPrototypeMethod(tpl, "free", Free);
661
+
662
+ Local<Function> func = Nan::GetFunction(tpl).ToLocalChecked();
663
+ Local<Context> context = Nan::GetCurrentContext();
664
+ v8::Isolate* isolate = context->GetIsolate();
665
+
666
+ constructor().Set(isolate, func);
667
+
668
+ Nan::Set(target,
669
+ Nan::New("GenericCipher").ToLocalChecked(),
670
+ func);
671
+ }
672
+
673
+ private:
674
+ explicit GenericCipher()
675
+ : ctx_(nullptr),
676
+ #if REAL_OPENSSL_MAJOR >= 3
677
+ mac_(nullptr),
678
+ mac_ctx_base_(nullptr),
679
+ #else
680
+ ctx_hmac_(nullptr),
681
+ #endif
682
+ hmac_len_(0),
683
+ is_etm_(0) {}
684
+
685
+ ~GenericCipher() {
686
+ clear();
687
+ }
688
+
689
+ void clear() {
690
+ if (ctx_) {
691
+ EVP_CIPHER_CTX_free(ctx_);
692
+ ctx_ = nullptr;
693
+ }
694
+ #if REAL_OPENSSL_MAJOR >= 3
695
+ if (mac_ctx_base_) {
696
+ EVP_MAC_CTX_free(mac_ctx_base_);
697
+ mac_ctx_base_ = nullptr;
698
+ }
699
+ if (mac_) {
700
+ EVP_MAC_free(mac_);
701
+ mac_ = nullptr;
702
+ }
703
+ #else
704
+ if (ctx_hmac_) {
705
+ HMAC_CTX_free(ctx_hmac_);
706
+ ctx_hmac_ = nullptr;
707
+ }
708
+ #endif
709
+ }
710
+
711
+ ErrorType init(const char* name,
712
+ unsigned char* key,
713
+ size_t key_len,
714
+ unsigned char* iv,
715
+ size_t iv_len,
716
+ const char* hmac_name,
717
+ unsigned char* hmac_key,
718
+ size_t hmac_key_len,
719
+ int is_etm) {
720
+ ErrorType r = kErrNone;
721
+
722
+ #if REAL_OPENSSL_MAJOR >= 3
723
+ OSSL_PARAM params[2];
724
+ #else
725
+ const EVP_MD* md;
726
+ #endif
727
+ const EVP_CIPHER* const cipher = EVP_get_cipherbyname(name);
728
+ if (cipher == nullptr) {
729
+ r = kErrOpenSSL;
730
+ goto out;
731
+ }
732
+
733
+ if ((ctx_ = EVP_CIPHER_CTX_new()) == nullptr
734
+ || EVP_EncryptInit_ex(ctx_, cipher, nullptr, nullptr, nullptr) != 1) {
735
+ r = kErrOpenSSL;
736
+ goto out;
737
+ }
738
+
739
+ if (iv_len != static_cast<size_t>(ctx_iv_len(ctx_))) {
740
+ r = kErrBadIVLen;
741
+ goto out;
742
+ }
743
+
744
+ if (key_len != static_cast<size_t>(ctx_key_len(ctx_))) {
745
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
746
+ r = kErrBadKeyLen;
747
+ goto out;
748
+ }
749
+ }
750
+
751
+ // Set key and IV
752
+ if (EVP_EncryptInit_ex(ctx_, nullptr, nullptr, key, iv) != 1) {
753
+ r = kErrOpenSSL;
754
+ goto out;
755
+ }
756
+
757
+ // Disable padding
758
+ EVP_CIPHER_CTX_set_padding(ctx_, 0);
759
+
760
+ if (cipher == EVP_rc4()) {
761
+ /* The "arcfour128" algorithm is the RC4 cipher, as described in
762
+ [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream
763
+ generated by the cipher MUST be discarded, and the first byte of the
764
+ first encrypted packet MUST be encrypted using the 1537th byte of
765
+ keystream.
766
+
767
+ -- http://tools.ietf.org/html/rfc4345#section-4 */
768
+ unsigned char zeros[1536] = {0};
769
+ int outlen = sizeof(zeros);
770
+ if (EVP_EncryptUpdate(ctx_,
771
+ zeros,
772
+ &outlen,
773
+ zeros,
774
+ sizeof(zeros)) != 1) {
775
+ r = kErrOpenSSL;
776
+ goto out;
777
+ }
778
+ if (static_cast<size_t>(outlen) != sizeof(zeros)) {
779
+ r = kErrBadInit;
780
+ goto out;
781
+ }
782
+ }
783
+
784
+ #if REAL_OPENSSL_MAJOR >= 3
785
+ if ((mac_ = EVP_MAC_fetch(nullptr,
786
+ "HMAC",
787
+ "provider=default")) == nullptr) {
788
+ r = kErrOpenSSL;
789
+ goto out;
790
+ }
791
+ if ((mac_ctx_base_ = EVP_MAC_CTX_new(mac_)) == nullptr) {
792
+ r = kErrOpenSSL;
793
+ goto out;
794
+ }
795
+ params[0] = OSSL_PARAM_construct_utf8_string("digest",
796
+ const_cast<char*>(hmac_name),
797
+ 0);
798
+ params[1] = OSSL_PARAM_END;
799
+ if (EVP_MAC_init(mac_ctx_base_, hmac_key, hmac_key_len, params) != 1) {
800
+ EVP_MAC_CTX_free(mac_ctx_base_);
801
+ r = kErrOpenSSL;
802
+ goto out;
803
+ }
804
+ hmac_len_ = EVP_MAC_CTX_get_mac_size(mac_ctx_base_);
805
+ #else
806
+ md = EVP_get_digestbyname(hmac_name);
807
+ if (md == nullptr) {
808
+ r = kErrBadHMACName;
809
+ goto out;
810
+ }
811
+
812
+ if ((ctx_hmac_ = HMAC_CTX_new()) == nullptr
813
+ || HMAC_Init_ex(ctx_hmac_, hmac_key, hmac_key_len, md, nullptr) != 1) {
814
+ r = kErrOpenSSL;
815
+ goto out;
816
+ }
817
+
818
+ hmac_len_ = HMAC_size(ctx_hmac_);
819
+ #endif
820
+ is_etm_ = is_etm;
821
+
822
+ out:
823
+ return r;
824
+ }
825
+
826
+ ErrorType encrypt(unsigned char* packet,
827
+ uint32_t packet_len,
828
+ uint32_t seqno) {
829
+ ErrorType r = kErrNone;
830
+
831
+ // `packet` layout:
832
+ // <packet length> <padding length> <payload> <padding> <mac>
833
+ uint32_t data_len = packet_len - hmac_len_;
834
+
835
+ int outlen;
836
+
837
+ uint8_t seqbuf[4] = {0};
838
+ ((uint8_t*)(seqbuf))[0] = (seqno >> 24) & 0xff;
839
+ ((uint8_t*)(seqbuf))[1] = (seqno >> 16) & 0xff;
840
+ ((uint8_t*)(seqbuf))[2] = (seqno >> 8) & 0xff;
841
+ ((uint8_t*)(seqbuf))[3] = seqno & 0xff;
842
+
843
+ if (is_etm_) {
844
+ // Encrypt everything but packet length
845
+ if (EVP_EncryptUpdate(ctx_,
846
+ packet + 4,
847
+ &outlen,
848
+ packet + 4,
849
+ data_len - 4) != 1) {
850
+ r = kErrOpenSSL;
851
+ goto out;
852
+ }
853
+ if (static_cast<size_t>(outlen) != data_len - 4) {
854
+ r = kErrPartialEncrypt;
855
+ goto out;
856
+ }
857
+ }
858
+
859
+ // Calculate HMAC
860
+ {
861
+ #if REAL_OPENSSL_MAJOR >= 3
862
+ size_t outlen = hmac_len_;
863
+
864
+ EVP_MAC_CTX* mac_ctx = EVP_MAC_CTX_dup(mac_ctx_base_);
865
+ if (mac_ctx == nullptr) {
866
+ r = kErrOpenSSL;
867
+ goto out;
868
+ }
869
+ if (EVP_MAC_update(mac_ctx, seqbuf, sizeof(seqbuf)) != 1
870
+ || EVP_MAC_update(mac_ctx, packet, data_len) != 1
871
+ || EVP_MAC_final(mac_ctx,
872
+ packet + data_len,
873
+ reinterpret_cast<size_t*>(&outlen),
874
+ outlen) != 1) {
875
+ EVP_MAC_CTX_free(mac_ctx);
876
+ r = kErrOpenSSL;
877
+ goto out;
878
+ }
879
+ if (outlen != hmac_len_) {
880
+ EVP_MAC_CTX_free(mac_ctx);
881
+ r = kErrBadHMACLen;
882
+ goto out;
883
+ }
884
+ EVP_MAC_CTX_free(mac_ctx);
885
+ #else
886
+ unsigned int outlen = hmac_len_;
887
+ if (HMAC_Init_ex(ctx_hmac_, nullptr, 0, nullptr, nullptr) != 1
888
+ || HMAC_Update(ctx_hmac_, seqbuf, sizeof(seqbuf)) != 1
889
+ || HMAC_Update(ctx_hmac_, packet, data_len) != 1
890
+ || HMAC_Final(ctx_hmac_, packet + data_len, &outlen) != 1) {
891
+ r = kErrOpenSSL;
892
+ goto out;
893
+ }
894
+ if (outlen != hmac_len_) {
895
+ r = kErrBadHMACLen;
896
+ goto out;
897
+ }
898
+ #endif
899
+ }
900
+
901
+ if (!is_etm_) {
902
+ // Encrypt packet
903
+ if (EVP_EncryptUpdate(ctx_,
904
+ packet,
905
+ &outlen,
906
+ packet,
907
+ data_len) != 1) {
908
+ r = kErrOpenSSL;
909
+ goto out;
910
+ }
911
+ if (static_cast<size_t>(outlen) != data_len) {
912
+
913
+ r = kErrPartialEncrypt;
914
+ goto out;
915
+ }
916
+ }
917
+
918
+ out:
919
+ return r;
920
+ }
921
+
922
+ static NAN_METHOD(New) {
923
+ MarkPopErrorOnReturn mark_pop_error_on_return;
924
+
925
+ if (!info[0]->IsString())
926
+ return Nan::ThrowTypeError("Missing/Invalid cipher name");
927
+
928
+ if (!Buffer::HasInstance(info[1]))
929
+ return Nan::ThrowTypeError("Missing/Invalid cipher key");
930
+
931
+ if (!Buffer::HasInstance(info[2]))
932
+ return Nan::ThrowTypeError("Missing/Invalid cipher IV");
933
+
934
+ if (!info[3]->IsString())
935
+ return Nan::ThrowTypeError("Missing/Invalid HMAC name");
936
+
937
+ if (!Buffer::HasInstance(info[4]))
938
+ return Nan::ThrowTypeError("Missing/Invalid HMAC key");
939
+
940
+ if (!info[5]->IsBoolean())
941
+ return Nan::ThrowTypeError("Missing/Invalid HMAC ETM flag");
942
+
943
+ const Nan::Utf8String cipher_name(info[0]);
944
+ const Nan::Utf8String mac_name(info[3]);
945
+ int is_etm = (Nan::To<bool>(info[5]).FromJust() ? 1 : 0);
946
+
947
+ GenericCipher* obj = new GenericCipher();
948
+ ErrorType r = obj->init(
949
+ *cipher_name,
950
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[1])),
951
+ Buffer::Length(info[1]),
952
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[2])),
953
+ Buffer::Length(info[2]),
954
+ *mac_name,
955
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[4])),
956
+ Buffer::Length(info[4]),
957
+ is_etm
958
+ );
959
+ if (r != kErrNone) {
960
+ if (r == kErrOpenSSL) {
961
+ char msg_buf[128] = {0};
962
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
963
+ ERR_clear_error();
964
+ obj->clear();
965
+ delete obj;
966
+ return Nan::ThrowError(msg_buf);
967
+ }
968
+ obj->clear();
969
+ delete obj;
970
+ switch (r) {
971
+ case kErrBadKeyLen:
972
+ return Nan::ThrowError("Invalid keys length");
973
+ case kErrBadIVLen:
974
+ return Nan::ThrowError("Invalid IV length");
975
+ case kErrBadCipherName:
976
+ return Nan::ThrowError("Invalid cipher name");
977
+ case kErrBadHMACName:
978
+ return Nan::ThrowError("Invalid MAC name");
979
+ case kErrBadInit:
980
+ return Nan::ThrowError("Failed to properly initialize cipher");
981
+ default:
982
+ return Nan::ThrowError("Unknown init failure");
983
+ }
984
+ }
985
+
986
+ obj->Wrap(info.This());
987
+ info.GetReturnValue().Set(info.This());
988
+ }
989
+
990
+ static NAN_METHOD(Encrypt) {
991
+ MarkPopErrorOnReturn mark_pop_error_on_return;
992
+
993
+ GenericCipher* obj = ObjectWrap::Unwrap<GenericCipher>(info.Holder());
994
+
995
+ if (!Buffer::HasInstance(info[0]))
996
+ return Nan::ThrowTypeError("Missing/Invalid packet");
997
+
998
+ if (!info[1]->IsUint32())
999
+ return Nan::ThrowTypeError("Missing/Invalid sequence number");
1000
+
1001
+ ErrorType r = obj->encrypt(
1002
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
1003
+ Buffer::Length(info[0]),
1004
+ Nan::To<uint32_t>(info[1]).FromJust()
1005
+ );
1006
+ switch (r) {
1007
+ case kErrNone:
1008
+ return;
1009
+ case kErrPartialEncrypt:
1010
+ return Nan::ThrowError("Failed to completely encrypt packet");
1011
+ case kErrBadHMACLen:
1012
+ return Nan::ThrowError("Unexpected HMAC length");
1013
+ case kErrOpenSSL: {
1014
+ char msg_buf[128] = {0};
1015
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
1016
+ ERR_clear_error();
1017
+ return Nan::ThrowError(msg_buf);
1018
+ }
1019
+ default:
1020
+ return Nan::ThrowError("Unknown encrypt failure");
1021
+ }
1022
+ }
1023
+
1024
+ static NAN_METHOD(Free) {
1025
+ GenericCipher* obj = ObjectWrap::Unwrap<GenericCipher>(info.Holder());
1026
+ obj->clear();
1027
+ }
1028
+
1029
+ static inline v8::Eternal<v8::Function> & constructor() {
1030
+ static v8::Eternal<v8::Function> my_constructor;
1031
+ return my_constructor;
1032
+ }
1033
+
1034
+ EVP_CIPHER_CTX* ctx_;
1035
+ #if REAL_OPENSSL_MAJOR >= 3
1036
+ EVP_MAC* mac_;
1037
+ EVP_MAC_CTX* mac_ctx_base_;
1038
+ size_t hmac_len_;
1039
+ #else
1040
+ HMAC_CTX* ctx_hmac_;
1041
+ unsigned int hmac_len_;
1042
+ #endif
1043
+ int is_etm_;
1044
+ };
1045
+
1046
+ // =============================================================================
1047
+
1048
+ class ChaChaPolyDecipher : public ObjectWrap {
1049
+ public:
1050
+ static NAN_MODULE_INIT(Init) {
1051
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
1052
+ tpl->SetClassName(Nan::New("ChaChaPolyDecipher").ToLocalChecked());
1053
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
1054
+
1055
+ SetPrototypeMethod(tpl, "decrypt", Decrypt);
1056
+ SetPrototypeMethod(tpl, "decryptLen", DecryptLen);
1057
+ SetPrototypeMethod(tpl, "free", Free);
1058
+
1059
+ Local<Function> func = Nan::GetFunction(tpl).ToLocalChecked();
1060
+ Local<Context> context = Nan::GetCurrentContext();
1061
+ v8::Isolate* isolate = context->GetIsolate();
1062
+
1063
+ constructor().Set(isolate, func);
1064
+
1065
+ Nan::Set(target,
1066
+ Nan::New("ChaChaPolyDecipher").ToLocalChecked(),
1067
+ func);
1068
+ }
1069
+
1070
+ private:
1071
+ explicit ChaChaPolyDecipher()
1072
+ : ctx_main_(nullptr),
1073
+ ctx_pktlen_(nullptr),
1074
+ #if REAL_OPENSSL_MAJOR >= 3
1075
+ mac_(nullptr),
1076
+ mac_ctx_(nullptr) {}
1077
+ #else
1078
+ md_ctx_(nullptr),
1079
+ polykey_(nullptr),
1080
+ polykey_ctx_(nullptr) {}
1081
+ #endif
1082
+
1083
+ ~ChaChaPolyDecipher() {
1084
+ clear();
1085
+ }
1086
+
1087
+ void clear() {
1088
+ if (ctx_pktlen_) {
1089
+ EVP_CIPHER_CTX_free(ctx_pktlen_);
1090
+ ctx_pktlen_ = nullptr;
1091
+ }
1092
+ if (ctx_main_) {
1093
+ EVP_CIPHER_CTX_free(ctx_main_);
1094
+ ctx_main_ = nullptr;
1095
+ }
1096
+ #if REAL_OPENSSL_MAJOR >= 3
1097
+ if (mac_ctx_) {
1098
+ EVP_MAC_CTX_free(mac_ctx_);
1099
+ mac_ctx_ = nullptr;
1100
+ }
1101
+ if (mac_) {
1102
+ EVP_MAC_free(mac_);
1103
+ mac_ = nullptr;
1104
+ }
1105
+ #else
1106
+ if (polykey_) {
1107
+ EVP_PKEY_free(polykey_);
1108
+ polykey_ = nullptr;
1109
+ }
1110
+ if (md_ctx_) {
1111
+ EVP_MD_CTX_free(md_ctx_);
1112
+ md_ctx_ = nullptr;
1113
+ }
1114
+ // `polykey_ctx_` is not explicitly freed as it is freed implicitly when
1115
+ // `md_ctx_` is freed
1116
+ #endif
1117
+ }
1118
+
1119
+ ErrorType init(unsigned char* keys, size_t keys_len) {
1120
+ ErrorType r = kErrNone;
1121
+ const EVP_CIPHER* const cipher = EVP_get_cipherbyname("chacha20");
1122
+
1123
+ if (keys_len != 64) {
1124
+ r = kErrBadKeyLen;
1125
+ goto out;
1126
+ }
1127
+
1128
+ if (cipher == nullptr) {
1129
+ r = kErrOpenSSL;
1130
+ goto out;
1131
+ }
1132
+
1133
+ if ((ctx_pktlen_ = EVP_CIPHER_CTX_new()) == nullptr
1134
+ || (ctx_main_ = EVP_CIPHER_CTX_new()) == nullptr
1135
+ #if REAL_OPENSSL_MAJOR >= 3
1136
+ || (mac_ = EVP_MAC_fetch(nullptr,
1137
+ "POLY1305",
1138
+ "provider=default")) == nullptr
1139
+ || (mac_ctx_ = EVP_MAC_CTX_new(mac_)) == nullptr
1140
+ #else
1141
+ || (md_ctx_ = EVP_MD_CTX_new()) == nullptr
1142
+ #endif
1143
+ || EVP_DecryptInit_ex(ctx_pktlen_,
1144
+ cipher,
1145
+ nullptr,
1146
+ keys + 32,
1147
+ nullptr) != 1
1148
+ || EVP_DecryptInit_ex(ctx_main_,
1149
+ cipher,
1150
+ nullptr,
1151
+ keys,
1152
+ nullptr) != 1) {
1153
+ r = kErrOpenSSL;
1154
+ goto out;
1155
+ }
1156
+ if (ctx_iv_len(ctx_pktlen_) != 16) {
1157
+ r = kErrBadIVLen;
1158
+ goto out;
1159
+ }
1160
+
1161
+ out:
1162
+ return r;
1163
+ }
1164
+
1165
+ ErrorType decrypt_length(unsigned char* data,
1166
+ size_t data_len,
1167
+ uint32_t seqno,
1168
+ uint32_t* packet_length) {
1169
+ ErrorType r = kErrNone;
1170
+ int outlen;
1171
+
1172
+ unsigned char dec_length_bytes[4];
1173
+
1174
+ uint8_t seqbuf[16] = {0};
1175
+ ((uint8_t*)(seqbuf))[12] = (seqno >> 24) & 0xff;
1176
+ ((uint8_t*)(seqbuf))[13] = (seqno >> 16) & 0xff;
1177
+ ((uint8_t*)(seqbuf))[14] = (seqno >> 8) & 0xff;
1178
+ ((uint8_t*)(seqbuf))[15] = seqno & 0xff;
1179
+
1180
+ if (EVP_DecryptInit_ex(ctx_pktlen_,
1181
+ nullptr,
1182
+ nullptr,
1183
+ nullptr,
1184
+ seqbuf) != 1) {
1185
+ r = kErrOpenSSL;
1186
+ goto out;
1187
+ }
1188
+ if (EVP_DecryptUpdate(ctx_pktlen_,
1189
+ dec_length_bytes,
1190
+ &outlen,
1191
+ data,
1192
+ data_len) != 1) {
1193
+ r = kErrOpenSSL;
1194
+ goto out;
1195
+ }
1196
+ if (static_cast<size_t>(outlen) != 4) {
1197
+ r = kErrPartialDecrypt;
1198
+ goto out;
1199
+ }
1200
+
1201
+ *packet_length = (uint32_t)dec_length_bytes[0] << 24
1202
+ | (uint32_t)dec_length_bytes[1] << 16
1203
+ | (uint32_t)dec_length_bytes[2] << 8
1204
+ | (uint32_t)dec_length_bytes[3];
1205
+ memcpy(length_bytes, data, data_len);
1206
+ out:
1207
+ return r;
1208
+ }
1209
+
1210
+ ErrorType decrypt(unsigned char* packet,
1211
+ uint32_t packet_len,
1212
+ unsigned char* mac,
1213
+ uint32_t seqno) {
1214
+ ErrorType r = kErrNone;
1215
+ size_t sig_len = 16;
1216
+ int outlen = 0;
1217
+
1218
+ // `packet` layout:
1219
+ // <padding length> <payload> <padding>
1220
+
1221
+ unsigned char polykey[POLY1305_KEYLEN] = {0};
1222
+ unsigned char calc_mac[POLY1305_TAGLEN] = {0};
1223
+
1224
+ uint8_t seqbuf[16] = {0};
1225
+ ((uint8_t*)(seqbuf))[12] = (seqno >> 24) & 0xff;
1226
+ ((uint8_t*)(seqbuf))[13] = (seqno >> 16) & 0xff;
1227
+ ((uint8_t*)(seqbuf))[14] = (seqno >> 8) & 0xff;
1228
+ ((uint8_t*)(seqbuf))[15] = seqno & 0xff;
1229
+
1230
+ // Generate Poly1305 key
1231
+ if (EVP_EncryptInit_ex(ctx_main_, nullptr, nullptr, nullptr, seqbuf) != 1) {
1232
+ r = kErrOpenSSL;
1233
+ goto out;
1234
+ }
1235
+ if (EVP_EncryptUpdate(ctx_main_,
1236
+ polykey,
1237
+ &outlen,
1238
+ polykey,
1239
+ sizeof(polykey)) != 1) {
1240
+ r = kErrOpenSSL;
1241
+ goto out;
1242
+ }
1243
+ if (static_cast<size_t>(outlen) != sizeof(polykey)) {
1244
+ r = kErrPartialEncrypt;
1245
+ goto out;
1246
+ }
1247
+
1248
+ // Poly1305 over ciphertext
1249
+ #if REAL_OPENSSL_MAJOR >= 3
1250
+ // TODO: check if dup()'ing a "base" context instead of calling init() with
1251
+ // the key each time is faster
1252
+ if (EVP_MAC_init(mac_ctx_, polykey, sizeof(polykey), nullptr) != 1
1253
+ || EVP_MAC_update(mac_ctx_, length_bytes, sizeof(length_bytes)) != 1
1254
+ || EVP_MAC_update(mac_ctx_, packet, packet_len) != 1
1255
+ || EVP_MAC_final(mac_ctx_, calc_mac, &sig_len, sig_len) != 1) {
1256
+ r = kErrOpenSSL;
1257
+ goto out;
1258
+ }
1259
+ #else
1260
+ if (polykey_) {
1261
+ if (EVP_PKEY_CTX_ctrl(polykey_ctx_,
1262
+ -1,
1263
+ EVP_PKEY_OP_SIGNCTX,
1264
+ EVP_PKEY_CTRL_SET_MAC_KEY,
1265
+ sizeof(polykey),
1266
+ (void*)polykey) <= 0) {
1267
+ r = kErrOpenSSL;
1268
+ goto out;
1269
+ }
1270
+ } else {
1271
+ polykey_ = EVP_PKEY_new_raw_private_key(EVP_PKEY_POLY1305,
1272
+ nullptr,
1273
+ polykey,
1274
+ sizeof(polykey));
1275
+ if (polykey_ == nullptr) {
1276
+ r = kErrOpenSSL;
1277
+ goto out;
1278
+ }
1279
+
1280
+ if (!EVP_DigestSignInit(md_ctx_,
1281
+ &polykey_ctx_,
1282
+ nullptr,
1283
+ nullptr,
1284
+ polykey_)) {
1285
+ r = kErrOpenSSL;
1286
+ goto out;
1287
+ }
1288
+ }
1289
+ if (EVP_DigestSignUpdate(md_ctx_,
1290
+ length_bytes,
1291
+ sizeof(length_bytes)) != 1) {
1292
+ r = kErrOpenSSL;
1293
+ goto out;
1294
+ }
1295
+ if (EVP_DigestSignUpdate(md_ctx_, packet, packet_len) != 1) {
1296
+ r = kErrOpenSSL;
1297
+ goto out;
1298
+ }
1299
+
1300
+ // Generate Poly1305 MAC
1301
+ if (EVP_DigestSignFinal(md_ctx_, calc_mac, &sig_len) != 1) {
1302
+ r = kErrOpenSSL;
1303
+ goto out;
1304
+ }
1305
+ #endif
1306
+
1307
+ // Compare MACs
1308
+ if (CRYPTO_memcmp(mac, calc_mac, sizeof(calc_mac))) {
1309
+ r = kErrInvalidMAC;
1310
+ goto out;
1311
+ }
1312
+
1313
+ // Decrypt packet
1314
+ seqbuf[0] = 1;
1315
+ if (EVP_DecryptInit_ex(ctx_main_, nullptr, nullptr, nullptr, seqbuf) != 1) {
1316
+ r = kErrOpenSSL;
1317
+ goto out;
1318
+ }
1319
+ if (EVP_DecryptUpdate(ctx_main_,
1320
+ packet,
1321
+ &outlen,
1322
+ packet,
1323
+ packet_len) != 1) {
1324
+ r = kErrOpenSSL;
1325
+ goto out;
1326
+ }
1327
+ if (static_cast<size_t>(outlen) != packet_len) {
1328
+ r = kErrPartialDecrypt;
1329
+ goto out;
1330
+ }
1331
+
1332
+ out:
1333
+ return r;
1334
+ }
1335
+
1336
+ static NAN_METHOD(New) {
1337
+ MarkPopErrorOnReturn mark_pop_error_on_return;
1338
+
1339
+ if (!Buffer::HasInstance(info[0]))
1340
+ return Nan::ThrowTypeError("Missing/Invalid keys");
1341
+
1342
+ ChaChaPolyDecipher* obj = new ChaChaPolyDecipher();
1343
+ ErrorType r = obj->init(
1344
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
1345
+ Buffer::Length(info[0])
1346
+ );
1347
+ if (r != kErrNone) {
1348
+ if (r == kErrOpenSSL) {
1349
+ char msg_buf[128] = {0};
1350
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
1351
+ ERR_clear_error();
1352
+ obj->clear();
1353
+ delete obj;
1354
+ return Nan::ThrowError(msg_buf);
1355
+ }
1356
+ obj->clear();
1357
+ delete obj;
1358
+ switch (r) {
1359
+ case kErrBadKeyLen:
1360
+ return Nan::ThrowError("Invalid keys length");
1361
+ case kErrBadIVLen:
1362
+ return Nan::ThrowError("Invalid IV length");
1363
+ default:
1364
+ return Nan::ThrowError("Unknown init failure");
1365
+ }
1366
+ }
1367
+
1368
+ obj->Wrap(info.This());
1369
+ info.GetReturnValue().Set(info.This());
1370
+ }
1371
+
1372
+ static NAN_METHOD(DecryptLen) {
1373
+ MarkPopErrorOnReturn mark_pop_error_on_return;
1374
+
1375
+ ChaChaPolyDecipher* obj =
1376
+ ObjectWrap::Unwrap<ChaChaPolyDecipher>(info.Holder());
1377
+
1378
+ if (!Buffer::HasInstance(info[0]) || Buffer::Length(info[0]) != 4)
1379
+ return Nan::ThrowTypeError("Missing/Invalid length bytes");
1380
+
1381
+ if (!info[1]->IsUint32())
1382
+ return Nan::ThrowTypeError("Missing/Invalid sequence number");
1383
+
1384
+ unsigned char* length_bytes =
1385
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0]));
1386
+
1387
+ uint32_t dec_packet_length;
1388
+ ErrorType r = obj->decrypt_length(
1389
+ length_bytes,
1390
+ Buffer::Length(info[0]),
1391
+ Nan::To<uint32_t>(info[1]).FromJust(),
1392
+ &dec_packet_length
1393
+ );
1394
+
1395
+ switch (r) {
1396
+ case kErrNone:
1397
+ return info.GetReturnValue().Set(dec_packet_length);
1398
+ case kErrPartialDecrypt:
1399
+ return Nan::ThrowError("Failed to completely decrypt packet length");
1400
+ case kErrOpenSSL: {
1401
+ char msg_buf[128] = {0};
1402
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
1403
+ ERR_clear_error();
1404
+ return Nan::ThrowError(msg_buf);
1405
+ }
1406
+ default:
1407
+ return Nan::ThrowError("Unknown decrypt failure");
1408
+ }
1409
+ }
1410
+
1411
+ static NAN_METHOD(Decrypt) {
1412
+ MarkPopErrorOnReturn mark_pop_error_on_return;
1413
+
1414
+ ChaChaPolyDecipher* obj =
1415
+ ObjectWrap::Unwrap<ChaChaPolyDecipher>(info.Holder());
1416
+
1417
+ if (!Buffer::HasInstance(info[0]))
1418
+ return Nan::ThrowTypeError("Missing/Invalid packet");
1419
+
1420
+ if (!Buffer::HasInstance(info[1])
1421
+ || Buffer::Length(info[1]) != POLY1305_TAGLEN) {
1422
+ return Nan::ThrowTypeError("Missing/Invalid mac");
1423
+ }
1424
+
1425
+ if (!info[2]->IsUint32())
1426
+ return Nan::ThrowTypeError("Missing/Invalid sequence number");
1427
+
1428
+ ErrorType r = obj->decrypt(
1429
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
1430
+ Buffer::Length(info[0]),
1431
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[1])),
1432
+ Nan::To<uint32_t>(info[2]).FromJust()
1433
+ );
1434
+
1435
+ switch (r) {
1436
+ case kErrNone:
1437
+ return;
1438
+ case kErrInvalidMAC:
1439
+ return Nan::ThrowError("Invalid MAC");
1440
+ case kErrPartialDecrypt:
1441
+ return Nan::ThrowError("Failed to completely decrypt packet length");
1442
+ case kErrOpenSSL: {
1443
+ char msg_buf[128] = {0};
1444
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
1445
+ ERR_clear_error();
1446
+ return Nan::ThrowError(msg_buf);
1447
+ }
1448
+ default:
1449
+ return Nan::ThrowError("Unknown decrypt failure");
1450
+ }
1451
+ }
1452
+
1453
+ static NAN_METHOD(Free) {
1454
+ ChaChaPolyDecipher* obj =
1455
+ ObjectWrap::Unwrap<ChaChaPolyDecipher>(info.Holder());
1456
+ obj->clear();
1457
+ }
1458
+
1459
+ static inline v8::Eternal<v8::Function> & constructor() {
1460
+ static v8::Eternal<v8::Function> my_constructor;
1461
+ return my_constructor;
1462
+ }
1463
+
1464
+ unsigned char length_bytes[4];
1465
+ EVP_CIPHER_CTX* ctx_main_;
1466
+ EVP_CIPHER_CTX* ctx_pktlen_;
1467
+ #if REAL_OPENSSL_MAJOR >= 3
1468
+ EVP_MAC* mac_;
1469
+ EVP_MAC_CTX* mac_ctx_;
1470
+ #else
1471
+ EVP_MD_CTX* md_ctx_;
1472
+ EVP_PKEY* polykey_;
1473
+ EVP_PKEY_CTX* polykey_ctx_;
1474
+ #endif
1475
+ };
1476
+
1477
+ class AESGCMDecipher : public ObjectWrap {
1478
+ public:
1479
+ static NAN_MODULE_INIT(Init) {
1480
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
1481
+ tpl->SetClassName(Nan::New("AESGCMDecipher").ToLocalChecked());
1482
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
1483
+
1484
+ SetPrototypeMethod(tpl, "decrypt", Decrypt);
1485
+ SetPrototypeMethod(tpl, "free", Free);
1486
+
1487
+ Local<Function> func = Nan::GetFunction(tpl).ToLocalChecked();
1488
+ Local<Context> context = Nan::GetCurrentContext();
1489
+ v8::Isolate* isolate = context->GetIsolate();
1490
+
1491
+ constructor().Set(isolate, func);
1492
+
1493
+ Nan::Set(target,
1494
+ Nan::New("AESGCMDecipher").ToLocalChecked(),
1495
+ func);
1496
+ }
1497
+
1498
+ private:
1499
+ explicit AESGCMDecipher() : ctx_(nullptr) {}
1500
+
1501
+ ~AESGCMDecipher() {
1502
+ clear();
1503
+ }
1504
+
1505
+ void clear() {
1506
+ if (ctx_) {
1507
+ EVP_CIPHER_CTX_free(ctx_);
1508
+ ctx_ = nullptr;
1509
+ }
1510
+ }
1511
+
1512
+ ErrorType init(const char* name,
1513
+ unsigned char* key,
1514
+ size_t key_len,
1515
+ unsigned char* iv,
1516
+ size_t iv_len) {
1517
+ ErrorType r = kErrNone;
1518
+
1519
+ const EVP_CIPHER* const cipher = EVP_get_cipherbyname(name);
1520
+ if (cipher == nullptr) {
1521
+ r = kErrOpenSSL;
1522
+ goto out;
1523
+ }
1524
+
1525
+ if (cipher != EVP_aes_128_gcm() && cipher != EVP_aes_256_gcm()) {
1526
+ r = kErrBadCipherName;
1527
+ goto out;
1528
+ }
1529
+
1530
+ if ((ctx_ = EVP_CIPHER_CTX_new()) == nullptr
1531
+ || EVP_DecryptInit_ex(ctx_, cipher, nullptr, nullptr, nullptr) != 1) {
1532
+ r = kErrOpenSSL;
1533
+ goto out;
1534
+ }
1535
+
1536
+ if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr)) {
1537
+ r = kErrOpenSSL;
1538
+ goto out;
1539
+ }
1540
+
1541
+ if (key_len != static_cast<size_t>(ctx_key_len(ctx_))) {
1542
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
1543
+ r = kErrBadKeyLen;
1544
+ goto out;
1545
+ }
1546
+ }
1547
+
1548
+ // Set key and IV
1549
+ if (EVP_DecryptInit_ex(ctx_, nullptr, nullptr, key, iv) != 1) {
1550
+ r = kErrOpenSSL;
1551
+ goto out;
1552
+ }
1553
+ if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) {
1554
+ r = kErrOpenSSL;
1555
+ goto out;
1556
+ }
1557
+
1558
+ // Disable padding
1559
+ EVP_CIPHER_CTX_set_padding(ctx_, 0);
1560
+
1561
+ out:
1562
+ return r;
1563
+ }
1564
+
1565
+ ErrorType decrypt(unsigned char* packet,
1566
+ uint32_t packet_len,
1567
+ unsigned char* length_bytes,
1568
+ unsigned char* tag) {
1569
+ ErrorType r = kErrNone;
1570
+
1571
+ // `packet` layout:
1572
+ // <padding length> <payload> <padding>
1573
+
1574
+ int outlen;
1575
+
1576
+ // Increment IV
1577
+ unsigned char lastiv[1];
1578
+ if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) {
1579
+ r = kErrOpenSSL;
1580
+ goto out;
1581
+ }
1582
+
1583
+ // Set AAD (the packet length)
1584
+ if (!EVP_DecryptUpdate(ctx_, nullptr, &outlen, length_bytes, 4)) {
1585
+ r = kErrOpenSSL;
1586
+ goto out;
1587
+ }
1588
+ if (outlen != 4) {
1589
+ r = kErrAADFailure;
1590
+ goto out;
1591
+ }
1592
+
1593
+ // Decrypt everything but the packet length
1594
+ if (EVP_DecryptUpdate(ctx_, packet, &outlen, packet, packet_len) != 1) {
1595
+ r = kErrOpenSSL;
1596
+ goto out;
1597
+ }
1598
+ if (static_cast<size_t>(outlen) != packet_len) {
1599
+ r = kErrPartialDecrypt;
1600
+ goto out;
1601
+ }
1602
+
1603
+ // Set authentication tag
1604
+ if (EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_TAG, 16, tag) != 1) {
1605
+ r = kErrOpenSSL;
1606
+ goto out;
1607
+ }
1608
+
1609
+ // Verify authentication tag
1610
+ if (!EVP_DecryptFinal_ex(ctx_, nullptr, &outlen)) {
1611
+ r = kErrOpenSSL;
1612
+ goto out;
1613
+ }
1614
+
1615
+ out:
1616
+ return r;
1617
+ }
1618
+
1619
+ static NAN_METHOD(New) {
1620
+ MarkPopErrorOnReturn mark_pop_error_on_return;
1621
+
1622
+ if (!info[0]->IsString())
1623
+ return Nan::ThrowTypeError("Missing/Invalid OpenSSL cipher name");
1624
+
1625
+ if (!Buffer::HasInstance(info[1]))
1626
+ return Nan::ThrowTypeError("Missing/Invalid key");
1627
+
1628
+ if (!Buffer::HasInstance(info[2]))
1629
+ return Nan::ThrowTypeError("Missing/Invalid iv");
1630
+
1631
+ const Nan::Utf8String cipher_name(info[0]);
1632
+
1633
+ AESGCMDecipher* obj = new AESGCMDecipher();
1634
+ ErrorType r = obj->init(
1635
+ *cipher_name,
1636
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[1])),
1637
+ Buffer::Length(info[1]),
1638
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[2])),
1639
+ Buffer::Length(info[2])
1640
+ );
1641
+ if (r != kErrNone) {
1642
+ if (r == kErrOpenSSL) {
1643
+ char msg_buf[128] = {0};
1644
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
1645
+ ERR_clear_error();
1646
+ obj->clear();
1647
+ delete obj;
1648
+ return Nan::ThrowError(msg_buf);
1649
+ }
1650
+ obj->clear();
1651
+ delete obj;
1652
+ switch (r) {
1653
+ case kErrBadKeyLen:
1654
+ return Nan::ThrowError("Invalid keys length");
1655
+ case kErrBadIVLen:
1656
+ return Nan::ThrowError("Invalid IV length");
1657
+ case kErrBadCipherName:
1658
+ return Nan::ThrowError("Invalid AES GCM cipher name");
1659
+ default:
1660
+ return Nan::ThrowError("Unknown init failure");
1661
+ }
1662
+ }
1663
+
1664
+ obj->Wrap(info.This());
1665
+ info.GetReturnValue().Set(info.This());
1666
+ }
1667
+
1668
+ static NAN_METHOD(Decrypt) {
1669
+ MarkPopErrorOnReturn mark_pop_error_on_return;
1670
+
1671
+ AESGCMDecipher* obj = ObjectWrap::Unwrap<AESGCMDecipher>(info.Holder());
1672
+
1673
+ if (!Buffer::HasInstance(info[0]))
1674
+ return Nan::ThrowTypeError("Missing/Invalid packet");
1675
+
1676
+ if (!info[1]->IsUint32())
1677
+ return Nan::ThrowTypeError("Missing/Invalid length");
1678
+
1679
+ if (!Buffer::HasInstance(info[2]) || Buffer::Length(info[2]) != 16)
1680
+ return Nan::ThrowTypeError("Missing/Invalid tag");
1681
+
1682
+ uint32_t length = Nan::To<uint32_t>(info[1]).FromJust();
1683
+ unsigned char length_bytes[4];
1684
+ length_bytes[0] = (length >> 24) & 0xFF;
1685
+ length_bytes[1] = (length >> 16) & 0xFF;
1686
+ length_bytes[2] = (length >> 8) & 0xFF;
1687
+ length_bytes[3] = length & 0xFF;
1688
+
1689
+ ErrorType r = obj->decrypt(
1690
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
1691
+ Buffer::Length(info[0]),
1692
+ length_bytes,
1693
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[2]))
1694
+ );
1695
+ switch (r) {
1696
+ case kErrNone:
1697
+ return;
1698
+ case kErrAADFailure:
1699
+ return Nan::ThrowError("Error setting AAD");
1700
+ case kErrPartialDecrypt:
1701
+ return Nan::ThrowError("Failed to completely decrypt packet");
1702
+ case kErrTagFailure:
1703
+ return Nan::ThrowError("Error generating authentication tag");
1704
+ case kErrOpenSSL: {
1705
+ char msg_buf[128] = {0};
1706
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
1707
+ ERR_clear_error();
1708
+ return Nan::ThrowError(msg_buf);
1709
+ }
1710
+ default:
1711
+ return Nan::ThrowError("Unknown decrypt failure");
1712
+ }
1713
+ }
1714
+
1715
+ static NAN_METHOD(Free) {
1716
+ AESGCMDecipher* obj = ObjectWrap::Unwrap<AESGCMDecipher>(info.Holder());
1717
+ obj->clear();
1718
+ }
1719
+
1720
+ static inline v8::Eternal<v8::Function> & constructor() {
1721
+ static v8::Eternal<v8::Function> my_constructor;
1722
+ return my_constructor;
1723
+ }
1724
+
1725
+ EVP_CIPHER_CTX* ctx_;
1726
+ };
1727
+
1728
+ class GenericDecipher : public ObjectWrap {
1729
+ public:
1730
+ static NAN_MODULE_INIT(Init) {
1731
+ Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
1732
+ tpl->SetClassName(Nan::New("GenericDecipher").ToLocalChecked());
1733
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
1734
+
1735
+ SetPrototypeMethod(tpl, "decryptBlock", DecryptBlock);
1736
+ SetPrototypeMethod(tpl, "decrypt", Decrypt);
1737
+ SetPrototypeMethod(tpl, "free", Free);
1738
+
1739
+ Local<Function> func = Nan::GetFunction(tpl).ToLocalChecked();
1740
+ Local<Context> context = Nan::GetCurrentContext();
1741
+ v8::Isolate* isolate = context->GetIsolate();
1742
+
1743
+ constructor().Set(isolate, func);
1744
+
1745
+ Nan::Set(target,
1746
+ Nan::New("GenericDecipher").ToLocalChecked(),
1747
+ func);
1748
+ }
1749
+
1750
+ private:
1751
+ explicit GenericDecipher()
1752
+ : ctx_(nullptr),
1753
+ #if REAL_OPENSSL_MAJOR >= 3
1754
+ mac_(nullptr),
1755
+ mac_ctx_base_(nullptr),
1756
+ #else
1757
+ ctx_hmac_(nullptr),
1758
+ #endif
1759
+ hmac_len_(0),
1760
+ is_etm_(0) {}
1761
+
1762
+ ~GenericDecipher() {
1763
+ clear();
1764
+ }
1765
+
1766
+ void clear() {
1767
+ if (ctx_) {
1768
+ EVP_CIPHER_CTX_free(ctx_);
1769
+ ctx_ = nullptr;
1770
+ }
1771
+ #if REAL_OPENSSL_MAJOR >= 3
1772
+ if (mac_ctx_base_) {
1773
+ EVP_MAC_CTX_free(mac_ctx_base_);
1774
+ mac_ctx_base_ = nullptr;
1775
+ }
1776
+ if (mac_) {
1777
+ EVP_MAC_free(mac_);
1778
+ mac_ = nullptr;
1779
+ }
1780
+ #else
1781
+ if (ctx_hmac_) {
1782
+ HMAC_CTX_free(ctx_hmac_);
1783
+ ctx_hmac_ = nullptr;
1784
+ }
1785
+ #endif
1786
+ }
1787
+
1788
+ ErrorType init(const char* name,
1789
+ unsigned char* key,
1790
+ size_t key_len,
1791
+ unsigned char* iv,
1792
+ size_t iv_len,
1793
+ const char* hmac_name,
1794
+ unsigned char* hmac_key,
1795
+ size_t hmac_key_len,
1796
+ int is_etm,
1797
+ size_t hmac_actual_len) {
1798
+ ErrorType r = kErrNone;
1799
+
1800
+ #if REAL_OPENSSL_MAJOR >= 3
1801
+ OSSL_PARAM params[2];
1802
+ #else
1803
+ const EVP_MD* md;
1804
+ #endif
1805
+ const EVP_CIPHER* const cipher = EVP_get_cipherbyname(name);
1806
+ if (cipher == nullptr) {
1807
+ r = kErrOpenSSL;
1808
+ goto out;
1809
+ }
1810
+
1811
+ if ((ctx_ = EVP_CIPHER_CTX_new()) == nullptr
1812
+ || EVP_DecryptInit_ex(ctx_, cipher, nullptr, nullptr, nullptr) != 1) {
1813
+ r = kErrOpenSSL;
1814
+ goto out;
1815
+ }
1816
+
1817
+ if (iv_len != static_cast<size_t>(ctx_iv_len(ctx_))) {
1818
+ r = kErrBadIVLen;
1819
+ goto out;
1820
+ }
1821
+
1822
+ if (key_len != static_cast<size_t>(ctx_key_len(ctx_))) {
1823
+ if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
1824
+ r = kErrBadKeyLen;
1825
+ goto out;
1826
+ }
1827
+ }
1828
+
1829
+ // Set key and IV
1830
+ if (EVP_DecryptInit_ex(ctx_, nullptr, nullptr, key, iv) != 1) {
1831
+ r = kErrOpenSSL;
1832
+ goto out;
1833
+ }
1834
+
1835
+ // Disable padding
1836
+ EVP_CIPHER_CTX_set_padding(ctx_, 0);
1837
+
1838
+ if (cipher == EVP_rc4()) {
1839
+ /* The "arcfour128" algorithm is the RC4 cipher, as described in
1840
+ [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream
1841
+ generated by the cipher MUST be discarded, and the first byte of the
1842
+ first encrypted packet MUST be encrypted using the 1537th byte of
1843
+ keystream.
1844
+
1845
+ -- http://tools.ietf.org/html/rfc4345#section-4 */
1846
+ unsigned char zeros[1536] = {0};
1847
+ int outlen = sizeof(zeros);
1848
+ if (EVP_DecryptUpdate(ctx_,
1849
+ zeros,
1850
+ &outlen,
1851
+ zeros,
1852
+ sizeof(zeros)) != 1) {
1853
+ r = kErrOpenSSL;
1854
+ goto out;
1855
+ }
1856
+ if (static_cast<size_t>(outlen) != sizeof(zeros)) {
1857
+ r = kErrBadInit;
1858
+ goto out;
1859
+ }
1860
+ }
1861
+
1862
+ #if REAL_OPENSSL_MAJOR >= 3
1863
+ if ((mac_ = EVP_MAC_fetch(nullptr,
1864
+ "HMAC",
1865
+ "provider=default")) == nullptr) {
1866
+ r = kErrOpenSSL;
1867
+ goto out;
1868
+ }
1869
+ if ((mac_ctx_base_ = EVP_MAC_CTX_new(mac_)) == nullptr) {
1870
+ r = kErrOpenSSL;
1871
+ goto out;
1872
+ }
1873
+ params[0] = OSSL_PARAM_construct_utf8_string("digest",
1874
+ const_cast<char*>(hmac_name),
1875
+ 0);
1876
+ params[1] = OSSL_PARAM_END;
1877
+ if (EVP_MAC_init(mac_ctx_base_, hmac_key, hmac_key_len, params) != 1) {
1878
+ EVP_MAC_CTX_free(mac_ctx_base_);
1879
+ r = kErrOpenSSL;
1880
+ goto out;
1881
+ }
1882
+ hmac_len_ = EVP_MAC_CTX_get_mac_size(mac_ctx_base_);
1883
+ #else
1884
+ md = EVP_get_digestbyname(hmac_name);
1885
+ if (md == nullptr) {
1886
+ r = kErrBadHMACName;
1887
+ goto out;
1888
+ }
1889
+
1890
+ if ((ctx_hmac_ = HMAC_CTX_new()) == nullptr
1891
+ || HMAC_Init_ex(ctx_hmac_, hmac_key, hmac_key_len, md, nullptr) != 1) {
1892
+ r = kErrOpenSSL;
1893
+ goto out;
1894
+ }
1895
+
1896
+ hmac_len_ = HMAC_size(ctx_hmac_);
1897
+ #endif
1898
+ hmac_actual_len_ = hmac_actual_len;
1899
+ is_etm_ = is_etm;
1900
+ #if REAL_OPENSSL_MAJOR >= 3
1901
+ switch (EVP_CIPHER_CTX_mode(ctx_)) {
1902
+ #else
1903
+ switch (cipher_flags(EVP_CIPHER_CTX_cipher(ctx_)) & EVP_CIPH_MODE) {
1904
+ #endif
1905
+ case EVP_CIPH_STREAM_CIPHER:
1906
+ case EVP_CIPH_CTR_MODE:
1907
+ is_stream_ = 1;
1908
+ break;
1909
+ default:
1910
+ is_stream_ = 0;
1911
+ }
1912
+ block_size_ = ctx_get_block_size(ctx_);
1913
+
1914
+ out:
1915
+ return r;
1916
+ }
1917
+
1918
+ ErrorType decrypt_block(unsigned char* data, uint32_t data_len) {
1919
+ ErrorType r = kErrNone;
1920
+
1921
+ int outlen;
1922
+
1923
+ if (!is_stream_ && data_len != block_size_) {
1924
+ r = kErrBadBlockLen;
1925
+ goto out;
1926
+ }
1927
+
1928
+ // Decrypt block
1929
+ if (EVP_DecryptUpdate(ctx_, data, &outlen, data, data_len) != 1) {
1930
+ r = kErrOpenSSL;
1931
+ goto out;
1932
+ }
1933
+ if (static_cast<size_t>(outlen) != data_len) {
1934
+ r = kErrPartialDecrypt;
1935
+ goto out;
1936
+ }
1937
+
1938
+ out:
1939
+ return r;
1940
+ }
1941
+
1942
+ ErrorType decrypt(unsigned char* packet,
1943
+ uint32_t packet_len,
1944
+ uint32_t seqno,
1945
+ unsigned char* first_block,
1946
+ uint32_t first_block_len,
1947
+ unsigned char* mac,
1948
+ uint32_t mac_len) {
1949
+ ErrorType r = kErrNone;
1950
+
1951
+ int outlen;
1952
+ unsigned char calc_mac[MAX_MAC_LEN] = {0};
1953
+
1954
+ uint8_t seqbuf[4] = {0};
1955
+ ((uint8_t*)(seqbuf))[0] = (seqno >> 24) & 0xff;
1956
+ ((uint8_t*)(seqbuf))[1] = (seqno >> 16) & 0xff;
1957
+ ((uint8_t*)(seqbuf))[2] = (seqno >> 8) & 0xff;
1958
+ ((uint8_t*)(seqbuf))[3] = seqno & 0xff;
1959
+
1960
+ if (!is_etm_) {
1961
+ // `first_block` for non-ETM should be a completely decrypted first block
1962
+ if (!is_stream_ && first_block_len != block_size_) {
1963
+ r = kErrBadBlockLen;
1964
+ goto out;
1965
+ }
1966
+
1967
+ const int offset = (is_stream_ ? 0 : block_size_ - 4);
1968
+ // Decrypt the rest of the packet
1969
+ if (EVP_DecryptUpdate(ctx_,
1970
+ packet + offset,
1971
+ &outlen,
1972
+ packet + offset,
1973
+ packet_len - offset) != 1) {
1974
+ r = kErrOpenSSL;
1975
+ goto out;
1976
+ }
1977
+ if (static_cast<size_t>(outlen) != packet_len - offset) {
1978
+ r = kErrPartialDecrypt;
1979
+ goto out;
1980
+ }
1981
+ }
1982
+
1983
+ // Calculate and compare HMAC
1984
+ {
1985
+ #if REAL_OPENSSL_MAJOR >= 3
1986
+ size_t outlen = hmac_len_;
1987
+
1988
+ EVP_MAC_CTX* mac_ctx = EVP_MAC_CTX_dup(mac_ctx_base_);
1989
+ if (mac_ctx == nullptr) {
1990
+ r = kErrOpenSSL;
1991
+ goto out;
1992
+ }
1993
+ if (EVP_MAC_update(mac_ctx, seqbuf, sizeof(seqbuf)) != 1
1994
+ || EVP_MAC_update(mac_ctx, first_block, 4) != 1
1995
+ || EVP_MAC_update(mac_ctx, packet, packet_len) != 1
1996
+ || EVP_MAC_final(mac_ctx,
1997
+ calc_mac,
1998
+ &outlen,
1999
+ outlen) != 1) {
2000
+ EVP_MAC_CTX_free(mac_ctx);
2001
+ r = kErrOpenSSL;
2002
+ goto out;
2003
+ }
2004
+ if (outlen != hmac_len_ || mac_len != hmac_actual_len_) {
2005
+ EVP_MAC_CTX_free(mac_ctx);
2006
+ r = kErrBadHMACLen;
2007
+ goto out;
2008
+ }
2009
+ EVP_MAC_CTX_free(mac_ctx);
2010
+ #else
2011
+ unsigned int outlen = hmac_len_;
2012
+ if (HMAC_Init_ex(ctx_hmac_, nullptr, 0, nullptr, nullptr) != 1
2013
+ || HMAC_Update(ctx_hmac_, seqbuf, sizeof(seqbuf)) != 1
2014
+ || HMAC_Update(ctx_hmac_, first_block, 4) != 1
2015
+ || HMAC_Update(ctx_hmac_, packet, packet_len) != 1
2016
+ || HMAC_Final(ctx_hmac_, calc_mac, &outlen) != 1) {
2017
+ r = kErrOpenSSL;
2018
+ goto out;
2019
+ }
2020
+ if (outlen != hmac_len_ || mac_len != hmac_actual_len_) {
2021
+ r = kErrBadHMACLen;
2022
+ goto out;
2023
+ }
2024
+ #endif
2025
+
2026
+ // Compare MACs
2027
+ if (CRYPTO_memcmp(mac, calc_mac, hmac_actual_len_)) {
2028
+ r = kErrInvalidMAC;
2029
+ goto out;
2030
+ }
2031
+ }
2032
+
2033
+ if (is_etm_) {
2034
+ // `first_block` for ETM should just be the unencrypted packet length
2035
+ if (first_block_len != 4) {
2036
+ r = kErrBadBlockLen;
2037
+ goto out;
2038
+ }
2039
+
2040
+ // Decrypt packet
2041
+ if (EVP_DecryptUpdate(ctx_, packet, &outlen, packet, packet_len) != 1) {
2042
+ r = kErrOpenSSL;
2043
+ goto out;
2044
+ }
2045
+ if (static_cast<size_t>(outlen) != packet_len) {
2046
+ r = kErrPartialDecrypt;
2047
+ goto out;
2048
+ }
2049
+ }
2050
+
2051
+ out:
2052
+ return r;
2053
+ }
2054
+
2055
+ static NAN_METHOD(New) {
2056
+ MarkPopErrorOnReturn mark_pop_error_on_return;
2057
+
2058
+ if (!info[0]->IsString())
2059
+ return Nan::ThrowTypeError("Missing/Invalid decipher name");
2060
+
2061
+ if (!Buffer::HasInstance(info[1]))
2062
+ return Nan::ThrowTypeError("Missing/Invalid decipher key");
2063
+
2064
+ if (!Buffer::HasInstance(info[2]))
2065
+ return Nan::ThrowTypeError("Missing/Invalid decipher IV");
2066
+
2067
+ if (!info[3]->IsString())
2068
+ return Nan::ThrowTypeError("Missing/Invalid HMAC name");
2069
+
2070
+ if (!Buffer::HasInstance(info[4]))
2071
+ return Nan::ThrowTypeError("Missing/Invalid HMAC key");
2072
+
2073
+ if (!info[5]->IsBoolean())
2074
+ return Nan::ThrowTypeError("Missing/Invalid HMAC ETM flag");
2075
+
2076
+ if (!info[6]->IsUint32())
2077
+ return Nan::ThrowTypeError("Missing/Invalid HMAC ETM flag");
2078
+
2079
+ const Nan::Utf8String cipher_name(info[0]);
2080
+ const Nan::Utf8String mac_name(info[3]);
2081
+ int is_etm = (Nan::To<bool>(info[5]).FromJust() ? 1 : 0);
2082
+
2083
+ GenericDecipher* obj = new GenericDecipher();
2084
+ ErrorType r = obj->init(
2085
+ *cipher_name,
2086
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[1])),
2087
+ Buffer::Length(info[1]),
2088
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[2])),
2089
+ Buffer::Length(info[2]),
2090
+ *mac_name,
2091
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[4])),
2092
+ Buffer::Length(info[4]),
2093
+ is_etm,
2094
+ Nan::To<uint32_t>(info[6]).FromJust()
2095
+ );
2096
+ if (r != kErrNone) {
2097
+ if (r == kErrOpenSSL) {
2098
+ char msg_buf[128] = {0};
2099
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
2100
+ ERR_clear_error();
2101
+ obj->clear();
2102
+ delete obj;
2103
+ return Nan::ThrowError(msg_buf);
2104
+ }
2105
+ obj->clear();
2106
+ delete obj;
2107
+ switch (r) {
2108
+ case kErrBadKeyLen:
2109
+ return Nan::ThrowError("Invalid decipher key length");
2110
+ case kErrBadIVLen:
2111
+ return Nan::ThrowError("Invalid decipher IV length");
2112
+ case kErrBadCipherName:
2113
+ return Nan::ThrowError("Invalid decipher name");
2114
+ case kErrBadHMACName:
2115
+ return Nan::ThrowError("Invalid MAC name");
2116
+ case kErrBadInit:
2117
+ return Nan::ThrowError("Failed to properly initialize decipher");
2118
+ default:
2119
+ return Nan::ThrowError("Unknown init failure");
2120
+ }
2121
+ }
2122
+
2123
+ obj->Wrap(info.This());
2124
+ info.GetReturnValue().Set(info.This());
2125
+ }
2126
+
2127
+ static NAN_METHOD(DecryptBlock) {
2128
+ MarkPopErrorOnReturn mark_pop_error_on_return;
2129
+
2130
+ GenericDecipher* obj = ObjectWrap::Unwrap<GenericDecipher>(info.Holder());
2131
+
2132
+ if (!Buffer::HasInstance(info[0]))
2133
+ return Nan::ThrowTypeError("Missing/Invalid block");
2134
+
2135
+ ErrorType r = obj->decrypt_block(
2136
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
2137
+ Buffer::Length(info[0])
2138
+ );
2139
+ switch (r) {
2140
+ case kErrNone:
2141
+ return;
2142
+ case kErrBadBlockLen:
2143
+ return Nan::ThrowError("Invalid block length");
2144
+ case kErrPartialDecrypt:
2145
+ return Nan::ThrowError("Failed to completely decrypt packet");
2146
+ case kErrOpenSSL: {
2147
+ char msg_buf[128] = {0};
2148
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
2149
+ ERR_clear_error();
2150
+ return Nan::ThrowError(msg_buf);
2151
+ }
2152
+ default:
2153
+ return Nan::ThrowError("Unknown decrypt failure");
2154
+ }
2155
+ }
2156
+
2157
+ static NAN_METHOD(Decrypt) {
2158
+ MarkPopErrorOnReturn mark_pop_error_on_return;
2159
+
2160
+ GenericDecipher* obj = ObjectWrap::Unwrap<GenericDecipher>(info.Holder());
2161
+
2162
+ if (!Buffer::HasInstance(info[0]))
2163
+ return Nan::ThrowTypeError("Missing/Invalid packet");
2164
+
2165
+ if (!info[1]->IsUint32())
2166
+ return Nan::ThrowTypeError("Missing/Invalid sequence number");
2167
+
2168
+ if (!Buffer::HasInstance(info[2]))
2169
+ return Nan::ThrowTypeError("Missing/Invalid first block");
2170
+
2171
+ if (!Buffer::HasInstance(info[3]))
2172
+ return Nan::ThrowTypeError("Missing/Invalid MAC");
2173
+
2174
+ ErrorType r = obj->decrypt(
2175
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[0])),
2176
+ Buffer::Length(info[0]),
2177
+ Nan::To<uint32_t>(info[1]).FromJust(),
2178
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[2])),
2179
+ Buffer::Length(info[2]),
2180
+ reinterpret_cast<unsigned char*>(Buffer::Data(info[3])),
2181
+ Buffer::Length(info[3])
2182
+ );
2183
+ switch (r) {
2184
+ case kErrNone:
2185
+ return;
2186
+ case kErrBadBlockLen:
2187
+ return Nan::ThrowError("Invalid block length");
2188
+ case kErrPartialDecrypt:
2189
+ return Nan::ThrowError("Failed to completely decrypt packet");
2190
+ case kErrBadHMACLen:
2191
+ return Nan::ThrowError("Unexpected HMAC length");
2192
+ case kErrInvalidMAC:
2193
+ return Nan::ThrowError("Invalid MAC");
2194
+ case kErrOpenSSL: {
2195
+ char msg_buf[128] = {0};
2196
+ ERR_error_string_n(ERR_get_error(), msg_buf, sizeof(msg_buf));
2197
+ ERR_clear_error();
2198
+ return Nan::ThrowError(msg_buf);
2199
+ }
2200
+ default:
2201
+ return Nan::ThrowError("Unknown decrypt failure");
2202
+ }
2203
+ }
2204
+
2205
+ static NAN_METHOD(Free) {
2206
+ GenericDecipher* obj = ObjectWrap::Unwrap<GenericDecipher>(info.Holder());
2207
+ obj->clear();
2208
+ }
2209
+
2210
+ static inline v8::Eternal<v8::Function> & constructor() {
2211
+ static v8::Eternal<v8::Function> my_constructor;
2212
+ return my_constructor;
2213
+ }
2214
+
2215
+ EVP_CIPHER_CTX* ctx_;
2216
+ #if REAL_OPENSSL_MAJOR >= 3
2217
+ EVP_MAC* mac_;
2218
+ EVP_MAC_CTX* mac_ctx_base_;
2219
+ size_t hmac_len_;
2220
+ #else
2221
+ HMAC_CTX* ctx_hmac_;
2222
+ unsigned int hmac_len_;
2223
+ #endif
2224
+ unsigned int hmac_actual_len_;
2225
+ uint8_t is_etm_;
2226
+ uint8_t is_stream_;
2227
+ uint32_t block_size_;
2228
+ };
2229
+
2230
+
2231
+ NAN_MODULE_INIT(init) {
2232
+ // These are needed because node-gyp (as of this writing) does not use the
2233
+ // proper (OpenSSL) system headers when node was built against a shared
2234
+ // version of OpenSSL. Usually this isn't an issue because OSes that build
2235
+ // node in this way typically use the same version of OpenSSL as was bundled
2236
+ // with node for a particular node version for the best compatibility. However
2237
+ // with the inclusion of OpenSSL 3.x in node v17.x, some OSes are still
2238
+ // linking with a shared OpenSSL 1.x, which can cause both compilation and
2239
+ // runtime errors because of changes in OpenSSL's code.
2240
+ //
2241
+ // For that reason, we need to make sure we need to resolve some specific
2242
+ // symbols at runtime to workaround these buggy situations.
2243
+ #ifdef _WIN32
2244
+ # define load_sym(name) GetProcAddress(GetModuleHandle(NULL), name)
2245
+ #else
2246
+ # define load_sym(name) dlsym(RTLD_DEFAULT, name)
2247
+ #endif
2248
+ if (!ctx_iv_len) {
2249
+ ctx_iv_len = reinterpret_cast<ctx_iv_len_func>(
2250
+ load_sym("EVP_CIPHER_CTX_get_iv_length")
2251
+ );
2252
+ if (!ctx_iv_len) {
2253
+ ctx_iv_len = reinterpret_cast<ctx_iv_len_func>(
2254
+ load_sym("EVP_CIPHER_CTX_iv_length")
2255
+ );
2256
+ }
2257
+ }
2258
+ if (!ctx_key_len) {
2259
+ ctx_key_len = reinterpret_cast<ctx_key_len_func>(
2260
+ load_sym("EVP_CIPHER_CTX_get_key_length")
2261
+ );
2262
+ if (!ctx_key_len) {
2263
+ ctx_key_len = reinterpret_cast<ctx_key_len_func>(
2264
+ load_sym("EVP_CIPHER_CTX_key_length")
2265
+ );
2266
+ }
2267
+ }
2268
+ if (!cipher_flags) {
2269
+ cipher_flags = reinterpret_cast<cipher_flags_func>(
2270
+ load_sym("EVP_CIPHER_get_flags")
2271
+ );
2272
+ if (!cipher_flags) {
2273
+ cipher_flags = reinterpret_cast<cipher_flags_func>(
2274
+ load_sym("EVP_CIPHER_flags")
2275
+ );
2276
+ }
2277
+ }
2278
+ if (!ctx_get_block_size) {
2279
+ ctx_get_block_size = reinterpret_cast<ctx_get_block_size_func>(
2280
+ load_sym("EVP_CIPHER_CTX_get_block_size")
2281
+ );
2282
+ if (!ctx_get_block_size) {
2283
+ ctx_get_block_size = reinterpret_cast<ctx_get_block_size_func>(
2284
+ load_sym("EVP_CIPHER_CTX_block_size")
2285
+ );
2286
+ }
2287
+ }
2288
+
2289
+ ChaChaPolyCipher::Init(target);
2290
+ AESGCMCipher::Init(target);
2291
+ GenericCipher::Init(target);
2292
+
2293
+ ChaChaPolyDecipher::Init(target);
2294
+ AESGCMDecipher::Init(target);
2295
+ GenericDecipher::Init(target);
2296
+ }
2297
+
2298
+ DISABLE_WCAST_FUNCTION_TYPE
2299
+ NAN_MODULE_WORKER_ENABLED(sshcrypto, init)
2300
+ DISABLE_WCAST_FUNCTION_TYPE_END