github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_encryption.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"bytes"
    18  	"compress/zlib"
    19  	"crypto/aes"
    20  	"crypto/md5"
    21  	"crypto/rand"
    22  	"crypto/sha1"
    23  	"crypto/sha256"
    24  	"crypto/sha512"
    25  	"encoding/binary"
    26  	"fmt"
    27  	"hash"
    28  	"io"
    29  	"strings"
    30  
    31  	"github.com/whtcorpsinc/errors"
    32  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    33  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    34  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    35  	"github.com/whtcorpsinc/milevadb/stochastikctx/variable"
    36  	"github.com/whtcorpsinc/milevadb/types"
    37  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    38  	"github.com/whtcorpsinc/milevadb/soliton/encrypt"
    39  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    40  )
    41  
    42  var (
    43  	_ functionClass = &aesDecryptFunctionClass{}
    44  	_ functionClass = &aesEncryptFunctionClass{}
    45  	_ functionClass = &compressFunctionClass{}
    46  	_ functionClass = &decodeFunctionClass{}
    47  	_ functionClass = &desDecryptFunctionClass{}
    48  	_ functionClass = &desEncryptFunctionClass{}
    49  	_ functionClass = &encodeFunctionClass{}
    50  	_ functionClass = &encryptFunctionClass{}
    51  	_ functionClass = &md5FunctionClass{}
    52  	_ functionClass = &oldPasswordFunctionClass{}
    53  	_ functionClass = &passwordFunctionClass{}
    54  	_ functionClass = &randomBytesFunctionClass{}
    55  	_ functionClass = &sha1FunctionClass{}
    56  	_ functionClass = &sha2FunctionClass{}
    57  	_ functionClass = &uncompressFunctionClass{}
    58  	_ functionClass = &uncompressedLengthFunctionClass{}
    59  	_ functionClass = &validatePasswordStrengthFunctionClass{}
    60  )
    61  
    62  var (
    63  	_ builtinFunc = &builtinAesDecryptSig{}
    64  	_ builtinFunc = &builtinAesDecryptIVSig{}
    65  	_ builtinFunc = &builtinAesEncryptSig{}
    66  	_ builtinFunc = &builtinAesEncryptIVSig{}
    67  	_ builtinFunc = &builtinCompressSig{}
    68  	_ builtinFunc = &builtinMD5Sig{}
    69  	_ builtinFunc = &builtinPasswordSig{}
    70  	_ builtinFunc = &builtinRandomBytesSig{}
    71  	_ builtinFunc = &builtinSHA1Sig{}
    72  	_ builtinFunc = &builtinSHA2Sig{}
    73  	_ builtinFunc = &builtinUncompressSig{}
    74  	_ builtinFunc = &builtinUncompressedLengthSig{}
    75  )
    76  
    77  // aesModeAttr indicates that the key length and iv attribute for specific block_encryption_mode.
    78  // keySize is the key length in bits and mode is the encryption mode.
    79  // ivRequired indicates that initialization vector is required or not.
    80  type aesModeAttr struct {
    81  	modeName   string
    82  	keySize    int
    83  	ivRequired bool
    84  }
    85  
    86  var aesModes = map[string]*aesModeAttr{
    87  	//TODO support more modes, permitted mode values are: ECB, CBC, CFB1, CFB8, CFB128, OFB
    88  	"aes-128-ecb": {"ecb", 16, false},
    89  	"aes-192-ecb": {"ecb", 24, false},
    90  	"aes-256-ecb": {"ecb", 32, false},
    91  	"aes-128-cbc": {"cbc", 16, true},
    92  	"aes-192-cbc": {"cbc", 24, true},
    93  	"aes-256-cbc": {"cbc", 32, true},
    94  	"aes-128-ofb": {"ofb", 16, true},
    95  	"aes-192-ofb": {"ofb", 24, true},
    96  	"aes-256-ofb": {"ofb", 32, true},
    97  	"aes-128-cfb": {"cfb", 16, true},
    98  	"aes-192-cfb": {"cfb", 24, true},
    99  	"aes-256-cfb": {"cfb", 32, true},
   100  }
   101  
   102  type aesDecryptFunctionClass struct {
   103  	baseFunctionClass
   104  }
   105  
   106  func (c *aesDecryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   107  	if err := c.verifyArgs(args); err != nil {
   108  		return nil, c.verifyArgs(args)
   109  	}
   110  	argTps := make([]types.EvalType, 0, len(args))
   111  	for range args {
   112  		argTps = append(argTps, types.ETString)
   113  	}
   114  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, argTps...)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	bf.tp.Flen = args[0].GetType().Flen // At most.
   119  	types.SetBinChsClnFlag(bf.tp)
   120  
   121  	blockMode, _ := ctx.GetStochastikVars().GetSystemVar(variable.BlockEncryptionMode)
   122  	mode, exists := aesModes[strings.ToLower(blockMode)]
   123  	if !exists {
   124  		return nil, errors.Errorf("unsupported causet encryption mode - %v", blockMode)
   125  	}
   126  	if mode.ivRequired {
   127  		if len(args) != 3 {
   128  			return nil, ErrIncorrectParameterCount.GenWithStackByArgs("aes_decrypt")
   129  		}
   130  		sig := &builtinAesDecryptIVSig{bf, mode}
   131  		sig.setPbCode(fidelpb.ScalarFuncSig_AesDecryptIV)
   132  		return sig, nil
   133  	}
   134  	sig := &builtinAesDecryptSig{bf, mode}
   135  	sig.setPbCode(fidelpb.ScalarFuncSig_AesDecrypt)
   136  	return sig, nil
   137  }
   138  
   139  type builtinAesDecryptSig struct {
   140  	baseBuiltinFunc
   141  	*aesModeAttr
   142  }
   143  
   144  func (b *builtinAesDecryptSig) Clone() builtinFunc {
   145  	newSig := &builtinAesDecryptSig{}
   146  	newSig.cloneFrom(&b.baseBuiltinFunc)
   147  	newSig.aesModeAttr = b.aesModeAttr
   148  	return newSig
   149  }
   150  
   151  // evalString evals AES_DECRYPT(crypt_str, key_key).
   152  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   153  func (b *builtinAesDecryptSig) evalString(event chunk.Event) (string, bool, error) {
   154  	// According to doc: If either function argument is NULL, the function returns NULL.
   155  	cryptStr, isNull, err := b.args[0].EvalString(b.ctx, event)
   156  	if isNull || err != nil {
   157  		return "", true, err
   158  	}
   159  	keyStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   160  	if isNull || err != nil {
   161  		return "", true, err
   162  	}
   163  	if !b.ivRequired && len(b.args) == 3 {
   164  		// For modes that do not require init_vector, it is ignored and a warning is generated if it is specified.
   165  		b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV"))
   166  	}
   167  
   168  	key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize)
   169  	var plainText []byte
   170  	switch b.modeName {
   171  	case "ecb":
   172  		plainText, err = encrypt.AESDecryptWithECB([]byte(cryptStr), key)
   173  	default:
   174  		return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   175  	}
   176  	if err != nil {
   177  		return "", true, nil
   178  	}
   179  	return string(plainText), false, nil
   180  }
   181  
   182  type builtinAesDecryptIVSig struct {
   183  	baseBuiltinFunc
   184  	*aesModeAttr
   185  }
   186  
   187  func (b *builtinAesDecryptIVSig) Clone() builtinFunc {
   188  	newSig := &builtinAesDecryptIVSig{}
   189  	newSig.cloneFrom(&b.baseBuiltinFunc)
   190  	newSig.aesModeAttr = b.aesModeAttr
   191  	return newSig
   192  }
   193  
   194  // evalString evals AES_DECRYPT(crypt_str, key_key, iv).
   195  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   196  func (b *builtinAesDecryptIVSig) evalString(event chunk.Event) (string, bool, error) {
   197  	// According to doc: If either function argument is NULL, the function returns NULL.
   198  	cryptStr, isNull, err := b.args[0].EvalString(b.ctx, event)
   199  	if isNull || err != nil {
   200  		return "", true, err
   201  	}
   202  
   203  	keyStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   204  	if isNull || err != nil {
   205  		return "", true, err
   206  	}
   207  
   208  	iv, isNull, err := b.args[2].EvalString(b.ctx, event)
   209  	if isNull || err != nil {
   210  		return "", true, err
   211  	}
   212  	if len(iv) < aes.BlockSize {
   213  		return "", true, errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_decrypt is too short. Must be at least %d bytes long", aes.BlockSize)
   214  	}
   215  	// init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored)
   216  	iv = iv[0:aes.BlockSize]
   217  
   218  	key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize)
   219  	var plainText []byte
   220  	switch b.modeName {
   221  	case "cbc":
   222  		plainText, err = encrypt.AESDecryptWithCBC([]byte(cryptStr), key, []byte(iv))
   223  	case "ofb":
   224  		plainText, err = encrypt.AESDecryptWithOFB([]byte(cryptStr), key, []byte(iv))
   225  	case "cfb":
   226  		plainText, err = encrypt.AESDecryptWithCFB([]byte(cryptStr), key, []byte(iv))
   227  	default:
   228  		return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   229  	}
   230  	if err != nil {
   231  		return "", true, nil
   232  	}
   233  	return string(plainText), false, nil
   234  }
   235  
   236  type aesEncryptFunctionClass struct {
   237  	baseFunctionClass
   238  }
   239  
   240  func (c *aesEncryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   241  	if err := c.verifyArgs(args); err != nil {
   242  		return nil, c.verifyArgs(args)
   243  	}
   244  	argTps := make([]types.EvalType, 0, len(args))
   245  	for range args {
   246  		argTps = append(argTps, types.ETString)
   247  	}
   248  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, argTps...)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	bf.tp.Flen = aes.BlockSize * (args[0].GetType().Flen/aes.BlockSize + 1) // At most.
   253  	types.SetBinChsClnFlag(bf.tp)
   254  
   255  	blockMode, _ := ctx.GetStochastikVars().GetSystemVar(variable.BlockEncryptionMode)
   256  	mode, exists := aesModes[strings.ToLower(blockMode)]
   257  	if !exists {
   258  		return nil, errors.Errorf("unsupported causet encryption mode - %v", blockMode)
   259  	}
   260  	if mode.ivRequired {
   261  		if len(args) != 3 {
   262  			return nil, ErrIncorrectParameterCount.GenWithStackByArgs("aes_encrypt")
   263  		}
   264  		sig := &builtinAesEncryptIVSig{bf, mode}
   265  		sig.setPbCode(fidelpb.ScalarFuncSig_AesEncryptIV)
   266  		return sig, nil
   267  	}
   268  	sig := &builtinAesEncryptSig{bf, mode}
   269  	sig.setPbCode(fidelpb.ScalarFuncSig_AesEncrypt)
   270  	return sig, nil
   271  }
   272  
   273  type builtinAesEncryptSig struct {
   274  	baseBuiltinFunc
   275  	*aesModeAttr
   276  }
   277  
   278  func (b *builtinAesEncryptSig) Clone() builtinFunc {
   279  	newSig := &builtinAesEncryptSig{}
   280  	newSig.cloneFrom(&b.baseBuiltinFunc)
   281  	newSig.aesModeAttr = b.aesModeAttr
   282  	return newSig
   283  }
   284  
   285  // evalString evals AES_ENCRYPT(str, key_str).
   286  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   287  func (b *builtinAesEncryptSig) evalString(event chunk.Event) (string, bool, error) {
   288  	// According to doc: If either function argument is NULL, the function returns NULL.
   289  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
   290  	if isNull || err != nil {
   291  		return "", true, err
   292  	}
   293  	keyStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   294  	if isNull || err != nil {
   295  		return "", true, err
   296  	}
   297  	if !b.ivRequired && len(b.args) == 3 {
   298  		// For modes that do not require init_vector, it is ignored and a warning is generated if it is specified.
   299  		b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV"))
   300  	}
   301  
   302  	key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize)
   303  	var cipherText []byte
   304  	switch b.modeName {
   305  	case "ecb":
   306  		cipherText, err = encrypt.AESEncryptWithECB([]byte(str), key)
   307  	default:
   308  		return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   309  	}
   310  	if err != nil {
   311  		return "", true, nil
   312  	}
   313  	return string(cipherText), false, nil
   314  }
   315  
   316  type builtinAesEncryptIVSig struct {
   317  	baseBuiltinFunc
   318  	*aesModeAttr
   319  }
   320  
   321  func (b *builtinAesEncryptIVSig) Clone() builtinFunc {
   322  	newSig := &builtinAesEncryptIVSig{}
   323  	newSig.cloneFrom(&b.baseBuiltinFunc)
   324  	newSig.aesModeAttr = b.aesModeAttr
   325  	return newSig
   326  }
   327  
   328  // evalString evals AES_ENCRYPT(str, key_str, iv).
   329  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   330  func (b *builtinAesEncryptIVSig) evalString(event chunk.Event) (string, bool, error) {
   331  	// According to doc: If either function argument is NULL, the function returns NULL.
   332  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
   333  	if isNull || err != nil {
   334  		return "", true, err
   335  	}
   336  
   337  	keyStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   338  	if isNull || err != nil {
   339  		return "", true, err
   340  	}
   341  
   342  	iv, isNull, err := b.args[2].EvalString(b.ctx, event)
   343  	if isNull || err != nil {
   344  		return "", true, err
   345  	}
   346  	if len(iv) < aes.BlockSize {
   347  		return "", true, errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_encrypt is too short. Must be at least %d bytes long", aes.BlockSize)
   348  	}
   349  	// init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored)
   350  	iv = iv[0:aes.BlockSize]
   351  
   352  	key := encrypt.DeriveKeyMyALLEGROSQL([]byte(keyStr), b.keySize)
   353  	var cipherText []byte
   354  	switch b.modeName {
   355  	case "cbc":
   356  		cipherText, err = encrypt.AESEncryptWithCBC([]byte(str), key, []byte(iv))
   357  	case "ofb":
   358  		cipherText, err = encrypt.AESEncryptWithOFB([]byte(str), key, []byte(iv))
   359  	case "cfb":
   360  		cipherText, err = encrypt.AESEncryptWithCFB([]byte(str), key, []byte(iv))
   361  	default:
   362  		return "", true, errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   363  	}
   364  	if err != nil {
   365  		return "", true, nil
   366  	}
   367  	return string(cipherText), false, nil
   368  }
   369  
   370  type decodeFunctionClass struct {
   371  	baseFunctionClass
   372  }
   373  
   374  func (c *decodeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   375  	if err := c.verifyArgs(args); err != nil {
   376  		return nil, err
   377  	}
   378  
   379  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETString)
   380  	if err != nil {
   381  		return nil, err
   382  	}
   383  
   384  	bf.tp.Flen = args[0].GetType().Flen
   385  	sig := &builtinDecodeSig{bf}
   386  	sig.setPbCode(fidelpb.ScalarFuncSig_Decode)
   387  	return sig, nil
   388  }
   389  
   390  type builtinDecodeSig struct {
   391  	baseBuiltinFunc
   392  }
   393  
   394  func (b *builtinDecodeSig) Clone() builtinFunc {
   395  	newSig := &builtinDecodeSig{}
   396  	newSig.cloneFrom(&b.baseBuiltinFunc)
   397  	return newSig
   398  }
   399  
   400  // evalString evals DECODE(str, password_str).
   401  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_decode
   402  func (b *builtinDecodeSig) evalString(event chunk.Event) (string, bool, error) {
   403  	dataStr, isNull, err := b.args[0].EvalString(b.ctx, event)
   404  	if isNull || err != nil {
   405  		return "", true, err
   406  	}
   407  
   408  	passwordStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   409  	if isNull || err != nil {
   410  		return "", true, err
   411  	}
   412  
   413  	decodeStr, err := encrypt.ALLEGROSQLDecode(dataStr, passwordStr)
   414  	return decodeStr, false, err
   415  }
   416  
   417  type desDecryptFunctionClass struct {
   418  	baseFunctionClass
   419  }
   420  
   421  func (c *desDecryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   422  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_DECRYPT")
   423  }
   424  
   425  type desEncryptFunctionClass struct {
   426  	baseFunctionClass
   427  }
   428  
   429  func (c *desEncryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   430  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_ENCRYPT")
   431  }
   432  
   433  type encodeFunctionClass struct {
   434  	baseFunctionClass
   435  }
   436  
   437  func (c *encodeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   438  	if err := c.verifyArgs(args); err != nil {
   439  		return nil, err
   440  	}
   441  
   442  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETString)
   443  	if err != nil {
   444  		return nil, err
   445  	}
   446  
   447  	bf.tp.Flen = args[0].GetType().Flen
   448  	sig := &builtinEncodeSig{bf}
   449  	sig.setPbCode(fidelpb.ScalarFuncSig_Encode)
   450  	return sig, nil
   451  }
   452  
   453  type builtinEncodeSig struct {
   454  	baseBuiltinFunc
   455  }
   456  
   457  func (b *builtinEncodeSig) Clone() builtinFunc {
   458  	newSig := &builtinEncodeSig{}
   459  	newSig.cloneFrom(&b.baseBuiltinFunc)
   460  	return newSig
   461  }
   462  
   463  // evalString evals ENCODE(crypt_str, password_str).
   464  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_encode
   465  func (b *builtinEncodeSig) evalString(event chunk.Event) (string, bool, error) {
   466  	decodeStr, isNull, err := b.args[0].EvalString(b.ctx, event)
   467  	if isNull || err != nil {
   468  		return "", true, err
   469  	}
   470  
   471  	passwordStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   472  	if isNull || err != nil {
   473  		return "", true, err
   474  	}
   475  
   476  	dataStr, err := encrypt.ALLEGROSQLEncode(decodeStr, passwordStr)
   477  	return dataStr, false, err
   478  }
   479  
   480  type encryptFunctionClass struct {
   481  	baseFunctionClass
   482  }
   483  
   484  func (c *encryptFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   485  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "ENCRYPT")
   486  }
   487  
   488  type oldPasswordFunctionClass struct {
   489  	baseFunctionClass
   490  }
   491  
   492  func (c *oldPasswordFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   493  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "OLD_PASSWORD")
   494  }
   495  
   496  type passwordFunctionClass struct {
   497  	baseFunctionClass
   498  }
   499  
   500  func (c *passwordFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   501  	if err := c.verifyArgs(args); err != nil {
   502  		return nil, err
   503  	}
   504  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   505  	if err != nil {
   506  		return nil, err
   507  	}
   508  	bf.tp.Flen = allegrosql.PWDHashLen + 1
   509  	sig := &builtinPasswordSig{bf}
   510  	sig.setPbCode(fidelpb.ScalarFuncSig_Password)
   511  	return sig, nil
   512  }
   513  
   514  type builtinPasswordSig struct {
   515  	baseBuiltinFunc
   516  }
   517  
   518  func (b *builtinPasswordSig) Clone() builtinFunc {
   519  	newSig := &builtinPasswordSig{}
   520  	newSig.cloneFrom(&b.baseBuiltinFunc)
   521  	return newSig
   522  }
   523  
   524  // evalString evals a builtinPasswordSig.
   525  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_password
   526  func (b *builtinPasswordSig) evalString(event chunk.Event) (d string, isNull bool, err error) {
   527  	pass, isNull, err := b.args[0].EvalString(b.ctx, event)
   528  	if isNull || err != nil {
   529  		return "", err != nil, err
   530  	}
   531  
   532  	if len(pass) == 0 {
   533  		return "", false, nil
   534  	}
   535  
   536  	// We should append a warning here because function "PASSWORD" is deprecated since MyALLEGROSQL 5.7.6.
   537  	// See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_password
   538  	b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoRememristed.GenWithStackByArgs("PASSWORD"))
   539  
   540  	return auth.EncodePassword(pass), false, nil
   541  }
   542  
   543  type randomBytesFunctionClass struct {
   544  	baseFunctionClass
   545  }
   546  
   547  func (c *randomBytesFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   548  	if err := c.verifyArgs(args); err != nil {
   549  		return nil, err
   550  	}
   551  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETInt)
   552  	if err != nil {
   553  		return nil, err
   554  	}
   555  	bf.tp.Flen = 1024 // Max allowed random bytes
   556  	types.SetBinChsClnFlag(bf.tp)
   557  	sig := &builtinRandomBytesSig{bf}
   558  	return sig, nil
   559  }
   560  
   561  type builtinRandomBytesSig struct {
   562  	baseBuiltinFunc
   563  }
   564  
   565  func (b *builtinRandomBytesSig) Clone() builtinFunc {
   566  	newSig := &builtinRandomBytesSig{}
   567  	newSig.cloneFrom(&b.baseBuiltinFunc)
   568  	return newSig
   569  }
   570  
   571  // evalString evals RANDOM_BYTES(len).
   572  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_random-bytes
   573  func (b *builtinRandomBytesSig) evalString(event chunk.Event) (string, bool, error) {
   574  	len, isNull, err := b.args[0].EvalInt(b.ctx, event)
   575  	if isNull || err != nil {
   576  		return "", true, err
   577  	}
   578  	if len < 1 || len > 1024 {
   579  		return "", false, types.ErrOverflow.GenWithStackByArgs("length", "random_bytes")
   580  	}
   581  	buf := make([]byte, len)
   582  	if n, err := rand.Read(buf); err != nil {
   583  		return "", true, err
   584  	} else if int64(n) != len {
   585  		return "", false, errors.New("fail to generate random bytes")
   586  	}
   587  	return string(buf), false, nil
   588  }
   589  
   590  type md5FunctionClass struct {
   591  	baseFunctionClass
   592  }
   593  
   594  func (c *md5FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   595  	if err := c.verifyArgs(args); err != nil {
   596  		return nil, err
   597  	}
   598  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   599  	if err != nil {
   600  		return nil, err
   601  	}
   602  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   603  	bf.tp.Flen = 32
   604  	sig := &builtinMD5Sig{bf}
   605  	sig.setPbCode(fidelpb.ScalarFuncSig_MD5)
   606  	return sig, nil
   607  }
   608  
   609  type builtinMD5Sig struct {
   610  	baseBuiltinFunc
   611  }
   612  
   613  func (b *builtinMD5Sig) Clone() builtinFunc {
   614  	newSig := &builtinMD5Sig{}
   615  	newSig.cloneFrom(&b.baseBuiltinFunc)
   616  	return newSig
   617  }
   618  
   619  // evalString evals a builtinMD5Sig.
   620  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_md5
   621  func (b *builtinMD5Sig) evalString(event chunk.Event) (string, bool, error) {
   622  	arg, isNull, err := b.args[0].EvalString(b.ctx, event)
   623  	if isNull || err != nil {
   624  		return "", isNull, err
   625  	}
   626  	sum := md5.Sum([]byte(arg))
   627  	hexStr := fmt.Sprintf("%x", sum)
   628  	return hexStr, false, nil
   629  }
   630  
   631  type sha1FunctionClass struct {
   632  	baseFunctionClass
   633  }
   634  
   635  func (c *sha1FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   636  	if err := c.verifyArgs(args); err != nil {
   637  		return nil, err
   638  	}
   639  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   640  	if err != nil {
   641  		return nil, err
   642  	}
   643  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   644  	bf.tp.Flen = 40
   645  	sig := &builtinSHA1Sig{bf}
   646  	sig.setPbCode(fidelpb.ScalarFuncSig_SHA1)
   647  	return sig, nil
   648  }
   649  
   650  type builtinSHA1Sig struct {
   651  	baseBuiltinFunc
   652  }
   653  
   654  func (b *builtinSHA1Sig) Clone() builtinFunc {
   655  	newSig := &builtinSHA1Sig{}
   656  	newSig.cloneFrom(&b.baseBuiltinFunc)
   657  	return newSig
   658  }
   659  
   660  // evalString evals SHA1(str).
   661  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_sha1
   662  // The value is returned as a string of 40 hexadecimal digits, or NULL if the argument was NULL.
   663  func (b *builtinSHA1Sig) evalString(event chunk.Event) (string, bool, error) {
   664  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
   665  	if isNull || err != nil {
   666  		return "", isNull, err
   667  	}
   668  	hasher := sha1.New()
   669  	_, err = hasher.Write([]byte(str))
   670  	if err != nil {
   671  		return "", true, err
   672  	}
   673  	return fmt.Sprintf("%x", hasher.Sum(nil)), false, nil
   674  }
   675  
   676  type sha2FunctionClass struct {
   677  	baseFunctionClass
   678  }
   679  
   680  func (c *sha2FunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   681  	if err := c.verifyArgs(args); err != nil {
   682  		return nil, err
   683  	}
   684  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETInt)
   685  	if err != nil {
   686  		return nil, err
   687  	}
   688  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   689  	bf.tp.Flen = 128 // sha512
   690  	sig := &builtinSHA2Sig{bf}
   691  	sig.setPbCode(fidelpb.ScalarFuncSig_SHA2)
   692  	return sig, nil
   693  }
   694  
   695  type builtinSHA2Sig struct {
   696  	baseBuiltinFunc
   697  }
   698  
   699  func (b *builtinSHA2Sig) Clone() builtinFunc {
   700  	newSig := &builtinSHA2Sig{}
   701  	newSig.cloneFrom(&b.baseBuiltinFunc)
   702  	return newSig
   703  }
   704  
   705  // Supported hash length of SHA-2 family
   706  const (
   707  	SHA0   = 0
   708  	SHA224 = 224
   709  	SHA256 = 256
   710  	SHA384 = 384
   711  	SHA512 = 512
   712  )
   713  
   714  // evalString evals SHA2(str, hash_length).
   715  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_sha2
   716  func (b *builtinSHA2Sig) evalString(event chunk.Event) (string, bool, error) {
   717  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
   718  	if isNull || err != nil {
   719  		return "", isNull, err
   720  	}
   721  	hashLength, isNull, err := b.args[1].EvalInt(b.ctx, event)
   722  	if isNull || err != nil {
   723  		return "", isNull, err
   724  	}
   725  	var hasher hash.Hash
   726  	switch int(hashLength) {
   727  	case SHA0, SHA256:
   728  		hasher = sha256.New()
   729  	case SHA224:
   730  		hasher = sha256.New224()
   731  	case SHA384:
   732  		hasher = sha512.New384()
   733  	case SHA512:
   734  		hasher = sha512.New()
   735  	}
   736  	if hasher == nil {
   737  		return "", true, nil
   738  	}
   739  
   740  	_, err = hasher.Write([]byte(str))
   741  	if err != nil {
   742  		return "", true, err
   743  	}
   744  	return fmt.Sprintf("%x", hasher.Sum(nil)), false, nil
   745  }
   746  
   747  // deflate compresses a string using the DEFLATE format.
   748  func deflate(data []byte) ([]byte, error) {
   749  	var buffer bytes.Buffer
   750  	w := zlib.NewWriter(&buffer)
   751  	if _, err := w.Write(data); err != nil {
   752  		return nil, err
   753  	}
   754  	if err := w.Close(); err != nil {
   755  		return nil, err
   756  	}
   757  	return buffer.Bytes(), nil
   758  }
   759  
   760  // inflate uncompresses a string using the DEFLATE format.
   761  func inflate(compressStr []byte) ([]byte, error) {
   762  	reader := bytes.NewReader(compressStr)
   763  	var out bytes.Buffer
   764  	r, err := zlib.NewReader(reader)
   765  	if err != nil {
   766  		return nil, err
   767  	}
   768  	if _, err = io.Copy(&out, r); err != nil {
   769  		return nil, err
   770  	}
   771  	err = r.Close()
   772  	return out.Bytes(), err
   773  }
   774  
   775  type compressFunctionClass struct {
   776  	baseFunctionClass
   777  }
   778  
   779  func (c *compressFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   780  	if err := c.verifyArgs(args); err != nil {
   781  		return nil, err
   782  	}
   783  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   784  	if err != nil {
   785  		return nil, err
   786  	}
   787  	srcLen := args[0].GetType().Flen
   788  	compressBound := srcLen + (srcLen >> 12) + (srcLen >> 14) + (srcLen >> 25) + 13
   789  	if compressBound > allegrosql.MaxBlobWidth {
   790  		compressBound = allegrosql.MaxBlobWidth
   791  	}
   792  	bf.tp.Flen = compressBound
   793  	types.SetBinChsClnFlag(bf.tp)
   794  	sig := &builtinCompressSig{bf}
   795  	sig.setPbCode(fidelpb.ScalarFuncSig_Compress)
   796  	return sig, nil
   797  }
   798  
   799  type builtinCompressSig struct {
   800  	baseBuiltinFunc
   801  }
   802  
   803  func (b *builtinCompressSig) Clone() builtinFunc {
   804  	newSig := &builtinCompressSig{}
   805  	newSig.cloneFrom(&b.baseBuiltinFunc)
   806  	return newSig
   807  }
   808  
   809  // evalString evals COMPRESS(str).
   810  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_compress
   811  func (b *builtinCompressSig) evalString(event chunk.Event) (string, bool, error) {
   812  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
   813  	if isNull || err != nil {
   814  		return "", true, err
   815  	}
   816  
   817  	// According to doc: Empty strings are stored as empty strings.
   818  	if len(str) == 0 {
   819  		return "", false, nil
   820  	}
   821  
   822  	compressed, err := deflate([]byte(str))
   823  	if err != nil {
   824  		return "", true, nil
   825  	}
   826  
   827  	resultLength := 4 + len(compressed)
   828  
   829  	// append "." if ends with space
   830  	shouldAppendSuffix := compressed[len(compressed)-1] == 32
   831  	if shouldAppendSuffix {
   832  		resultLength++
   833  	}
   834  
   835  	buffer := make([]byte, resultLength)
   836  	binary.LittleEndian.PutUint32(buffer, uint32(len(str)))
   837  	copy(buffer[4:], compressed)
   838  
   839  	if shouldAppendSuffix {
   840  		buffer[len(buffer)-1] = '.'
   841  	}
   842  
   843  	return string(buffer), false, nil
   844  }
   845  
   846  type uncompressFunctionClass struct {
   847  	baseFunctionClass
   848  }
   849  
   850  func (c *uncompressFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   851  	if err := c.verifyArgs(args); err != nil {
   852  		return nil, err
   853  	}
   854  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   855  	if err != nil {
   856  		return nil, err
   857  	}
   858  	bf.tp.Flen = allegrosql.MaxBlobWidth
   859  	types.SetBinChsClnFlag(bf.tp)
   860  	sig := &builtinUncompressSig{bf}
   861  	sig.setPbCode(fidelpb.ScalarFuncSig_Uncompress)
   862  	return sig, nil
   863  }
   864  
   865  type builtinUncompressSig struct {
   866  	baseBuiltinFunc
   867  }
   868  
   869  func (b *builtinUncompressSig) Clone() builtinFunc {
   870  	newSig := &builtinUncompressSig{}
   871  	newSig.cloneFrom(&b.baseBuiltinFunc)
   872  	return newSig
   873  }
   874  
   875  // evalString evals UNCOMPRESS(compressed_string).
   876  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompress
   877  func (b *builtinUncompressSig) evalString(event chunk.Event) (string, bool, error) {
   878  	sc := b.ctx.GetStochastikVars().StmtCtx
   879  	payload, isNull, err := b.args[0].EvalString(b.ctx, event)
   880  	if isNull || err != nil {
   881  		return "", true, err
   882  	}
   883  	if len(payload) == 0 {
   884  		return "", false, nil
   885  	}
   886  	if len(payload) <= 4 {
   887  		// corrupted
   888  		sc.AppendWarning(errZlibZData)
   889  		return "", true, nil
   890  	}
   891  	length := binary.LittleEndian.Uint32([]byte(payload[0:4]))
   892  	bytes, err := inflate([]byte(payload[4:]))
   893  	if err != nil {
   894  		sc.AppendWarning(errZlibZData)
   895  		return "", true, nil
   896  	}
   897  	if length < uint32(len(bytes)) {
   898  		sc.AppendWarning(errZlibZBuf)
   899  		return "", true, nil
   900  	}
   901  	return string(bytes), false, nil
   902  }
   903  
   904  type uncompressedLengthFunctionClass struct {
   905  	baseFunctionClass
   906  }
   907  
   908  func (c *uncompressedLengthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   909  	if err := c.verifyArgs(args); err != nil {
   910  		return nil, err
   911  	}
   912  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString)
   913  	if err != nil {
   914  		return nil, err
   915  	}
   916  	bf.tp.Flen = 10
   917  	sig := &builtinUncompressedLengthSig{bf}
   918  	sig.setPbCode(fidelpb.ScalarFuncSig_UncompressedLength)
   919  	return sig, nil
   920  }
   921  
   922  type builtinUncompressedLengthSig struct {
   923  	baseBuiltinFunc
   924  }
   925  
   926  func (b *builtinUncompressedLengthSig) Clone() builtinFunc {
   927  	newSig := &builtinUncompressedLengthSig{}
   928  	newSig.cloneFrom(&b.baseBuiltinFunc)
   929  	return newSig
   930  }
   931  
   932  // evalInt evals UNCOMPRESSED_LENGTH(str).
   933  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompressed-length
   934  func (b *builtinUncompressedLengthSig) evalInt(event chunk.Event) (int64, bool, error) {
   935  	sc := b.ctx.GetStochastikVars().StmtCtx
   936  	payload, isNull, err := b.args[0].EvalString(b.ctx, event)
   937  	if isNull || err != nil {
   938  		return 0, true, err
   939  	}
   940  	if len(payload) == 0 {
   941  		return 0, false, nil
   942  	}
   943  	if len(payload) <= 4 {
   944  		// corrupted
   945  		sc.AppendWarning(errZlibZData)
   946  		return 0, false, nil
   947  	}
   948  	len := binary.LittleEndian.Uint32([]byte(payload)[0:4])
   949  	return int64(len), false, nil
   950  }
   951  
   952  type validatePasswordStrengthFunctionClass struct {
   953  	baseFunctionClass
   954  }
   955  
   956  func (c *validatePasswordStrengthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   957  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "VALIDATE_PASSWORD_STRENGTH")
   958  }