variantlmk

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package variantlmk emulates the Thales payShield Variant LMK scheme in Go.

Index

Constants

This section is empty.

Variables

View Source
var KeyTypes = map[string]KeyType{

	"000": {Name: "ZMK", Code: "000", LMKPair: 2, VariantID: 0},
	"100": {Name: "ZMK (Comp)", Code: "100", LMKPair: 2, VariantID: 1},
	"200": {Name: "KML", Code: "200", LMKPair: 2, VariantID: 2},
	"300": {Name: "KEKr", Code: "300", LMKPair: 2, VariantID: 3},
	"400": {Name: "KEKs", Code: "400", LMKPair: 2, VariantID: 4},

	"001": {Name: "ZPK", Code: "001", LMKPair: 3, VariantID: 0},

	"002": {Name: "PVK/Generic", Code: "002", LMKPair: 7, VariantID: 0},
	"102": {Name: "TMK1 (AS2805)", Code: "102", LMKPair: 7, VariantID: 1},
	"202": {Name: "TMK2 (AS2805)", Code: "202", LMKPair: 7, VariantID: 2},

	"402": {Name: "CVK/CSCK", Code: "402", LMKPair: 7, VariantID: 4},

	"602": {Name: "KIA (AS2805)", Code: "602", LMKPair: 7, VariantID: 6},

	"003": {Name: "TAK", Code: "003", LMKPair: 8, VariantID: 0},
	"103": {Name: "TAKs/TAKr (AS2805)", Code: "103", LMKPair: 8, VariantID: 1},

	"105": {Name: "KML/KMLISS (OBKM)", Code: "105", LMKPair: 10, VariantID: 1},
	"205": {Name: "KMX/KMXISS (OBKM)", Code: "205", LMKPair: 10, VariantID: 2},
	"305": {Name: "KMP/KMPISS (OBKM)", Code: "305", LMKPair: 10, VariantID: 3},
	"405": {Name: "KIS.5 (OBKM)", Code: "405", LMKPair: 10, VariantID: 4},
	"505": {Name: "KM3L/KM3LISS (OBKM)", Code: "505", LMKPair: 10, VariantID: 5},
	"605": {Name: "KM3X/KM3XISS (OBKM)", Code: "605", LMKPair: 10, VariantID: 6},
	"705": {Name: "KMACS4 (OBKM)", Code: "705", LMKPair: 10, VariantID: 7},
	"805": {Name: "KMACS5 (OBKM)", Code: "805", LMKPair: 10, VariantID: 8},
	"905": {Name: "KMACACQ/KMACACK (OBKM)", Code: "905", LMKPair: 10, VariantID: 9},

	"006": {Name: "WWK", Code: "006", LMKPair: 11, VariantID: 0},
	"106": {Name: "KMACUPD (OBKM)", Code: "106", LMKPair: 11, VariantID: 1},
	"206": {Name: "KMACMA (OBKM)", Code: "206", LMKPair: 11, VariantID: 2},
	"306": {Name: "KMACCI/KMACISS (OBKM)", Code: "306", LMKPair: 11, VariantID: 3},
	"406": {Name: "KMSCISS (OBKM)", Code: "406", LMKPair: 11, VariantID: 4},
	"506": {Name: "BKEM (OBKM)", Code: "506", LMKPair: 11, VariantID: 5},
	"606": {Name: "BKAM (OBKM)", Code: "606", LMKPair: 11, VariantID: 6},

	"107": {Name: "KEK (Issuing)", Code: "107", LMKPair: 12, VariantID: 1},
	"207": {Name: "KMC (Issuing)", Code: "207", LMKPair: 12, VariantID: 2},
	"307": {Name: "SK-ENC (Issuing)", Code: "307", LMKPair: 12, VariantID: 3},
	"407": {Name: "SK-MAC (Issuing)", Code: "407", LMKPair: 12, VariantID: 4},
	"507": {Name: "SK-DEK/KDPERSO (Issuing)", Code: "507", LMKPair: 12, VariantID: 5},
	"807": {Name: "MK-KE (Issuing)", Code: "807", LMKPair: 12, VariantID: 8},
	"907": {Name: "MK-AS (Issuing)", Code: "907", LMKPair: 12, VariantID: 9},

	"008": {Name: "ZAK", Code: "008", LMKPair: 13, VariantID: 0},
	"108": {Name: "ZAKs (AS2805)", Code: "108", LMKPair: 13, VariantID: 1},
	"208": {Name: "ZAKr (AS2805)", Code: "208", LMKPair: 13, VariantID: 2},

	"009": {Name: "BDK type-1", Code: "009", LMKPair: 14, VariantID: 0},
	"109": {Name: "MK-AC", Code: "109", LMKPair: 14, VariantID: 1},
	"209": {Name: "MK-SMI", Code: "209", LMKPair: 14, VariantID: 2},
	"309": {Name: "MK-SMC", Code: "309", LMKPair: 14, VariantID: 3},
	"409": {Name: "MK-DAC", Code: "409", LMKPair: 14, VariantID: 4},
	"509": {Name: "MK-DN", Code: "509", LMKPair: 14, VariantID: 5},
	"609": {Name: "BDK type-2", Code: "609", LMKPair: 14, VariantID: 6},
	"709": {Name: "MK-CVC3/MK-DCVV3", Code: "709", LMKPair: 14, VariantID: 7},
	"809": {Name: "BDK type-3", Code: "809", LMKPair: 14, VariantID: 8},

	"00A": {Name: "ZEK", Code: "00A", LMKPair: 15, VariantID: 0},
	"10A": {Name: "ZEKs (AS2805)", Code: "10A", LMKPair: 15, VariantID: 1},
	"20A": {Name: "ZEKr (AS2805)", Code: "20A", LMKPair: 15, VariantID: 2},

	"00B": {Name: "DEK/TEK", Code: "00B", LMKPair: 16, VariantID: 0},
	"10B": {Name: "TEKs/TEKr (AS2805)", Code: "10B", LMKPair: 16, VariantID: 1},

	"30B": {Name: "TEK (PCI Code 30B)", Code: "30B", LMKPair: 16, VariantID: 3},

	"00C": {Name: "RSA-SK", Code: "00C", LMKPair: 17, VariantID: 0},
	"10C": {Name: "HMAC", Code: "10C", LMKPair: 17, VariantID: 1},

	"00D": {Name: "RSA-PK", Code: "00D", LMKPair: 18, VariantID: 0},
}

