Module 6: Security - MAC & PIN Blocks

Slide 1: Why Security in Payment Messages?

                    THREAT LANDSCAPE
┌──────────────────────────────────────────────────────────┐
│                                                          │
│  Terminal ──► Router ──► Gateway ──► Network ──► Issuer  │
│                                                          │
│     At every hop, messages can be:                       │
│     • Intercepted (read by attackers)                    │
│     • Modified (amounts changed, routing altered)        │
│     • Replayed (same transaction sent twice)             │
│                                                          │
└──────────────────────────────────────────────────────────┘

Two Critical Protections:
┌─────────────────────────┐  ┌─────────────────────────┐
│         MAC             │  │       PIN Block         │
│  Message Authentication │  │    PIN Encryption       │
│  "Was this modified?"   │  │  "Keep PIN secret"      │
└─────────────────────────┘  └─────────────────────────┘
1 / 26

Slide 2: What a MAC Does

MESSAGE AUTHENTICATION CODE (MAC)

Input:                          Output:
┌─────────────────────────┐     ┌──────────────────┐
│  Message Content        │     │ 8-byte checksum  │
│  (0100...DE2...DE4...) │ ──► │ A7 B3 2C 4F ...  │
│  +                      │     └──────────────────┘
│  Secret Key (16 bytes)  │
└─────────────────────────┘

Properties:
1. INTEGRITY     - Any change invalidates MAC
2. AUTHENTICITY  - Only key holders can generate
3. NOT ENCRYPTION - Message stays readable

      ┌─ Original: DE4 = 000000005000 ($50.00)
      │  MAC: A7B32C4F9E1D8A55 ✓
      │
      └─ Tampered: DE4 = 000000500000 ($5000.00)
         MAC: A7B32C4F9E1D8A55 ✗ Invalid!
2 / 26

Slide 3: DE64 and DE128 - Where MACs Live

MESSAGE STRUCTURE WITH MAC

┌──────────────────────────────────────────────────────────┐
│ MTI │ Primary  │  DE2...DE63  │ DE64 │ DE65...127 │ DE128│
│     │ Bitmap   │              │ MAC  │            │ MAC  │
│     │          │              │ (1)  │            │ (2)  │
└──────────────────────────────────────────────────────────┘

DE64 (Primary MAC):
• Covers fields 1-63
• Calculated by acquirer
• Verified by network

DE128 (Secondary MAC):
• Covers fields 1-127 (including DE64)
• Calculated by network
• Verified by issuer

Most systems use only DE64.
3 / 26

Slide 4: ANSI X9.9 - Single DES CBC-MAC

MESSAGE:   M1    M2    M3    M4   (8-byte blocks)
KEY:       K (8 bytes, single DES)
IV:        00 00 00 00 00 00 00 00

    M1          M2          M3          M4
    │           │           │           │
    ▼           ▼           ▼           ▼
  ┌───┐       ┌───┐       ┌───┐       ┌───┐
  │XOR│◄─IV   │XOR│       │XOR│       │XOR│
  └─┬─┘       └─┬─┘       └─┬─┘       └─┬─┘
    │           │           │           │
    ▼           ▼           ▼           ▼
  ┌───┐       ┌───┐       ┌───┐       ┌───┐
  │DES│       │DES│       │DES│       │DES│
  │ K │       │ K │       │ K │       │ K │
  └─┬─┘       └─┬─┘       └─┬─┘       └─┬─┘
    │           │           │           │
    └───────────►───────────►───────────┴──► MAC

WARNING: Single DES is OBSOLETE (56-bit key crackable in hours)
4 / 26

Slide 5: ANSI X9.19 - Triple DES MAC (Retail MAC)

KEY: K = K1 || K2 (16 bytes)

STEP 1: CBC-MAC with K1 through all blocks
    M1         M2         Mn
    │          │          │
    ▼          ▼          ▼
  XOR→DES(K1)→XOR→DES(K1)→XOR→DES(K1)
                              │
                       Intermediate

