Michael Micsen Johannessen Wehus f3c269bb0d Add some more sample tags
2026-01-24 08:09:27 +01:00
2026-01-24 08:09:04 +01:00

Smartair data format

The intention of this repo is to document how the data format of cards are in SmartAir

The installation gets programmed with an "Entry point" to the User sector in the card using the programming tool.

The rest is defined by the data in the card.

User sector format

X 0xX0 0xX1 0xX2 0xX3 0xX4 0xX5 0xX6 0xX7 0xX8 0xX9 0xXA 0xXB 0xXC 0xXD 0xXE 0xXF
0x0X Card Config LICSENSE? SITE ID .. .. .. ? User ID .. 00 Encoding Time .. .. .. 00 Valid From
0x1X .. .. Valid Until .. .. Pin code .. .. CardConfig UOC Block ADDR .. .. Grants .. .. ..
0x2X 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Decoded

CardConfig:

[Enchanced encryptage info](Enhanced Encryptage.md)

0: Enhanced encryptage 
1: ?
2: ?
3: ?
4: ?
5: ?
6: ?
7: ?

Licsense? We don't know but we assume it's config based on the licsense given from Tesa

SiteID: The site id which is embedded in the licsense from Tesa

UserID: A 2 Byte sequential increasing number which increases for each cardholder added in the TS1000 software

Encoding time 4 Bytes with 1 minute accuracy

Valid from/until: 3 Byte dates with 10 minute resolution

Time formats

Year  = 2000 + uint7(Bit 0-6)
Month = uint4(7-9)
Day   = uint5(11-15)
Hour  = uint4(16-20)

Minutes can be with 10 or 1 minute resolution 1 minute is used for encoding time while 10 for valid from/to

Minutes *10 = uint3(21-24[23 if low accuracy])
Minutes *1  = uint3(25-27)

Cyberchef decoder:

Some issues with minutes handling will likely fix later but for now not a priority

[{"op":"From Hex","args":["Auto"]},{"op":"To Binary","args":["None",8]},{"op":"Regular expression","args":["User defined","^([0|1]{7})([0|1]{4})([0|1]{5})([0|1]{4})(([0|1]{4})|([0|1]{3})([0|1]{4}).*)$",true,true,false,false,false,false,"List capture groups"]},{"op":"Find / Replace","args":[{"option":"Regex","string":"([0|1]{8}\\n)"},"\\n",true,false,true,false]},{"op":"Find / Replace","args":[{"option":"Regex","string":"(undefined\\n)"},"",true,false,false,false]},{"op":"Fork","args":["\\n",",",false]},{"op":"From Binary","args":["Space",8]},{"op":"To Decimal","args":["Space",false]},{"op":"Merge","args":[true]},{"op":"Find / Replace","args":[{"option":"Regex","string":"^(.*)$"},"Year,Month,Day,Hour,Minute*10,Minute*1\\n$1",true,false,true,false]},{"op":"To Table","args":[",","\\r\\n",false,"ASCII"]}]

PinCode: 3 bytes with the users pin code terminated with FF if the pin is only 4 digits

Card Config(0x18): Seems to act somewhat like "User flags" or similar

0: ?
1: Disabled user(Extended opening time)
2: ?
3: Audit 1?
4: ?
5: ?
6: Audit 2?
7: ?

Audit 1/2 are assumptions they seem to be related to the "Cardholder collects audit trail" and "Do not open if audit is full"

UOC Block:

Reversed endianess of the location where the Update on card config block is located

00 c0 = 00 0c = 12 = Block 0 Sector 3

Grants: Each grant is assigned a bit position so a reader configured to accept grants just checks expirations of the card and that the bit configured has been set on the card presented used for things like Pool access, Elevator floors or other generic functions you want to allow many people with a credential to do without keeping a big locking plan in the lock

Mifare KEYS

For mifare classic the cards use a Site Specific key as keyA the last 4 bytes of the key is the SiteID and the readers auth with KeyA making it possible to mint a valid credential by using mfkey32 on a reader.

key B is static and the same across all sites E7 31 68 53 E7 31

Description
No description provided
Readme 44 KiB
Languages
JavaScript 100%