kex

package
v0.0.0-...-5b993c5 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2024 License: Apache-2.0 Imports: 20 Imported by: 1

Documentation

Overview

Package kex implements the Key Exchange subprotocol of FDO.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Available

func Available(suite Suite, cipher CipherSuiteID) bool

Available returns whether the given key exchange and cipher suites are both available.

func RegisterCipherSuite

func RegisterCipherSuite(id CipherSuiteID, suite CipherSuite)

RegisterCipherSuite sets a new cipher suite constructor for a given ID. This function is meant to be called in the init function of a package implementing a cipher suite.

func RegisterKeyExchangeSuite

func RegisterKeyExchangeSuite(name string, f func([]byte, CipherSuiteID) Session)

RegisterKeyExchangeSuite sets a constructor for a Session using a given key exchange suite.

Types

type CipherSuite

type CipherSuite struct {
	EncryptAlg cose.EncryptAlgorithm
	MacAlg     cose.MacAlgorithm

	// Hash used for generating encryption and verification keys during key
	// exchange
	PRFHash crypto.Hash
}

CipherSuite combines a COSE encryption algorithm with a COSE MAC algorithm. MacAlg must only be non-zero when EncryptAlg is a non-AE cipher.

func (CipherSuite) String

func (c CipherSuite) String() string

type CipherSuiteID

type CipherSuiteID int64

CipherSuiteID enumeration

const (
	// Authenticated encryption ciphers
	A128GcmCipher          CipherSuiteID = 1
	A192GcmCipher          CipherSuiteID = 2
	A256GcmCipher          CipherSuiteID = 3
	AesCcm16_128_128Cipher CipherSuiteID = 30 // deprecated, not implemented
	AesCcm16_128_256Cipher CipherSuiteID = 31 // deprecated, not implemented
	AesCcm64_128_128Cipher CipherSuiteID = 32
	AesCcm64_128_256Cipher CipherSuiteID = 33

	// Encrypt-then-MAC ciphers
	CoseAes128CbcCipher CipherSuiteID = -17760703
	CoseAes128CtrCipher CipherSuiteID = -17760704
	CoseAes256CbcCipher CipherSuiteID = -17760705
	CoseAes256CtrCipher CipherSuiteID = -17760706
)

Cipher suite IDs

func CipherSuiteByName

func CipherSuiteByName(name string) (CipherSuiteID, bool)

CipherSuiteByName parses a name and returns its identifier.

func (CipherSuiteID) String

func (id CipherSuiteID) String() string

func (CipherSuiteID) Suite

func (id CipherSuiteID) Suite() CipherSuite

Suite returns the cipher suite registered to the given ID.

type DHSession

type DHSession struct {

	// Session encrypt/decrypt data
	SessionCrypter
	// contains filtered or unexported fields
}

DHSession implements a Session using Diffie-Hellman key exchange. Sessions are created using Suite.New.

func (*DHSession) MarshalBinary

func (s *DHSession) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler

func (*DHSession) MarshalCBOR

func (s *DHSession) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler.

func (*DHSession) Parameter

func (s *DHSession) Parameter(rand io.Reader, _ *rsa.PublicKey) ([]byte, error)

Parameter generates the exchange parameter to send to its peer. This function will generate a new parameter every time it is called. This method is used by both the client and server.

func (*DHSession) SetParameter

func (s *DHSession) SetParameter(xB []byte, _ *rsa.PrivateKey) error

SetParameter sets the received parameter from the client. This method is only called by a server.

func (DHSession) String

func (s DHSession) String() string

func (*DHSession) UnmarshalBinary

func (s *DHSession) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler

func (*DHSession) UnmarshalCBOR

func (s *DHSession) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler.

type DecryptOnly

type DecryptOnly struct {
	Session
}

DecryptOnly is a session that only performs decryption and key exchange functions.

func (DecryptOnly) Encrypt

func (s DecryptOnly) Encrypt(_ io.Reader, payload any) (any, error)

Encrypt uses a session key to encrypt a payload. Depending on the suite, the result may be a plain COSE_Encrypt0 or one wrapped by COSE_Mac0.

type ECDHSession

type ECDHSession struct {

	// Session encrypt/decrypt data
	SessionCrypter
	// contains filtered or unexported fields
}

ECDHSession implements a Session using elliptic curve cryptography. Sessions are created using Suite.New.

