]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/hidcardformatutils.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2018 grauerfuchs
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 // HID card format packing/unpacking support functions
9 //-----------------------------------------------------------------------------
15 #include "hidcardformatutils.h"
18 bool get_bit_by_position(/* in */hidproxmessage_t
* data
, /* in */uint8_t pos
){
19 if (pos
>= data
->Length
) return false;
20 pos
= (data
->Length
- pos
) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit.
25 result
= (data
->top
>> (pos
- 64)) & 1;
27 result
= (data
->mid
>> (pos
- 32)) & 1;
29 result
= (data
->bot
>> pos
) & 1;
32 bool set_bit_by_position(/* inout */hidproxmessage_t
* data
, /* in */bool value
, /* in */uint8_t pos
){
33 if (pos
>= data
->Length
) return false;
34 pos
= (data
->Length
- pos
) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit.
37 } else if (pos
> 63) {
39 data
->top
|= (1 << (pos
- 64));
41 data
->top
&= ~(1 << (pos
- 64));
43 } else if (pos
> 31) {
45 data
->mid
|= (1 << (pos
- 32));
47 data
->mid
&= ~(1 << (pos
- 32));
51 data
->bot
|= (1 << pos
);
53 data
->bot
&= ~(1 << pos
);
58 * Safeguard the data by doing a manual deep copy
60 * At the time of the initial writing, the struct does not contain pointers. That doesn't
61 * mean it won't eventually contain one, however. To prevent memory leaks and erroneous
62 * aliasing, perform the copy function manually instead. Hence, this function.
64 * If the definition of the hidproxmessage struct changes, this function must also
65 * be updated to match.
67 void proxmessage_datacopy(/*in*/hidproxmessage_t
* src
, /*out*/hidproxmessage_t
* dest
){
71 dest
->Length
= src
->Length
;
75 * Yes, this is horribly inefficient for linear data.
76 * The current code is a temporary measure to have a working function in place
77 * until all the bugs shaken from the block/chunk version of the code.
80 uint64_t get_linear_field(/* in */hidproxmessage_t
* data
, uint8_t firstBit
, uint8_t length
){
82 for (uint8_t i
= 0; i
< length
; i
++ ) {
83 result
= (result
<< 1) | get_bit_by_position(data
, firstBit
+ i
);
87 bool set_linear_field(/* inout */hidproxmessage_t
* data
, uint64_t value
, uint8_t firstBit
, uint8_t length
){
88 hidproxmessage_t tmpdata
;
89 proxmessage_datacopy(data
, &tmpdata
);
91 for (int i
= 0; i
< length
; i
++){
92 result
&= set_bit_by_position(&tmpdata
, (value
>> ((length
- i
) - 1)) & 1, firstBit
+ i
);
94 if (result
) proxmessage_datacopy(&tmpdata
, data
);
98 uint64_t get_nonlinear_field(/* in */hidproxmessage_t
* data
, uint8_t numBits
, uint8_t* bits
){
100 for (int i
= 0; i
< numBits
; i
++){
101 result
= (result
<< 1) | (get_bit_by_position(data
, *(bits
+i
)) & 1);
105 bool set_nonlinear_field(/* inout */hidproxmessage_t
* data
, uint64_t value
, uint8_t numBits
, uint8_t* bits
){
106 hidproxmessage_t tmpdata
;
107 proxmessage_datacopy(data
, &tmpdata
);
109 for (int i
= 0; i
< numBits
; i
++){
110 result
&= set_bit_by_position(&tmpdata
, (value
>> ((numBits
- i
) - 1)) & 1, *(bits
+ i
));
112 if (result
) proxmessage_datacopy(&tmpdata
, data
);
116 uint8_t get_length_from_header(/* inout */hidproxmessage_t
* data
) {
119 uint32_t hFmt
; // for calculating card length
120 if ((data
->top
& 0x000FFFFF) > 0) { // > 64 bits
121 hFmt
= data
->top
& 0x000FFFFF;
123 } else if ((data
->mid
& 0xFFFFFFC0) > 0) { // < 63-38 bits
124 hFmt
= data
->mid
& 0xFFFFFFC0;
126 } else if ((data
->mid
& 0x00000020) == 0) { // 37 bits
129 } else if ((data
->mid
& 0x0000001F) > 0){ // 36-32 bits
130 hFmt
= data
->mid
& 0x0000001F;
144 hidproxmessage_t
initialize_proxmessage_object(uint32_t top
, uint32_t mid
, uint32_t bot
){
145 struct hidproxmessage_s result
;
146 memset(&result
, 0, sizeof(hidproxmessage_t
));
150 result
.Length
= get_length_from_header(&result
);
153 bool add_HID_header(/* inout */hidproxmessage_t
* data
){
154 if (data
->Length
> 84 || data
->Length
== 0) return false; // Invalid value
156 if (data
->Length
>= 64){
157 data
->top
|= 1 << (data
->Length
- 64); // leading 1: start bit
158 data
->top
|= 0x09e00000; // Extended-length header
159 } else if (data
->Length
> 37){
160 data
->mid
|= 1 << (data
->Length
- 32); // leading 1: start bit
161 data
->top
|= 0x09e00000; // Extended-length header
162 } else if (data
->Length
== 37){
163 // No header bits added to 37-bit cards
164 } else if (data
->Length
>= 32){
165 data
->mid
|= 0x20; // Bit 37; standard header
166 data
->mid
|= 1 << (data
->Length
- 32); // leading 1: start bit
168 data
->mid
|= 0x20; // Bit 37; standard header
169 data
->bot
|= 1 << data
->Length
; // leading 1: start bit