fix little endian vs big endian in the macros... again... but this time correct
[RRG-proxmark3.git] / client / src / cmdhfseos.c
blob6de8ad89a30bbfbaafe13aaf8ba45b7a1e87f733
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2021 iceman
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // SEOS commands
9 //-----------------------------------------------------------------------------
10 #include "cmdhfseos.h"
11 #include <stdio.h>
12 #include <string.h>
13 #include <ctype.h> // tolower
14 #include "cliparser.h"
15 #include "cmdparser.h" // command_t
16 #include "comms.h" // clearCommandBuffer
17 #include "cmdtrace.h"
18 #include "crc16.h"
19 #include "ui.h"
20 #include "cmdhf14a.h" // manufacture
21 #include "protocols.h" // definitions of ISO14A/7816 protocol
22 #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
23 #include "crypto/asn1utils.h" // ASN1 decode / print
25 static int CmdHelp(const char *Cmd);
27 static uint16_t get_sw(uint8_t *d, uint8_t n) {
28 if (n < 2)
29 return 0;
31 n -= 2;
32 return d[n] * 0x0100 + d[n + 1];
35 static int seos_select(void) {
36 bool activate_field = true;
37 bool keep_field_on = true;
38 uint8_t response[PM3_CMD_DATA_SIZE];
39 int resplen = 0;
41 // --------------- Select SEOS applet ----------------
42 uint8_t aSELECT_AID[80];
43 int aSELECT_AID_n = 0;
44 param_gethex_to_eol("00a404000aa000000440000101000100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
45 int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
46 if (res != PM3_SUCCESS) {
47 DropField();
48 return res;
51 if (resplen < 2) {
52 DropField();
53 return PM3_ESOFT;
56 uint16_t sw = get_sw(response, resplen);
57 if (sw != 0x9000) {
58 PrintAndLogEx(ERR, "Selecting SEOS applet aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
59 DropField();
60 return PM3_ESOFT;
63 activate_field = false;
64 keep_field_on = false;
65 // --------------- CC file reading ----------------
67 uint8_t aSELECT_FILE_ADF[30];
68 int aSELECT_FILE_ADF_n = 0;
69 param_gethex_to_eol("80a504001306112b0601040181e43801010201180101020200", 0, aSELECT_FILE_ADF, sizeof(aSELECT_FILE_ADF), &aSELECT_FILE_ADF_n);
70 res = ExchangeAPDU14a(aSELECT_FILE_ADF, aSELECT_FILE_ADF_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
71 if (res != PM3_SUCCESS) {
72 DropField();
73 return res;
76 sw = get_sw(response, resplen);
77 if (sw != 0x9000) {
78 PrintAndLogEx(ERR, "Selecting ADF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
79 DropField();
80 return PM3_ESOFT;
83 // remove the 2byte SW
84 asn1_print(response, resplen - 2, " ");
85 return PM3_SUCCESS;
88 int infoSeos(bool verbose) {
89 int res = seos_select();
90 if (res == PM3_SUCCESS) {
91 PrintAndLogEx(NORMAL, "");
92 PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
94 return PM3_SUCCESS;
97 static int CmdHfSeosInfo(const char *Cmd) {
98 CLIParserContext *ctx;
99 CLIParserInit(&ctx, "hf seos info",
100 "Get info from SEOS tags",
101 "hf seos info");
103 void *argtable[] = {
104 arg_param_begin,
105 arg_param_end
107 CLIExecWithReturn(ctx, Cmd, argtable, true);
108 CLIParserFree(ctx);
109 return infoSeos(true);
112 static int CmdHfSeosList(const char *Cmd) {
113 return CmdTraceListAlias(Cmd, "hf seos", "7816");
116 static command_t CommandTable[] = {
117 {"help", CmdHelp, AlwaysAvailable, "This help"},
118 {"info", CmdHfSeosInfo, IfPm3NfcBarcode, "Tag information"},
119 {"list", CmdHfSeosList, AlwaysAvailable, "List SEOS history"},
120 {NULL, NULL, NULL, NULL}
123 static int CmdHelp(const char *Cmd) {
124 (void)Cmd; // Cmd is not used so far
125 CmdsHelp(CommandTable);
126 return PM3_SUCCESS;
129 int CmdHFSeos(const char *Cmd) {
130 clearCommandBuffer();
131 return CmdsParse(CommandTable, Cmd);