8000 backport enhancements from v2beta (mlock & RAND_bytes) · PHPDOTSQL/sqlcipher@ed03f15 · GitHub
[go: up one dir, main page]

Skip to content

Commit ed03f15

Browse files
committed
backport enhancements from v2beta (mlock & RAND_bytes)
1 parent dea8ae9 commit ed03f15

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

src/crypto.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@
4141
#include "btreeInt.h"
4242
#include "crypto.h"
4343

44+
45+
#ifndef OMIT_MEMLOCK
46+
#if defined(__unix__) || defined(__APPLE__)
47+
#include <sys/mman.h>
48+
#elif defined(_WIN32)
49+
# include <windows.h>
50+
#endif
51+
#endif
52+
53+
4454
#ifdef CODEC_DEBUG
4555
#define CODEC_TRACE(X) {printf X;fflush(stdout);}
4656
#else
@@ -102,11 +112,40 @@ static void cipher_hex2bin(const char *hex, int sz, unsigned char *out){
102112
*/
103113
static void codec_free(void *ptr, int sz) {
104114
if(ptr) {
105-
if(sz > 0) memset(ptr, 0, sz); // FIXME - require buffer size
115+
if(sz > 0) {
116+
memset(ptr, 0, sz);
117+
#ifndef OMIT_MEMLOCK
118+
#if defined(__unix__) || defined(__APPLE__)
119+
munlock(ptr, sz);
120+
#elif defined(_WIN32)
121+
VirtualUnlock(ptr, sz);
122+
#endif
123+
#endif
124+
}
106125
sqlite3_free(ptr);
107126
}
108127
}
109128

129+
/**
130+
* allocate memory. Uses sqlite's internall malloc wrapper so memory can be
131+
* reference counted and leak detection works. Unless compiled with OMIT_MEMLOCK
132+
* attempts to lock the memory pages so sensitive information won't be swapped
133+
*/
134+
void* codec_malloc(int sz) {
135+
void *ptr = sqlite3Malloc(sz);
136+
#ifndef OMIT_MEMLOCK
137+
if(ptr) {
138+
#if defined(__unix__) || defined(__APPLE__)
139+
mlock(ptr, sz);
140+
#elif defined(_WIN32)
141+
VirtualLock(ptr, sz);
142+
#endif
143+
}
144+
#endif
145+
return ptr;
146+
}
147+
148+
110149
/**
111150
* Set the raw password / key data for a cipher context
112151
*
@@ -118,7 +157,7 @@ static int cipher_ctx_set_pass(cipher_ctx *ctx, const void *zKey, int nKey) {
118157
codec_free(ctx->pass, ctx->pass_sz);
119158
ctx->pass_sz = nKey;
120159
if(zKey && nKey) {
121-
ctx->pass = sqlite3Malloc(nKey);
160+
ctx->pass = codec_malloc(nKey);
122161
if(ctx->pass == NULL) return SQLITE_NOMEM;
123162
memcpy(ctx->pass, zKey, nKey);
124163
return SQLITE_OK;
@@ -135,11 +174,11 @@ static int cipher_ctx_set_pass(cipher_ctx *ctx, const void *zKey, int nKey) {
135174
*/
136175
static int cipher_ctx_init(cipher_ctx **iCtx) {
137176
cipher_ctx *ctx;
138-
*iCtx = sqlite3Malloc(sizeof(cipher_ctx));
177+
*iCtx = codec_malloc(sizeof(cipher_ctx));
139178
ctx = *iCtx;
140179
if(ctx == NULL) return SQLITE_NOMEM;
141180
memset(ctx, 0, sizeof(cipher_ctx));
142-
ctx->key = sqlite3Malloc(EVP_MAX_KEY_LENGTH);
181+
ctx->key = codec_malloc(EVP_MAX_KEY_LENGTH);
143182
if(ctx->key == NULL) return SQLITE_NOMEM;
144183
return SQLITE_OK;
145184
}
@@ -171,7 +210,7 @@ static int cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
171210

172211
target->key = key; //restore pointer to previously allocated key data
173212
memcpy(target->key, source->key, EVP_MAX_KEY_LENGTH);
174-
target->pass = sqlite3Malloc(source->pass_sz);
213+
target->pass = codec_malloc(source->pass_sz);
175214
if(target->pass == NULL) return SQLITE_NOMEM;
176215
memcpy(target->pass, source->pass, source->pass_sz);
177216
return SQLITE_OK;
@@ -270,7 +309,7 @@ static int codec_cipher(cipher_ctx *ctx, Pgno pgno, int mode, int size, unsigned
270309
size = size - ctx->iv_sz; /* adjust size to useable size and memset reserve at end of page */
271310
iv = out + size;
272311
if(mode == CIPHER_ENCRYPT) {
273-
RAND_pseudo_bytes(iv, ctx->iv_sz);
312+
RAND_bytes(iv, ctx->iv_sz);
274313
} else {
275314
memcpy(iv, in+size, ctx->iv_sz);
276315
}
@@ -425,7 +464,7 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
425464
Pager *pPager = pDb->pBt->pBt->pPager;
426465
sqlite3_file *fd;
427466

428-
ctx = sqlite3Malloc(sizeof(codec_ctx));
467+
ctx = codec_malloc(sizeof(codec_ctx));
429468
if(ctx == NULL) return SQLITE_NOMEM;
430469
memset(ctx, 0, sizeof(codec_ctx)); /* initialize all pointers and values to 0 */
431470

@@ -437,22 +476,22 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
437476
/* pre-allocate a page buffer of PageSize bytes. This will
438477
be used as a persistent buffer for encryption and decryption
439478
operations to avoid overhead of multiple memory allocations*/
440-
ctx->buffer = sqlite3Malloc(SQLITE_DEFAULT_PAGE_SIZE);
479+
ctx->buffer = codec_malloc(SQLITE_DEFAULT_PAGE_SIZE);
441480
if(ctx->buffer == NULL) return SQLITE_NOMEM;
442481

443482
/* allocate space for salt data. Then read the first 16 bytes
444483
directly off the database file. This is the salt for the
445484
key derivation function. If we get a short read allocate
446485
a new random salt value */
447486
ctx->kdf_salt_sz = FILE_HEADER_SZ;
448-
ctx->kdf_salt = sqlite3Malloc(ctx->kdf_salt_sz);
487+
ctx->kdf_salt = codec_malloc(ctx->kdf_salt_sz);
449488
if(ctx->kdf_salt == NULL) return SQLITE_NOMEM;
450489

451490

452491
fd = sqlite3Pager_get_fd(pPager);
453492
if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
454493
/* if unable to read the bytes, generate random salt */
455-
RAND_pseudo_bytes(ctx->kdf_salt, FILE_HEADER_SZ);
494+
RAND_bytes(ctx->kdf_salt, FILE_HEADER_SZ);
456495
}
457496

458497
sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
@@ -542,7 +581,7 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
542581
sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
543582

544583
/* prepare this setup as if it had already been initialized */
545-
RAND_pseudo_bytes(ctx->kdf_salt, ctx->kdf_salt_sz);
584+
RAND_bytes(ctx->kdf_salt, ctx->kdf_salt_sz);
546585
ctx->read_ctx->key_sz = ctx->read_ctx->iv_sz = ctx->read_ctx->pass_sz = 0;
547586
}
548587

0 commit comments

Comments
 (0)
0