@@ -234,19 +234,38 @@ class CardReaderNFC: @unchecked CardReader, Loggable {
234234 }
235235 return ( tlvEnc, tlvRes, tlvMac)
236236 }
237-
237+ // swiftlint:disable cyclomatic_complexity
238238 func transmit( _ apduData: Bytes ) async throws -> ( responseData: Bytes , sw: UInt16 ) {
239239 CardReaderNFC . logger ( ) . info ( " Plain >: \( apduData. toHex) " )
240240 guard let apdu = NFCISO7816APDU ( data: Data ( apduData) ) else {
241241 throw IdCardInternalError . invalidAPDU
242242 }
243243 _ = SSC . increment ( )
244- let DO87 = try getDO87 ( apdu)
245- let DO97 = try getDO97 ( apdu)
244+ let DO87 : Data
245+ if let data = apdu. data, !data. isEmpty {
246+ let ivValue = try AES . CBC ( key: ksEnc) . encrypt ( SSC)
247+ let encData = try AES . CBC ( key: ksEnc, ivVal: ivValue) . encrypt ( data. addPadding ( ) )
248+ if apdu. instructionCode & 0x01 == 0 {
249+ DO87 = TLV ( tag: 0x87 , bytes: [ 0x01 ] + encData) . data
250+ } else {
251+ DO87 = TLV ( tag: 0x85 , bytes: encData) . data
252+ }
253+ } else {
254+ DO87 = Data ( )
255+ }
256+ let DO97 : Data
257+ if apdu. expectedResponseLength > 0 {
258+ DO97 = TLV (
259+ tag: 0x97 ,
260+ bytes: [ UInt8 ( apdu. expectedResponseLength == 256 ? 0 : apdu. expectedResponseLength) ]
261+ ) . data
262+ } else {
263+ DO97 = Data ( )
264+ }
246265 let cmdHeader : Bytes = [ apdu. instructionClass | 0x0C , apdu. instructionCode, apdu. p1Parameter, apdu. p2Parameter]
247- let MValue = cmdHeader. addPadding ( ) + DO87 + DO97
248- let NValue = SSC + MValue
249- let mac = try AES . CMAC ( key: ksMac) . authenticate ( bytes: NValue . addPadding ( ) )
266+ let mVal = cmdHeader. addPadding ( ) + DO87 + DO97
267+ let nVal = SSC + mVal
268+ let mac = try AES . CMAC ( key: ksMac) . authenticate ( bytes: nVal . addPadding ( ) )
250269 let DO8E = TLV ( tag: 0x8E , bytes: mac) . data
251270 let send = DO87 + DO97 + DO8E
252271 let response = try await tag. sendCommand (
@@ -257,26 +276,39 @@ class CardReaderNFC: @unchecked CardReader, Loggable {
257276 data: send,
258277 leByte: 256
259278 )
260- let ( tlvEnc, tlvRes, tlvMac) = try getTLVs ( response)
279+ var tlvEnc : TKTLVRecord ?
280+ var tlvRes : TKTLVRecord ?
281+ var tlvMac : TKTLVRecord ?
282+ for tlv in TLV . sequenceOfRecords ( from: response) ?? [ ] {
283+ switch tlv. tag {
284+ case 0x85 , 0x87 : tlvEnc = tlv
285+ case 0x99 : tlvRes = tlv
286+ case 0x8E : tlvMac = tlv
287+ default : print ( " Unknown tag " )
288+ }
289+ }
261290 guard let tlvRes else {
262291 throw IdCardInternalError . missingRESTag
263292 }
264293 guard let tlvMac else {
265294 throw IdCardInternalError . missingMACTag
266295 }
267- let KValue = SSC . increment ( ) + ( tlvEnc? . data ?? Data ( ) ) + tlvRes. data
268- if try Data ( AES . CMAC ( key: ksMac) . authenticate ( bytes: KValue . addPadding ( ) ) ) != tlvMac. value {
296+ let kVal = SSC . increment ( ) + ( tlvEnc? . data ?? Data ( ) ) + tlvRes. data
297+ if try Data ( AES . CMAC ( key: ksMac) . authenticate ( bytes: kVal . addPadding ( ) ) ) != tlvMac. value {
269298 throw IdCardInternalError . invalidMACValue
270299 }
271300 guard let tlvEnc else {
272301 CardReaderNFC . logger ( ) . info ( " Plain <: \( tlvRes. value. toHex) " )
273302 return ( . init( ) , UInt16 ( tlvRes. value [ 0 ] , tlvRes. value [ 1 ] ) )
274303 }
275304 let ivValue = try AES . CBC ( key: ksEnc) . encrypt ( SSC)
276- let responseData = try ( try AES . CBC ( key: ksEnc, ivVal: ivValue) . decrypt ( tlvEnc. value [ 1 ... ] ) ) . removePadding ( )
277- CardReaderNFC . logger ( ) . info ( " Plain <: \( responseData. toHex) \( tlvRes. value. toHex) " )
305+ let responseData = try ( try AES . CBC ( key: ksEnc, ivVal: ivValue)
306+ . decrypt ( tlvEnc. tag == 0x85 ? tlvEnc. value : tlvEnc. value [ 1 ... ] ) )
307+ . removePadding ( )
308+ CardReaderNFC . logger ( ) . debug ( " Plain <: \( responseData. toHex) \( tlvRes. value. toHex) " )
278309 return ( Bytes ( responseData) , UInt16 ( tlvRes. value [ 0 ] , tlvRes. value [ 1 ] ) )
279310 }
311+ // swiftlint:enable cyclomatic_complexity
280312
281313 // MARK: - Utils
282314
0 commit comments