1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // LEGIC's obfuscation function
17 //-----------------------------------------------------------------------------
19 #include "legic_prng.h"
20 // the prng is a muxed value from two lsfr a, b
23 // c keeps track on which step the prng is.
24 // legic_prng_get_bit() = gets a bit muxed from a and b.
31 // Normal init is set following variables with a random value IV
34 // * someone mentioned iv must be ODD.
36 // Now we have a special case with iv == 0
37 // it sets b to 0 as well to make sure we get a all zero keystream out
38 // which is used in the initialisation phase sending the IV
40 void legic_prng_init(uint8_t iv
) {
42 lfsr
.b
= 0; // hack to get a always 0 keystream
45 lfsr
.b
= (iv
<< 1) | 1;
48 void legic_prng_forward(int count
) {
49 if (count
== 0) return;
53 // According: http://www.proxmark.org/forum/viewtopic.php?pid=5437#p5437
54 lfsr
.a
= (lfsr
.a
>> 1 | (lfsr
.a
^ lfsr
.a
>> 6) << 6) & 0x7F;
55 lfsr
.b
= lfsr
.b
>> 1 | (lfsr
.b
^ lfsr
.b
>> 2 ^ lfsr
.b
>> 3 ^ lfsr
.b
>> 7) << 7;
59 uint8_t legic_prng_get_bit(void) {
60 uint8_t idx
= 7 - ((lfsr
.a
& 4) | (lfsr
.a
>> 2 & 2) | (lfsr
.a
>> 4 & 1));
61 return lfsr
.b
>> idx
& 1;
64 uint32_t legic_prng_get_bits(uint8_t len
) {
66 for (uint8_t i
= 0; i
< len
; ++i
) {
67 a
|= legic_prng_get_bit() << i
;
68 legic_prng_forward(1);