scp02

package module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2021 License: MIT Imports: 8 Imported by: 0

README

scp02

Golang implementation of GlobalPlatform SCP02

Documentation

Index

Constants

View Source
const (
	// KeyIDEnc is the ID of the Secure Channel encryption key (ENC).
	KeyIDEnc byte = 0x01
	// KeyIDMac is the ID of the Secure Channel message authentication code key (MAC).
	KeyIDMac byte = 0x02
	// KeyIDDek is the ID of the Data encryption key (DEK).
	KeyIDDek byte = 0x03
)
View Source
const (
	BeginRMACSessionP1RMAC              byte = 0x10
	BeginRMACSessionP1NoSecureMessaging byte = 0x00
	EndRMACSessionP2EndAndReturnRMAC    byte = 0x03
	EndRMACSessionP2ReturnRMAC          byte = 0x01
)

Variables

This section is empty.

Functions

func Pad80

func Pad80(b []byte, blockSize int, force bool) ([]byte, error)

Pad80 takes bytes and a block size (must be a multiple of 8) and appends '80' and zero bytes until the length reaches a multiple of the block size and returns the padded bytes. If force is false, the padding will only be applied, if the length of bytes is not a multiple of the block size. If force is true, the padding will be applied anyways.

Types

type CardCryptogramError

type CardCryptogramError struct {
	Expected []byte // Expected card cryptogram.
	Received []byte // Received card cryptogram.
}

CardCryptogramError results from a mismatch between the card cryptogram calculated on host and the card cryptogram received from the card.

func (CardCryptogramError) Error

func (e CardCryptogramError) Error() string

type ExplicitInitiationConfiguration

type ExplicitInitiationConfiguration struct {
	SecurityLevel    ExplicitInitiationSecurityLevel
	Options          Options
	ChannelID        uint8
	KeyVersionNumber uint8
	HostChallenge    [8]byte
}

ExplicitInitiationConfiguration is the configuration for the explicit initiation of a Secure Channel Session.

type ExplicitInitiationSecurityLevel

type ExplicitInitiationSecurityLevel int

ExplicitInitiationSecurityLevel represents the security level options applicable for explicit initiation.

const (
	CMAC               ExplicitInitiationSecurityLevel = iota // Apply only CMAC on commands.
	CMACAndRMAC        ExplicitInitiationSecurityLevel = iota // Apply CMAC on commands and RMAC on responses.
	CMACAndCDEC        ExplicitInitiationSecurityLevel = iota // Apply CMAC and CDEC on commands.
	CMACAndCDECAndRMAC ExplicitInitiationSecurityLevel = iota // Apply CMAC and CDEC on commands and RMAC on responses.
)

type ImplicitInitiationConfiguration

type ImplicitInitiationConfiguration struct {
	SecurityLevel       ImplicitInitiationSecurityLevel // security level that shall be used for the session.
	Options             Options                         // i-parameter options.
	KeyVersionNumber    uint8                           // key version number of the key(s) to use.
	SequenceCounter     uint16                          // current value of the sequence counter.
	Capdu               apdu.Capdu                      // command APDU on which the initial C-MAC shall be calculated.
	SelectedAid         []byte                          // AID of the currently selected application.
	DiversificationData []byte                          // key diversification data.
}

ImplicitInitiationConfiguration is the configuration for the implicit initiation of a Secure Channel Session.

type ImplicitInitiationSecurityLevel

type ImplicitInitiationSecurityLevel int

ImplicitInitiationSecurityLevel represents the security level options applicable for explicit initiation.

const (
	ImplicitCMAC        ImplicitInitiationSecurityLevel = iota // Apply only CMAC on commands.
	ImplicitCMACAndRMAC ImplicitInitiationSecurityLevel = iota // Apply CMAC on commands and RMAC on responses.
)

type KeyDerivationError

type KeyDerivationError struct {
	Message string
	Cause   error
}

