@@ -110,12 +110,7 @@ static void init_opt_select_LUT(void) {
110110}
111111***********************************************************************************/
112112
113- #define loclass_opt__select (x , y , r ) \
114- (4 & ((((r) & ((r) << 2)) >> 5) ^ (((r) & ~((r) << 2)) >> 4) ^ (((r) | (r) << 2) >> 3))) | \
115- (2 & ((((r) | (r) << 2) >> 6) ^ (((r) | (r) << 2) >> 1) ^ ((r) >> 5) ^ (r) ^ (((x) ^ (y)) << 1))) | \
116- (1 & ((((r) & ~((r) << 2)) >> 4) ^ (((r) & ((r) << 2)) >> 3) ^ (r) ^ (x)))
117-
118- static void loclass_opt_successor (const uint8_t * k , LoclassState_t * s , uint8_t y ) {
113+ static inline void loclass_opt_successor (const uint8_t * k , LoclassState_t * s , uint8_t y ) {
119114 uint16_t Tt = s -> t & 0xc533 ;
120115 Tt = Tt ^ (Tt >> 1 );
121116 Tt = Tt ^ (Tt >> 4 );
@@ -133,38 +128,38 @@ static void loclass_opt_successor(const uint8_t* k, LoclassState_t* s, uint8_t y
133128 s -> b = s -> b >> 1 ;
134129 s -> b |= (opt_B ^ s -> r ) << 7 ;
135130
136- uint8_t opt_select = loclass_opt_select_LUT [s -> r ] & 0x04 ;
137- opt_select |= (loclass_opt_select_LUT [s -> r ] ^ ((Tt ^ y ) << 1 )) & 0x02 ;
138- opt_select |= (loclass_opt_select_LUT [s -> r ] ^ Tt ) & 0x01 ;
131+ uint8_t Tt1 = Tt & 0x01 ;
132+ uint8_t opt_select = loclass_opt_select_LUT [s -> r ] ^ Tt1 ^ ((Tt1 ^ (y & 0x01 )) << 1 );
139133
140134 uint8_t r = s -> r ;
141135 s -> r = (k [opt_select ] ^ s -> b ) + s -> l ;
142136 s -> l = s -> r + r ;
143137}
144138
145- static void loclass_opt_suc (
139+ static inline void loclass_opt_suc (
146140 const uint8_t * k ,
147141 LoclassState_t * s ,
148142 const uint8_t * in ,
149143 uint8_t length ,
150144 bool add32Zeroes ) {
151145 for (int i = 0 ; i < length ; i ++ ) {
152146 uint8_t head = in [i ];
147+ #pragma GCC unroll 8
153148 for (int j = 0 ; j < 8 ; j ++ ) {
154149 loclass_opt_successor (k , s , head );
155150 head >>= 1 ;
156151 }
157152 }
158- //For tag MAC, an additional 32 zeroes
153+ // For tag MAC, an additional 32 zeroes
159154 if (add32Zeroes ) {
160- for (int i = 0 ; i < 16 ; i ++ ) {
161- loclass_opt_successor (k , s , 0 );
155+ for (int i = 0 ; i < 32 ; i ++ ) {
162156 loclass_opt_successor (k , s , 0 );
163157 }
164158 }
165159}
166160
167- static void loclass_opt_output (const uint8_t * k , LoclassState_t * s , uint8_t * buffer ) {
161+ static inline void loclass_opt_output (const uint8_t * k , LoclassState_t * s , uint8_t * buffer ) {
162+ #pragma GCC unroll 4
168163 for (uint8_t times = 0 ; times < 4 ; times ++ ) {
169164 uint8_t bout = 0 ;
170165 bout |= (s -> r & 0x4 ) >> 2 ;
@@ -280,19 +275,25 @@ void loclass_opt_doTagMAC_2(
280275 loclass_opt_output (div_key_p , & _init , mac );
281276}
282277
278+ /**
279+ * The second part of the tag MAC calculation, since the CC is already calculated into the state,
280+ * this function is fed only the NR, and generates both the reader and tag MACs.
281+ * @param _init - precalculated cipher state
282+ * @param nr - the reader challenge
283+ * @param rmac - where to store the reader MAC
284+ * @param tmac - where to store the tag MAC
285+ * @param div_key_p - the key to use
286+ */
283287void loclass_opt_doBothMAC_2 (
284288 LoclassState_t _init ,
285289 uint8_t * nr ,
286290 uint8_t rmac [4 ],
287291 uint8_t tmac [4 ],
288292 const uint8_t * div_key_p ) {
289- loclass_opt_suc (div_key_p , & _init , nr , 4 , false);
290- // Save internal state for reuse before outputting
291- LoclassState_t nr_state = _init ;
292- loclass_opt_output (div_key_p , & _init , rmac );
293- // Feed the 32 0 bits for the tag mac
294- loclass_opt_suc (div_key_p , & nr_state , NULL , 0 , true);
295- loclass_opt_output (div_key_p , & nr_state , tmac );
293+ LoclassState_t * s = & _init ;
294+ loclass_opt_suc (div_key_p , s , nr , 4 , false);
295+ loclass_opt_output (div_key_p , s , rmac );
296+ loclass_opt_output (div_key_p , s , tmac );
296297}
297298
298299void loclass_iclass_calc_div_key (uint8_t * csn , const uint8_t * key , uint8_t * div_key , bool elite ) {
0 commit comments