From: Date: June 30 2008 3:22am Subject: [patch 06/10] WL4271 Encrypted online backup: my_crypt_io: an IO abstraction allowing for filtering List-Archive: http://lists.mysql.com/internals/35765 Message-Id: <20080630012612.053675389@flamingspork.com> --- include/my_crypt_io.h | 33 +++++++ include/my_sys.h | 2 mysys/Makefile.am | 1 mysys/my_crypt_io.c | 188 ++++++++++++++++++++++++++++++++++++++++ mysys/my_malloc.c | 33 +++++++ unittest/mysys/Makefile.am | 2 unittest/mysys/my_crypt_io-t.c | 104 ++++++++++++++++++++++ unittest/mysys/my_crypt_io2-t.c | 95 ++++++++++++++++++++ 8 files changed, 457 insertions(+), 1 deletion(-) Index: stew-encrypted-backup/include/my_crypt_io.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ stew-encrypted-backup/include/my_crypt_io.h 2008-06-24 17:26:47.142445056 +1000 @@ -0,0 +1,33 @@ + +#ifndef _MY_CRYPT_IO_H_ +#define _MY_CRYPT_IO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct my_crypt_fd +{ + File fd; + char mode; + char *file_buf; + + char *crypt_buf; + size_t crypt_buf_start; + size_t crypt_buf_end; + + void* filterparam; + int (*filter)(void*, char*, char*, size_t); + int filter_block_size; +}; + +int my_crypt_fdopen(struct my_crypt_fd* cfd, File fd, int flags, int (*filter)(void*,char*,char*,size_t), void* filterparam, int filter_block_size); +ssize_t my_crypt_read(struct my_crypt_fd* cfd, void* buf, size_t count); +ssize_t my_crypt_write(struct my_crypt_fd *cfd, void* buf, size_t count); +int my_crypt_close(struct my_crypt_fd *cfd, int call_my_close); + +#ifdef __cplusplus +} +#endif + +#endif Index: stew-encrypted-backup/include/my_sys.h =================================================================== --- stew-encrypted-backup.orig/include/my_sys.h 2008-06-23 14:29:36.299514077 +1000 +++ stew-encrypted-backup/include/my_sys.h 2008-06-23 15:10:59.086512595 +1000 @@ -171,6 +171,8 @@ extern char *my_strndup(const char *from #define ORIG_CALLER_INFO /* nothing */ #define TRASH(A,B) /* nothing */ #endif +extern void *my_malloc_aligned(size_t size, myf my_flags, size_t alignment); +extern void my_free_aligned(void *p); #ifdef HAVE_LARGE_PAGES extern uint my_get_large_page_size(void); Index: stew-encrypted-backup/mysys/Makefile.am =================================================================== --- stew-encrypted-backup.orig/mysys/Makefile.am 2008-06-23 14:05:40.694521493 +1000 +++ stew-encrypted-backup/mysys/Makefile.am 2008-06-23 14:05:59.302513842 +1000 @@ -53,6 +53,7 @@ libmysys_a_SOURCES = my_init.c my_get my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_handler.c my_netware.c my_largepage.c \ my_memmem.c \ + my_crypt_io.c \ my_windac.c my_access.c base64.c my_libwrap.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c \ Index: stew-encrypted-backup/mysys/my_crypt_io.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ stew-encrypted-backup/mysys/my_crypt_io.c 2008-06-25 01:21:09.952194676 +1000 @@ -0,0 +1,188 @@ + + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define MY_CRYPT_FILE_BUF_SZ 32768 +#define MY_CRYPT_CRYPT_BUF_SZ 32768 + +int my_crypt_fdopen(struct my_crypt_fd* cfd, File fd, int flags, int (*filter)(void*,char*,char*,size_t), void* filterparam, int filter_block_size) +{ + int err; + if (fd < 0) + return -EBADF; + + if (!cfd) + return -1; + + if(!flags) + cfd->mode= 'r'; + else if(flags & O_WRONLY) + cfd->mode= 'w'; + else + return -ENOTSUP; + + cfd->fd= fd; + + cfd->filter= filter; + cfd->filterparam= filterparam; + cfd->filter_block_size= filter_block_size; + + cfd->file_buf= my_malloc_aligned(MY_CRYPT_FILE_BUF_SZ, MYF(0), 512); + cfd->crypt_buf= my_malloc_aligned(MY_CRYPT_FILE_BUF_SZ, MYF(0), 512); + + if(!cfd->file_buf || !cfd->crypt_buf) + return -ENOMEM; + + cfd->crypt_buf_start= cfd->crypt_buf_end= 0; + + return 0; +} + +ssize_t my_crypt_read(struct my_crypt_fd* cfd, void* buf, size_t count) +{ + ssize_t retval= 0; + int r; + size_t bytes_read; + int tail_padding= 0; + + if(!cfd) + return -EBADF; + + if(cfd->mode!='r') + return -EBADF; + + while(count) + { + if(cfd->crypt_buf_start != cfd->crypt_buf_end) + { + int sz= min(count, cfd->crypt_buf_end - cfd->crypt_buf_start); + memcpy(buf, &(cfd->crypt_buf[cfd->crypt_buf_start]), sz); + buf+=sz; + cfd->crypt_buf_start+=sz; + count-=sz; + retval+=sz; + if(!count) + break; + } + else + cfd->crypt_buf_start= cfd->crypt_buf_end= 0; + + bytes_read= my_read(cfd->fd, cfd->file_buf, MY_CRYPT_FILE_BUF_SZ, MYF(0)); + if(bytes_read <= 0) + return retval; + if(bytes_read < MY_CRYPT_FILE_BUF_SZ) + { + tail_padding= cfd->file_buf[bytes_read-1]; + bytes_read--; + if(count > bytes_read) + count= bytes_read - tail_padding; + if(!bytes_read) + return retval; + } + + r= (cfd->filter)(cfd->filterparam, cfd->crypt_buf, + cfd->file_buf, bytes_read); + + int sz= min(count, bytes_read - tail_padding); + retval+=sz; + memcpy(buf, cfd->crypt_buf, sz); + buf+=sz; + + cfd->crypt_buf_start= sz; + cfd->crypt_buf_end= bytes_read - tail_padding; + count-=sz; + } + + return retval; +} + +ssize_t my_crypt_write(struct my_crypt_fd *cfd, void* buf, size_t count) +{ + ssize_t retval= 0; + int r; + size_t bytes_written; + int tail_padding= 0; + + if(!cfd) + return -EBADF; + + if(cfd->mode!='w') + return -EBADF; + + while(count) + { + if(cfd->crypt_buf_end < MY_CRYPT_CRYPT_BUF_SZ) + { + int sz= min(count, MY_CRYPT_CRYPT_BUF_SZ - cfd->crypt_buf_end); + + memcpy(&(cfd->crypt_buf[cfd->crypt_buf_end]), buf, sz); + cfd->crypt_buf_end+=sz; + count-=sz; + retval+=sz; + if(!count) + break; + else + continue; + } + + r= (cfd->filter)(cfd->filterparam, cfd->file_buf, + cfd->crypt_buf, MY_CRYPT_CRYPT_BUF_SZ); + + + bytes_written= my_write(cfd->fd, cfd->file_buf, + MY_CRYPT_FILE_BUF_SZ, MYF(0)); + + if(cfd->crypt_buf_end != MY_CRYPT_CRYPT_BUF_SZ) + { + count-= bytes_written; + retval+=bytes_written; + } + + cfd->crypt_buf_start= 0; + cfd->crypt_buf_end= 0; + + if(!bytes_written || bytes_written < MY_CRYPT_FILE_BUF_SZ) + return retval; + } + + return retval; +} + +int my_crypt_close(struct my_crypt_fd *cfd, int call_my_close) +{ + int r; + size_t bytes_written; + + if(cfd->mode=='w') + { + memset(&(cfd->crypt_buf[cfd->crypt_buf_end]), 0, + MY_CRYPT_CRYPT_BUF_SZ - cfd->crypt_buf_end); + + const int bs= cfd->filter_block_size; + int sz= ((cfd->crypt_buf_end + bs - 1) / bs) * bs; + + char padding= (int)(sz - cfd->crypt_buf_end); + + r= (cfd->filter)(cfd->filterparam, cfd->file_buf, + cfd->crypt_buf, sz); + + bytes_written= my_write(cfd->fd, cfd->file_buf, sz, MYF(0)); + bytes_written= my_write(cfd->fd, &padding, 1, MYF(0)); + } + my_free_aligned(cfd->file_buf); + my_free_aligned(cfd->crypt_buf); + + if(call_my_close) + return my_close(cfd->fd, MYF(0)); + else + return 0; +} Index: stew-encrypted-backup/mysys/my_malloc.c =================================================================== --- stew-encrypted-backup.orig/mysys/my_malloc.c 2008-06-23 14:28:27.423520136 +1000 +++ stew-encrypted-backup/mysys/my_malloc.c 2008-06-24 12:02:48.680325043 +1000 @@ -92,3 +92,36 @@ char *my_strndup(const char *from, size_ } return((char*) ptr); } + +void *my_malloc_aligned(size_t size, myf my_flags, size_t alignment) +{ + void *p, *retp; + + if( alignment & (alignment-1)) + return NULL; + + size_t sz= size + alignment - 1; + + sz+=sizeof(size_t); + + p= my_malloc(sz, my_flags); + + if(!p) + return NULL; + + retp= (void*) ((char*)p) + sizeof(size_t); + + retp= (void*) (((size_t)retp + alignment - 1) & ~(alignment - 1)); + + *((size_t*)retp - 1) = (size_t)retp - (size_t)p; + + return retp; +} + +void my_free_aligned(void *p) +{ + if(!p) + return; + + free((void*) ((size_t)p - *((size_t*)p - 1))); +} Index: stew-encrypted-backup/unittest/mysys/Makefile.am =================================================================== --- stew-encrypted-backup.orig/unittest/mysys/Makefile.am 2008-06-24 15:05:29.061241155 +1000 +++ stew-encrypted-backup/unittest/mysys/Makefile.am 2008-06-24 20:13:23.618486685 +1000 @@ -21,7 +21,7 @@ LDADD = $(top_builddir)/unittest/mytap $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a -noinst_PROGRAMS = bitmap-t base64-t my_atomic-t +noinst_PROGRAMS = bitmap-t base64-t my_atomic-t my_crypt_io-t my_crypt_io2-t EXTRA_DIST = CMakeLists.txt Index: stew-encrypted-backup/unittest/mysys/my_crypt_io-t.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ stew-encrypted-backup/unittest/mysys/my_crypt_io-t.c 2008-06-24 18:41:53.824376762 +1000 @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include + +#include + + +#ifndef HAVE_YASSL +int +main(void) +{ + MY_INIT("my_crypt_io-t"); + PLAN(0); + return exit_status(); +} +#else + +#include + +int enc_filter(void* obj,char* obuf,char* ibuf,size_t sz) +{ + int i; + for(i=0; i +#include +#include +#include +#include + +#include + + +#ifndef HAVE_YASSL +int +main(void) +{ + MY_INIT("my_crypt_io-t"); + PLAN(0); + return exit_status(); +} +#else + +#include + +int enc_filter(void* obj,char* obuf,char* ibuf,size_t sz) +{ + int i; + for(i=0; i0 && buf[r]==7; r--) + ; + + ok(r==0, "check read"); + + return exit_status(); +} +#endif -- Stewart Smith