KeyDerivationError results from an error during the derivation of session keys.

func (KeyDerivationError) Error

func (e KeyDerivationError) Error() string

type NonSuccessResponseError

type NonSuccessResponseError struct {
	Command  apdu.Capdu // CAPDU that was transmitted.
	Response apdu.Rapdu // RAPDU that has been received.
}

NonSuccessResponseError results from receiving a Response APDU with a non-success status word.

func (NonSuccessResponseError) Error

func (e NonSuccessResponseError) Error() string

type Options

type Options struct {
	CMACOnUnmodifiedAPDU bool // true: C-MAC on unmodified APDU, false: C-MAC on modified APDU
	ICVEncryptionForCMAC bool // true: ICV encryption for C-MAC session, false: No ICV encryption
}

Options represents implementation options of SCP02 that are encoded on the i-parameter. Other options such as R-MAC support, the initiation mode or number of base keys are not configured via Options but implicitly used e.g. by calling InitiateChannelImplicit or InitiateChannelExplicit.

type RMACError

type RMACError struct {
	Expected []byte // Expected R-MAC.
	Received []byte // Received R-MAC.
}

RMACError results from a mismatch between the R-MAC calculated on host and the R-MAC received from the card.

func (RMACError) Error

func (e RMACError) Error() string

type RMACSession

type RMACSession struct {
	// contains filtered or unexported fields
}

RMACSession is a SCP02 R-MAC session.

func BeginRMACSession

func BeginRMACSession(config RMACSessionConfiguration, transmitter Transmitter, keyProvider SessionKeyProvider) (*RMACSession, error)

BeginRMACSession begins an R-MAC session and returns RMACSession. This function calls Transmitter.Transmit to transmit the BEGIN R-MAC SESSION CAPDU and receive the RAPDU.

func (*RMACSession) End

func (rmacSession *RMACSession) End(transmitter Transmitter, endSession bool) (apdu.Rapdu, error)

End ends an R-MAC session and/or retrieves the current R-MAC value depending on the value of endSession. This function calls Transmitter.Transmit to transmit the END R-MAC SESSION CAPDU and receive the RAPDU.

func (*RMACSession) UpdateLastCommand

func (rmacSession *RMACSession) UpdateLastCommand(capdu apdu.Capdu)

UpdateLastCommand updates the last command that was sent during the R-MAC session which is required for the calculation and verification of the R-MAC.

type RMACSessionConfiguration

type RMACSessionConfiguration struct {
	ChannelID        uint8
	P1               byte
	Data             []byte
	KeyVersionNumber uint8
	SequenceCounter  uint16
	// contains filtered or unexported fields
}

RMACSessionConfiguration is the configuration for the initiation of an RMACSession.

type SecurityLevel

type SecurityLevel struct {
	CDEC bool // command decryption
	CMAC bool // command message authentication code
	RMAC bool // response message authentication code
}

SecurityLevel represents the security level options applicable for SCP02.

func (SecurityLevel) Byte

func (level SecurityLevel) Byte() byte

Byte encodes SecurityLevel on a byte.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is a SCP02 secure channel session.

func InitiateChannelExplicit

func InitiateChannelExplicit(config ExplicitInitiationConfiguration, transmitter Transmitter, keyProvider SessionKeyProvider) (*Session, error)

InitiateChannelExplicit uses implicit initiation to create a Secure Channel and returns a Session. This function calls Transmitter.Transmit to transmit the INITIALIZE UPDATE and EXTERNAL AUTHENTICATE CAPDUs and receive the RAPDUs.

func InitiateChannelImplicit

func InitiateChannelImplicit(config ImplicitInitiationConfiguration, transmitter Transmitter, keyProvider SessionKeyProvider) (*Session, error)

InitiateChannelImplicit uses implicit initiation to create a Secure Channel and returns a Session. Note that security level C-DEC is not supported for implicit initiation.

