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 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)
}

View File

@ -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))
}

View File

@ -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++ {
} }