]> matita.cs.unibo.it Git - pkg-cerco/frama-c-cost-plugin.git/blob - plugin/tests/success/a5.c
Imported Upstream version 0.1
[pkg-cerco/frama-c-cost-plugin.git] / plugin / tests / success / a5.c
1 /*
2  * In writing this program, I've had to guess a few pices of information:
3  *
4  * 1. Which bits of the key are loaded into which bits of the shift register
5  * 2. Which order the frame sequence number is shifted into the SR (MSB
6  *    first or LSB first)
7  * 3. The position of the feedback taps on R2 and R3 (R1 is known).
8  * 4. The position of the clock control taps. These are on the `middle' one, 
9  *    I've assumed to be 9 on R1, 11 on R2, 11 on R3.
10  */
11
12 /*
13  * Look at the `middle' stage of each of the 3 shift registers.
14  * Either 0, 1, 2 or 3 of these 3 taps will be set high.
15  * If 0 or 1 or one of them are high, return true. This will cause each of
16  * the middle taps to be inverted before being used as a clock control. In
17  * all cases either 2 or 3 of the clock enable lines will be active. Thus,
18  * at least two shift registers change on every clock-tick and the system
19  * never becomes stuck.
20  */
21
22 static int threshold(r1, r2, r3)
23 unsigned int r1;
24 unsigned int r2;
25 unsigned int r3;
26 {
27 int total;
28
29   total = (((r1 >>  9) & 0x1) == 1) +
30           (((r2 >> 11) & 0x1) == 1) +
31           (((r3 >> 11) & 0x1) == 1);
32
33   if (total > 1)
34     return (0);
35   else
36     return (1);
37 }
38
39 unsigned long clock_r1(ctl, r1)
40 int ctl;
41 unsigned long r1;
42 {
43 unsigned long feedback;
44
45  /*
46   * Primitive polynomial x**19 + x**5 + x**2 + x + 1
47   */
48
49   ctl ^= ((r1 >> 9) & 0x1);
50   if (ctl)
51   {
52     feedback = (r1 >> 18) ^ (r1 >> 17) ^ (r1 >> 16) ^ (r1 >> 13);
53     r1 = (r1 << 1) & 0x7ffff;
54     if (feedback & 0x01)
55       r1 ^= 0x01;
56   }
57   return (r1);
58 }
59
60 unsigned long clock_r2(ctl, r2)
61 int ctl;
62 unsigned long r2;
63 {
64 unsigned long feedback;
65
66   
67  /*
68   * Primitive polynomial x**22 + x**9 + x**5 + x + 1
69   */   
70
71   ctl ^= ((r2 >> 11) & 0x1);
72   if (ctl)
73   {
74     feedback = (r2 >> 21) ^ (r2 >> 20) ^ (r2 >> 16) ^ (r2 >> 12);
75     r2 = (r2 << 1) & 0x3fffff;
76     if (feedback & 0x01)
77       r2 ^= 0x01;
78   }
79   return (r2);
80 }
81
82 unsigned long clock_r3(ctl, r3)
83 int ctl;
84 unsigned long r3;
85 {
86 unsigned long feedback;
87
88  /*
89   * Primitive polynomial x**23 + x**5 + x**4 + x + 1
90   */
91
92   ctl ^= ((r3 >> 11) & 0x1);
93   if (ctl)
94   {
95     feedback = (r3 >> 22) ^ (r3 >> 21) ^ (r3 >> 18) ^ (r3 >> 17);
96     r3 = (r3 << 1) & 0x7fffff;
97     if (feedback & 0x01)
98       r3 ^= 0x01;
99   }
100   return (r3);
101 }
102
103 int keystream(key, frame, alice, bob)
104 unsigned char *key;   /* 64 bit session key              */
105 unsigned long frame;  /* 22 bit frame sequence number    */
106 unsigned char *alice; /* 114 bit Alice to Bob key stream */
107 unsigned char *bob;   /* 114 bit Bob to Alice key stream */
108 {
109 unsigned long r1;   /* 19 bit shift register */
110 unsigned long r2;   /* 22 bit shift register */
111 unsigned long r3;   /* 23 bit shift register */
112 int i;              /* counter for loops     */
113 int clock_ctl;      /* xored with clock enable on each shift register */
114 unsigned char *ptr; /* current position in keystream */
115 unsigned char byte; /* byte of keystream being assembled */
116 unsigned int bits;  /* number of bits of keystream in byte */
117 unsigned int bit;   /* bit output from keystream generator */
118
119   /* Initialise shift registers from session key */
120
121   r1 = (key[0] | (key[1] << 8) | (key[2] << 16) ) & 0x7ffff;
122   r2 = ((key[2] >> 3) | (key[3] << 5) | (key[4] << 13) | (key[5] << 21)) & 0x3fffff;
123   r3 = ((key[5] >> 1) | (key[6] << 7) | (key[7] << 15) ) & 0x7fffff;
124
125
126   /* Merge frame sequence number into shift register state, by xor'ing it
127    * into the feedback path
128    */
129
130   for (i=0;i<22;i++)
131   {
132     clock_ctl = threshold(r1, r2, r2);
133     r1 = clock_r1(clock_ctl, r1);
134     r2 = clock_r2(clock_ctl, r2);
135     r3 = clock_r3(clock_ctl, r3);
136     if (frame & 1)
137     {
138       r1 ^= 1;
139       r2 ^= 1;
140       r3 ^= 1;
141     }
142     frame = frame >> 1;
143   }
144
145   /* Run shift registers for 100 clock ticks to allow frame number to
146    * be diffused into all the bits of the shift registers
147    */
148
149   for (i=0;i<100;i++)
150   {
151     clock_ctl = threshold(r1, r2, r2);
152     r1 = clock_r1(clock_ctl, r1);
153     r2 = clock_r2(clock_ctl, r2);
154     r3 = clock_r3(clock_ctl, r3);
155   }
156
157   /* Produce 114 bits of Alice->Bob key stream */
158
159   ptr = alice;
160   bits = 0;
161   byte = 0;
162   for (i=0;i<114;i++)
163   {
164     clock_ctl = threshold(r1, r2, r2);
165     r1 = clock_r1(clock_ctl, r1);
166     r2 = clock_r2(clock_ctl, r2);
167     r3 = clock_r3(clock_ctl, r3);
168
169     bit = ((r1 >> 18) ^ (r2 >> 21) ^ (r3 >> 22)) & 0x01;
170     byte = (byte << 1) | bit;
171     bits++;
172     if (bits == 8)
173     {
174       *ptr = byte;
175       ptr++;
176       bits = 0;
177       byte = 0;
178     }
179   }
180   if (bits)
181     *ptr = byte;
182
183   /* Run shift registers for another 100 bits to hide relationship between
184    * Alice->Bob key stream and Bob->Alice key stream.
185    */
186
187   for (i=0;i<100;i++)
188   {
189     clock_ctl = threshold(r1, r2, r2);
190     r1 = clock_r1(clock_ctl, r1);
191     r2 = clock_r2(clock_ctl, r2);
192     r3 = clock_r3(clock_ctl, r3);
193   }
194
195   /* Produce 114 bits of Bob->Alice key stream */
196
197   ptr = bob;
198   bits = 0;
199   byte = 0;
200   for (i=0;i<114;i++)
201   {
202     clock_ctl = threshold(r1, r2, r2);
203     r1 = clock_r1(clock_ctl, r1);
204     r2 = clock_r2(clock_ctl, r2);
205     r3 = clock_r3(clock_ctl, r3);
206
207     bit = ((r1 >> 18) ^ (r2 >> 21) ^ (r3 >> 22)) & 0x01;
208     byte = (byte << 1) | bit;
209     bits++;
210     if (bits == 8)
211     {
212       *ptr = byte;
213       ptr++;
214       bits = 0;
215       byte = 0;
216     }
217   }
218   if (bits)
219     *ptr = byte;
220  
221   return (0);
222
223 }
224
225
226