KeyTypes maps key type codes to their LMK pair and variant mappings. This table is based on the Thales payShield documentation for Variant LMKs, specifically the "Key Type Table" (non-PCI compliant version shown first in spec).

View Source
var KeyTypesPCI = map[string]KeyType{

	"000": {Name: "ZMK", Code: "000", LMKPair: 2, VariantID: 0},
	"100": {Name: "ZMK (Comp)", Code: "100", LMKPair: 2, VariantID: 1},
	"200": {Name: "KML", Code: "200", LMKPair: 2, VariantID: 2},
	"300": {Name: "KEKr", Code: "300", LMKPair: 2, VariantID: 3},
	"400": {Name: "KEKs", Code: "400", LMKPair: 2, VariantID: 4},

	"001": {Name: "ZPK", Code: "001", LMKPair: 3, VariantID: 0},

	"002": {Name: "PVK", Code: "002", LMKPair: 7, VariantID: 0},
	"102": {Name: "TMK1 (AS2805)", Code: "102", LMKPair: 7, VariantID: 1},
	"202": {Name: "TMK2 (AS2805)", Code: "202", LMKPair: 7, VariantID: 2},
	"402": {Name: "CVK/CSCK", Code: "402", LMKPair: 7, VariantID: 4},
	"602": {Name: "KIA (AS2805)", Code: "602", LMKPair: 7, VariantID: 6},

	"003": {Name: "TAK", Code: "003", LMKPair: 8, VariantID: 0},
	"103": {Name: "TAKs/TAKr (AS2805)", Code: "103", LMKPair: 8, VariantID: 1},

	"105": {Name: "KML/KMLISS (OBKM)", Code: "105", LMKPair: 10, VariantID: 1},
	"205": {Name: "KMX/KMXISS (OBKM)", Code: "205", LMKPair: 10, VariantID: 2},
	"305": {Name: "KMP/KMPISS (OBKM)", Code: "305", LMKPair: 10, VariantID: 3},
	"405": {Name: "KIS.5 (OBKM)", Code: "405", LMKPair: 10, VariantID: 4},
	"505": {Name: "KM3L/KM3LISS (OBKM)", Code: "505", LMKPair: 10, VariantID: 5},
	"605": {Name: "KM3X/KM3XISS (OBKM)", Code: "605", LMKPair: 10, VariantID: 6},
	"705": {Name: "KMACS4 (OBKM)", Code: "705", LMKPair: 10, VariantID: 7},
	"805": {Name: "KMACS5 (OBKM)", Code: "805", LMKPair: 10, VariantID: 8},
	"905": {Name: "KMACACQ/KMACACK (OBKM)", Code: "905", LMKPair: 10, VariantID: 9},

	"006": {Name: "WWK", Code: "006", LMKPair: 11, VariantID: 0},
	"106": {Name: "KMACUPD (OBKM)", Code: "106", LMKPair: 11, VariantID: 1},
	"206": {Name: "KMACMA (OBKM)", Code: "206", LMKPair: 11, VariantID: 2},
	"306": {Name: "KMACCI/KMACISS (OBKM)", Code: "306", LMKPair: 11, VariantID: 3},
	"406": {Name: "KMSCISS (OBKM)", Code: "406", LMKPair: 11, VariantID: 4},
	"506": {Name: "BKEM (OBKM)", Code: "506", LMKPair: 11, VariantID: 5},
	"606": {Name: "BKAM (OBKM)", Code: "606", LMKPair: 11, VariantID: 6},

	"107": {Name: "KEK (Issuing)", Code: "107", LMKPair: 12, VariantID: 1},
	"207": {Name: "KMC (Issuing)", Code: "207", LMKPair: 12, VariantID: 2},
	"307": {Name: "SK-ENC (Issuing)", Code: "307", LMKPair: 12, VariantID: 3},
	"407": {Name: "SK-MAC (Issuing)", Code: "407", LMKPair: 12, VariantID: 4},
	"507": {Name: "SK-DEK/KDPERSO (Issuing)", Code: "507", LMKPair: 12, VariantID: 5},
	"807": {Name: "MK-KE (Issuing)", Code: "807", LMKPair: 12, VariantID: 8},
	"907": {Name: "MK-AS (Issuing)", Code: "907", LMKPair: 12, VariantID: 9},

	"008": {Name: "ZAK", Code: "008", LMKPair: 13, VariantID: 0},
	"108": {Name: "ZAKs (AS2805)", Code: "108", LMKPair: 13, VariantID: 1},
	"208": {Name: "ZAKr (AS2805)", Code: "208", LMKPair: 13, VariantID: 2},

	"009": {Name: "BDK type-1", Code: "009", LMKPair: 14, VariantID: 0},
	"109": {Name: "MK-AC", Code: "109", LMKPair: 14, VariantID: 1},
	"209": {Name: "MK-SMI", Code: "209", LMKPair: 14, VariantID: 2},
	"309": {Name: "MK-SMC", Code: "309", LMKPair: 14, VariantID: 3},
	"409": {Name: "MK-DAC", Code: "409", LMKPair: 14, VariantID: 4},
	"509": {Name: "MK-DN", Code: "509", LMKPair: 14, VariantID: 5},
	"609": {Name: "BDK type-2", Code: "609", LMKPair: 14, VariantID: 6},
	"709": {Name: "MK-CVC3/MK-DCVV3", Code: "709", LMKPair: 14, VariantID: 7},
	"809": {Name: "BDK type-3", Code: "809", LMKPair: 14, VariantID: 8},

	"00A": {Name: "ZEK", Code: "00A", LMKPair: 15, VariantID: 0},
	"10A": {Name: "ZEKs (AS2805)", Code: "10A", LMKPair: 15, VariantID: 1},
	"20A": {Name: "ZEKr (AS2805)", Code: "20A", LMKPair: 15, VariantID: 2},

	"00B": {Name: "DEK/TEK", Code: "00B", LMKPair: 16, VariantID: 0},
	"10B": {Name: "TEKs/TEKr (AS2805)", Code: "10B", LMKPair: 16, VariantID: 1},
	"30B": {Name: "TEK (PCI Code 30B)", Code: "30B", LMKPair: 16, VariantID: 3},

	"00C": {Name: "RSA-SK", Code: "00C", LMKPair: 17, VariantID: 0},
	"10C": {Name: "HMAC", Code: "10C", LMKPair: 17, VariantID: 1},

	"00D": {Name: "RSA-PK", Code: "00D", LMKPair: 18, VariantID: 0},

	"70D": {
		Name:      "TPK / PEK (PCI)",
		Code:      "70D",
		LMKPair:   18,
		VariantID: 2,
	},
	"80D": {
		Name:      "TMK (PCI)",
		Code:      "80D",
		LMKPair:   18,
		VariantID: 4,
	},
	"90D": {
		Name:      "TKR (PCI)",
		Code:      "90D",
		LMKPair:   18,
		VariantID: 9,
	},
}

