Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
graynk committed Jun 11, 2019
1 parent 4bd179f commit 990794d
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
output/
.idea/
28 changes: 28 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Diversification

Writer takes 16-byte 2K3DES master key as command line argument, derives from it
a new key based on UID of the tag, and then writes the new key to the tag.
If second argument is provided, then it's used as the current key.
If no second argument is provided, then the default key (BREAKMEIFYOUCAN!) is used.

Reader takes master key and reads the whole card with derived key.

This works only for Mifare Ultralight C tags.

## Dependencies
I use my [fork](https://github.com/graynk/freefare) of [fuzxxl/freefare](https://github.com/fuzxxl/freefare)
that supports key diversification and has some ad-hoc fixes to work with latest
version of [libfreefare](https://github.com/nfc-tools/libfreefare) (as well as some minor bug fixes).

Obviously this means that building and installing [libnfc](https://github.com/nfc-tools/libnfc/) and
[libfreefare](https://github.com/nfc-tools/libfreefare) from
master is needed too. I'd have provided a specific version that's required, but
for some reason they have decided
to not bump the version for the past 4 years despite continuous changes to the API,
so expect things to be broken.

## Usage
```
sh build.sh
output/writer 00112233445566778899AABBCCDDEEFF FFEEDDCCBBAA99887766554433221100
output/reader FFEEDDCCBBAA99887766554433221100
3 changes: 3 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
go build -o output/reader reader/main.go
go build -o output/writer writer/main.go
70 changes: 70 additions & 0 deletions reader/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"C"
"encoding/hex"
"fmt"
"github.com/fuzxxl/nfc/2.0/nfc"
"github.com/graynk/freefare/0.3-diversify/freefare"
"log"
"os"
)

func main() {
args := os.Args
if len(args) == 1 {
log.Fatal("No master key provided")
}
devices, err := nfc.ListDevices()
if err != nil || len(devices) == 0 {
log.Fatalf("No devices found, %s", err)
}
device, err := nfc.Open(devices[0])
if err != nil {
log.Fatalf("Failed to open device, %s", err)
}
tags, err := freefare.GetTags(device)
if err != nil {
log.Fatalf("Failed to get tags, %s", err)
}
for _, tag := range tags {
err = tag.Connect()
if err != nil {
log.Fatalf("Can't connect, %s", err)
}
fmt.Println(tag)
fmt.Println(tag.UID())
if tag.Type() != freefare.UltralightC {
return
}

ultralightC := tag.(freefare.UltralightTag)
masterKeySlice, err := hex.DecodeString(args[1])
if err != nil || len(masterKeySlice) != 16 {
log.Fatalf("Failed to decode hex string to 16-byte key, %s", args[1])
}
var masterKeyBytes [16]byte
copy(masterKeyBytes[:], masterKeySlice)
masterKey := freefare.NewDESFire3DESKey(masterKeyBytes)
newKey, err := ultralightC.Diversify(*masterKey)
if err != nil {
log.Fatalf("Failed to diversify master key, %s", err)
}
err = ultralightC.Authenticate(*newKey)
if err != nil {
log.Fatal(err)
}
for page := byte(0); page < 44; page++ {
readBytes, err := ultralightC.ReadPage(page)
if err != nil {
log.Fatalf("Can't read, %s", err)
}
fmt.Printf("% X\n", readBytes)
}
err = tag.Disconnect()
if err != nil {
log.Fatal(err)
}
fmt.Println("Done")
}
}
78 changes: 78 additions & 0 deletions writer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package main

import (
"encoding/hex"
"fmt"
"github.com/fuzxxl/nfc/2.0/nfc"
"github.com/graynk/freefare/0.3-diversify/freefare"
"log"
"os"
)

func main() {
args := os.Args
if len(args) == 1 {
log.Fatal("No master key provided")
}
devices, err := nfc.ListDevices()
if err != nil || len(devices) == 0 {
log.Fatalf("No devices found, %s", err)
}
device, err := nfc.Open(devices[0])
if err != nil {
log.Fatalf("Failed to open device, %s", err)
}
tags, err := freefare.GetTags(device)
if err != nil {
log.Fatalf("Failed to get tags, %s", err)
}
masterKeySlice, err := hex.DecodeString(args[1])
if err != nil || len(masterKeySlice) != 16 {
log.Fatalf("Failed to decode hex string to 16-byte key, %s", args[1])
}
var masterKeyBytes [16]byte
copy(masterKeyBytes[:], masterKeySlice)
masterKey := freefare.NewDESFire3DESKey(masterKeyBytes)

var defaultKeyBytes [16]byte
if len(args) > 2 {
defaultKeySlice, err := hex.DecodeString(args[2])
if err != nil || len(masterKeySlice) != 16 {
log.Fatalf("Failed to decode hex string to 16-byte key, %s", args[2])
}
copy(defaultKeyBytes[:], defaultKeySlice)
} else {
// BREAKMEIFYOUCAN!
defaultKeyBytes = [16]byte{0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46}
}
defaultKey := freefare.NewDESFire3DESKey(defaultKeyBytes)
for _, tag := range tags {
err = tag.Connect()
if err != nil {
log.Fatalf("Failed to connect, %s", err)
}
fmt.Println(tag)
fmt.Println(tag.UID())
if tag.Type() != freefare.UltralightC {
log.Fatal("Not Ultralight C")
}
ultralightC := tag.(freefare.UltralightTag)
diversifiedKey, err := ultralightC.Diversify(*masterKey)
if err != nil {
log.Fatalf("Failed to diversify master key, %s", err)
}
err = ultralightC.SwapKeys(*defaultKey, *diversifiedKey)
if err != nil {
log.Fatalf("Failed to swap, %s", err)
}
err = ultralightC.Authenticate(*diversifiedKey)
if err != nil {
log.Fatalf("Failed to auth with diversified key, %s", err)
}
err = tag.Disconnect()
if err != nil {
log.Fatalf("Failed to disconnect, %s", err)
}
fmt.Println("Done")
}
}

0 comments on commit 990794d

Please sign in to comment.