]>
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"
11 #include "nonce2key/nonce2key.h"
13 static int CmdHelp ( const char * Cmd
);
15 int usage_analyse_lcr ( void ) {
16 PrintAndLog ( "Specifying the bytes of a UID with a known LRC will find the last byte value" );
17 PrintAndLog ( "needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX." );
19 PrintAndLog ( "Usage: analyse lcr [h] <bytes>" );
20 PrintAndLog ( "Options:" );
21 PrintAndLog ( " h This help" );
22 PrintAndLog ( " <bytes> bytes to calc missing XOR in a LCR" );
24 PrintAndLog ( "Samples:" );
25 PrintAndLog ( " analyse lcr 04008064BA" );
26 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] [v] b <bytes> m <mask>" );
34 PrintAndLog ( "Options:" );
35 PrintAndLog ( " h This help" );
36 PrintAndLog ( " v supress header" );
37 PrintAndLog ( " b <bytes> bytes to calc missing XOR in a LCR" );
38 PrintAndLog ( " m <mask> bit mask to limit the outpuyt" );
40 PrintAndLog ( "Samples:" );
41 PrintAndLog ( " analyse chksum b 137AF00A0A0D m FF" );
42 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" );
57 int usage_analyse_hid ( void ){
58 PrintAndLog ( "Permute function from 'heart of darkness' paper." );
60 PrintAndLog ( "Usage: analyse hid [h] <r|f> <bytes>" );
61 PrintAndLog ( "Options:" );
62 PrintAndLog ( " h This help" );
63 PrintAndLog ( " r reverse permuted key" );
64 PrintAndLog ( " f permute key" );
65 PrintAndLog ( " <bytes> input bytes" );
67 PrintAndLog ( "Samples:" );
68 PrintAndLog ( " analyse hid r 0123456789abcdef" );
71 int usage_analyse_nuid ( void ){
72 PrintAndLog ( "Generate 4byte NUID from 7byte UID" );
74 PrintAndLog ( "Usage: analyse hid [h] <bytes>" );
75 PrintAndLog ( "Options:" );
76 PrintAndLog ( " h This help" );
77 PrintAndLog ( " <bytes> input bytes (14 hexsymbols)" );
79 PrintAndLog ( "Samples:" );
80 PrintAndLog ( " analyse nuid 11223344556677" );
84 static uint8_t calculateLRC ( uint8_t * bytes
, uint8_t len
) {
86 for ( uint8_t i
= 0 ; i
< len
; i
++)
91 static uint16_t calcSumCrumbAdd ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
93 for ( uint8_t i
= 0 ; i
< len
; i
++) {
94 sum
+= CRUMB ( bytes
[ i
], 0 );
95 sum
+= CRUMB ( bytes
[ i
], 2 );
96 sum
+= CRUMB ( bytes
[ i
], 4 );
97 sum
+= CRUMB ( bytes
[ i
], 6 );
102 static uint16_t calcSumCrumbAddOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
103 return (~ calcSumCrumbAdd ( bytes
, len
, mask
) & mask
);
105 static uint16_t calcSumNibbleAdd ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
107 for ( uint8_t i
= 0 ; i
< len
; i
++) {
108 sum
+= NIBBLE_LOW ( bytes
[ i
]);
109 sum
+= NIBBLE_HIGH ( bytes
[ i
]);
114 static uint16_t calcSumNibbleAddOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
){
115 return (~ calcSumNibbleAdd ( bytes
, len
, mask
) & mask
);
117 static uint16_t calcSumCrumbXor ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
119 for ( uint8_t i
= 0 ; i
< len
; i
++) {
120 sum
^= CRUMB ( bytes
[ i
], 0 );
121 sum
^= CRUMB ( bytes
[ i
], 2 );
122 sum
^= CRUMB ( bytes
[ i
], 4 );
123 sum
^= CRUMB ( bytes
[ i
], 6 );
128 static uint16_t calcSumNibbleXor ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
130 for ( uint8_t i
= 0 ; i
< len
; i
++) {
131 sum
^= NIBBLE_LOW ( bytes
[ i
]);
132 sum
^= NIBBLE_HIGH ( bytes
[ i
]);
137 static uint16_t calcSumByteXor ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
139 for ( uint8_t i
= 0 ; i
< len
; i
++)
144 static uint16_t calcSumByteAdd ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
146 for ( uint8_t i
= 0 ; i
< len
; i
++)
152 static uint16_t calcSumByteAddOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
153 return (~ calcSumByteAdd ( bytes
, len
, mask
) & mask
);
156 static uint16_t calcSumByteSub ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
158 for ( uint8_t i
= 0 ; i
< len
; i
++)
163 static uint16_t calcSumByteSubOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
){
164 return (~ calcSumByteSub ( bytes
, len
, mask
) & mask
);
166 static uint16_t calcSumNibbleSub ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
168 for ( uint8_t i
= 0 ; i
< len
; i
++) {
169 sum
-= NIBBLE_LOW ( bytes
[ i
]);
170 sum
-= NIBBLE_HIGH ( bytes
[ i
]);
175 static uint16_t calcSumNibbleSubOnes ( uint8_t * bytes
, uint8_t len
, uint32_t mask
) {
176 return (~ calcSumNibbleSub ( bytes
, len
, mask
) & mask
);
179 // BSD shift checksum 8bit version
180 static uint16_t calcBSDchecksum8 ( uint8_t * bytes
, uint8_t len
, uint32_t mask
){
182 for ( uint8_t i
= 0 ; i
< len
; i
++){
183 sum
= (( sum
& 0xFF ) >> 1 ) | (( sum
& 0x1 ) << 7 ); // rotate accumulator
184 sum
+= bytes
[ i
]; // add next byte
190 // BSD shift checksum 4bit version
191 static uint16_t calcBSDchecksum4 ( uint8_t * bytes
, uint8_t len
, uint32_t mask
){
193 for ( uint8_t i
= 0 ; i
< len
; i
++){
194 sum
= (( sum
& 0xF ) >> 1 ) | (( sum
& 0x1 ) << 3 ); // rotate accumulator
195 sum
+= NIBBLE_HIGH ( bytes
[ i
]); // add high nibble
197 sum
= (( sum
& 0xF ) >> 1 ) | (( sum
& 0x1 ) << 3 ); // rotate accumulator
198 sum
+= NIBBLE_LOW ( bytes
[ i
]); // add low nibble
205 // measuring LFSR maximum length
206 int CmdAnalyseLfsr ( const char * Cmd
){
208 uint16_t start_state
= 0 ; /* Any nonzero start state will work. */
209 uint16_t lfsr
= start_state
;
210 //uint32_t period = 0;
212 uint8_t iv
= param_get8ex ( Cmd
, 0 , 0 , 16 );
213 uint8_t find
= param_get8ex ( Cmd
, 1 , 0 , 16 );
215 printf ( "LEGIC LFSR IV 0x%02X: \n " , iv
);
216 printf ( " bit# | lfsr | ^0x40 | 0x%02X ^ lfsr \n " , find
);
218 for ( uint8_t i
= 0x01 ; i
< 0x30 ; i
+= 1 ) {
221 legic_prng_forward ( i
);
222 lfsr
= legic_prng_get_bits ( 12 );
224 printf ( " %02X | %03X | %03X | %03X \n " , i
, lfsr
, 0x40 ^ lfsr
, find
^ lfsr
);
228 int CmdAnalyseLCR ( const char * Cmd
) {
230 char cmdp
= param_getchar ( Cmd
, 0 );
231 if ( strlen ( Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H' ) return usage_analyse_lcr ();
234 param_gethex_ex ( Cmd
, 0 , data
, & len
);
235 if ( len
% 2 ) return usage_analyse_lcr ();
237 uint8_t finalXor
= calculateLRC ( data
, len
);
238 PrintAndLog ( "Target [%02X] requires final LRC XOR byte value: 0x%02X" , data
[ len
- 1 ] , finalXor
);
241 int CmdAnalyseCRC ( const char * Cmd
) {
243 char cmdp
= param_getchar ( Cmd
, 0 );
244 if ( strlen ( Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H' ) return usage_analyse_crc ();
246 int len
= strlen ( Cmd
);
247 if ( len
& 1 ) return usage_analyse_crc ();
249 // add 1 for null terminator.
250 uint8_t * data
= malloc ( len
+ 1 );
251 if ( data
== NULL
) return 1 ;
253 if ( param_gethex ( Cmd
, 0 , data
, len
)) {
255 return usage_analyse_crc ();
259 //PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));
261 PrintAndLog ( " \n Tests of reflection. Two current methods in source code" );
262 PrintAndLog ( " reflect(0x3e23L,3) is %04X == 0x3e26" , reflect ( 0x3e23 L
, 3 ) );
263 PrintAndLog ( " SwapBits(0x3e23L,3) is %04X == 0x3e26" , SwapBits ( 0x3e23 L
, 3 ) );
264 PrintAndLog ( " 0xB400 == %04X" , reflect ( ( 1 << 16 | 0xb400 ), 16 ) );
267 // Test of CRC16, '123456789' string.
269 PrintAndLog ( " \n Tests with '123456789' string" );
270 uint8_t dataStr
[] = { 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39 };
271 uint8_t legic8
= CRC8Legic ( dataStr
, sizeof ( dataStr
));
273 PrintAndLog ( "LEGIC: CRC16: %X" , CRC16Legic ( dataStr
, sizeof ( dataStr
), legic8
));
275 //these below has been tested OK.
276 PrintAndLog ( "Confirmed CRC Implementations" );
277 PrintAndLog ( "LEGIC: CRC8 : %X (0xC6 expected)" , legic8
);
278 PrintAndLog ( "MAXIM: CRC8 : %X (0xA1 expected)" , CRC8Maxim ( dataStr
, sizeof ( dataStr
)));
279 PrintAndLog ( "DNP : CRC16: %X (0x82EA expected)" , CRC16_DNP ( dataStr
, sizeof ( dataStr
)));
280 PrintAndLog ( "CCITT: CRC16: %X (0xE5CC expected)" , CRC16_CCITT ( dataStr
, sizeof ( dataStr
)));
282 PrintAndLog ( "ICLASS org: CRC16: %X (0x expected)" , iclass_crc16 ( ( char *) dataStr
, sizeof ( dataStr
)));
283 PrintAndLog ( "ICLASS ice: CRC16: %X (0x expected)" , CRC16_ICLASS ( dataStr
, sizeof ( dataStr
)));
287 uint8_t dataStr1234
[] = { 0x1 , 0x2 , 0x3 , 0x4 };
288 PrintAndLog ( "ISO15693 org: : CRC16: %X (0xF0B8 expected)" , Iso15693Crc ( dataStr1234
, sizeof ( dataStr1234
)));
289 PrintAndLog ( "ISO15693 ice: : CRC16: %X (0xF0B8 expected)" , CRC16_Iso15693 ( dataStr1234
, sizeof ( dataStr1234
)));
294 int CmdAnalyseCHKSUM ( const char * Cmd
){
298 uint32_t mask
= 0xFFFF ;
300 bool useHeader
= false ;
302 memset ( data
, 0x0 , sizeof ( data
));
304 while ( param_getchar ( Cmd
, cmdp
) != 0x00 ) {
305 switch ( param_getchar ( Cmd
, cmdp
)) {
308 param_gethex_ex ( Cmd
, cmdp
+ 1 , data
, & len
);
309 if ( len
% 2 ) errors
= true ;
315 mask
= param_get32ex ( Cmd
, cmdp
+ 1 , 0 , 16 );
325 return usage_analyse_checksum ();
327 PrintAndLog ( "Unknown parameter '%c'" , param_getchar ( Cmd
, cmdp
));
334 if ( errors
) return usage_analyse_checksum ();
337 PrintAndLog ( " add | sub | add 1's compl | sub 1's compl | xor" );
338 PrintAndLog ( "byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb | BSD |" );
339 PrintAndLog ( "------------------+-------------+------------------+-----------------+--------------------" );
341 PrintAndLog ( "0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | \n " ,
342 calcSumByteAdd ( data
, len
, mask
)
343 , calcSumNibbleAdd ( data
, len
, mask
)
344 , calcSumCrumbAdd ( data
, len
, mask
)
345 , calcSumByteSub ( data
, len
, mask
)
346 , calcSumNibbleSub ( data
, len
, mask
)
347 , calcSumByteAddOnes ( data
, len
, mask
)
348 , calcSumNibbleAddOnes ( data
, len
, mask
)
349 , calcSumCrumbAddOnes ( data
, len
, mask
)
350 , calcSumByteSubOnes ( data
, len
, mask
)
351 , calcSumNibbleSubOnes ( data
, len
, mask
)
352 , calcSumByteXor ( data
, len
, mask
)
353 , calcSumNibbleXor ( data
, len
, mask
)
354 , calcSumCrumbXor ( data
, len
, mask
)
355 , calcBSDchecksum8 ( data
, len
, mask
)
356 , calcBSDchecksum4 ( data
, len
, mask
)
361 int CmdAnalyseDates ( const char * Cmd
){
362 // look for datestamps in a given array of bytes
363 PrintAndLog ( "To be implemented. Feel free to contribute!" );
366 int CmdAnalyseTEASelfTest ( const char * Cmd
){
368 uint8_t v
[ 8 ], v_le
[ 8 ];
369 memset ( v
, 0x00 , sizeof ( v
));
370 memset ( v_le
, 0x00 , sizeof ( v_le
));
371 uint8_t * v_ptr
= v_le
;
373 uint8_t cmdlen
= strlen ( Cmd
);
374 cmdlen
= ( sizeof ( v
)<< 2 < cmdlen
) ? sizeof ( v
)<< 2 : cmdlen
;
376 if ( param_gethex ( Cmd
, 0 , v
, cmdlen
) > 0 ){
377 PrintAndLog ( "can't read hex chars, uneven? :: %u" , cmdlen
);
381 SwapEndian64ex ( v
, 8 , 4 , v_ptr
);
384 uint8_t key
[ 16 ] = { 0x55 , 0xFE , 0xF6 , 0x30 , 0x62 , 0xBF , 0x0B , 0xC1 , 0xC9 , 0xB3 , 0x7C , 0x34 , 0x97 , 0x3E , 0x29 , 0xFB };
386 uint8_t * key_ptr
= keyle
;
387 SwapEndian64ex ( key
, sizeof ( key
), 4 , key_ptr
);
389 PrintAndLog ( "TEST LE enc| %s" , sprint_hex ( v_ptr
, 8 ));
391 tea_decrypt ( v_ptr
, key_ptr
);
392 PrintAndLog ( "TEST LE dec | %s" , sprint_hex_ascii ( v_ptr
, 8 ));
394 tea_encrypt ( v_ptr
, key_ptr
);
395 tea_encrypt ( v_ptr
, key_ptr
);
396 PrintAndLog ( "TEST enc2 | %s" , sprint_hex_ascii ( v_ptr
, 8 ));
401 int CmdAnalyseA ( const char * Cmd
){
404 // uid(2e086b1a) nt(230736f6) ks(0b0008000804000e) nr(000000000)
405 // uid(2e086b1a) nt(230736f6) ks(0e0b0e0b090c0d02) nr(000000001)
406 // uid(2e086b1a) nt(230736f6) ks(0e05060e01080b08) nr(000000002)
407 uint64_t d1[] = {0x2e086b1a, 0x230736f6, 0x0000001, 0x0e0b0e0b090c0d02};
408 uint64_t d2[] = {0x2e086b1a, 0x230736f6, 0x0000002, 0x0e05060e01080b08};
410 // uid(17758822) nt(c0c69e59) ks(080105020705040e) nr(00000001)
411 // uid(17758822) nt(c0c69e59) ks(01070a05050c0705) nr(00000002)
412 uint64_t d1[] = {0x17758822, 0xc0c69e59, 0x0000001, 0x080105020705040e};
413 uint64_t d2[] = {0x17758822, 0xc0c69e59, 0x0000002, 0x01070a05050c0705};
415 // uid(6e442129) nt(8f699195) ks(090d0b0305020f02) nr(00000001)
416 // uid(6e442129) nt(8f699195) ks(03030508030b0c0e) nr(00000002)
417 // uid(6e442129) nt(8f699195) ks(02010f030c0d050d) nr(00000003)
418 // uid(6e442129) nt(8f699195) ks(00040f0f0305030e) nr(00000004)
419 uint64_t d1[] = {0x6e442129, 0x8f699195, 0x0000001, 0x090d0b0305020f02};
420 uint64_t d2[] = {0x6e442129, 0x8f699195, 0x0000004, 0x00040f0f0305030e};
422 uid(3e172b29) nt(039b7bd2) ks(0c0e0f0505080800) nr(00000001)
423 uid(3e172b29) nt(039b7bd2) ks(0e06090d03000b0f) nr(00000002)
426 uint64_t d1
[] = { 0x3e172b29 , 0x039b7bd2 , 0x0000001 , 0x0c0e0f0505080800 };
427 uint64_t d2
[] = { 0x3e172b29 , 0x039b7bd2 , 0x0000002 , 0x0e06090d03000b0f };
429 nonce2key_ex ( 0 , 0 , d1
[ 0 ], d1
[ 1 ], d1
[ 2 ], d1
[ 3 ], & key
);
430 nonce2key_ex ( 0 , 0 , d2
[ 0 ], d2
[ 1 ], d2
[ 2 ], d2
[ 3 ], & key
);
434 static void permute ( uint8_t * data
, uint8_t len
, uint8_t * output
){
437 if ( len
> KEY_SIZE
) {
438 for ( uint8_t m
= 0 ; m
< len
; m
+= KEY_SIZE
){
439 permute ( data
+ m
, KEY_SIZE
, output
+ m
);
443 if ( len
!= KEY_SIZE
) {
444 printf ( "wrong key size \n " );
448 for ( i
= 0 ; i
< KEY_SIZE
; ++ i
){
451 for ( j
= 0 ; j
< KEY_SIZE
; ++ j
){
459 static void permute_rev ( uint8_t * data
, uint8_t len
, uint8_t * output
){
460 permute ( data
, len
, output
);
461 permute ( output
, len
, data
);
462 permute ( data
, len
, output
);
464 static void simple_crc ( uint8_t * data
, uint8_t len
, uint8_t * output
){
466 for ( uint8_t i
= 0 ; i
< len
; ++ i
){
467 // seventh byte contains the crc.
468 if ( ( i
& 0x7 ) == 0x7 ) {
469 output
[ i
] = crc
^ 0xFF ;
477 // DES doesn't use the MSB.
478 static void shave ( uint8_t * data
, uint8_t len
){
479 for ( uint8_t i
= 0 ; i
< len
; ++ i
)
482 static void generate_rev ( uint8_t * data
, uint8_t len
) {
483 uint8_t * key
= calloc ( len
, 1 );
484 printf ( "input permuted key | %s \n " , sprint_hex ( data
, len
));
485 permute_rev ( data
, len
, key
);
486 printf ( " unpermuted key | %s \n " , sprint_hex ( key
, len
));
488 printf ( " key | %s \n " , sprint_hex ( key
, len
));
491 static void generate ( uint8_t * data
, uint8_t len
) {
492 uint8_t * key
= calloc ( len
, 1 );
493 uint8_t * pkey
= calloc ( len
, 1 );
494 printf ( " input key | %s \n " , sprint_hex ( data
, len
));
495 permute ( data
, len
, pkey
);
496 printf ( " permuted key | %s \n " , sprint_hex ( pkey
, len
));
497 simple_crc ( pkey
, len
, key
);
498 printf ( " CRC'ed key | %s \n " , sprint_hex ( key
, len
));
502 int CmdAnalyseHid ( const char * Cmd
){
504 uint8_t key
[ 8 ] = { 0 };
505 uint8_t key_std_format
[ 8 ] = { 0 };
506 uint8_t key_iclass_format
[ 8 ] = { 0 };
507 uint8_t data
[ 16 ] = { 0 };
508 bool isReverse
= FALSE
;
510 char cmdp
= param_getchar ( Cmd
, 0 );
511 if ( strlen ( Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H' ) return usage_analyse_hid ();
513 if ( cmdp
== 'r' || cmdp
== 'R' )
516 param_gethex_ex ( Cmd
, 1 , data
, & len
);
517 if ( len
% 2 ) return usage_analyse_hid ();
521 memcpy ( key
, data
, 8 );
524 generate_rev ( data
, len
);
525 permutekey_rev ( key
, key_std_format
);
526 printf ( " holiman iclass key | %s \n " , sprint_hex ( key_std_format
, 8 ));
530 permutekey ( key
, key_iclass_format
);
531 printf ( " holiman std key | %s \n " , sprint_hex ( key_iclass_format
, 8 ));
536 void generate4bNUID ( uint8_t * uid
, uint8_t * nuid
){
538 uint8_t first
, second
;
540 ComputeCrc14443 ( CRC_14443_A
, uid
, 3 , & first
, & second
);
541 nuid
[ 0 ] |= ( second
& 0xE0 ) | 0xF ;
547 UpdateCrc14443 ( uid
[ 3 ], & crc
);
548 UpdateCrc14443 ( uid
[ 4 ], & crc
);
549 UpdateCrc14443 ( uid
[ 5 ], & crc
);
550 UpdateCrc14443 ( uid
[ 6 ], & crc
);
552 nuid
[ 2 ] = ( crc
>> 8 ) & 0xFF ;
553 nuid
[ 3 ] = crc
& 0xFF ;
556 int CmdAnalyseNuid ( const char * Cmd
){
557 uint8_t nuid
[ 4 ] = { 0 };
558 uint8_t uid
[ 7 ] = { 0 };
560 char cmdp
= param_getchar ( Cmd
, 0 );
561 if ( strlen ( Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H' ) return usage_analyse_nuid ();
563 /* selftest UID 040D681AB52281 -> NUID 8F430FEF */
564 if ( cmdp
== 't' || cmdp
== 'T' ) {
565 memcpy ( uid
, " \x04\x0d\x68\x1a\xb5\x22\x81 " , 7 );
566 generate4bNUID ( uid
, nuid
);
567 if ( 0 == memcmp ( nuid
, " \x8f\x43\x0f\xef " , 4 ))
568 printf ( "Selftest OK \n " );
570 printf ( "Selftest Failed \n " );
574 param_gethex_ex ( Cmd
, 0 , uid
, & len
);
575 if ( len
% 2 || len
!= 14 ) return usage_analyse_nuid ();
577 generate4bNUID ( uid
, nuid
);
579 printf ( "UID | %s \n " , sprint_hex ( uid
, 7 ));
580 printf ( "NUID | %s \n " , sprint_hex ( nuid
, 4 ));
583 static command_t CommandTable
[] = {
584 { "help" , CmdHelp
, 1 , "This help" },
585 { "lcr" , CmdAnalyseLCR
, 1 , "Generate final byte for XOR LRC" },
586 { "crc" , CmdAnalyseCRC
, 1 , "Stub method for CRC evaluations" },
587 { "chksum" , CmdAnalyseCHKSUM
, 1 , "Checksum with adding, masking and one's complement" },
588 { "dates" , CmdAnalyseDates
, 1 , "Look for datestamps in a given array of bytes" },
589 { "tea" , CmdAnalyseTEASelfTest
, 1 , "Crypto TEA test" },
590 { "lfsr" , CmdAnalyseLfsr
, 1 , "LFSR tests" },
591 { "a" , CmdAnalyseA
, 1 , "num bits test" },
592 { "hid" , CmdAnalyseHid
, 1 , "Permute function from 'heart of darkness' paper" },
593 { "nuid" , CmdAnalyseNuid
, 1 , "create NUID from 7byte UID" },
594 { NULL
, NULL
, 0 , NULL
}
597 int CmdAnalyse ( const char * Cmd
) {
598 clearCommandBuffer ();
599 CmdsParse ( CommandTable
, Cmd
);
603 int CmdHelp ( const char * Cmd
) {
604 CmdsHelp ( CommandTable
);