KeyTypesPCI maps key type codes to their LMK pair and variant mappings for PCI-HSM compliant mode. This table is based on the Thales payShield documentation for Variant LMKs, specifically "Key Type Table 2" and "Variant Key Type Codes" (Code 2 column). Note: Some key types from non-PCI mode are re-mapped to different LMK Pairs/Variants here. Key types not explicitly listed in Table 2 but present in the general "Variant Key Type Codes" list under "Code 2" are included if their LMK Pair/Variant is clear.

View Source
var VariantMap = map[int]byte{
	1: 0xA6,
	2: 0x5A,
	3: 0x6A,
	4: 0xDE,
	5: 0x2B,
	6: 0x50,
	7: 0x74,
	8: 0x9C,
	9: 0xFA,
}

Functions

func DecryptKeyUnderScheme

func DecryptKeyUnderScheme(
	keyTypeCode string,
	schemeTag byte,
	encryptedKey []byte,
	lmkSet LMKSet,
	isKeyComponent bool,
) ([]byte, error)

DecryptKeyUnderScheme decrypts an encryptedKey using the LMK associated with keyTypeCode and schemeTag. If isKeyComponent is true, an additional 0xFF variant is applied to the LMK after the key-type variant.

func DecryptUnderVariantLMK

func DecryptUnderVariantLMK(encryptedKey []byte, pair LMKPair, schemeTag byte) ([]byte, error)

