init: v1.0.0
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"xdx.jelly/xgcl/api/common"
|
||||
)
|
||||
|
||||
type DeviceInfo struct {
|
||||
IssuerName [40]byte
|
||||
DeviceName [16]byte
|
||||
DeviceSerial [16]byte
|
||||
DeviceVersion uint32
|
||||
StandardVersion uint32
|
||||
AsymAlgAbility [2]uint32
|
||||
SymAlgAbility uint32
|
||||
HashAlgAbility uint32
|
||||
BufferSize uint32
|
||||
}
|
||||
|
||||
func (d *DeviceInfo) Size() int {
|
||||
return 40 + 16 + 16 + 4*7
|
||||
}
|
||||
|
||||
func strlen(s []byte) int {
|
||||
for i, c := range s {
|
||||
if c == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (d *DeviceInfo) String() string {
|
||||
return fmt.Sprintf("IssuerName: %s\nDeviceName: %s\nDeviceSerial: %s\nDeviceVersion: 0x%08x\nStandardVersion: 0x%08x\nAsymAlgAbility: 0x%08x%08x\nSymAlgAbility 0x%08x\nHashAlgAbility 0x%08x\nBufferSize: 0x%08x",
|
||||
string(d.IssuerName[:strlen(d.IssuerName[:])]),
|
||||
string(d.DeviceName[:strlen(d.DeviceName[:])]),
|
||||
string(d.DeviceSerial[:strlen(d.DeviceSerial[:])]),
|
||||
d.DeviceVersion,
|
||||
d.StandardVersion,
|
||||
d.AsymAlgAbility[0],
|
||||
d.AsymAlgAbility[1],
|
||||
d.SymAlgAbility,
|
||||
d.HashAlgAbility,
|
||||
d.BufferSize)
|
||||
}
|
||||
|
||||
func (d *DeviceInfo) Unmarshal(data []byte) error {
|
||||
fmt.Println(data)
|
||||
if len(data) < d.Size() {
|
||||
return common.SDR_INARGERR
|
||||
}
|
||||
n := copy(d.IssuerName[:], data)
|
||||
data = data[n:]
|
||||
n = copy(d.DeviceName[:], data)
|
||||
data = data[n:]
|
||||
n = copy(d.DeviceSerial[:], data)
|
||||
data = data[n:]
|
||||
d.DeviceVersion = binary.LittleEndian.Uint32(data)
|
||||
data = data[4:]
|
||||
d.StandardVersion = binary.LittleEndian.Uint32(data)
|
||||
data = data[4:]
|
||||
d.AsymAlgAbility[0] = binary.LittleEndian.Uint32(data)
|
||||
data = data[4:]
|
||||
d.AsymAlgAbility[1] = binary.LittleEndian.Uint32(data)
|
||||
data = data[4:]
|
||||
d.SymAlgAbility = binary.LittleEndian.Uint32(data)
|
||||
data = data[4:]
|
||||
d.HashAlgAbility = binary.LittleEndian.Uint32(data)
|
||||
data = data[4:]
|
||||
d.BufferSize = binary.LittleEndian.Uint32(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
devInfo = &DeviceInfo{
|
||||
IssuerName: [40]byte{'G', 'o', 'M', 'a', 'i', 'n'},
|
||||
DeviceName: [16]byte{'G', 'C', 'L'},
|
||||
DeviceSerial: [16]byte{'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'},
|
||||
DeviceVersion: 1,
|
||||
StandardVersion: 1,
|
||||
AsymAlgAbility: [2]uint32{10000, 10000},
|
||||
SymAlgAbility: 10000,
|
||||
HashAlgAbility: 10000,
|
||||
BufferSize: 1024, // 最大随机数长度
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
package sdf
|
||||
|
||||
/* package sdf 是对gcl的SDF接口封装。
|
||||
*/
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"hash"
|
||||
|
||||
"xdx.jelly/xgcl/sm/sm3"
|
||||
)
|
||||
|
||||
// Split a premaster secret in two as specified in RFC 4346, Section 5.
|
||||
func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
|
||||
s1 = secret[0 : (len(secret)+1)/2]
|
||||
s2 = secret[len(secret)/2:]
|
||||
return
|
||||
}
|
||||
|
||||
// pHash implements the P_hash function, as defined in RFC 4346, Section 5.
|
||||
func pHash(result, secret, seed []byte, hash func() hash.Hash) {
|
||||
h := hmac.New(hash, secret)
|
||||
h.Write(seed)
|
||||
a := h.Sum(nil)
|
||||
|
||||
j := 0
|
||||
for j < len(result) {
|
||||
h.Reset()
|
||||
h.Write(a)
|
||||
h.Write(seed)
|
||||
b := h.Sum(nil)
|
||||
copy(result[j:], b)
|
||||
j += len(b)
|
||||
|
||||
h.Reset()
|
||||
h.Write(a)
|
||||
a = h.Sum(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func prfTLCP(result, secret, label, seed []byte) {
|
||||
labelAndSeed := make([]byte, len(label)+len(seed))
|
||||
copy(labelAndSeed, label)
|
||||
copy(labelAndSeed[len(label):], seed)
|
||||
|
||||
pHash(result, secret, labelAndSeed, sm3.New)
|
||||
}
|
||||
|
||||
const (
|
||||
masterSecretLength = 48 // Length of a master secret in TLS 1.1.
|
||||
finishedVerifyLength = 12 // Length of verify_data in a Finished message.
|
||||
)
|
||||
|
||||
var masterSecretLabel = []byte("master secret")
|
||||
var keyExpansionLabel = []byte("key expansion")
|
||||
|
||||
// masterFromPreMasterSecret generates the master secret from the pre-master
|
||||
// secret. See RFC 5246, Section 8.1.
|
||||
func masterFromPreMasterSecretTLCP(preMasterSecret, clientRandom, serverRandom []byte) []byte {
|
||||
seed := make([]byte, 0, len(clientRandom)+len(serverRandom))
|
||||
seed = append(seed, clientRandom...)
|
||||
seed = append(seed, serverRandom...)
|
||||
|
||||
masterSecret := make([]byte, masterSecretLength)
|
||||
prfTLCP(masterSecret, preMasterSecret, masterSecretLabel, seed)
|
||||
return masterSecret
|
||||
}
|
||||
|
||||
// keysFromMasterSecret generates the connection keys from the master
|
||||
// secret, given the lengths of the MAC key, cipher key and IV, as defined in
|
||||
// RFC 2246, Section 6.3.
|
||||
func keysFromMasterSecretTLCP(masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
|
||||
seed := make([]byte, 0, len(serverRandom)+len(clientRandom))
|
||||
seed = append(seed, serverRandom...)
|
||||
seed = append(seed, clientRandom...)
|
||||
|
||||
n := 2*macLen + 2*keyLen + 2*ivLen
|
||||
keyMaterial := make([]byte, n)
|
||||
prfTLCP(keyMaterial, masterSecret, keyExpansionLabel, seed)
|
||||
clientMAC = keyMaterial[:macLen]
|
||||
keyMaterial = keyMaterial[macLen:]
|
||||
serverMAC = keyMaterial[:macLen]
|
||||
keyMaterial = keyMaterial[macLen:]
|
||||
clientKey = keyMaterial[:keyLen]
|
||||
keyMaterial = keyMaterial[keyLen:]
|
||||
serverKey = keyMaterial[:keyLen]
|
||||
keyMaterial = keyMaterial[keyLen:]
|
||||
clientIV = keyMaterial[:ivLen]
|
||||
keyMaterial = keyMaterial[ivLen:]
|
||||
serverIV = keyMaterial[:ivLen]
|
||||
return
|
||||
}
|
||||
|
||||
func KeysFromPreMasterSecretTLCP(preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
|
||||
|
||||
masterSecret := masterFromPreMasterSecretTLCP(preMasterSecret, clientRandom, serverRandom)
|
||||
return keysFromMasterSecretTLCP(masterSecret, clientRandom, serverRandom, macLen, keyLen, ivLen)
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
"golang.org/x/crypto/cryptobyte/asn1"
|
||||
"xdx.jelly/xgcl/api/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
panic("Use package xdx.jelly/xsxfv2 instead")
|
||||
}
|
||||
|
||||
// PrivateKey implements the crypto.{Signer,Decrypter} interfaces
|
||||
type PrivateKey struct {
|
||||
Sdfable
|
||||
Index uint32
|
||||
KeyType KeyType
|
||||
|
||||
publicKey interface{}
|
||||
}
|
||||
|
||||
// ?
|
||||
type PublicKey struct {
|
||||
Sdfable
|
||||
Index uint32
|
||||
KeyType KeyType
|
||||
}
|
||||
|
||||
// Public return the public key. 注意可能return nil
|
||||
func (p *PrivateKey) Public() crypto.PublicKey {
|
||||
if p.publicKey != nil {
|
||||
return p
|
||||
}
|
||||
|
||||
switch p.KeyType {
|
||||
case KeyTypeSm2Enc:
|
||||
if k, err := p.SDF_ExportEncPublicKey_ECC(p.Index); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
p.publicKey = k
|
||||
return k
|
||||
}
|
||||
case KeyTypeSm2Sign:
|
||||
if k, err := p.SDF_ExportSignPublicKey_ECC(p.Index); err != nil {
|
||||
return nil
|
||||
} else {
|
||||
p.publicKey = k
|
||||
return k
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Sign signs digest with the private key
|
||||
// rand为nil,使用sdf接口的随机数. 有时rand也可以取如crypto/rand, 减少密码机调用,加快速度。
|
||||
// SM2:digest输入预处理结果。opts输入nil
|
||||
// RSA:TODO
|
||||
// return: ASN1 encoded signature
|
||||
func (p *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
||||
switch p.KeyType {
|
||||
case KeyTypeSm2Sign:
|
||||
sig, err := p.SDF_InternalSign_ECC(p.Index, digest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var b cryptobyte.Builder
|
||||
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
|
||||
b.AddASN1BigInt(sig.R)
|
||||
b.AddASN1BigInt(sig.S)
|
||||
})
|
||||
return b.Bytes()
|
||||
default:
|
||||
return nil, common.SDR_NOTSUPPORT
|
||||
}
|
||||
}
|
||||
|
||||
// Decrypter implements the crypto.Decryptor interface.
|
||||
// rand为nil,使用sdf接口的随机数. 有时rand也可以取如crypto/rand, 减少密码机调用,加快速度。
|
||||
// SM2:digest输入预处理结果。opts输入nil
|
||||
// RSA:TODO
|
||||
func (p *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) {
|
||||
switch p.KeyType {
|
||||
case KeyTypeSm2Enc:
|
||||
return nil, common.SDR_NOTSUPPORT
|
||||
|
||||
default:
|
||||
return nil, common.SDR_NOTSUPPORT
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
package sdf_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"xdx.jelly/xgcl/api/common"
|
||||
"xdx.jelly/xgcl/api/sdf"
|
||||
"xdx.jelly/xgcl/identifier"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
)
|
||||
|
||||
var gsdf sdf.Sdfable
|
||||
var index uint32 = 1
|
||||
var peerIndex uint32 = 2
|
||||
|
||||
func init() {
|
||||
SDF := &sdf.SdfNoLock{}
|
||||
for idx := uint32(1); idx < 10000; idx++ {
|
||||
refKey := &common.ECCrefPrivateKey{Bits: 256}
|
||||
SDF.SDF_GenerateRandom(refKey.K[32:])
|
||||
|
||||
var err error
|
||||
err = SDF.ImportSm2KeyAtIndex(idx, sdf.KeyTypeSm2Sign, refKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = SDF.ImportSm2KeyAtIndex(idx, sdf.KeyTypeSm2Enc, refKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
for idx := uint32(0); idx < 10000; idx++ {
|
||||
SDF.GenerateKekAtIndex(idx)
|
||||
}
|
||||
|
||||
gsdf = SDF
|
||||
}
|
||||
|
||||
func TestDevInfo(t *testing.T) {
|
||||
_, err := gsdf.SDF_GetDeviceInfo()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRandom(t *testing.T) {
|
||||
buf := make([]byte, 32)
|
||||
if n, err := gsdf.SDF_GenerateRandom(buf); err != nil || n < uint32(len(buf)) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
t.Fatalf("Generate %d random bytes, desired %d\n", n, len(buf))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSign(t *testing.T) {
|
||||
buf := make([]byte, 32)
|
||||
|
||||
sig, err := gsdf.SDF_InternalSign_ECC(index, buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = gsdf.SDF_InternalVerify_ECC(index, buf, sig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateKey_ECC(t *testing.T) {
|
||||
gsdf.SDF_OpenSession()
|
||||
defer gsdf.SDF_CloseSession()
|
||||
encKey, handle1, err := gsdf.SDF_GenerateKeyWithIPK_ECC(index, 128)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer gsdf.SDF_DestroyKey(handle1)
|
||||
|
||||
handle2, err := gsdf.SDF_ImportKeyWithISK_ECC(index, encKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer gsdf.SDF_DestroyKey(handle2)
|
||||
|
||||
var data [128]byte
|
||||
var iv [16]byte
|
||||
encData := []byte{}
|
||||
decData := []byte{}
|
||||
_, _ = gsdf.SDF_GenerateRandom(data[:])
|
||||
_, _ = gsdf.SDF_GenerateRandom(iv[:])
|
||||
|
||||
err = gsdf.SDF_Encrypt(handle1, identifier.SGDSM4CBC, append([]byte{}, iv[:]...), data[:], &encData)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = gsdf.SDF_Decrypt(handle2, identifier.SGDSM4CBC, append([]byte{}, iv[:]...), encData, &decData)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if bytes.Compare(data[:], decData) != 0 {
|
||||
t.Fatal("Compare unequal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateKey_KEK(t *testing.T) {
|
||||
gsdf.SDF_OpenSession()
|
||||
defer gsdf.SDF_CloseSession()
|
||||
encKey, handle1, err := gsdf.SDF_GenerateKeyWithKEK(128, identifier.SGDSM4ECB, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer gsdf.SDF_DestroyKey(handle1)
|
||||
|
||||
handle2, err := gsdf.SDF_ImportKeyWithKEK(identifier.SGDSM4ECB, 0, encKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer gsdf.SDF_DestroyKey(handle2)
|
||||
|
||||
var data [128]byte
|
||||
var iv [16]byte
|
||||
encData := []byte{}
|
||||
decData := []byte{}
|
||||
_, _ = gsdf.SDF_GenerateRandom(data[:])
|
||||
_, _ = gsdf.SDF_GenerateRandom(iv[:])
|
||||
|
||||
err = gsdf.SDF_Encrypt(handle1, identifier.SGDSM4CBC, append([]byte{}, iv[:]...), data[:], &encData)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = gsdf.SDF_Decrypt(handle2, identifier.SGDSM4CBC, append([]byte{}, iv[:]...), encData, &decData)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if bytes.Compare(data[:], decData) != 0 {
|
||||
t.Fatal("Compare unequal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExportPublicKey_ECC(t *testing.T) {
|
||||
gsdf.SDF_OpenSession()
|
||||
defer gsdf.SDF_CloseSession()
|
||||
|
||||
pk, err := gsdf.SDF_ExportSignPublicKey_ECC(index)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
e := make([]byte, 32)
|
||||
sig, err := gsdf.SDF_InternalSign_ECC(index, e)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = gsdf.SDF_ExternalVerify_ECC(identifier.SGDSM21, pk, e, sig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateKey_SSL(t *testing.T) {
|
||||
|
||||
preMasterSecret := make([]byte, 48)
|
||||
preMasterSecret[0] = 1
|
||||
preMasterSecret[1] = 1
|
||||
gsdf.SDF_GenerateRandom(preMasterSecret[2:])
|
||||
|
||||
var clientServerRandom [32 * 2]byte
|
||||
gsdf.SDF_GenerateRandom(clientServerRandom[:])
|
||||
|
||||
pucPublicKey, err := gsdf.SDF_ExportEncPublicKey_ECC(index)
|
||||
|
||||
pucKeyClientMac, phKeyHandleClientMac, pucKeyServerMac, phKeyHandleServerMac, pucKeyClientEnc, phKeyHandleClientEnc, pucKeyServerEnc, phKeyHandleServerEnc,
|
||||
clientWriteIV, serverWriteIV, err := gsdf.SDF_GenerateKeywithEPK_SSL(preMasterSecret, clientServerRandom[:32], clientServerRandom[32:], identifier.SGDSM3, identifier.SGDSM23, pucPublicKey, 128, 128, 128, 128)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
keyHandleClientMac, err := gsdf.SDF_ImportKeyWithISK_ECC(index, pucKeyClientMac)
|
||||
keyHandleServerMac, err := gsdf.SDF_ImportKeyWithISK_ECC(index, pucKeyServerMac)
|
||||
keyHandleClientEnc, err := gsdf.SDF_ImportKeyWithISK_ECC(index, pucKeyClientEnc)
|
||||
keyHandleServerEnc, err := gsdf.SDF_ImportKeyWithISK_ECC(index, pucKeyServerEnc)
|
||||
|
||||
msg := make([]byte, 128)
|
||||
gsdf.SDF_GenerateRandom(msg)
|
||||
|
||||
clientMac1, err := gsdf.SDF_CalculateMAC(keyHandleClientMac, identifier.SGDSM3, nil, msg)
|
||||
clientMac2, err := gsdf.SDF_CalculateMAC(phKeyHandleClientMac, identifier.SGDSM3, nil, msg)
|
||||
if bytes.Compare(clientMac1, clientMac2) != 0 {
|
||||
t.Fatal("client mac error")
|
||||
}
|
||||
|
||||
serverMac1, err := gsdf.SDF_CalculateMAC(keyHandleServerMac, identifier.SGDSM3, nil, msg)
|
||||
serverMac2, err := gsdf.SDF_CalculateMAC(phKeyHandleServerMac, identifier.SGDSM3, nil, msg)
|
||||
if bytes.Compare(serverMac1, serverMac2) != 0 {
|
||||
t.Fatal("server mac error")
|
||||
}
|
||||
|
||||
encMsg := make([]byte, len(msg))
|
||||
decMsg := make([]byte, len(msg))
|
||||
err = gsdf.SDF_Encrypt(keyHandleClientEnc, identifier.SGDSM4CBC, append([]byte{}, clientWriteIV...), msg, &encMsg)
|
||||
err = gsdf.SDF_Decrypt(phKeyHandleClientEnc, identifier.SGDSM4CBC, append([]byte{}, clientWriteIV...), encMsg, &decMsg)
|
||||
if bytes.Compare(msg, decMsg) != 0 {
|
||||
t.Fatal("client enc error")
|
||||
}
|
||||
|
||||
err = gsdf.SDF_Encrypt(keyHandleServerEnc, identifier.SGDSM4CBC, append([]byte{}, serverWriteIV...), msg, &encMsg)
|
||||
err = gsdf.SDF_Decrypt(phKeyHandleServerEnc, identifier.SGDSM4CBC, append([]byte{}, serverWriteIV...), encMsg, &decMsg)
|
||||
if bytes.Compare(msg, decMsg) != 0 {
|
||||
t.Fatal("server enc error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGenerateKey_ECDHE_SSL(t *testing.T) {
|
||||
//TODO 预主密钥48字节,前两字节应该是版本号。生成46字节的协商密钥
|
||||
pucSponsorPublicKey, pucSponsorTmpPublicKey, phAgreementHandle, err := gsdf.SDF_GenerateAgreementDataWithECC(index, 46*8, sm2.GetDefaultID())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pucResponsePublicKey, pucResponseTmpPublicKey, phKeyHandle2, err := gsdf.SDF_GenerateAgreementDataAndKeyWithECC(peerIndex, 46*8, sm2.GetDefaultID(), sm2.GetDefaultID(), pucSponsorPublicKey, pucSponsorTmpPublicKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
phKeyHandle1, err := gsdf.SDF_GenerateKeyWithECC(sm2.GetDefaultID(), pucResponsePublicKey, pucResponseTmpPublicKey, phAgreementHandle)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var clientServerRandom [32 * 2]byte
|
||||
gsdf.SDF_GenerateRandom(clientServerRandom[:])
|
||||
pucClientRandom := clientServerRandom[:32]
|
||||
pucServerRandom := clientServerRandom[:32]
|
||||
|
||||
phKeyHandleClientMac1, phKeyHandleServerMac1, phKeyHandleClientEnc1, phKeyHandleServerEnc1, clientWriteIV1, serverWriteIV1, err := gsdf.SDF_GenerateKeywithECDHE_SSL(phKeyHandle1, pucClientRandom, pucServerRandom, identifier.SGDSM3, 128, 128, 128, 128)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
phKeyHandleClientMac2, phKeyHandleServerMac2, phKeyHandleClientEnc2, phKeyHandleServerEnc2, clientWriteIV2, serverWriteIV2, err := gsdf.SDF_GenerateKeywithECDHE_SSL(phKeyHandle2, pucClientRandom, pucServerRandom, identifier.SGDSM3, 128, 128, 128, 128)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
msg := make([]byte, 128)
|
||||
gsdf.SDF_GenerateRandom(msg)
|
||||
|
||||
clientMac1, err := gsdf.SDF_CalculateMAC(phKeyHandleClientMac1, identifier.SGDSM3, nil, msg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
clientMac2, err := gsdf.SDF_CalculateMAC(phKeyHandleClientMac2, identifier.SGDSM3, nil, msg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(clientMac1, clientMac2) != 0 {
|
||||
t.Fatal("client mac error")
|
||||
}
|
||||
|
||||
serverMac1, err := gsdf.SDF_CalculateMAC(phKeyHandleServerMac1, identifier.SGDSM3, nil, msg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serverMac2, err := gsdf.SDF_CalculateMAC(phKeyHandleServerMac2, identifier.SGDSM3, nil, msg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if bytes.Compare(serverMac1, serverMac2) != 0 {
|
||||
t.Fatal("server mac error")
|
||||
}
|
||||
|
||||
encMsg := make([]byte, len(msg))
|
||||
decMsg := make([]byte, len(msg))
|
||||
err = gsdf.SDF_Encrypt(phKeyHandleClientEnc1, identifier.SGDSM4CBC, clientWriteIV1, msg, &encMsg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = gsdf.SDF_Decrypt(phKeyHandleClientEnc2, identifier.SGDSM4CBC, clientWriteIV2, encMsg, &decMsg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if bytes.Compare(msg, decMsg) != 0 {
|
||||
t.Fatal("client enc error")
|
||||
}
|
||||
|
||||
err = gsdf.SDF_Encrypt(phKeyHandleServerEnc1, identifier.SGDSM4CBC, serverWriteIV1, msg, &encMsg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = gsdf.SDF_Decrypt(phKeyHandleServerEnc2, identifier.SGDSM4CBC, serverWriteIV2, encMsg, &decMsg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if bytes.Compare(msg, decMsg) != 0 {
|
||||
t.Fatal("server enc error")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"xdx.jelly/xgcl/rsa"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
)
|
||||
|
||||
// Sdfable is the golang style of SDF interface(GB/T 36322-2018). The interface is
|
||||
// to minimum the upper applications' burden to use.
|
||||
//
|
||||
// The implement itself should be a sessionhandle.
|
||||
// So there are no need of sessionhandle in function params.
|
||||
// When New a impl. instants, it should include the device infos - IP,
|
||||
// port, connection timeout e.t.
|
||||
//
|
||||
// Its the impl's responsible to check connections to hardware
|
||||
// crypto-services.
|
||||
//
|
||||
// The params' name are keep the same with 0018/36322 for reference, though
|
||||
// the "puc" are not means "pointer to unsigned char".
|
||||
type Sdfable interface {
|
||||
StdSdfable // 标准0018接口
|
||||
ExtSdfable // 扩展接口
|
||||
SdfManager // 管理接口
|
||||
}
|
||||
|
||||
// 标准sdf接口
|
||||
type StdSdfable interface {
|
||||
// 实际上应该是OpenDevice返回一个Sdfable接口对象。实现时可以以包函数的方式实现。
|
||||
// SDF_OpenDevice() error
|
||||
// SDF_CloseDevice() error
|
||||
|
||||
// 一个Sdfable接口对象即是一个session
|
||||
SDF_OpenSession() error
|
||||
SDF_CloseSession() error
|
||||
|
||||
SDF_GetDeviceInfo() (*DeviceInfo, error)
|
||||
SDF_GetPrivateKeyAccessRight(keyIndex uint32, password []byte) error
|
||||
SDF_ReleasePrivateKeyAccessRight(keyIndex uint32) error
|
||||
|
||||
// 以随机数填充buffer。返回实际获取字节和错误。
|
||||
SDF_GenerateRandom(buffer []byte) (n uint32, err error)
|
||||
|
||||
// 6.3.1 导出RSA签名公钥
|
||||
// 描述: 导出密码设备内部存储的指定索引位置的签名公钥。
|
||||
// 备注:返回公钥只可读。不可进行更改。
|
||||
SDF_ExportSignPublicKey_RSA(uiKeyIndex uint32) (*rsa.PublicKey, error)
|
||||
|
||||
// 6.3.2 导出RSA加密公钥
|
||||
// 描述: 导出密码设备内部存储的指定索引位置的加密公钥。
|
||||
// 备注:返回公钥只可读。不可进行更改。
|
||||
SDF_ExportEncPublicKey_RSA(uiKeyIndex uint32) (*rsa.PublicKey, error)
|
||||
|
||||
// 6.3.3 产生RSA密钥对并输出
|
||||
SDF_GenerateKeyPair_RSA(uiKeyBits uint32) (*rsa.PublicKey, *rsa.PrivateKey, error)
|
||||
|
||||
// 6.3.4 生成会话密钥并用内部RSA公钥加密输出
|
||||
// 描述: 生成会话密钥并用指定索引的内部加密公钥加密输出, 同时返回密钥句柄。
|
||||
// 备注: 公钥加密数据时填充方式按照PKCS#1 v1.5的要求进行。
|
||||
SDF_GenerateKeyWithIPK_RSA(uiIPKIndex uint32, uiKeyBits uint32) (pucKey []byte, phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.5 生成会话密钥并用外部RSA公钥加密输出
|
||||
// 描述: 生成会话密钥并用外部公钥加密输出, 同时返回密钥句柄。
|
||||
// 备注: 公钥加密数据时填充方式按照PKCS#1 v1.5的要求进行。
|
||||
SDF_GenerateKeyWithEPK_RSA(uiKeyBits uint32, pucPublicKey *rsa.PublicKey) (Key []byte, phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.6 导入会话密钥并用内部RSA私钥解密
|
||||
// 描述: 导入会话密钥并用内部私钥解密, 同时返回密钥句柄。
|
||||
// 注:填充方式与公钥加密时相同。
|
||||
SDF_ImportKeyWithISK_RSA(uiISKIndex uint32, pucKey []byte) (phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.7 基于RSA算法的数字信封转换
|
||||
// 描述: 将由内部加密公钥加密的会话密钥转换为由外部指定的公钥加密, 可用于数字信封转换。
|
||||
SDF_ExchangeDigitEnvelopeBaseOnRSA(uiKeyIndex uint32, pucPublicKey *rsa.PublicKey, pucDEInput []byte) (pucDEOutput []byte, err error)
|
||||
|
||||
// 6.3.8 导出ECC签名公钥
|
||||
SDF_ExportSignPublicKey_ECC(uiKeyIndex uint32) (*sm2.PublicKey, error)
|
||||
|
||||
// 6.3.9 导出ECC加密公钥
|
||||
// 描述: 导出密码设备内部存储的指定索引位置的加密公钥。
|
||||
SDF_ExportEncPublicKey_ECC(uiKeyIndex uint32) (*sm2.PublicKey, error)
|
||||
|
||||
// 6.3.10 产生ECC密钥对并输出
|
||||
// 描述: 请求密码设备产生指定类型和模长的ECC密钥对。
|
||||
SDF_GenerateKeyPair_ECC(uiAlgID uint32, uiKeyBits uint32) (*sm2.PublicKey, *sm2.PrivateKey, error)
|
||||
|
||||
// 6.3.11 生成会话密钥并用内部ECC公钥加密输出
|
||||
// 描述: 生成会话密钥并用指定索引的内部ECC加密公钥加密输出, 同时返回密钥句柄。
|
||||
SDF_GenerateKeyWithIPK_ECC(uiIPKIndex uint32, uiKeyBits uint32) (pucKey *sm2.Cipher, phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.12 生成会话密钥并用外部ECC公钥加密输出
|
||||
// 描述: 生成会话密钥并用外部ECC公钥加密输出, 同时返回密钥句柄。
|
||||
SDF_GenerateKeyWithEPK_ECC(uiKeyBits uint32, uiAlgID uint32, pucPublicKey *sm2.PublicKey) (pucKey *sm2.Cipher, phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.13 导入会话密钥并用内部ECC私钥解密
|
||||
// 描述: 导入会话密钥并用内部ECC加密私钥解密, 同时返回密钥句柄。
|
||||
SDF_ImportKeyWithISK_ECC(uiISKIndex uint32, pucKey *sm2.Cipher) (phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.14 生成密钥协商参数并输出
|
||||
// 描述: 使用ECC密钥协商算法, 为计算会话密钥而产生协商参数, 同时返回指定索引位置的ECC公钥、临时ECC密钥对的公钥及协商句柄。
|
||||
SDF_GenerateAgreementDataWithECC(uiISKIndex uint32, uiKeyBits uint32, pucSponsorID []byte) (pucSponsorPublicKey *sm2.PublicKey, pucSponsorTmpPublicKey *sm2.PublicKey, phAgreementHandle interface{}, err error)
|
||||
|
||||
// 6.3.15 计算会话密钥
|
||||
// 描述: 使用ECC密钥协商算法, 使用自身协商句柄和响应方的协商参数计算会话密钥, 同时返回会话密钥句柄。
|
||||
// 备注: 协商的发起方获得响应方的协商参数后调用本函数, 计算会话密钥。使用SM2算法计算会话密钥的过程见GM/T 0009。
|
||||
SDF_GenerateKeyWithECC(pucResponseID []byte, pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, hAgreementHandle interface{}) (phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.16 产生协商数据并计算会话密钥
|
||||
// 描述: 使用ECC密钥协商算法, 产生协商参数并计算会话密钥, 同时返回产生的协商参数和密钥句柄。
|
||||
SDF_GenerateAgreementDataAndKeyWithECC(uiISKIndex uint32, uiKeyBits uint32, pucResponseID []byte, pucSponsorID []byte, pucSponsorPublicKey, pucSponsorTmpPublicKey *sm2.PublicKey) (pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.17 基于ECC算法的数字信封转换
|
||||
// 描述: 将由内部加密公钥加密的会话密钥转换为由外部指定的公钥加密, 可用于数字信封转换。
|
||||
SDF_ExchangeDigitEnvelopeBaseOnECC(uiKeyIndex uint32, uiAlgID uint32, pucPublicKey *sm2.PublicKey,
|
||||
pucEncDataIn *sm2.Cipher) (pucEncDataOut *sm2.Cipher, err error)
|
||||
|
||||
// 6.3.18 生成会话密钥并用密钥加密密钥加密输出
|
||||
// 描述: 生成会话密钥并用密钥加密密钥加密输出, 同时返回密钥句柄。
|
||||
// 备注: 加密模式使用ECB模式。
|
||||
SDF_GenerateKeyWithKEK(uiKeyBits uint32, uiAlgID uint32, uiKEKIndex uint32) (pucKey []byte, phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.19 导入会话密钥并用密钥加密密钥解密
|
||||
// 描述: 导入会话密钥并用密钥加密密钥解密, 同时返回会话密钥句柄。
|
||||
// 备注: 加密模式使用ECB模式。
|
||||
SDF_ImportKeyWithKEK(uiAlgID uint32, uiKEKIndex uint32, pucKey []byte) (phKeyHandle interface{}, err error)
|
||||
|
||||
// 6.3.20 计算IKE工作密钥
|
||||
// 描述: 使用IKE一阶段(主模式)交换得到的密钥计算参数计算IKE会话密钥, 同时返回会话密钥句柄。
|
||||
// 备注: IKE一阶段(主模式)消息3和消息4交互完成后, 参与通信的双方调用本函数,
|
||||
// 计算后续会话密钥SKEYID_d, SKEYID_a, SKEYID_e。IKE一阶段(主模式)计算IKE会话密钥的过程见GM/T 0022。
|
||||
// 输入的密钥参数按顺序为Ni_b, Nr_b, CKY_I, CKY_R,返回的密钥句柄按顺序为SKEYID_d,SKEYID_a,SKEYID_e
|
||||
SDF_GenerateKeywithIKE(pucSponsorNonce []byte, pucResponseNonce []byte, pucSponsorCookie []byte, pucResponseCookie []byte, uiPrfAlgID uint32, uiKeyBitsD, uiKeyBitsA, uiKeyBitsE uint32) (phKeyHandleD interface{}, phKeyHandleA interface{}, phKeyHandleE interface{}, err error)
|
||||
|
||||
// 6.3.22 计算IKE工作密钥并用外部ECC公钥加密输出
|
||||
// 描述: 使用IKE一阶段(主模式)交换得到的密钥计算参数计算IKE工作密钥,并用外部
|
||||
// ECC公钥加密输出,同时返回工作密钥句柄。
|
||||
// 备注: IKE一阶段(主模式)消息3和消息4交互完成后, 参与通信的双方调用本函数,
|
||||
// 计算后续会话密钥SKEYID_d, SKEYID_a, SKEYID_e。IKE一阶段(主模式)计算IKE会话密钥的过程见GM/T 0022。
|
||||
// 输入的密钥参数按顺序为Ni_b, Nr_b, CKY_I, CKY_R,返回的密钥句柄按顺序为SKEYID_d,SKEYID_a,SKEYID_e
|
||||
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)
|
||||
|
||||
// 6.3.23 计算IPSEC会话密钥
|
||||
// 描述: 使用IKE二阶段(快速模式)交换得到的密钥计算参数计算IPSEC会话密钥, 同时返回会话密钥句柄。
|
||||
// 备注: IKE二阶段(快速模式)消息交互完成后, 参与通信的双方调用本函数, 计算IPSEC会话密钥, 包括用于加密的会话密钥和用于完整性校验的会话密钥。IKE二阶段(快速模式)计算IPSEC会话密钥的过程见GM/T 0022。本函数需在6.3.20计算IKE会话密钥函数调用之后调用, 并将该函数返回的密钥句柄之一(SKEYID_d)作为输入。
|
||||
SDF_GenerateKeywithIPSEC(
|
||||
pucProtocolID []byte,
|
||||
pucSpi []byte,
|
||||
pucSponsorNonce []byte,
|
||||
pucResponseNonce []byte,
|
||||
hKeyHandle interface{},
|
||||
uiPrfAlgID uint32,
|
||||
uiKeyBitsEnc, uiKeyBitsMac uint32,
|
||||
) (phKeyHandleEnc interface{}, phKeyHandleMac interface{}, err error)
|
||||
|
||||
// 6.3.24 计算IPSEC会话密钥并用外部ECC公钥加密输出
|
||||
// 注:IKE 二阶段(快速模式)消息交互完成后,本函数由参与通信的双方各自调用,计算IPSEC 会话密钥,包括用于
|
||||
// 加密的会话密钥和用于完整性校验的会话密钥。IKE 二阶段(快速模式)计算IPSEC 会话密钥的过程参见
|
||||
// GM/T0022,输入的密钥参数按顺序为protocol、SPI、Ni_b、Nr_b,返回的密钥密文和密钥句柄按顺序为加密密
|
||||
// 钥和杂凑密钥(用于完整性校验)。本函数在6.3.21计算IKE 工作密钥函数调用之后调用,该函数返回的密钥
|
||||
// 句柄之一(SKEYID_d)作为本函数输入。
|
||||
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)
|
||||
|
||||
// 6.3.25 计算SSL工作密钥
|
||||
// 描述: 使用SSL握手协议得到的密钥计算参数计算SSL会话密钥, 同时返回会话密钥句柄。
|
||||
// 备注:
|
||||
// SSL握手协议消息交互完成后, 参与通信的双方调用本函数, 计算SSL记录层协议的会话密钥client_write_MAC_secret, server_write_MAC_secret, client_write_ key, server_write_key。SSL计算会话密钥的过程见GM/T 0024。
|
||||
// 备注:与标准有不同,这里增加了返回pucClientIV, pucServerIV
|
||||
SDF_GenerateKeywithSSL(
|
||||
pucKeyPremaster, pucClientRandom, pucServerRandom []byte,
|
||||
uiPrfAlgID uint32,
|
||||
uiKeyBitsClientMac, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc uint32,
|
||||
) (phKeyHandleClientMac, phKeyHandleServerMac, phKeyHandleClientEnc, phKeyHandleServerEnc interface{}, pucClientIV, pucServerIV []byte, err error)
|
||||
|
||||
// 6.3.26 计算SSL工作密钥并用外部ECC公钥加密输出
|
||||
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)
|
||||
|
||||
// 6.3.27 计算SSL工作密钥(ECDHE)
|
||||
// 描述: 使用SSL握手协议得到的密钥计算参数计算SSL工作密钥,同时返回工作密钥句柄。
|
||||
// 备注:这里的预主密钥为SM2密钥交换得到的密钥句柄。
|
||||
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)
|
||||
|
||||
// 6.3.28 计算SSL工作密钥并用外部ECC公钥加密输出
|
||||
// 描述: 使用SSL握手协议得到的密钥计算参数计算SSL工作密钥,同时返回工作密钥句柄。
|
||||
// 备注:这里的预主密钥为SM2密钥交换得到的密钥句柄。
|
||||
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)
|
||||
|
||||
// 6.3.29 销毁会话密钥
|
||||
// 描述: 销毁会话密钥, 并释放为密钥句柄分配的内存等资源。
|
||||
// 备注: 在对称算法运算完成后, 应调用本函数销毁会话密钥。
|
||||
SDF_DestroyKey(hKeyHandle interface{}) error
|
||||
|
||||
// 6.4 非对称算法运算类函数
|
||||
// 6.4.2 外部公钥RSA运算
|
||||
// 描述: 指定使用外部公钥对数据进行运算。
|
||||
// 备注1: 数据格式由应用层封装。
|
||||
// 备注2:一般非对称运算加密密钥,因此输出为内部分配内存。
|
||||
SDF_ExternalPublicKeyOperation_RSA(pucPublicKey *rsa.PublicKey, pucDataInput []byte) (pucDataOutput []byte, err error)
|
||||
|
||||
// 6.4.3 内部公钥RSA运算
|
||||
// 描述: 使用内部指定索引的公钥对数据进行运算。
|
||||
// 备注: 索引范围仅限于内部签名密钥对, 数据格式由应用层封装。
|
||||
SDF_DecryptPublicKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error)
|
||||
|
||||
// 6.4.4 内部私钥RSA运算
|
||||
// 描述: 使用内部指定索引的私钥对数据进行运算。
|
||||
// 备注: 索引范围仅限于内部签名密钥对, 数据格式由应用层封装。
|
||||
SDF_InternalPrivateKeyOperation_RSA(
|
||||
uiKeyIndex uint32,
|
||||
pucDataInput []byte) (pucDataOutput []byte, err error)
|
||||
|
||||
// 6.4.5 外部密钥ECC验证
|
||||
// 描述: 使用外部ECC公钥对ECC签名值进行验证运算。
|
||||
// 备注: 输入数据为待签数据的杂凑值。当使用SM2算法时, 该输入数据为待签数据经过SM2签名预处理的结果, 预处理过程见GM/T 0009。
|
||||
SDF_ExternalVerify_ECC(
|
||||
uiAlgID uint32,
|
||||
pucPublicKey *sm2.PublicKey,
|
||||
pucDataInput []byte,
|
||||
pucSignature *sm2.Signature) (err error)
|
||||
|
||||
// GMT 0018-2012 有,但36322没有
|
||||
SDF_ExternalSign_ECC(uiAlgID uint32, pucPrivateKey *sm2.PrivateKey, pucData []byte) (*sm2.Signature, error)
|
||||
|
||||
// 6.4.6 内部密钥ECC签名
|
||||
// 描述: 使用内部ECC私钥对数据进行签名运算。
|
||||
// 备注: 输入数据为待签数据的杂凑值。当使用SM2算法时, 该输入数据为待签数据经过SM2签名预处理的结果, 预处理过程见GM/T 0009。
|
||||
SDF_InternalSign_ECC(uiISKIndex uint32, pucData []byte) (pucSignature *sm2.Signature, err error)
|
||||
|
||||
// 6.4.7 内部密钥ECC验证
|
||||
// 描述: 使用内部ECC公钥对ECC签名值进行验证运算。
|
||||
// 备注: 输入数据为待签数据的杂凑值。当使用SM2算法时, 该输入数据为待签数据经过SM2签名预处理的结果, 预处理过程见GM/T 0009。
|
||||
SDF_InternalVerify_ECC(
|
||||
uiISKIndex uint32,
|
||||
pucData []byte,
|
||||
pucSignature *sm2.Signature) (err error)
|
||||
|
||||
// 6.4.8 外部密钥ECC公钥加密
|
||||
// 描述: 使用外部ECC公钥对数据进行加密运算。
|
||||
SDF_ExternalEncrypt_ECC(
|
||||
uiAlgID uint32,
|
||||
pucPublicKey *sm2.PublicKey,
|
||||
pucData []byte) (pucEncData *sm2.Cipher, err error)
|
||||
|
||||
// 外部ECC私钥解密,GMT0018有,36322没有。
|
||||
SDF_ExternalDecrypt_ECC(uiAlgID uint32, pucPrivateKey *sm2.PrivateKey, pucEncData *sm2.Cipher) (pucData []byte, err error)
|
||||
|
||||
// 6.5 对称算法运算类函数
|
||||
// 对称算法运算类函数包括以下具体函数, 各函数返回值见附录A函数返回代码定义:
|
||||
// a) 对称加密:Encrypt
|
||||
// b) 对称解密:Decrypt
|
||||
// c) 计算MAC:CalculateMAC
|
||||
|
||||
// 6.5.1 对称加密
|
||||
// 描述: 使用指定的密钥句柄和IV对数据进行对称加密运算
|
||||
// 备注1: 此函数不对数据进行填充处理, 输入的数据必须是指定算法分组长度的整数倍。
|
||||
// 备注2: 为避免内存分配,pucEncData提前分配好足够的空间。pucEncData如果空间不够,会重分配内存
|
||||
// 备注3: pucIV-输入输出
|
||||
SDF_Encrypt(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte, pucEncData *[]byte) (err error)
|
||||
|
||||
// 6.5.2 对称解密
|
||||
// 描述: 使用指定句柄和IV对数据进行对称解密运算。
|
||||
// 备注1: 此函数不对数据进行填充处理, 输入的数据必须是指定算法分组长度的整数倍。
|
||||
// 备注2: pucIV和pucData同对称加密
|
||||
SDF_Decrypt(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucEncData []byte, pucData *[]byte) (err error)
|
||||
|
||||
// 6.5.3 计算MAC
|
||||
// 描述: 使用指定的密钥句柄和IV对数据进行MAC运算。
|
||||
// uiAlgID的取值为:
|
||||
// - identifier.SGD_SM3, 计算HMAC_SM3, 忽略pucIV
|
||||
// - identifier.SGD_SM1_MAC, 计算SM1_CBCMAC
|
||||
// - identifier.SGD_SM4_MAC, 计算SM4_CBCMAC
|
||||
// 备注:CBCMac不对数据进行分包处理, 多包数据MAC运算由IV控制最后的MAC值。
|
||||
SDF_CalculateMAC(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte) (pucMAC []byte, err error)
|
||||
|
||||
// 6.6 杂凑运算类函数
|
||||
// 备注:0018中杂凑运算与hSessionHandle相关联。
|
||||
// 6.6.2 杂凑运算初始化
|
||||
// 描述: 三步式数据杂凑运算第一步。
|
||||
// 备注: uiIDLength非零且uiAlgID为SGD_SM3时, 函数执行SM2的预处理操作。计算过程见GM/T 0009。
|
||||
SDF_HashInit(uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucID []byte) (err error)
|
||||
|
||||
// 6.6.3 多包杂凑运算
|
||||
// 描述: 三步式运算第二步, 对输入的明文进行杂凑运算。
|
||||
SDF_HashUpdate(pucData []byte) (err error)
|
||||
|
||||
// 6.6.4 杂凑运算结束
|
||||
SDF_HashFinal() (pucHash []byte, err error)
|
||||
|
||||
// 6.7 用户文件操作类函数
|
||||
// 用户文件操作类函数包括以下具体函数, 各函数返回值见附录A函数返回代码定义:
|
||||
// a) 创建文件 CreateFile
|
||||
// b) 读取文件:ReadFile
|
||||
// c) 写文件:WriteFile
|
||||
// d) 删除文件:DeleteFile
|
||||
|
||||
// 6.7.2 创建文件
|
||||
// 描述: 在密码设备内部创建用于存储用户数据的文件。
|
||||
SDF_CreateFile(pucFileName string, uiFileSize uint32) error
|
||||
|
||||
// 6.7.3 读取文件
|
||||
// 描述: 读取在密码设备内部存储用户数据的文件的内容。
|
||||
// 备注: 读取文件内容至pucBuffer,返回读取字节数。
|
||||
// 当err != nil时,有可能n>0. 例如err = io.EOF时,仍可能读取到一定字节数。
|
||||
SDF_ReadFile(pucFileName string, uiOffset uint32, pucBuffer []byte) (n uint32, err error)
|
||||
|
||||
// 6.7.3 写文件
|
||||
// 描述: 向密码设备内部存储用户数据的文件中写入内容。
|
||||
SDF_WriteFile(pucFileName string, uiOffset uint32, pucBuffer []byte) error
|
||||
|
||||
// 6.7.4 删除文件
|
||||
// 描述: 删除指定文件名的密码设备内部存储用户数据的文件。
|
||||
SDF_DeleteFile(pucFileName string) error
|
||||
}
|
||||
|
||||
// sdf 的扩展接口
|
||||
type ExtSdfable interface {
|
||||
|
||||
// 内部sm2私钥解密
|
||||
SDFEXT_InternalDecryptECC(uiKeyIndex uint32, pucEncData *sm2.Cipher) (pucData []byte, err error)
|
||||
|
||||
// 6.3.14 生成密钥协商参数并输出-这个与标准接口一致
|
||||
// 描述: 使用ECC密钥协商算法, 为计算会话密钥而产生协商参数, 同时返回指定索引位置的ECC公钥、临时ECC密钥对的公钥及协商句柄。
|
||||
SDFEXT_GenerateAgreementDataWithECC(uiISKIndex uint32, uiKeyBits uint32, pucSponsorID []byte) (pucSponsorPublicKey *sm2.PublicKey, pucSponsorTmpPublicKey *sm2.PublicKey, phAgreementHandle interface{}, err error)
|
||||
|
||||
// 6.3.15 计算会话密钥变体
|
||||
// 描述: 使用ECC密钥协商算法, 使用自身协商句柄和响应方的协商参数计算会话密钥, 同时返回会话密钥。
|
||||
// 备注: 协商的发起方获得响应方的协商参数后调用本函数, 计算会话密钥。使用SM2算法计算会话密钥的过程见GM/T 0009。
|
||||
SDFEXT_GenerateKeyWithECC(pucResponseID []byte, pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, hAgreementHandle interface{}) (agreementKey []byte, err error)
|
||||
|
||||
// 6.3.16 产生协商数据并计算会话密钥
|
||||
// 描述: 使用ECC密钥协商算法, 产生协商参数并计算会话密钥, 同时返回产生的协商参数和密钥。
|
||||
SDFEXT_GenerateAgreementDataAndKeyWithECC(uiISKIndex uint32, uiKeyBits uint32, pucResponseID []byte, pucSponsorID []byte, pucSponsorPublicKey, pucSponsorTmpPublicKey *sm2.PublicKey) (pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, agreementKey []byte, err error)
|
||||
}
|
||||
|
||||
type SdfManager interface {
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
package sdf
|
||||
|
||||
import "sync"
|
||||
|
||||
// SdfWithLock 带锁的SDFable实现。
|
||||
// GCL作为软算法实例,应看做是一个device。需要进行加锁同步,可多线程共用一个实例。
|
||||
type SdfWithLock struct {
|
||||
sdflocked SdfNoLock // 先加锁,再调用sdflocked.xx
|
||||
mu sync.RWMutex
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"xdx.jelly/xgcl/pbkd"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
"xdx.jelly/xgcl/sm/sm4"
|
||||
)
|
||||
|
||||
/*
|
||||
Example of snapshot:
|
||||
{
|
||||
"keys":[
|
||||
{
|
||||
"type": "Sm2SignKey",
|
||||
"url": "sm2sign/12",
|
||||
"material": ["base64(d)", "base64(04||x||y)"]
|
||||
},
|
||||
{
|
||||
"type": "Sm2SignKey",
|
||||
"url": "sm2enc/12",
|
||||
"material": ["base64(d)", "base64(04||x||y)"]
|
||||
},
|
||||
{
|
||||
"type": "BlockKey",
|
||||
"url": "kek/0",
|
||||
"material": ["base64(key)"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
*/
|
||||
type KeyMaterial struct {
|
||||
Type string `json:"type"`
|
||||
Url string `json:"url"`
|
||||
Nonces [][]byte `json:"nonces"` // coresponding to each Material, with add Url
|
||||
Materials [][]byte `json:"materials"`
|
||||
}
|
||||
|
||||
type EncParam struct {
|
||||
Algo string `json:"algo"` // only "sm4_gcm" are supported
|
||||
Salt []byte `json:"salt"`
|
||||
Count uint32 `json:"count"`
|
||||
}
|
||||
|
||||
type Snapshot struct {
|
||||
Time time.Time `json:"time"`
|
||||
Info string `json:"info"`
|
||||
Enc bool `json:"enc"`
|
||||
EncParam *EncParam `json:"encParam"`
|
||||
Keys []*KeyMaterial `json:"keys"`
|
||||
}
|
||||
|
||||
func (s *SdfNoLock) Snapshot(enc bool, password []byte, count int) (*Snapshot, error) {
|
||||
|
||||
snapshot := &Snapshot{
|
||||
Time: time.Now(),
|
||||
Enc: enc,
|
||||
Keys: make([]*KeyMaterial, 0),
|
||||
}
|
||||
var aead cipher.AEAD
|
||||
var nonces [][]byte
|
||||
|
||||
if enc {
|
||||
var salt []byte
|
||||
var err error
|
||||
var n uint32
|
||||
salt = make([]byte, 16)
|
||||
if n, err = s.SDF_GenerateRandom(salt); err != nil || n != uint32(len(salt)) {
|
||||
return nil, err
|
||||
}
|
||||
var encryptionKey []byte
|
||||
if encryptionKey, err = pbkd.PbkdfWithHmacSm3(password, salt, count, sm4.BlockSize); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if aead, err = sm4.NewGCM(encryptionKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonces = [][]byte{
|
||||
make([]byte, aead.NonceSize()),
|
||||
make([]byte, aead.NonceSize()),
|
||||
}
|
||||
|
||||
snapshot.EncParam = &EncParam{
|
||||
Algo: "sm4_gcm",
|
||||
Salt: salt,
|
||||
Count: uint32(count),
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range s.Sm2Key {
|
||||
if v.signKey != nil {
|
||||
sk := v.signKey.Bytes()
|
||||
pk := v.signKey.PublicKey.Bytes()
|
||||
url := fmt.Sprintf("sm2sign/%d", k)
|
||||
thisNonces := nonces
|
||||
if aead != nil {
|
||||
s.SDF_GenerateRandom(nonces[0])
|
||||
s.SDF_GenerateRandom(nonces[1])
|
||||
thisNonces = [][]byte{
|
||||
append([]byte{}, nonces[0]...),
|
||||
append([]byte{}, nonces[1]...),
|
||||
}
|
||||
sk = aead.Seal(sk[:0], nonces[0], sk, []byte(url))
|
||||
pk = aead.Seal(pk[:0], nonces[1], pk, []byte(url))
|
||||
}
|
||||
km := &KeyMaterial{
|
||||
Type: KeyTypeSm2Sign.String(),
|
||||
Url: url,
|
||||
Nonces: thisNonces,
|
||||
Materials: [][]byte{sk, pk},
|
||||
}
|
||||
snapshot.Keys = append(snapshot.Keys, km)
|
||||
}
|
||||
|
||||
if v.encKey != nil {
|
||||
sk := v.encKey.Bytes()
|
||||
pk := v.encKey.PublicKey.Bytes()
|
||||
url := fmt.Sprintf("sm2enc/%d", k)
|
||||
thisNonces := nonces
|
||||
if aead != nil {
|
||||
s.SDF_GenerateRandom(nonces[0])
|
||||
s.SDF_GenerateRandom(nonces[1])
|
||||
thisNonces = [][]byte{
|
||||
append([]byte{}, nonces[0]...),
|
||||
append([]byte{}, nonces[1]...),
|
||||
}
|
||||
sk = aead.Seal(sk[:0], nonces[0], sk, []byte(url))
|
||||
pk = aead.Seal(pk[:0], nonces[1], pk, []byte(url))
|
||||
}
|
||||
km := &KeyMaterial{
|
||||
Type: KeyTypeSm2Enc.String(),
|
||||
Url: url,
|
||||
Nonces: thisNonces,
|
||||
Materials: [][]byte{sk, pk},
|
||||
}
|
||||
snapshot.Keys = append(snapshot.Keys, km)
|
||||
}
|
||||
}
|
||||
for k, v := range s.SymKey {
|
||||
key := make([]byte, len(v.key), len(v.key)+16)
|
||||
url := fmt.Sprintf("kek/%d", k)
|
||||
thisNonces := nonces
|
||||
copy(key, v.key)
|
||||
if aead != nil {
|
||||
s.SDF_GenerateRandom(nonces[0])
|
||||
thisNonces = [][]byte{
|
||||
append([]byte{}, nonces[0]...),
|
||||
}
|
||||
key = aead.Seal(key[:0], nonces[0], key, []byte(url))
|
||||
}
|
||||
|
||||
km := &KeyMaterial{
|
||||
Type: v.keyType.String(),
|
||||
Url: url,
|
||||
Nonces: thisNonces,
|
||||
Materials: [][]byte{key},
|
||||
}
|
||||
snapshot.Keys = append(snapshot.Keys, km)
|
||||
}
|
||||
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
func (s *SdfNoLock) Restore(ss *Snapshot, password []byte) error {
|
||||
var sdf = &SdfNoLock{
|
||||
RsaKey: make(map[uint32]*RsaKey),
|
||||
Sm2Key: make(map[uint32]*Sm2Key),
|
||||
SymKey: make(map[uint32]*SymKey),
|
||||
}
|
||||
var aead cipher.AEAD
|
||||
var err error
|
||||
if ss.Enc {
|
||||
var encryptionKey []byte
|
||||
if encryptionKey, err = pbkd.PbkdfWithHmacSm3([]byte(password), ss.EncParam.Salt, int(ss.EncParam.Count), sm4.BlockSize); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if aead, err = sm4.NewGCM(encryptionKey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, k := range ss.Keys {
|
||||
if k == nil {
|
||||
return fmt.Errorf("nil key")
|
||||
}
|
||||
switch GetKeyType(k.Type) {
|
||||
case KeyTypeBlock:
|
||||
if len(k.Materials) != 1 || len(k.Nonces) != len(k.Materials) {
|
||||
return fmt.Errorf("key material error")
|
||||
}
|
||||
key := k.Materials[0]
|
||||
if aead != nil {
|
||||
key, err = aead.Open(nil, k.Nonces[0], key, []byte(k.Url))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
urlSplits := strings.Split(k.Url, "/")
|
||||
if len(urlSplits) != 2 {
|
||||
return fmt.Errorf("key url error")
|
||||
}
|
||||
if strings.TrimSpace(urlSplits[0]) != "kek" {
|
||||
return fmt.Errorf("key url error")
|
||||
}
|
||||
index, err := strconv.Atoi(urlSplits[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("key url error")
|
||||
} else {
|
||||
sdf.SymKey[uint32(index)] = &SymKey{
|
||||
keyType: KeyTypeBlock,
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
case KeyTypeSm2Sign:
|
||||
if len(k.Materials) != 2 || len(k.Nonces) != len(k.Materials) {
|
||||
return fmt.Errorf("key material error")
|
||||
}
|
||||
sk := k.Materials[0]
|
||||
pk := k.Materials[1]
|
||||
if aead != nil {
|
||||
sk, err = aead.Open(nil, k.Nonces[0], sk, []byte(k.Url))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pk, err = aead.Open(nil, k.Nonces[1], pk, []byte(k.Url))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
urlSplits := strings.Split(k.Url, "/")
|
||||
if len(urlSplits) != 2 {
|
||||
return fmt.Errorf("key url error")
|
||||
}
|
||||
if strings.TrimSpace(urlSplits[0]) != "sm2sign" {
|
||||
return fmt.Errorf("key url error")
|
||||
}
|
||||
index, err := strconv.Atoi(urlSplits[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("key url error")
|
||||
} else {
|
||||
sm2PrivateKey := &sm2.PrivateKey{
|
||||
D: new(big.Int).SetBytes(sk),
|
||||
}
|
||||
sm2PrivateKey.PublicKey.Curve = sm2.Curve()
|
||||
sm2PrivateKey.PublicKey.X = new(big.Int).SetBytes(pk[:sm2.ByteSize()])
|
||||
sm2PrivateKey.PublicKey.Y = new(big.Int).SetBytes(pk[sm2.ByteSize():])
|
||||
|
||||
if _, ok := sdf.Sm2Key[uint32(index)]; !ok {
|
||||
sdf.Sm2Key[uint32(index)] = &Sm2Key{}
|
||||
}
|
||||
sdf.Sm2Key[uint32(index)].signKey = sm2PrivateKey
|
||||
}
|
||||
|
||||
case KeyTypeSm2Enc:
|
||||
if len(k.Materials) != 2 || len(k.Nonces) != len(k.Materials) {
|
||||
return fmt.Errorf("key material error")
|
||||
}
|
||||
sk := k.Materials[0]
|
||||
pk := k.Materials[1]
|
||||
if aead != nil {
|
||||
sk, err = aead.Open(nil, k.Nonces[0], sk, []byte(k.Url))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pk, err = aead.Open(nil, k.Nonces[1], pk, []byte(k.Url))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
urlSplits := strings.Split(k.Url, "/")
|
||||
if len(urlSplits) != 2 {
|
||||
return fmt.Errorf("key url error")
|
||||
}
|
||||
if strings.TrimSpace(urlSplits[0]) != "sm2enc" {
|
||||
return fmt.Errorf("key url error")
|
||||
}
|
||||
index, err := strconv.Atoi(urlSplits[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("key url error")
|
||||
} else {
|
||||
sm2PrivateKey := &sm2.PrivateKey{
|
||||
D: new(big.Int).SetBytes(sk),
|
||||
}
|
||||
sm2PrivateKey.PublicKey.Curve = sm2.Curve()
|
||||
sm2PrivateKey.PublicKey.X = new(big.Int).SetBytes(pk[:sm2.ByteSize()])
|
||||
sm2PrivateKey.PublicKey.Y = new(big.Int).SetBytes(pk[sm2.ByteSize():])
|
||||
|
||||
if _, ok := sdf.Sm2Key[uint32(index)]; !ok {
|
||||
sdf.Sm2Key[uint32(index)] = &Sm2Key{}
|
||||
}
|
||||
sdf.Sm2Key[uint32(index)].encKey = sm2PrivateKey
|
||||
}
|
||||
case KeyTypeSm1:
|
||||
fallthrough
|
||||
case KeyTypeSm4:
|
||||
fallthrough
|
||||
case KeyTypeSm9MasterSign:
|
||||
fallthrough
|
||||
case KeyTypeSm9MasterEnc:
|
||||
fallthrough
|
||||
case KeyTypeSm9UserSign:
|
||||
fallthrough
|
||||
case KeyTypeSm9UserEnc:
|
||||
fallthrough
|
||||
case KeyTypeRsa:
|
||||
fallthrough
|
||||
default:
|
||||
return fmt.Errorf("key type errror")
|
||||
}
|
||||
}
|
||||
|
||||
// now copy sdf to s
|
||||
s.Sm2Key = sdf.Sm2Key
|
||||
s.SymKey = sdf.SymKey
|
||||
s.RsaKey = sdf.RsaKey
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"xdx.jelly/xgcl/api/common"
|
||||
)
|
||||
|
||||
func TestKeyType(t *testing.T) {
|
||||
keyTypes := []KeyType{KeyTypeUnknow,
|
||||
KeyTypeBlock,
|
||||
KeyTypeSm1,
|
||||
KeyTypeSm4,
|
||||
KeyTypeSm2Sign,
|
||||
KeyTypeSm2Enc,
|
||||
KeyTypeSm9MasterSign,
|
||||
KeyTypeSm9MasterEnc,
|
||||
KeyTypeSm9UserSign,
|
||||
KeyTypeSm9UserEnc,
|
||||
KeyTypeRsa,
|
||||
}
|
||||
for _, kt := range keyTypes {
|
||||
if GetKeyType(kt.String()) != kt {
|
||||
t.Fatal("error:", kt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshot(t *testing.T) {
|
||||
|
||||
SDF := &SdfNoLock{}
|
||||
for idx := uint32(0); idx < 10; idx++ {
|
||||
refKey := &common.ECCrefPrivateKey{Bits: 256}
|
||||
SDF.SDF_GenerateRandom(refKey.K[32:])
|
||||
|
||||
var err error
|
||||
err = SDF.ImportSm2KeyAtIndex(idx, KeyTypeSm2Sign, refKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = SDF.ImportSm2KeyAtIndex(idx, KeyTypeSm2Enc, refKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
for idx := uint32(0); idx < 10; idx++ {
|
||||
SDF.GenerateKekAtIndex(idx)
|
||||
}
|
||||
password := []byte("12345")
|
||||
snapshot, err := SDF.Snapshot(true, password, 1000)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
snapshotBytes, err := json.MarshalIndent(snapshot, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println(string(snapshotBytes))
|
||||
|
||||
var restor Snapshot
|
||||
json.Unmarshal(snapshotBytes, &restor)
|
||||
err = SDF.Restore(&restor, password)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
snapshot2, err := SDF.Snapshot(false, []byte("12345"), 1000)
|
||||
snapshotBytes2, err := json.MarshalIndent(snapshot2, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(snapshotBytes2))
|
||||
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
package sdf
|
||||
|
||||
import (
|
||||
"xdx.jelly/xgcl/rsa"
|
||||
"xdx.jelly/xgcl/sm/sm2"
|
||||
)
|
||||
|
||||
// assert DefaultSDF is a SDFable interface
|
||||
var _ Sdfable = UnimplementedSDF{}
|
||||
|
||||
type UnimplementedSDF struct{}
|
||||
|
||||
func (UnimplementedSDF) SDF_OpenSession() error {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_CloseSession() error {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_GetDeviceInfo() (*DeviceInfo, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_GetPrivateKeyAccessRight(keyIndex uint32, password []byte) error {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_ReleasePrivateKeyAccessRight(keyIndex uint32) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateRandom(buffer []byte) (n uint32, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExportSignPublicKey_RSA(uiKeyIndex uint32) (*rsa.PublicKey, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExportEncPublicKey_RSA(uiKeyIndex uint32) (*rsa.PublicKey, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyPair_RSA(uiKeyBits uint32) (*rsa.PublicKey, *rsa.PrivateKey, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyWithIPK_RSA(uiIPKIndex uint32, uiKeyBits uint32) (pucKey []byte, phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyWithEPK_RSA(uiKeyBits uint32, pucPublicKey *rsa.PublicKey) (Key []byte, phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ImportKeyWithISK_RSA(uiISKIndex uint32, pucKey []byte) (phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExchangeDigitEnvelopeBaseOnRSA(uiKeyIndex uint32, pucPublicKey *rsa.PublicKey, pucDEInput []byte) (pucDEOutput []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExportSignPublicKey_ECC(uiKeyIndex uint32) (*sm2.PublicKey, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExportEncPublicKey_ECC(uiKeyIndex uint32) (*sm2.PublicKey, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyPair_ECC(uiAlgID uint32, uiKeyBits uint32) (*sm2.PublicKey, *sm2.PrivateKey, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyWithIPK_ECC(uiIPKIndex uint32, uiKeyBits uint32) (pucKey *sm2.Cipher, phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyWithEPK_ECC(uiKeyBits uint32, uiAlgID uint32, pucPublicKey *sm2.PublicKey) (pucKey *sm2.Cipher, phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ImportKeyWithISK_ECC(uiISKIndex uint32, pucKey *sm2.Cipher) (phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateAgreementDataWithECC(uiISKIndex uint32, uiKeyBits uint32, pucSponsorID []byte) (pucSponsorPublicKey *sm2.PublicKey, pucSponsorTmpPublicKey *sm2.PublicKey, phAgreementHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyWithECC(pucResponseID []byte, pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, hAgreementHandle interface{}) (phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateAgreementDataAndKeyWithECC(uiISKIndex uint32, uiKeyBits uint32, pucResponseID []byte, pucSponsorID []byte, pucSponsorPublicKey, pucSponsorTmpPublicKey *sm2.PublicKey) (pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExchangeDigitEnvelopeBaseOnECC(uiKeyIndex uint32, uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucEncDataIn *sm2.Cipher) (pucEncDataOut *sm2.Cipher, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeyWithKEK(uiKeyBits uint32, uiAlgID uint32, uiKEKIndex uint32) (pucKey []byte, phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ImportKeyWithKEK(uiAlgID uint32, uiKEKIndex uint32, pucKey []byte) (phKeyHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeywithIKE(pucSponsorNonce []byte, pucResponseNonce []byte, pucSponsorCookie []byte, pucResponseCookie []byte, uiPrfAlgID uint32, uiKeyBitsD, uiKeyBitsA, uiKeyBitsE uint32) (phKeyHandleD interface{}, phKeyHandleA interface{}, phKeyHandleE interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) 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) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeywithIPSEC(pucProtocolID []byte, pucSpi []byte, pucSponsorNonce []byte, pucResponseNonce []byte, hKeyHandle interface{}, uiPrfAlgID uint32, uiKeyBitsEnc, uiKeyBitsMac uint32) (phKeyHandleEnc interface{}, phKeyHandleMac interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) 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) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_GenerateKeywithSSL(pucKeyPremaster, pucClientRandom, pucServerRandom []byte, uiPrfAlgID uint32, uiKeyBitsClientMac, uiKeyBitsServerMac, uiKeyBitsClientEnc, uiKeyBitsServerEnc uint32) (phKeyHandleClientMac, phKeyHandleServerMac, phKeyHandleClientEnc, phKeyHandleServerEnc interface{}, pucClientIV, pucServerIV []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) 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) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) 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) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) 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) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_DestroyKey(hKeyHandle interface{}) error {
|
||||
panic("implement me")
|
||||
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExternalPublicKeyOperation_RSA(pucPublicKey *rsa.PublicKey, pucDataInput []byte) (pucDataOutput []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_InternalPublicKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_InternalPrivateKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_DecryptPublicKeyOperation_RSA(uiKeyIndex uint32, pucDataInput []byte) (pucDataOutput []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExternalVerify_ECC(uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucDataInput []byte, pucSignature *sm2.Signature) (err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExternalSign_ECC(uiAlgID uint32, pucPrivateKey *sm2.PrivateKey, pucData []byte) (*sm2.Signature, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_InternalSign_ECC(uiISKIndex uint32, pucData []byte) (pucSignature *sm2.Signature, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_InternalVerify_ECC(uiISKIndex uint32, pucData []byte, pucSignature *sm2.Signature) (err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ExternalEncrypt_ECC(uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucData []byte) (pucEncData *sm2.Cipher, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_ExternalDecrypt_ECC(uiAlgID uint32, pucPrivateKey *sm2.PrivateKey, pucEncData *sm2.Cipher) (pucData []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
func (UnimplementedSDF) SDF_Encrypt(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte, pucEncData *[]byte) (err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_Decrypt(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte, pucEncData *[]byte) (err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_CalculateMAC(hKeyHandle interface{}, uiAlgID uint32, pucIV []byte, pucData []byte) (pucMAC []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_HashInit(uiAlgID uint32, pucPublicKey *sm2.PublicKey, pucID []byte) (err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_HashUpdate(pucData []byte) (err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_HashFinal() (pucHash []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_CreateFile(pucFileName string, uiFileSize uint32) error {
|
||||
panic("implement me")
|
||||
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_ReadFile(pucFileName string, uiOffset uint32, pucBuffer []byte) (n uint32, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_WriteFile(pucFileName string, uiOffset uint32, pucBuffer []byte) error {
|
||||
panic("implement me")
|
||||
|
||||
}
|
||||
|
||||
func (UnimplementedSDF) SDF_DeleteFile(pucFileName string) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// 内部sm2私钥解密
|
||||
func (UnimplementedSDF) SDFEXT_InternalDecryptECC(uiKeyIndex uint32, pucEncData *sm2.Cipher) (pucData []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// 6.3.14 生成密钥协商参数并输出-这个与标准接口一致
|
||||
// 描述: 使用ECC密钥协商算法, 为计算会话密钥而产生协商参数, 同时返回指定索引位置的ECC公钥、临时ECC密钥对的公钥及协商句柄。
|
||||
func (UnimplementedSDF) SDFEXT_GenerateAgreementDataWithECC(uiISKIndex uint32, uiKeyBits uint32, pucSponsorID []byte) (pucSponsorPublicKey *sm2.PublicKey, pucSponsorTmpPublicKey *sm2.PublicKey, phAgreementHandle interface{}, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// 6.3.15 计算会话密钥变体
|
||||
// 描述: 使用ECC密钥协商算法, 使用自身协商句柄和响应方的协商参数计算会话密钥, 同时返回会话密钥。
|
||||
// 备注: 协商的发起方获得响应方的协商参数后调用本函数, 计算会话密钥。使用SM2算法计算会话密钥的过程见GM/T 0009。
|
||||
func (UnimplementedSDF) SDFEXT_GenerateKeyWithECC(pucResponseID []byte, pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, hAgreementHandle interface{}) (agreementKey []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// 6.3.16 产生协商数据并计算会话密钥
|
||||
// 描述: 使用ECC密钥协商算法, 产生协商参数并计算会话密钥, 同时返回产生的协商参数和密钥。
|
||||
func (UnimplementedSDF) SDFEXT_GenerateAgreementDataAndKeyWithECC(uiISKIndex uint32, uiKeyBits uint32, pucResponseID []byte, pucSponsorID []byte, pucSponsorPublicKey, pucSponsorTmpPublicKey *sm2.PublicKey) (pucResponsePublicKey *sm2.PublicKey, pucResponseTmpPublicKey *sm2.PublicKey, agreementKey []byte, err error) {
|
||||
panic("implement me")
|
||||
}
|
||||
Reference in New Issue
Block a user