@@ -1199,6 +1199,250 @@ int emv_processing_restrictions(struct emv_ctx_t* ctx)
1199
1199
return 0 ;
1200
1200
}
1201
1201
1202
+ int emv_terminal_risk_management (struct emv_ctx_t * ctx )
1203
+ {
1204
+ int r ;
1205
+ const struct emv_tlv_t * term_floor_limit ;
1206
+ const struct emv_tlv_t * txn_amount ;
1207
+ uint32_t floor_limit_value ;
1208
+ uint32_t amount_value ;
1209
+ const struct emv_tlv_t * lower_offline_limit ;
1210
+ const struct emv_tlv_t * upper_offline_limit ;
1211
+ struct emv_tlv_list_t get_data_list = EMV_TLV_LIST_INIT ;
1212
+
1213
+ if (!ctx ) {
1214
+ emv_debug_trace_msg ("ctx=%p" , ctx );
1215
+ emv_debug_error ("Invalid parameter" );
1216
+ return EMV_ERROR_INVALID_PARAMETER ;
1217
+ }
1218
+ if (!ctx -> tvr || !ctx -> tsi ) {
1219
+ emv_debug_trace_msg ("tvr=%p, tsi=%p" , ctx -> tvr , ctx -> tsi );
1220
+ emv_debug_error ("Invalid context variable" );
1221
+ return EMV_ERROR_INVALID_PARAMETER ;
1222
+ }
1223
+
1224
+ // Ensure mandatory configuration fields are present and have valid length
1225
+ term_floor_limit = emv_tlv_list_find_const (& ctx -> config , EMV_TAG_9F1B_TERMINAL_FLOOR_LIMIT );
1226
+ if (!term_floor_limit || term_floor_limit -> length != 4 ) {
1227
+ emv_debug_trace_msg ("term_floor_limit=%p, term_floor_limit->length=%u" ,
1228
+ term_floor_limit , term_floor_limit ? term_floor_limit -> length : 0 );
1229
+ emv_debug_error ("Terminal Floor Limit (9F1B) not found or invalid" );
1230
+ return EMV_ERROR_INVALID_CONFIG ;
1231
+ }
1232
+
1233
+ // Ensure mandatory transaction parameters are present and have valid length
1234
+ txn_amount = emv_tlv_list_find_const (& ctx -> params , EMV_TAG_81_AMOUNT_AUTHORISED_BINARY );
1235
+ if (!txn_amount || txn_amount -> length != 4 ) {
1236
+ emv_debug_trace_msg ("txn_amount=%p, txn_amount->length=%u" ,
1237
+ txn_amount , txn_amount ? txn_amount -> length : 0 );
1238
+ emv_debug_error ("Amount, Authorised - Binary (81) not found or invalid" );
1239
+ return EMV_ERROR_INVALID_PARAMETER ;
1240
+ }
1241
+
1242
+ // Mandatory fields are present for terminal risk management to proceed
1243
+ ctx -> tsi -> value [0 ] |= EMV_TSI_TERMINAL_RISK_MANAGEMENT_PERFORMED ;
1244
+
1245
+ // Floor Limits
1246
+ // See EMV 4.4 Book 3, 10.6.1
1247
+ r = emv_format_b_to_uint (
1248
+ term_floor_limit -> value ,
1249
+ term_floor_limit -> length ,
1250
+ & floor_limit_value
1251
+ );
1252
+ if (r ) {
1253
+ emv_debug_trace_msg ("emv_format_b_to_uint() failed; r=%d" , r );
1254
+
1255
+ // Internal error; terminate session
1256
+ emv_debug_error ("Internal error" );
1257
+ return EMV_ERROR_INTERNAL ;
1258
+ }
1259
+ emv_debug_trace_msg ("Terminal Floor Limit value is %u" , (unsigned int )floor_limit_value );
1260
+ r = emv_format_b_to_uint (
1261
+ txn_amount -> value ,
1262
+ txn_amount -> length ,
1263
+ & amount_value
1264
+ );
1265
+ if (r ) {
1266
+ emv_debug_trace_msg ("emv_format_b_to_uint() failed; r=%d" , r );
1267
+
1268
+ // Internal error; terminate session
1269
+ emv_debug_error ("Internal error" );
1270
+ return EMV_ERROR_INTERNAL ;
1271
+ }
1272
+ emv_debug_trace_msg ("Amount, Authorised (Binary) value is %u" , (unsigned int )amount_value );
1273
+ if (amount_value >= floor_limit_value ) {
1274
+ emv_debug_info ("Floor limit exceeded" );
1275
+ ctx -> tvr -> value [3 ] |= EMV_TVR_TXN_FLOOR_LIMIT_EXCEEDED ;
1276
+ } else {
1277
+ emv_debug_info ("Floor limit not exceeded" );
1278
+ ctx -> tvr -> value [3 ] &= ~EMV_TVR_TXN_FLOOR_LIMIT_EXCEEDED ;
1279
+ }
1280
+
1281
+ // Velocity Checking
1282
+ // See EMV 4.4 Book 3, 10.6.3
1283
+ lower_offline_limit = emv_tlv_list_find_const (& ctx -> icc , EMV_TAG_9F14_LOWER_CONSECUTIVE_OFFLINE_LIMIT );
1284
+ upper_offline_limit = emv_tlv_list_find_const (& ctx -> icc , EMV_TAG_9F23_UPPER_CONSECUTIVE_OFFLINE_LIMIT );
1285
+ if (lower_offline_limit && lower_offline_limit -> length == 1 &&
1286
+ upper_offline_limit && upper_offline_limit -> length == 1
1287
+ ) {
1288
+ const struct emv_tlv_t * atc ;
1289
+ uint32_t atc_value ;
1290
+ const struct emv_tlv_t * last_online_atc ;
1291
+ uint32_t last_online_atc_value ;
1292
+
1293
+ // Retrieve Application Transaction Counter (9F36)
1294
+ r = emv_tal_get_data (
1295
+ ctx -> ttl ,
1296
+ EMV_TAG_9F36_APPLICATION_TRANSACTION_COUNTER ,
1297
+ & get_data_list
1298
+ );
1299
+ if (r ) {
1300
+ emv_debug_trace_msg ("emv_tal_get_data() failed; r=%d" , r );
1301
+ emv_debug_error ("Failed to retrieve Application Transaction Counter (9F36)" );
1302
+
1303
+ if (r < 0 ) {
1304
+ if (r == EMV_TAL_ERROR_INTERNAL || r == EMV_TAL_ERROR_INVALID_PARAMETER ) {
1305
+ r = EMV_ERROR_INTERNAL ;
1306
+ } else {
1307
+ // All other GET DATA errors are card errors
1308
+ r = EMV_OUTCOME_CARD_ERROR ;
1309
+ }
1310
+ goto exit ;
1311
+ }
1312
+
1313
+ // Otherwise continue processing
1314
+ }
1315
+ atc = emv_tlv_list_find_const (& get_data_list , EMV_TAG_9F36_APPLICATION_TRANSACTION_COUNTER );
1316
+ if (atc ) {
1317
+ r = emv_format_b_to_uint (
1318
+ atc -> value ,
1319
+ atc -> length ,
1320
+ & atc_value
1321
+ );
1322
+ if (r ) {
1323
+ emv_debug_trace_msg ("emv_format_b_to_uint() failed; r=%d" , r );
1324
+
1325
+ // Internal error; terminate session
1326
+ emv_debug_error ("Internal error" );
1327
+ r = EMV_ERROR_INTERNAL ;
1328
+ goto exit ;
1329
+ }
1330
+
1331
+ emv_debug_trace_msg ("ATC value is %u" , atc_value );
1332
+ }
1333
+
1334
+ // Retrieve Last Online ATC Register (9F13)
1335
+ r = emv_tal_get_data (
1336
+ ctx -> ttl ,
1337
+ EMV_TAG_9F13_LAST_ONLINE_ATC_REGISTER ,
1338
+ & get_data_list
1339
+ );
1340
+ if (r ) {
1341
+ emv_debug_trace_msg ("emv_tal_get_data() failed; r=%d" , r );
1342
+ emv_debug_error ("Failed to retrieve Last Online ATC Register (9F13)" );
1343
+
1344
+ if (r < 0 ) {
1345
+ if (r == EMV_TAL_ERROR_INTERNAL || r == EMV_TAL_ERROR_INVALID_PARAMETER ) {
1346
+ r = EMV_ERROR_INTERNAL ;
1347
+ } else {
1348
+ // All other GET DATA errors are card errors
1349
+ r = EMV_OUTCOME_CARD_ERROR ;
1350
+ }
1351
+ goto exit ;
1352
+ }
1353
+
1354
+ // Otherwise continue processing
1355
+ }
1356
+ last_online_atc = emv_tlv_list_find_const (& get_data_list , EMV_TAG_9F13_LAST_ONLINE_ATC_REGISTER );
1357
+ if (last_online_atc ) {
1358
+ r = emv_format_b_to_uint (
1359
+ last_online_atc -> value ,
1360
+ last_online_atc -> length ,
1361
+ & last_online_atc_value
1362
+ );
1363
+ if (r ) {
1364
+ emv_debug_trace_msg ("emv_format_b_to_uint() failed; r=%d" , r );
1365
+
1366
+ // Internal error; terminate session
1367
+ emv_debug_error ("Internal error" );
1368
+ r = EMV_ERROR_INTERNAL ;
1369
+ goto exit ;
1370
+ }
1371
+
1372
+ emv_debug_trace_msg ("Last Online ATC value is %u" , last_online_atc_value );
1373
+ }
1374
+
1375
+ // If both ATC and Last Online ATC are available, and offline
1376
+ // transaction attempts have happened since the previous online
1377
+ // authorisation, apply issuer velocity limits
1378
+ if (atc && last_online_atc &&
1379
+ atc_value > last_online_atc_value
1380
+ ) {
1381
+ // Check velocity limits
1382
+ // See EMV 4.4 Book 3, 10.6.3
1383
+ if (atc_value - last_online_atc_value > lower_offline_limit -> value [0 ]) {
1384
+ emv_debug_info ("Lower Consecutive Offline Limits exceeded" );
1385
+ ctx -> tvr -> value [3 ] |= EMV_TVR_LOWER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1386
+ } else {
1387
+ emv_debug_info ("Lower Consecutive Offline Limits not exceeded" );
1388
+ ctx -> tvr -> value [3 ] &= ~EMV_TVR_LOWER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1389
+ }
1390
+ if (atc_value - last_online_atc_value > upper_offline_limit -> value [0 ]) {
1391
+ emv_debug_info ("Upper Consecutive Offline Limits exceeded" );
1392
+ ctx -> tvr -> value [3 ] |= EMV_TVR_UPPER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1393
+ } else {
1394
+ emv_debug_info ("Upper Consecutive Offline Limits not exceeded" );
1395
+ ctx -> tvr -> value [3 ] &= ~EMV_TVR_UPPER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1396
+ }
1397
+
1398
+ } else {
1399
+ // Unable to apply velocity checking
1400
+ // See EMV 4.4 Book 3, 10.6.3
1401
+ emv_debug_info ("Velocity checking not possible. Assume both Consecutive Offline Limits exceeded." );
1402
+ ctx -> tvr -> value [3 ] |= EMV_TVR_LOWER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1403
+ ctx -> tvr -> value [3 ] |= EMV_TVR_UPPER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1404
+ }
1405
+
1406
+ // Check for new card
1407
+ // See EMV 4.4 Book 3, 10.6.3
1408
+ if (last_online_atc && last_online_atc_value == 0 ) {
1409
+ emv_debug_info ("New card" );
1410
+ ctx -> tvr -> value [1 ] |= EMV_TVR_NEW_CARD ;
1411
+ } else {
1412
+ ctx -> tvr -> value [1 ] &= ~EMV_TVR_NEW_CARD ;
1413
+ }
1414
+
1415
+ } else {
1416
+ // If not present, skip velocity checking
1417
+ // See EMV 4.4 Book 3, 10.6.3
1418
+ // See EMV 4.4 Book 3, 7.3
1419
+ emv_debug_trace_msg ("One or both Consecutive Offline Limits (9F14 or 9F23) not found" );
1420
+ emv_debug_info ("ICC does not support velocity checking" );
1421
+ ctx -> tvr -> value [1 ] &= ~EMV_TVR_NEW_CARD ;
1422
+ ctx -> tvr -> value [3 ] &= ~EMV_TVR_LOWER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1423
+ ctx -> tvr -> value [3 ] &= ~EMV_TVR_UPPER_CONSECUTIVE_OFFLINE_LIMIT_EXCEEDED ;
1424
+ }
1425
+
1426
+ // Append GET DATA output to ICC data list
1427
+ r = emv_tlv_list_append (& ctx -> icc , & get_data_list );
1428
+ if (r ) {
1429
+ emv_debug_trace_msg ("emv_tlv_list_append() failed; r=%d" , r );
1430
+
1431
+ // Internal error; terminate session
1432
+ emv_debug_error ("Internal error" );
1433
+ r = EMV_ERROR_INTERNAL ;
1434
+ goto exit ;
1435
+ }
1436
+
1437
+ // Success
1438
+ r = 0 ;
1439
+ goto exit ;
1440
+
1441
+ exit :
1442
+ emv_tlv_list_clear (& get_data_list );
1443
+ return r ;
1444
+ }
1445
+
1202
1446
int emv_card_action_analysis (struct emv_ctx_t * ctx )
1203
1447
{
1204
1448
int r ;
0 commit comments