diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 2ba67eb40cf..fca41a85db0 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 43201f954c2..4e9bfcfd103 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp index 94ce7bfff7b..35641802e03 100644 --- a/include/mysql/plugin_data_type.h.pp +++ b/include/mysql/plugin_data_type.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index f26a02def18..e8b7f7b3e60 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 7c3e476849a..4de3fc3a9e6 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp index 42970389951..63c63cefa10 100644 --- a/include/mysql/plugin_function.h.pp +++ b/include/mysql/plugin_function.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 3d92c127b87..6cc728a8529 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -169,6 +169,8 @@ extern "C" { enum my_aes_mode { MY_AES_ECB, MY_AES_CBC }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -182,6 +184,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -193,6 +199,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *src, unsigned int slen, unsigned char *dst, unsigned int *dlen, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); } diff --git a/include/mysql/service_my_crypt.h b/include/mysql/service_my_crypt.h index 1a4ebcfd067..3a58d0828fc 100644 --- a/include/mysql/service_my_crypt.h +++ b/include/mysql/service_my_crypt.h @@ -57,6 +57,9 @@ enum my_aes_mode { #endif }; +enum my_digest { MY_DIGEST_SHA1, MY_DIGEST_SHA224, MY_DIGEST_SHA256, + MY_DIGEST_SHA384, MY_DIGEST_SHA512 }; + extern struct my_crypt_service_st { int (*my_aes_crypt_init)(void *ctx, enum my_aes_mode mode, int flags, const unsigned char* key, unsigned int klen, @@ -70,6 +73,10 @@ extern struct my_crypt_service_st { unsigned int (*my_aes_get_size)(enum my_aes_mode mode, unsigned int source_length); unsigned int (*my_aes_ctx_size)(enum my_aes_mode mode); int (*my_random_bytes)(unsigned char* buf, int num); + void (*my_bytes_to_key)(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); } *my_crypt_service; #ifdef MYSQL_DYNAMIC_PLUGIN @@ -95,6 +102,9 @@ extern struct my_crypt_service_st { #define my_random_bytes(A,B)\ my_crypt_service->my_random_bytes(A,B) +#define my_bytes_to_key(A, B, C, D, E, F, G) \ +my_crypt_service->my_bytes_to_key(A,B,C,D,E,F,G) + #else int my_aes_crypt_init(void *ctx, enum my_aes_mode mode, int flags, @@ -108,6 +118,10 @@ int my_aes_crypt(enum my_aes_mode mode, int flags, const unsigned char *key, unsigned int klen, const unsigned char *iv, unsigned int ivlen); int my_random_bytes(unsigned char* buf, int num); +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + unsigned int input_len, unsigned char *key, + unsigned char *iv, enum my_digest digest, + unsigned int use_pbkdf2); unsigned int my_aes_get_size(enum my_aes_mode mode, unsigned int source_length); unsigned int my_aes_ctx_size(enum my_aes_mode mode); #endif diff --git a/include/service_versions.h b/include/service_versions.h index ea74ac01bb9..40e668ea843 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -27,7 +27,7 @@ #define VERSION_encryption 0x0300 #define VERSION_encryption_scheme 0x0100 #define VERSION_logger 0x0200 -#define VERSION_my_crypt 0x0100 +#define VERSION_my_crypt 0x0101 #define VERSION_my_md5 0x0100 #define VERSION_my_print_error 0x0200 #define VERSION_my_sha1 0x0101 diff --git a/mysql-test/suite/encryption/t/filekeys-data-sha1-pbkdf2.enc b/mysql-test/suite/encryption/t/filekeys-data-sha1-pbkdf2.enc new file mode 100644 index 00000000000..fee415deeff --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-data-sha1-pbkdf2.enc @@ -0,0 +1 @@ +Salted__pΞU*y|ρ3HZ t#rҾb=V9,377ʼ)F"}S*Z8 ƄdśfX&wNlވ3{.IBouae4R:M +\ZI-& u:?/3clM:Ŷpk.xz"G4K6Gِ[aU uXvJx ;4s99.yqxl$46&͐Uh 0z*+a1# !.5]/="okgP2< +ZC&3_9E\[H4=;[:×UbaE|-M"=-}凛#,~#g:ؠV15w^ulyANWCwS0UP0[F51F \ No newline at end of file diff --git a/mysql-test/suite/encryption/t/filekeys-data-sha384.enc b/mysql-test/suite/encryption/t/filekeys-data-sha384.enc new file mode 100644 index 00000000000..c588121b62a Binary files /dev/null and b/mysql-test/suite/encryption/t/filekeys-data-sha384.enc differ diff --git a/mysql-test/suite/encryption/t/filekeys-data-sha512-pbkdf2.enc b/mysql-test/suite/encryption/t/filekeys-data-sha512-pbkdf2.enc new file mode 100644 index 00000000000..9e7582b12e9 Binary files /dev/null and b/mysql-test/suite/encryption/t/filekeys-data-sha512-pbkdf2.enc differ diff --git a/mysql-test/suite/encryption/t/filekeys-data-sha512.enc b/mysql-test/suite/encryption/t/filekeys-data-sha512.enc new file mode 100644 index 00000000000..a616b045775 Binary files /dev/null and b/mysql-test/suite/encryption/t/filekeys-data-sha512.enc differ diff --git a/mysql-test/suite/encryption/t/filekeys_encfile.combinations b/mysql-test/suite/encryption/t/filekeys_encfile.combinations new file mode 100644 index 00000000000..652ef183e42 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile.combinations @@ -0,0 +1,52 @@ +[sha1] +--loose-file-key-management-filekey=secret +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha1.enc + +[sha224] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha224 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha224.enc + +[sha256] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha256 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha256.enc + +[sha384] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha384 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha384.enc + +[sha512] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha512 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha512.enc + +[sha1_pbkdf2] +--loose-file-key-management-filekey=secret +--loose-file-key-management-use-pbkdf2=10000 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha1-pbkdf2.enc + +[sha224_pbkdf2] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha224 +--loose-file-key-management-use-pbkdf2=1000 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha224-pbkdf2.enc + +[sha256_pbkdf2] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha256 +--loose-file-key-management-use-pbkdf2=100000 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha256-pbkdf2.enc + +[sha384_pbkdf2] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha384 +--loose-file-key-management-use-pbkdf2=12345 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha384-pbkdf2.enc + +[sha512_pbkdf2] +--loose-file-key-management-filekey=secret +--loose-file-key-management-digest=sha512 +--loose-file-key-management-use-pbkdf2=10000 +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data-sha512-pbkdf2.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile.opt b/mysql-test/suite/encryption/t/filekeys_encfile.opt deleted file mode 100644 index 651cc0f4cbe..00000000000 --- a/mysql-test/suite/encryption/t/filekeys_encfile.opt +++ /dev/null @@ -1,2 +0,0 @@ ---loose-file-key-management-filekey=secret ---loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile.test b/mysql-test/suite/encryption/t/filekeys_encfile.test index a0611a38ec4..66a79b09ad0 100644 --- a/mysql-test/suite/encryption/t/filekeys_encfile.test +++ b/mysql-test/suite/encryption/t/filekeys_encfile.test @@ -1 +1,34 @@ +# # The encrypted key files were generated using the following: + +# let $plain_keyfile=$MYSQL_TMP_DIR/keys.txt; +# let $enc_keyfile_prefix=$MTR_SUITE_DIR/t/filekeys-data; + +# write_file $plain_keyfile; +# # +# # this is a comment +# # +# 1;770A8A65DA156D24EE2A093277530142 +# 2;4D92199549E0F2EF009B4160F3582E5528A11A45017F3EF8 +# # another comment +# 33;B374A26A71490437AA024E4FADD5B497FDFF1A8EA6FF12F6FB65AF2720B59CCF +# 4;18420B5CBA31CCDFFE9716E91EB61374D05914F3ADE23E03 --> ignored + +# 5;966050D7777350B6FD5CCB3E5F648DA45C63BEFB6DEDDFA13443F156B7D35C84 +# 6;B5EA210C8C09EF20DB95EC584714A89F # and yet another + +# EOF + +# exec openssl enc -aes-256-cbc -md sha1 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha1.enc; +# exec openssl enc -aes-256-cbc -md sha224 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha224.enc; +# exec openssl enc -aes-256-cbc -md sha256 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha256.enc; +# exec openssl enc -aes-256-cbc -md sha384 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha384.enc; +# exec openssl enc -aes-256-cbc -md sha512 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha512.enc; +# exec openssl enc -aes-256-cbc -md sha1 -pbkdf2 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha1-pbkdf2.enc; +# exec openssl enc -aes-256-cbc -md sha224 -iter 1000 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha224-pbkdf2.enc; +# exec openssl enc -aes-256-cbc -md sha256 -iter 100000 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha256-pbkdf2.enc; +# exec openssl enc -aes-256-cbc -md sha384 -iter 12345 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha384-pbkdf2.enc; +# exec openssl enc -aes-256-cbc -md sha512 -iter 10000 -pass pass:secret -in $plain_keyfile -out $enc_keyfile_prefix-sha512-pbkdf2.enc; + +# echo Done; + source filekeys_goodtest.inc; diff --git a/mysys_ssl/my_crypt.cc b/mysys_ssl/my_crypt.cc index 346eff51b1b..a70ce4efef6 100644 --- a/mysys_ssl/my_crypt.cc +++ b/mysys_ssl/my_crypt.cc @@ -31,6 +31,8 @@ #include #define CTX_ALIGN 16 +#define KEY_LENGTH 32 +#define IV_LENGTH 16 class MyCTX { @@ -382,4 +384,39 @@ int my_random_bytes(uchar *buf, int num) return MY_AES_OK; } +static inline const EVP_MD *get_digest(enum my_digest digest) +{ + switch (digest) + { + case MY_DIGEST_SHA1: return EVP_sha1(); + case MY_DIGEST_SHA224: return EVP_sha224(); + case MY_DIGEST_SHA256: return EVP_sha256(); + case MY_DIGEST_SHA384: return EVP_sha384(); + case MY_DIGEST_SHA512: return EVP_sha512(); + default: + { + assert(0); + return NULL; + } + } +} + +void my_bytes_to_key(const unsigned char *salt, const unsigned char *input, + uint input_len, unsigned char *key, unsigned char *iv, + enum my_digest digest, uint use_pbkdf2) +{ + if (use_pbkdf2 == 0) + EVP_BytesToKey(EVP_aes_256_cbc(), get_digest(digest), salt, + input, input_len, 1, key, iv); + else + { + uchar keyiv[KEY_LENGTH + IV_LENGTH]; + PKCS5_PBKDF2_HMAC((const char*) input, input_len, salt, 8, + use_pbkdf2, get_digest(digest), + KEY_LENGTH + IV_LENGTH, keyiv); + memcpy(key, keyiv, KEY_LENGTH); + memcpy(iv, keyiv + KEY_LENGTH, IV_LENGTH); + } +} + } diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc index 8702785a1fd..1ceac9d1875 100644 --- a/plugin/file_key_management/file_key_management_plugin.cc +++ b/plugin/file_key_management/file_key_management_plugin.cc @@ -22,6 +22,8 @@ static char* filename; static char* filekey; static unsigned long encryption_algorithm; +static unsigned long digest; +static uint use_pbkdf2; static const char *encryption_algorithm_names[]= { @@ -32,8 +34,20 @@ static const char *encryption_algorithm_names[]= 0 }; +static const char *digest_names[]= +{ + "sha1", + "sha224", + "sha256", + "sha384", + "sha512", + 0 +}; + static TYPELIB encryption_algorithm_typelib=CREATE_TYPELIB_FOR(encryption_algorithm_names); +static TYPELIB digest_typelib=CREATE_TYPELIB_FOR(digest_names); + static MYSQL_SYSVAR_STR(filename, filename, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Path and name of the key file", @@ -54,10 +68,24 @@ static MYSQL_SYSVAR_ENUM(encryption_algorithm, encryption_algorithm, "Encryption algorithm to use" recommendation, NULL, NULL, 0, &encryption_algorithm_typelib); +static MYSQL_SYSVAR_ENUM(digest, digest, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Digest algorithm used for decrypting the key file. The value of the " + "openssl enc -md option", + NULL, NULL, 0, &digest_typelib); + +static MYSQL_SYSVAR_UINT(use_pbkdf2, use_pbkdf2, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, + "Number of PBKDF2 iteration used for decrypting the key file. Use 0 to " + "disable PBKDF2, otherwise it's a value of the openssl enc -iter option", + NULL, NULL, 0, 0, UINT_MAX, 0); + static struct st_mysql_sys_var* settings[] = { MYSQL_SYSVAR(filename), MYSQL_SYSVAR(filekey), MYSQL_SYSVAR(encryption_algorithm), + MYSQL_SYSVAR(digest), + MYSQL_SYSVAR(use_pbkdf2), NULL }; @@ -127,6 +155,23 @@ static inline enum my_aes_mode mode(int flags) return MY_AES_CBC; } +static inline enum my_digest get_digest() +{ + switch (digest) + { + case 0: return MY_DIGEST_SHA1; + case 1: return MY_DIGEST_SHA224; + case 2: return MY_DIGEST_SHA256; + case 3: return MY_DIGEST_SHA384; + case 4: return MY_DIGEST_SHA512; + default: + { + assert(0); + return MY_DIGEST_SHA1; + } + } +} + static int ctx_init(void *ctx, const unsigned char* key, unsigned int klen, const unsigned char* iv, unsigned int ivlen, int flags, unsigned int key_id, unsigned int key_version) @@ -170,7 +215,7 @@ struct st_mariadb_encryption file_key_management_plugin= { static int file_key_management_plugin_init(void *p) { - Parser parser(filename, filekey); + Parser parser(filename, filekey, get_digest(), use_pbkdf2); return parser.parse(&keys); } diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index 65ff5a14705..e8aecd3500b 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -88,54 +88,6 @@ openssl enc -aes-256-cbc -md sha1 -k "secret" -in keys.txt -out keys.enc #define OpenSSL_key_len 32 #define OpenSSL_iv_len 16 -/** - Calculate key and iv from a given salt and secret as in the - openssl command-line tool - - @param salt [in] the given salt as extracted from the encrypted file - @param secret [in] the given secret as String, provided by the user - @param key [out] 32 Bytes of key are written to this pointer - @param iv [out] 16 Bytes of iv are written to this pointer -*/ - -void Parser::bytes_to_key(const unsigned char *salt, const char *input, - unsigned char *key, unsigned char *iv) -{ - unsigned char digest[MY_SHA1_HASH_SIZE]; - int key_left = OpenSSL_key_len; - int iv_left = OpenSSL_iv_len; - const size_t ilen= strlen(input); - const size_t slen= OpenSSL_salt_len; // either this or explicit (size_t) casts below - - my_sha1_multi(digest, input, ilen, salt, slen, NullS); - - while (iv_left) - { - int left= MY_SHA1_HASH_SIZE; - if (key_left) - { - int store = MY_MIN(key_left, MY_SHA1_HASH_SIZE); - memcpy(&key[OpenSSL_key_len - key_left], digest, store); - - key_left -= store; - left -= store; - } - - if (iv_left && left) - { - int store= MY_MIN(iv_left, left); - memcpy(&iv[OpenSSL_iv_len - iv_left], &digest[MY_SHA1_HASH_SIZE - left], store); - - iv_left -= store; - } - - if (iv_left) - my_sha1_multi(digest, digest, MY_SHA1_HASH_SIZE, - input, ilen, salt, slen, NullS); - } -} - - bool Parser::parse(std::map *keys) { const char *secret= filekey; @@ -374,7 +326,9 @@ char* Parser::read_and_decrypt_file(const char *secret) my_error(EE_OUTOFMEMORY, ME_ERROR_LOG | ME_FATAL, file_size); goto err2; } - bytes_to_key(buffer + OpenSSL_prefix_len, secret, key, iv); + my_bytes_to_key(buffer + OpenSSL_prefix_len, + (const unsigned char *) secret, (uint) strlen(secret), + key, iv, digest, use_pbkdf2); uint32 d_size; if (my_aes_crypt(MY_AES_CBC, ENCRYPTION_FLAG_DECRYPT, buffer + OpenSSL_prefix_len + OpenSSL_salt_len, diff --git a/plugin/file_key_management/parser.h b/plugin/file_key_management/parser.h index e2fda758bf9..8af2b5b035e 100644 --- a/plugin/file_key_management/parser.h +++ b/plugin/file_key_management/parser.h @@ -35,13 +35,13 @@ class Parser { const char *filename; const char *filekey; + const enum my_digest digest; + const uint use_pbkdf2; unsigned int line_number; unsigned int from_hex(char c) { return c <= '9' ? c - '0' : tolower(c) - 'a' + 10; } - void bytes_to_key(const unsigned char *salt, const char *secret, - unsigned char *key, unsigned char *iv); bool read_filekey(const char *filekey, char *secret); bool parse_file(std::map *keys, const char *secret); void report_error(const char *reason, size_t position); @@ -49,7 +49,9 @@ class Parser char* read_and_decrypt_file(const char *secret); public: - Parser(const char* fn, const char *fk) : - filename(fn), filekey(fk), line_number(0) { } + Parser(const char* fn, const char *fk, enum my_digest digest, + uint use_pbkdf2) : + filename(fn), filekey(fk), digest(digest), use_pbkdf2(use_pbkdf2), + line_number(0) { } bool parse(std::map *keys); }; diff --git a/sql/sql_plugin_services.inl b/sql/sql_plugin_services.inl index 2114f3560a7..5d314dcfce8 100644 --- a/sql/sql_plugin_services.inl +++ b/sql/sql_plugin_services.inl @@ -210,7 +210,8 @@ static struct my_crypt_service_st crypt_handler= my_aes_crypt, my_aes_get_size, my_aes_ctx_size, - my_random_bytes + my_random_bytes, + my_bytes_to_key, }; static struct my_print_error_service_st my_print_error_handler=