Commit d42d39d0 authored by g3gg0's avatar g3gg0
Browse files

io_crypt: various cleanups, some more comments, io_decrypt with only one parameter

--HG--
branch : unified
parent 0d3cadfbf3a7
......@@ -8,3 +8,7 @@ include ../Makefile.modules
# include host tool makefile rules
include Makefile.io_decrypt
CFLAGS+=-DTRACE_DISABLED
HOST_CFLAGS+=-DTRACE_DISABLED
MINGW_CFLAGS+=-DTRACE_DISABLED
#ifdef MODULE
#include <dryos.h>
#include <property.h>
#include <bmp.h>
#include <menu.h>
#define TRACE_DISABLED
#include "../trace/trace.h"
#else
......@@ -12,13 +14,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#if defined(TRACE_DISABLED)
#define trace_write(x,...) do { (void)0; } while (0)
//#define trace_write(x,...) do { printf(__VA_ARGS__); printf("\n"); } while (0)
#else
#define trace_write(x,...) do { printf(__VA_ARGS__); printf("\n"); } while (0)
#endif
#endif
/* common includes */
#include <string.h>
#include "io_crypt.h"
#include "crypt_lfsr64.h"
......@@ -29,7 +36,6 @@
the larger the block size is, the easier it is to reconstruct the current block key
*/
static uint32_t crypt_lfsr64_blocksize = 0x00020000;
extern uint32_t iocrypt_trace_ctx;
/* clock the current LFSR by given number of clocks */
......@@ -67,7 +73,7 @@ static void crypt_lfsr64_xor_uint64(void *dst_in, void *src_in, lfsr64_ctx_t *ct
static void update_key(lfsr64_ctx_t *ctx, uint32_t offset, uint32_t force)
{
/* update the current encryption key whever reaching the next block */
uint32_t block = offset / crypt_lfsr64_blocksize;
uint32_t block = offset / ctx->blocksize;
if(!force)
{
......@@ -110,25 +116,31 @@ static void update_key(lfsr64_ctx_t *ctx, uint32_t offset, uint32_t force)
}
}
#define IS_UNALIGNED(x) ((((uint32_t)dst) % (x)) || (((uint32_t)src) % (x)))
static uint32_t crypt_lfsr64_encrypt(crypt_cipher_t *cipher_ctx, uint8_t *dst, uint8_t *src, uint32_t length, uint32_t offset)
/* small helper to simplify alignment checking and make encrypt loops better readable */
static uint32_t crypt_lfsr64_unaligned(void *addr)
{
return ((uint32_t)addr) % 8;
}
/* de-/encryption routine, XORing every 64 bit word with an offset based crypt key */
static uint32_t crypt_lfsr64_encrypt(crypt_cipher_t *cipher_ctx, uint8_t *dst, uint8_t *src, uint32_t in_length, uint32_t offset)
{
lfsr64_ctx_t *ctx = cipher_ctx->priv;
uint32_t length = in_length;
/* initial key creation */
/* ensure initial key creation if necessary */
update_key(ctx, offset, 0);
/* try to get the addresses aligned */
//trace_write(iocrypt_trace_ctx, "crypt_lfsr64_xor_uint8 offset 0x%08X, length 0x%08X", offset, length);
while((IS_UNALIGNED(8) || (offset % 8)) && (length > 0))
while((crypt_lfsr64_unaligned(src) || crypt_lfsr64_unaligned(dst)) && (length > 0))
{
uint32_t block_remain = offset % crypt_lfsr64_blocksize;
if(block_remain == 0)
/* at every block start, rerun key update */
if((offset % ctx->blocksize) == 0)
{
update_key(ctx, offset, 0);
}
/* encrypt a single byte, thats very slow of course */
crypt_lfsr64_xor_uint8(dst, src, ctx, offset);
dst += 1;
src += 1;
......@@ -136,13 +148,18 @@ static uint32_t crypt_lfsr64_encrypt(crypt_cipher_t *cipher_ctx, uint8_t *dst, u
length -= 1;
}
//trace_write(iocrypt_trace_ctx, "crypt_lfsr64_xor_uint64 offset 0x%08X, length 0x%08X", offset, length);
if(!IS_UNALIGNED(8))
if(!length)
{
/* processing loop for 64 bit writes and even file offsets */
while(length >= 8 && ((offset % 8) == 0))
return in_length;
}
/* either the pointers are 64 bit aligned now or all data is encrypted already. do 64 bit writes if possible. */
if((offset % 8) == 0)
{
/* processing loop for 64 bit writes at even file offsets. due to compiler optimizations this loop is faster */
while(length >= 8)
{
if((offset % crypt_lfsr64_blocksize) == 0)
if((offset % ctx->blocksize) == 0)
{
update_key(ctx, offset, 0);
}
......@@ -153,34 +170,36 @@ static uint32_t crypt_lfsr64_encrypt(crypt_cipher_t *cipher_ctx, uint8_t *dst, u
offset += 8;
length -= 8;
}
}
/* processing loop for 64 bit writes at odd file offsets. this loop has to do an extra lookup */
while(length >= 8)
{
uint32_t block_remain = offset % ctx->blocksize;
/* processing loop for 64 bit writes and odd file offsets */
while(length >= 8)
if(block_remain == 0)
{
uint32_t block_remain = offset % crypt_lfsr64_blocksize;
if(block_remain == 0)
{
update_key(ctx, offset, 0);
}
else if(block_remain < 8)
{
break;
}
crypt_lfsr64_xor_uint64(dst, src, ctx, offset);
dst += 8;
src += 8;
offset += 8;
length -= 8;
update_key(ctx, offset, 0);
}
else if(block_remain < 8)
{
/* okay here i get lazy to play safe.
correct would be doing bytewise encryption for the remaining 1-7 bytes, then continue 64 bit crypts.
but fall back to bytewise for all remaining bytes. */
break;
}
crypt_lfsr64_xor_uint64(dst, src, ctx, offset);
dst += 8;
src += 8;
offset += 8;
length -= 8;
}
/* do the rest */
//trace_write(iocrypt_trace_ctx, "crypt_lfsr64_xor_uint8 offset 0x%08X, length 0x%08X", offset, length);
/* do the rest, very slow */
while(length > 0)
{
uint32_t block_remain = offset % crypt_lfsr64_blocksize;
uint32_t block_remain = offset % ctx->blocksize;
if(block_remain == 0)
{
......@@ -188,16 +207,14 @@ static uint32_t crypt_lfsr64_encrypt(crypt_cipher_t *cipher_ctx, uint8_t *dst, u
}
crypt_lfsr64_xor_uint8(dst, src, ctx, offset);
trace_write(iocrypt_trace_ctx, "crypt_lfsr64_xor_uint8 offset 0x%08X, 0x%02X <- 0x%02X", offset, *dst, *src);
dst += 1;
src += 1;
offset += 1;
length -= 1;
}
return 0;
return length;
}
#undef IS_UNALIGNED
/* using a symmetric cipher, both encryption and decryption are the same */
static uint32_t crypt_lfsr64_decrypt(crypt_cipher_t *ctx, uint8_t *dst, uint8_t *src, uint32_t length, uint32_t offset)
......@@ -205,11 +222,15 @@ static uint32_t crypt_lfsr64_decrypt(crypt_cipher_t *ctx, uint8_t *dst, uint8_t
return crypt_lfsr64_encrypt(ctx, dst, src, length, offset);
}
/* set encryption blocksize for this context */
static void crypt_lfsr64_set_blocksize(crypt_cipher_t *crypt_ctx, uint32_t size)
{
crypt_lfsr64_blocksize = size;
lfsr64_ctx_t *ctx = crypt_ctx->priv;
ctx->blocksize = size;
}
/* not much to do here, just free the previously allocated structure */
static void crypt_lfsr64_deinit(crypt_cipher_t *crypt_ctx)
{
if(crypt_ctx && crypt_ctx->priv)
......@@ -219,6 +240,20 @@ static void crypt_lfsr64_deinit(crypt_cipher_t *crypt_ctx)
}
}
/* reset operation is not implemented yet */
static void crypt_lfsr64_reset(crypt_cipher_t *crypt_ctx)
{
lfsr64_ctx_t *ctx = crypt_ctx->priv;
/* to mark LFSR state as invalid */
ctx->current_block = 0xFFFFFFFF;
ctx->lfsr_state = 0;
ctx->blocksize = crypt_lfsr64_blocksize;
/* setup initial cipher key */
update_key(ctx, 0, 1);
}
/* allocate and initialize an LFSR64 cipher ctx and save to pointer */
void crypt_lfsr64_init(crypt_cipher_t *crypt_ctx, uint64_t password)
{
......@@ -234,15 +269,13 @@ void crypt_lfsr64_init(crypt_cipher_t *crypt_ctx, uint64_t password)
crypt_ctx->encrypt = (uint32_t (*)(void *, uint8_t *, uint8_t *, uint32_t, uint32_t))&crypt_lfsr64_encrypt;
crypt_ctx->decrypt = (uint32_t (*)(void *, uint8_t *, uint8_t *, uint32_t, uint32_t))&crypt_lfsr64_decrypt;
crypt_ctx->deinit = (void (*)(void *))&crypt_lfsr64_deinit;
crypt_ctx->reset = (void (*)(void *))&crypt_lfsr64_reset;
crypt_ctx->set_blocksize = (void (*)(void *, uint32_t))&crypt_lfsr64_set_blocksize;
crypt_ctx->priv = ctx;
ctx->password = password;
ctx->current_block = 0xFFFFFFFF;
ctx->lfsr_state = 0;
/* setup initial cipher key */
update_key(ctx, 0, 1);
/* initialize to default values */
ctx->password = password;
crypt_lfsr64_reset(crypt_ctx);
trace_write(iocrypt_trace_ctx, "crypt_lfsr64_init: initialized");
}
......
......@@ -9,6 +9,7 @@ typedef struct
uint64_t key_uint64[8];
uint64_t password;
uint32_t current_block;
uint32_t blocksize;
} lfsr64_ctx_t;
void crypt_lfsr64_init(crypt_cipher_t *crypt_ctx, uint64_t password);
......
//#define TRACE_DISABLED
#ifdef MODULE
#include <dryos.h>
#include <property.h>
#include <bmp.h>
#include <menu.h>
#include <string.h>
#define TRACE_DISABLED
#include "../trace/trace.h"
extern char *module_card_drive;
......@@ -18,15 +18,18 @@ extern char *module_card_drive;
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#if defined(TRACE_DISABLED)
#define trace_write(x,...) do { (void)0; } while (0)
//#define trace_write(x,...) do { printf(__VA_ARGS__); printf("\n"); } while (0)
#else
#define trace_write(x,...) do { printf(__VA_ARGS__); printf("\n"); } while (0)
#endif
/* simulate ML/DryOS behavoir for desktop mode */
#define NotifyBox(x,...) do { printf(__VA_ARGS__); printf("\n"); } while (0)
#define NotifyBoxHide() do { } while(0)
#define beep() do { } while(0)
......@@ -40,6 +43,7 @@ extern char *module_card_drive;
#define FIO_CloseFile(x) fclose(f)
#define FIO_Open(file,mode) fopen(file, "r")
#define FIO_GetFileSize(f,ret) getFileSize(f,ret)
#define INVALID_PTR 0
#define O_RDONLY 0
#define O_SYNC 0
......@@ -56,6 +60,8 @@ size_t getFileSize(const char * filename, int *ret)
char *module_card_drive = "";
#endif
/* common includes */
#include <string.h>
#include <rand.h>
#include "io_crypt.h"
......@@ -557,6 +563,10 @@ static void crypt_rsa_deinit(void **crypt_ctx)
}
}
static void crypt_rsa_reset(void **crypt_ctx)
{
}
static uint32_t crypt_rsa_save(char *file, t_crypt_key *key)
{
char filename[32];
......@@ -601,6 +611,7 @@ uint32_t crypt_rsa_load(char *file, t_crypt_key *key)
char *buffer = malloc(size);
if(FIO_ReadFile(f, buffer, size) != (int)size)
{
FIO_CloseFile(f);
trace_write(iocrypt_trace_ctx, "io_crypt: crypt_rsa_load: FIO_ReadFile failed");
free(buffer);
return 0;
......@@ -609,6 +620,7 @@ uint32_t crypt_rsa_load(char *file, t_crypt_key *key)
char *sep = strchr(buffer, '\n');
if(!sep)
{
FIO_CloseFile(f);
trace_write(iocrypt_trace_ctx, "io_crypt: crypt_rsa_load: invalid file format");
free(buffer);
return 0;
......@@ -762,6 +774,7 @@ void crypt_rsa_init(crypt_cipher_t *crypt_ctx)
crypt_ctx->encrypt = (uint32_t (*)(void *, uint8_t *, uint8_t *, uint32_t, uint32_t))&crypt_rsa_encrypt;
crypt_ctx->decrypt = (uint32_t (*)(void *, uint8_t *, uint8_t *, uint32_t, uint32_t))&crypt_rsa_decrypt;
crypt_ctx->deinit = (void (*)(void *))&crypt_rsa_deinit;
crypt_ctx->reset = (void (*)(void *))&crypt_rsa_reset;
crypt_ctx->set_blocksize = (void (*)(void *, uint32_t))&crypt_rsa_set_blocksize;
crypt_ctx->priv = ctx;
......@@ -774,13 +787,6 @@ void crypt_rsa_init(crypt_cipher_t *crypt_ctx)
crypt_rsa_load("io_crypt.pub", &ctx->pub_key);
crypt_rsa_load("io_crypt.key", &ctx->priv_key);
//trace_write(iocrypt_trace_ctx, " pub_key: name %s", ctx->pub_key.name);
//trace_write(iocrypt_trace_ctx, " pub_key: primefac %s", ctx->pub_key.primefac);
//trace_write(iocrypt_trace_ctx, " pub_key: key %s", ctx->pub_key.key);
//trace_write(iocrypt_trace_ctx, " priv_key: name %s", ctx->priv_key.name);
//trace_write(iocrypt_trace_ctx, " priv_key: primefac %s", ctx->priv_key.primefac);
//trace_write(iocrypt_trace_ctx, " priv_key: key %s", ctx->priv_key.key);
trace_write(iocrypt_trace_ctx, "crypt_rsa_init: initialized");
}
......
......@@ -14,7 +14,6 @@
#include "crypt_lfsr64.h"
#include "crypt_rsa.h"
#define TRACE_DISABLED
#include "../trace/trace.h"
#include "../ime_base/ime_base.h"
......@@ -264,7 +263,7 @@ static uint32_t hook_iodev_OpenFile(void *iodev, char *filename, int32_t flags,
uint32_t lfsr_blocksize = 0;
iodev_SetPosition(fd, 4);
orig_iodev->ReadFile(fd, &lfsr_blocksize, 4);
orig_iodev->ReadFile(fd, (uint8_t *)&lfsr_blocksize, 4);
iodev_SetPosition(fd, 0x200);
crypt_lfsr64_init(&iocrypt_files[fd].crypt_ctx, iocrypt_key);
......@@ -397,10 +396,9 @@ static uint32_t hook_iodev_ReadFile(uint32_t fd, uint8_t *buf, uint32_t length)
iodev_SetPosition(fd, iodev_GetPosition(fd) - iocrypt_files[fd].header_size);
}
if(fd < COUNT(iocrypt_files))
{
trace_write(iocrypt_trace_ctx, "iodev_ReadFile(0x%08X, 0x%08X) -> %s, fd = %d, pos_before = 0x%08X, ret %d, pos_after %d", buf, length, fd, fd_pos, iocrypt_files[fd].filename, ret, iodev_GetPosition(fd));
trace_write(iocrypt_trace_ctx, "iodev_ReadFile(0x%08X, 0x%08X) -> %s, fd = %d, pos_before = 0x%08X, ret %d, pos_after %d", buf, length, iocrypt_files[fd].filename, fd, fd_pos, iocrypt_files[fd].filename, ret, iodev_GetPosition(fd));
if(iocrypt_files[fd].crypt_ctx.priv)
{
......@@ -425,7 +423,7 @@ static uint32_t hook_iodev_WriteFile(uint32_t fd, uint8_t *buf, uint32_t length)
if(iocrypt_files[fd].crypt_ctx.priv)
{
trace_write(iocrypt_trace_ctx, "iodev_WriteFile pre(0x%08X, 0x%08X) -> fd = %d, fd_pos = 0x%08X, misalign = %d, %s", buf, length, fd, fd_pos, misalign, iocrypt_files[fd].filename);
trace_write(iocrypt_trace_ctx, "iodev_WriteFile pre(0x%08X, 0x%08X) -> %s, fd = %d, fd_pos = 0x%08X, misalign = %d", buf, length, iocrypt_files[fd].filename, fd, fd_pos, misalign);
/* if there is no buffer or the size is too big, do expensive in-place encryption */
if(iocrypt_scratch && (length <= CRYPT_SCRATCH_SIZE))
......@@ -449,7 +447,7 @@ static uint32_t hook_iodev_WriteFile(uint32_t fd, uint8_t *buf, uint32_t length)
trace_write(iocrypt_trace_ctx, "iodev_WriteFile: undo offset %d", iocrypt_files[fd].header_size);
iodev_SetPosition(fd, iodev_GetPosition(fd) - iocrypt_files[fd].header_size);
trace_write(iocrypt_trace_ctx, "iodev_WriteFile post(0x%08X, 0x%08X) -> fd = %d, fd_pos = 0x%08X, fd_pos (now) = 0x%08X, %s", buf, length, fd, fd_pos, iodev_GetPosition(fd), iocrypt_files[fd].filename);
trace_write(iocrypt_trace_ctx, "iodev_WriteFile post(0x%08X, 0x%08X) -> fd = %d, fd_pos = 0x%08X, fd_pos (now) = 0x%08X", buf, length, fd, fd_pos, iodev_GetPosition(fd));
/* if we were not able to write it from scratch, undo in-place encryption */
if(work_ptr == buf)
......@@ -647,7 +645,7 @@ static MENU_UPDATE_FUNC(iocrypt_update)
else if(crypt_rsa_get_priv(&iocrypt_rsa_ctx))
{
MENU_SET_VALUE("INSECURE!");
MENU_SET_WARNING(MENU_WARN_ADVICE, "Move /ML/DATA/IO_CRYPT.KEY to a safe place and DELETE from card.");
MENU_SET_WARNING(MENU_WARN_ADVICE, "Move IO_CRYPT.KEY to a safe place and DELETE from card.");
}
else
{
......@@ -717,7 +715,6 @@ static struct menu_entry iocrypt_menus[] =
.choices = (const char *[]) {"512", "1024", "2048", "4096"},
.help = "Key size when creating a RSA key pair. The smaller, the less security you have.",
},
{
.name = "Test: Speed",
.select = &iocrypt_test_speed,
......
......@@ -5,12 +5,18 @@
#define CRYPT_SCRATCH_SIZE 0x00800000
typedef struct crypt_cipher_t
{
/* priv: private data for the encryption algorithm */
void *priv;
/* encrypt: encrypt given data at *src of given length and store at *dst, returns encrypted data length */
uint32_t (*encrypt)(void *ctx, uint8_t *dst, uint8_t *src, uint32_t length, uint32_t offset);
/* encrypt: decrypt given data at *src of given length and store at *dst, returns decrypted data length */
uint32_t (*decrypt)(void *ctx, uint8_t *dst, uint8_t *src, uint32_t length, uint32_t offset);
/* set_blocksize: set encryption algorithm parameter blocksize */
void (*set_blocksize)(void *ctx, uint32_t size);
/* reset: reset internal data to the state right after initialization */
void (*reset)(void *ctx);
/* deinit: free private data */
void (*deinit)(void *ctx);
void (*set_blocksize)(void *ctx, uint32_t size);
} crypt_cipher_t;
typedef struct
......
......@@ -50,9 +50,9 @@ void rand_seed(uint32_t seed)
static crypt_cipher_t iocrypt_rsa_ctx;
int main(int argc, char *argv[])
{
if(argc < 3)
if(argc < 2)
{
printf("Usage: '%s <infile> <outfile> [password]\n", argv[0]);
printf("Usage: '%s <infile> [outfile] [password]\n", argv[0]);
return -1;
}
......@@ -60,7 +60,14 @@ int main(int argc, char *argv[])
uint32_t lfsr_blocksize = 0x00020000;
char *in_filename = argv[1];
char *out_filename = argv[2];
char *out_filename = malloc(strlen(in_filename) + 9);
sprintf(out_filename, "%s_out.cr2", in_filename);
if(argc >= 3)
{
out_filename = strdup(argv[2]);
}
/* password is optional */
if(argc >= 4)
......@@ -216,4 +223,5 @@ int main(int argc, char *argv[])
fclose(in_file);
fclose(out_file);
free(out_filename);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment