1 //-----------------------------------------------------------------------------
2 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
3 // at your option, any later version. See the LICENSE.txt file for the text of
5 //-----------------------------------------------------------------------------
6 // LEFIC's obfuscation function
7 //-----------------------------------------------------------------------------
9 #include "legic_prng.h"
10 // the prng is a muxed value from two lsfr a, b
13 // c keeps track on which step the prng is.
14 // legic_prng_get_bit() = gets a bit muxed from a and b.
21 // Normal init is set following variables with a random value IV
24 // * someone mentioned iv must be ODD.
26 // Now we have a special case with iv == 0
27 // it sets b to 0 as well to make sure we get a all zero keystream out
28 // which is used in the initialisation phase sending the IV
30 void legic_prng_init(uint8_t iv
) {
32 lfsr
.b
= 0; // hack to get a always 0 keystream
35 lfsr
.b
= (iv
<< 1) | 1;
38 void legic_prng_forward(int count
) {
39 if (count
== 0) return;
43 // According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
44 lfsr
.a
= (lfsr
.a
>> 1 | (lfsr
.a
^ lfsr
.a
>> 6) << 6) & 0x7F;
45 lfsr
.b
= lfsr
.b
>> 1 | (lfsr
.b
^ lfsr
.b
>> 2 ^ lfsr
.b
>> 3 ^ lfsr
.b
>> 7) << 7;
49 uint8_t legic_prng_get_bit(void) {
50 uint8_t idx
= 7 - ((lfsr
.a
& 4) | (lfsr
.a
>> 2 & 2) | (lfsr
.a
>> 4 & 1));
51 return lfsr
.b
>> idx
& 1;
54 uint32_t legic_prng_get_bits(uint8_t len
) {
56 for (uint8_t i
= 0; i
< len
; ++i
) {
57 a
|= legic_prng_get_bit() << i
;
58 legic_prng_forward(1);