The Sequence Counter must be provided to derive the correct session keys. It is either implicitly known or can be retrieved with a GET DATA command. The AID of the application that is currently selected on the given channel is used for calculating the ICV for the first C-MAC (ICV MAC over AID).

The first C-MAC is calculated on and appended to the given APDU which is then passed to Transmitter.Transmit.

func (*Session) BeginRMACSession

func (session *Session) BeginRMACSession(transmitter Transmitter, data []byte) error

BeginRMACSession starts a R-MAC session. Data is used to specify the Data field of the BEGIN R-MAC SESSION command. This function calls SessionKeyProvider.ProvideSessionKey on the sessionKeyProvider for the MAC key, that was provided when creating Session, in order to derive the R-MAC key and calls Transmitter.Transmit to transmit the BEGIN R-MAC SESSION CAPDU and receive the RAPDU.

func (*Session) ChannelID

func (session *Session) ChannelID() uint8

ChannelID returns the ID of the channel the Session is active on.

func (*Session) EncryptWithSDEK

func (session *Session) EncryptWithSDEK(dst []byte, src []byte) error

EncryptWithSDEK uses Triple DES in ECB mode for encrypting the given Data with the session DEK. The length of src and dst must be a multiple of 8. If padding is required, it must be applied before calling the function.

func (*Session) EndRMACSession

func (session *Session) EndRMACSession(transmitter Transmitter, endSession bool) (apdu.Rapdu, error)

EndRMACSession ends an R-MAC session and/or retrieves the current R-MAC value depending on the value of endSession. This function calls Transmitter.Transmit to transmit the END R-MAC SESSION CAPDU and receive the RAPDU.

func (*Session) MaximumCommandPayloadLength

func (session *Session) MaximumCommandPayloadLength() int

MaximumCommandPayloadLength returns the maximum length of payload for the Data field of CAPDUs that are transmitted during the session. The length depends on the Session's SecurityLevel.

func (*Session) SecurityLevel

func (session *Session) SecurityLevel() SecurityLevel

SecurityLevel returns the Security Level of the Session.

func (*Session) SequenceCounter

func (session *Session) SequenceCounter() uint16

SequenceCounter returns the session's value of the Sequence Counter.

func (*Session) Unwrap

func (session *Session) Unwrap(rapdu apdu.Rapdu) (apdu.Rapdu, error)

Unwrap takes an apdu.Rapdu and verifies the R-MAC if an R-MAC session was started with Session and returns the unwrapped apdu.Rapdu.

func (*Session) Wrap

func (session *Session) Wrap(capdu apdu.Capdu) (apdu.Capdu, error)

Wrap takes an apdu.Capdu and applies C-MAC and encryption according to the Session's SecurityLevel and returns the wrapped apdu.Capdu.

type SessionKeyProvider

type SessionKeyProvider interface {
	// ProvideSessionKey uses the static key with the given key ID and key version number with
	// Triple DES encryption in CBC mode for the derivation of a session key.
	// diversificationData may be present to provide data for the derivation of card static keys.
	// src contains the derivation input Data (2B derivation constant | 2B sequence counter | 12B zero padding)
	// and dst is used for storing the encryption result.
	ProvideSessionKey(keyID byte, kvn byte, diversificationData []byte, dst *[16]byte, src [16]byte) error
}

SessionKeyProvider is the interface that provides access to the cryptographic operation for session key derivation.

type TransmitError

type TransmitError struct {
	Command apdu.Capdu // CAPDU that should have been transmitted.
	Cause   error
}

TransmitError results from an error during the transmission of a Command APDU.

func (TransmitError) Error

func (e TransmitError) Error() string

type Transmitter

type Transmitter interface {
	Transmit(capdu apdu.Capdu) (apdu.Rapdu, error)
}

Transmitter is the interface that transmits apdu.Capdu and returns apdu.Rapdu.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL