scp03

package module
v0.1.0-alpha 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

scp03

Golang implementation of GlobalPlatform SCP03

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
)

Variables

This section is empty.

Functions

func KDF

func KDF(dst []byte, aesCipher cipher.Block, label []byte, context []byte) error

KDF implements a version of KDF in counter mode as specified in NIST SP 800-108. The PRF used in the KDF shall is CMAC as specified in NIST 800-38B] with 16-byte output length. The KDF takes an AES cipher, a label, a derivation context and the required number of output bits.

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 CommandSecurityLevel

type CommandSecurityLevel int

CommandSecurityLevel represents the security level options applicable for commands.

const (
	CMAC        CommandSecurityLevel = iota // Apply only CMAC on commands.
	CMACAndCDEC CommandSecurityLevel = iota // Apply CMAC and CDEC on commands.
)

type ConfigureResponseSecurityLevel

type ConfigureResponseSecurityLevel func(rmacSupport bool, rencSupport bool) ResponseSecurityLevel

ConfigureResponseSecurityLevel is a function that takes the indication of R-MAC and R-ENC support and returns a ResponseSecurityLevel. It is used to set the response Security Level depending on the options indicated by the response to INITIALIZE UPDATE.

type InitiationConfiguration

type InitiationConfiguration struct {
	CommandSecurityLevel CommandSecurityLevel // Security Level applied for Command APDUs.
	ChannelID            uint8                // ID of the base/logical channel the SCP session shall be initiated on. Should be in range of 0-19.
	KeyVersionNumber     uint8                // Key Version Number within the Security Domain to be used to initiate the Secure Channel Session. If this value is zero, the first available key chosen by the Security Domain will be used.
	HostChallenge        [8]byte              // Host Challenge used in the INITIALIZE UPDATE command and as part of 'context' for session key derivation.
}

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

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 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 ResponseSecurityLevel

type ResponseSecurityLevel int

ResponseSecurityLevel represents the security level options applicable for responses.

const (
	None        ResponseSecurityLevel = iota // Apply nothing on responses.
	RMAC        ResponseSecurityLevel = iota // Apply only RMAC on responses.
	RMACAndRENC ResponseSecurityLevel = iota // Apply RMAC and RENC on responses.
)

type SecurityLevel

type SecurityLevel struct {
	CDEC bool // command decryption
	CMAC bool // command Message authentication code
	RMAC bool // response Message authentication code
	RENC bool // response encryption
}

SecurityLevel represents the security level options for SCP03.

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 SCP03 secure channel session.

func InitiateChannel

func InitiateChannel(config InitiationConfiguration, transmitter Transmitter, keyProvider SessionKeyProvider, configureResponseSecurityLevel ConfigureResponseSecurityLevel) (*Session, error)

InitiateChannel uses explicit initiation to create a Secure Channel to the currently selected application (or associated Security Domain) and returns a Session.

Transmitter.Transmit is called to transmit the INITIALIZE UPDATE and EXTERNAL AUTHENTICATE CAPDUs and receive the RAPDUs.

SessionKeyProvider.KeyByteSize is called to determine the size of session keys. SessionKeyProvider.ProvideSessionKey is called two to three times (depending on the configured Security Level) to derive session keys from the static keys ENC and MAC.

ConfigureResponseSecurityLevel is called to configure the response Security Level after receiving the INITIALIZE UPDATE response.

func (*Session) BeginRMACSession

func (session *Session) BeginRMACSession(responseSecurityLevel ResponseSecurityLevel, 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.Encrypt on the encrypter 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) EndRMACSession

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

EndRMACSession terminates a Secure Channel Session for APDU response Message integrity or to retrieve the current R-MAC without ending the R-MAC SCP02Session. The END R-MAC SESSION command may be issued to the card at any time during an R-MAC session.

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

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

Unwrap applies operations (R-MAC, response decryption) depending on the SecurityLevel of the session to a apdu.Rapdu and returns the resulting apdu.Rapdu.

func (*Session) Wrap

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

Wrap applies operations (C-MAC, command encryption) depending on the SecurityLevel of the session to a apdu.Capdu and returns the resulting apdu.Capdu.

type SessionKeyProvider

type SessionKeyProvider interface {
	// ProvideSessionKey provides an AES session key by using the static AES key
	// with the given Key ID and Key Version Number and by using it with the data derivation
	// function specified in NIST SP 800-108.
	//
	// The result of the application of the KDF (which is the derived session key) is provided in dst.
	//
	// The PRF used in the KDF shall be CMAC as specified in NIST 800-38B, used with full 16-byte output length.
	// The “fixed input data” plus iteration counter for the KDF is the concatenation of the following items in the given sequence:
	// 		A 12-byte “label” consisting of 11 bytes with value '00' followed by a 1-byte derivation constant as defined below.
	//		A 1-byte “separation indicator” with value '00'.
	//		A 2-byte integer “L” specifying the length in bits of the derived data (value '0040', '0080', '00C0', or '0100').
	//		A 1-byte counter “i” as specified in the KDF (which may take the values '01' or '02'; value '02' is used when “L” takes the values '00C0' and '0100', i.e. when the PRF of the KDF is to be called twice to generate enough derived data).
	//		The “context” parameter of the KDF.
	//
	// Key ID and Key Version Number uniquely identify the key of a Security Domain that shall be used for the
	// Secure Channel Session.
	//
	// Key Diversification Data returned in the response to the INITIALIZE UPDATE command may be used for the derivation of static keys.
	ProvideSessionKey(dst []byte, label []byte, context []byte, keyID byte, kvn byte, diversificationData []byte) error

	// KeyByteSize returns the size of a key in the key set with the given Key Version Number in bytes.
	KeyByteSize(kvn byte) (int, error)
}

SessionKeyProvider is the interface that provides 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