add external auth command

This commit is contained in:
Andrea Franz 2018-10-01 13:25:24 +02:00
parent 0ef7630270
commit 8721418cd7
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
3 changed files with 67 additions and 12 deletions

View File

@ -1,13 +1,18 @@
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 (
Cla = uint8(0x00)
ClaGp = uint8(0x80)
Cla = uint8(0x00)
ClaGp = uint8(0x80)
ClaMac = uint8(0x84)
InsSelect = uint8(0xA4)
InsInitializeUpdate = uint8(0x50)
InsSelect = uint8(0xA4)
InsInitializeUpdate = uint8(0x50)
InsExternalAuthenticate = uint8(0x82)
)
func NewCommandSelect(aid []byte) *apdu.Command {
@ -29,3 +34,27 @@ func NewCommandInitializeUpdate(challenge []byte) *apdu.Command {
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)
}

View File

@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestCommandSelect(t *testing.T) {
func TestNewCommandSelect(t *testing.T) {
aid := []byte{}
cmd := NewCommandSelect(aid)
@ -17,7 +17,7 @@ func TestCommandSelect(t *testing.T) {
assert.Equal(t, uint8(0x00), cmd.P2)
}
func TestCommandInitializeUpdate(t *testing.T) {
func TestNewCommandInitializeUpdate(t *testing.T) {
challenge := hexutils.HexToBytes("010203")
cmd := NewCommandInitializeUpdate(challenge)
@ -27,3 +27,29 @@ func TestCommandInitializeUpdate(t *testing.T) {
assert.Equal(t, uint8(0x00), cmd.P2)
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))
}

View File

@ -36,8 +36,8 @@ func VerifyCryptogram(encKey, hostChallenge, cardChallenge, cardCryptogram []byt
data := make([]byte, 0)
data = append(data, hostChallenge...)
data = append(data, cardChallenge...)
paddedData := appendDESPadding(data)
calculated, err := mac3des(encKey, paddedData, NullBytes8)
paddedData := AppendDESPadding(data)
calculated, err := Mac3DES(encKey, paddedData, NullBytes8)
if err != nil {
return false, err
}
@ -46,7 +46,7 @@ func VerifyCryptogram(encKey, hostChallenge, cardChallenge, cardCryptogram []byt
}
func MacFull3DES(key, data, iv []byte) ([]byte, error) {
data = appendDESPadding(data)
data = AppendDESPadding(data)
desBlock, err := des.NewCipher(resizeKey8(key))
if err != nil {
@ -89,7 +89,7 @@ func EncryptICV(macKey, mac []byte) ([]byte, error) {
return ciphertext, nil
}
func mac3des(key, data, iv []byte) ([]byte, error) {
func Mac3DES(key, data, iv []byte) ([]byte, error) {
key24 := resizeKey24(key)
block, err := des.NewTripleDESCipher(key24)
@ -117,7 +117,7 @@ func resizeKey8(key []byte) []byte {
return key[:8]
}
func appendDESPadding(data []byte) []byte {
func AppendDESPadding(data []byte) []byte {
length := len(data) + 1
for ; length%8 != 0; length++ {
}