react-native-quick-crypto 0.7.3 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QuickCrypto.podspec +34 -0
- package/README.md +13 -46
- package/android/CMakeLists.txt +32 -64
- package/android/build.gradle +52 -125
- package/android/gradle.properties +4 -4
- package/android/src/main/cpp/cpp-adapter.cpp +9 -54
- package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +38 -0
- package/cpp/random/HybridRandom.cpp +34 -0
- package/cpp/random/HybridRandom.hpp +44 -0
- package/cpp/utils/Utils.hpp +9 -0
- package/ios/QuickCryptoOnLoad.mm +19 -0
- package/lib/commonjs/index.js +39 -39
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/random.js +26 -12
- package/lib/commonjs/random.js.map +1 -1
- package/lib/commonjs/{NativeQuickCrypto/rsa.js → specs/random.nitro.js} +1 -1
- package/lib/commonjs/{NativeQuickCrypto/aes.js.map → specs/random.nitro.js.map} +1 -1
- package/lib/commonjs/utils/conversion.js +22 -0
- package/lib/commonjs/utils/conversion.js.map +1 -0
- package/lib/commonjs/utils/index.js +12 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/types.js +2 -0
- package/lib/{module/NativeQuickCrypto/aes.js.map → commonjs/utils/types.js.map} +1 -1
- package/lib/module/index.js +38 -38
- package/lib/module/index.js.map +1 -1
- package/lib/module/random.js +26 -12
- package/lib/module/random.js.map +1 -1
- package/lib/module/specs/random.nitro.js +4 -0
- package/lib/module/{NativeQuickCrypto/rsa.js.map → specs/random.nitro.js.map} +1 -1
- package/lib/module/utils/conversion.js +16 -0
- package/lib/module/utils/conversion.js.map +1 -0
- package/lib/module/utils/index.js +8 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/types.js +2 -0
- package/lib/{commonjs/NativeQuickCrypto/rsa.js.map → module/utils/types.js.map} +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/typescript/index.d.ts +10 -141
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/random.d.ts +4 -5
- package/lib/typescript/random.d.ts.map +1 -1
- package/lib/typescript/specs/random.nitro.d.ts +9 -0
- package/lib/typescript/specs/random.nitro.d.ts.map +1 -0
- package/lib/typescript/utils/conversion.d.ts +4 -0
- package/lib/typescript/utils/conversion.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +6 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/lib/typescript/utils/types.d.ts +5 -0
- package/lib/typescript/utils/types.d.ts.map +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +45 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +26 -0
- package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +57 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +9 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +25 -0
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +29 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +62 -0
- package/package.json +50 -106
- package/src/index.ts +38 -48
- package/src/random.ts +51 -48
- package/src/specs/random.nitro.ts +14 -0
- package/src/utils/conversion.ts +16 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/types.ts +15 -0
- package/LICENSE +0 -27
- package/android/src/main/java/com/margelo/quickcrypto/QuickCryptoModule.java +0 -70
- package/android/src/main/java/com/margelo/quickcrypto/QuickCryptoPackage.java +0 -25
- package/cpp/Cipher/MGLCipherHostObject.cpp +0 -663
- package/cpp/Cipher/MGLCipherHostObject.h +0 -90
- package/cpp/Cipher/MGLCreateCipherInstaller.cpp +0 -75
- package/cpp/Cipher/MGLCreateCipherInstaller.h +0 -22
- package/cpp/Cipher/MGLCreateDecipherInstaller.cpp +0 -77
- package/cpp/Cipher/MGLCreateDecipherInstaller.h +0 -17
- package/cpp/Cipher/MGLGenerateKeyPairInstaller.cpp +0 -134
- package/cpp/Cipher/MGLGenerateKeyPairInstaller.h +0 -35
- package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.cpp +0 -63
- package/cpp/Cipher/MGLGenerateKeyPairSyncInstaller.h +0 -37
- package/cpp/Cipher/MGLPublicCipher.h +0 -124
- package/cpp/Cipher/MGLPublicCipherInstaller.h +0 -107
- package/cpp/Cipher/MGLRsa.cpp +0 -573
- package/cpp/Cipher/MGLRsa.h +0 -109
- package/cpp/HMAC/MGLHmacHostObject.cpp +0 -95
- package/cpp/HMAC/MGLHmacHostObject.h +0 -39
- package/cpp/HMAC/MGLHmacInstaller.cpp +0 -43
- package/cpp/HMAC/MGLHmacInstaller.h +0 -20
- package/cpp/Hash/MGLHashHostObject.cpp +0 -147
- package/cpp/Hash/MGLHashHostObject.h +0 -53
- package/cpp/Hash/MGLHashInstaller.cpp +0 -44
- package/cpp/Hash/MGLHashInstaller.h +0 -20
- package/cpp/JSIUtils/MGLJSIMacros.h +0 -110
- package/cpp/JSIUtils/MGLJSIUtils.h +0 -41
- package/cpp/JSIUtils/MGLSmartHostObject.cpp +0 -43
- package/cpp/JSIUtils/MGLSmartHostObject.h +0 -46
- package/cpp/JSIUtils/MGLThreadAwareHostObject.cpp +0 -24
- package/cpp/JSIUtils/MGLThreadAwareHostObject.h +0 -43
- package/cpp/JSIUtils/MGLTypedArray.cpp +0 -325
- package/cpp/JSIUtils/MGLTypedArray.h +0 -160
- package/cpp/MGLKeys.cpp +0 -1426
- package/cpp/MGLKeys.h +0 -203
- package/cpp/MGLQuickCryptoHostObject.cpp +0 -127
- package/cpp/MGLQuickCryptoHostObject.h +0 -30
- package/cpp/Random/MGLRandomHostObject.cpp +0 -96
- package/cpp/Random/MGLRandomHostObject.h +0 -27
- package/cpp/Sig/MGLSignHostObjects.cpp +0 -757
- package/cpp/Sig/MGLSignHostObjects.h +0 -128
- package/cpp/Sig/MGLSignInstaller.cpp +0 -24
- package/cpp/Sig/MGLSignInstaller.h +0 -29
- package/cpp/Sig/MGLVerifyInstaller.cpp +0 -24
- package/cpp/Sig/MGLVerifyInstaller.h +0 -22
- package/cpp/Utils/MGLDispatchQueue.cpp +0 -75
- package/cpp/Utils/MGLDispatchQueue.h +0 -55
- package/cpp/Utils/MGLUtils.cpp +0 -295
- package/cpp/Utils/MGLUtils.h +0 -358
- package/cpp/Utils/base64.h +0 -320
- package/cpp/Utils/logs.h +0 -38
- package/cpp/Utils/node.h +0 -13
- package/cpp/fastpbkdf2/MGLPbkdf2HostObject.cpp +0 -164
- package/cpp/fastpbkdf2/MGLPbkdf2HostObject.h +0 -29
- package/cpp/fastpbkdf2/fastpbkdf2.c +0 -352
- package/cpp/fastpbkdf2/fastpbkdf2.h +0 -68
- package/cpp/webcrypto/MGLWebCrypto.cpp +0 -125
- package/cpp/webcrypto/MGLWebCrypto.h +0 -32
- package/cpp/webcrypto/crypto_aes.cpp +0 -516
- package/cpp/webcrypto/crypto_aes.h +0 -79
- package/cpp/webcrypto/crypto_ec.cpp +0 -424
- package/cpp/webcrypto/crypto_ec.h +0 -78
- package/cpp/webcrypto/crypto_keygen.cpp +0 -86
- package/cpp/webcrypto/crypto_keygen.h +0 -38
- package/ios/QuickCrypto.xcodeproj/project.pbxproj +0 -274
- package/ios/QuickCryptoModule.h +0 -5
- package/ios/QuickCryptoModule.mm +0 -42
- package/lib/commonjs/Cipher.js +0 -502
- package/lib/commonjs/Cipher.js.map +0 -1
- package/lib/commonjs/Hash.js +0 -99
- package/lib/commonjs/Hash.js.map +0 -1
- package/lib/commonjs/Hashnames.js +0 -87
- package/lib/commonjs/Hashnames.js.map +0 -1
- package/lib/commonjs/Hmac.js +0 -79
- package/lib/commonjs/Hmac.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/Cipher.js +0 -30
- package/lib/commonjs/NativeQuickCrypto/Cipher.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js +0 -52
- package/lib/commonjs/NativeQuickCrypto/NativeQuickCrypto.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/aes.js +0 -6
- package/lib/commonjs/NativeQuickCrypto/hash.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/hash.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/hmac.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/hmac.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/keygen.js +0 -6
- package/lib/commonjs/NativeQuickCrypto/keygen.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/pbkdf2.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/pbkdf2.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/random.js +0 -2
- package/lib/commonjs/NativeQuickCrypto/random.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/sig.js +0 -19
- package/lib/commonjs/NativeQuickCrypto/sig.js.map +0 -1
- package/lib/commonjs/NativeQuickCrypto/webcrypto.js +0 -6
- package/lib/commonjs/NativeQuickCrypto/webcrypto.js.map +0 -1
- package/lib/commonjs/Utils.js +0 -608
- package/lib/commonjs/Utils.js.map +0 -1
- package/lib/commonjs/aes.js +0 -281
- package/lib/commonjs/aes.js.map +0 -1
- package/lib/commonjs/constants.js +0 -85
- package/lib/commonjs/constants.js.map +0 -1
- package/lib/commonjs/ec.js +0 -276
- package/lib/commonjs/ec.js.map +0 -1
- package/lib/commonjs/keygen.js +0 -56
- package/lib/commonjs/keygen.js.map +0 -1
- package/lib/commonjs/keys.js +0 -492
- package/lib/commonjs/keys.js.map +0 -1
- package/lib/commonjs/pbkdf2.js +0 -90
- package/lib/commonjs/pbkdf2.js.map +0 -1
- package/lib/commonjs/rsa.js +0 -248
- package/lib/commonjs/rsa.js.map +0 -1
- package/lib/commonjs/sig.js +0 -129
- package/lib/commonjs/sig.js.map +0 -1
- package/lib/commonjs/subtle.js +0 -448
- package/lib/commonjs/subtle.js.map +0 -1
- package/lib/commonjs/webcrypto.js +0 -14
- package/lib/commonjs/webcrypto.js.map +0 -1
- package/lib/module/Cipher.js +0 -491
- package/lib/module/Cipher.js.map +0 -1
- package/lib/module/Hash.js +0 -93
- package/lib/module/Hash.js.map +0 -1
- package/lib/module/Hashnames.js +0 -85
- package/lib/module/Hashnames.js.map +0 -1
- package/lib/module/Hmac.js +0 -74
- package/lib/module/Hmac.js.map +0 -1
- package/lib/module/NativeQuickCrypto/Cipher.js +0 -26
- package/lib/module/NativeQuickCrypto/Cipher.js.map +0 -1
- package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js +0 -49
- package/lib/module/NativeQuickCrypto/NativeQuickCrypto.js.map +0 -1
- package/lib/module/NativeQuickCrypto/aes.js +0 -4
- package/lib/module/NativeQuickCrypto/hash.js +0 -2
- package/lib/module/NativeQuickCrypto/hash.js.map +0 -1
- package/lib/module/NativeQuickCrypto/hmac.js +0 -2
- package/lib/module/NativeQuickCrypto/hmac.js.map +0 -1
- package/lib/module/NativeQuickCrypto/keygen.js +0 -4
- package/lib/module/NativeQuickCrypto/keygen.js.map +0 -1
- package/lib/module/NativeQuickCrypto/pbkdf2.js +0 -2
- package/lib/module/NativeQuickCrypto/pbkdf2.js.map +0 -1
- package/lib/module/NativeQuickCrypto/random.js +0 -2
- package/lib/module/NativeQuickCrypto/random.js.map +0 -1
- package/lib/module/NativeQuickCrypto/rsa.js +0 -4
- package/lib/module/NativeQuickCrypto/sig.js +0 -17
- package/lib/module/NativeQuickCrypto/sig.js.map +0 -1
- package/lib/module/NativeQuickCrypto/webcrypto.js +0 -4
- package/lib/module/NativeQuickCrypto/webcrypto.js.map +0 -1
- package/lib/module/Utils.js +0 -539
- package/lib/module/Utils.js.map +0 -1
- package/lib/module/aes.js +0 -274
- package/lib/module/aes.js.map +0 -1
- package/lib/module/constants.js +0 -81
- package/lib/module/constants.js.map +0 -1
- package/lib/module/ec.js +0 -267
- package/lib/module/ec.js.map +0 -1
- package/lib/module/keygen.js +0 -49
- package/lib/module/keygen.js.map +0 -1
- package/lib/module/keys.js +0 -477
- package/lib/module/keys.js.map +0 -1
- package/lib/module/pbkdf2.js +0 -84
- package/lib/module/pbkdf2.js.map +0 -1
- package/lib/module/rsa.js +0 -242
- package/lib/module/rsa.js.map +0 -1
- package/lib/module/sig.js +0 -124
- package/lib/module/sig.js.map +0 -1
- package/lib/module/subtle.js +0 -443
- package/lib/module/subtle.js.map +0 -1
- package/lib/module/webcrypto.js +0 -10
- package/lib/module/webcrypto.js.map +0 -1
- package/lib/typescript/Cipher.d.ts +0 -81
- package/lib/typescript/Cipher.d.ts.map +0 -1
- package/lib/typescript/Hash.d.ts +0 -44
- package/lib/typescript/Hash.d.ts.map +0 -1
- package/lib/typescript/Hashnames.d.ts +0 -11
- package/lib/typescript/Hashnames.d.ts.map +0 -1
- package/lib/typescript/Hmac.d.ts +0 -37
- package/lib/typescript/Hmac.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/Cipher.d.ts +0 -44
- package/lib/typescript/NativeQuickCrypto/Cipher.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/NativeQuickCrypto.d.ts +0 -33
- package/lib/typescript/NativeQuickCrypto/NativeQuickCrypto.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/aes.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/aes.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/hash.d.ts +0 -7
- package/lib/typescript/NativeQuickCrypto/hash.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/hmac.d.ts +0 -6
- package/lib/typescript/NativeQuickCrypto/hmac.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/keygen.d.ts +0 -4
- package/lib/typescript/NativeQuickCrypto/keygen.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/pbkdf2.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/pbkdf2.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/random.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/random.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/rsa.d.ts +0 -5
- package/lib/typescript/NativeQuickCrypto/rsa.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/sig.d.ts +0 -23
- package/lib/typescript/NativeQuickCrypto/sig.d.ts.map +0 -1
- package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts +0 -39
- package/lib/typescript/NativeQuickCrypto/webcrypto.d.ts.map +0 -1
- package/lib/typescript/Utils.d.ts +0 -48
- package/lib/typescript/Utils.d.ts.map +0 -1
- package/lib/typescript/aes.d.ts +0 -22
- package/lib/typescript/aes.d.ts.map +0 -1
- package/lib/typescript/constants.d.ts +0 -76
- package/lib/typescript/constants.d.ts.map +0 -1
- package/lib/typescript/ec.d.ts +0 -7
- package/lib/typescript/ec.d.ts.map +0 -1
- package/lib/typescript/keygen.d.ts +0 -6
- package/lib/typescript/keygen.d.ts.map +0 -1
- package/lib/typescript/keys.d.ts +0 -206
- package/lib/typescript/keys.d.ts.map +0 -1
- package/lib/typescript/pbkdf2.d.ts +0 -12
- package/lib/typescript/pbkdf2.d.ts.map +0 -1
- package/lib/typescript/rsa.d.ts +0 -12
- package/lib/typescript/rsa.d.ts.map +0 -1
- package/lib/typescript/sig.d.ts +0 -21
- package/lib/typescript/sig.d.ts.map +0 -1
- package/lib/typescript/subtle.d.ts +0 -15
- package/lib/typescript/subtle.d.ts.map +0 -1
- package/lib/typescript/webcrypto.d.ts +0 -9
- package/lib/typescript/webcrypto.d.ts.map +0 -1
- package/react-native-quick-crypto.podspec +0 -40
- package/src/Cipher.ts +0 -832
- package/src/Hash.ts +0 -132
- package/src/Hashnames.ts +0 -93
- package/src/Hmac.ts +0 -106
- package/src/NativeQuickCrypto/Cipher.ts +0 -102
- package/src/NativeQuickCrypto/NativeQuickCrypto.ts +0 -102
- package/src/NativeQuickCrypto/aes.ts +0 -14
- package/src/NativeQuickCrypto/hash.ts +0 -10
- package/src/NativeQuickCrypto/hmac.ts +0 -9
- package/src/NativeQuickCrypto/keygen.ts +0 -7
- package/src/NativeQuickCrypto/pbkdf2.ts +0 -16
- package/src/NativeQuickCrypto/random.ts +0 -12
- package/src/NativeQuickCrypto/rsa.ts +0 -12
- package/src/NativeQuickCrypto/sig.ts +0 -44
- package/src/NativeQuickCrypto/webcrypto.ts +0 -72
- package/src/Utils.ts +0 -777
- package/src/aes.ts +0 -402
- package/src/constants.ts +0 -79
- package/src/ec.ts +0 -375
- package/src/keygen.ts +0 -80
- package/src/keys.ts +0 -787
- package/src/pbkdf2.ts +0 -169
- package/src/rsa.ts +0 -370
- package/src/sig.ts +0 -164
- package/src/subtle.ts +0 -639
- package/src/webcrypto.ts +0 -8
- /package/android/src/main/{AndroidManifestNew.xml → AndroidManifest.xml} +0 -0
|
@@ -1,663 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Created by Oscar on 07.06.22.
|
|
3
|
-
//
|
|
4
|
-
#include "MGLCipherHostObject.h"
|
|
5
|
-
|
|
6
|
-
#ifdef ANDROID
|
|
7
|
-
#include "JSIUtils/MGLJSIUtils.h"
|
|
8
|
-
#include "JSIUtils/MGLTypedArray.h"
|
|
9
|
-
#else
|
|
10
|
-
#include "MGLJSIUtils.h"
|
|
11
|
-
#include "MGLTypedArray.h"
|
|
12
|
-
#endif
|
|
13
|
-
|
|
14
|
-
#include <openssl/evp.h>
|
|
15
|
-
|
|
16
|
-
#include <algorithm>
|
|
17
|
-
#include <memory>
|
|
18
|
-
#include <string>
|
|
19
|
-
#include <utility>
|
|
20
|
-
#include <vector>
|
|
21
|
-
|
|
22
|
-
#define OUT
|
|
23
|
-
|
|
24
|
-
// TODO(osp) Some of the code is inspired or copied from node-js, check if
|
|
25
|
-
// attribution is needed
|
|
26
|
-
namespace margelo {
|
|
27
|
-
|
|
28
|
-
namespace jsi = facebook::jsi;
|
|
29
|
-
|
|
30
|
-
// TODO(osp) move this to constants file (crypto_aes.cpp in node)
|
|
31
|
-
constexpr unsigned kNoAuthTagLength = static_cast<unsigned>(-1);
|
|
32
|
-
|
|
33
|
-
bool IsSupportedAuthenticatedMode(const EVP_CIPHER *cipher) {
|
|
34
|
-
switch (EVP_CIPHER_mode(cipher)) {
|
|
35
|
-
case EVP_CIPH_CCM_MODE:
|
|
36
|
-
case EVP_CIPH_GCM_MODE:
|
|
37
|
-
#ifndef OPENSSL_NO_OCB
|
|
38
|
-
case EVP_CIPH_OCB_MODE:
|
|
39
|
-
#endif
|
|
40
|
-
return true;
|
|
41
|
-
case EVP_CIPH_STREAM_CIPHER:
|
|
42
|
-
return EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305;
|
|
43
|
-
default:
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX *ctx) {
|
|
49
|
-
const EVP_CIPHER *cipher = EVP_CIPHER_CTX_cipher(ctx);
|
|
50
|
-
return IsSupportedAuthenticatedMode(cipher);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
bool IsValidGCMTagLength(unsigned int tag_len) {
|
|
54
|
-
return tag_len == 4 || tag_len == 8 || (tag_len >= 12 && tag_len <= 16);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
void CopyTo(jsi::Runtime &runtime, jsi::ArrayBuffer *src, char *dest,
|
|
58
|
-
size_t len) {
|
|
59
|
-
// static_assert(sizeof(M) == 1, "sizeof(M) must equal 1");
|
|
60
|
-
len = std::min(len, src->size(runtime));
|
|
61
|
-
if (len > 0 && src->data(runtime) != nullptr)
|
|
62
|
-
memcpy(dest, src->data(runtime), len);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
MGLCipherHostObject::MGLCipherHostObject(
|
|
66
|
-
std::shared_ptr<react::CallInvoker> jsCallInvoker,
|
|
67
|
-
std::shared_ptr<DispatchQueue::dispatch_queue> workerQueue)
|
|
68
|
-
: MGLSmartHostObject(jsCallInvoker, workerQueue) {
|
|
69
|
-
installMethods();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
MGLCipherHostObject::MGLCipherHostObject(
|
|
73
|
-
MGLCipherHostObject *other,
|
|
74
|
-
std::shared_ptr<react::CallInvoker> jsCallInvoker,
|
|
75
|
-
std::shared_ptr<DispatchQueue::dispatch_queue> workerQueue)
|
|
76
|
-
: MGLSmartHostObject(jsCallInvoker, workerQueue),
|
|
77
|
-
isCipher_(other->isCipher_) {
|
|
78
|
-
installMethods();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
MGLCipherHostObject::MGLCipherHostObject(
|
|
82
|
-
const std::string &cipher_type, jsi::ArrayBuffer *cipher_key, bool isCipher,
|
|
83
|
-
unsigned int auth_tag_len, jsi::Runtime &runtime,
|
|
84
|
-
std::shared_ptr<react::CallInvoker> jsCallInvoker,
|
|
85
|
-
std::shared_ptr<DispatchQueue::dispatch_queue> workerQueue)
|
|
86
|
-
: MGLSmartHostObject(jsCallInvoker, workerQueue),
|
|
87
|
-
isCipher_(isCipher),
|
|
88
|
-
pending_auth_failed_(false) {
|
|
89
|
-
// TODO(osp) is this needed on the SSL version we are using?
|
|
90
|
-
// #if OPENSSL_VERSION_MAJOR >= 3
|
|
91
|
-
// if (EVP_default_properties_is_fips_enabled(nullptr)) {
|
|
92
|
-
// #else
|
|
93
|
-
// if (FIPS_mode()) {
|
|
94
|
-
// #endif
|
|
95
|
-
// return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
|
|
96
|
-
// "crypto.createCipher()
|
|
97
|
-
// is not supported in
|
|
98
|
-
// FIPS mode.");
|
|
99
|
-
// }
|
|
100
|
-
|
|
101
|
-
const EVP_CIPHER *const cipher = EVP_get_cipherbyname(cipher_type.c_str());
|
|
102
|
-
if (cipher == nullptr) {
|
|
103
|
-
throw jsi::JSError(runtime, "Invalid Cipher Algorithm!");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
unsigned char key[EVP_MAX_KEY_LENGTH];
|
|
107
|
-
unsigned char iv[EVP_MAX_IV_LENGTH];
|
|
108
|
-
|
|
109
|
-
int key_len =
|
|
110
|
-
EVP_BytesToKey(cipher, EVP_md5(), nullptr, cipher_key->data(runtime),
|
|
111
|
-
static_cast<int>(cipher_key->size(runtime)), 1, key, iv);
|
|
112
|
-
|
|
113
|
-
// TODO(osp) this looks like a macro, check if necessary
|
|
114
|
-
// CHECK_NE(key_len, 0);
|
|
115
|
-
|
|
116
|
-
// TODO(osp) this seems like a runtime check
|
|
117
|
-
// const int mode = EVP_CIPHER_mode(cipher);
|
|
118
|
-
// if (isCipher && (mode == EVP_CIPH_CTR_MODE ||
|
|
119
|
-
// mode == EVP_CIPH_GCM_MODE ||
|
|
120
|
-
// mode == EVP_CIPH_CCM_MODE)) {
|
|
121
|
-
// // Ignore the return value (i.e. possible exception) because we are
|
|
122
|
-
// // not calling back into JS anyway.
|
|
123
|
-
// ProcessEmitWarning(env(),
|
|
124
|
-
// "Use Cipheriv for counter mode of %s",
|
|
125
|
-
// cipher_type);
|
|
126
|
-
// }
|
|
127
|
-
|
|
128
|
-
commonInit(runtime, cipher_type.c_str(), cipher, key, key_len, iv,
|
|
129
|
-
EVP_CIPHER_iv_length(cipher), auth_tag_len);
|
|
130
|
-
|
|
131
|
-
installMethods();
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
MGLCipherHostObject::MGLCipherHostObject(
|
|
135
|
-
const std::string &cipher_type, jsi::ArrayBuffer *cipher_key, bool isCipher,
|
|
136
|
-
unsigned int auth_tag_len, jsi::ArrayBuffer *iv, jsi::Runtime &runtime,
|
|
137
|
-
std::shared_ptr<react::CallInvoker> jsCallInvoker,
|
|
138
|
-
std::shared_ptr<DispatchQueue::dispatch_queue> workerQueue)
|
|
139
|
-
: MGLSmartHostObject(jsCallInvoker, workerQueue),
|
|
140
|
-
isCipher_(isCipher),
|
|
141
|
-
pending_auth_failed_(false) {
|
|
142
|
-
// TODO(osp) is this needed on the SSL version we are using?
|
|
143
|
-
// #if OPENSSL_VERSION_MAJOR >= 3
|
|
144
|
-
// if (EVP_default_properties_is_fips_enabled(nullptr)) {
|
|
145
|
-
// #else
|
|
146
|
-
// if (FIPS_mode()) {
|
|
147
|
-
// #endif
|
|
148
|
-
// return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
|
|
149
|
-
// "crypto.createCipher()
|
|
150
|
-
// is not supported in
|
|
151
|
-
// FIPS mode.");
|
|
152
|
-
// }
|
|
153
|
-
|
|
154
|
-
const EVP_CIPHER *const cipher = EVP_get_cipherbyname(cipher_type.c_str());
|
|
155
|
-
if (cipher == nullptr) {
|
|
156
|
-
throw jsi::JSError(runtime, "Invalid Cipher Algorithm!");
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const int expected_iv_len = EVP_CIPHER_iv_length(cipher);
|
|
160
|
-
const int is_authenticated_mode = IsSupportedAuthenticatedMode(cipher);
|
|
161
|
-
const bool has_iv = iv->size(runtime) > 0;
|
|
162
|
-
|
|
163
|
-
// Throw if an IV was passed which does not match the cipher's fixed IV length
|
|
164
|
-
// static_cast<int> for the iv_buf.size() is safe because we've verified
|
|
165
|
-
// prior that the value is not larger than MAX_INT.
|
|
166
|
-
if (!is_authenticated_mode && has_iv &&
|
|
167
|
-
static_cast<int>(iv->size(runtime)) != expected_iv_len) {
|
|
168
|
-
throw jsi::JSError(runtime, "Invalid iv");
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (EVP_CIPHER_nid(cipher) == NID_chacha20_poly1305) {
|
|
172
|
-
// CHECK(has_iv);
|
|
173
|
-
// Check for invalid IV lengths, since OpenSSL does not under some
|
|
174
|
-
// conditions:
|
|
175
|
-
// https://www.openssl.org/news/secadv/20190306.txt.
|
|
176
|
-
if (iv->size(runtime) > 12) throw jsi::JSError(runtime, "Invalid iv");
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
commonInit(runtime, cipher_type.c_str(), cipher, cipher_key->data(runtime),
|
|
180
|
-
cipher_key->size(runtime), iv->data(runtime), iv->size(runtime),
|
|
181
|
-
auth_tag_len);
|
|
182
|
-
|
|
183
|
-
installMethods();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
void MGLCipherHostObject::commonInit(jsi::Runtime &runtime,
|
|
187
|
-
const char *cipher_type,
|
|
188
|
-
const EVP_CIPHER *cipher,
|
|
189
|
-
const unsigned char *key, int key_len,
|
|
190
|
-
const unsigned char *iv, int iv_len,
|
|
191
|
-
unsigned int auth_tag_len) {
|
|
192
|
-
// TODO(osp) check for this macro
|
|
193
|
-
// CHECK(!ctx_);
|
|
194
|
-
|
|
195
|
-
EVP_CIPHER_CTX_free(ctx_);
|
|
196
|
-
ctx_ = EVP_CIPHER_CTX_new();
|
|
197
|
-
|
|
198
|
-
const int mode = EVP_CIPHER_mode(cipher);
|
|
199
|
-
if (mode == EVP_CIPH_WRAP_MODE) {
|
|
200
|
-
EVP_CIPHER_CTX_set_flags(ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (1 !=
|
|
204
|
-
EVP_CipherInit_ex(ctx_, cipher, nullptr, nullptr, nullptr, isCipher_)) {
|
|
205
|
-
throw jsi::JSError(runtime, "Failed to initialize cipher");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (IsSupportedAuthenticatedMode(cipher)) {
|
|
209
|
-
// TODO(osp) implement this check macro
|
|
210
|
-
// CHECK_GE(iv_len, 0);
|
|
211
|
-
if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len)) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (!EVP_CIPHER_CTX_set_key_length(ctx_, key_len)) {
|
|
217
|
-
EVP_CIPHER_CTX_free(ctx_);
|
|
218
|
-
ctx_ = nullptr;
|
|
219
|
-
throw std::runtime_error("Invalid Cipher key length!");
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (1 != EVP_CipherInit_ex(ctx_, nullptr, nullptr, key, iv, isCipher_)) {
|
|
223
|
-
throw std::runtime_error("Failed to initialize cipher!");
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
void MGLCipherHostObject::installMethods() {
|
|
228
|
-
// Instance methods
|
|
229
|
-
|
|
230
|
-
// update
|
|
231
|
-
this->fields.push_back(buildPair(
|
|
232
|
-
"update", JSIF([this]) {
|
|
233
|
-
if (count != 1) {
|
|
234
|
-
throw jsi::JSError(runtime,
|
|
235
|
-
"cipher.update requires at least 2 parameters");
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (!arguments[0].isObject() ||
|
|
239
|
-
!arguments[0].asObject(runtime).isArrayBuffer(runtime)) {
|
|
240
|
-
throw jsi::JSError(runtime,
|
|
241
|
-
"cipher.update first argument ('data') needs to "
|
|
242
|
-
"be an ArrayBuffer");
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
auto dataArrayBuffer =
|
|
246
|
-
arguments[0].asObject(runtime).getArrayBuffer(runtime);
|
|
247
|
-
|
|
248
|
-
const unsigned char *data = dataArrayBuffer.data(runtime);
|
|
249
|
-
auto len = dataArrayBuffer.length(runtime);
|
|
250
|
-
|
|
251
|
-
if (ctx_ == nullptr || len > INT_MAX) {
|
|
252
|
-
// On the node version there are several layers of wrapping and errors
|
|
253
|
-
// are not immediately surfaced On our version we can simply throw an
|
|
254
|
-
// error as soon as something goes wrong
|
|
255
|
-
throw jsi::JSError(runtime, "kErrorState");
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const int mode = EVP_CIPHER_CTX_mode(ctx_);
|
|
259
|
-
|
|
260
|
-
if (mode == EVP_CIPH_CCM_MODE && !CheckCCMMessageLength(len)) {
|
|
261
|
-
throw jsi::JSError(runtime, "kErrorMessageSize");
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Pass the authentication tag to OpenSSL if possible. This will only
|
|
265
|
-
// happen once, usually on the first update.
|
|
266
|
-
if (!isCipher_ && IsAuthenticatedMode()) {
|
|
267
|
-
// TODO(osp) check
|
|
268
|
-
MaybePassAuthTagToOpenSSL();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
int buf_len = len + EVP_CIPHER_CTX_block_size(ctx_);
|
|
272
|
-
// For key wrapping algorithms, get output size by calling
|
|
273
|
-
// EVP_CipherUpdate() with null output.
|
|
274
|
-
if (isCipher_ && mode == EVP_CIPH_WRAP_MODE &&
|
|
275
|
-
EVP_CipherUpdate(ctx_, nullptr, &buf_len, data, len) != 1) {
|
|
276
|
-
throw jsi::JSError(runtime, "kErrorState");
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
MGLTypedArray<MGLTypedArrayKind::Uint8Array> out(runtime, buf_len);
|
|
280
|
-
|
|
281
|
-
// Important this function returns the real size of the data in buf_len
|
|
282
|
-
// Output needs to be truncated to not send extra 0s
|
|
283
|
-
int r = EVP_CipherUpdate(ctx_, out.getBuffer(runtime).data(runtime),
|
|
284
|
-
&buf_len, data, len);
|
|
285
|
-
|
|
286
|
-
// Trim exceeding bytes
|
|
287
|
-
MGLTypedArray<MGLTypedArrayKind::Uint8Array> ret(runtime, buf_len);
|
|
288
|
-
std::vector<unsigned char> vec(
|
|
289
|
-
out.getBuffer(runtime).data(runtime),
|
|
290
|
-
out.getBuffer(runtime).data(runtime) + buf_len);
|
|
291
|
-
ret.update(runtime, vec);
|
|
292
|
-
|
|
293
|
-
// When in CCM mode, EVP_CipherUpdate will fail if the authentication
|
|
294
|
-
// tag is invalid. In that case, remember the error and throw in
|
|
295
|
-
// final().
|
|
296
|
-
if (!r && !isCipher_ && mode == EVP_CIPH_CCM_MODE) {
|
|
297
|
-
pending_auth_failed_ = true;
|
|
298
|
-
return ret;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// return r == 1 ? jsi::Value((int)kSuccess) :
|
|
302
|
-
// jsi::Value((int)kErrorState);
|
|
303
|
-
return ret;
|
|
304
|
-
}));
|
|
305
|
-
|
|
306
|
-
// final
|
|
307
|
-
this->fields.push_back(HOST_LAMBDA("final", {
|
|
308
|
-
if (ctx_ == nullptr) {
|
|
309
|
-
throw jsi::JSError(runtime, "kErrorState");
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const int mode = EVP_CIPHER_CTX_mode(ctx_);
|
|
313
|
-
|
|
314
|
-
int buf_len = EVP_CIPHER_CTX_block_size(ctx_);
|
|
315
|
-
MGLTypedArray<MGLTypedArrayKind::Uint8Array> out(runtime, buf_len);
|
|
316
|
-
|
|
317
|
-
if (!isCipher_ && IsSupportedAuthenticatedMode(ctx_)) {
|
|
318
|
-
MaybePassAuthTagToOpenSSL();
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// In CCM mode, final() only checks whether authentication failed in
|
|
322
|
-
// update(). EVP_CipherFinal_ex must not be called and will fail.
|
|
323
|
-
bool ok;
|
|
324
|
-
int out_len = out.byteLength(runtime);
|
|
325
|
-
if (!isCipher_ && mode == EVP_CIPH_CCM_MODE) {
|
|
326
|
-
ok = !pending_auth_failed_;
|
|
327
|
-
MGLTypedArray<MGLTypedArrayKind::Uint8Array> out(runtime, 0);
|
|
328
|
-
} else {
|
|
329
|
-
ok = EVP_CipherFinal_ex(ctx_, out.getBuffer(runtime).data(runtime),
|
|
330
|
-
&out_len) == 1;
|
|
331
|
-
|
|
332
|
-
// Additional operations for authenticated modes
|
|
333
|
-
if (ok && isCipher_ && IsAuthenticatedMode()) {
|
|
334
|
-
// In GCM mode: default to 16 bytes.
|
|
335
|
-
// In CCM, OCB mode: must be provided by user.
|
|
336
|
-
|
|
337
|
-
// Logic for default auth tag length
|
|
338
|
-
if (auth_tag_len_ == kNoAuthTagLength) {
|
|
339
|
-
// TODO(osp) check
|
|
340
|
-
// CHECK(mode == EVP_CIPH_GCM_MODE);
|
|
341
|
-
auth_tag_len_ = sizeof(auth_tag_);
|
|
342
|
-
}
|
|
343
|
-
ok = (1 == EVP_CIPHER_CTX_ctrl(
|
|
344
|
-
ctx_, EVP_CTRL_AEAD_GET_TAG, auth_tag_len_,
|
|
345
|
-
reinterpret_cast<unsigned char *>(auth_tag_)));
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
MGLTypedArray<MGLTypedArrayKind::Uint8Array> ret(runtime, out_len);
|
|
350
|
-
if (out_len > 0) {
|
|
351
|
-
std::vector<unsigned char> vec(
|
|
352
|
-
out.getBuffer(runtime).data(runtime),
|
|
353
|
-
out.getBuffer(runtime).data(runtime) + out_len);
|
|
354
|
-
ret.update(runtime, vec);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
EVP_CIPHER_CTX_free(ctx_);
|
|
358
|
-
ctx_ = nullptr;
|
|
359
|
-
|
|
360
|
-
return ret;
|
|
361
|
-
}));
|
|
362
|
-
|
|
363
|
-
// setAAD
|
|
364
|
-
this->fields.push_back(HOST_LAMBDA("setAAD", {
|
|
365
|
-
if (count != 1) {
|
|
366
|
-
throw jsi::JSError(runtime, "cipher.setAAD requires an argument record");
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (!arguments[0].isObject()) {
|
|
370
|
-
throw jsi::JSError(runtime,
|
|
371
|
-
"cipher.setAAD first argument needs to be a record");
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
auto args = arguments[0].asObject(runtime);
|
|
375
|
-
|
|
376
|
-
if (!args.hasProperty(runtime, "data") ||
|
|
377
|
-
!args.getProperty(runtime, "data").isObject() ||
|
|
378
|
-
!args.getProperty(runtime, "data")
|
|
379
|
-
.asObject(runtime)
|
|
380
|
-
.isArrayBuffer(runtime)) {
|
|
381
|
-
throw jsi::JSError(runtime, "data is missing in arguments record");
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
auto dataArrayBuffer = args.getProperty(runtime, "data")
|
|
385
|
-
.asObject(runtime)
|
|
386
|
-
.getArrayBuffer(runtime);
|
|
387
|
-
|
|
388
|
-
int plaintext_len = -1;
|
|
389
|
-
if (args.hasProperty(runtime, "plaintextLength") &&
|
|
390
|
-
!args.getProperty(runtime, "plaintextLength").isNull() &&
|
|
391
|
-
!args.getProperty(runtime, "plaintextLength").isUndefined()) {
|
|
392
|
-
if (args.getProperty(runtime, "plaintextLength").isNumber()) {
|
|
393
|
-
plaintext_len =
|
|
394
|
-
(int)args.getProperty(runtime, "plaintextLength").asNumber();
|
|
395
|
-
} else {
|
|
396
|
-
throw jsi::JSError(runtime,
|
|
397
|
-
"plaintextLength property needs to be a number");
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const unsigned char *data = dataArrayBuffer.data(runtime);
|
|
402
|
-
auto len = dataArrayBuffer.length(runtime);
|
|
403
|
-
|
|
404
|
-
if (!ctx_ || !IsAuthenticatedMode()) return false;
|
|
405
|
-
|
|
406
|
-
int outlen;
|
|
407
|
-
const int mode = EVP_CIPHER_CTX_mode(ctx_);
|
|
408
|
-
|
|
409
|
-
// When in CCM mode, we need to set the authentication tag and the plaintext
|
|
410
|
-
// length in advance.
|
|
411
|
-
if (mode == EVP_CIPH_CCM_MODE) {
|
|
412
|
-
if (plaintext_len < 0) {
|
|
413
|
-
throw jsi::JSError(runtime,
|
|
414
|
-
"plaintextLength required for CCM mode with AAD");
|
|
415
|
-
return false;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if (!CheckCCMMessageLength(plaintext_len)) return false;
|
|
419
|
-
|
|
420
|
-
if (!isCipher_) {
|
|
421
|
-
if (!MaybePassAuthTagToOpenSSL()) return false;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Specify the plaintext length.
|
|
425
|
-
if (!EVP_CipherUpdate(ctx_, nullptr, &outlen, nullptr, plaintext_len))
|
|
426
|
-
return false;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
return 1 == EVP_CipherUpdate(ctx_, nullptr, &outlen, data, len);
|
|
430
|
-
}));
|
|
431
|
-
|
|
432
|
-
// setAutoPadding
|
|
433
|
-
this->fields.push_back(HOST_LAMBDA("setAutoPadding", {
|
|
434
|
-
if (count != 1) {
|
|
435
|
-
throw jsi::JSError(
|
|
436
|
-
runtime, "cipher.setAutoPadding requires at least one argument");
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (!arguments[0].isBool()) {
|
|
440
|
-
throw jsi::JSError(
|
|
441
|
-
runtime, "cipher.setAutoPadding first argument must be a boolean");
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
if (ctx_ == nullptr) {
|
|
445
|
-
return false;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
return EVP_CIPHER_CTX_set_padding(ctx_, arguments[0].getBool());
|
|
449
|
-
}));
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
// getAuthTag
|
|
453
|
-
this->fields.push_back(buildPair(
|
|
454
|
-
"getAuthTag", JSIF([this]) {
|
|
455
|
-
if (ctx_) {
|
|
456
|
-
throw jsi::JSError(runtime, "Cannot getAuthTag while encryption in progress.");
|
|
457
|
-
}
|
|
458
|
-
if (!isCipher_) {
|
|
459
|
-
throw jsi::JSError(runtime, "Cannot getAuthTag in decryption mode.");
|
|
460
|
-
}
|
|
461
|
-
if (auth_tag_len_ == kNoAuthTagLength) {
|
|
462
|
-
throw jsi::JSError(runtime, "Authentication tag not set or not available. Make sure to call 'final' before getting the authentication tag.");
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
MGLTypedArray<MGLTypedArrayKind::Uint8Array> authTagArray(runtime, auth_tag_len_);
|
|
466
|
-
auto buffer = authTagArray.getBuffer(runtime);
|
|
467
|
-
auto dataPtr = buffer.data(runtime);
|
|
468
|
-
std::memcpy(dataPtr, auth_tag_, auth_tag_len_);
|
|
469
|
-
|
|
470
|
-
return authTagArray;
|
|
471
|
-
}));
|
|
472
|
-
|
|
473
|
-
// setAuthTag
|
|
474
|
-
this->fields.push_back(buildPair(
|
|
475
|
-
"setAuthTag", JSIF([=]) {
|
|
476
|
-
if (count != 1 || !arguments[0].isObject() ||
|
|
477
|
-
!arguments[0].asObject(runtime).isArrayBuffer(runtime)) {
|
|
478
|
-
throw jsi::JSError(
|
|
479
|
-
runtime,
|
|
480
|
-
"cipher.setAuthTag requires an ArrayBuffer tag argument");
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
if (!ctx_ || !IsAuthenticatedMode() || isCipher_ ||
|
|
484
|
-
auth_tag_state_ != kAuthTagUnknown) {
|
|
485
|
-
return false;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
auto authTagArrayBuffer =
|
|
489
|
-
arguments[0].asObject(runtime).getArrayBuffer(runtime);
|
|
490
|
-
if (!CheckSizeInt32(runtime, authTagArrayBuffer)) {
|
|
491
|
-
throw jsi::JSError(
|
|
492
|
-
runtime,
|
|
493
|
-
"cipher.setAuthTag requires an ArrayBuffer tag argument");
|
|
494
|
-
}
|
|
495
|
-
// const unsigned char *data = authTagArrayBuffer.data(runtime);
|
|
496
|
-
unsigned int tag_len =
|
|
497
|
-
static_cast<unsigned int>(authTagArrayBuffer.length(runtime));
|
|
498
|
-
|
|
499
|
-
// ArrayBufferOrViewContents<char> auth_tag(args[0]);
|
|
500
|
-
// TODO(osp) implement this check
|
|
501
|
-
// if (UNLIKELY(!auth_tag.CheckSizeInt32()))
|
|
502
|
-
// return THROW_ERR_OUT_OF_RANGE(env, "buffer is too big");
|
|
503
|
-
|
|
504
|
-
// unsigned int tag_len = auth_tag.size();
|
|
505
|
-
|
|
506
|
-
const int mode = EVP_CIPHER_CTX_mode(ctx_);
|
|
507
|
-
bool is_valid;
|
|
508
|
-
if (mode == EVP_CIPH_GCM_MODE) {
|
|
509
|
-
// Restrict GCM tag lengths according to NIST 800-38d, page 9.
|
|
510
|
-
is_valid =
|
|
511
|
-
(auth_tag_len_ == kNoAuthTagLength || auth_tag_len_ == tag_len) &&
|
|
512
|
-
IsValidGCMTagLength(tag_len);
|
|
513
|
-
} else {
|
|
514
|
-
// At this point, the tag length is already known and must match the
|
|
515
|
-
// length of the given authentication tag.
|
|
516
|
-
// TODO(osp) add CHECK here
|
|
517
|
-
IsSupportedAuthenticatedMode(ctx_);
|
|
518
|
-
// CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength);
|
|
519
|
-
is_valid = auth_tag_len_ == tag_len;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if (!is_valid) {
|
|
523
|
-
throw jsi::JSError(runtime, "Invalid authentication tag length");
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
auth_tag_len_ = tag_len;
|
|
527
|
-
auth_tag_state_ = kAuthTagKnown;
|
|
528
|
-
// CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
|
|
529
|
-
|
|
530
|
-
memset(auth_tag_, 0, sizeof(auth_tag_));
|
|
531
|
-
CopyTo(runtime, &authTagArrayBuffer, auth_tag_, auth_tag_len_);
|
|
532
|
-
|
|
533
|
-
return true;
|
|
534
|
-
}));
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
bool MGLCipherHostObject::MaybePassAuthTagToOpenSSL() {
|
|
538
|
-
if (auth_tag_state_ == kAuthTagKnown) {
|
|
539
|
-
if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_TAG, auth_tag_len_,
|
|
540
|
-
reinterpret_cast<unsigned char *>(auth_tag_))) {
|
|
541
|
-
return false;
|
|
542
|
-
}
|
|
543
|
-
auth_tag_state_ = kAuthTagPassedToOpenSSL;
|
|
544
|
-
}
|
|
545
|
-
return true;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
bool MGLCipherHostObject::IsAuthenticatedMode() const {
|
|
549
|
-
// Check if this cipher operates in an AEAD mode that we support.
|
|
550
|
-
// CHECK(ctx_);
|
|
551
|
-
return IsSupportedAuthenticatedMode(ctx_);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
bool MGLCipherHostObject::InitAuthenticated(const char *cipher_type, int iv_len,
|
|
555
|
-
unsigned int auth_tag_len) {
|
|
556
|
-
// TODO(osp) implement this check
|
|
557
|
-
// CHECK(IsAuthenticatedMode());
|
|
558
|
-
// TODO(osp) what is this? some sort of node error?
|
|
559
|
-
// MarkPopErrorOnReturn mark_pop_error_on_return;
|
|
560
|
-
|
|
561
|
-
if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr)) {
|
|
562
|
-
// throw std::runtime_error("Invalid Cipher IV");
|
|
563
|
-
// THROW_ERR_CRYPTO_INVALID_IV(env());
|
|
564
|
-
return false;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
const int mode = EVP_CIPHER_CTX_mode(ctx_);
|
|
568
|
-
if (mode == EVP_CIPH_GCM_MODE) {
|
|
569
|
-
if (auth_tag_len != kNoAuthTagLength) {
|
|
570
|
-
if (!IsValidGCMTagLength(auth_tag_len)) {
|
|
571
|
-
// throw std::runtime_error("Invalid Cipher authentication tag
|
|
572
|
-
// length!");
|
|
573
|
-
// THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
|
|
574
|
-
// env(),
|
|
575
|
-
// "Invalid authentication tag length: %u",
|
|
576
|
-
// auth_tag_len);
|
|
577
|
-
return false;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
// Remember the given authentication tag length for later.
|
|
581
|
-
auth_tag_len_ = auth_tag_len;
|
|
582
|
-
}
|
|
583
|
-
} else {
|
|
584
|
-
if (auth_tag_len == kNoAuthTagLength) {
|
|
585
|
-
// We treat ChaCha20-Poly1305 specially. Like GCM, the authentication tag
|
|
586
|
-
// length defaults to 16 bytes when encrypting. Unlike GCM, the
|
|
587
|
-
// authentication tag length also defaults to 16 bytes when decrypting,
|
|
588
|
-
// whereas GCM would accept any valid authentication tag length.
|
|
589
|
-
if (EVP_CIPHER_CTX_nid(ctx_) == NID_chacha20_poly1305) {
|
|
590
|
-
auth_tag_len = 16;
|
|
591
|
-
} else {
|
|
592
|
-
// throw std::runtime_error("authTagLength required for cipher
|
|
593
|
-
// type");
|
|
594
|
-
// THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
|
|
595
|
-
// env(), "authTagLength required for %s",
|
|
596
|
-
// cipher_type);
|
|
597
|
-
return false;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// TODO(tniessen) Support CCM decryption in FIPS mode
|
|
602
|
-
|
|
603
|
-
#if OPENSSL_VERSION_MAJOR >= 3
|
|
604
|
-
if (mode == EVP_CIPH_CCM_MODE && !isCipher_ &&
|
|
605
|
-
EVP_default_properties_is_fips_enabled(nullptr)) {
|
|
606
|
-
#else
|
|
607
|
-
if (mode == EVP_CIPH_CCM_MODE && !isCipher_ && FIPS_mode()) {
|
|
608
|
-
#endif
|
|
609
|
-
// throw std::runtime_error("CCM encryption not supported in FIPS
|
|
610
|
-
// mode");
|
|
611
|
-
// THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(env(),
|
|
612
|
-
// "CCM encryption not
|
|
613
|
-
// supported in FIPS
|
|
614
|
-
// mode");
|
|
615
|
-
return false;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
// Tell OpenSSL about the desired length.
|
|
619
|
-
if (!EVP_CIPHER_CTX_ctrl(ctx_, EVP_CTRL_AEAD_SET_TAG, auth_tag_len,
|
|
620
|
-
nullptr)) {
|
|
621
|
-
// throw std::runtime_error("Invalid authentication tag length");
|
|
622
|
-
// THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
|
|
623
|
-
// env(), "Invalid authentication tag length: %u",
|
|
624
|
-
// auth_tag_len);
|
|
625
|
-
return false;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
// Remember the given authentication tag length for later.
|
|
629
|
-
auth_tag_len_ = auth_tag_len;
|
|
630
|
-
|
|
631
|
-
if (mode == EVP_CIPH_CCM_MODE) {
|
|
632
|
-
// Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes.
|
|
633
|
-
// TODO(osp) implement this check
|
|
634
|
-
// CHECK(iv_len >= 7 && iv_len <= 13);
|
|
635
|
-
max_message_size_ = INT_MAX;
|
|
636
|
-
if (iv_len == 12) max_message_size_ = 16777215;
|
|
637
|
-
if (iv_len == 13) max_message_size_ = 65535;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
return true;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
bool MGLCipherHostObject::CheckCCMMessageLength(int message_len) {
|
|
645
|
-
// TODO(osp) Implement this check
|
|
646
|
-
// CHECK(EVP_CIPHER_CTX_mode(ctx_) == EVP_CIPH_CCM_MODE);
|
|
647
|
-
|
|
648
|
-
if (message_len > max_message_size_) {
|
|
649
|
-
// THROW_ERR_CRYPTO_INVALID_MESSAGELEN(env());
|
|
650
|
-
return false;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
return true;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
MGLCipherHostObject::~MGLCipherHostObject() {
|
|
657
|
-
if (this->ctx_ != nullptr) {
|
|
658
|
-
EVP_CIPHER_CTX_free(this->ctx_);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// TODO(osp) go over destructor
|
|
662
|
-
}
|
|
663
|
-
} // namespace margelo
|