X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/3742d905632dbce9792f70b110e7ba5605bf312f..6d7234cd43b2f40b3bce56055d9727f9cdbc29ee:/armsrc/hitag2.c diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 26ab1066..15daa25e 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -1,17 +1,21 @@ -/* - * Hitag2 emulation - * - * Contains state and functions for an emulated Hitag2 tag. Offers an entry - * point to handle commands, needs a callback to send response. - * - * (c) 2009 Henryk Plötz - */ - -#include -#include - +//----------------------------------------------------------------------------- +// (c) 2009 Henryk Plötz +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Hitag2 emulation +// +// Contains state and functions for an emulated Hitag2 tag. Offers an entry +// point to handle commands, needs a callback to send response. +//----------------------------------------------------------------------------- + +#include "proxmark3.h" #include "apps.h" +#include "util.h" #include "hitag2.h" +#include "string.h" struct hitag2_cipher_state { uint64_t state; @@ -19,7 +23,7 @@ struct hitag2_cipher_state { struct hitag2_tag { uint32_t uid; - enum { + enum { TAG_STATE_RESET, // Just powered up, awaiting GetSnr TAG_STATE_ACTIVATING, // In activation phase (password mode), sent UID, awaiting reader password TAG_STATE_AUTHENTICATING, // In activation phase (crypto mode), awaiting reader authentication @@ -74,7 +78,7 @@ int hitag2_handle_command(const char* data, const int length, hitag2_response_ca data = temp; } - + handle_command_retry: switch(tag.state) { case TAG_STATE_RESET: @@ -148,8 +152,8 @@ handle_command_retry: /* transmission error */ DbpString("Transmission error (write) in activated state"); } - } - + } + } case TAG_STATE_WRITING: if(length == 32) { @@ -159,7 +163,7 @@ handle_command_retry: done=1; } } - + if(!done && !retry) { /* We didn't respond, maybe our state is faulty. Reset and try again. */ retry=1; @@ -205,13 +209,13 @@ static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 101 static u32 _f20 (const u64 x) { u32 i5; - + i5 = ((ht2_f4a >> i4 (x, 1, 2, 4, 5)) & 1)* 1 + ((ht2_f4b >> i4 (x, 7,11,13,14)) & 1)* 2 + ((ht2_f4b >> i4 (x,16,20,22,25)) & 1)* 4 + ((ht2_f4b >> i4 (x,27,28,30,32)) & 1)* 8 + ((ht2_f4a >> i4 (x,33,42,43,45)) & 1)*16; - + return (ht2_f5c >> i5) & 1; } @@ -219,7 +223,7 @@ static u64 _hitag2_init (const u64 key, const u32 serial, const u32 IV) { u32 i; u64 x = ((key & 0xFFFF) << 32) + serial; - + for (i = 0; i < 32; i++) { x >>= 1; @@ -231,67 +235,21 @@ static u64 _hitag2_init (const u64 key, const u32 serial, const u32 IV) static u64 _hitag2_round (u64 *state) { u64 x = *state; - + x = (x >> 1) + ((((x >> 0) ^ (x >> 2) ^ (x >> 3) ^ (x >> 6) ^ (x >> 7) ^ (x >> 8) ^ (x >> 16) ^ (x >> 22) ^ (x >> 23) ^ (x >> 26) ^ (x >> 30) ^ (x >> 41) ^ (x >> 42) ^ (x >> 43) ^ (x >> 46) ^ (x >> 47)) & 1) << 47); - + *state = x; return _f20 (x); } -// Bitslice Hitag2 functions: - -#define ht2bs_4a(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) -#define ht2bs_4b(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) -#define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) - -#define uf20bs u32 // choose your own type/width - -static uf20bs _f20bs (const uf20bs *x) -{ - return ht2bs_5c ( - ht2bs_4a(x[ 1],x[ 2],x[ 4],x[ 5]), - ht2bs_4b(x[ 7],x[11],x[13],x[14]), - ht2bs_4b(x[16],x[20],x[22],x[25]), - ht2bs_4b(x[27],x[28],x[30],x[32]), - ht2bs_4a(x[33],x[42],x[43],x[45])); -} - -static void _hitag2bs_init (uf20bs *x, const uf20bs *key, const uf20bs *serial, const uf20bs *IV) -{ - u32 i, r; - - for (i = 0; i < 32; i++) x[i] = serial[i]; - for (i = 0; i < 16; i++) x[32+i] = key[i]; - - for (r = 0; r < 32; r++) - { - for (i = 0; i < 47; i++) x[i] = x[i+1]; - x[47] = _f20bs (x) ^ IV[i] ^ key[16+i]; - } -} - -static uf20bs _hitag2bs_round (uf20bs *x) -{ - uf20bs y; - u32 i; - - y = x[ 0] ^ x[ 2] ^ x[ 3] ^ x[ 6] ^ x[ 7] ^ x[ 8] ^ x[16] ^ x[22] - ^ x[23] ^ x[26] ^ x[30] ^ x[41] ^ x[42] ^ x[43] ^ x[46] ^ x[47]; - - for (i = 0; i < 47; i++) x[i] = x[i+1]; - x[47] = y; - - return _f20bs (x); -} - static u32 _hitag2_byte (u64 * x) { u32 i, c; - + for (i = 0, c = 0; i < 8; i++) c += (u32) _hitag2_round (x) << (i^7); return c; }