react-native-mmkv-dz 2.5.1
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/LICENSE +219 -0
- package/MMKV/CHANGELOG.md +553 -0
- package/MMKV/Core/CMakeLists.txt +153 -0
- package/MMKV/Core/CodedInputData.cpp +228 -0
- package/MMKV/Core/CodedInputData.h +83 -0
- package/MMKV/Core/CodedInputDataCrypt.cpp +280 -0
- package/MMKV/Core/CodedInputDataCrypt.h +87 -0
- package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +62 -0
- package/MMKV/Core/CodedInputData_OSX.cpp +92 -0
- package/MMKV/Core/CodedOutputData.cpp +174 -0
- package/MMKV/Core/CodedOutputData.h +82 -0
- package/MMKV/Core/Core.xcodeproj/project.pbxproj +702 -0
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +67 -0
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +67 -0
- package/MMKV/Core/InterProcessLock.cpp +186 -0
- package/MMKV/Core/InterProcessLock.h +119 -0
- package/MMKV/Core/InterProcessLock_Android.cpp +103 -0
- package/MMKV/Core/InterProcessLock_Win32.cpp +108 -0
- package/MMKV/Core/KeyValueHolder.cpp +236 -0
- package/MMKV/Core/KeyValueHolder.h +118 -0
- package/MMKV/Core/MMBuffer.cpp +185 -0
- package/MMKV/Core/MMBuffer.h +107 -0
- package/MMKV/Core/MMKV.cpp +1418 -0
- package/MMKV/Core/MMKV.h +386 -0
- package/MMKV/Core/MMKVLog.cpp +127 -0
- package/MMKV/Core/MMKVLog.h +86 -0
- package/MMKV/Core/MMKVLog_Android.cpp +79 -0
- package/MMKV/Core/MMKVMetaInfo.hpp +81 -0
- package/MMKV/Core/MMKVPredef.h +245 -0
- package/MMKV/Core/MMKV_Android.cpp +259 -0
- package/MMKV/Core/MMKV_IO.cpp +1119 -0
- package/MMKV/Core/MMKV_IO.h +57 -0
- package/MMKV/Core/MMKV_OSX.cpp +347 -0
- package/MMKV/Core/MMKV_OSX.h +51 -0
- package/MMKV/Core/MemoryFile.cpp +537 -0
- package/MMKV/Core/MemoryFile.h +182 -0
- package/MMKV/Core/MemoryFile_Android.cpp +211 -0
- package/MMKV/Core/MemoryFile_Linux.cpp +120 -0
- package/MMKV/Core/MemoryFile_OSX.cpp +142 -0
- package/MMKV/Core/MemoryFile_Win32.cpp +536 -0
- package/MMKV/Core/MiniPBCoder.cpp +366 -0
- package/MMKV/Core/MiniPBCoder.h +129 -0
- package/MMKV/Core/MiniPBCoder_OSX.cpp +228 -0
- package/MMKV/Core/PBEncodeItem.hpp +86 -0
- package/MMKV/Core/PBUtility.cpp +61 -0
- package/MMKV/Core/PBUtility.h +153 -0
- package/MMKV/Core/ScopedLock.hpp +69 -0
- package/MMKV/Core/ThreadLock.cpp +68 -0
- package/MMKV/Core/ThreadLock.h +78 -0
- package/MMKV/Core/ThreadLock_Win32.cpp +89 -0
- package/MMKV/Core/aes/AESCrypt.cpp +256 -0
- package/MMKV/Core/aes/AESCrypt.h +107 -0
- package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +1231 -0
- package/MMKV/Core/aes/openssl/openssl_aes.h +118 -0
- package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +1044 -0
- package/MMKV/Core/aes/openssl/openssl_aes_locl.h +38 -0
- package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +308 -0
- package/MMKV/Core/aes/openssl/openssl_arm_arch.h +84 -0
- package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +97 -0
- package/MMKV/Core/aes/openssl/openssl_md32_common.h +254 -0
- package/MMKV/Core/aes/openssl/openssl_md5.h +49 -0
- package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +166 -0
- package/MMKV/Core/aes/openssl/openssl_md5_locl.h +75 -0
- package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +30 -0
- package/MMKV/Core/aes/openssl/openssl_opensslconf.h +271 -0
- package/MMKV/Core/core.vcxproj +186 -0
- package/MMKV/Core/core.vcxproj.filters +150 -0
- package/MMKV/Core/crc32/Checksum.h +67 -0
- package/MMKV/Core/crc32/crc32_armv8.cpp +132 -0
- package/MMKV/Core/crc32/zlib/crc32.cpp +55 -0
- package/MMKV/Core/crc32/zlib/crc32.h +48 -0
- package/MMKV/Core/crc32/zlib/zconf.h +380 -0
- package/MMKV/Core/crc32/zlib/zutil.h +25 -0
- package/MMKV/LICENSE.TXT +193 -0
- package/MMKV/README.md +288 -0
- package/README.md +221 -0
- package/android/CMakeLists.txt +71 -0
- package/android/build.gradle +371 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/cpp/MmkvHostObject.cpp +302 -0
- package/android/src/main/cpp/MmkvHostObject.h +26 -0
- package/android/src/main/cpp/cpp-adapter.cpp +65 -0
- package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +49 -0
- package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +26 -0
- package/cpp/TypedArray.cpp +341 -0
- package/cpp/TypedArray.h +175 -0
- package/ios/JSIUtils.h +50 -0
- package/ios/JSIUtils.mm +194 -0
- package/ios/Mmkv.xcodeproj/project.pbxproj +291 -0
- package/ios/MmkvHostObject.h +27 -0
- package/ios/MmkvHostObject.mm +299 -0
- package/ios/MmkvModule.h +5 -0
- package/ios/MmkvModule.mm +73 -0
- package/lib/commonjs/MMKV.js +146 -0
- package/lib/commonjs/MMKV.js.map +1 -0
- package/lib/commonjs/PlatformChecker.js +16 -0
- package/lib/commonjs/PlatformChecker.js.map +1 -0
- package/lib/commonjs/createMMKV.js +66 -0
- package/lib/commonjs/createMMKV.js.map +1 -0
- package/lib/commonjs/createMMKV.mock.js +40 -0
- package/lib/commonjs/createMMKV.mock.js.map +1 -0
- package/lib/commonjs/createMMKV.web.js +77 -0
- package/lib/commonjs/createMMKV.web.js.map +1 -0
- package/lib/commonjs/createTextEncoder.js +24 -0
- package/lib/commonjs/createTextEncoder.js.map +1 -0
- package/lib/commonjs/hooks.js +200 -0
- package/lib/commonjs/hooks.js.map +1 -0
- package/lib/commonjs/index.js +32 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/MMKV.js +134 -0
- package/lib/module/MMKV.js.map +1 -0
- package/lib/module/PlatformChecker.js +9 -0
- package/lib/module/PlatformChecker.js.map +1 -0
- package/lib/module/createMMKV.js +55 -0
- package/lib/module/createMMKV.js.map +1 -0
- package/lib/module/createMMKV.mock.js +31 -0
- package/lib/module/createMMKV.mock.js.map +1 -0
- package/lib/module/createMMKV.web.js +67 -0
- package/lib/module/createMMKV.web.js.map +1 -0
- package/lib/module/createTextEncoder.js +17 -0
- package/lib/module/createTextEncoder.js.map +1 -0
- package/lib/module/hooks.js +181 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/MMKV.d.ts +137 -0
- package/lib/typescript/PlatformChecker.d.ts +1 -0
- package/lib/typescript/createMMKV.d.ts +6 -0
- package/lib/typescript/createMMKV.mock.d.ts +2 -0
- package/lib/typescript/createMMKV.web.d.ts +2 -0
- package/lib/typescript/createTextEncoder.d.ts +1 -0
- package/lib/typescript/hooks.d.ts +81 -0
- package/lib/typescript/index.d.ts +2 -0
- package/package.json +168 -0
- package/react-native-mmkv.podspec +32 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tencent is pleased to support the open source community by making
|
|
3
|
+
* MMKV available.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (C) 2018 THL A29 Limited, a Tencent company.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the BSD 3-Clause License (the "License"); you may not use
|
|
9
|
+
* this file except in compliance with the License. You may obtain a copy of
|
|
10
|
+
* the License at
|
|
11
|
+
*
|
|
12
|
+
* https://opensource.org/licenses/BSD-3-Clause
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#ifndef MMKV_THREADLOCK_H
|
|
22
|
+
#define MMKV_THREADLOCK_H
|
|
23
|
+
#ifdef __cplusplus
|
|
24
|
+
|
|
25
|
+
#include "MMKVPredef.h"
|
|
26
|
+
|
|
27
|
+
#ifndef MMKV_WIN32
|
|
28
|
+
# include <pthread.h>
|
|
29
|
+
# define MMKV_USING_PTHREAD 1
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
#if MMKV_USING_PTHREAD
|
|
33
|
+
#else
|
|
34
|
+
# include <atomic>
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
namespace mmkv {
|
|
38
|
+
|
|
39
|
+
#if MMKV_USING_PTHREAD
|
|
40
|
+
# define ThreadOnceToken_t pthread_once_t
|
|
41
|
+
# define ThreadOnceUninitialized PTHREAD_ONCE_INIT
|
|
42
|
+
#else
|
|
43
|
+
enum ThreadOnceTokenEnum : int32_t { ThreadOnceUninitialized = 0, ThreadOnceInitializing, ThreadOnceInitialized };
|
|
44
|
+
using ThreadOnceToken_t = std::atomic<ThreadOnceTokenEnum>;
|
|
45
|
+
#endif
|
|
46
|
+
|
|
47
|
+
class ThreadLock {
|
|
48
|
+
private:
|
|
49
|
+
#if MMKV_USING_PTHREAD
|
|
50
|
+
pthread_mutex_t m_lock;
|
|
51
|
+
#else
|
|
52
|
+
CRITICAL_SECTION m_lock;
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
public:
|
|
56
|
+
ThreadLock();
|
|
57
|
+
~ThreadLock();
|
|
58
|
+
|
|
59
|
+
void initialize();
|
|
60
|
+
|
|
61
|
+
void lock();
|
|
62
|
+
void unlock();
|
|
63
|
+
|
|
64
|
+
static void ThreadOnce(ThreadOnceToken_t *onceToken, void (*callback)(void));
|
|
65
|
+
|
|
66
|
+
#ifdef MMKV_WIN32
|
|
67
|
+
static void Sleep(int ms);
|
|
68
|
+
#endif
|
|
69
|
+
|
|
70
|
+
// just forbid it for possibly misuse
|
|
71
|
+
explicit ThreadLock(const ThreadLock &other) = delete;
|
|
72
|
+
ThreadLock &operator=(const ThreadLock &other) = delete;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
} // namespace mmkv
|
|
76
|
+
|
|
77
|
+
#endif
|
|
78
|
+
#endif //MMKV_THREADLOCK_H
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tencent is pleased to support the open source community by making
|
|
3
|
+
* MMKV available.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the BSD 3-Clause License (the "License"); you may not use
|
|
9
|
+
* this file except in compliance with the License. You may obtain a copy of
|
|
10
|
+
* the License at
|
|
11
|
+
*
|
|
12
|
+
* https://opensource.org/licenses/BSD-3-Clause
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#include "ThreadLock.h"
|
|
22
|
+
|
|
23
|
+
#if !(MMKV_USING_PTHREAD)
|
|
24
|
+
|
|
25
|
+
# include "MMKVLog.h"
|
|
26
|
+
# include <atomic>
|
|
27
|
+
# include <cassert>
|
|
28
|
+
|
|
29
|
+
namespace mmkv {
|
|
30
|
+
|
|
31
|
+
ThreadLock::ThreadLock() : m_lock{0} {
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
ThreadLock::~ThreadLock() {
|
|
35
|
+
DeleteCriticalSection(&m_lock);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
void ThreadLock::initialize() {
|
|
39
|
+
// TODO: a better spin count?
|
|
40
|
+
if (!InitializeCriticalSectionAndSpinCount(&m_lock, 1024)) {
|
|
41
|
+
MMKVError("fail to init critical section:%d", GetLastError());
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void ThreadLock::lock() {
|
|
46
|
+
EnterCriticalSection(&m_lock);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
void ThreadLock::unlock() {
|
|
50
|
+
LeaveCriticalSection(&m_lock);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
void ThreadLock::ThreadOnce(ThreadOnceToken_t *onceToken, void (*callback)()) {
|
|
54
|
+
if (!onceToken || !callback) {
|
|
55
|
+
assert(onceToken);
|
|
56
|
+
assert(callback);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
while (true) {
|
|
60
|
+
auto expected = ThreadOnceUninitialized;
|
|
61
|
+
atomic_compare_exchange_weak(onceToken, &expected, ThreadOnceInitializing);
|
|
62
|
+
switch (expected) {
|
|
63
|
+
case ThreadOnceInitialized:
|
|
64
|
+
return;
|
|
65
|
+
case ThreadOnceUninitialized:
|
|
66
|
+
callback();
|
|
67
|
+
onceToken->store(ThreadOnceInitialized);
|
|
68
|
+
return;
|
|
69
|
+
case ThreadOnceInitializing: {
|
|
70
|
+
// another thread is initializing, let's wait for 1ms
|
|
71
|
+
ThreadLock::Sleep(1);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
default: {
|
|
75
|
+
MMKVError("should never happen:%d", expected);
|
|
76
|
+
assert(0);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void ThreadLock::Sleep(int ms) {
|
|
84
|
+
::Sleep(ms);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
} // namespace mmkv
|
|
88
|
+
|
|
89
|
+
#endif // MMKV_USING_PTHREAD
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tencent is pleased to support the open source community by making
|
|
3
|
+
* MMKV available.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (C) 2018 THL A29 Limited, a Tencent company.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the BSD 3-Clause License (the "License"); you may not use
|
|
9
|
+
* this file except in compliance with the License. You may obtain a copy of
|
|
10
|
+
* the License at
|
|
11
|
+
*
|
|
12
|
+
* https://opensource.org/licenses/BSD-3-Clause
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#include "AESCrypt.h"
|
|
22
|
+
#include "openssl/openssl_aes.h"
|
|
23
|
+
#include <cstdint>
|
|
24
|
+
#include <cstdlib>
|
|
25
|
+
#include <cstring>
|
|
26
|
+
#include <ctime>
|
|
27
|
+
|
|
28
|
+
#ifndef MMKV_DISABLE_CRYPT
|
|
29
|
+
|
|
30
|
+
using namespace openssl;
|
|
31
|
+
|
|
32
|
+
namespace mmkv {
|
|
33
|
+
|
|
34
|
+
AESCrypt::AESCrypt(const void *key, size_t keyLength, const void *iv, size_t ivLength) {
|
|
35
|
+
if (key && keyLength > 0) {
|
|
36
|
+
memcpy(m_key, key, (keyLength > AES_KEY_LEN) ? AES_KEY_LEN : keyLength);
|
|
37
|
+
|
|
38
|
+
resetIV(iv, ivLength);
|
|
39
|
+
|
|
40
|
+
m_aesKey = new AES_KEY;
|
|
41
|
+
memset(m_aesKey, 0, sizeof(AES_KEY));
|
|
42
|
+
int ret = AES_set_encrypt_key(m_key, AES_KEY_BITSET_LEN, m_aesKey);
|
|
43
|
+
MMKV_ASSERT(ret == 0);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
AESCrypt::AESCrypt(const AESCrypt &other, const AESCryptStatus &status) : m_isClone(true), m_number(status.m_number) {
|
|
48
|
+
//memcpy(m_key, other.m_key, sizeof(m_key));
|
|
49
|
+
memcpy(m_vector, status.m_vector, sizeof(m_vector));
|
|
50
|
+
m_aesKey = other.m_aesKey;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
AESCrypt::~AESCrypt() {
|
|
54
|
+
if (!m_isClone) {
|
|
55
|
+
delete m_aesKey;
|
|
56
|
+
delete m_aesRollbackKey;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void AESCrypt::resetIV(const void *iv, size_t ivLength) {
|
|
61
|
+
m_number = 0;
|
|
62
|
+
if (iv && ivLength > 0) {
|
|
63
|
+
memcpy(m_vector, iv, (ivLength > AES_KEY_LEN) ? AES_KEY_LEN : ivLength);
|
|
64
|
+
} else {
|
|
65
|
+
memcpy(m_vector, m_key, AES_KEY_LEN);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void AESCrypt::resetStatus(const AESCryptStatus &status) {
|
|
70
|
+
m_number = status.m_number;
|
|
71
|
+
memcpy(m_vector, status.m_vector, AES_KEY_LEN);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void AESCrypt::getKey(void *output) const {
|
|
75
|
+
if (output) {
|
|
76
|
+
memcpy(output, m_key, AES_KEY_LEN);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
void AESCrypt::encrypt(const void *input, void *output, size_t length) {
|
|
81
|
+
if (!input || !output || length == 0) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
AES_cfb128_encrypt((const uint8_t *) input, (uint8_t *) output, length, m_aesKey, m_vector, &m_number);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
void AESCrypt::decrypt(const void *input, void *output, size_t length) {
|
|
88
|
+
if (!input || !output || length == 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
AES_cfb128_decrypt((const uint8_t *) input, (uint8_t *) output, length, m_aesKey, m_vector, &m_number);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void AESCrypt::fillRandomIV(void *vector) {
|
|
95
|
+
if (!vector) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
srand((unsigned) time(nullptr));
|
|
99
|
+
int *ptr = (int *) vector;
|
|
100
|
+
for (uint32_t i = 0; i < AES_KEY_LEN / sizeof(int); i++) {
|
|
101
|
+
ptr[i] = rand();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static inline void
|
|
106
|
+
Rollback_cfb_decrypt(const uint8_t *input, const uint8_t *output, size_t len, AES_KEY *key, AESCryptStatus &status) {
|
|
107
|
+
auto ivec = status.m_vector;
|
|
108
|
+
auto n = status.m_number;
|
|
109
|
+
|
|
110
|
+
while (n && len) {
|
|
111
|
+
auto c = *(--output);
|
|
112
|
+
ivec[--n] = *(--input) ^ c;
|
|
113
|
+
len--;
|
|
114
|
+
}
|
|
115
|
+
if (n == 0 && (status.m_number != 0)) {
|
|
116
|
+
AES_decrypt(ivec, ivec, key);
|
|
117
|
+
}
|
|
118
|
+
while (len >= 16) {
|
|
119
|
+
len -= 16;
|
|
120
|
+
output -= 16;
|
|
121
|
+
input -= 16;
|
|
122
|
+
for (; n < 16; n += sizeof(size_t)) {
|
|
123
|
+
size_t t = *(size_t *) (output + n);
|
|
124
|
+
*(size_t *) (ivec + n) = *(size_t *) (input + n) ^ t;
|
|
125
|
+
}
|
|
126
|
+
n = 0;
|
|
127
|
+
AES_decrypt(ivec, ivec, key);
|
|
128
|
+
}
|
|
129
|
+
if (len) {
|
|
130
|
+
n = 16;
|
|
131
|
+
do {
|
|
132
|
+
auto c = *(--output);
|
|
133
|
+
ivec[--n] = *(--input) ^ c;
|
|
134
|
+
len--;
|
|
135
|
+
} while (len);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
status.m_number = n;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void AESCrypt::statusBeforeDecrypt(const void *input, const void *output, size_t length, AESCryptStatus &status) {
|
|
142
|
+
if (length == 0) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (!m_aesRollbackKey) {
|
|
146
|
+
m_aesRollbackKey = new AES_KEY;
|
|
147
|
+
memset(m_aesRollbackKey, 0, sizeof(AES_KEY));
|
|
148
|
+
int ret = AES_set_decrypt_key(m_key, AES_KEY_BITSET_LEN, m_aesRollbackKey);
|
|
149
|
+
MMKV_ASSERT(ret == 0);
|
|
150
|
+
}
|
|
151
|
+
getCurStatus(status);
|
|
152
|
+
Rollback_cfb_decrypt((const uint8_t *) input, (const uint8_t *) output, length, m_aesRollbackKey, status);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
void AESCrypt::getCurStatus(AESCryptStatus &status) {
|
|
156
|
+
status.m_number = static_cast<uint8_t>(m_number);
|
|
157
|
+
memcpy(status.m_vector, m_vector, sizeof(m_vector));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
AESCrypt AESCrypt::cloneWithStatus(const AESCryptStatus &status) const {
|
|
161
|
+
return AESCrypt(*this, status);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
} // namespace mmkv
|
|
165
|
+
|
|
166
|
+
# ifdef MMKV_DEBUG
|
|
167
|
+
|
|
168
|
+
# include "../MMKVLog.h"
|
|
169
|
+
# include "../MemoryFile.h"
|
|
170
|
+
|
|
171
|
+
namespace mmkv {
|
|
172
|
+
|
|
173
|
+
// check if AESCrypt is encrypt-decrypt full-duplex
|
|
174
|
+
void AESCrypt::testAESCrypt() {
|
|
175
|
+
const uint8_t plainText[] = "Hello, OpenSSL-mmkv::AESCrypt::testAESCrypt() with AES CFB 128.";
|
|
176
|
+
constexpr size_t textLength = sizeof(plainText) - 1;
|
|
177
|
+
|
|
178
|
+
const uint8_t key[] = "TheAESKey";
|
|
179
|
+
constexpr size_t keyLength = sizeof(key) - 1;
|
|
180
|
+
|
|
181
|
+
uint8_t iv[AES_KEY_LEN];
|
|
182
|
+
srand((unsigned) time(nullptr));
|
|
183
|
+
for (uint32_t i = 0; i < AES_KEY_LEN; i++) {
|
|
184
|
+
iv[i] = (uint8_t) rand();
|
|
185
|
+
}
|
|
186
|
+
AESCrypt crypt1(key, keyLength, iv, sizeof(iv));
|
|
187
|
+
AESCrypt crypt2(key, keyLength, iv, sizeof(iv));
|
|
188
|
+
|
|
189
|
+
auto encryptText = new uint8_t[DEFAULT_MMAP_SIZE];
|
|
190
|
+
auto decryptText = new uint8_t[DEFAULT_MMAP_SIZE];
|
|
191
|
+
memset(encryptText, 0, DEFAULT_MMAP_SIZE);
|
|
192
|
+
memset(decryptText, 0, DEFAULT_MMAP_SIZE);
|
|
193
|
+
|
|
194
|
+
/* in-place encryption & decryption
|
|
195
|
+
memcpy(encryptText, plainText, textLength);
|
|
196
|
+
crypt1.encrypt(encryptText, encryptText, textLength);
|
|
197
|
+
crypt2.decrypt(encryptText, encryptText, textLength);
|
|
198
|
+
return;
|
|
199
|
+
*/
|
|
200
|
+
AES_KEY decryptKey;
|
|
201
|
+
AES_set_decrypt_key(crypt1.m_key, AES_KEY_BITSET_LEN, &decryptKey);
|
|
202
|
+
|
|
203
|
+
size_t actualSize = 0;
|
|
204
|
+
bool flip = false;
|
|
205
|
+
for (const uint8_t *ptr = plainText; ptr < plainText + textLength;) {
|
|
206
|
+
auto tokenPtr = (const uint8_t *) strchr((const char *) ptr, ' ');
|
|
207
|
+
size_t size = 0;
|
|
208
|
+
if (!tokenPtr) {
|
|
209
|
+
size = static_cast<size_t>(plainText + textLength - ptr);
|
|
210
|
+
} else {
|
|
211
|
+
size = static_cast<size_t>(tokenPtr - ptr + 1);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
AESCrypt *decrypter;
|
|
215
|
+
uint32_t oldNum;
|
|
216
|
+
uint8_t oldVector[sizeof(crypt1.m_vector)];
|
|
217
|
+
|
|
218
|
+
flip = !flip;
|
|
219
|
+
if (flip) {
|
|
220
|
+
crypt1.encrypt(plainText + actualSize, encryptText + actualSize, size);
|
|
221
|
+
|
|
222
|
+
decrypter = &crypt2;
|
|
223
|
+
oldNum = decrypter->m_number;
|
|
224
|
+
memcpy(oldVector, decrypter->m_vector, sizeof(oldVector));
|
|
225
|
+
crypt2.decrypt(encryptText + actualSize, decryptText + actualSize, size);
|
|
226
|
+
} else {
|
|
227
|
+
crypt2.encrypt(plainText + actualSize, encryptText + actualSize, size);
|
|
228
|
+
|
|
229
|
+
decrypter = &crypt1;
|
|
230
|
+
oldNum = decrypter->m_number;
|
|
231
|
+
memcpy(oldVector, decrypter->m_vector, sizeof(oldVector));
|
|
232
|
+
crypt1.decrypt(encryptText + actualSize, decryptText + actualSize, size);
|
|
233
|
+
}
|
|
234
|
+
// that's why AESCrypt can be full-duplex
|
|
235
|
+
assert(crypt1.m_number == crypt2.m_number);
|
|
236
|
+
assert(0 == memcmp(crypt1.m_vector, crypt2.m_vector, sizeof(crypt1.m_vector)));
|
|
237
|
+
|
|
238
|
+
// how rollback works
|
|
239
|
+
AESCryptStatus status;
|
|
240
|
+
decrypter->statusBeforeDecrypt(encryptText + actualSize + size, decryptText + actualSize + size, size, status);
|
|
241
|
+
assert(oldNum == status.m_number);
|
|
242
|
+
assert(0 == memcmp(oldVector, status.m_vector, sizeof(oldVector)));
|
|
243
|
+
|
|
244
|
+
actualSize += size;
|
|
245
|
+
ptr += size;
|
|
246
|
+
}
|
|
247
|
+
MMKVInfo("AES CFB decode: %s", decryptText);
|
|
248
|
+
|
|
249
|
+
delete[] encryptText;
|
|
250
|
+
delete[] decryptText;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
} // namespace mmkv
|
|
254
|
+
|
|
255
|
+
# endif // MMKV_DEBUG
|
|
256
|
+
#endif // MMKV_DISABLE_CRYPT
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tencent is pleased to support the open source community by making
|
|
3
|
+
* MMKV available.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (C) 2018 THL A29 Limited, a Tencent company.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the BSD 3-Clause License (the "License"); you may not use
|
|
9
|
+
* this file except in compliance with the License. You may obtain a copy of
|
|
10
|
+
* the License at
|
|
11
|
+
*
|
|
12
|
+
* https://opensource.org/licenses/BSD-3-Clause
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#ifndef AES_CRYPT_H_
|
|
22
|
+
#define AES_CRYPT_H_
|
|
23
|
+
#ifdef __cplusplus
|
|
24
|
+
|
|
25
|
+
#include "MMKVPredef.h"
|
|
26
|
+
#include <cstddef>
|
|
27
|
+
|
|
28
|
+
#ifdef MMKV_DISABLE_CRYPT
|
|
29
|
+
|
|
30
|
+
namespace mmkv {
|
|
31
|
+
class AESCrypt;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#else
|
|
35
|
+
|
|
36
|
+
namespace openssl {
|
|
37
|
+
struct AES_KEY;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
namespace mmkv {
|
|
41
|
+
|
|
42
|
+
#pragma pack(push, 1)
|
|
43
|
+
|
|
44
|
+
struct AESCryptStatus {
|
|
45
|
+
uint8_t m_number;
|
|
46
|
+
uint8_t m_vector[AES_KEY_LEN];
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
#pragma pack(pop)
|
|
50
|
+
|
|
51
|
+
class CodedInputDataCrypt;
|
|
52
|
+
|
|
53
|
+
// a AES CFB-128 encrypt-decrypt full-duplex wrapper
|
|
54
|
+
class AESCrypt {
|
|
55
|
+
bool m_isClone = false;
|
|
56
|
+
uint32_t m_number = 0;
|
|
57
|
+
openssl::AES_KEY *m_aesKey = nullptr;
|
|
58
|
+
openssl::AES_KEY *m_aesRollbackKey = nullptr;
|
|
59
|
+
uint8_t m_key[AES_KEY_LEN] = {};
|
|
60
|
+
|
|
61
|
+
public:
|
|
62
|
+
uint8_t m_vector[AES_KEY_LEN] = {};
|
|
63
|
+
|
|
64
|
+
private:
|
|
65
|
+
// for cloneWithStatus()
|
|
66
|
+
AESCrypt(const AESCrypt &other, const AESCryptStatus &status);
|
|
67
|
+
|
|
68
|
+
public:
|
|
69
|
+
AESCrypt(const void *key, size_t keyLength, const void *iv = nullptr, size_t ivLength = 0);
|
|
70
|
+
AESCrypt(AESCrypt &&other) = default;
|
|
71
|
+
|
|
72
|
+
~AESCrypt();
|
|
73
|
+
|
|
74
|
+
void encrypt(const void *input, void *output, size_t length);
|
|
75
|
+
|
|
76
|
+
void decrypt(const void *input, void *output, size_t length);
|
|
77
|
+
|
|
78
|
+
void getCurStatus(AESCryptStatus &status);
|
|
79
|
+
void statusBeforeDecrypt(const void *input, const void *output, size_t length, AESCryptStatus &status);
|
|
80
|
+
|
|
81
|
+
AESCrypt cloneWithStatus(const AESCryptStatus &status) const;
|
|
82
|
+
|
|
83
|
+
void resetIV(const void *iv = nullptr, size_t ivLength = 0);
|
|
84
|
+
void resetStatus(const AESCryptStatus &status);
|
|
85
|
+
|
|
86
|
+
// output must have [AES_KEY_LEN] space
|
|
87
|
+
void getKey(void *output) const;
|
|
88
|
+
|
|
89
|
+
static void fillRandomIV(void *vector);
|
|
90
|
+
|
|
91
|
+
// just forbid it for possibly misuse
|
|
92
|
+
explicit AESCrypt(const AESCrypt &other) = delete;
|
|
93
|
+
AESCrypt &operator=(const AESCrypt &other) = delete;
|
|
94
|
+
|
|
95
|
+
friend CodedInputDataCrypt;
|
|
96
|
+
|
|
97
|
+
#ifdef MMKV_DEBUG
|
|
98
|
+
// check if AESCrypt is encrypt-decrypt full-duplex
|
|
99
|
+
static void testAESCrypt();
|
|
100
|
+
#endif
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
} // namespace mmkv
|
|
104
|
+
|
|
105
|
+
#endif // MMKV_DISABLE_CRYPT
|
|
106
|
+
#endif // __cplusplus
|
|
107
|
+
#endif /* AES_CRYPT_H_ */
|