List:Internals« Previous MessageNext Message »
From:stewart Date:June 30 2008 3:22am
Subject:[patch 07/10] WL4271 Encrytped backup: implement basic AES Encyrption
View as plain text  
---
 mysql-test/r/backup_encrypted.result            |   15 ++++
 mysql-test/t/backup_encrypted.test              |   13 ++++
 mysql-test/t/backup_encrypted_syntax_basic.test |    5 -
 sql/Makefile.am                                 |    6 -
 sql/backup/Makefile.am                          |    5 +
 sql/backup/kernel.cc                            |   44 +++++++++++++-
 sql/backup/stream.cc                            |   73 ++++++++++++++++++++----
 sql/backup/stream.h                             |   12 +++
 8 files changed, 151 insertions(+), 22 deletions(-)

Index: stew-encrypted-backup/mysql-test/t/backup_encrypted_syntax_basic.test
===================================================================
--- stew-encrypted-backup.orig/mysql-test/t/backup_encrypted_syntax_basic.test	2008-06-26
02:59:29.002616740 +1000
+++ stew-encrypted-backup/mysql-test/t/backup_encrypted_syntax_basic.test	2008-06-26
13:42:15.792049536 +1000
@@ -3,11 +3,10 @@
 BACKUP DATABASE test TO 'test.ba';
 --error 1235
 BACKUP DATABASE test TO 'test1.ba' ENCRYPTION_ALGORITHM=foo;
---error 1235
+--error 1149
 BACKUP DATABASE test TO 'test2.ba' ENCRYPTION_ALGORITHM=aes;
---error 1235
+--error 1149
 BACKUP DATABASE test TO 'test3.ba' ENCRYPTION_ALGORITHM=aes ENCRYPTION_KEYSIZE=128;
---error 1235
 BACKUP DATABASE test TO 'test4.ba' ENCRYPTION_ALGORITHM=aes ENCRYPTION_KEYSIZE=128
PASSWORD='pants';
 --error 1235
 BACKUP DATABASE test TO 'test5.ba' ENCRYPTION_ALGORITHM=aes ENCRYPTION_KEYSIZE=128
ENCRYPTION_KEYFILE='foo.key';
Index: stew-encrypted-backup/sql/backup/Makefile.am
===================================================================
--- stew-encrypted-backup.orig/sql/backup/Makefile.am	2008-06-26 02:33:16.975621412 +1000
+++ stew-encrypted-backup/sql/backup/Makefile.am	2008-06-26 03:09:27.899623071 +1000
@@ -24,7 +24,10 @@ INCLUDES = \
   -I$(top_builddir)/include \
   -I$(top_srcdir)/include \
   -I$(top_srcdir)/sql \
-  -I$(top_srcdir)/regex
+  -I$(top_srcdir)/regex \
+  -I$(top_srcdir)/extra/yassl/include \
+  -I$(top_srcdir)/extra/yassl/taocrypt/include
+
 
 libbackup_la_SOURCES = \
   stream.cc \
Index: stew-encrypted-backup/sql/backup/kernel.cc
===================================================================
--- stew-encrypted-backup.orig/sql/backup/kernel.cc	2008-06-26 03:03:29.670639990 +1000
+++ stew-encrypted-backup/sql/backup/kernel.cc	2008-06-26 13:42:13.123048043 +1000
@@ -64,6 +64,11 @@
 #include "../mysql_priv.h"
 #include "../si_objects.h"
 
+#ifdef HAVE_YASSL
+#include <yassl_types.hpp>
+#include <crypto_wrapper.hpp>
+#endif
+
 #include "backup_kernel.h"
 #include "backup_info.h"
 #include "restore_info.h"