DecryptUnderVariantLMK decrypts an input key that was encrypted under a variant LMK pair using a specific scheme. The provided LMKPair should already have the key-type specific variant applied.

func EncryptKeyUnderScheme

func EncryptKeyUnderScheme(
	keyTypeCode string,
	schemeTag byte,
	inputKey []byte,
	lmkSet LMKSet,
	isKeyComponent bool,
) ([]byte, error)

EncryptKeyUnderScheme encrypts inputKey under the correct LMK based on keyTypeCode and schemeTag. If isKeyComponent is true, an additional 0xFF variant is applied to the LMK after the key-type variant.

func EncryptUnderVariantLMK

func EncryptUnderVariantLMK(inputKey []byte, pair LMKPair, schemeTag byte) ([]byte, error)

EncryptUnderVariantLMK encrypts inputKey under a variant LMK pair using a specific scheme. The provided LMKPair should already have the key-type specific variant applied.

func GetPCIComplianceMode

func GetPCIComplianceMode() bool

GetPCIComplianceMode returns true if the HSM is set to operate in PCI-HSM compliant mode.

func SetPCIComplianceMode

func SetPCIComplianceMode(enabled bool)

SetPCIComplianceMode sets the HSM operating mode for key type table selection. If enabled is true, the PCI-HSM compliant key type table will be used.

Types

type KeyType

type KeyType struct {
	Name      string
	Code      string
	LMKPair   int
	VariantID int
}

KeyType defines the mapping of a key type to its LMK pair and variant. It aligns with the Thales Key Type Table. LMKPair is the 0-based index into the LMKSet (e.g., index 2 for LMKs 04-05). VariantID is the variant number (0-9) applied to the LMK pair. Code is the Thales Key Type Code (e.g., "000", "001", "002-70D"). Name is a descriptive name for the key type.

func GetKeyTypeDetails

func GetKeyTypeDetails(keyTypeStr string, pciMode bool) (KeyType, error)

GetKeyTypeDetails returns the LMK pair index and variant ID for a given key type string. It considers the PCI compliance mode to select the correct key type table.

func (KeyType) String

func (kt KeyType) String() string

String returns a string representation of the KeyType.

type LMKPair

type LMKPair struct {
	Left  []byte
	Right []byte
}

func LoadLMKFromHex

func LoadLMKFromHex(leftHex, rightHex string) (LMKPair, error)

func (LMKPair) ApplyVariant

func (lmk LMKPair) ApplyVariant(variantID int) (LMKPair, error)

type LMKSet

type LMKSet [20]LMKPair

func LoadDefaultLMKSet

func LoadDefaultLMKSet() (LMKSet, error)

LoadDefaultLMKSet loads the predefined default LMK set (Double-length Variant Test LMK).

Jump to

Keyboard shortcuts

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