2018-09-19 13:31:06 +00:00
|
|
|
package globalplatform
|
|
|
|
|
2018-10-01 11:25:24 +00:00
|
|
|
import (
|
|
|
|
"github.com/status-im/status-go/smartcard/apdu"
|
|
|
|
"github.com/status-im/status-go/smartcard/globalplatform/crypto"
|
|
|
|
)
|
2018-09-19 13:31:06 +00:00
|
|
|
|
2018-09-25 15:43:26 +00:00
|
|
|
const (
|
2018-10-02 11:24:13 +00:00
|
|
|
ClaISO7816 = uint8(0x00)
|
|
|
|
ClaGp = uint8(0x80)
|
|
|
|
ClaMac = uint8(0x84)
|
2018-09-19 13:31:06 +00:00
|
|
|
|
2018-10-01 11:25:24 +00:00
|
|
|
InsSelect = uint8(0xA4)
|
|
|
|
InsInitializeUpdate = uint8(0x50)
|
|
|
|
InsExternalAuthenticate = uint8(0x82)
|
2018-10-02 11:24:13 +00:00
|
|
|
InsGetResponse = uint8(0xC0)
|
2018-10-02 11:44:14 +00:00
|
|
|
InsDelete = uint8(0xE4)
|
2018-10-02 15:15:17 +00:00
|
|
|
InsInstall = uint8(0xE6)
|
|
|
|
|
|
|
|
P1InstallForLoad = uint8(0x02)
|
2018-10-02 11:24:13 +00:00
|
|
|
|
|
|
|
Sw1ResponseDataIncomplete = uint8(0x61)
|
2018-10-02 12:24:30 +00:00
|
|
|
|
2018-10-02 14:52:50 +00:00
|
|
|
SwOK = uint16(0x9000)
|
|
|
|
SwReferencedDataNotFound = uint16(0x6A88)
|
|
|
|
SwSecurityConditionNotSatisfied = uint16(0x6982)
|
|
|
|
SwAuthenticationMethodBlocked = uint16(0x6983)
|
|
|
|
|
2018-10-02 12:24:30 +00:00
|
|
|
tagDeleteAID = byte(0x4F)
|
2018-09-25 15:43:26 +00:00
|
|
|
)
|
2018-09-19 13:31:06 +00:00
|
|
|
|
|
|
|
func NewCommandSelect(aid []byte) *apdu.Command {
|
2018-10-02 11:24:13 +00:00
|
|
|
c := apdu.NewCommand(
|
|
|
|
ClaISO7816,
|
2018-09-19 13:31:06 +00:00
|
|
|
InsSelect,
|
|
|
|
uint8(0x04),
|
|
|
|
uint8(0x00),
|
|
|
|
aid,
|
|
|
|
)
|
2018-10-02 11:24:13 +00:00
|
|
|
|
|
|
|
c.SetLe(0x00)
|
|
|
|
|
|
|
|
return c
|
2018-09-19 13:31:06 +00:00
|
|
|
}
|
2018-09-25 15:43:26 +00:00
|
|
|
|
|
|
|
func NewCommandInitializeUpdate(challenge []byte) *apdu.Command {
|
|
|
|
return apdu.NewCommand(
|
|
|
|
ClaGp,
|
|
|
|
InsInitializeUpdate,
|
|
|
|
uint8(0x00),
|
|
|
|
uint8(0x00),
|
|
|
|
challenge,
|
|
|
|
)
|
|
|
|
}
|
2018-10-01 11:25:24 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-10-02 11:24:13 +00:00
|
|
|
func NewCommandGetResponse(length uint8) *apdu.Command {
|
|
|
|
c := apdu.NewCommand(
|
|
|
|
ClaISO7816,
|
|
|
|
InsGetResponse,
|
|
|
|
uint8(0),
|
|
|
|
uint8(0),
|
|
|
|
nil,
|
|
|
|
)
|
|
|
|
|
|
|
|
c.SetLe(length)
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2018-10-02 11:44:14 +00:00
|
|
|
func NewCommandDelete(aid []byte) *apdu.Command {
|
2018-10-02 12:24:30 +00:00
|
|
|
data := []byte{tagDeleteAID, byte(len(aid))}
|
|
|
|
data = append(data, aid...)
|
|
|
|
|
2018-10-02 11:44:14 +00:00
|
|
|
return apdu.NewCommand(
|
|
|
|
ClaGp,
|
|
|
|
InsDelete,
|
|
|
|
uint8(0x00),
|
|
|
|
uint8(0x00),
|
2018-10-02 12:24:30 +00:00
|
|
|
data,
|
2018-10-02 11:44:14 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-10-02 15:15:17 +00:00
|
|
|
func NewCommandInstallForLoad(aid, sdaid []byte) *apdu.Command {
|
|
|
|
data := []byte{byte(len(aid))}
|
|
|
|
data = append(data, aid...)
|
|
|
|
data = append(data, byte(len(sdaid)))
|
|
|
|
data = append(data, sdaid...)
|
|
|
|
// empty hash length and hash
|
|
|
|
data = append(data, []byte{0x00, 0x00, 0x00}...)
|
|
|
|
|
|
|
|
return apdu.NewCommand(
|
|
|
|
ClaGp,
|
|
|
|
InsInstall,
|
|
|
|
P1InstallForLoad,
|
|
|
|
uint8(0x00),
|
|
|
|
data,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-10-01 11:25:24 +00:00
|
|
|
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)
|
|
|
|
}
|