STEP 2: Triple-DES final step
                       Intermediate
                              │
                              ▼
                         ┌─────────┐
                         │  DES⁻¹  │  ← Decrypt with K2
                         │   K2    │
                         └────┬────┘
                              │
                              ▼
                         ┌─────────┐
                         │   DES   │  ← Encrypt with K1
                         │   K1    │
                         └────┬────┘
                              │
                              ▼
                            MAC (8 bytes)

This is the MINIMUM STANDARD for new systems.
5 / 26

Slide 6: X9.19 MAC in Go

func CalculateX919MAC(key, data []byte) ([]byte, error) {
    if len(key) != 16 {
        return nil, errors.New("X9.19 requires 16-byte key")
    }

    k1, k2 := key[0:8], key[8:16]
    cipher1, _ := des.NewCipher(k1)
    cipher2, _ := des.NewCipher(k2)

    // Pad to 8-byte boundary
    padded := padISO7816(data)

    // CBC-MAC with K1
    intermediate := make([]byte, 8)
    for i := 0; i < len(padded); i += 8 {
        for j := 0; j < 8; j++ {
            intermediate[j] ^= padded[i+j]
        }
        cipher1.Encrypt(intermediate, intermediate)
    }

    // Final: Decrypt(K2) then Encrypt(K1)
    cipher2.Decrypt(intermediate, intermediate)
    cipher1.Encrypt(intermediate, intermediate)

    return intermediate, nil
}
6 / 26

Slide 7: Constant-Time MAC Comparison

// WRONG: Timing attack vulnerable
// ========================================
if bytes.Equal(receivedMAC, expectedMAC) {
    return true
}

// Attacker measures response time:
// • 0.1ms = first byte matched, failed on 2nd
// • 0.2ms = first 2 bytes matched
// Eventually guesses entire MAC byte-by-byte


// RIGHT: Constant-time comparison
// ========================================
import "crypto/subtle"

if subtle.ConstantTimeCompare(receivedMAC, expectedMAC) == 1 {
    return true
}

// Same time regardless of how many bytes match
// No information leakage
7 / 26

Slide 8: PIN Block Concept

                    THE PIN BLOCK

Customer enters: 1 2 3 4 (PIN)
                    │
                    ▼
            ┌───────────────┐
            │  PIN Block    │  Combines:
            │  Format       │  • PIN digits
            │  (ISO-0)      │  • Length
            │               │  • PAN (for uniqueness)
            └───────┬───────┘
                    │
     Clear Block: 04 12 14 EA EE D7 CF C9
                    │
                    ▼
            ┌───────────────┐
            │  3DES Encrypt │
            │  with ZPK     │
            └───────┬───────┘
                    │
   Encrypted: A7 3B 2C 4F 9E 1D 8A 55
                    │
                    ▼
                  DE52

PIN is NEVER in cleartext outside secure hardware.
8 / 26

Slide 9: ISO Format 0 (Most Common)

ISO-0 PIN BLOCK STRUCTURE

Step 1: Build PIN field (16 hex nibbles)
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│0│L│P│P│P│P│F│F│F│F│F│F│F│F│F│F│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
 │ │ └──────┴───────────────────┘
 │ │   PIN      Fill (0xF)
 │ └── Length
 └── Format (0)

Step 2: Build PAN field (16 hex nibbles)
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│0│0│0│0│N│N│N│N│N│N│N│N│N│N│N│N│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
       └────────────────────────┘
         12 rightmost PAN digits
         (excluding check digit)

Step 3: XOR them
Clear PIN Block = PIN_field ⊕ PAN_field
9 / 26

Slide 10: ISO-0 Example Calculation

PIN:  1234
PAN:  4532015112830366

PIN field:  0  4  1  2  3  4  F  F  F  F  F  F  F  F  F  F
            │  │  │  │  │  │
            │  │  └──┴──┴──┘ PIN digits
            │  └── Length = 4
            └── Format = 0

PAN digits: 4532015112830366
                          │
            └── Check digit (excluded)

12 rightmost (excluding check): 201511283036

PAN field:  0  0  0  0  2  0  1  5  1  1  2  8  3  0  3  6

