Loading mysql-test/r/func_encrypt.result 0 → 100644 +6.8 KiB File added.No diff preview for this file type. View file mysql-test/t/func_encrypt.test 0 → 100644 +46 −0 Original line number Diff line number Diff line -- source include/have_openssl.inc use test; drop table if exists x; create table x (x blob); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('a','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','a')); insert into x values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab')); insert into x values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc')); insert into x values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd')); insert into x values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde')); insert into x values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef')); insert into x values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg')); insert into x values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh')); insert into x values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi')); insert into x values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij')); insert into x values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('red fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('over the lazy brown dog','sabakala')); insert into x values (des_encrypt('the lazy brown dog','sabakala')); insert into x values (des_encrypt('lazy brown dog','sabakala')); insert into x values (des_encrypt('brown dog','sabakala')); insert into x values (des_encrypt('dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); select * from x; select des_decrypt(x,'sabakala') from x; #drop table x; sql/item_strfunc.cc +74 −62 Original line number Diff line number Diff line Loading @@ -204,56 +204,65 @@ 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 ascii_to_bin(c) ((c)<=57 ? (c)-46 : (c)<=90 ? (c)-53 : (c)-59) /* Function des_encrypt() by tonu@spam.ee Works only if compiled with OpenSSL library support. Output always starts with magic char "1" and all encrypted output is encoded into ASCII-protected container. Original input is returned as output if input string begins with magic "1". Credit card number always begin with 4,5 or 6. Encryption result is longer than original by formula: new_length=(8-(original_length % 8))*2+1 */ String *Item_func_des_encrypt::val_str(String *str) { String *res =args[0]->val_str(str); #ifdef HAVE_OPENSSL des_key_schedule ks1, ks2, ks3; des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; union { des_cblock allkeys[3]; // 24 bytes (168 bits) total struct { des_cblock key1, key2, key3; // 8 bytes each } key; } keyblock; if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) return &empty_string; if(res->c_ptr()[0]!='1') { // Skip encryption if already encrypted String *keystr=args[1]->val_str(&tmp_value); int32 mode=0; if(arg_count == 3 && !args[2]->null_value) mode=args[2]->val_int(); // 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, /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, (uchar *)keystr->c_ptr(), 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.key2,ks2); des_set_key_unchecked(&key.key3,ks3); /* 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( (int)keystr->length(),1,(uchar *)&keyblock,ivec); des_set_key_unchecked(&keyblock.key1,ks1); // Here we set all 64-bit keys des_set_key_unchecked(&keyblock.key2,ks2); // (56 effective) one by one des_set_key_unchecked(&keyblock.key3,ks3); /* 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= 7-( res->length() %8); // 0..7 marking real offsets 1..8 for(int i=0 ; i < tail ; ++i) res->append('*'); res->append(tail); // Write tail length 0..7 to last pos str->length(res->length()); des_ede3_cbc_encrypt( // Real encryption (const uchar*)(res->c_ptr()), (uchar*)(res->c_ptr()), (uchar*)(str->c_ptr()), res->length(), ks1, ks2, ks3, &ivec, TRUE); if(mode) { // In case of ASCII mode we should convert binary string into ASCII str->set((const char*)0,(uint)0); for(uint i=0 ; i < res->length() ; ++i) { str->append(bin_to_ascii((uchar)res->c_ptr()[i] & 0x3f)); str->append(bin_to_ascii(((uchar)res->c_ptr()[i] >> 5 ) & 0x3f)); res->set((const char*)"1",(uint)1); for(uint i=0 ; i < str->length() ; ++i) { res->append(bin_to_ascii((uchar)str->c_ptr()[i] & 0x3f)); res->append(bin_to_ascii(((uchar)str->c_ptr()[i] >> 5 ) & 0x3f)); } } return str; } else return res; #else null_value=1; Loading @@ -267,43 +276,46 @@ String *Item_func_des_decrypt::val_str(String *str) #ifdef HAVE_OPENSSL des_key_schedule ks1, ks2, ks3; des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; union { des_cblock allkeys[3]; // 24 bytes total struct { des_cblock key1, key2, key3; // 8 bytes each } key; } keyblock; if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) return &empty_string; if(res->c_ptr()[0]=='1') // Skip decryption if not encrypted { str->set((const char*)0,(uint)0); for(uint i=1 ; i < res->length() ; i+=2) { str->append((ascii_to_bin(res->c_ptr()[i])) | (ascii_to_bin(res->c_ptr()[i+1]) << 5 )); } String *keystr=args[1]->val_str(&tmp_value); int32 mode=0; if(arg_count == 3 && !args[2]->null_value) mode=args[2]->val_int(); // 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, /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, (uchar *)keystr->c_ptr(), 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.key2,ks2); des_set_key_unchecked(&key.key3,ks3); str->set((const char*)0,(uint)0); if(mode) { for(uint i=0 ; i < res->length() ; i+=2) { str->append((ascii_to_bin(res->c_ptr()[i])) | (ascii_to_bin(res->c_ptr()[i+1]) << 5 )); } } else str->copy(res->c_ptr()); // Real decryption des_ede3_cbc_encrypt( (int)keystr->length(),1,(uchar *)&keyblock,ivec); des_set_key_unchecked(&keyblock.key1,ks1); // Here we set all 64-bit keys des_set_key_unchecked(&keyblock.key2,ks2); // (56 effective) one by one des_set_key_unchecked(&keyblock.key3,ks3); res->length(str->length()); des_ede3_cbc_encrypt( // Real decryption (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); uchar tail=(res->c_ptr()[res->length()-1]) & 0x7; if((res->length() > ((uint)1+tail))) // We should avoid negative length res->length(res->length()-1-tail); // (can happen with wrong key) } return res; #else null_value=1; Loading sql/item_strfunc.h +2 −2 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ class Item_func_des_encrypt :public Item_str_func 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 *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; } const char *func_name() const { return "des_encrypt"; } }; Loading @@ -242,7 +242,7 @@ class Item_func_des_decrypt :public Item_str_func 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 *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; } const char *func_name() const { return "des_decrypt"; } }; Loading Loading
mysql-test/r/func_encrypt.result 0 → 100644 +6.8 KiB File added.No diff preview for this file type. View file
mysql-test/t/func_encrypt.test 0 → 100644 +46 −0 Original line number Diff line number Diff line -- source include/have_openssl.inc use test; drop table if exists x; create table x (x blob); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('a','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','a')); insert into x values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab')); insert into x values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc')); insert into x values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd')); insert into x values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde')); insert into x values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef')); insert into x values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg')); insert into x values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh')); insert into x values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi')); insert into x values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij')); insert into x values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk')); insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('red fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('fox jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('over the lazy brown dog','sabakala')); insert into x values (des_encrypt('the lazy brown dog','sabakala')); insert into x values (des_encrypt('lazy brown dog','sabakala')); insert into x values (des_encrypt('brown dog','sabakala')); insert into x values (des_encrypt('dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala')); select * from x; select des_decrypt(x,'sabakala') from x; #drop table x;
sql/item_strfunc.cc +74 −62 Original line number Diff line number Diff line Loading @@ -204,56 +204,65 @@ 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 ascii_to_bin(c) ((c)<=57 ? (c)-46 : (c)<=90 ? (c)-53 : (c)-59) /* Function des_encrypt() by tonu@spam.ee Works only if compiled with OpenSSL library support. Output always starts with magic char "1" and all encrypted output is encoded into ASCII-protected container. Original input is returned as output if input string begins with magic "1". Credit card number always begin with 4,5 or 6. Encryption result is longer than original by formula: new_length=(8-(original_length % 8))*2+1 */ String *Item_func_des_encrypt::val_str(String *str) { String *res =args[0]->val_str(str); #ifdef HAVE_OPENSSL des_key_schedule ks1, ks2, ks3; des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; union { des_cblock allkeys[3]; // 24 bytes (168 bits) total struct { des_cblock key1, key2, key3; // 8 bytes each } key; } keyblock; if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) return &empty_string; if(res->c_ptr()[0]!='1') { // Skip encryption if already encrypted String *keystr=args[1]->val_str(&tmp_value); int32 mode=0; if(arg_count == 3 && !args[2]->null_value) mode=args[2]->val_int(); // 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, /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, (uchar *)keystr->c_ptr(), 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.key2,ks2); des_set_key_unchecked(&key.key3,ks3); /* 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( (int)keystr->length(),1,(uchar *)&keyblock,ivec); des_set_key_unchecked(&keyblock.key1,ks1); // Here we set all 64-bit keys des_set_key_unchecked(&keyblock.key2,ks2); // (56 effective) one by one des_set_key_unchecked(&keyblock.key3,ks3); /* 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= 7-( res->length() %8); // 0..7 marking real offsets 1..8 for(int i=0 ; i < tail ; ++i) res->append('*'); res->append(tail); // Write tail length 0..7 to last pos str->length(res->length()); des_ede3_cbc_encrypt( // Real encryption (const uchar*)(res->c_ptr()), (uchar*)(res->c_ptr()), (uchar*)(str->c_ptr()), res->length(), ks1, ks2, ks3, &ivec, TRUE); if(mode) { // In case of ASCII mode we should convert binary string into ASCII str->set((const char*)0,(uint)0); for(uint i=0 ; i < res->length() ; ++i) { str->append(bin_to_ascii((uchar)res->c_ptr()[i] & 0x3f)); str->append(bin_to_ascii(((uchar)res->c_ptr()[i] >> 5 ) & 0x3f)); res->set((const char*)"1",(uint)1); for(uint i=0 ; i < str->length() ; ++i) { res->append(bin_to_ascii((uchar)str->c_ptr()[i] & 0x3f)); res->append(bin_to_ascii(((uchar)str->c_ptr()[i] >> 5 ) & 0x3f)); } } return str; } else return res; #else null_value=1; Loading @@ -267,43 +276,46 @@ String *Item_func_des_decrypt::val_str(String *str) #ifdef HAVE_OPENSSL des_key_schedule ks1, ks2, ks3; des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; union { des_cblock allkeys[3]; // 24 bytes total struct { des_cblock key1, key2, key3; // 8 bytes each } key; } keyblock; if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) return &empty_string; if(res->c_ptr()[0]=='1') // Skip decryption if not encrypted { str->set((const char*)0,(uint)0); for(uint i=1 ; i < res->length() ; i+=2) { str->append((ascii_to_bin(res->c_ptr()[i])) | (ascii_to_bin(res->c_ptr()[i+1]) << 5 )); } String *keystr=args[1]->val_str(&tmp_value); int32 mode=0; if(arg_count == 3 && !args[2]->null_value) mode=args[2]->val_int(); // 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, /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL, (uchar *)keystr->c_ptr(), 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.key2,ks2); des_set_key_unchecked(&key.key3,ks3); str->set((const char*)0,(uint)0); if(mode) { for(uint i=0 ; i < res->length() ; i+=2) { str->append((ascii_to_bin(res->c_ptr()[i])) | (ascii_to_bin(res->c_ptr()[i+1]) << 5 )); } } else str->copy(res->c_ptr()); // Real decryption des_ede3_cbc_encrypt( (int)keystr->length(),1,(uchar *)&keyblock,ivec); des_set_key_unchecked(&keyblock.key1,ks1); // Here we set all 64-bit keys des_set_key_unchecked(&keyblock.key2,ks2); // (56 effective) one by one des_set_key_unchecked(&keyblock.key3,ks3); res->length(str->length()); des_ede3_cbc_encrypt( // Real decryption (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); uchar tail=(res->c_ptr()[res->length()-1]) & 0x7; if((res->length() > ((uint)1+tail))) // We should avoid negative length res->length(res->length()-1-tail); // (can happen with wrong key) } return res; #else null_value=1; Loading
sql/item_strfunc.h +2 −2 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ class Item_func_des_encrypt :public Item_str_func 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 *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; } const char *func_name() const { return "des_encrypt"; } }; Loading @@ -242,7 +242,7 @@ class Item_func_des_decrypt :public Item_str_func 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 *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; } const char *func_name() const { return "des_decrypt"; } }; Loading