func (*ECDHSession) Equal

func (s *ECDHSession) Equal(other Session) bool

Equal compares two key exchange sessions. If an Equal method is not implemented, the sessions can be compared with reflect.DeepEqual.

func (*ECDHSession) MarshalBinary

func (s *ECDHSession) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler

func (*ECDHSession) MarshalCBOR

func (s *ECDHSession) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler.

func (*ECDHSession) Parameter

func (s *ECDHSession) Parameter(rand io.Reader, _ *rsa.PublicKey) ([]byte, error)

Parameter generates the exchange parameter to send to its peer. This function will generate a new parameter every time it is called. This method is used by both the client and server.

func (*ECDHSession) SetParameter

func (s *ECDHSession) SetParameter(xB []byte, _ *rsa.PrivateKey) error

SetParameter sets the received parameter from the client. This method is only called by a server.

func (ECDHSession) String

func (s ECDHSession) String() string

func (*ECDHSession) UnmarshalBinary

func (s *ECDHSession) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler

func (*ECDHSession) UnmarshalCBOR

func (s *ECDHSession) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler.

type OAEPSession

type OAEPSession struct {

	// Session encrypt/decrypt data
	SessionCrypter
	// contains filtered or unexported fields
}

OAEPSession implements a Session using RSA keys directly with OAEP encryption. Sessions are created using Suite.New.

func (*OAEPSession) MarshalBinary

func (s *OAEPSession) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler

func (*OAEPSession) MarshalCBOR

func (s *OAEPSession) MarshalCBOR() ([]byte, error)

MarshalCBOR implements cbor.Marshaler.

func (*OAEPSession) Parameter

func (s *OAEPSession) Parameter(rand io.Reader, ownerKey *rsa.PublicKey) ([]byte, error)

Parameter generates the exchange parameter to send to its peer. This function will generate a new parameter every time it is called. This method is used by both the client and server.

func (*OAEPSession) SetParameter

func (s *OAEPSession) SetParameter(xB []byte, ownerKey *rsa.PrivateKey) (err error)

SetParameter sets the received parameter from the client. This method is only called by a server.

func (OAEPSession) String

func (s OAEPSession) String() string

func (*OAEPSession) UnmarshalBinary

func (s *OAEPSession) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler

func (*OAEPSession) UnmarshalCBOR

func (s *OAEPSession) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements cbor.Unmarshaler.

type Session

type Session interface {
	// Parameter generates the exchange parameter to send to its peer. This function will generate
	// a new parameter every time it is called. This method is used by both the client and server.
	//
	// The public key parameter is only used for ASYMKEX* suites.
	Parameter(rand io.Reader, ownerKey *rsa.PublicKey) ([]byte, error)

	// SetParameter sets the received parameter from the client. This method is only called by a
	// server.
	//
	// The private key parameter is only used for ASYMKEX* suites.
	SetParameter(xB []byte, ownerKey *rsa.PrivateKey) error

	// Encrypt uses a session key to encrypt a payload. Depending on the suite, the result may be a
	// plain COSE_Encrypt0 or one wrapped by COSE_Mac0.
	Encrypt(rand io.Reader, payload any) (any, error)

	// Decrypt a tagged COSE Encrypt0 or Mac0 object.
	Decrypt(rand io.Reader, r io.Reader) ([]byte, error)

	// Destroy zeroes secrets that last until the end of the session. This means SEK/SVK, but not
	// exchanged parameters, which can be destroyed automatically when SEK/SVK are derived.
	Destroy()
}

Session implements encryption/decryption for a single session. It is suggested that Session implementations also implement binary.Marshaler and binary.Unmarshaler so that owner service implementations can load balance on a per-message basis without any affinity.

All Sessions from Suites in this package implement encoding.BinaryMarshaler and encoding.BinaryUnmarshaler.

type SessionCrypter

type SessionCrypter struct {
	ID     CipherSuiteID
	Cipher CipherSuite

	SEK []byte
	SVK []byte
}

SessionCrypter implements Encrypt/Decrypt methods and can be used (via struct embedding) to implement the Session interface.

func (SessionCrypter) Decrypt

func (s SessionCrypter) Decrypt(rand io.Reader, r io.Reader) ([]byte, error)

Decrypt a tagged COSE Encrypt0 or Mac0 object.