XOR:
PIN field:  0  4  1  2  3  4  F  F  F  F  F  F  F  F  F  F
PAN field:  0  0  0  0  2  0  1  5  1  1  2  8  3  0  3  6
            ────────────────────────────────────────────────
Result:     0  4  1  2  1  4  E  A  E  E  D  7  C  F  C  9

Clear PIN Block: 04 12 14 EA EE D7 CF C9
10 / 26

Slide 11: Why XOR with PAN?

WITHOUT PAN XOR:
─────────────────
PIN 1234 on ANY card: 04 12 34 FF FF FF FF FF

Attack: Collect encrypted blocks, find duplicates
        → Same encrypted block = same PIN
        → Statistical analysis breaks PINs


WITH PAN XOR (ISO-0):
─────────────────────
PIN 1234 on Card A:   04 12 14 EA EE D7 CF C9
PIN 1234 on Card B:   04 12 27 A3 91 8C 2B FE
PIN 1234 on Card C:   04 12 56 3D 4A E2 18 77

Each card has UNIQUE clear block even with same PIN!

Security benefit:
• Can't correlate blocks across cards
• Block is useless without corresponding PAN
• Statistical attacks defeated
11 / 26

Slide 12: Other PIN Block Formats

FORMAT COMPARISON

ISO-0 (Format 0) - XOR with PAN
  PIN + PAN → Block
  Most common, standard for interchange

ISO-1 (Format 1) - Random fill
  PIN + Random → Block
  No PAN needed, less obfuscation

ISO-2 (Format 2) - For chip cards
  PIN + Fill → Block (no XOR)
  Used for offline PIN verification

ISO-3 (Format 3) - ANSI X9.8
  Same as ISO-0, different format nibble

ISO-4 (Format 4) - AES-based
  PIN + PAN → 16-byte block (AES)
  Modern, requires infrastructure changes


DE53 tells which format is used:
Position 1-2: 01=ISO-0, 02=ISO-1, 03=ISO-2, etc.
12 / 26

Slide 13: DE52 and DE53 Structure

DE52: Encrypted PIN Block
──────────────────────────
Length: 8 bytes (binary)
Content: 3DES encrypted PIN block

    A7 3B 2C 4F 9E 1D 8A 55
    └────────────────────────┘
         Encrypted block


DE53: Security Control Information
───────────────────────────────────
Length: 16 characters (typically)

  0  1  0  2  0  1  0  0  0  0  0  0  0  0  0  0
  │  │  │  │  │  │
  └──┘  └──┘  └──┘
   │     │     │
   │     │     └── Key Index (01)
   │     └── Algorithm (02 = 3DES)
   └── Format (01 = ISO-0)
13 / 26

Slide 14: The Key Hierarchy

                    ┌─────────────────┐
                    │      LMK        │  Local Master Key
                    │  (HSM internal) │  Never exportable
                    └────────┬────────┘
                             │
            ┌────────────────┼────────────────┐
            ▼                ▼                ▼
       ┌────────┐       ┌────────┐       ┌────────┐
       │  ZMK   │       │  TMK   │       │  ZMK   │
       │(Zone A)│       │Terminal│       │(Zone B)│
       └───┬────┘       │ Master │       └────────┘
           │            └───┬────┘
           ▼                ▼
       ┌────────┐       ┌────────┐
       │  ZPK   │       │  TPK   │
       │Zone PIN│       │Terminal│
       │  Key   │       │PIN Key │
       └────────┘       └────────┘

LMK: Never leaves HSM, encrypts all other keys
ZMK: Shared between zones (key exchange)
ZPK: Working key for PIN encryption
TMK: Per-terminal master key
TPK: Per-terminal working key for PINs
14 / 26

Slide 15: PIN Translation Flow

                     PIN NEVER IN CLEARTEXT
                        (except in HSM)

