Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class PretixMf0aes(val keySets: List<Mf0aesKeySet>, val useRandomIdForNewTags: B
Page 0x04: public_id (big endian)
*/

fun process(nfca: AbstractNfcA, encodeWith: Mf0aesKeySet? = null): String {
fun process(nfca: AbstractNfcA, encodeWith: Mf0aesKeySet? = null, wipe: Boolean = false): String {
nfca.connect()
try {
val tagType = GetVersion().execute(nfca) as? UltralightAESTagType
Expand All @@ -39,7 +39,7 @@ class PretixMf0aes(val keySets: List<Mf0aesKeySet>, val useRandomIdForNewTags: B

val firstPage = readPages(nfca, 0x04, 1)
if (firstPage.contentEquals(byteArrayOf(0, 0, 0, 0))) {
if (encodeWith != null) {
if (encodeWith != null && !wipe) {
return encode(nfca, encodeWith)
} else {
throw NfcChipReadError(ChipReadError.EMPTY_CHIP)
Expand All @@ -48,7 +48,12 @@ class PretixMf0aes(val keySets: List<Mf0aesKeySet>, val useRandomIdForNewTags: B
for (keySet in keySets) {
val expectedPage = idToBytes(keySet.publicId)
if (firstPage.contentEquals(expectedPage)) {
return decode(nfca, keySet)
return if (wipe) {
wipe(nfca, keySet)
"OK"
} else {
decode(nfca, keySet)
}
}
}
throw NfcChipReadError(ChipReadError.FOREIGN_CHIP)
Expand Down Expand Up @@ -90,6 +95,51 @@ class PretixMf0aes(val keySets: List<Mf0aesKeySet>, val useRandomIdForNewTags: B
return uid.toHexString(false)
}


private fun wipe(nfca: AbstractNfcA, keySet: Mf0aesKeySet) {
var authenticatedNfcA = AuthenticationHelper(
AuthenticationHelper.KeyId.UID_RETR_KEY,
nfca,
keySet.uidKey
).authenticate()
val uid = UidHelper(authenticatedNfcA).readUid()

val diversifiedKey = An10922KeyDiversification().generateDiversifiedKeyAES128(
keySet.diversificationKey,
uid, // 4 bytes
"eu.pretix".toByteArray(Charset.defaultCharset()), // 9 bytes
idToBytes(keySet.publicId) // 4 bytes
// total diversification input: 17 bytes (must be 16..32)
)

authenticatedNfcA = AuthenticationHelper(
AuthenticationHelper.KeyId.DATA_PROT_KEY,
authenticatedNfcA,
diversifiedKey
).authenticate()

MifareUltralightAesConfigChange.Builder()
.setDataProtKey(ByteArray(16) {0})
.setUidRetrKey(ByteArray(16) {0})
.setSecurityOptions(
randomIdActive = false,
secureMessagingActive = false,
auth0 = MifareUltralightAesConfigChange.AUTH0_DEFAULT
)
.setProtectionOptions(
protectReads = false,
lockUserConfig = false,
counter2IncrementWithoutAuthEnabled = false,
counter2ReadWithoutAuthEnabled = false,
vctId = 0x05,
authLim = 0
)
.build()
.write(authenticatedNfcA)

writePages(authenticatedNfcA, 0x04, ByteArray(35 * 4) { 0 })
}

private fun encode(nfca: AbstractNfcA, keySet: Mf0aesKeySet): String {
var uid = UidHelper(nfca).readUid()
if (uid[0] == 0x08.toByte()) {
Expand Down Expand Up @@ -120,18 +170,18 @@ class PretixMf0aes(val keySets: List<Mf0aesKeySet>, val useRandomIdForNewTags: B
.setDataProtKey(diversifiedKey)
.setUidRetrKey(keySet.uidKey)
.setSecurityOptions(
useRandomIdForNewTags,
true,
randomIdActive = useRandomIdForNewTags,
secureMessagingActive = true,
// Don't write-protect chip in debug mode so it can be easily recovered and reused
if (debug) MifareUltralightAesConfigChange.AUTH0_DEFAULT else 0x04
auth0 = if (debug) MifareUltralightAesConfigChange.AUTH0_DEFAULT else 0x04
)
.setProtectionOptions(
false,
false,
false,
false,
0x05,
256
protectReads = false,
lockUserConfig = false,
counter2IncrementWithoutAuthEnabled = false,
counter2ReadWithoutAuthEnabled = false,
vctId = 0x05,
authLim = 256
)
.build()
.write(nfca)
Expand Down