#ifdef __WASM__
#ifdef SQLITE_USER_AUTHENTICATION
#undef SQLITE_USER_AUTHENTICATION
#endif
#define SQLITE_USER_AUTHENTICATION 0
#ifdef SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT
#undef SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT
#endif
#define SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT 1
#endif
#ifndef SQLITE_DEBUG
#if defined(SQLITE_ENABLE_DEBUG) && (SQLITE_ENABLE_DEBUG == 1)
#define SQLITE_DEBUG 1
#endif
#endif
#define SQLITE_EXTRA_INIT sqlite3mc_initialize
#define SQLITE_EXTRA_SHUTDOWN sqlite3mc_shutdown
int sqlite3mc_initialize(const char* arg);
void sqlite3mc_shutdown(void);
#if !SQLITE_USER_AUTHENTICATION
#ifndef SQLITE_USER_AUTHENTICATION
#define SQLITE_USER_AUTHENTICATION 1
#else
#undef SQLITE_USER_AUTHENTICATION
#endif
#endif
#if defined(_WIN32) || defined(WIN32)
#ifndef SQLITE3MC_USE_RAND_S
#define SQLITE3MC_USE_RAND_S 1
#endif
#if SQLITE3MC_USE_RAND_S
#if !defined(_CRT_RAND_S)
#define _CRT_RAND_S
#endif
#else
#define __STDC_WANT_LIB_EXT1__ 1
#endif
#ifndef SQLITE_API
#define SQLITE_API
#endif
#if defined (_MSC_VER)
#if defined _M_ARM
#define _ARM_USE_NEW_NEON_INTRINSICS
#endif
#endif
#include <windows.h>
extern SQLITE_API void sqlite3_win32_write_debug(const char*, int);
extern SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
extern SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char*);
extern SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char*, int);
extern SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char*);
extern SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char*, int);
extern SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
#endif
#include "sqlite3.c"
#include "sqlite3mc_config.h"
#include "sqlite3mc.h"
SQLITE_API const char*
sqlite3mc_version()
{
static const char* version = SQLITE3MC_VERSION_STRING;
return version;
}
SQLITE_PRIVATE void
sqlite3mcVersion(sqlite3_context* context, int argc, sqlite3_value** argv)
{
assert(argc == 0);
sqlite3_result_text(context, sqlite3mc_version(), -1, 0);
}
#ifndef SQLITE3MC_SECURE_MEMORY
#define SQLITE3MC_SECURE_MEMORY 0
#endif
#if SQLITE3MC_SECURE_MEMORY
#define SECURE_MEMORY_NONE 0
#define SECURE_MEMORY_FILL 1
#define SECURE_MEMORY_LOCK 2
SQLITE_PRIVATE void sqlite3mcSetMemorySecurity(int value);
SQLITE_PRIVATE int sqlite3mcGetMemorySecurity();
#ifndef SQLITE3MC_USE_RANDOM_FILL_MEMORY
#define SQLITE3MC_USE_RANDOM_FILL_MEMORY 0
#endif
#ifdef SQLITE3MC_ENABLE_MEMLOCK
#undef SQLITE3MC_ENABLE_MEMLOCK
#endif
#define SQLITE3MC_ENABLE_MEMLOCK 0
#endif
#include "md5.c"
#include "sha1.c"
#include "sha2.c"
#if HAVE_CIPHER_CHACHA20 || HAVE_CIPHER_SQLCIPHER
#include "fastpbkdf2.c"
void chacha20_xor(void* data, size_t n, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter);
void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], uint8_t tag[16]);
int poly1305_tagcmp(const uint8_t tag1[16], const uint8_t tag2[16]);
void chacha20_rng(void* out, size_t n);
#include "chacha20poly1305.c"
#endif
#ifdef SQLITE_USER_AUTHENTICATION
#include "userauth.c"
#endif
static int
mcRegisterCodecExtensions(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#if HAVE_CIPHER_AES_128_CBC || HAVE_CIPHER_AES_256_CBC || HAVE_CIPHER_SQLCIPHER
#include "rijndael.c"
#endif
#include "codec_algos.c"
#include "cipher_wxaes128.c"
#include "cipher_wxaes256.c"
#include "cipher_chacha20.c"
#include "cipher_sqlcipher.c"
#include "cipher_sds_rc4.c"
#include "cipher_ascon.c"
#include "cipher_common.c"
#include "cipher_config.c"
#include "codecext.c"
#include "memory_secure.c"
#ifdef SQLITE_ENABLE_EXTFUNC
int RegisterExtensionFunctions(sqlite3* db);
#include "extensionfunctions.c"
#endif
#ifdef SQLITE_ENABLE_CSV
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_csv_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "csv.c"
#endif
#ifdef SQLITE_ENABLE_VSV
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_vsv_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "vsv.c"
#endif
#ifdef SQLITE_ENABLE_SHA3
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_shathree_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "shathree.c"
#endif
#ifdef SQLITE_ENABLE_CARRAY
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_carray_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "carray.c"
#endif
#ifdef SQLITE_ENABLE_FILEIO
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_fileio_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
# include <unistd.h>
# include <dirent.h>
# if defined(__MINGW32__)
# define DIRENT dirent
# ifndef S_ISLNK
# define S_ISLNK(mode) (0)
# endif
# endif
#endif
#include "test_windirent.c"
#include "fileio.c"
#endif
#ifdef SQLITE_ENABLE_SERIES
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_series_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "series.c"
#endif
#ifdef SQLITE_ENABLE_UUID
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_uuid_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "uuid.c"
#endif
#ifdef SQLITE_ENABLE_REGEXP
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_regexp_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi);
#include "regexp.c"
#endif
#if defined(SQLITE_ENABLE_COMPRESS) || defined(SQLITE_ENABLE_SQLAR) || defined(SQLITE_ENABLE_ZIPFILE)
#if SQLITE3MC_USE_MINIZ != 0
#include "miniz.c"
#endif
#endif
#ifdef SQLITE_ENABLE_COMPRESS
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_compress_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
#include "compress.c"
#endif
#ifdef SQLITE_ENABLE_SQLAR
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_sqlar_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
#include "sqlar.c"
#endif
#ifdef SQLITE_ENABLE_ZIPFILE
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_zipfile_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
#include "zipfile.c"
#endif
#include "sqlite3mc_vfs.c"
static int
mcRegisterCodecExtensions(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi)
{
int rc = SQLITE_OK;
CodecParameter* codecParameterTable = NULL;
if (sqlite3FindFunction(db, "sqlite3mc_config_table", 1, SQLITE_UTF8, 0) != NULL)
{
return rc;
}
codecParameterTable = sqlite3mcCloneCodecParameterTable();
rc = (codecParameterTable != NULL) ? SQLITE_OK : SQLITE_NOMEM;
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function_v2(db, "sqlite3mc_config_table", 0, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
codecParameterTable, sqlite3mcConfigTable, 0, 0, (void(*)(void*)) sqlite3mcFreeCodecParameterTable);
}
rc = (codecParameterTable != NULL) ? SQLITE_OK : SQLITE_NOMEM;
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "sqlite3mc_config", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
codecParameterTable, sqlite3mcConfigParams, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "sqlite3mc_config", 2, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
codecParameterTable, sqlite3mcConfigParams, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "sqlite3mc_config", 3, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
codecParameterTable, sqlite3mcConfigParams, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "sqlite3mc_codec_data", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
NULL, sqlite3mcCodecDataSql, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "sqlite3mc_codec_data", 2, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
NULL, sqlite3mcCodecDataSql, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "sqlite3mc_version", 0, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
NULL, sqlite3mcVersion, 0, 0);
}
return rc;
}
#ifdef SQLITE_ENABLE_EXTFUNC
static int
sqlite3_extfunc_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi)
{
return RegisterExtensionFunctions(db);
}
#endif
static int
mcCheckValidName(char* name)
{
size_t nl;
if (!name)
return SQLITE_ERROR;
nl = strlen(name);
if (nl < 1 || nl >= CIPHER_NAME_MAXLEN)
return SQLITE_ERROR;
CipherName* cipherNameTable = &globalCipherNameTable[0];
for (; cipherNameTable->m_name[0] != 0; ++cipherNameTable)
{
if (sqlite3_stricmp(name, cipherNameTable->m_name) == 0) break;
}
if (cipherNameTable->m_name[0] != 0)
return SQLITE_ERROR;
if (sqlite3Isalpha(name[0]))
{
size_t j;
for (j = 1; j < nl && (name[j] == '_' || sqlite3Isalnum(name[j])); ++j) {}
if (j == nl)
return SQLITE_OK;
}
return SQLITE_ERROR;
}
SQLITE_PRIVATE int
sqlite3mcGetGlobalCipherCount()
{
int cipherCount = 0;
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MAIN));
cipherCount = globalCipherCount;
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MAIN));
return cipherCount;
}
static int
sqlite3mcRegisterCipher(const CipherDescriptor* desc, const CipherParams* params, int makeDefault)
{
int rc;
int np;
CipherParams* cipherParams;
if (!desc || !params)
return SQLITE_ERROR;
if (!desc->m_name ||
!desc->m_allocateCipher ||
!desc->m_freeCipher ||
!desc->m_cloneCipher ||
!desc->m_getLegacy ||
!desc->m_getPageSize ||
!desc->m_getReserved ||
!desc->m_getSalt ||
!desc->m_generateKey ||
!desc->m_encryptPage ||
!desc->m_decryptPage)
return SQLITE_ERROR;
if (mcCheckValidName(desc->m_name) != SQLITE_OK)
return SQLITE_ERROR;
for (np = 0; np < CIPHER_PARAMS_COUNT_MAX; ++np)
{
CipherParams entry = params[np];
if (entry.m_name == 0 || entry.m_name[0] == 0)
break;
if (mcCheckValidName(entry.m_name) != SQLITE_OK)
return SQLITE_ERROR;
if (!(entry.m_minValue >= 0 && entry.m_maxValue >= 0 && entry.m_minValue <= entry.m_maxValue &&
entry.m_value >= entry.m_minValue && entry.m_value <= entry.m_maxValue &&
entry.m_default >= entry.m_minValue && entry.m_default <= entry.m_maxValue))
return SQLITE_ERROR;
}
if (np >= CIPHER_PARAMS_COUNT_MAX || params[np].m_name == 0)
return SQLITE_ERROR;
cipherParams = (CipherParams*) sqlite3_malloc((np+1) * sizeof(CipherParams));
if (!cipherParams)
return SQLITE_NOMEM;
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MAIN));
if (globalCipherCount < CODEC_COUNT_MAX)
{
int n;
char* cipherName;
++globalCipherCount;
cipherName = globalCipherNameTable[globalCipherCount].m_name;
strcpy(cipherName, desc->m_name);
globalCodecDescriptorTable[globalCipherCount - 1] = *desc;
globalCodecDescriptorTable[globalCipherCount - 1].m_name = cipherName;
globalCodecParameterTable[globalCipherCount].m_name = cipherName;
globalCodecParameterTable[globalCipherCount].m_id = globalCipherCount;
globalCodecParameterTable[globalCipherCount].m_params = cipherParams;
for (n = 0; n < np; ++n)
{
cipherParams[n] = params[n];
cipherParams[n].m_name = (char*) sqlite3_malloc((int) strlen(params[n].m_name) + 1);
strcpy(cipherParams[n].m_name, params[n].m_name);
}
cipherParams[n] = params[n];
cipherParams[n].m_name = globalSentinelName;
if (makeDefault)
{
CipherParams* param = globalCodecParameterTable[0].m_params;
for (; param->m_name[0] != 0; ++param)
{
if (sqlite3_stricmp("cipher", param->m_name) == 0) break;
}
if (param->m_name[0] != 0)
{
param->m_value = param->m_default = globalCipherCount;
}
}
rc = SQLITE_OK;
}
else
{
rc = SQLITE_NOMEM;
}
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MAIN));
return rc;
}
SQLITE_API int
sqlite3mc_register_cipher(const CipherDescriptor* desc, const CipherParams* params, int makeDefault)
{
int rc;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if (rc) return rc;
#endif
return sqlite3mcRegisterCipher(desc, params, makeDefault);
}
SQLITE_PRIVATE int
sqlite3mcInitCipherTables()
{
size_t n;
strcpy(globalCipherNameTable[0].m_name, "global");
for (n = 1; n < CODEC_COUNT_MAX + 2; ++n)
{
strcpy(globalCipherNameTable[n].m_name, "");
}
for (n = 0; n < CODEC_COUNT_MAX + 1; ++n)
{
globalCodecDescriptorTable[n] = mcSentinelDescriptor;
}
globalCodecParameterTable[0] = globalCommonParams;
for (n = 1; n < CODEC_COUNT_MAX + 2; ++n)
{
globalCodecParameterTable[n] = globalSentinelParams;
}
return SQLITE_OK;
}
SQLITE_PRIVATE void
sqlite3mcTermCipherTables()
{
size_t n;
for (n = CODEC_COUNT_MAX+1; n > 0; --n)
{
if (globalCodecParameterTable[n].m_name[0] != 0)
{
int k;
CipherParams* params = globalCodecParameterTable[n].m_params;
for (k = 0; params[k].m_name[0] != 0; ++k)
{
sqlite3_free(params[k].m_name);
}
sqlite3_free(globalCodecParameterTable[n].m_params);
}
}
}
int
sqlite3mc_initialize(const char* arg)
{
int rc = sqlite3mcInitCipherTables();
#if HAVE_CIPHER_AES_128_CBC
if (rc == SQLITE_OK)
{
rc = sqlite3mcRegisterCipher(&mcAES128Descriptor, mcAES128Params, (CODEC_TYPE_AES128 == CODEC_TYPE));
}
#endif
#if HAVE_CIPHER_AES_256_CBC
if (rc == SQLITE_OK)
{
rc = sqlite3mcRegisterCipher(&mcAES256Descriptor, mcAES256Params, (CODEC_TYPE_AES256 == CODEC_TYPE));
}
#endif
#if HAVE_CIPHER_CHACHA20
if (rc == SQLITE_OK)
{
rc = sqlite3mcRegisterCipher(&mcChaCha20Descriptor, mcChaCha20Params, (CODEC_TYPE_CHACHA20 == CODEC_TYPE));
}
#endif
#if HAVE_CIPHER_SQLCIPHER
if (rc == SQLITE_OK)
{
rc = sqlite3mcRegisterCipher(&mcSQLCipherDescriptor, mcSQLCipherParams, (CODEC_TYPE_SQLCIPHER == CODEC_TYPE));
}
#endif
#if HAVE_CIPHER_RC4
if (rc == SQLITE_OK)
{
rc = sqlite3mcRegisterCipher(&mcRC4Descriptor, mcRC4Params, (CODEC_TYPE_RC4 == CODEC_TYPE));
}
#endif
#if HAVE_CIPHER_ASCON128
if (rc == SQLITE_OK)
{
rc = sqlite3mcRegisterCipher(&mcAscon128Descriptor, mcAscon128Params, (CODEC_TYPE_ASCON128 == CODEC_TYPE));
}
#endif
if (rc == SQLITE_OK)
{
rc = sqlite3mc_vfs_create(NULL, 1);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) mcRegisterCodecExtensions);
}
#ifdef SQLITE_ENABLE_EXTFUNC
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_extfunc_init);
}
#endif
#ifdef SQLITE_ENABLE_CSV
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_csv_init);
}
#endif
#ifdef SQLITE_ENABLE_VSV
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_vsv_init);
}
#endif
#ifdef SQLITE_ENABLE_SHA3
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_shathree_init);
}
#endif
#ifdef SQLITE_ENABLE_CARRAY
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_carray_init);
}
#endif
#ifdef SQLITE_ENABLE_FILEIO
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_fileio_init);
}
#endif
#ifdef SQLITE_ENABLE_SERIES
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_series_init);
}
#endif
#ifdef SQLITE_ENABLE_UUID
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_uuid_init);
}
#endif
#ifdef SQLITE_ENABLE_REGEXP
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_regexp_init);
}
#endif
#ifdef SQLITE_ENABLE_COMPRESS
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_compress_init);
}
#endif
#ifdef SQLITE_ENABLE_SQLAR
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_sqlar_init);
}
#endif
#ifdef SQLITE_ENABLE_ZIPFILE
if (rc == SQLITE_OK)
{
rc = sqlite3_auto_extension((void(*)(void)) sqlite3_zipfile_init);
}
#endif
return rc;
}
void
sqlite3mc_shutdown(void)
{
sqlite3mc_vfs_shutdown();
sqlite3mcTermCipherTables();
}
#ifdef SQLITE_ENABLE_TCL
#include "tclsqlite.c"
#endif