Terminal           Acquirer HSM          Network HSM          Issuer HSM
   │                    │                     │                    │
   │ ┌─────────────┐    │                     │                    │
   │ │PIN encrypted│    │                     │                    │
   │ │ with TPK    │────►                     │                    │
   │ └─────────────┘    │                     │                    │
   │                    │                     │                    │
   │             ┌──────┴──────┐              │                    │
   │             │ Decrypt TPK │              │                    │
   │             │ Encrypt ZPK1│              │                    │
   │             └──────┬──────┘              │                    │
   │                    │                     │                    │
   │                    └─────────────────────►                    │
   │                                          │                    │
   │                                   ┌──────┴──────┐             │
   │                                   │ Decrypt ZPK1│             │
   │                                   │ Encrypt ZPK2│             │
   │                                   └──────┬──────┘             │
   │                                          │                    │
   │                                          └────────────────────►
   │                                                               │
   │                                                        ┌──────┴──────┐
   │                                                        │ Decrypt ZPK2│
   │                                                        │ Verify PIN  │
   │                                                        └─────────────┘
15 / 26

Slide 16: Key Check Values (KCV)

KEY CHECK VALUE - Verifying Key Without Revealing It

Formula:
KCV = First 3 bytes of 3DES_Encrypt(Key, 0x0000000000000000)


Example:
Key:     0123456789ABCDEF FEDCBA9876543210
         │
         ▼
    3DES_Encrypt(Key, 0x0000000000000000)
         │
         ▼
    08 D7 B4 A2 1C 5E 9F 33
    └──────┘
       KCV = 08D7B4


Usage:
• Both parties compute KCV after key exchange
• If KCVs match, keys are synchronized
• Never reveals actual key material

Side A: "My KCV is 08D7B4"
Side B: "My KCV is 08D7B4"  ✓ Keys match!
16 / 26

Slide 17: HSM - The Security Foundation

┌────────────────────────────────────────────────────────────┐
│                 HARDWARE SECURITY MODULE (HSM)             │
├────────────────────────────────────────────────────────────┤
│                                                            │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                 TAMPER-RESISTANT BOUNDARY            │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │  │
│  │  │ Key Storage │  │   Crypto    │  │   Random    │   │  │
│  │  │ (encrypted) │  │   Engine    │  │  Generator  │   │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘   │  │
│  │                                                      │  │
│  │  Keys NEVER leave this boundary in cleartext         │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                            │
│  API Commands:                                             │
│  • PE: Generate ZPK                                        │
│  • CA: Translate PIN (re-encrypt under different key)      │
│  • MS: Generate MAC                                        │
│  • MV: Verify MAC                                          │
│                                                            │
└────────────────────────────────────────────────────────────┘

Your code calls HSM APIs, never handles raw keys!
17 / 26

Slide 18: Common Attack - Statistical PIN Analysis

ATTACK SCENARIO

Attacker collects encrypted PIN blocks:
┌─────────────────────────────────────────────────┐
│ Block1: A7 3B 2C 4F 9E 1D 8A 55                │
│ Block2: A7 3B 2C 4F 9E 1D 8A 55  ← Same block! │
│ Block3: B8 2A 4D 3E 7F 0C 6B 44                │
│ Block4: A7 3B 2C 4F 9E 1D 8A 55  ← Same again! │
└─────────────────────────────────────────────────┘

Without PAN XOR:
Same PIN = Same block → Statistical attack possible
"1234" is most common → Most frequent block = "1234"

With ISO-0 (PAN XOR):
Same PIN + Different PAN = Different block
No statistical correlation possible


MITIGATIONS:
1. Use ISO-0 (XOR with PAN)
2. Rotate keys frequently
3. Limit PIN entry attempts
4. Monitor for collection attacks
18 / 26

Slide 19: Common Attack - Timing Side Channel

TIMING ATTACK ON MAC VERIFICATION

Vulnerable Code:
┌─────────────────────────────────────────────────────────┐
│ if bytes.Equal(receivedMAC, expectedMAC) {              │
│     return true                                         │
│ }                                                       │
└─────────────────────────────────────────────────────────┘

Attack:
┌─────────────────────────────────────────────────────────┐
│ Guess:  00 00 00 00 00 00 00 00  → 0.10ms (fast fail)  │
│ Guess:  A7 00 00 00 00 00 00 00  → 0.12ms (1st matched)│
│ Guess:  A7 B3 00 00 00 00 00 00  → 0.14ms (2 matched)  │
│ ...continue until all 8 bytes guessed...               │
└─────────────────────────────────────────────────────────┘

