github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_encryption_vec.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  	"crypto/aes"
    19  	"crypto/md5"
    20  	"crypto/rand"
    21  	"crypto/sha1"
    22  	"crypto/sha256"
    23  	"crypto/sha512"
    24  	"encoding/binary"
    25  	"fmt"
    26  	"hash"
    27  	"io"
    28  	"sync"
    29  
    30  	"github.com/whtcorpsinc/errors"
    31  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    32  	"github.com/whtcorpsinc/milevadb/types"
    33  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    34  	"github.com/whtcorpsinc/milevadb/soliton/encrypt"
    35  	"github.com/whtcorpsinc/milevadb/soliton/replog"
    36  )
    37  
    38  func (b *builtinAesDecryptSig) vectorized() bool {
    39  	return true
    40  }
    41  
    42  func (b *builtinAesDecryptSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
    43  	n := input.NumEvents()
    44  	strBuf, err := b.bufSlabPredictor.get(types.ETString, n)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	defer b.bufSlabPredictor.put(strBuf)
    49  	if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil {
    50  		return err
    51  	}
    52  
    53  	keyBuf, err := b.bufSlabPredictor.get(types.ETString, n)
    54  	if err != nil {
    55  		return err
    56  	}
    57  	defer b.bufSlabPredictor.put(keyBuf)
    58  	if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil {
    59  		return err
    60  	}
    61  
    62  	if b.modeName != "ecb" {
    63  		return errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
    64  	}
    65  
    66  	isWarning := !b.ivRequired && len(b.args) == 3
    67  	isConstKey := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx)
    68  
    69  	var key []byte
    70  	if isConstKey {
    71  		key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize)
    72  	}
    73  
    74  	result.ReserveString(n)
    75  	stmtCtx := b.ctx.GetStochastikVars().StmtCtx
    76  	for i := 0; i < n; i++ {
    77  		// According to doc: If either function argument is NULL, the function returns NULL.
    78  		if strBuf.IsNull(i) || keyBuf.IsNull(i) {
    79  			result.AppendNull()
    80  			continue
    81  		}
    82  		if isWarning {
    83  			// For modes that do not require init_vector, it is ignored and a warning is generated if it is specified.
    84  			stmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV"))
    85  		}
    86  		if !isConstKey {
    87  			key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize)
    88  		}
    89  		// ANNOTATION:
    90  		// we can't use GetBytes here because GetBytes return raw memory in strBuf,
    91  		// and the memory will be modified in AESEncryptWithECB & AESDecryptWithECB
    92  		str := []byte(strBuf.GetString(i))
    93  		plainText, err := encrypt.AESDecryptWithECB(str, key)
    94  		if err != nil {
    95  			result.AppendNull()
    96  			continue
    97  		}
    98  		result.AppendBytes(plainText)
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  func (b *builtinAesEncryptIVSig) vectorized() bool {
   105  	return true
   106  }
   107  
   108  // evalString evals AES_ENCRYPT(str, key_str, iv).
   109  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   110  func (b *builtinAesEncryptIVSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   111  	n := input.NumEvents()
   112  	strBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   113  	if err != nil {
   114  		return err
   115  	}
   116  	defer b.bufSlabPredictor.put(strBuf)
   117  	if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil {
   118  		return err
   119  	}
   120  
   121  	keyBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   122  	if err != nil {
   123  		return err
   124  	}
   125  	defer b.bufSlabPredictor.put(keyBuf)
   126  	if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil {
   127  		return err
   128  	}
   129  
   130  	ivBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   131  	if err != nil {
   132  		return err
   133  	}
   134  	defer b.bufSlabPredictor.put(ivBuf)
   135  	if err := b.args[2].VecEvalString(b.ctx, input, ivBuf); err != nil {
   136  		return err
   137  	}
   138  
   139  	isCBC := false
   140  	isOFB := false
   141  	isCFB := false
   142  	switch b.modeName {
   143  	case "cbc":
   144  		isCBC = true
   145  	case "ofb":
   146  		isOFB = true
   147  	case "cfb":
   148  		isCFB = true
   149  	default:
   150  		return errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   151  	}
   152  
   153  	isConst := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx)
   154  	var key []byte
   155  	if isConst {
   156  		key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize)
   157  	}
   158  
   159  	result.ReserveString(n)
   160  	for i := 0; i < n; i++ {
   161  		// According to doc: If either function argument is NULL, the function returns NULL.
   162  		if strBuf.IsNull(i) || keyBuf.IsNull(i) || ivBuf.IsNull(i) {
   163  			result.AppendNull()
   164  			continue
   165  		}
   166  
   167  		iv := ivBuf.GetBytes(i)
   168  		if len(iv) < aes.BlockSize {
   169  			return errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_encrypt is too short. Must be at least %d bytes long", aes.BlockSize)
   170  		}
   171  		// init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored)
   172  		iv = iv[0:aes.BlockSize]
   173  		if !isConst {
   174  			key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize)
   175  		}
   176  		var cipherText []byte
   177  
   178  		// ANNOTATION:
   179  		// we can't use GetBytes here because GetBytes return raw memory in strBuf,
   180  		// and the memory will be modified in AESEncryptWithCBC & AESEncryptWithOFB & AESEncryptWithCFB
   181  		if isCBC {
   182  			cipherText, err = encrypt.AESEncryptWithCBC([]byte(strBuf.GetString(i)), key, iv)
   183  		}
   184  		if isOFB {
   185  			cipherText, err = encrypt.AESEncryptWithOFB([]byte(strBuf.GetString(i)), key, iv)
   186  		}
   187  		if isCFB {
   188  			cipherText, err = encrypt.AESEncryptWithCFB([]byte(strBuf.GetString(i)), key, iv)
   189  		}
   190  		if err != nil {
   191  			result.AppendNull()
   192  			continue
   193  		}
   194  		result.AppendBytes(cipherText)
   195  	}
   196  	return nil
   197  }
   198  
   199  func (b *builtinDecodeSig) vectorized() bool {
   200  	return true
   201  }
   202  
   203  func (b *builtinDecodeSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   204  	n := input.NumEvents()
   205  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   206  	if err != nil {
   207  		return err
   208  	}
   209  	defer b.bufSlabPredictor.put(buf)
   210  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   211  		return err
   212  	}
   213  	buf1, err1 := b.bufSlabPredictor.get(types.ETString, n)
   214  	if err1 != nil {
   215  		return err1
   216  	}
   217  	defer b.bufSlabPredictor.put(buf1)
   218  	if err := b.args[1].VecEvalString(b.ctx, input, buf1); err != nil {
   219  		return err
   220  	}
   221  	result.ReserveString(n)
   222  	for i := 0; i < n; i++ {
   223  		if buf.IsNull(i) || buf1.IsNull(i) {
   224  			result.AppendNull()
   225  			continue
   226  		}
   227  		dataStr := buf.GetString(i)
   228  		passwordStr := buf1.GetString(i)
   229  		decodeStr, err := encrypt.ALLEGROSQLDecode(dataStr, passwordStr)
   230  		if err != nil {
   231  			return err
   232  		}
   233  		result.AppendString(decodeStr)
   234  	}
   235  	return nil
   236  }
   237  
   238  func (b *builtinEncodeSig) vectorized() bool {
   239  	return true
   240  }
   241  
   242  func (b *builtinEncodeSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   243  	n := input.NumEvents()
   244  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   245  	if err != nil {
   246  		return err
   247  	}
   248  	defer b.bufSlabPredictor.put(buf)
   249  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   250  		return err
   251  	}
   252  	buf1, err1 := b.bufSlabPredictor.get(types.ETString, n)
   253  	if err1 != nil {
   254  		return err1
   255  	}
   256  	defer b.bufSlabPredictor.put(buf1)
   257  	if err := b.args[1].VecEvalString(b.ctx, input, buf1); err != nil {
   258  		return err
   259  	}
   260  	result.ReserveString(n)
   261  	for i := 0; i < n; i++ {
   262  		if buf.IsNull(i) || buf1.IsNull(i) {
   263  			result.AppendNull()
   264  			continue
   265  		}
   266  		decodeStr := buf.GetString(i)
   267  		passwordStr := buf1.GetString(i)
   268  		dataStr, err := encrypt.ALLEGROSQLEncode(decodeStr, passwordStr)
   269  		if err != nil {
   270  			return err
   271  		}
   272  		result.AppendString(dataStr)
   273  	}
   274  	return nil
   275  }
   276  
   277  func (b *builtinAesDecryptIVSig) vectorized() bool {
   278  	return true
   279  }
   280  
   281  // evalString evals AES_DECRYPT(crypt_str, key_key, iv).
   282  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   283  func (b *builtinAesDecryptIVSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   284  	n := input.NumEvents()
   285  	strBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   286  	if err != nil {
   287  		return err
   288  	}
   289  	defer b.bufSlabPredictor.put(strBuf)
   290  	if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil {
   291  		return err
   292  	}
   293  
   294  	keyBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   295  	if err != nil {
   296  		return err
   297  	}
   298  	defer b.bufSlabPredictor.put(keyBuf)
   299  	if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil {
   300  		return err
   301  	}
   302  
   303  	ivBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   304  	if err != nil {
   305  		return err
   306  	}
   307  	defer b.bufSlabPredictor.put(ivBuf)
   308  	if err := b.args[2].VecEvalString(b.ctx, input, ivBuf); err != nil {
   309  		return err
   310  	}
   311  
   312  	isCBC := false
   313  	isOFB := false
   314  	isCFB := false
   315  	switch b.modeName {
   316  	case "cbc":
   317  		isCBC = true
   318  	case "ofb":
   319  		isOFB = true
   320  	case "cfb":
   321  		isCFB = true
   322  	default:
   323  		return errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   324  	}
   325  
   326  	isConst := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx)
   327  	var key []byte
   328  	if isConst {
   329  		key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize)
   330  	}
   331  
   332  	result.ReserveString(n)
   333  	for i := 0; i < n; i++ {
   334  		// According to doc: If either function argument is NULL, the function returns NULL.
   335  		if strBuf.IsNull(i) || keyBuf.IsNull(i) || ivBuf.IsNull(i) {
   336  			result.AppendNull()
   337  			continue
   338  		}
   339  
   340  		iv := ivBuf.GetBytes(i)
   341  		if len(iv) < aes.BlockSize {
   342  			return errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_decrypt is too short. Must be at least %d bytes long", aes.BlockSize)
   343  		}
   344  		// init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored)
   345  		iv = iv[0:aes.BlockSize]
   346  		if !isConst {
   347  			key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize)
   348  		}
   349  		var plainText []byte
   350  
   351  		// ANNOTATION:
   352  		// we can't use GetBytes here because GetBytes return raw memory in strBuf,
   353  		// and the memory will be modified in AESDecryptWithCBC & AESDecryptWithOFB & AESDecryptWithCFB
   354  		if isCBC {
   355  			plainText, err = encrypt.AESDecryptWithCBC([]byte(strBuf.GetString(i)), key, iv)
   356  		}
   357  		if isOFB {
   358  			plainText, err = encrypt.AESDecryptWithOFB([]byte(strBuf.GetString(i)), key, iv)
   359  		}
   360  		if isCFB {
   361  			plainText, err = encrypt.AESDecryptWithCFB([]byte(strBuf.GetString(i)), key, iv)
   362  		}
   363  		if err != nil {
   364  			result.AppendNull()
   365  			continue
   366  		}
   367  		result.AppendBytes(plainText)
   368  	}
   369  	return nil
   370  }
   371  
   372  func (b *builtinRandomBytesSig) vectorized() bool {
   373  	return true
   374  }
   375  
   376  func (b *builtinRandomBytesSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   377  	n := input.NumEvents()
   378  	buf, err := b.bufSlabPredictor.get(types.ETInt, n)
   379  	if err != nil {
   380  		return err
   381  	}
   382  	defer b.bufSlabPredictor.put(buf)
   383  	if err := b.args[0].VecEvalInt(b.ctx, input, buf); err != nil {
   384  		return err
   385  	}
   386  	result.ReserveString(n)
   387  	i64s := buf.Int64s()
   388  	var dst bytes.Buffer
   389  	for i := 0; i < n; i++ {
   390  		if buf.IsNull(i) {
   391  			result.AppendNull()
   392  			continue
   393  		}
   394  		byteLen := i64s[i]
   395  		if byteLen < 1 || byteLen > 1024 {
   396  			return types.ErrOverflow.GenWithStackByArgs("length", "random_bytes")
   397  		}
   398  		if n, err := io.CopyN(&dst, rand.Reader, byteLen); err != nil {
   399  			return err
   400  		} else if n != byteLen {
   401  			return errors.New("fail to generate random bytes")
   402  		}
   403  		result.AppendBytes(dst.Bytes())
   404  		dst.Reset()
   405  	}
   406  	return nil
   407  }
   408  
   409  func (b *builtinMD5Sig) vectorized() bool {
   410  	return true
   411  }
   412  
   413  func (b *builtinMD5Sig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   414  	n := input.NumEvents()
   415  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   416  	if err != nil {
   417  		return err
   418  	}
   419  	defer b.bufSlabPredictor.put(buf)
   420  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   421  		return err
   422  	}
   423  	result.ReserveString(n)
   424  	digest := md5.New()
   425  	for i := 0; i < n; i++ {
   426  		if buf.IsNull(i) {
   427  			result.AppendNull()
   428  			continue
   429  		}
   430  		cryptByte := buf.GetBytes(i)
   431  		_, err := digest.Write(cryptByte)
   432  		if err != nil {
   433  			return err
   434  		}
   435  		result.AppendString(fmt.Sprintf("%x", digest.Sum(nil)))
   436  		digest.Reset()
   437  	}
   438  	return nil
   439  }
   440  
   441  func (b *builtinSHA2Sig) vectorized() bool {
   442  	return true
   443  }
   444  
   445  // vecEvalString evals SHA2(str, hash_length).
   446  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_sha2
   447  func (b *builtinSHA2Sig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   448  	n := input.NumEvents()
   449  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   450  	if err != nil {
   451  		return err
   452  	}
   453  	defer b.bufSlabPredictor.put(buf)
   454  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   455  		return err
   456  	}
   457  	buf1, err := b.bufSlabPredictor.get(types.ETInt, n)
   458  	if err != nil {
   459  		return err
   460  	}
   461  	defer b.bufSlabPredictor.put(buf1)
   462  	if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil {
   463  		return err
   464  	}
   465  	result.ReserveString(n)
   466  	i64s := buf1.Int64s()
   467  	var (
   468  		hasher224 hash.Hash
   469  		hasher256 hash.Hash
   470  		hasher384 hash.Hash
   471  		hasher512 hash.Hash
   472  	)
   473  	for i := 0; i < n; i++ {
   474  		if buf.IsNull(i) || buf1.IsNull(i) {
   475  			result.AppendNull()
   476  			continue
   477  		}
   478  		hashLength := i64s[i]
   479  		var hasher hash.Hash
   480  		switch int(hashLength) {
   481  		case SHA0, SHA256:
   482  			if hasher256 == nil {
   483  				hasher256 = sha256.New()
   484  			}
   485  			hasher = hasher256
   486  		case SHA224:
   487  			if hasher224 == nil {
   488  				hasher224 = sha256.New224()
   489  			}
   490  			hasher = hasher224
   491  		case SHA384:
   492  			if hasher384 == nil {
   493  				hasher384 = sha512.New384()
   494  			}
   495  			hasher = hasher384
   496  		case SHA512:
   497  			if hasher512 == nil {
   498  				hasher512 = sha512.New()
   499  			}
   500  			hasher = hasher512
   501  		}
   502  		if hasher == nil {
   503  			result.AppendNull()
   504  			continue
   505  		}
   506  
   507  		str := buf.GetBytes(i)
   508  		_, err = hasher.Write(str)
   509  		if err != nil {
   510  			return err
   511  		}
   512  		result.AppendString(fmt.Sprintf("%x", hasher.Sum(nil)))
   513  		hasher.Reset()
   514  	}
   515  	return nil
   516  }
   517  
   518  func (b *builtinCompressSig) vectorized() bool {
   519  	return true
   520  }
   521  
   522  var (
   523  	defaultByteSliceSize = 1024
   524  	bytePool             = sync.Pool{
   525  		New: func() interface{} {
   526  			return make([]byte, defaultByteSliceSize)
   527  		},
   528  	}
   529  )
   530  
   531  func allocByteSlice(n int) []byte {
   532  	if n > defaultByteSliceSize {
   533  		return make([]byte, n)
   534  	}
   535  	return bytePool.Get().([]byte)
   536  }
   537  
   538  func deallocateByteSlice(b []byte) {
   539  	if cap(b) <= defaultByteSliceSize {
   540  		bytePool.Put(b)
   541  	}
   542  }
   543  
   544  // evalString evals COMPRESS(str).
   545  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_compress
   546  func (b *builtinCompressSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   547  	n := input.NumEvents()
   548  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   549  	if err != nil {
   550  		return err
   551  	}
   552  	defer b.bufSlabPredictor.put(buf)
   553  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   554  		return err
   555  	}
   556  
   557  	result.ReserveString(n)
   558  	for i := 0; i < n; i++ {
   559  		if buf.IsNull(i) {
   560  			result.AppendNull()
   561  			continue
   562  		}
   563  
   564  		str := buf.GetString(i)
   565  
   566  		// According to doc: Empty strings are stored as empty strings.
   567  		if len(str) == 0 {
   568  			result.AppendString("")
   569  		}
   570  
   571  		compressed, err := deflate(replog.Slice(str))
   572  		if err != nil {
   573  			result.AppendNull()
   574  			continue
   575  		}
   576  
   577  		resultLength := 4 + len(compressed)
   578  
   579  		// append "." if ends with space
   580  		shouldAppendSuffix := compressed[len(compressed)-1] == 32
   581  		if shouldAppendSuffix {
   582  			resultLength++
   583  		}
   584  
   585  		buffer := allocByteSlice(resultLength)
   586  		defer deallocateByteSlice(buffer)
   587  		buffer = buffer[:resultLength]
   588  
   589  		binary.LittleEndian.PutUint32(buffer, uint32(len(str)))
   590  		copy(buffer[4:], compressed)
   591  
   592  		if shouldAppendSuffix {
   593  			buffer[len(buffer)-1] = '.'
   594  		}
   595  
   596  		result.AppendBytes(buffer)
   597  	}
   598  	return nil
   599  }
   600  
   601  func (b *builtinAesEncryptSig) vectorized() bool {
   602  	return true
   603  }
   604  
   605  // evalString evals AES_ENCRYPT(str, key_str).
   606  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
   607  func (b *builtinAesEncryptSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   608  	n := input.NumEvents()
   609  	strBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   610  	if err != nil {
   611  		return err
   612  	}
   613  	defer b.bufSlabPredictor.put(strBuf)
   614  	if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil {
   615  		return err
   616  	}
   617  
   618  	keyBuf, err := b.bufSlabPredictor.get(types.ETString, n)
   619  	if err != nil {
   620  		return err
   621  	}
   622  	defer b.bufSlabPredictor.put(keyBuf)
   623  	if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil {
   624  		return err
   625  	}
   626  
   627  	if b.modeName != "ecb" {
   628  		// For modes that do not require init_vector, it is ignored and a warning is generated if it is specified.
   629  		return errors.Errorf("unsupported causet encryption mode - %v", b.modeName)
   630  	}
   631  
   632  	isWarning := !b.ivRequired && len(b.args) == 3
   633  	isConst := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx)
   634  	var key []byte
   635  	if isConst {
   636  		key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize)
   637  	}
   638  
   639  	sc := b.ctx.GetStochastikVars().StmtCtx
   640  	result.ReserveString(n)
   641  	for i := 0; i < n; i++ {
   642  		// According to doc: If either function argument is NULL, the function returns NULL.
   643  		if strBuf.IsNull(i) || keyBuf.IsNull(i) {
   644  			result.AppendNull()
   645  			continue
   646  		}
   647  		if isWarning {
   648  			sc.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV"))
   649  		}
   650  		if !isConst {
   651  			key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize)
   652  		}
   653  
   654  		// NOTE: we can't use GetBytes, because in AESEncryptWithECB padding is automatically
   655  		//       added to str and this will damange the data layout in chunk.DeferredCauset
   656  		str := []byte(strBuf.GetString(i))
   657  		cipherText, err := encrypt.AESEncryptWithECB(str, key)
   658  		if err != nil {
   659  			result.AppendNull()
   660  			continue
   661  		}
   662  		result.AppendBytes(cipherText)
   663  	}
   664  
   665  	return nil
   666  }
   667  
   668  func (b *builtinPasswordSig) vectorized() bool {
   669  	return true
   670  }
   671  
   672  func (b *builtinPasswordSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   673  	n := input.NumEvents()
   674  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   675  	if err != nil {
   676  		return err
   677  	}
   678  	defer b.bufSlabPredictor.put(buf)
   679  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   680  		return err
   681  	}
   682  	result.ReserveString(n)
   683  	for i := 0; i < n; i++ {
   684  		if buf.IsNull(i) {
   685  			result.AppendString("")
   686  			continue
   687  		}
   688  		pass := buf.GetString(i)
   689  		if len(pass) == 0 {
   690  			result.AppendString("")
   691  			continue
   692  		}
   693  		// We should append a warning here because function "PASSWORD" is deprecated since MyALLEGROSQL 5.7.6.
   694  		// See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_password
   695  		b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoRememristed.GenWithStackByArgs("PASSWORD"))
   696  
   697  		result.AppendString(auth.EncodePassword(pass))
   698  	}
   699  	return nil
   700  }
   701  
   702  func (b *builtinSHA1Sig) vectorized() bool {
   703  	return true
   704  }
   705  
   706  func (b *builtinSHA1Sig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   707  	n := input.NumEvents()
   708  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   709  	if err != nil {
   710  		return err
   711  	}
   712  	defer b.bufSlabPredictor.put(buf)
   713  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   714  		return err
   715  	}
   716  	result.ReserveString(n)
   717  	hasher := sha1.New()
   718  	for i := 0; i < n; i++ {
   719  		if buf.IsNull(i) {
   720  			result.AppendNull()
   721  			continue
   722  		}
   723  		str := buf.GetBytes(i)
   724  		_, err = hasher.Write(str)
   725  		if err != nil {
   726  			return err
   727  		}
   728  		result.AppendString(fmt.Sprintf("%x", hasher.Sum(nil)))
   729  		hasher.Reset()
   730  	}
   731  	return nil
   732  }
   733  
   734  func (b *builtinUncompressSig) vectorized() bool {
   735  	return true
   736  }
   737  
   738  // evalString evals UNCOMPRESS(compressed_string).
   739  // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompress
   740  func (b *builtinUncompressSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   741  	n := input.NumEvents()
   742  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
   743  	if err != nil {
   744  		return err
   745  	}
   746  	defer b.bufSlabPredictor.put(buf)
   747  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
   748  		return err
   749  	}
   750  
   751  	result.ReserveString(n)
   752  	sc := b.ctx.GetStochastikVars().StmtCtx
   753  	for i := 0; i < n; i++ {
   754  		if buf.IsNull(i) {
   755  			result.AppendNull()
   756  			continue
   757  		}
   758  
   759  		payload := buf.GetString(i)
   760  
   761  		if len(payload) == 0 {
   762  			result.AppendString("")
   763  			continue
   764  		}
   765  		if len(payload) <= 4 {
   766  			// corrupted
   767  			sc.AppendWarning(errZlibZData)
   768  			result.AppendNull()
   769  			continue
   770  		}
   771  		length := binary.LittleEndian.Uint32([]byte(payload[0:4]))
   772  		bytes, err := inflate([]byte(payload[4:]))
   773  		if err != nil {
   774  			sc.AppendWarning(errZlibZData)
   775  			result.AppendNull()
   776  			continue
   777  		}
   778  		if length < uint32(len(bytes)) {
   779  			sc.AppendWarning(errZlibZBuf)
   780  			result.AppendNull()
   781  			continue
   782  		}
   783  
   784  		result.AppendBytes(bytes)
   785  	}
   786  
   787  	return nil
   788  }
   789  
   790  func (b *builtinUncompressedLengthSig) vectorized() bool {
   791  	return true
   792  }
   793  
   794  func (b *builtinUncompressedLengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   795  	sc := b.ctx.GetStochastikVars().StmtCtx
   796  	nr := input.NumEvents()
   797  	payloadBuf, err := b.bufSlabPredictor.get(types.ETString, nr)
   798  	if err != nil {
   799  		return err
   800  	}
   801  	defer b.bufSlabPredictor.put(payloadBuf)
   802  	if err := b.args[0].VecEvalString(b.ctx, input, payloadBuf); err != nil {
   803  		return err
   804  	}
   805  
   806  	result.ResizeInt64(nr, false)
   807  	result.MergeNulls(payloadBuf)
   808  	i64s := result.Int64s()
   809  	for i := 0; i < nr; i++ {
   810  		if result.IsNull(i) {
   811  			continue
   812  		}
   813  		str := payloadBuf.GetString(i)
   814  		if len(str) == 0 {
   815  			i64s[i] = 0
   816  			continue
   817  		}
   818  		if len(str) <= 4 {
   819  			sc.AppendWarning(errZlibZData)
   820  			i64s[i] = 0
   821  			continue
   822  		}
   823  		i64s[i] = int64(binary.LittleEndian.Uint32([]byte(str)[0:4]))
   824  	}
   825  	return nil
   826  }