mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-31474 KDF() function
KDF(key_str, salt [, {info | iterations} [, kdf_name [, width ]]]) kdf_name is "hkdf" or "pbkdf2_hmac" (default). width (in bits) can be any number divisible by 8, by default it's taken from @@block_encryption_mode iterations must be positive, and is 1000 by default OpenSSL 1.0 doesn't support HKDF, so it'll return NULL. This OpenSSL version is still used in SLES 12 and CentOS 7
This commit is contained in:
@@ -60,6 +60,7 @@ MACRO (MYSQL_USE_BUNDLED_SSL)
|
|||||||
SET(HAVE_EncryptAes128Ctr ON CACHE INTERNAL "wolfssl does support AES-CTR")
|
SET(HAVE_EncryptAes128Ctr ON CACHE INTERNAL "wolfssl does support AES-CTR")
|
||||||
SET(HAVE_EncryptAes128Gcm OFF CACHE INTERNAL "wolfssl does not support AES-GCM")
|
SET(HAVE_EncryptAes128Gcm OFF CACHE INTERNAL "wolfssl does not support AES-GCM")
|
||||||
SET(HAVE_X509_check_host ON CACHE INTERNAL "wolfssl does support X509_check_host")
|
SET(HAVE_X509_check_host ON CACHE INTERNAL "wolfssl does support X509_check_host")
|
||||||
|
SET(HAVE_hkdf ON CACHE INTERNAL "wolfssl does support EVP_PKEY API")
|
||||||
CHANGE_SSL_SETTINGS("bundled")
|
CHANGE_SSL_SETTINGS("bundled")
|
||||||
ADD_SUBDIRECTORY(extra/wolfssl)
|
ADD_SUBDIRECTORY(extra/wolfssl)
|
||||||
MESSAGE_ONCE(SSL_LIBRARIES "SSL_LIBRARIES = ${SSL_LIBRARIES}")
|
MESSAGE_ONCE(SSL_LIBRARIES "SSL_LIBRARIES = ${SSL_LIBRARIES}")
|
||||||
@@ -158,6 +159,8 @@ MACRO (MYSQL_CHECK_SSL)
|
|||||||
HAVE_EncryptAes128Gcm)
|
HAVE_EncryptAes128Gcm)
|
||||||
CHECK_SYMBOL_EXISTS(X509_check_host "openssl/x509v3.h"
|
CHECK_SYMBOL_EXISTS(X509_check_host "openssl/x509v3.h"
|
||||||
HAVE_X509_check_host)
|
HAVE_X509_check_host)
|
||||||
|
CHECK_SYMBOL_EXISTS(EVP_PKEY_CTX_set_hkdf_md "string.h;stdarg.h;openssl/kdf.h"
|
||||||
|
HAVE_hkdf)
|
||||||
SET(CMAKE_REQUIRED_INCLUDES)
|
SET(CMAKE_REQUIRED_INCLUDES)
|
||||||
SET(CMAKE_REQUIRED_LIBRARIES)
|
SET(CMAKE_REQUIRED_LIBRARIES)
|
||||||
SET(CMAKE_REQUIRED_DEFINITIONS)
|
SET(CMAKE_REQUIRED_DEFINITIONS)
|
||||||
|
@@ -499,6 +499,7 @@
|
|||||||
#cmakedefine HAVE_COMPRESS 1
|
#cmakedefine HAVE_COMPRESS 1
|
||||||
#cmakedefine HAVE_EncryptAes128Ctr 1
|
#cmakedefine HAVE_EncryptAes128Ctr 1
|
||||||
#cmakedefine HAVE_EncryptAes128Gcm 1
|
#cmakedefine HAVE_EncryptAes128Gcm 1
|
||||||
|
#cmakedefine HAVE_hkdf 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Stuff that always need to be defined (compile breaks without it)
|
Stuff that always need to be defined (compile breaks without it)
|
||||||
|
64
mysql-test/main/func_kdf,old.rdiff
Normal file
64
mysql-test/main/func_kdf,old.rdiff
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
--- main/func_kdf.result
|
||||||
|
+++ main/func_kdf.reject
|
||||||
|
@@ -21,10 +21,14 @@
|
||||||
|
48565B49B42FBF88537AFA1D4C0FA2C6
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'hkdf'))
|
||||||
|
-710583081D40A55F0B573A76E02D8975
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select hex(kdf('foo', 'bar', 'infa', 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', 'infa', 'hkdf'))
|
||||||
|
-612875F859CFB4EE0DFEFF9F2A18E836
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'pbkdf2_hmac'))
|
||||||
|
NULL
|
||||||
|
@@ -55,7 +59,9 @@
|
||||||
|
NULL
|
||||||
|
select hex(kdf('foo', 'bar', NULL, 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', NULL, 'hkdf'))
|
||||||
|
-4AFD0088E56CAF7CB5C94F6C101D58D5
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select hex(kdf('foo', 'bar', NULL, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', NULL, 'pbkdf2_hmac'))
|
||||||
|
NULL
|
||||||
|
@@ -81,10 +87,14 @@
|
||||||
|
set @@block_encryption_mode='aes-192-cbc';
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'hkdf'))
|
||||||
|
-710583081D40A55F0B573A76E02D8975AA11A4595954C0A1
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf', 256));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'hkdf', 256))
|
||||||
|
-710583081D40A55F0B573A76E02D8975AA11A4595954C0A1487D6D33ABAB93C3
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac'))
|
||||||
|
430D4780B57254EF39EE13CE53DB381A552151AA62A9FA92
|
||||||
|
@@ -110,10 +120,14 @@
|
||||||
|
Warning 3047 Invalid argument error: 0 in function kdf.
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 32768));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 32768))
|
||||||
|
-4096
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 65536));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 65536))
|
||||||
|
-8192
|
||||||
|
+NULL
|
||||||
|
+Warnings:
|
||||||
|
+Warning 1235 This version of MariaDB doesn't yet support 'kdf(..., 'hkdf')'
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 65537));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 65537))
|
||||||
|
NULL
|
4
mysql-test/main/func_kdf.combinations
Normal file
4
mysql-test/main/func_kdf.combinations
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[new]
|
||||||
|
|
||||||
|
[old]
|
||||||
|
# remove when no longer building with OpenSSL 1.0
|
158
mysql-test/main/func_kdf.result
Normal file
158
mysql-test/main/func_kdf.result
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
#
|
||||||
|
# MDEV-31474 KDF() function
|
||||||
|
#
|
||||||
|
select hex(kdf('foo', 'bar'));
|
||||||
|
hex(kdf('foo', 'bar'))
|
||||||
|
76BA6DEC5C3F6A60704D730A2A4BAA1C
|
||||||
|
select hex(kdf('foo', 'bar'));
|
||||||
|
hex(kdf('foo', 'bar'))
|
||||||
|
76BA6DEC5C3F6A60704D730A2A4BAA1C
|
||||||
|
select hex(kdf('faa', 'bar'));
|
||||||
|
hex(kdf('faa', 'bar'))
|
||||||
|
62A8C6FD3E6FDA7ECE6D37CF1C95E3CC
|
||||||
|
select hex(kdf('foo', 'bor'));
|
||||||
|
hex(kdf('foo', 'bor'))
|
||||||
|
F0FE3B0884C9733A520EC8C2EE711137
|
||||||
|
select hex(kdf('foo', 'bar', 10));
|
||||||
|
hex(kdf('foo', 'bar', 10))
|
||||||
|
1D25A9E01C2078FF10DECEC874B3F21E
|
||||||
|
select hex(kdf('foo', 'bar', 11));
|
||||||
|
hex(kdf('foo', 'bar', 11))
|
||||||
|
48565B49B42FBF88537AFA1D4C0FA2C6
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'hkdf'))
|
||||||
|
710583081D40A55F0B573A76E02D8975
|
||||||
|
select hex(kdf('foo', 'bar', 'infa', 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', 'infa', 'hkdf'))
|
||||||
|
612875F859CFB4EE0DFEFF9F2A18E836
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'pbkdf2_hmac'))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect INTEGER value: 'info'
|
||||||
|
Warning 3047 Invalid argument error: 0 in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', -1, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', -1, 'pbkdf2_hmac'))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: -1 in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', 0, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 0, 'pbkdf2_hmac'))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 0 in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', 1, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 1, 'pbkdf2_hmac'))
|
||||||
|
DB658012DC3E52AEC1F4933C280B6E10
|
||||||
|
select hex(kdf('foo', 'bar', 10, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 10, 'pbkdf2_hmac'))
|
||||||
|
1D25A9E01C2078FF10DECEC874B3F21E
|
||||||
|
select hex(kdf(NULL, 'bar'));
|
||||||
|
hex(kdf(NULL, 'bar'))
|
||||||
|
NULL
|
||||||
|
select hex(kdf('foo', NULL));
|
||||||
|
hex(kdf('foo', NULL))
|
||||||
|
NULL
|
||||||
|
select hex(kdf('foo', 'bar', NULL, 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', NULL, 'hkdf'))
|
||||||
|
4AFD0088E56CAF7CB5C94F6C101D58D5
|
||||||
|
select hex(kdf('foo', 'bar', NULL, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', NULL, 'pbkdf2_hmac'))
|
||||||
|
NULL
|
||||||
|
select hex(kdf('foo', 'bar', 2000, NULL));
|
||||||
|
hex(kdf('foo', 'bar', 2000, NULL))
|
||||||
|
NULL
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'foo'));
|
||||||
|
hex(kdf('foo', 'bar', 2000, 'foo'))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 'foo' in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', 2000, '\n\n\n\0!!!'));
|
||||||
|
hex(kdf('foo', 'bar', 2000, '\n\n\n\0!!!'))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: '
|
||||||
|
|
||||||
|
|
||||||
|
\0000!!!' in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', NULL));
|
||||||
|
hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', NULL))
|
||||||
|
NULL
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', -8));
|
||||||
|
hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', -8))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: -8 in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', 10));
|
||||||
|
hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', 10))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 10 in function kdf.
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', 16));
|
||||||
|
hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', 16))
|
||||||
|
76BA
|
||||||
|
set @@block_encryption_mode='aes-192-cbc';
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf'));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'hkdf'))
|
||||||
|
710583081D40A55F0B573A76E02D8975AA11A4595954C0A1
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf', 256));
|
||||||
|
hex(kdf('foo', 'bar', 'info', 'hkdf', 256))
|
||||||
|
710583081D40A55F0B573A76E02D8975AA11A4595954C0A1487D6D33ABAB93C3
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac'));
|
||||||
|
hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac'))
|
||||||
|
430D4780B57254EF39EE13CE53DB381A552151AA62A9FA92
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac', 256));
|
||||||
|
hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac', 256))
|
||||||
|
430D4780B57254EF39EE13CE53DB381A552151AA62A9FA922B9949DF270AE10C
|
||||||
|
set @key=kdf('password', 'salt', 2048);
|
||||||
|
select hex(aes_encrypt('secret', @key, '1234123412341234'));
|
||||||
|
hex(aes_encrypt('secret', @key, '1234123412341234'))
|
||||||
|
9EED553CDDEE426D5635EF559E015ECA
|
||||||
|
select aes_decrypt(x'9EED553CDDEE426D5635EF559E015ECA', @key, '1234123412341234');
|
||||||
|
aes_decrypt(x'9EED553CDDEE426D5635EF559E015ECA', @key, '1234123412341234')
|
||||||
|
secret
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', -1));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', -1))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: -1 in function kdf.
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 0));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 0))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 0 in function kdf.
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 32768));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 32768))
|
||||||
|
4096
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 65536));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 65536))
|
||||||
|
8192
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 65537));
|
||||||
|
length(kdf('foo', 'bar', 'info', 'hkdf', 65537))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 65537 in function kdf.
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', -1));
|
||||||
|
length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', -1))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: -1 in function kdf.
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 0));
|
||||||
|
length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 0))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 0 in function kdf.
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 32768));
|
||||||
|
length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 32768))
|
||||||
|
4096
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 65536));
|
||||||
|
length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 65536))
|
||||||
|
8192
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 65537));
|
||||||
|
length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 65537))
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 3047 Invalid argument error: 65537 in function kdf.
|
||||||
|
#
|
||||||
|
# End of 11.3 tests
|
||||||
|
#
|
57
mysql-test/main/func_kdf.test
Normal file
57
mysql-test/main/func_kdf.test
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
--echo #
|
||||||
|
--echo # MDEV-31474 KDF() function
|
||||||
|
--echo #
|
||||||
|
select hex(kdf('foo', 'bar'));
|
||||||
|
select hex(kdf('foo', 'bar')); # same result every time
|
||||||
|
select hex(kdf('faa', 'bar'));
|
||||||
|
select hex(kdf('foo', 'bor'));
|
||||||
|
|
||||||
|
select hex(kdf('foo', 'bar', 10));
|
||||||
|
select hex(kdf('foo', 'bar', 11));
|
||||||
|
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf'));
|
||||||
|
select hex(kdf('foo', 'bar', 'infa', 'hkdf'));
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'pbkdf2_hmac'));
|
||||||
|
select hex(kdf('foo', 'bar', -1, 'pbkdf2_hmac'));
|
||||||
|
select hex(kdf('foo', 'bar', 0, 'pbkdf2_hmac'));
|
||||||
|
select hex(kdf('foo', 'bar', 1, 'pbkdf2_hmac'));
|
||||||
|
select hex(kdf('foo', 'bar', 10, 'pbkdf2_hmac'));
|
||||||
|
|
||||||
|
select hex(kdf(NULL, 'bar'));
|
||||||
|
select hex(kdf('foo', NULL));
|
||||||
|
select hex(kdf('foo', 'bar', NULL, 'hkdf'));
|
||||||
|
select hex(kdf('foo', 'bar', NULL, 'pbkdf2_hmac'));
|
||||||
|
select hex(kdf('foo', 'bar', 2000, NULL));
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'foo'));
|
||||||
|
select hex(kdf('foo', 'bar', 2000, '\n\n\n\0!!!'));
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', NULL));
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', -8));
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', 10));
|
||||||
|
select hex(kdf('foo', 'bar', 1000, 'pbkdf2_hmac', 16));
|
||||||
|
|
||||||
|
set @@block_encryption_mode='aes-192-cbc';
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf'));
|
||||||
|
select hex(kdf('foo', 'bar', 'info', 'hkdf', 256));
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac'));
|
||||||
|
select hex(kdf('foo', 'bar', 2000, 'pbkdf2_hmac', 256));
|
||||||
|
|
||||||
|
set @key=kdf('password', 'salt', 2048);
|
||||||
|
select hex(aes_encrypt('secret', @key, '1234123412341234'));
|
||||||
|
select aes_decrypt(x'9EED553CDDEE426D5635EF559E015ECA', @key, '1234123412341234');
|
||||||
|
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', -1));
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 0));
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 32768));
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 65536));
|
||||||
|
select length(kdf('foo', 'bar', 'info', 'hkdf', 65537));
|
||||||
|
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', -1));
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 0));
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 32768));
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 65536));
|
||||||
|
select length(kdf('foo', 'bar', 100, 'pbkdf2_hmac', 65537));
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 11.3 tests
|
||||||
|
--echo #
|
||||||
|
|
@@ -84,6 +84,8 @@ sub skip_combinations {
|
|||||||
$skip{'main/ssl_7937.combinations'} = [ 'x509v3' ]
|
$skip{'main/ssl_7937.combinations'} = [ 'x509v3' ]
|
||||||
unless $ssl_lib =~ /WolfSSL/ or $openssl_ver ge "1.0.2";
|
unless $ssl_lib =~ /WolfSSL/ or $openssl_ver ge "1.0.2";
|
||||||
|
|
||||||
|
$skip{'main/func_kdf.combinations'} = [ $ssl_lib =~ /OpenSSL 1\.0\./ ? 'new' : 'old' ];
|
||||||
|
|
||||||
$skip{'main/ssl_verify_ip.test'} = 'x509v3 support required'
|
$skip{'main/ssl_verify_ip.test'} = 'x509v3 support required'
|
||||||
unless $openssl_ver ge "1.0.2";
|
unless $openssl_ver ge "1.0.2";
|
||||||
|
|
||||||
|
@@ -155,6 +155,20 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Create_func_kdf : public Create_native_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Item *create_native(THD *thd, const LEX_CSTRING *name,
|
||||||
|
List<Item> *item_list);
|
||||||
|
|
||||||
|
static Create_func_kdf s_singleton;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Create_func_kdf() = default;
|
||||||
|
virtual ~Create_func_kdf() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Create_func_asin : public Create_func_arg1
|
class Create_func_asin : public Create_func_arg1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -2986,6 +3000,32 @@ Create_func_aes_decrypt::create_native(THD *thd, const LEX_CSTRING *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Create_func_kdf Create_func_kdf::s_singleton;
|
||||||
|
|
||||||
|
Item*
|
||||||
|
Create_func_kdf::create_native(THD *thd, const LEX_CSTRING *name,
|
||||||
|
List<Item> *item_list)
|
||||||
|
{
|
||||||
|
uint arg_count= item_list->elements;
|
||||||
|
Item *a[5];
|
||||||
|
for (uint i=0; i < MY_MIN(array_elements(a), arg_count); i++)
|
||||||
|
a[i]= item_list->pop();
|
||||||
|
switch (arg_count)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return new (thd->mem_root) Item_func_kdf(thd, a[0], a[1]);
|
||||||
|
case 3:
|
||||||
|
return new (thd->mem_root) Item_func_kdf(thd, a[0], a[1], a[2]);
|
||||||
|
case 4:
|
||||||
|
return new (thd->mem_root) Item_func_kdf(thd, a[0], a[1], a[2], a[3]);
|
||||||
|
case 5:
|
||||||
|
return new (thd->mem_root) Item_func_kdf(thd, a[0], a[1], a[2], a[3], a[4]);
|
||||||
|
}
|
||||||
|
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Create_func_asin Create_func_asin::s_singleton;
|
Create_func_asin Create_func_asin::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
@@ -5941,6 +5981,7 @@ const Native_func_registry func_array[] =
|
|||||||
{ { STRING_WITH_LEN("JSON_UNQUOTE") }, BUILDER(Create_func_json_unquote)},
|
{ { STRING_WITH_LEN("JSON_UNQUOTE") }, BUILDER(Create_func_json_unquote)},
|
||||||
{ { STRING_WITH_LEN("JSON_VALID") }, BUILDER(Create_func_json_valid)},
|
{ { STRING_WITH_LEN("JSON_VALID") }, BUILDER(Create_func_json_valid)},
|
||||||
{ { STRING_WITH_LEN("JSON_VALUE") }, BUILDER(Create_func_json_value)},
|
{ { STRING_WITH_LEN("JSON_VALUE") }, BUILDER(Create_func_json_value)},
|
||||||
|
{ { STRING_WITH_LEN("KDF") }, BUILDER(Create_func_kdf)},
|
||||||
{ { STRING_WITH_LEN("LAST_DAY") }, BUILDER(Create_func_last_day)},
|
{ { STRING_WITH_LEN("LAST_DAY") }, BUILDER(Create_func_last_day)},
|
||||||
{ { STRING_WITH_LEN("LAST_INSERT_ID") }, BUILDER(Create_func_last_insert_id)},
|
{ { STRING_WITH_LEN("LAST_INSERT_ID") }, BUILDER(Create_func_last_insert_id)},
|
||||||
{ { STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)},
|
{ { STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)},
|
||||||
|
@@ -56,6 +56,10 @@ C_MODE_END
|
|||||||
#include "sql_statistics.h"
|
#include "sql_statistics.h"
|
||||||
#include "strfunc.h"
|
#include "strfunc.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_hkdf
|
||||||
|
#include <openssl/kdf.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* fmtlib include (https://fmt.dev/). */
|
/* fmtlib include (https://fmt.dev/). */
|
||||||
#define FMT_STATIC_THOUSANDS_SEPARATOR ','
|
#define FMT_STATIC_THOUSANDS_SEPARATOR ','
|
||||||
#define FMT_HEADER_ONLY 1
|
#define FMT_HEADER_ONLY 1
|
||||||
@@ -434,6 +438,122 @@ bool Item_func_aes_decrypt::fix_length_and_dec(THD *thd)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item_func_kdf::fix_length_and_dec(THD *thd)
|
||||||
|
{
|
||||||
|
if (arg_count > 4 && args[4]->const_item())
|
||||||
|
{
|
||||||
|
if (((key_length= (uint)args[4]->val_int()) % 8) || key_length > 65536)
|
||||||
|
key_length= 0;
|
||||||
|
}
|
||||||
|
else if (arg_count <= 4)
|
||||||
|
key_length= block_encryption_mode_to_key_length(thd->variables.block_encryption_mode);
|
||||||
|
else
|
||||||
|
key_length= 0;
|
||||||
|
key_length/= 8;
|
||||||
|
max_length= key_length ? key_length : 256/8;
|
||||||
|
set_maybe_null();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void invalid_argument_error(const char *func, const char *val)
|
||||||
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
|
ER_STD_INVALID_ARGUMENT, ER_THD(thd, ER_STD_INVALID_ARGUMENT),
|
||||||
|
val, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
String *Item_func_kdf::val_str(String *buf)
|
||||||
|
{
|
||||||
|
// KDF(key_str, salt [, {info | iterations} [, kdf_name [, width ]]])
|
||||||
|
DBUG_ASSERT(fixed());
|
||||||
|
StringBuffer<80> key_buf, salt_buf;
|
||||||
|
String *key= args[0]->val_str(&key_buf);
|
||||||
|
String *salt= args[1]->val_str(&salt_buf);
|
||||||
|
bool use_hkdf= false;
|
||||||
|
size_t klen= key_length;
|
||||||
|
bool ok= false;
|
||||||
|
|
||||||
|
if (!key || !salt)
|
||||||
|
goto ret_null;
|
||||||
|
|
||||||
|
if (arg_count > 3)
|
||||||
|
{
|
||||||
|
if (String *s= args[3]->val_str(buf))
|
||||||
|
{
|
||||||
|
if (strcasecmp(s->c_ptr(), "hkdf") == 0)
|
||||||
|
use_hkdf= true;
|
||||||
|
else if (strcasecmp(s->c_ptr(), "pbkdf2_hmac") != 0)
|
||||||
|
{
|
||||||
|
invalid_argument_error(func_name(), ErrConvStringQ(s).ptr());
|
||||||
|
goto ret_null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto ret_null;
|
||||||
|
}
|
||||||
|
if (!klen)
|
||||||
|
{
|
||||||
|
klen= args[4]->val_int();
|
||||||
|
if (!klen || klen % 8 || klen > 65536)
|
||||||
|
{
|
||||||
|
if (!args[4]->null_value)
|
||||||
|
invalid_argument_error(func_name(),
|
||||||
|
ErrConvInteger({(ssize_t)klen, args[4]->unsigned_flag}).ptr());
|
||||||
|
goto ret_null;
|
||||||
|
}
|
||||||
|
klen/= 8;
|
||||||
|
}
|
||||||
|
buf->reserve(klen);
|
||||||
|
buf->length(klen);
|
||||||
|
|
||||||
|
if (use_hkdf)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_hkdf
|
||||||
|
StringBuffer<80> info_buf;
|
||||||
|
String *info= arg_count > 2 ? args[2]->val_str(&info_buf) : 0;
|
||||||
|
|
||||||
|
EVP_PKEY_CTX *ctx= EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
|
||||||
|
ok= EVP_PKEY_derive_init(ctx) > 0 &&
|
||||||
|
EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha512()) > 0 &&
|
||||||
|
EVP_PKEY_CTX_set1_hkdf_key(ctx, (const uchar*)key->ptr(), key->length()) > 0 &&
|
||||||
|
EVP_PKEY_CTX_set1_hkdf_salt(ctx, (const uchar*)salt->ptr(), salt->length()) > 0 &&
|
||||||
|
(!info || EVP_PKEY_CTX_add1_hkdf_info(ctx, (const uchar*)info->ptr(), info->length()) > 0) &&
|
||||||
|
EVP_PKEY_derive(ctx, (uchar*)buf->ptr(), &klen) > 0;
|
||||||
|
|
||||||
|
EVP_PKEY_CTX_free(ctx);
|
||||||
|
#else
|
||||||
|
THD *thd= current_thd;
|
||||||
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
|
ER_NOT_SUPPORTED_YET, ER_THD(thd, ER_NOT_SUPPORTED_YET),
|
||||||
|
"kdf(..., 'hkdf')");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
longlong iter= arg_count > 2 ? args[2]->val_int() : 1000;
|
||||||
|
if (iter <= 0)
|
||||||
|
{
|
||||||
|
if (!args[2]->null_value)
|
||||||
|
invalid_argument_error(func_name(),
|
||||||
|
ErrConvInteger({iter, args[2]->unsigned_flag}).ptr());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ok= PKCS5_PBKDF2_HMAC(key->ptr(), key->length(),
|
||||||
|
(const uchar*)salt->ptr(), salt->length(), (int)iter,
|
||||||
|
EVP_sha512(), (int)klen, (uchar*)buf->ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
null_value= 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_null:
|
||||||
|
null_value=1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool Item_func_to_base64::fix_length_and_dec(THD *thd)
|
bool Item_func_to_base64::fix_length_and_dec(THD *thd)
|
||||||
{
|
{
|
||||||
|
@@ -133,6 +133,8 @@ public:
|
|||||||
:Item_str_func(thd, a, b, c) { }
|
:Item_str_func(thd, a, b, c) { }
|
||||||
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b, Item *c, Item *d)
|
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b, Item *c, Item *d)
|
||||||
:Item_str_func(thd, a, b, c, d) { }
|
:Item_str_func(thd, a, b, c, d) { }
|
||||||
|
Item_str_binary_checksum_func(THD *thd, Item *a, Item *b, Item *c, Item *d, Item *e)
|
||||||
|
:Item_str_func(thd, a, b, c, d, e) { }
|
||||||
bool eq(const Item *item, bool binary_cmp) const
|
bool eq(const Item *item, bool binary_cmp) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -295,6 +297,35 @@ public:
|
|||||||
{ return get_item_copy<Item_func_aes_decrypt>(thd, this); }
|
{ return get_item_copy<Item_func_aes_decrypt>(thd, this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Item_func_kdf :public Item_str_binary_checksum_func
|
||||||
|
{
|
||||||
|
uint key_length;
|
||||||
|
public:
|
||||||
|
Item_func_kdf(THD *thd, Item *a, Item *b)
|
||||||
|
: Item_str_binary_checksum_func(thd, a, b) {}
|
||||||
|
Item_func_kdf(THD *thd, Item *a, Item *b, Item *c)
|
||||||
|
: Item_str_binary_checksum_func(thd, a, b, c) {}
|
||||||
|
Item_func_kdf(THD *thd, Item *a, Item *b, Item *c, Item *d)
|
||||||
|
: Item_str_binary_checksum_func(thd, a, b, c, d) {}
|
||||||
|
Item_func_kdf(THD *thd, Item *a, Item *b, Item *c, Item *d, Item *e)
|
||||||
|
: Item_str_binary_checksum_func(thd, a, b, c, d, e) {}
|
||||||
|
bool fix_length_and_dec(THD *thd) override;
|
||||||
|
String *val_str(String *) override;
|
||||||
|
bool check_vcol_func_processor(void *arg) override
|
||||||
|
{
|
||||||
|
if (arg_count > 4)
|
||||||
|
return FALSE;
|
||||||
|
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
|
||||||
|
}
|
||||||
|
LEX_CSTRING func_name_cstring() const override
|
||||||
|
{
|
||||||
|
static LEX_CSTRING name= {STRING_WITH_LEN("kdf") };
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
Item *get_copy(THD *thd) override
|
||||||
|
{ return get_item_copy<Item_func_kdf>(thd, this); }
|
||||||
|
};
|
||||||
|
|
||||||
class Item_func_natural_sort_key : public Item_str_func
|
class Item_func_natural_sort_key : public Item_str_func
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user