]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdanalyse.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2016 iceman
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
7 //-----------------------------------------------------------------------------
8 // Analyse bytes commands
9 //-----------------------------------------------------------------------------
10 #include "cmdanalyse.h"
12 static int CmdHelp ( const char * Cmd
);
14 int usage_analyse_lcr ( void ) {
15 PrintAndLog ( "Specifying the bytes of a UID with a known LRC will find the last byte value" );
16 PrintAndLog ( "needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX." );
18 PrintAndLog ( "Usage: analyse lcr [h] <bytes>" );
19 PrintAndLog ( "Options:" );
20 PrintAndLog ( " h This help" );
21 PrintAndLog ( " <bytes> bytes to calc missing XOR in a LCR" );
23 PrintAndLog ( "Samples:" );
24 PrintAndLog ( " analyse lcr 04008064BA" );
25 PrintAndLog ( "expected output: Target (BA) requires final LRC XOR byte value: 5A" );
29 int usage_analyse_checksum ( void ) {
30 PrintAndLog ( "The bytes will be added with eachother and than limited with the applied mask" );
31 PrintAndLog ( "Finally compute ones' complement of the least significant bytes" );
33 PrintAndLog ( "Usage: analyse chksum [h] b <bytes> m <mask>" );
34 PrintAndLog ( "Options:" );
35 PrintAndLog ( " h This help" );
36 PrintAndLog ( " b <bytes> bytes to calc missing XOR in a LCR" );
37 PrintAndLog ( " m <mask> bit mask to limit the outpuyt" );
39 PrintAndLog ( "Samples:" );
40 PrintAndLog ( " analyse chksum b 137AF00A0A0D m FF" );
41 PrintAndLog ( "expected output: 0x61" );
45 int usage_analyse_crc ( void ){
46 PrintAndLog ( "A stub method to test different crc implementations inside the PM3 sourcecode. Just because you figured out the poly, doesn't mean you get the desired output" );
48 PrintAndLog ( "Usage: analyse crc [h] <bytes>" );
49 PrintAndLog ( "Options:" );
50 PrintAndLog ( " h This help" );
51 PrintAndLog ( " <bytes> bytes to calc crc" );
53 PrintAndLog ( "Samples:" );
54 PrintAndLog ( " analyse crc 137AF00A0A0D" );
58 static uint8_t calculateLRC ( uint8_t * bytes
, uint8_t len
) {
60 for ( uint8_t i
= 0 ; i
< len
; i
++)
65 static uint8_t calcSumCrumbAdd ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
67 for ( uint8_t i
= 0 ; i
< len
; i
++) {
68 sum
+= CRUMB ( bytes
[ i
], 0 );
69 sum
+= CRUMB ( bytes
[ i
], 2 );
70 sum
+= CRUMB ( bytes
[ i
], 4 );
71 sum
+= CRUMB ( bytes
[ i
], 6 );
76 static uint8_t calcSumCrumbAddOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
77 return ~ calcSumCrumbAdd ( bytes
, len
, mask
);
79 static uint8_t calcSumNibbleAdd ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
81 for ( uint8_t i
= 0 ; i
< len
; i
++) {
82 sum
+= NIBBLE_LOW ( bytes
[ i
]);
83 sum
+= NIBBLE_HIGH ( bytes
[ i
]);
88 static uint8_t calcSumNibbleAddOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
){
89 return ~ calcSumNibbleAdd ( bytes
, len
, mask
);
92 static uint8_t calcSumByteAdd ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
94 for ( uint8_t i
= 0 ; i
< len
; i
++)
100 static uint8_t calcSumByteAddOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
101 return ~ calcSumByteAdd ( bytes
, len
, mask
);
104 static uint8_t calcSumByteSub ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
106 for ( uint8_t i
= 0 ; i
< len
; i
++)
111 static uint8_t calcSumByteSubOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
){
112 return ~ calcSumByteSub ( bytes
, len
, mask
);
114 static uint8_t calcSumNibbleSub ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
116 for ( uint8_t i
= 0 ; i
< len
; i
++) {
117 sum
-= NIBBLE_LOW ( bytes
[ i
]);
118 sum
-= NIBBLE_HIGH ( bytes
[ i
]);
123 static uint8_t calcSumNibbleSubOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
124 return ~ calcSumNibbleSub ( bytes
, len
, mask
);
127 int CmdAnalyseLCR ( const char * Cmd
) {
129 char cmdp
= param_getchar ( Cmd
, 0 );
130 if ( strlen ( Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H' ) return usage_analyse_lcr ();
133 param_gethex_ex ( Cmd
, 0 , data
, & len
);
134 if ( len
% 2 ) return usage_analyse_lcr ();
136 uint8_t finalXor
= calculateLRC ( data
, len
);
137 PrintAndLog ( "Target [%02X] requires final LRC XOR byte value: 0x%02X" , data
[ len
- 1 ] , finalXor
);
140 int CmdAnalyseCRC ( const char * Cmd
) {
142 char cmdp
= param_getchar ( Cmd
, 0 );
143 if ( strlen ( Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H' ) return usage_analyse_crc ();
145 int len
= strlen ( Cmd
);
146 if ( len
& 1 ) return usage_analyse_crc ();
148 // add 1 for null terminator.
149 uint8_t * data
= malloc ( len
+ 1 );
150 if ( data
== NULL
) return 1 ;
152 if ( param_gethex ( Cmd
, 0 , data
, len
)) {
154 return usage_analyse_crc ();
158 //PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));
160 PrintAndLog ( " \n Tests of reflection. Two current methods in source code" );
161 PrintAndLog ( " reflect(0x3e23L,3) is %04X == 0x3e26" , reflect ( 0x3e23 L
, 3 ) );
162 PrintAndLog ( " SwapBits(0x3e23L,3) is %04X == 0x3e26" , SwapBits ( 0x3e23 L
, 3 ) );
163 PrintAndLog ( " 0xB400 == %04X" , reflect ( ( 1 << 16 | 0xb400 ), 16 ) );
166 // Test of CRC16, '123456789' string.
168 PrintAndLog ( " \n Tests with '123456789' string" );
169 uint8_t dataStr
[] = { 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39 };
170 uint8_t legic8
= CRC8Legic ( dataStr
, sizeof ( dataStr
));
172 PrintAndLog ( "LEGIC: CRC16: %X" , CRC16Legic ( dataStr
, sizeof ( dataStr
), legic8
));
174 //these below has been tested OK.
175 PrintAndLog ( "Confirmed CRC Implementations" );
176 PrintAndLog ( "LEGIC: CRC8 : %X (0xC6 expected)" , legic8
);
177 PrintAndLog ( "MAXIM: CRC8 : %X (0xA1 expected)" , CRC8Maxim ( dataStr
, sizeof ( dataStr
)));
178 PrintAndLog ( "DNP : CRC16: %X (0x82EA expected)" , CRC16_DNP ( dataStr
, sizeof ( dataStr
)));
179 PrintAndLog ( "CCITT: CRC16: %X (0xE5CC expected)" , CRC16_CCITT ( dataStr
, sizeof ( dataStr
)));
181 PrintAndLog ( "ICLASS org: CRC16: %X (0x expected)" , iclass_crc16 ( ( char *) dataStr
, sizeof ( dataStr
)));
182 PrintAndLog ( "ICLASS ice: CRC16: %X (0x expected)" , CRC16_ICLASS ( dataStr
, sizeof ( dataStr
)));
186 uint8_t dataStr1234
[] = { 0x1 , 0x2 , 0x3 , 0x4 };
187 PrintAndLog ( "ISO15693 org: : CRC16: %X (0xF0B8 expected)" , Iso15693Crc ( dataStr1234
, sizeof ( dataStr1234
)));
188 PrintAndLog ( "ISO15693 ice: : CRC16: %X (0xF0B8 expected)" , CRC16_Iso15693 ( dataStr1234
, sizeof ( dataStr1234
)));
193 int CmdAnalyseCHKSUM ( const char * Cmd
){
197 uint32_t mask
= 0xFF ;
200 memset ( data
, 0x0 , sizeof ( data
));
202 while ( param_getchar ( Cmd
, cmdp
) != 0x00 ) {
203 switch ( param_getchar ( Cmd
, cmdp
)) {
206 param_gethex_ex ( Cmd
, cmdp
+ 1 , data
, & len
);
207 if ( len
% 2 ) errors
= true ;
213 mask
= param_get32ex ( Cmd
, cmdp
+ 1 , 0 , 16 );
218 return usage_analyse_checksum ();
220 PrintAndLog ( "Unknown parameter '%c'" , param_getchar ( Cmd
, cmdp
));
227 if ( errors
) return usage_analyse_checksum ();
229 PrintAndLog ( " \n Byte Add | 0x%X" , calcSumByteAdd ( data
, len
, mask
));
230 PrintAndLog ( "Nibble Add | 0x%X" , calcSumNibbleAdd ( data
, len
, mask
));
231 PrintAndLog ( "Crumb Add | 0x%X" , calcSumCrumbAdd ( data
, len
, mask
));
233 PrintAndLog ( " \n Byte Subtract | 0x%X" , calcSumByteSub ( data
, len
, mask
));
234 PrintAndLog ( "Nibble Subtract | 0x%X" , calcSumNibbleSub ( data
, len
, mask
));
236 PrintAndLog ( " \n CHECKSUM - One's complement" );
237 PrintAndLog ( "Byte Add | 0x%X" , calcSumByteAddOnes ( data
, len
, mask
));
238 PrintAndLog ( "Nibble Add | 0x%X" , calcSumNibbleAddOnes ( data
, len
, mask
));
239 PrintAndLog ( "Crumb Add | 0x%X" , calcSumCrumbAddOnes ( data
, len
, mask
));
241 PrintAndLog ( "Byte Subtract | 0x%X" , calcSumByteSubOnes ( data
, len
, mask
));
242 PrintAndLog ( "Nibble Subtract | 0x%X" , calcSumNibbleSubOnes ( data
, len
, mask
));
247 int CmdAnalyseDates ( const char * Cmd
){
248 // look for datestamps in a given array of bytes
249 PrintAndLog ( "To be implemented. Feel free to contribute!" );
252 int CmdAnalyseTEASelfTest ( const char * Cmd
){
254 uint8_t v
[ 8 ], v_le
[ 8 ];
255 memset ( v
, 0x00 , sizeof ( v
));
256 memset ( v_le
, 0x00 , sizeof ( v_le
));
257 uint8_t * v_ptr
= v_le
;
259 uint8_t cmdlen
= strlen ( Cmd
);
260 cmdlen
= ( sizeof ( v
)<< 2 < cmdlen
) ? sizeof ( v
)<< 2 : cmdlen
;
262 if ( param_gethex ( Cmd
, 0 , v
, cmdlen
) > 0 ){
263 PrintAndLog ( "can't read hex chars, uneven? :: %u" , cmdlen
);
267 SwapEndian64ex ( v
, 8 , 4 , v_ptr
);
270 uint8_t key
[ 16 ] = { 0x55 , 0xFE , 0xF6 , 0x30 , 0x62 , 0xBF , 0x0B , 0xC1 , 0xC9 , 0xB3 , 0x7C , 0x34 , 0x97 , 0x3E , 0x29 , 0xFB };
272 uint8_t * key_ptr
= keyle
;
273 SwapEndian64ex ( key
, sizeof ( key
), 4 , key_ptr
);
275 PrintAndLog ( "TEST LE enc| %s" , sprint_hex ( v_ptr
, 8 ));
277 tea_decrypt ( v_ptr
, key_ptr
);
278 PrintAndLog ( "TEST LE dec | %s" , sprint_hex_ascii ( v_ptr
, 8 ));
280 tea_encrypt ( v_ptr
, key_ptr
);
281 tea_encrypt ( v_ptr
, key_ptr
);
282 PrintAndLog ( "TEST enc2 | %s" , sprint_hex_ascii ( v_ptr
, 8 ));
287 static command_t CommandTable
[] = {
288 { "help" , CmdHelp
, 1 , "This help" },
289 { "lcr" , CmdAnalyseLCR
, 1 , "Generate final byte for XOR LRC" },
290 { "crc" , CmdAnalyseCRC
, 1 , "Stub method for CRC evaluations" },
291 { "chksum" , CmdAnalyseCHKSUM
, 1 , "Checksum with adding, masking and one's complement" },
292 { "dates" , CmdAnalyseDates
, 1 , "Look for datestamps in a given array of bytes" },
293 { "tea" , CmdAnalyseTEASelfTest
, 1 , "Crypto TEA test" },
294 { NULL
, NULL
, 0 , NULL
}
297 int CmdAnalyse ( const char * Cmd
) {
298 clearCommandBuffer ();
299 CmdsParse ( CommandTable
, Cmd
);
303 int CmdHelp ( const char * Cmd
) {
304 CmdsHelp ( CommandTable
);