mirror of
https://github.com/status-im/keycard-go.git
synced 2025-01-19 08:21:43 +00:00
add external auth command
This commit is contained in:
parent
0ef7630270
commit
8721418cd7
@ -1,13 +1,18 @@
|
|||||||
package globalplatform
|
package globalplatform
|
||||||
|
|
||||||
import "github.com/status-im/status-go/smartcard/apdu"
|
import (
|
||||||
|
"github.com/status-im/status-go/smartcard/apdu"
|
||||||
|
"github.com/status-im/status-go/smartcard/globalplatform/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Cla = uint8(0x00)
|
Cla = uint8(0x00)
|
||||||
ClaGp = uint8(0x80)
|
ClaGp = uint8(0x80)
|
||||||
|
ClaMac = uint8(0x84)
|
||||||
|
|
||||||
InsSelect = uint8(0xA4)
|
InsSelect = uint8(0xA4)
|
||||||
InsInitializeUpdate = uint8(0x50)
|
InsInitializeUpdate = uint8(0x50)
|
||||||
|
InsExternalAuthenticate = uint8(0x82)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCommandSelect(aid []byte) *apdu.Command {
|
func NewCommandSelect(aid []byte) *apdu.Command {
|
||||||
@ -29,3 +34,27 @@ func NewCommandInitializeUpdate(challenge []byte) *apdu.Command {
|
|||||||
challenge,
|
challenge,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewCommandExternalAuthenticate(encKey, cardChallenge, hostChallenge []byte) (*apdu.Command, error) {
|
||||||
|
hostCryptogram, err := calculateHostCryptogram(encKey, cardChallenge, hostChallenge)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu.NewCommand(
|
||||||
|
ClaMac,
|
||||||
|
InsExternalAuthenticate,
|
||||||
|
uint8(0x01), // C-MAC
|
||||||
|
uint8(0x00),
|
||||||
|
hostCryptogram,
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calculateHostCryptogram(encKey, cardChallenge, hostChallenge []byte) ([]byte, error) {
|
||||||
|
var data []byte
|
||||||
|
data = append(data, cardChallenge...)
|
||||||
|
data = append(data, hostChallenge...)
|
||||||
|
data = crypto.AppendDESPadding(data)
|
||||||
|
|
||||||
|
return crypto.Mac3DES(encKey, data, crypto.NullBytes8)
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommandSelect(t *testing.T) {
|
func TestNewCommandSelect(t *testing.T) {
|
||||||
aid := []byte{}
|
aid := []byte{}
|
||||||
cmd := NewCommandSelect(aid)
|
cmd := NewCommandSelect(aid)
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ func TestCommandSelect(t *testing.T) {
|
|||||||
assert.Equal(t, uint8(0x00), cmd.P2)
|
assert.Equal(t, uint8(0x00), cmd.P2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCommandInitializeUpdate(t *testing.T) {
|
func TestNewCommandInitializeUpdate(t *testing.T) {
|
||||||
challenge := hexutils.HexToBytes("010203")
|
challenge := hexutils.HexToBytes("010203")
|
||||||
cmd := NewCommandInitializeUpdate(challenge)
|
cmd := NewCommandInitializeUpdate(challenge)
|
||||||
|
|
||||||
@ -27,3 +27,29 @@ func TestCommandInitializeUpdate(t *testing.T) {
|
|||||||
assert.Equal(t, uint8(0x00), cmd.P2)
|
assert.Equal(t, uint8(0x00), cmd.P2)
|
||||||
assert.Equal(t, challenge, cmd.Data)
|
assert.Equal(t, challenge, cmd.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCalculateHostCryptogram(t *testing.T) {
|
||||||
|
encKey := hexutils.HexToBytes("0EF72A1065236DD6CAC718D5E3F379A4")
|
||||||
|
cardChallenge := hexutils.HexToBytes("0076a6c0d55e9535")
|
||||||
|
hostChallenge := hexutils.HexToBytes("266195e638da1b95")
|
||||||
|
|
||||||
|
result, err := calculateHostCryptogram(encKey, cardChallenge, hostChallenge)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected := "45A5F48DAE68203C"
|
||||||
|
assert.Equal(t, expected, hexutils.BytesToHex(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewCommandExternalAuthenticate(t *testing.T) {
|
||||||
|
encKey := hexutils.HexToBytes("8D289AFE0AB9C45B1C76DEEA182966F4")
|
||||||
|
cardChallenge := hexutils.HexToBytes("000f3fd65d4d6e45")
|
||||||
|
hostChallenge := hexutils.HexToBytes("cf307b6719bf224d")
|
||||||
|
|
||||||
|
cmd, err := NewCommandExternalAuthenticate(encKey, cardChallenge, hostChallenge)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected := "84 82 01 00 08 77 02 AC 6C E4 6A 47 F0"
|
||||||
|
raw, err := cmd.Serialize()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expected, hexutils.BytesToHexWithSpaces(raw))
|
||||||
|
}
|
||||||
|
@ -36,8 +36,8 @@ func VerifyCryptogram(encKey, hostChallenge, cardChallenge, cardCryptogram []byt
|
|||||||
data := make([]byte, 0)
|
data := make([]byte, 0)
|
||||||
data = append(data, hostChallenge...)
|
data = append(data, hostChallenge...)
|
||||||
data = append(data, cardChallenge...)
|
data = append(data, cardChallenge...)
|
||||||
paddedData := appendDESPadding(data)
|
paddedData := AppendDESPadding(data)
|
||||||
calculated, err := mac3des(encKey, paddedData, NullBytes8)
|
calculated, err := Mac3DES(encKey, paddedData, NullBytes8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ func VerifyCryptogram(encKey, hostChallenge, cardChallenge, cardCryptogram []byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MacFull3DES(key, data, iv []byte) ([]byte, error) {
|
func MacFull3DES(key, data, iv []byte) ([]byte, error) {
|
||||||
data = appendDESPadding(data)
|
data = AppendDESPadding(data)
|
||||||
|
|
||||||
desBlock, err := des.NewCipher(resizeKey8(key))
|
desBlock, err := des.NewCipher(resizeKey8(key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -89,7 +89,7 @@ func EncryptICV(macKey, mac []byte) ([]byte, error) {
|
|||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mac3des(key, data, iv []byte) ([]byte, error) {
|
func Mac3DES(key, data, iv []byte) ([]byte, error) {
|
||||||
key24 := resizeKey24(key)
|
key24 := resizeKey24(key)
|
||||||
|
|
||||||
block, err := des.NewTripleDESCipher(key24)
|
block, err := des.NewTripleDESCipher(key24)
|
||||||
@ -117,7 +117,7 @@ func resizeKey8(key []byte) []byte {
|
|||||||
return key[:8]
|
return key[:8]
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendDESPadding(data []byte) []byte {
|
func AppendDESPadding(data []byte) []byte {
|
||||||
length := len(data) + 1
|
length := len(data) + 1
|
||||||
for ; length%8 != 0; length++ {
|
for ; length%8 != 0; length++ {
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user