@@ -497,6 +502,10 @@ Backup_restore_ctx::prepare_for_backup(L
   backup::String encryption_keyfile_str(encryption_keyfile);
   backup::String encryption_password_str(encryption_password);
 
+#ifdef HAVE_YASSL
+  yaSSL::BulkCipher *cipher= NULL;
+#endif
+
   if(encryption_algorithm_str.ptr()
      || encryption_keyfile_str.ptr()
      || encryption_password_str.ptr()
@@ -506,8 +515,37 @@ Backup_restore_ctx::prepare_for_backup(L
     fatal_error(ER_NOT_SUPPORTED_YET, "Need YaSSL to support encrypted backup");
     return NULL;
 #else
-    fatal_error(ER_NOT_SUPPORTED_YET, "Encrypted backup not yet implemented");
-    return NULL;
+    if(encryption_keyfile_str.ptr())
+    {
+      fatal_error(ER_NOT_SUPPORTED_YET, "Encryption with keyfile");
+      return NULL;
+    }
+
+    if(strcmp(encryption_algorithm_str.ptr(),"aes")==0)
+    {
+      if(!encryption_password_str.ptr())
+      {
+        fatal_error(ER_SYNTAX_ERROR, "Encryption requires password");
+        return NULL;
+      }
+      byte key[yaSSL::AES_256_KEY_SZ];
+      byte iv[yaSSL::AES_IV_SZ];
+
+      memset(key,0,yaSSL::AES_256_KEY_SZ);
+      memset(iv,0,yaSSL::AES_IV_SZ);
+
+      EVP_BytesToKey("AES-128-CBC", "MD5", NULL,
+                     (byte*)encryption_password_str.ptr(),
+                     encryption_password_str.length(),
+                     1, key, iv);
+      cipher= new yaSSL::AES;
+      cipher->set_encryptKey(key,iv);
+    }
+    else
+    {
+      fatal_error(ER_NOT_SUPPORTED_YET, encryption_algorithm_str.ptr());
+      return NULL;
+    }
 #endif
   }
 
@@ -515,7 +553,7 @@ Backup_restore_ctx::prepare_for_backup(L
     Open output stream.
    */
 
-  Output_stream *s= new Output_stream(*this, path, with_compression);
+  Output_stream *s= new Output_stream(*this, path, with_compression, cipher);
   
   if (!s)
   {
Index: stew-encrypted-backup/sql/backup/stream.cc
===================================================================
--- stew-encrypted-backup.orig/sql/backup/stream.cc	2008-06-26 02:33:17.646618152 +1000
+++ stew-encrypted-backup/sql/backup/stream.cc	2008-06-26 13:47:41.031040513 +1000
@@ -1,5 +1,11 @@
 #include "../mysql_priv.h"
 
+#ifdef HAVE_YASSL
+#include <yassl.hpp>
+#include "crypto_wrapper.hpp"
+#include <my_crypt_io.h>
+#endif
+
 #include "backup_stream.h"
 #include "stream.h"
 
@@ -33,7 +39,7 @@ namespace backup {
 extern "C" int stream_write(void *instance, bstream_blob *buf, bstream_blob)
 {
   int fd;
-  int res;
+  int res= 0;
 
   DBUG_ENTER("backup::stream_write");
 
@@ -62,8 +68,13 @@ extern "C" int stream_write(void *instan
     {
       if (!zstream->avail_out)
       {
-        if (my_write(fd, s->zbuf, ZBUF_SIZE, MYF(MY_NABP)))
-          DBUG_RETURN(BSTREAM_ERROR);
+#ifdef HAVE_YASSL
+        if (s->m_cipher)
+          res= (howmuch==my_crypt_write(&(s->m_cfd), s->zbuf, ZBUF_SIZE))?0:-1;
+        else
+#endif
+          if (my_write(fd, s->zbuf, ZBUF_SIZE, MYF(MY_NABP)))
+            DBUG_RETURN(BSTREAM_ERROR);
         zstream->next_out= s->zbuf;
         zstream->avail_out= ZBUF_SIZE;
       }
@@ -74,8 +85,13 @@ extern "C" int stream_write(void *instan
   else
 #endif
   {
-    res= my_write(fd, buf->begin, howmuch,
-                  MY_NABP /* error if not all bytes written */ );
+#ifdef HAVE_YASSL
+    if (s->m_cipher)
+      res= (howmuch==my_crypt_write(&(s->m_cfd), buf->begin, howmuch))?0:-1;
+    else
+#endif
+      res= my_write(fd, buf->begin, howmuch,
+                    MY_NABP /* error if not all bytes written */ );
 
     if (res)
       DBUG_RETURN(BSTREAM_ERROR);
@@ -214,12 +230,13 @@ bool Stream::rewind()
 
 
 Output_stream::Output_stream(Logger &log, const ::String &name,
-                             bool with_compression)
+                             bool with_compression, yaSSL::BulkCipher *cipher)
   :Stream(log, name, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC)
 {
   m_with_compression= with_compression;
   stream.write= stream_write;
   m_block_size=0; // use default block size provided by the backup stram library
+  m_cipher= cipher;
 }
 
 /**
@@ -274,6 +291,13 @@ bool Output_stream::init()
   return TRUE;
 }
 
+int enc_filter(void* obj,char* obuf,char* ibuf,size_t sz)
+{
+  yaSSL::BulkCipher *c= (yaSSL::BulkCipher*)obj;
+  c->encrypt((yaSSL::byte*)obuf, (yaSSL::byte*)ibuf, sz);
+  return 0;
+}
+
 /**
   Open and initialize backup stream for writing.
 
@@ -288,6 +312,13 @@ bool Output_stream::open()
 
   bool ret= Stream::open();
 
+#ifdef HAVE_YASSL
+  int r= 0;
+  if(m_cipher)
+    r= my_crypt_fdopen(&m_cfd, m_fd, O_WRONLY, &enc_filter, (void*)m_cipher,
+                       m_cipher->get_blockSize());
+#endif
+
   if (!ret)
     return FALSE;
 
@@ -348,11 +379,25 @@ void Output_stream::close()
         m_log.report_error(ER_GET_ERRMSG, zerr, zstream.msg, "deflate");
         break;
       }
-      if (my_write(m_fd, zbuf, ZBUF_SIZE - zstream.avail_out,
-                   MYF(MY_NABP)))
+#ifdef HAVE_YASSL
+      if(m_cipher)
       {
-        m_log.report_error(ER_GET_ERRMSG, my_errno, "", "my_write");
-        break;
+        int sz= ZBUF_SIZE - zstream.avail_out;
+        if (my_crypt_write(&m_cfd, zbuf, sz)!=sz)
+        {
+          m_log.report_error(ER_GET_ERRMSG, my_errno, "", "my_write");
+          break;
+        }
+      }
+      else
+#endif
+      {
+        if (my_write(m_fd, zbuf, ZBUF_SIZE - zstream.avail_out,
+                     MYF(MY_NABP)))
+        {
+          m_log.report_error(ER_GET_ERRMSG, my_errno, "", "my_write");
+          break;
+        }
       }
       zstream.next_out= zbuf;
       zstream.avail_out= ZBUF_SIZE;
@@ -362,6 +407,14 @@ void Output_stream::close()
     my_free(zbuf, MYF(0));
   }
 #endif
+
+#ifdef HAVE_YASSL
+  if(m_cipher)
+  {
+    my_crypt_close(&m_cfd, 0);
+  }
+#endif
+
   Stream::close();
 }
 
Index: stew-encrypted-backup/sql/backup/stream.h
===================================================================
--- stew-encrypted-backup.orig/sql/backup/stream.h	2008-06-26 02:33:17.818625434 +1000
+++ stew-encrypted-backup/sql/backup/stream.h	2008-06-26 13:42:12.159050036 +1000
@@ -11,6 +11,9 @@
 #include <zlib.h>
 #endif
 
+#include <crypto_wrapper.hpp>
+#include <my_crypt_io.h>
+
 /**
   @file
 
@@ -64,7 +67,12 @@ struct fd_stream: public backup_stream
   z_stream zstream;
   uchar *zbuf;
 #endif
-  
+
+#ifdef HAVE_YASSL
+  yaSSL::BulkCipher *m_cipher;
+  struct my_crypt_fd m_cfd;
+#endif
+
   fd_stream() :m_fd(-1), bytes(0) {}
 };
 
@@ -110,7 +118,7 @@ class Output_stream:
 {
  public:
 
-  Output_stream(Logger&, const ::String&, bool);
+  Output_stream(Logger&, const ::String&, bool, yaSSL::BulkCipher*);
 
   bool open();
   void close();
Index: stew-encrypted-backup/sql/Makefile.am
===================================================================
--- stew-encrypted-backup.orig/sql/Makefile.am	2008-06-25 01:43:36.216194493 +1000
+++ stew-encrypted-backup/sql/Makefile.am	2008-06-26 03:09:28.115656988 +1000
@@ -46,15 +46,15 @@ SUPPORTING_LIBS =	$(top_builddir)/vio/li
 			$(top_builddir)/dbug/libdbug.a \
 			$(top_builddir)/regex/libregex.a \
 			$(top_builddir)/strings/libmystrings.a
-mysqld_DEPENDENCIES=	@mysql_plugin_libs@ $(SUPPORTING_LIBS) backup/libbackup.la libndb.la
+mysqld_DEPENDENCIES=	backup/libbackup.la @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la
 LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
 mysqld_LDADD =		libndb.la \
+			backup/libbackup.la \
 			@MYSQLD_EXTRA_LDFLAGS@ \
 			@pstack_libs@ $(libevent_libs) \
 			@mysql_plugin_libs@ \
 			$(LDADD)  $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
-			$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@ \
-			backup/libbackup.la
+			$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
 
 noinst_HEADERS =	item.h item_func.h item_sum.h item_cmpfunc.h \
 			item_strfunc.h item_timefunc.h \
Index: stew-encrypted-backup/mysql-test/t/backup_encrypted.test
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ stew-encrypted-backup/mysql-test/t/backup_encrypted.test	2008-06-26 13:42:12.195064313
+1000
@@ -0,0 +1,13 @@
+create table t1 (a int);
+insert into t1 values (1),(2),(42),(3),(4),(1);
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ insert into t1 select * from t1; 
+ BACKUP DATABASE test TO 'test42.ba' ENCRYPTION_ALGORITHM=aes ENCRYPTION_KEYSIZE=128
PASSWORD='pants';
Index: stew-encrypted-backup/mysql-test/r/backup_encrypted.result
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ stew-encrypted-backup/mysql-test/r/backup_encrypted.result	2008-06-26
03:09:28.151618373 +1000
@@ -0,0 +1,15 @@
+create table t1 (a int);
+insert into t1 values (1),(2),(42),(3),(4),(1);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+BACKUP DATABASE test TO 'test42.ba' ENCRYPTION_ALGORITHM=aes ENCRYPTION_KEYSIZE=128
PASSWORD='pants';
+backup_id
+1

-- 
Stewart Smith
Thread
[patch 00/10] Encrypted online backupstewart30 Jun
  • [patch 01/10] Bug #37654 lex backup_compression not being set when no compressionstewart30 Jun
  • [patch 02/10] Basic backup and restore teststewart30 Jun
  • [patch 03/10] WL4271: Encrypted Online Backup: add symbols to parserstewart30 Jun
  • [patch 05/10] WL4271 Encrypted online backup: display correct message for no yassl/not implementedstewart30 Jun
  • [patch 04/10] WL4271 Encrypted online backup: pass encryption information to backup kernel, return ER_NOT_SUPPORTED_YETstewart30 Jun
  • [patch 06/10] WL4271 Encrypted online backup: my_crypt_io: an IO abstraction allowing for filteringstewart30 Jun
  • [patch 08/10] WL4271 Encrypted online backup: encrypted restore syntaxstewart30 Jun
  • [patch 07/10] WL4271 Encrytped backup: implement basic AES Encyrptionstewart30 Jun
  • [patch 09/10] WL4271 Encrypted online backup: pass restore options to backup kernelstewart30 Jun
  • [patch 10/10] WL4271 Encrypted online backup: decrypt encrytped backupstewart30 Jun