func NewIvGCM() (IvGCM, error) {
	return newIV(ivLengthGCM)
}
NewIvGCM randomly generate an IV for GCM mode.
package encryption
import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/binary"
	"io"
	"unsafe"
	"github.com/pingcap/kvproto/pkg/encryptionpb"
	"github.com/tikv/pd/pkg/errs"
)
const (
	ivLengthCTR = 16
	ivLengthGCM = 12
)
func CheckEncryptionMethodSupported(method encryptionpb.EncryptionMethod) error {
	switch method {
	case encryptionpb.EncryptionMethod_AES128_CTR:
		return nil
	case encryptionpb.EncryptionMethod_AES192_CTR:
		return nil
	case encryptionpb.EncryptionMethod_AES256_CTR:
		return nil
	default:
		name, ok := encryptionpb.EncryptionMethod_name[int32(method)]
		if ok {
			return errs.ErrEncryptionInvalidMethod.GenWithStackByArgs(name)
		}
		return errs.ErrEncryptionInvalidMethod.GenWithStackByArgs(int32(method))
	}
}
func KeyLength(method encryptionpb.EncryptionMethod) (int, error) {
	switch method {
	case encryptionpb.EncryptionMethod_AES128_CTR:
		return 16, nil
	case encryptionpb.EncryptionMethod_AES192_CTR:
		return 24, nil
	case encryptionpb.EncryptionMethod_AES256_CTR:
		return 32, nil
	default:
		name, ok := encryptionpb.EncryptionMethod_name[int32(method)]
		if ok {
			return 0, errs.ErrEncryptionInvalidMethod.GenWithStackByArgs(name)
		}
		return 0, errs.ErrEncryptionInvalidMethod.GenWithStackByArgs(int32(method))
	}
}
type IvCTR []byte
type IvGCM []byte
func newIV(ivLength int) ([]byte, error) {
	iv := make([]byte, ivLength)
	n, err := io.ReadFull(rand.Reader, iv)
	if err != nil {
		return nil, errs.ErrEncryptionGenerateIV.Wrap(err).GenWithStackByArgs()
	}
	if n != ivLength {
		return nil, errs.ErrEncryptionGenerateIV.GenWithStack(
			"iv length exepcted %d vs actual %d", ivLength, n)
	}
	return iv, nil
}
func NewIvCTR() (IvCTR, error) {
	return newIV(ivLengthCTR)
}