Defense:
┌─────────────────────────────────────────────────────────┐
│ import "crypto/subtle"                                  │
│                                                         │
│ if subtle.ConstantTimeCompare(received, expected) == 1 {│
│     return true                                         │
│ }                                                       │
│                                                         │
│ // Same execution time regardless of match position     │
└─────────────────────────────────────────────────────────┘
19 / 26

Slide 20: Key Rollover - The Distributed Problem

THE KEY ROLLOVER TRAP

Timeline:
──────────────────────────────────────────────────────
02:00:00  Issuer activates NEW ZPK
02:00:01  Transaction arrives (encrypted with OLD ZPK)
          Issuer decrypts with NEW ZPK → GARBAGE
          Result: PIN verification fails
02:05:00  Network activates NEW ZPK
──────────────────────────────────────────────────────

5 minutes of failed transactions!


SOLUTION: Grace Period with Dual Keys

┌─────────────────────────────────────────────────────┐
│ type KeyState struct {                              │
│     CurrentKey    []byte                            │
│     PreviousKey   []byte  // Keep during grace      │
│     RolloverTime  time.Time                         │
│     GracePeriod   time.Duration  // e.g., 10 min   │
│ }                                                   │
│                                                     │
│ // Try current key first                            │
│ // If fails AND within grace period, try previous   │
└─────────────────────────────────────────────────────┘
20 / 26

Slide 21: Debugging Security Failures

SECURITY DEBUGGING CHECKLIST

□ KEY SYNC: Compare KCVs
  Side A: KCV = 08D7B4
  Side B: KCV = 08D7B4  ✓
  If different → Keys out of sync

□ MAC INPUT: Compare byte counts
  Side A: MAC input = 1247 bytes
  Side B: MAC input = 1239 bytes  ✗
  If different → Wrong fields in MAC scope

□ PIN FORMAT: Check DE53
  DE53 says Format 01 (ISO-0)
  Terminal sends Format 03 (ISO-3)  ✗
  If mismatch → Garbage PIN after decode

□ PAN CONSISTENCY: Check XOR PAN
  Terminal XORed with: 4532XXXXXXXX0366 (masked)
  Issuer XORed with:   4532015112830366 (full)  ✗
  If different → Wrong PIN extracted


NEVER LOG:
• Actual keys
• Clear PIN blocks
• Full PANs
21 / 26

Slide 22: Complete Secure Message Flow

TERMINAL                ACQUIRER              NETWORK               ISSUER
   │                       │                     │                    │
   │ 1. PIN entered        │                     │                    │
   │ 2. Encrypt with TPK   │                     │                    │
   │ 3. Calculate MAC      │                     │                    │
   │                       │                     │                    │
   │───── 0100 + DE52 + DE64 ──────►            │                    │
   │                       │                     │                    │
   │                       │ 4. Verify MAC       │                    │
   │                       │ 5. Translate PIN    │                    │
   │                       │    TPK → ZPK1       │                    │
   │                       │ 6. New MAC          │                    │
   │                       │                     │                    │
   │                       │───── 0100 ──────────►                   │
   │                       │                     │                    │
   │                       │                     │ 7. Verify MAC      │
   │                       │                     │ 8. Translate PIN   │
   │                       │                     │    ZPK1 → ZPK2     │
   │                       │                     │                    │
   │                       │                     │──── 0100 ──────────►
   │                       │                     │                    │
   │                       │                     │    9. Verify MAC   │
   │                       │                     │   10. Decrypt PIN  │
   │                       │                     │   11. Verify PIN   │
   │                       │                     │                    │
   │◄───────────────────── 0110 (DE39=00/55) ────────────────────────│
22 / 26

Slide 23: Common Pitfalls Summary

SECURITY PITFALLS - DON'T DO THESE

1. USING SINGLE DES
   ✗ des.NewCipher(key8bytes)
   ✓ des.NewTripleDESCipher(key16bytes)