func (*SessionCrypter) Destroy

func (s *SessionCrypter) Destroy()

Destroy zeroes secrets that last until the end of the session. This means SEK/SVK, but not exchanged parameters, which can be destroyed automatically when SEK/SVK are derived.

func (SessionCrypter) Encrypt

func (s SessionCrypter) Encrypt(rand io.Reader, payload any) (any, error)

Encrypt uses a session key to encrypt a payload. Depending on the suite, the result may be a plain COSE_Encrypt0 or one wrapped by COSE_Mac0.

func (SessionCrypter) String

func (s SessionCrypter) String() string

type Suite

type Suite string

Suite name of each key exchange suite

When the Owner Key is RSA:

  • “DHKEXid14”: Diffie-Hellman key exchange method using a standard Diffie-Hellman mechanism with a standard NIST exponent and 2048-bit modulus ([RFC3526], id 14). This is the preferred method for RSA2048RESTR Owner keys.
  • “DHKEXid15”: Diffie-Hellman key exchange method using a standard Diffie-Hellman mechanism with a standard National Institute of Standards and Technology (NIST) exponent and 3072-bit modulus. ([RFC3526], id 15), This is the preferred method for RSA 3072-bit Owner keys.
  • “ASYMKEX2048”: Asymmetric key exchange method uses the encryption by an Owner key based on RSA2048RESTR; this method is useful in FIDO Device Onboard Client environments where Diffie-Hellman computation is slow or difficult to code.
  • “ASYMKEX3072”: The Asymmetric key exchange method uses the encryption by an Owner key based on RSA with 3072-bit key.

DHKEXid14 and DHKEXid15 differ in the size of the Diffie-Hellman modulus, which is chosen to match the RSA key size in use.

When the Owner key is ECDSA:

  • “ECDH256”: The ECDH method uses a standard Diffie-Hellman mechanism for ECDSA keys. The ECC keys follow NIST P-256 (SECP256R1)
  • “ECDH384”: Standard Diffie-Hellman mechanism ECC NIST P-384 (SECP384R1)
const (
	DHKEXid14Suite   Suite = "DHKEXid14"
	DHKEXid15Suite   Suite = "DHKEXid15"
	ASYMKEX2048Suite Suite = "ASYMKEX2048"
	ASYMKEX3072Suite Suite = "ASYMKEX3072"
	ECDH256Suite     Suite = "ECDH256"
	ECDH384Suite     Suite = "ECDH384"
)

Key exchange suites

CDDL

KexSuiteNames /= (
    "DHKEXid14",
    "DHKEXid15",
    "ASYMKEX2048",
    "ASYMKEX3072",
    "ECDH256",
    "ECDH384"
)

func (Suite) New

func (s Suite) New(xA []byte, c CipherSuiteID) Session

New returns a Session for the given key exchange suite. If no session constructor is registered for the suite, then the return value is nil.

For the server, xA will be nil.

func (Suite) Valid

func (s Suite) Valid(device, owner crypto.PublicKey) bool

Valid returns whether the spec allows the key exchange suite for the given device and owner attestation keys. The device parameter must be either an *ecdsa.PublicKey, *rsa.PublicKey, or cose.SignatureAlgorithm.

(3.6.5) Key Exchange and FIDO Device Onboard Crypto Mapping

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Device Attestation    Owner Attestation           Key Exchange                                                      │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ECDSA NIST P-256      RSA2048 or RSA2048RESTR     DHKEXid14/ASYMKEX2048                                             │
│ ECDSA NIST P-384      RSA2048 or RSA2048RESTR     DHKEXid14/ASYMKEX2048 (Not a recommended configuration, see note) │
│ ECDSA NIST P-256      RSA3072                     DHKEXid15/ASYMKEX3072 (Not a recommended configuration, see note) │
│ ECDSA NIST P-384      RSA3072                     DHKEXid15/ASYMKEX3072                                             │
│ ECDSA NIST P-256      ECDSA NIST P-256            ECDH256                                                           │
│ ECDSA NIST P-384      ECDSA NIST P-256            ECDH256 (Not a recommended configuration) *                       │
│ ECDSA NIST P-256      ECDSA NIST P-384            ECDH384 (Not a recommended configuration, see note)               │
│ ECDSA NIST P-384      ECDSA NIST P-384            ECDH384                                                           │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Jump to

Keyboard shortcuts

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