Commit eae23d6b authored by unknown's avatar unknown

des_encrypt()/des_decrypt() work much better now

parent b88341bb
...@@ -202,127 +202,109 @@ void Item_func_concat::fix_length_and_dec() ...@@ -202,127 +202,109 @@ void Item_func_concat::fix_length_and_dec()
} }
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
#define ascii_to_bin(c) ((c)<=57 ? (c)-46 : (c)<=90 ? (c)-53 : (c)-59)
String *Item_func_des_encrypt::val_str(String *str) String *Item_func_des_encrypt::val_str(String *str)
{ {
String *res =args[0]->val_str(str); String *res =args[0]->val_str(str);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
des_key_schedule ks1, ks2, ks3; des_key_schedule ks1, ks2, ks3;
des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
union { union {
des_cblock allkeys[3]; des_cblock allkeys[3]; // 24 bytes (168 bits) total
des_cblock key1; des_cblock key1, key2, key3; // 8 bytes each
des_cblock key2;
des_cblock key3;
} key; } key;
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0; return 0;
if (res->length() == 0) if (res->length() == 0)
return &empty_string; return &empty_string;
String *in_str=args[1]->val_str(&tmp_value); String *keystr=args[1]->val_str(&tmp_value);
char *tmp=my_malloc(res->length()+8, MYF(0)); int32 mode=0;
DBUG_PRINT("info",("DES: key string='%s'",in_str->c_ptr())); if(arg_count == 3 && !args[2]->null_value)
DBUG_PRINT("info",("DES: data string='%s'",res->c_ptr())); mode=args[2]->val_int();
DBUG_PRINT("info",("DES: cipher pointer='%x'",EVP_get_cipherbyname("DES-EDE3-CBC"))); // We make good 24-byte (168 bit) key from given plaintext key with MD5
EVP_BytesToKey(EVP_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL, EVP_BytesToKey(EVP_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL,
(unsigned char *)in_str->c_ptr(), (uchar *)keystr->c_ptr(),
in_str->length(),1,(uchar *)&key.allkeys,ivec); keystr->length(),1,(uchar *)&key.allkeys,ivec);
// Here we set all 64-bit (56 actually) one by one
des_set_key_unchecked(&key.key1,ks1); des_set_key_unchecked(&key.key1,ks1);
des_set_key_unchecked(&key.key2,ks2); des_set_key_unchecked(&key.key2,ks2);
des_set_key_unchecked(&key.key3,ks3); des_set_key_unchecked(&key.key3,ks3);
DBUG_PRINT("info",("DES: checkpoint")); /* The problem: DES algorithm requires original data to be in 8-bytes
* chunks. Missing bytes get filled with zeros and result of encryption
* can be up to 7 bytes longer than original string. When decrypted,
* we do not know the size of original string :(
* We add one byte with value 0x0..0x7 to original plaintext marking
* change of string length */
uchar tail=8-(res->length() % 8); // 1..8
for(int i=0 ; i < (tail-1) ; ++i) res->append('*');
res->append(tail-1); // Write tail length 0..7 to last pos
// Real encryption
des_ede3_cbc_encrypt( des_ede3_cbc_encrypt(
(const unsigned char*)(res->c_ptr()) , (const uchar*)(res->c_ptr()),
(uchar*)tmp, (uchar*)(res->c_ptr()),
res->length(), res->length(), ks1, ks2, ks3, &ivec, TRUE);
ks1, ks2, ks3, &ivec, TRUE); if(mode) {
res->length(res->length()+8-(res->length() % 8)); // In case of ASCII mode we should convert binary string into ASCII
DBUG_PRINT("info",("DES: checkpoint"));
DBUG_PRINT("info",("DES: string length='%d' versus '%d'",res->length(),strlen(res->c_ptr())));
DBUG_PRINT("info",("DES: crypted data string='%s'",tmp));
str->set((const char*)0,(uint)0); str->set((const char*)0,(uint)0);
for(uint i=0 ; i < res->length() ; ++i) for(uint i=0 ; i < res->length() ; ++i) {
{ str->append(bin_to_ascii((uchar)res->c_ptr()[i] & 0x3f));
str->append(tmp[i]); str->append(bin_to_ascii(((uchar)res->c_ptr()[i] >> 5 ) & 0x3f));
// str->append(bin_to_ascii(tmp[i] & 0x3f)); }
// str->append(bin_to_ascii((tmp[i] >> 5) & 0x3f)); return str;
} } else
DBUG_PRINT("info",("DES: crypted data plain string='%s'",str->c_ptr())); return res;
str->copy();
DBUG_PRINT("info",("DES: crypted data plain string='%s'",str->c_ptr()));
my_free(tmp,MYF(0));
return str;
#else #else
null_value=1; null_value=1;
return 0; return 0;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
} }
String *Item_func_des_decrypt::val_str(String *str) String *Item_func_des_decrypt::val_str(String *str)
{ {
String *res =args[0]->val_str(str); String *res =args[0]->val_str(str);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
des_key_schedule ks1, ks2, ks3; des_key_schedule ks1, ks2, ks3;
des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
union { union {
des_cblock allkeys[3]; des_cblock allkeys[3]; // 24 bytes total
des_cblock key1; des_cblock key1, key2, key3; // 8 bytes each
des_cblock key2;
des_cblock key3;
} key; } key;
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0; return 0;
if (res->length() == 0) if (res->length() == 0)
return &empty_string; return &empty_string;
String *in_str=args[1]->val_str(&tmp_value); String *keystr=args[1]->val_str(&tmp_value);
char *tmp=my_malloc(res->length()+8, MYF(0)); int32 mode=0;
DBUG_PRINT("info",("DES: key string='%s'",in_str->c_ptr())); if(arg_count == 3 && !args[2]->null_value)
DBUG_PRINT("info",("DES: data string='%s'",res->c_ptr())); mode=args[2]->val_int();
/* int EVP_BytesToKey(const EVP_CIPHER *type, EVP_MD *md, // We make good 24-byte (168 bit) key from given plaintext key with MD5
const unsigned char *salt, const unsigned char *data, int datal,
int count, unsigned char *key, unsigned char *iv)
*/
EVP_BytesToKey(EVP_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL, EVP_BytesToKey(EVP_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL,
(unsigned char *)in_str->c_ptr(), (uchar *)keystr->c_ptr(),
in_str->length(),1,(uchar *)&key.allkeys,ivec); keystr->length(),1,(uchar *)&key.allkeys,ivec);
// Here we set all 64-bit keys (56 effective) one by one
des_set_key_unchecked(&key.key1,ks1); des_set_key_unchecked(&key.key1,ks1);
des_set_key_unchecked(&key.key2,ks2); des_set_key_unchecked(&key.key2,ks2);
des_set_key_unchecked(&key.key3,ks3); des_set_key_unchecked(&key.key3,ks3);
DBUG_PRINT("info",("DES: cipher pointer='%x'",EVP_get_cipherbyname("DES-EDE3-CBC"))); str->set((const char*)0,(uint)0);
EVP_BytesToKey(EVP_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL, if(mode) {
(unsigned char *)in_str->c_ptr(), for(uint i=0 ; i < res->length() ; i+=2) {
in_str->length(),1,(uchar *)&key.allkeys,ivec); str->append((ascii_to_bin(res->c_ptr()[i]))
| (ascii_to_bin(res->c_ptr()[i+1]) << 5 ));
DBUG_PRINT("info",("DES: checkpoint"));
des_ede3_cbc_encrypt(
(const unsigned char*)(res->c_ptr()) ,
(uchar*)tmp,
res->length(),
ks1, ks2, ks3, &ivec, FALSE);
DBUG_PRINT("info",("DES: checkpoint"));
DBUG_PRINT("info",("DES: string length='%d' versus '%d'",res->length(),strlen(res->c_ptr())));
DBUG_PRINT("info",("DES: crypted data string='%s'",tmp));
str->set((const char*)0,(uint)0);
for(uint i=0 ; i < res->length() ; ++i)
{
str->append(tmp[i]);
// str->append(bin_to_ascii(tmp[i] & 0x3f));
// str->append(bin_to_ascii((tmp[i] >> 5) & 0x3f));
} }
DBUG_PRINT("info",("DES: crypted data plain string='%s'",str->c_ptr())); } else
str->copy(); str->copy(res->c_ptr());
DBUG_PRINT("info",("DES: crypted data plain string='%s'",str->c_ptr())); // Real decryption
my_free(tmp,MYF(0)); des_ede3_cbc_encrypt(
return str; (const uchar*)(str->c_ptr()),
(uchar*)(res->c_ptr()),
str->length(),
ks1, ks2, ks3, &ivec, FALSE);
uchar tail=(res->c_ptr()[str->length()-1]) & 0x7;
res->length(str->length()-tail-1);
return res;
#else #else
null_value=1; null_value=1;
return 0; return 0;
...@@ -331,7 +313,6 @@ String *Item_func_des_decrypt::val_str(String *str) ...@@ -331,7 +313,6 @@ String *Item_func_des_decrypt::val_str(String *str)
/* /*
** concat with separator. First arg is the separator ** concat with separator. First arg is the separator
** concat_ws takes at least two arguments. ** concat_ws takes at least two arguments.
......
...@@ -228,8 +228,10 @@ class Item_func_des_encrypt :public Item_str_func ...@@ -228,8 +228,10 @@ class Item_func_des_encrypt :public Item_str_func
public: public:
Item_func_des_encrypt(Item *a) :Item_str_func(a) {} Item_func_des_encrypt(Item *a) :Item_str_func(a) {}
Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {} Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
Item_func_des_encrypt(Item *a, Item *b, Item *c): Item_str_func(a,b,c) {}
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = 13; } void fix_length_and_dec() { maybe_null=1; max_length = 13; }
const char *func_name() const { return "des_encrypt"; }
}; };
class Item_func_des_decrypt :public Item_str_func class Item_func_des_decrypt :public Item_str_func
...@@ -238,8 +240,10 @@ class Item_func_des_decrypt :public Item_str_func ...@@ -238,8 +240,10 @@ class Item_func_des_decrypt :public Item_str_func
public: public:
Item_func_des_decrypt(Item *a) :Item_str_func(a) {} Item_func_des_decrypt(Item *a) :Item_str_func(a) {}
Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {} Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
Item_func_des_decrypt(Item *a, Item *b, Item *c): Item_str_func(a,b,c) {}
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = 13; } void fix_length_and_dec() { maybe_null=1; max_length = 13; }
const char *func_name() const { return "des_decrypt"; }
}; };
class Item_func_encrypt :public Item_str_func class Item_func_encrypt :public Item_str_func
......
...@@ -1612,8 +1612,12 @@ simple_expr: ...@@ -1612,8 +1612,12 @@ simple_expr:
{ $$= new Item_func_decode($3,$5.str); } { $$= new Item_func_decode($3,$5.str); }
| ENCODE_SYM '(' expr ',' TEXT_STRING ')' | ENCODE_SYM '(' expr ',' TEXT_STRING ')'
{ $$= new Item_func_encode($3,$5.str); } { $$= new Item_func_encode($3,$5.str); }
| DES_ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_des_encrypt($3,$5); } | DES_ENCRYPT '(' expr ')' { $$= new Item_func_des_encrypt($3); }
| DES_DECRYPT '(' expr ',' expr ')' { $$= new Item_func_des_decrypt($3,$5); } | DES_DECRYPT '(' expr ')' { $$= new Item_func_des_decrypt($3); }
| DES_ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_des_encrypt($3,$5); }
| DES_DECRYPT '(' expr ',' expr ')' { $$= new Item_func_des_decrypt($3,$5); }
| DES_ENCRYPT '(' expr ',' expr ',' expr ')' { $$= new Item_func_des_encrypt($3,$5,$7); }
| DES_DECRYPT '(' expr ',' expr ',' expr ')' { $$= new Item_func_des_decrypt($3,$5,$7); }
| EXPORT_SET '(' expr ',' expr ',' expr ')' | EXPORT_SET '(' expr ',' expr ',' expr ')'
{ $$= new Item_func_export_set($3, $5, $7); } { $$= new Item_func_export_set($3, $5, $7); }
| EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')' | EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')'
......
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