User Tools

Site Tools


cvend

This is an old revision of the document!


cVEND NFC Reader

cVEND is the NFC reader on the bottom half of the PM3

cvend_plug.pdf

The associated serial device appears to be at /dev/ttymxc3 in Linux.

cVEND protocol notes

Boot-up / initialization logic analyzer trace (open with the Saleae app):

cvend-bootup.sal

IPP packet structure

offset length name description
0 1 always 0xBC
1 1 seq monotonically increasing from 1; skips 0 when rolling over
2 1 unknown, usually 0
3 1 msgType
4 2 msgLen length of msgData
6 1 hdrCRC CRC-8-Dallas/Maxim over previous 6 bytes
7 msgLen msgData message payload, structure depends on msgType
7+msgLen 4 msgCRC little endian inverted IEEE CRC-32 over msgData, iff msgType & 0x80

IPP message types

msgType dir name description
0x02 Version
0x03 VersionReply (device ID from rockchip otp, firmware version, cwd) as length-prefixed strings
e.g. “\x18\x00\xdd\xf5\x14cS01.05.46-49.00-2-2\x0502.35\n/home/app0”
0x04 Status
0x05 StatusReply e.g. “\x00\x00”
0x07 Heartbeat sent periodically by reader
0x0f Startup sent by reader after startup, approx 1 minute after power on, e.g. “\x00”
0x10 Reset
0x11 ResetReply
0x20 Leds sets LED status, u32 bitmap; the only two externally visible LEDs on the PM3 are “\x00\x00\x00\x40” and “\x00\x00\x00\x80”
0x22 Buzzer makes the cvend beep; u16 frequency, u16 duration. e.g. “\x06\x00\x01\x00”
0x32 unknown, registered in ProxCardCtrl::ProxCardCtrl(RFIDReader&)
0x46 unknown, registered in ProxCardCtrl::ProxCardCtrl(RFIDReader&)
0x96 PutFile
0x97 PutFileReply
0x98 GetFile
0x99 GetFileReply
0x9a DeleteFile
0x9b DeleteFileReply
0x9c FileInfo
0x9d FileInfoReply
0xa4 FileList
0xa5 FileListReply
0xaa SetTime
0xab SetTimeReply
0xac ITSOData conditionally registered in ItsoIppHandler::_handleItsoCtrlReq(CommBuffer&, IppHeader const&, unsigned char const*)
0xad ITSODataReply
0xae ITSOCtrl registered in ItsoIppHandler::ItsoIppHandler(ProxCardItso&)
0xaf ITSOCtrlReply
0xb1 ISORead sent by reader when ISO14443A card presented, after enabling Iso with 0xe4
card UID at offset 2
0xb4 APDUProx registered in ProxCardCtrl::ProxCardCtrl(RFIDReader&)
0xb5 APDUProxReply
0xb6 SAMCtrl registered in SamCtrl::SamCtrl()
0xb7 SAMCtrlReply
0xb9 DESFireRead sent by reader when DESFire card presented, after enabling DESFire with 0xe4
0xba unknown, registered in ProxCardDesfire::ProxCardDesfire(RFIDReader&)
0xbc unknown, registered in ProxCardDesfire::ProxCardDesfire(RFIDReader&)
0xbe PICCRead sent by reader when a card is read, containing UID, historical bytes, and other data
0xce unknown, registered in IppHandling::IppHandling()
0xd0 unknown, registered in EmvIppHandler::EmvIppHandler()
0xd1 EMVTransactionSuccessUnk sent by reader after startup and certain nfc state changes, format and semantics not yet understood
0xd4 unknown, registered in ProxCardUltralightC::ProxCardUltralightC(RFIDReader&)
0xe4 ProxCardFunction first 2 bytes specify function (4=VdvKa, 5=MifareClassic, 6=Iso, 7=Desfire, 8=Girogo, 9=Itso, 10=UltralightC), remaining bytes unknown
00070101 sent by PM3 to enable DESFire reading at startup
0xe5 ProxCardFunctionReply
0xe6 unknown, registered in GirogoIppHandler::GirogoIppHandler(RFIDReader&, ProxCardGirogo*)
0xe8 SecurityServices first byte selects subcommand (0=GetVersionOfKey, 1=RemoveX509Cert, 2=RemoveKeyBlock, 3=ImportX509Cert, 4=ExportX509Cert, 5=ImportKeyBlock, 6=ExportKeyBlock, 7=GenerateKSKPair), remaining bytes unknown
0xe9 SecurityServicesReply
0xea unknown, registered in ProxCardMifareClassic::ProxCardMifareClassic(RFIDReader&)
0xed Log human-readable log message from reader

