Files
2026-05-27 23:03:00 +08:00

1115 lines
34 KiB
Go

package sdf
import (
"crypto/cipher"
"hash"
"io"
"xdx.jelly/xgcl/api/common"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/identifier"
"xdx.jelly/xgcl/mac"
"xdx.jelly/xgcl/mac/cbcmac"
"xdx.jelly/xgcl/rsa"
"xdx.jelly/xgcl/sm/sm1"
"xdx.jelly/xgcl/sm/sm2"
"xdx.jelly/xgcl/sm/sm3"
"xdx.jelly/xgcl/sm/sm4"
)
type Handle uint32
type KeyType int
const (
// internal use
KeyTypeUnknow KeyType = 0
KeyTypeBlock KeyType = 0x10 // 对称密钥,SM1 or SM4
KeyTypeSm1 KeyType = 0x11
KeyTypeSm4 KeyType = 0x14
KeyTypeSm2Sign KeyType = 0x21
KeyTypeSm2Enc KeyType = 0x22
KeyTypeSm9MasterSign KeyType = 0x90
KeyTypeSm9MasterEnc KeyType = 0x91
KeyTypeSm9UserSign KeyType = 0x92
KeyTypeSm9UserEnc KeyType = 0x93
KeyTypeRsa KeyType = 0x100
)
func (k KeyType) String() string {
switch k {
case KeyTypeBlock:
return "BlockKey"
case KeyTypeSm1:
return "Sm1Key"
case KeyTypeSm2Sign:
return "Sm2SignKey"
case KeyTypeSm2Enc:
return "Sm2EncKey"
case KeyTypeSm4:
return "Sm4Key"
case KeyTypeSm9MasterSign:
return "Sm9MasterSignKey"
case KeyTypeSm9MasterEnc:
return "Sm9MasterEncKey"
case KeyTypeSm9UserSign:
return "Sm9UserSignKey"
case KeyTypeSm9UserEnc:
return "Sm9UserEncKey"
case KeyTypeRsa:
return "RsaKey"
default:
// Panic?
return "unknown"
}
}
func GetKeyType(s string) KeyType {
switch {
case s == "BlockKey":
return KeyTypeBlock
case s == "Sm1Key":
return KeyTypeSm1
case s == "Sm2SignKey":
return KeyTypeSm2Sign
case s == "Sm2EncKey":
return KeyTypeSm2Enc
case s == "Sm4Key":
return KeyTypeSm4
case s == "Sm9MasterSignKey":
return KeyTypeSm9MasterSign
case s == "Sm9MasterEncKey":
return KeyTypeSm9MasterEnc
case s == "Sm9UserSignKey":
return KeyTypeSm9UserSign
case s == "Sm9UserEncKey":
return KeyTypeSm9UserEnc
case s == "RsaKey":
return KeyTypeRsa
default:
return KeyTypeUnknow
}
}
type SymKey struct {
keyType KeyType
key []byte
}
type Sm2Key struct {
signKey *sm2.PrivateKey
encKey *sm2.PrivateKey
}
func (k *Sm2Key) Key(tpe KeyType) *sm2.PrivateKey {
if tpe == KeyTypeSm2Sign {
return k.signKey
}
return k.encKey
}
type RsaKey struct {
signKey *rsa.PrivateKey
encKey *rsa.PrivateKey
}
type Sm2Agreement struct {
param *sm2.ExchgParameters
sk *sm2.PrivateKey
keyBits int
sponsorID []byte
}
var _ Sdfable = &SdfNoLock{}
// SdfNoLock 无锁的SDFable实现。
// GCL作为软算法实例,应看做是一个device。需要进行加锁同步,可多线程共用一个实例。
// 这里的SdfNoLock,避免加锁,适用于单线程中调用。
//
// 若是密码卡的SdfNoLock实例,则看做session,不需加锁,不能多线程共用一个实例。
type SdfNoLock struct {
rand io.Reader //随机数发生器
RsaKey map[uint32]*RsaKey // RSAKey -- TODO
Sm2Key map[uint32]*Sm2Key // SM2Key
SymKey map[uint32]*SymKey // KEK
SessionKey map[Handle]*SymKey
Sm2Agreement map[Handle]*Sm2Agreement // Sm2密钥交换句柄
hash hash.Hash
}
var reader = grand.Reader
func (s *SdfNoLock) Marshal() []byte {
return nil
}
func (s *SdfNoLock) Unmarshal(data []byte) {
}
// //////////////////////////////////////////////////////////////////////////
//
// Helper function to use gcl with Sdfable interface
//
// /////////////////////////////////////////////////////////////////////////
const (
minIndex uint32 = 1000
maxIndex uint32 = 10000
NilIndex uint32 = ^uint32(0)
minHandle Handle = 1000
maxHandle Handle = 10000
NilHandle Handle = ^Handle(0)
)
func (s *SdfNoLock) GenerateKekAtIndex(keyIndex uint32) error {
if s.SymKey == nil {
s.SymKey = make(map[uint32]*SymKey)
}
k := &SymKey{
keyType: KeyTypeBlock,
key: make([]byte, sm4.BlockSize),
}
s.reader().Read(k.key)
s.SymKey[keyIndex] = k
return nil
}
func (s *SdfNoLock) ImportSm2KeyAtIndex(index uint32, tpe KeyType, key *common.ECCrefPrivateKey) (err error) {
if s.Sm2Key == nil {
s.Sm2Key = make(map[uint32]*Sm2Key)
}
k := &sm2.PrivateKey{}
if err = k.UnmarshalSDF(key); err != nil {
return err
}
sm2Key, ok := s.Sm2Key[index]
if !ok {
sm2Key = new(Sm2Key)
}
switch tpe {
case KeyTypeSm2Sign:
sm2Key.signKey = k
case KeyTypeSm2Enc:
sm2Key.encKey = k
default:
return common.SDR_INARGERR
}
s.Sm2Key[index] = sm2Key
return
}
func (s *SdfNoLock) ImportSm2Key(tpe KeyType, key *common.ECCrefPrivateKey) (index uint32, err error) {
if s.Sm2Key == nil {
s.Sm2Key = make(map[uint32]*Sm2Key)
}
index = minIndex
var sm2Key *Sm2Key
var ok bool
for index < maxIndex {
if sm2Key, ok = s.Sm2Key[index]; !ok {
sm2Key = new(Sm2Key)
break
} else if sm2Key.Key(tpe) == nil {
break
}
index++
}
if index == maxIndex {
return NilIndex, common.SDR_NOBUFFER
}
k := &sm2.PrivateKey{}
if err = k.UnmarshalSDF(key); err != nil {
return NilIndex, err
}
switch tpe {
case KeyTypeSm2Sign:
sm2Key.signKey = k
case KeyTypeSm2Enc:
sm2Key.encKey = k
default:
return NilIndex, common.SDR_INARGERR
}
s.Sm2Key[index] = sm2Key
return
}
// ImportSessionKey 将key存入s中
// movable, key是否可移动
func (s *SdfNoLock) ImportSessionKey(tpe KeyType, key []byte, movable bool) (handle Handle, err error) {
if s.SessionKey == nil {
s.SessionKey = make(map[Handle]*SymKey)
}
handle = minHandle
var ok bool
for handle < maxHandle {
if _, ok = s.SessionKey[handle]; !ok {
break
}
handle++
}
if handle == maxHandle {
return NilHandle, common.SDR_NOBUFFER
}
if movable {
s.SessionKey[handle] = &SymKey{
keyType: tpe,
key: key,
}
} else {
s.SessionKey[handle] = &SymKey{
keyType: tpe,
key: append([]byte{}, key...), // make a new one
}
}
return handle, nil
}
// ImportSm2Agreement 将agreement存入s中
func (s *SdfNoLock) ImportSm2Agreement(agreement *Sm2Agreement) (handle Handle, err error) {
if s.Sm2Agreement == nil {
s.Sm2Agreement = make(map[Handle]*Sm2Agreement)
}
handle = minHandle
var ok bool
for handle < maxHandle {
if _, ok = s.Sm2Agreement[handle]; !ok {
break
}
handle++
}
s.Sm2Agreement[handle] = agreement
return handle, nil
}
func (s *SdfNoLock) reader() io.Reader {
if s.rand == nil {
s.rand = reader
}
return s.rand
}
func (s *SdfNoLock) getSm2KeyWith(tpe KeyType, index uint32) (*sm2.PrivateKey, bool) {
if s.Sm2Key == nil {
return nil, false
}
sm2Key, ok := s.Sm2Key[index]
if !ok {
return nil, ok
}
switch tpe {
case KeyTypeSm2Sign:
if sm2Key.signKey != nil {
return sm2Key.signKey, true
}
case KeyTypeSm2Enc:
if sm2Key.encKey != nil {
return sm2Key.encKey, true
}
}
return nil, false
}
func (s *SdfNoLock) getKEKWith(index uint32) ([]byte, bool) {
if s.SymKey == nil {
return nil, false
}
key, ok := s.SymKey[index]
return key.key, ok
}
func (s *SdfNoLock) getSessionKeyWith(handle Handle) ([]byte, bool) {
if s.SessionKey == nil {
return nil, false
}
key, ok := s.SessionKey[handle]
return key.key, ok
}
// //////////////////////////////////////////////////////////////////////////
//
// Implements of Sdfable functions
//
// /////////////////////////////////////////////////////////////////////////
func (s *SdfNoLock) SDF_OpenSession() error {
return nil
}
func (s *SdfNoLock) SDF_CloseSession() error {
return nil
}
func (s *SdfNoLock) SDF_GetDeviceInfo() (*DeviceInfo, error) {
return devInfo, nil
}
// To be simple, no password
func (s *SdfNoLock) SDF_GetPrivateKeyAccessRight(keyIndex uint32, password []byte) error {
return nil
}
func (s *SdfNoLock) SDF_ReleasePrivateKeyAccessRight(keyIndex uint32) error {
return nil
}
func (s *SdfNoLock) SDF_GenerateRandom(buffer []byte) (n uint32, err error) {
if uint32(len(buffer)) > devInfo.BufferSize {
return 0, common.SDR_INARGERR
}
m, err := io.ReadAtLeast(s.reader(), buffer, int(len(buffer)))
return uint32(m), err
}
func (s *SdfNoLock) SDF_ExportSignPublicKey_RSA(uiKeyIndex uint32) (*rsa.PublicKey, error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_ExportEncPublicKey_RSA(uiKeyIndex uint32) (*rsa.PublicKey, error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeyPair_RSA(uiKeyBits uint32) (*rsa.PublicKey, *rsa.PrivateKey, error) {
return nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeyWithIPK_RSA(uiIPKIndex uint32, uiKeyBits uint32) (pucKey []byte, phKeyHandle interface{}, err error) {
return nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeyWithEPK_RSA(uiKeyBits uint32, pucPublicKey *rsa.PublicKey) (Key []byte, phKeyHandle interface{}, err error) {
return nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_ImportKeyWithISK_RSA(uiISKIndex uint32, pucKey []byte) (phKeyHandle interface{}, err error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_ExchangeDigitEnvelopeBaseOnRSA(uiKeyIndex uint32, pucPublicKey *rsa.PublicKey, pucDEInput []byte) (pucDEOutput []byte, err error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_DecryptPublicKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_ExportSignPublicKey_ECC(keyIndex uint32) (*sm2.PublicKey, error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Sign, keyIndex)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
return &sk.PublicKey, nil
}
func (s *SdfNoLock) SDF_ExportEncPublicKey_ECC(keyIndex uint32) (*sm2.PublicKey, error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, keyIndex)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
return &sk.PublicKey, nil
}
func (s *SdfNoLock) SDF_GenerateKeyPair_ECC(algID, keyBits uint32) (*sm2.PublicKey, *sm2.PrivateKey, error) {
// we do not check the params
sk, err := sm2.GenerateKey(sm2.Curve(), s.reader())
if err != nil {
return nil, nil, common.SDR_RANDERR
}
return &sk.PublicKey, sk, nil
}
func (s *SdfNoLock) SDF_GenerateKeyWithIPK_ECC(uiIPKIndex uint32, uiKeyBits uint32) (pucKey *sm2.Cipher, phKeyHandle interface{}, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, uiIPKIndex)
if !ok {
return nil, nil, common.SDR_KEYNOTEXIST
}
return s.SDF_GenerateKeyWithEPK_ECC(uiKeyBits, identifier.SGDSM23, &sk.PublicKey)
}
func (s *SdfNoLock) SDF_GenerateKeyWithEPK_ECC(uiKeyBits uint32, uiAlgID uint32, pucPublicKey *sm2.PublicKey) (pucKey *sm2.Cipher, phKeyHandle interface{}, err error) {
keyBytes := (uiKeyBits + 7) / 8
buf := make([]byte, sm2.ByteSize())
if n, err := s.SDF_GenerateRandom(buf); err != nil || n != uint32(len(buf)) {
return nil, nil, common.SDR_RANDERR
}
key := make([]byte, keyBytes)
if n, err := s.SDF_GenerateRandom(key); err != nil || n != keyBytes {
return nil, nil, common.SDR_RANDERR
}
handle, err := s.ImportSessionKey(KeyTypeBlock, key, true)
if err != nil {
return nil, nil, err
}
pucKey, err = sm2.Encrypt(pucPublicKey, key, buf[keyBytes:])
if err != nil {
delete(s.SessionKey, handle)
if !pucPublicKey.IsValid() {
return nil, nil, common.SDR_KEYERR
}
return nil, nil, common.SDR_INARGERR
}
return pucKey, handle, nil
}
func (s *SdfNoLock) SDF_ImportKeyWithISK_ECC(uiISKIndex uint32, pucKey *sm2.Cipher) (phKeyHandle interface{}, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, uiISKIndex)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
key, err := s.SDF_ExternalDecrypt_ECC(identifier.SGDSM23, sk, pucKey)
if err != nil {
return nil, err
}
return s.ImportSessionKey(KeyTypeBlock, key, true)
}
func (s *SdfNoLock) SDF_GenerateAgreementDataWithECC(uiISKIndex uint32, uiKeyBits uint32, pucSponsorID []byte) (pucSponsorPublicKey *sm2.PublicKey, pucSponsorTmpPublicKey *sm2.PublicKey, phAgreementHandle interface{}, err error) {
return s.SDFEXT_GenerateAgreementDataWithECC(uiISKIndex, uiKeyBits, pucSponsorID)
}
func (s *SdfNoLock) SDF_GenerateKeyWithECC(pucResponseID []byte, pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, hAgreementHandle interface{}) (phKeyHandle interface{}, err error) {
key, err := s.SDFEXT_GenerateKeyWithECC(pucResponseID, pucResponsePublicKey, pucResponseTmpPublicKey, hAgreementHandle)
if err != nil {
return nil, err
}
return s.ImportSessionKey(KeyTypeBlock, key, true)
}
func (s *SdfNoLock) SDF_GenerateAgreementDataAndKeyWithECC(uiISKIndex uint32, uiKeyBits uint32, pucResponseID []byte, pucSponsorID []byte, pucSponsorPublicKey, pucSponsorTmpPublicKey *sm2.PublicKey) (pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, phKeyHandle interface{}, err error) {
return s.SDFEXT_GenerateAgreementDataAndKeyWithECC(uiISKIndex, uiKeyBits, pucResponseID, pucSponsorID, pucSponsorPublicKey, pucSponsorTmpPublicKey)
}
func (s *SdfNoLock) SDF_ExchangeDigitEnvelopeBaseOnECC(uiKeyIndex uint32, uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucEncDataIn *sm2.Cipher) (pucEncDataOut *sm2.Cipher, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, uiKeyIndex)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
data, err := sm2.Decrypt(sk, pucEncDataIn)
if err != nil {
if !pucPublicKey.IsValid() {
// pucPublicKey 错误
return nil, common.SDR_KEYERR
}
return nil, common.SDR_ENCDATAERR
}
rand := make([]byte, sm2.ByteSize())
if n, err := s.SDF_GenerateRandom(rand); err != nil || n < uint32(len(rand)) {
return nil, common.SDR_RANDERR
}
return sm2.Encrypt(pucPublicKey, data, rand)
}
func (s *SdfNoLock) SDF_GenerateKeyWithKEK(uiKeyBits uint32, uiAlgID uint32, uiKEKIndex uint32) (pucKey []byte, phKeyHandle interface{}, err error) {
kek, ok := s.getKEKWith(uiKEKIndex)
if !ok {
return nil, nil, common.SDR_KEYNOTEXIST
}
keyBytes := (uiKeyBits + 7) / 8
// 必须是16的倍数。要用SM4ECB加密
if keyBytes&0xf != 0 {
return nil, nil, common.SDR_INARGERR
}
key := make([]byte, keyBytes)
if n, err := s.SDF_GenerateRandom(key); err != nil || n != keyBytes {
return nil, nil, common.SDR_RANDERR
}
handle, err := s.ImportSessionKey(KeyTypeBlock, key, true)
pucKey = make([]byte, len(key))
// kek should always be 16 bytes. so no err will occure here.
switch uiAlgID {
case identifier.SGDSM1ECB:
_, _ = sm1.EncryptECB(pucKey, kek, key)
case identifier.SGDSM4ECB:
_, _ = sm4.EncryptECB(pucKey, kek, key)
default:
// 算法id错误
return nil, nil, common.SDR_ALGNOTSUPPORT
}
return pucKey, handle, nil
}
func (s *SdfNoLock) SDF_ImportKeyWithKEK(uiAlgID uint32, uiKEKIndex uint32, pucKey []byte) (phKeyHandle interface{}, err error) {
kek, ok := s.getKEKWith(uiKEKIndex)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
if len(pucKey)&0xf != 0 {
return nil, common.SDR_INARGERR
}
key := make([]byte, len(pucKey))
// kek should always be 16 bytes. so no err will occure here.
switch uiAlgID {
case identifier.SGDSM1ECB:
_, _ = sm1.DecryptECB(key, kek, pucKey)
case identifier.SGDSM4ECB:
_, _ = sm4.DecryptECB(key, kek, pucKey)
default:
// 算法id错误
return nil, common.SDR_ALGNOTSUPPORT
}
return s.ImportSessionKey(KeyTypeBlock, key, true)
}
func (s *SdfNoLock) SDF_GenerateKeywithIKE(pucSponsorNonce []byte, pucResponseNonce []byte, pucSponsorCookie []byte, pucResponseCookie []byte, uiPrfAlgID uint32, uiKeyBitsD, uiKeyBitsA, uiKeyBitsE uint32) (phKeyHandleD interface{}, phKeyHandleA interface{}, phKeyHandleE interface{}, err error) {
return nil, nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeywithEPK_IKE(pucSponsorNonce []byte, pucResponseNonce []byte, pucSponsorCookie []byte, pucResponseCookie []byte, uiPrfAlgID, uiEccAlgID uint32, pucPublicKey sm2.PublicKey, uiKeyBitsD, uiKeyBitsA, uiKeyBitsE uint32) (pucKeyD *sm2.Cipher, phKeyHandleD interface{}, pucKeyA *sm2.Cipher, phKeyHandleA interface{}, pucKeyE *sm2.Cipher, phKeyHandleE interface{}, err error) {
return nil, nil, nil, nil, nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeywithIPSEC(pucProtocolID []byte, pucSpi []byte, pucSponsorNonce []byte, pucResponseNonce []byte, hKeyHandle interface{}, uiPrfAlgID uint32, uiKeyBitsEnc, uiKeyBitsMac uint32) (phKeyHandleEnc interface{}, phKeyHandleMac interface{}, err error) {
return nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeywithEPK_IPSEC(pucProtocolID []byte, pucSpi []byte, pucSponsorNonce []byte, pucResponseNonce []byte, hKeyHandle interface{}, uiPrfAlgID uint32, uiEccAlgID uint32, pucPublicKey *sm2.PublicKey, uiKeyBitsEnc, uiKeyBitsMac uint32) (pucKeyEnc *sm2.Cipher, phKeyHandleEnc interface{}, pucKeyMac *sm2.Cipher, phKeyHandleMac interface{}, err error) {
return nil, nil, nil, nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_GenerateKeywithSSL(pucKeyPremaster, pucClientRandom, pucServerRandom []byte, uiPrfAlgID uint32, uiKeyBitsClientMac, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc uint32) (phKeyHandleClientMac, phKeyHandleServerMac, phKeyHandleClientEnc, phKeyHandleServerEnc interface{}, pucClientIV, pucServerIV []byte, err error) {
clientMAC, serverMAC, clientKey, serverKey, pucClientIV, pucServerIV := KeysFromPreMasterSecretTLCP(pucKeyPremaster, pucClientRandom, pucServerRandom, sm4.BlockSize, sm4.BlockSize, sm4.BlockSize)
phKeyHandleClientMac, err = s.ImportSessionKey(KeyTypeBlock, clientMAC, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
phKeyHandleServerMac, err = s.ImportSessionKey(KeyTypeBlock, serverMAC, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
phKeyHandleClientEnc, err = s.ImportSessionKey(KeyTypeBlock, clientKey, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
phKeyHandleServerEnc, err = s.ImportSessionKey(KeyTypeBlock, serverKey, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
return
}
func (s *SdfNoLock) SDF_GenerateKeywithEPK_SSL(pucKeyPremaster, pucClientRandom, pucServerRandom []byte, uiPrfAlgID uint32, uiEccAlgID uint32, pucPublicKey *sm2.PublicKey, uiKeyBitsClientMac, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc uint32) (pucKeyClientMac *sm2.Cipher, phKeyHandleClientMac interface{}, pucKeyServerMac *sm2.Cipher, phKeyHandleServerMac interface{}, pucKeyClientEnc *sm2.Cipher, phKeyHandleClientEnc interface{}, pucKeyServerEnc *sm2.Cipher, phKeyHandleServerEnc interface{}, pucClientIV, pucServerIV []byte, err error) {
masterSecret := masterFromPreMasterSecretTLCP(pucKeyPremaster, pucClientRandom, pucServerRandom)
clientMAC, serverMAC, clientKey, serverKey, pucClientIV, pucServerIV := keysFromMasterSecretTLCP(masterSecret, pucClientRandom, pucServerRandom, sm4.BlockSize, sm4.BlockSize, sm4.BlockSize)
rnd := make([]byte, sm2.ByteSize())
if n, err := s.reader().Read(rnd); err != nil || n < len(rnd) {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
pucKeyClientMac, err = sm2.Encrypt(pucPublicKey, clientMAC, rnd)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
phKeyHandleClientMac, err = s.ImportSessionKey(KeyTypeBlock, clientMAC, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
if n, err := s.reader().Read(rnd); err != nil || n < len(rnd) {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
pucKeyServerMac, err = sm2.Encrypt(pucPublicKey, serverMAC, rnd)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
phKeyHandleServerMac, err = s.ImportSessionKey(KeyTypeBlock, serverMAC, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
if n, err := s.reader().Read(rnd); err != nil || n < len(rnd) {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
pucKeyClientEnc, err = sm2.Encrypt(pucPublicKey, clientKey, rnd)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
phKeyHandleClientEnc, err = s.ImportSessionKey(KeyTypeBlock, clientKey, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
if n, err := s.reader().Read(rnd); err != nil || n < len(rnd) {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
pucKeyServerEnc, err = sm2.Encrypt(pucPublicKey, serverKey, rnd)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
phKeyHandleServerEnc, err = s.ImportSessionKey(KeyTypeBlock, serverKey, true)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
return
}
func (s *SdfNoLock) SDF_GenerateKeywithECDHE_SSL(phKeyHandlePremaster interface{}, pucClientRandom, pucServerRandom []byte, uiPrfAlgID uint32, uiKeyBitsClientMac, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc uint32) (phKeyHandleClientMac, phKeyHandleServerMac, phKeyHandleClientEnc, phKeyHandleServerEnc interface{}, pucClientIV, pucServerIV []byte, err error) {
handle, ok := phKeyHandlePremaster.(Handle)
if !ok {
return nil, nil, nil, nil, nil, nil, common.SDR_INARGERR
}
preMasterSecret, ok := s.getSessionKeyWith(handle)
if !ok {
return nil, nil, nil, nil, nil, nil, common.SDR_KEYNOTEXIST
}
return s.SDF_GenerateKeywithSSL(preMasterSecret, pucClientRandom, pucServerRandom, uiPrfAlgID, uiKeyBitsClientEnc, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc)
}
func (s *SdfNoLock) SDF_GenerateKeywithEPK_ECDHE_SSL(phKeyHandlePremaster interface{}, pucClientRandom, pucServerRandom []byte, uiPrfAlgID uint32, uiEccAlgID uint32, pucPublicKey *sm2.PublicKey, uiKeyBitsClientMac, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc uint32) (pucKeyClientMac *sm2.Cipher, phKeyHandleClientMac interface{}, pucKeyServerMac *sm2.Cipher, phKeyHandleServerMac interface{}, pucKeyClientEnc *sm2.Cipher, phKeyHandleClientEnc interface{}, pucKeyServerEnc *sm2.Cipher, phKeyHandleServerEnc interface{}, pucClientIV, pucServerIV []byte, err error) {
handle, ok := phKeyHandlePremaster.(Handle)
if !ok {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, common.SDR_INARGERR
}
preMasterSecret := [48]byte{1, 1}
preMasterSecretRandom, ok := s.getSessionKeyWith(handle)
if !ok {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, common.SDR_KEYNOTEXIST
}
if len(preMasterSecretRandom) != 46 {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, common.SDR_KEYERR
}
copy(preMasterSecret[2:], preMasterSecretRandom)
return s.SDF_GenerateKeywithEPK_SSL(preMasterSecret[:], pucClientRandom, pucServerRandom, uiPrfAlgID, uiEccAlgID, pucPublicKey, uiKeyBitsClientEnc, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc)
}
func (s *SdfNoLock) SDF_DestroyKey(hKeyHandle interface{}) error {
handle, ok := hKeyHandle.(Handle)
if !ok {
return common.SDR_INARGERR
}
if key, ok := s.SessionKey[handle]; ok {
// 内存置0
for i := range key.key {
key.key[i] = 0
}
delete(s.SessionKey, handle)
}
return nil
}
////////////////////////////////////////////////////////////////////////////
//
// 非对称算法运算类函数
//
///////////////////////////////////////////////////////////////////////////
func (s *SdfNoLock) SDF_ExternalPublicKeyOperation_RSA(pucPublicKey *rsa.PublicKey, pucDataInput []byte) (pucDataOutput []byte, err error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_InternalPublicKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_InternalPrivateKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error) {
return nil, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_ExternalSign_ECC(uiAlgID uint32, pucPrivateKey *sm2.PrivateKey, pucData []byte) (*sm2.Signature, error) {
if len(pucData) != sm3.Size {
return nil, common.SDR_INARGERR
}
r, S, err := sm2.SignWithReader(s.reader(), pucPrivateKey, pucData)
return &sm2.Signature{R: r, S: S}, err
}
func (s *SdfNoLock) SDF_ExternalVerify_ECC(uiAlgID uint32,
pucPublicKey *sm2.PublicKey, pucDataInput []byte,
pucSignature *sm2.Signature) error {
if len(pucDataInput) != sm3.Size {
return common.SDR_INARGERR
}
if sm2.Verify(pucDataInput, pucPublicKey, pucSignature) {
return nil
} else {
return common.SDR_VERIFYERR
}
}
func (s *SdfNoLock) SDF_InternalSign_ECC(iskIndex uint32, data []byte) (signature *sm2.Signature, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Sign, iskIndex)
if !ok {
return nil, common.SDR_INARGERR
}
r, S, err := sm2.SignWithReader(s.reader(), sk, data)
return &sm2.Signature{R: r, S: S}, err
}
func (s *SdfNoLock) SDF_InternalVerify_ECC(iskIndex uint32, data []byte, signature *sm2.Signature) error {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Sign, iskIndex)
if !ok {
return common.SDR_INARGERR
}
ok = sm2.Verify(data, &sk.PublicKey, signature)
if ok {
return nil
} else {
return common.SDR_SIGNERR
}
}
func (s *SdfNoLock) SDF_ExternalEncrypt_ECC(
uiAlgID uint32,
pucPublicKey *sm2.PublicKey,
pucData []byte) (pucEncData *sm2.Cipher, err error) {
// omit the check of uiAlgID
buf := make([]byte, sm2.ByteSize())
if n, err := s.SDF_GenerateRandom(buf); err != nil || n < uint32(len(buf)) {
return nil, common.SDR_RANDERR
}
pucEncData, err = sm2.Encrypt(pucPublicKey, pucData, buf)
if err != nil {
if !pucPublicKey.IsValid() {
return nil, common.SDR_KEYERR
}
return nil, common.SDR_INARGERR
}
return
}
// 外部ECC私钥解密,GMT0018有,36322没有。
func (s *SdfNoLock) SDF_ExternalDecrypt_ECC(uiAlgID uint32, pucPrivateKey *sm2.PrivateKey, pucEncData *sm2.Cipher) (pucData []byte, err error) {
pucData, err = sm2.Decrypt(pucPrivateKey, pucEncData)
if err != nil {
return nil, common.SDR_INARGERR
}
return
}
func (s *SdfNoLock) SDF_Encrypt(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte, pucEncData *[]byte) (err error) {
h, ok := hKeyHandle.(Handle)
if !ok {
return common.SDR_KEYERR
}
key, ok := s.getSessionKeyWith(h)
if !ok {
return common.SDR_KEYNOTEXIST
}
if len(pucData)&0xf != 0 {
return common.SDR_INARGERR
}
// expand pucEncData
for len(pucData) > len(*pucEncData) {
*pucEncData = append(*pucEncData, 0)
}
switch uiAlgID {
case identifier.SGDSM1ECB:
sm1.EncryptECB(*pucEncData, key, pucData)
case identifier.SGDSM1CBC:
if pucIV == nil || len(pucIV) < sm1.BlockSize {
return common.SDR_INARGERR
}
sm1.EncryptCBC(*pucEncData, pucIV, key, pucData)
case identifier.SGDSM1CFB:
if pucIV == nil || len(pucIV) < sm1.BlockSize {
return common.SDR_INARGERR
}
sm1.EncryptCFB(*pucEncData, pucIV, key, pucData)
case identifier.SGDSM1OFB:
if pucIV == nil || len(pucIV) < sm1.BlockSize {
return common.SDR_INARGERR
}
sm1.EncryptOFB(*pucEncData, pucIV, key, pucData)
case identifier.SGDSM4ECB:
sm4.EncryptECB(*pucEncData, key, pucData)
case identifier.SGDSM4CBC:
if pucIV == nil || len(pucIV) < sm4.BlockSize {
return common.SDR_INARGERR
}
sm4.EncryptCBC(*pucEncData, pucIV, key, pucData)
case identifier.SGDSM4CFB:
if pucIV == nil || len(pucIV) < sm4.BlockSize {
return common.SDR_INARGERR
}
sm4.EncryptCFB(*pucEncData, pucIV, key, pucData)
case identifier.SGDSM4OFB:
if pucIV == nil || len(pucIV) < sm4.BlockSize {
return common.SDR_INARGERR
}
sm4.EncryptOFB(*pucEncData, pucIV, key, pucData)
default:
return common.SDR_ALGMODNOTSUPPORT
}
return nil
}
func (s *SdfNoLock) SDF_Decrypt(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucEncData []byte, pucData *[]byte) (err error) {
h, ok := hKeyHandle.(Handle)
if !ok {
return common.SDR_KEYERR
}
key, ok := s.getSessionKeyWith(h)
if !ok {
return common.SDR_KEYNOTEXIST
}
if len(pucEncData)&0xf != 0 {
return common.SDR_INARGERR
}
// expand pucEncData
for len(pucEncData) > len(*pucData) {
*pucData = append(*pucData, 0)
}
switch uiAlgID {
case identifier.SGDSM1ECB:
sm1.DecryptECB(*pucData, key, pucEncData)
case identifier.SGDSM1CBC:
if pucIV == nil || len(pucIV) < sm1.BlockSize {
return common.SDR_INARGERR
}
sm1.DecryptCBC(*pucData, pucIV, key, pucEncData)
case identifier.SGDSM1CFB:
if pucIV == nil || len(pucIV) < sm1.BlockSize {
return common.SDR_INARGERR
}
sm1.DecryptCFB(*pucData, pucIV, key, pucEncData)
case identifier.SGDSM1OFB:
if pucIV == nil || len(pucIV) < sm1.BlockSize {
return common.SDR_INARGERR
}
sm1.DecryptOFB(*pucData, pucIV, key, pucEncData)
case identifier.SGDSM4ECB:
sm4.DecryptECB(*pucData, key, pucEncData)
case identifier.SGDSM4CBC:
if pucIV == nil || len(pucIV) < sm4.BlockSize {
return common.SDR_INARGERR
}
sm4.DecryptCBC(*pucData, pucIV, key, pucEncData)
case identifier.SGDSM4CFB:
if pucIV == nil || len(pucIV) < sm4.BlockSize {
return common.SDR_INARGERR
}
sm4.DecryptCFB(*pucData, pucIV, key, pucEncData)
case identifier.SGDSM4OFB:
if pucIV == nil || len(pucIV) < sm4.BlockSize {
return common.SDR_INARGERR
}
sm4.DecryptOFB(*pucData, pucIV, key, pucEncData)
default:
return common.SDR_ALGMODNOTSUPPORT
}
return nil
}
func (s *SdfNoLock) SDF_CalculateMAC(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte) (pucMAC []byte, err error) {
h, ok := hKeyHandle.(Handle)
if !ok {
return nil, common.SDR_KEYERR
}
key, ok := s.getSessionKeyWith(h)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
if uiAlgID == identifier.SGDSM3 {
// SM3-HMAC
h, err := mac.NewMac(mac.HMAC_SM3, key)
if err != nil {
return nil, common.SDR_KEYERR
}
pucMAC, err := h.ComputeMAC(pucData)
if err != nil {
return nil, common.SDR_KEYERR
}
return pucMAC, err
} else {
// CBC-MAC
var block cipher.Block
switch uiAlgID {
case identifier.SGDSM1Mac:
block, err = sm1.NewCipher(key)
case identifier.SGDSM4Mac:
block, err = sm4.NewCipher(key)
default:
return nil, common.SDR_ALGNOTSUPPORT
}
if err != nil {
return nil, common.SDR_KEYERR
}
pucMAC = make([]byte, block.BlockSize())
err := cbcmac.CalculateMAC(pucData, pucIV, block, pucMAC)
if err != nil {
return nil, common.SDR_INARGERR
}
return pucMAC, nil
}
}
func (s *SdfNoLock) SDF_HashInit(uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucID []byte) (err error) {
if len(pucID) > 0 && pucPublicKey != nil {
z := sm2.PreComputeWithIdAndPubkey(pucID, pucPublicKey)
s.hash = sm3.New()
s.hash.Write(z)
} else {
s.hash = sm3.New()
}
return nil
}
func (s *SdfNoLock) SDF_HashUpdate(pucData []byte) (err error) {
if s.hash == nil {
return common.SDR_STEPERR
}
s.hash.Write(pucData)
return nil
}
func (s *SdfNoLock) SDF_HashFinal() (pucHash []byte, err error) {
if s.hash == nil {
return nil, common.SDR_STEPERR
}
pucHash = s.hash.Sum(nil)
s.hash = nil
return pucHash, nil
}
func (s *SdfNoLock) SDF_CreateFile(pucFileName string, uiFileSize uint32) error {
return common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_ReadFile(pucFileName string, uiOffset uint32, pucBuffer []byte) (n uint32, err error) {
return 0, common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_WriteFile(pucFileName string, uiOffset uint32, pucBuffer []byte) error {
return common.SDR_NOTSUPPORT
}
func (s *SdfNoLock) SDF_DeleteFile(pucFileName string) error {
return common.SDR_NOTSUPPORT
}
// 内部sm2私钥解密
func (s *SdfNoLock) SDFEXT_InternalDecryptECC(uiKeyIndex uint32, pucEncData *sm2.Cipher) (pucData []byte, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, uiKeyIndex)
if !ok {
return nil, common.SDR_KEYNOTEXIST
}
pucData, err = sm2.Decrypt(sk, pucEncData)
if err != nil {
return nil, common.SDR_INARGERR
}
return pucData, nil
}
// 6.3.14 生成密钥协商参数并输出-这个与标准接口一致
// 描述: 使用ECC密钥协商算法, 为计算会话密钥而产生协商参数, 同时返回指定索引位置的ECC公钥、临时ECC密钥对的公钥及协商句柄。
func (s *SdfNoLock) SDFEXT_GenerateAgreementDataWithECC(uiISKIndex uint32, uiKeyBits uint32, pucSponsorID []byte) (pucSponsorPublicKey *sm2.PublicKey, pucSponsorTmpPublicKey *sm2.PublicKey, phAgreementHandle interface{}, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, uiISKIndex)
if !ok {
return nil, nil, nil, common.SDR_KEYNOTEXIST
}
param, err := sm2.GenerateAgreementData(s.reader())
if err != nil {
return nil, nil, nil, common.SDR_RANDERR
}
handle, err := s.ImportSm2Agreement(&Sm2Agreement{
param: param,
sk: sk,
keyBits: int(uiKeyBits),
sponsorID: append([]byte{}, pucSponsorID...), // make a new one
})
if err != nil {
return nil, nil, nil, err
}
return &sk.PublicKey, &param.PrivateKey.PublicKey, handle, nil
}
// 6.3.15 计算会话密钥变体
// 描述: 使用ECC密钥协商算法, 使用自身协商句柄和响应方的协商参数计算会话密钥, 同时返回会话密钥。
// 备注: 协商的发起方获得响应方的协商参数后调用本函数, 计算会话密钥。使用SM2算法计算会话密钥的过程见GM/T 0009。
func (s *SdfNoLock) SDFEXT_GenerateKeyWithECC(pucResponseID []byte, pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, hAgreementHandle interface{}) (agreementKey []byte, err error) {
if s.Sm2Agreement == nil {
return nil, common.SDR_INARGERR
}
handle, ok := hAgreementHandle.(Handle)
if !ok {
return nil, common.SDR_INARGERR
}
agreement, ok := s.Sm2Agreement[handle]
if !ok {
return nil, common.SDR_INARGERR
}
key, err := sm2.GenerateSharedKey(agreement.param, agreement.sponsorID, agreement.sk, pucResponseID, pucResponsePublicKey, pucResponseTmpPublicKey, (agreement.keyBits+7)/8)
if err != nil {
return nil, common.SDR_INARGERR
}
return key, nil
}
// 6.3.16 产生协商数据并计算会话密钥
// 描述: 使用ECC密钥协商算法, 产生协商参数并计算会话密钥, 同时返回产生的协商参数和密钥。
func (s *SdfNoLock) SDFEXT_GenerateAgreementDataAndKeyWithECC(uiISKIndex uint32, uiKeyBits uint32, pucResponseID []byte, pucSponsorID []byte, pucSponsorPublicKey, pucSponsorTmpPublicKey *sm2.PublicKey) (pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, agreementKey []byte, err error) {
sk, ok := s.getSm2KeyWith(KeyTypeSm2Enc, uiISKIndex)
if !ok {
return nil, nil, nil, common.SDR_KEYNOTEXIST
}
key, param, err := sm2.GenerateAgreementDataAndKey(pucResponseID, sk, pucSponsorID, pucSponsorPublicKey, pucSponsorTmpPublicKey, int((uiKeyBits+7)/8), s.reader())
if err != nil {
return nil, nil, nil, common.SDR_UNKNOWERR
}
return &sk.PublicKey, &param.PrivateKey.PublicKey, key, nil
}