2. WRONG KEY FORMAT
   ✗ key := "0123456789ABCDEF"  // ASCII string?
   ✓ key, _ := hex.DecodeString("01234...")

3. MAC ON PARSED DATA
   ✗ input := msg.PAN + msg.Amount  // Strings
   ✓ input := msg.RawBytes[4:1247]   // Wire bytes

4. FORGETTING PAN XOR (ISO-0)
   ✗ block := padPIN(pin)
   ✓ block := xor(padPIN(pin), padPAN(pan))

5. LOGGING SECRETS
   ✗ log.Printf("Key: %X, PIN: %s", key, pin)
   ✓ log.Printf("KeyID: %s, KCV: %X", id, kcv)

6. NON-CONSTANT COMPARISON
   ✗ if received == expected
   ✓ if subtle.ConstantTimeCompare(...) == 1
23 / 26

Slide 24: Quick Reference Card

┌────────────────────────────────────────────────────────────┐
│               SECURITY QUICK REFERENCE                     │
├────────────────────────────────────────────────────────────┤
│                                                            │
│ MAC ALGORITHMS:                                            │
│   X9.9:  Single DES CBC-MAC (OBSOLETE)                    │
│   X9.19: 3DES CBC-MAC with final triple-DES step          │
│                                                            │
│ MAC FIELDS:                                                │
│   DE64:  Primary MAC (fields 1-63)                        │
│   DE128: Secondary MAC (fields 1-127)                     │
│                                                            │
│ PIN FORMATS:                                               │
│   ISO-0: PIN XOR PAN (most common)                        │
│   ISO-1: PIN + random fill                                │
│   ISO-2: PIN + 0xF fill (chip cards)                      │
│   ISO-3: Same as ISO-0, format nibble = 3                 │
│   ISO-4: AES-based, 16-byte block                         │
│                                                            │
│ KEY TYPES:                                                 │
│   LMK: Local Master (never leaves HSM)                    │
│   ZMK: Zone Master (key exchange key)                     │
│   ZPK: Zone PIN Key (working key)                         │
│   TMK: Terminal Master Key                                 │
│   TPK: Terminal PIN Key                                    │
│                                                            │
│ KCV = First 3 bytes of 3DES(Key, 0x00...00)               │
│                                                            │
│ CRITICAL: Use constant-time comparison for MACs!           │
└────────────────────────────────────────────────────────────┘
24 / 26

Slide 25: Key Takeaways

WHAT YOU MUST REMEMBER

1. MAC protects INTEGRITY, not confidentiality
   • Message is readable
   • Any tampering invalidates MAC
   • Use X9.19 (3DES), never X9.9 alone

2. PIN blocks protect the cardholder secret
   • ISO-0 XORs with PAN for uniqueness
   • Always encrypted before transmission
   • PIN never in cleartext outside HSM

3. Keys are hierarchical
   • LMK → ZMK → ZPK
   • HSMs manage all crypto operations
   • Your code never handles raw keys

4. Security failures are subtle
   • Key sync issues cause silent failures
   • Timing attacks leak information
   • Key rollover needs coordination

5. When debugging:
   • Compare KCVs (never actual keys)
   • Check MAC input byte counts
   • Verify PIN format in DE53
   • Log metadata, never secrets
25 / 26

Slide 26: Next Steps

APPLY YOUR KNOWLEDGE

Problem 1: mac-calculator
────────────────────────
Calculate X9.19 MACs for ISO8583 messages
• Implement CBC-MAC with 3DES final step
• Handle proper message padding
• Build MAC input from message fields


Problem 2: mac-verifier
───────────────────────
Verify MACs and handle key rotation
• Constant-time comparison
• Grace period for key rollover
• Reject tampered messages


Problem 3: pin-block-parser
───────────────────────────
Parse and validate PIN block formats
• Implement ISO-0 encode/decode
• XOR with PAN field correctly
• Extract PIN from encrypted blocks


These problems require the cryptographic fundamentals
from this module. Security is where precision matters.
26 / 26
Use arrow keys or click edges to navigate. Press H to toggle help, F for fullscreen.