mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-19 18:47:54 +08:00
Extract RC4 code to separate file
This commit is contained in:
@@ -648,6 +648,9 @@ void mdb_iconv_init(MdbHandle *mdb);
|
|||||||
void mdb_iconv_close(MdbHandle *mdb);
|
void mdb_iconv_close(MdbHandle *mdb);
|
||||||
const char* mdb_target_charset(MdbHandle *mdb);
|
const char* mdb_target_charset(MdbHandle *mdb);
|
||||||
|
|
||||||
|
/* rc4.c */
|
||||||
|
void mdb_rc4(unsigned char *key, guint32 key_len, unsigned char *buf, guint32 buf_len);
|
||||||
|
|
||||||
/** @}*/
|
/** @}*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
lib_LTLIBRARIES = libmdb.la
|
lib_LTLIBRARIES = libmdb.la
|
||||||
libmdb_la_SOURCES= catalog.c file.c table.c data.c dump.c backend.c money.c sargs.c index.c like.c write.c stats.c map.c props.c worktable.c options.c iconv.c version.c
|
libmdb_la_SOURCES= catalog.c file.c table.c data.c dump.c backend.c money.c sargs.c index.c like.c write.c stats.c map.c props.c worktable.c options.c iconv.c version.c rc4.c
|
||||||
libmdb_la_LDFLAGS = -version-info $(VERSION_INFO)
|
libmdb_la_LDFLAGS = -version-info $(VERSION_INFO)
|
||||||
if FAKE_GLIB
|
if FAKE_GLIB
|
||||||
libmdb_la_SOURCES += fakeglib.c
|
libmdb_la_SOURCES += fakeglib.c
|
||||||
|
@@ -66,69 +66,8 @@ MdbFormatConstants MdbJet3Constants = {
|
|||||||
.tab_row_col_num_offset = 5
|
.tab_row_col_num_offset = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _RC4_KEY
|
|
||||||
{
|
|
||||||
unsigned char state[256];
|
|
||||||
unsigned char x;
|
|
||||||
unsigned char y;
|
|
||||||
} RC4_KEY;
|
|
||||||
|
|
||||||
#define swap_byte(x,y) t = *(x); *(x) = *(y); *(y) = t
|
|
||||||
|
|
||||||
static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, unsigned long pg);
|
static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, unsigned long pg);
|
||||||
|
|
||||||
static void RC4_set_key(RC4_KEY *key, int key_data_len, unsigned char *key_data_ptr)
|
|
||||||
{
|
|
||||||
unsigned char t;
|
|
||||||
unsigned char index1;
|
|
||||||
unsigned char index2;
|
|
||||||
unsigned char* state;
|
|
||||||
short counter;
|
|
||||||
|
|
||||||
state = &key->state[0];
|
|
||||||
for(counter = 0; counter < 256; counter++)
|
|
||||||
state[counter] = counter;
|
|
||||||
key->x = 0;
|
|
||||||
key->y = 0;
|
|
||||||
index1 = 0;
|
|
||||||
index2 = 0;
|
|
||||||
for(counter = 0; counter < 256; counter++) {
|
|
||||||
index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
|
|
||||||
swap_byte(&state[counter], &state[index2]);
|
|
||||||
index1 = (index1 + 1) % key_data_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* this algorithm does 'encrypt in place' instead of inbuff/outbuff
|
|
||||||
* note also: encryption and decryption use same routine
|
|
||||||
* implementation supplied by (Adam Back) at <adam at cypherspace dot org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void RC4(RC4_KEY *key, int buffer_len, unsigned char * buff)
|
|
||||||
{
|
|
||||||
unsigned char t;
|
|
||||||
unsigned char x;
|
|
||||||
unsigned char y;
|
|
||||||
unsigned char* state;
|
|
||||||
unsigned char xorIndex;
|
|
||||||
short counter;
|
|
||||||
|
|
||||||
x = key->x;
|
|
||||||
y = key->y;
|
|
||||||
state = &key->state[0];
|
|
||||||
for(counter = 0; counter < buffer_len; counter++) {
|
|
||||||
x = (x + 1) % 256;
|
|
||||||
y = (state[x] + y) % 256;
|
|
||||||
swap_byte(&state[x], &state[y]);
|
|
||||||
xorIndex = (state[x] + state[y]) % 256;
|
|
||||||
buff[counter] ^= state[xorIndex];
|
|
||||||
}
|
|
||||||
key->x = x;
|
|
||||||
key->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mdb_find_file:
|
* mdb_find_file:
|
||||||
* @filename: path to MDB (database) file
|
* @filename: path to MDB (database) file
|
||||||
@@ -232,10 +171,13 @@ static MdbHandle *mdb_handle_from_stream(FILE *stream, MdbFileFlags flags) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RC4_KEY rc4_key;
|
guint32 tmp_key = 0x6b39dac7;
|
||||||
unsigned int tmp_key = 0x6b39dac7;
|
mdb_rc4(
|
||||||
RC4_set_key(&rc4_key, 4, (unsigned char *)&tmp_key);
|
(unsigned char *)&tmp_key,
|
||||||
RC4(&rc4_key, mdb->f->jet_version == MDB_VER_JET3 ? 126 : 128, mdb->pg_buf + 0x18);
|
4,
|
||||||
|
mdb->pg_buf + 0x18,
|
||||||
|
mdb->f->jet_version == MDB_VER_JET3 ? 126 : 128
|
||||||
|
);
|
||||||
|
|
||||||
if (mdb->f->jet_version == MDB_VER_JET3) {
|
if (mdb->f->jet_version == MDB_VER_JET3) {
|
||||||
mdb->f->lang_id = mdb_get_int16(mdb->pg_buf, 0x3a);
|
mdb->f->lang_id = mdb_get_int16(mdb->pg_buf, 0x3a);
|
||||||
@@ -436,10 +378,8 @@ static ssize_t _mdb_read_pg(MdbHandle *mdb, void *pg_buf, unsigned long pg)
|
|||||||
*/
|
*/
|
||||||
if (pg != 0 && mdb->f->db_key != 0)
|
if (pg != 0 && mdb->f->db_key != 0)
|
||||||
{
|
{
|
||||||
RC4_KEY rc4_key;
|
|
||||||
unsigned int tmp_key = mdb->f->db_key ^ pg;
|
unsigned int tmp_key = mdb->f->db_key ^ pg;
|
||||||
RC4_set_key(&rc4_key, 4, (unsigned char *)&tmp_key);
|
mdb_rc4((unsigned char*)&tmp_key, 4, pg_buf, mdb->fmt->pg_size);
|
||||||
RC4(&rc4_key, mdb->fmt->pg_size, pg_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mdb->fmt->pg_size;
|
return mdb->fmt->pg_size;
|
||||||
|
67
src/libmdb/rc4.c
Normal file
67
src/libmdb/rc4.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include "mdbtools.h"
|
||||||
|
|
||||||
|
typedef struct _RC4_KEY
|
||||||
|
{
|
||||||
|
unsigned char state[256];
|
||||||
|
unsigned char x;
|
||||||
|
unsigned char y;
|
||||||
|
} RC4_KEY;
|
||||||
|
|
||||||
|
#define swap_byte(x,y) t = *(x); *(x) = *(y); *(y) = t
|
||||||
|
|
||||||
|
|
||||||
|
static void RC4_set_key(RC4_KEY *key, int key_data_len, unsigned char *key_data_ptr)
|
||||||
|
{
|
||||||
|
unsigned char t;
|
||||||
|
unsigned char index1;
|
||||||
|
unsigned char index2;
|
||||||
|
unsigned char* state;
|
||||||
|
short counter;
|
||||||
|
|
||||||
|
state = &key->state[0];
|
||||||
|
for(counter = 0; counter < 256; counter++)
|
||||||
|
state[counter] = counter;
|
||||||
|
key->x = 0;
|
||||||
|
key->y = 0;
|
||||||
|
index1 = 0;
|
||||||
|
index2 = 0;
|
||||||
|
for(counter = 0; counter < 256; counter++) {
|
||||||
|
index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
|
||||||
|
swap_byte(&state[counter], &state[index2]);
|
||||||
|
index1 = (index1 + 1) % key_data_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this algorithm does 'encrypt in place' instead of inbuff/outbuff
|
||||||
|
* note also: encryption and decryption use same routine
|
||||||
|
* implementation supplied by (Adam Back) at <adam at cypherspace dot org>
|
||||||
|
*/
|
||||||
|
static void RC4(RC4_KEY *key, int buffer_len, unsigned char * buff)
|
||||||
|
{
|
||||||
|
unsigned char t;
|
||||||
|
unsigned char x;
|
||||||
|
unsigned char y;
|
||||||
|
unsigned char* state;
|
||||||
|
unsigned char xorIndex;
|
||||||
|
short counter;
|
||||||
|
|
||||||
|
x = key->x;
|
||||||
|
y = key->y;
|
||||||
|
state = &key->state[0];
|
||||||
|
for(counter = 0; counter < buffer_len; counter++) {
|
||||||
|
x = (x + 1) % 256;
|
||||||
|
y = (state[x] + y) % 256;
|
||||||
|
swap_byte(&state[x], &state[y]);
|
||||||
|
xorIndex = (state[x] + state[y]) % 256;
|
||||||
|
buff[counter] ^= state[xorIndex];
|
||||||
|
}
|
||||||
|
key->x = x;
|
||||||
|
key->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mdb_rc4(unsigned char *key, guint32 key_len, unsigned char *buf, guint32 buf_len) {
|
||||||
|
RC4_KEY rc4_key;
|
||||||
|
RC4_set_key(&rc4_key, key_len, key);
|
||||||
|
RC4(&rc4_key, buf_len, buf);
|
||||||
|
}
|
Reference in New Issue
Block a user