→ - Host to Reader
← - Reader to Host

Reader -> Host

packet type 0xED seems to be a log message:

\xBC\xB9\0\xED\0h\xB6\x0306:48:13 Error: feclr_transceive() failed: error: 0, status: 0x00000008 

0xB9 - card read?

Host -> reader

0xBC - appears after every read (ack of some sort?)

Card read flow

R: BCB600B9000BBB0C000000048A6EF29B149079CB8CF0
H: BC2200BC000158602A714F60           # DESFire GetVersion (60)
R: BCB722BD001E3D00000401013300160504010103001605048A6EF29B149020487330305022C98C7E9B
H: BC2300BC0004AA5A2BC3F911A8A56A     # DESFire SelectApplication (5A 2BC3F9)
R: BCB823BD0002E301FDE0523164

Another one (same payloads as previous but with different seq/hdrCRC):

R:  BCBF00B9000B480C000000048A6EF29B149079CB8CF0
H:  BC2400BC0001C4602A714F60
R:  BCC024BD001E0800000401013300160504010103001605048A6EF29B149020487330305022C98C7E9B
H:  BC2500BC0004365A2BC3F911A8A56A
R:  BCC125BD00027401FDE0523164

Sample log message:

BCB000ED0068450330363A34383A3038204572726F723A206665636C725F7472616E7363656976652829206661696C65643A206572726F723A20302C207374617475733A2030783030303030303038200A205B524649445265616465724D756C74694170702E6370703A3135395D0002CD1533BCB100ED0046B40130363A34383A3038207472616E7363656976652065
00000000  bc b0 00 ed 00 68 45 03 30 36 3a 34 38 3a 30 38  |¼°.í.hE.06:48:08|
00000010  20 45 72 72 6f 72 3a 20 66 65 63 6c 72 5f 74 72  | Error: feclr_tr|
00000020  61 6e 73 63 65 69 76 65 28 29 20 66 61 69 6c 65  |ansceive() faile|
00000030  64 3a 20 65 72 72 6f 72 3a 20 30 2c 20 73 74 61  |d: error: 0, sta|
00000040  74 75 73 3a 20 30 78 30 30 30 30 30 30 30 38 20  |tus: 0x00000008 |
00000050  0a 20 5b 52 46 49 44 52 65 61 64 65 72 4d 75 6c  |. [RFIDReaderMul|
00000060  74 69 41 70 70 2e 63 70 70 3a 31 35 39 5d 00 02  |tiApp.cpp:159]..|
00000070  cd 15 33 bc b1 00 ed 00 46 b4 01 30 36 3a 34 38  |Í.3¼±.í.F´.06:48|
00000080  3a 30 38 20 74 72 61 6e 73 63 65 69 76 65 20 65  |:08 transceive e|

There are 4 bytes appended at the end of some messages (presumably those with ID LSB=1, if the Rust struct description is accurate?) which is not a CRC32 with any polynomial I recognize, but a CRC32 of (message + CRC) is always 0xFFFFFFFF. These 4 bytes are NOT included in the length.

The checksum is _appended_, as can be seen by it following the log message (after the final \0).

is it a _little endian_, _bit negated_ CRC32. Which is weird because the length is big endian?..

* Host only sends two types of messages after initialization - both of type 0xBC. One is length 1 and the body is always 0x60 (+ negated CRC 2A714F60), the other is of length 4 and the body is always 5A2BC3F9 (+ negated-CRC 11A8A56A)

cvend.1772281633.txt.gz · Last modified: by doof