Commit b903e65b authored by yiwenshao's avatar yiwenshao

add ASHE and ASHEFactory, the initial version is the same as HOM, the next step…

add ASHE and ASHEFactory, the initial version is the same as HOM, the next step is to replace it with ASHE
parent ccf76a9b
...@@ -60,6 +60,40 @@ using namespace NTL; ...@@ -60,6 +60,40 @@ using namespace NTL;
*/ */
//helper functions//
static ZZ
ItemIntToZZ(const Item &ptext)
{
const ulonglong val = RiboldMYSQL::val_uint(ptext);
return ZZFromUint64(val);
}
static Item *
ZZToItemInt(const ZZ &val)
{
const ulonglong v = uint64FromZZ(val);
return new (current_thd->mem_root) Item_int(v);
}
static Item *
ZZToItemStr(const ZZ &val)
{
const std::string &str = StringFromZZ(val);
Item * const newit =
new (current_thd->mem_root) Item_string(make_thd_string(str),
str.length(),
&my_charset_bin);
newit->name = NULL; //no alias
return newit;
}
static ZZ
ItemStrToZZ(const Item &i)
{
return ZZFromString(ItemToString(i));
}
//============= FACTORIES ==========================// //============= FACTORIES ==========================//
...@@ -129,6 +163,15 @@ public: ...@@ -129,6 +163,15 @@ public:
}; };
class ASHEFactory : public LayerFactory {
public:
static std::unique_ptr<EncLayer>
create(const Create_field &cf, const std::string &key);
static std::unique_ptr<EncLayer>
deserialize(unsigned int id, const SerialLayer &serial);
};
/*===================== SERIALIZE Helpers =============================*/ /*===================== SERIALIZE Helpers =============================*/
struct SerialLayer { struct SerialLayer {
...@@ -1377,7 +1420,7 @@ OPE_str::decrypt(const Item &ctext, uint64_t IV) const ...@@ -1377,7 +1420,7 @@ OPE_str::decrypt(const Item &ctext, uint64_t IV) const
} }
/**************** HOM ***************************/ /**************** HOMFactory ***************************/
std::unique_ptr<EncLayer> std::unique_ptr<EncLayer>
HOMFactory::create(const Create_field &cf, const std::string &key) HOMFactory::create(const Create_field &cf, const std::string &key)
...@@ -1398,40 +1441,38 @@ HOMFactory::deserialize(unsigned int id, const SerialLayer &serial) { ...@@ -1398,40 +1441,38 @@ HOMFactory::deserialize(unsigned int id, const SerialLayer &serial) {
return std::unique_ptr<EncLayer>(new HOM(id, serial.layer_info)); return std::unique_ptr<EncLayer>(new HOM(id, serial.layer_info));
} }
static ZZ
ItemIntToZZ(const Item &ptext)
{
const ulonglong val = RiboldMYSQL::val_uint(ptext);
return ZZFromUint64(val);
}
static Item * /**************************************************************************
ZZToItemInt(const ZZ &val) ****************************ASHEFactory************************************
{ ***************************************************************************
const ulonglong v = uint64FromZZ(val); */
return new (current_thd->mem_root) Item_int(v);
}
static Item *
ZZToItemStr(const ZZ &val) std::unique_ptr<EncLayer>
ASHEFactory::create(const Create_field &cf, const std::string &key)
{ {
const std::string &str = StringFromZZ(val); if (cf.sql_type == MYSQL_TYPE_DECIMAL
Item * const newit = || cf.sql_type == MYSQL_TYPE_NEWDECIMAL) {
new (current_thd->mem_root) Item_string(make_thd_string(str), FAIL_TextMessageError("decimal support is broken");
str.length(), }
&my_charset_bin);
newit->name = NULL; //no alias
return newit; return std::unique_ptr<EncLayer>(new ASHE(cf, key));
} }
static ZZ std::unique_ptr<EncLayer>
ItemStrToZZ(const Item &i) ASHEFactory::deserialize(unsigned int id, const SerialLayer &serial) {
{ if (serial.name == "ASHE_dec") {
return ZZFromString(ItemToString(i)); FAIL_TextMessageError("decimal support broken");
}
return std::unique_ptr<EncLayer>(new ASHE(id, serial.layer_info));
} }
/****************************************************************************
*******************************HOM*******************************************
*****************************************************************************
*/
HOM::HOM(const Create_field &f, const std::string &seed_key) HOM::HOM(const Create_field &f, const std::string &seed_key)
: seed_key(seed_key), sk(NULL), waiting(true) : seed_key(seed_key), sk(NULL), waiting(true)
{} {}
...@@ -1543,6 +1584,9 @@ HOM::~HOM() { ...@@ -1543,6 +1584,9 @@ HOM::~HOM() {
delete sk; delete sk;
} }
/******* SEARCH **************************/ /******* SEARCH **************************/
Search::Search(const Create_field &f, const std::string &seed_key) Search::Search(const Create_field &f, const std::string &seed_key)
...@@ -1765,3 +1809,120 @@ const std::vector<udf_func*> udf_list = { ...@@ -1765,3 +1809,120 @@ const std::vector<udf_func*> udf_list = {
&u_cryptdb_version &u_cryptdb_version
}; };
/************************************************ASHE********************************************/
ASHE::ASHE(const Create_field &f, const std::string &seed_key)
: seed_key(seed_key), sk(NULL), waiting(true)
{}
ASHE::ASHE(unsigned int id, const std::string &serial)
: EncLayer(id), seed_key(serial), sk(NULL), waiting(true)
{}
Create_field *
ASHE::newCreateField(const Create_field &cf,
const std::string &anonname) const{
return arrayCreateFieldHelper(cf, 2*nbits/BITS_PER_BYTE,
MYSQL_TYPE_VARCHAR, anonname,
&my_charset_bin);
}
//if first, use seed key to generate
void
ASHE::unwait() const {
const std::unique_ptr<streamrng<arc4>>
prng(new streamrng<arc4>(seed_key));
sk = new Paillier_priv(Paillier_priv::keygen(prng.get(), nbits));
waiting = false;
}
Item *
ASHE::encrypt(const Item &ptext, uint64_t IV) const{
if (true == waiting) {
this->unwait();
}
const ZZ enc = sk->encrypt(ItemIntToZZ(ptext));
return ZZToItemStr(enc);
}
Item *
ASHE::decrypt(const Item &ctext, uint64_t IV) const
{
if (true == waiting) {
this->unwait();
}
const ZZ enc = ItemStrToZZ(ctext);
const ZZ dec = sk->decrypt(enc);
LOG(encl) << "ASHE ciph " << enc << "---->" << dec;
TEST_Text(NumBytes(dec) <= 8,
"Summation produced an integer larger than 64 bits");
return ZZToItemInt(dec);
}
//static udf_func u_sum_a = {
// LEXSTRING("cryptdb_agg"),
// STRING_RESULT,
// UDFTYPE_AGGREGATE,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// 0L,
//};
//
//static udf_func u_sum_f = {
// LEXSTRING("cryptdb_func_add_set"),
// STRING_RESULT,
// UDFTYPE_FUNCTION,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// NULL,
// 0L,
//};
//
Item *
ASHE::sumUDA(Item *const expr) const
{
if (true == waiting) {
this->unwait();
}
List<Item> l;
l.push_back(expr);
l.push_back(ZZToItemStr(sk->hompubkey()));
return new (current_thd->mem_root) Item_func_udf_str(&u_sum_a, l);
}
Item *
ASHE::sumUDF(Item *const i1, Item *const i2) const
{
if (true == waiting) {
this->unwait();
}
List<Item> l;
l.push_back(i1);
l.push_back(i2);
l.push_back(ZZToItemStr(sk->hompubkey()));
return new (current_thd->mem_root) Item_func_udf_str(&u_sum_f, l);
}
ASHE::~ASHE() {
delete sk;
}
...@@ -117,6 +117,40 @@ private: ...@@ -117,6 +117,40 @@ private:
mutable bool waiting; mutable bool waiting;
}; };
class ASHE : public EncLayer {
public:
ASHE(const Create_field &cf, const std::string &seed_key);
// serialize and deserialize
std::string doSerialize() const {return seed_key;}
ASHE(unsigned int id, const std::string &serial);
~ASHE();
SECLEVEL level() const {return SECLEVEL::ASHE;}
std::string name() const {return "ASHE";}
Create_field * newCreateField(const Create_field &cf,
const std::string &anonname = "")
const;
//TODO needs multi encrypt and decrypt
Item *encrypt(const Item &p, uint64_t IV) const;
Item * decrypt(const Item &c, uint64_t IV) const;
//expr is the expression (e.g. a field) over which to sum
Item *sumUDA(Item *const expr) const;
Item *sumUDF(Item *const i1, Item *const i2) const;
protected:
std::string const seed_key;
static const uint nbits = 1024;
mutable Paillier_priv * sk;
private:
void unwait() const;
mutable bool waiting;
};
class Search : public EncLayer { class Search : public EncLayer {
public: public:
Search(const Create_field &cf, const std::string &seed_key); Search(const Create_field &cf, const std::string &seed_key);
......
...@@ -66,65 +66,65 @@ void myRewriteInsertHelper(const Item &i, const FieldMeta &fm, Analysis &a, ...@@ -66,65 +66,65 @@ void myRewriteInsertHelper(const Item &i, const FieldMeta &fm, Analysis &a,
} }
static std::string getInsertResults(Analysis a,LEX* lex){ static std::string getInsertResults(Analysis a,LEX* lex){
LEX *const new_lex = copyWithTHD(lex); LEX *const new_lex = copyWithTHD(lex);
const std::string &table = const std::string &table =
lex->select_lex.table_list.first->table_name; lex->select_lex.table_list.first->table_name;
const std::string &db_name = const std::string &db_name =
lex->select_lex.table_list.first->db; lex->select_lex.table_list.first->db;
//from databasemeta to tablemeta. //from databasemeta to tablemeta.
const TableMeta &tm = a.getTableMeta(db_name, table); const TableMeta &tm = a.getTableMeta(db_name, table);
//rewrite table name //rewrite table name
new_lex->select_lex.table_list.first = new_lex->select_lex.table_list.first =
rewrite_table_list(lex->select_lex.table_list.first, a); rewrite_table_list(lex->select_lex.table_list.first, a);
std::vector<FieldMeta *> fmVec; std::vector<FieldMeta *> fmVec;
std::vector<Item *> implicit_defaults; std::vector<Item *> implicit_defaults;
// No field list, use the table order. // No field list, use the table order.
assert(fmVec.empty()); assert(fmVec.empty());
std::vector<FieldMeta *> fmetas = tm.orderedFieldMetas(); std::vector<FieldMeta *> fmetas = tm.orderedFieldMetas();
fmVec.assign(fmetas.begin(), fmetas.end()); fmVec.assign(fmetas.begin(), fmetas.end());
if (lex->many_values.head()) { if (lex->many_values.head()) {
//start processing many values //start processing many values
auto it = List_iterator<List_item>(lex->many_values); auto it = List_iterator<List_item>(lex->many_values);
List<List_item> newList; List<List_item> newList;
for (;;) { for (;;) {
List_item *const li = it++; List_item *const li = it++;
if (!li) { if (!li) {
break; break;
} }
List<Item> *const newList0 = new List<Item>(); List<Item> *const newList0 = new List<Item>();
if (li->elements != fmVec.size()) { if (li->elements != fmVec.size()) {
TEST_TextMessageError(0 == li->elements TEST_TextMessageError(0 == li->elements
&& NULL == lex->field_list.head(), && NULL == lex->field_list.head(),
"size mismatch between fields" "size mismatch between fields"
" and values!"); " and values!");
} else { } else {
auto it0 = List_iterator<Item>(*li); auto it0 = List_iterator<Item>(*li);
auto fmVecIt = fmVec.begin(); auto fmVecIt = fmVec.begin();
for (;;) { for (;;) {
const Item *const i = it0++; const Item *const i = it0++;
assert(!!i == (fmVec.end() != fmVecIt)); assert(!!i == (fmVec.end() != fmVecIt));
if (!i) { if (!i) {
break; break;
}
//fetch values, and use fieldMeta to facilitate rewrite
//every filed should be encrypted with onions of encryption
myRewriteInsertHelper(*i, **fmVecIt, a, newList0);
++fmVecIt;
}
for (auto def_it : implicit_defaults) {
newList0->push_back(def_it);
} }
//fetch values, and use fieldMeta to facilitate rewrite
//every filed should be encrypted with onions of encryption
myRewriteInsertHelper(*i, **fmVecIt, a, newList0);
++fmVecIt;
}
for (auto def_it : implicit_defaults) {
newList0->push_back(def_it);
} }
newList.push_back(newList0);
} }
new_lex->many_values = newList; newList.push_back(newList0);
} }
return lexToQuery(*new_lex); new_lex->many_values = newList;
}
return lexToQuery(*new_lex);
} }
......
...@@ -319,10 +319,10 @@ init_onions_layout(const AES_KEY *const m_key, FieldMeta *const fm, ...@@ -319,10 +319,10 @@ init_onions_layout(const AES_KEY *const m_key, FieldMeta *const fm,
LOG(cdb_v) << "adding onion layer " << onion_name LOG(cdb_v) << "adding onion layer " << onion_name
<< " for " << fm->getFieldName(); << " for " << fm->getFieldName();
} }
return true; return true;
} }
/*fieldmeta that is newed*/
FieldMeta::FieldMeta(const Create_field &field, FieldMeta::FieldMeta(const Create_field &field,
const AES_KEY * const m_key, const AES_KEY * const m_key,
SECURITY_RATING sec_rating, SECURITY_RATING sec_rating,
...@@ -408,10 +408,10 @@ OnionMeta *FieldMeta::getOnionMeta(onion o) const ...@@ -408,10 +408,10 @@ OnionMeta *FieldMeta::getOnionMeta(onion o) const
return getChild(OnionMetaKey(o)); return getChild(OnionMetaKey(o));
} }
/*determine the onion layout when creating the fieldmeta*/
onionlayout FieldMeta::determineOnionLayout(const AES_KEY *const m_key, onionlayout FieldMeta::determineOnionLayout(const AES_KEY *const m_key,
const Create_field &f, const Create_field &f,
SECURITY_RATING sec_rating) SECURITY_RATING sec_rating){
{
if (sec_rating == SECURITY_RATING::PLAIN) { if (sec_rating == SECURITY_RATING::PLAIN) {
// assert(!m_key); // assert(!m_key);
return PLAIN_ONION_LAYOUT; return PLAIN_ONION_LAYOUT;
...@@ -419,16 +419,15 @@ onionlayout FieldMeta::determineOnionLayout(const AES_KEY *const m_key, ...@@ -419,16 +419,15 @@ onionlayout FieldMeta::determineOnionLayout(const AES_KEY *const m_key,
TEST_TextMessageError(m_key, TEST_TextMessageError(m_key,
"Should be using SECURITY_RATING::PLAIN!"); "Should be using SECURITY_RATING::PLAIN!");
if (false == encryptionSupported(f)) { if (false == encryptionSupported(f)) {
//TEST_TextMessageError(SECURITY_RATING::SENSITIVE != sec_rating, return PLAIN_ONION_LAYOUT;//do not report error here
// "A SENSITIVE security rating requires the"
// " field to be supported with cryptography!");
return PLAIN_ONION_LAYOUT;
} }
// Don't encrypt AUTO_INCREMENT. // Don't encrypt AUTO_INCREMENT.
if (Field::NEXT_NUMBER == f.unireg_check) { if (Field::NEXT_NUMBER == f.unireg_check) {
return PLAIN_ONION_LAYOUT; return PLAIN_ONION_LAYOUT;
} }
/*we only support sensitive rating here*/
if (SECURITY_RATING::SENSITIVE == sec_rating) { if (SECURITY_RATING::SENSITIVE == sec_rating) {
if (true == isMySQLTypeNumeric(f)) { if (true == isMySQLTypeNumeric(f)) {
return NUM_ONION_LAYOUT; return NUM_ONION_LAYOUT;
......
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