16 #include "nested_util.h"
19 #define MEM_CHUNK 10000
39 inline static int compar_int(const void *a
, const void *b
) {
40 if (*(uint64_t *)b
== *(uint64_t *)a
) return 0;
41 if (*(uint64_t *)b
< * (uint64_t *)a
) return 1;
45 // Compare countKeys structure
46 static int compar_special_int(const void *a
, const void *b
) {
47 return (((countKeys
*)b
)->count
- ((countKeys
*)a
)->count
);
50 // keys qsort and unique.
51 static countKeys
*uniqsort(uint64_t *possibleKeys
, uint32_t size
) {
52 unsigned int i
, j
= 0;
54 countKeys
*our_counts
;
56 qsort(possibleKeys
, size
, sizeof(uint64_t), compar_int
);
58 our_counts
= calloc(size
, sizeof(countKeys
));
59 if (our_counts
== NULL
) {
60 printf("Memory allocation error for our_counts");
64 for (i
= 0; i
< size
; i
++) {
65 if (possibleKeys
[i
+ 1] == possibleKeys
[i
]) {
68 our_counts
[j
].key
= possibleKeys
[i
];
69 our_counts
[j
].count
= count
;
74 qsort(our_counts
, j
, sizeof(countKeys
), compar_special_int
);
79 static void *nested_revover(void *args
) {
80 struct Crypto1State
*revstate
, * revstate_start
= NULL
;
82 uint32_t i
, kcount
= 0;
85 RecPar
*rp
= (RecPar
*)args
;
90 //printf("Start pos is %d, End pos is %d\r\n", rp->startPos, rp->endPos);
92 for (i
= rp
->startPos
; i
< rp
->endPos
; i
++) {
93 uint32_t nt_probe
= rp
->pNK
[i
].ntp
^ rp
->authuid
;
94 uint32_t ks1
= rp
->pNK
[i
].ks1
;
97 printf(" ntp = %"PRIu32"\r\n", nt_probe);
98 printf(" ks1 = %"PRIu32"\r\n", ks1);
102 // And finally recover the first 32 bits of the key
103 revstate
= lfsr_recovery32(ks1
, nt_probe
);
104 if (revstate_start
== NULL
) {
105 revstate_start
= revstate
;
108 while ((revstate
->odd
!= 0x0) || (revstate
->even
!= 0x0)) {
109 lfsr_rollback_word(revstate
, nt_probe
, 0);
110 crypto1_get_lfsr(revstate
, &lfsr
);
111 if (((kcount
% MEM_CHUNK
) == 0) || (kcount
>= rp
->keyCount
)) {
112 rp
->keyCount
+= MEM_CHUNK
;
113 // printf("New chunk by %d, sizeof %lu\n", kcount, rp->keyCount * sizeof(uint64_t));
114 void *tmp
= realloc(rp
->keys
, rp
->keyCount
* sizeof(uint64_t));
116 printf("Memory allocation error for pk->possibleKeys");
121 rp
->keys
= (uint64_t *)tmp
;
123 rp
->keys
[kcount
] = lfsr
;
128 free(revstate_start
);
129 revstate_start
= NULL
;
136 rp
->keyCount
= kcount
;
137 void *tmp
= (uint64_t *)realloc(rp
->keys
, rp
->keyCount
* sizeof(uint64_t));
139 printf("Memory allocation error for pk->possibleKeys");
153 uint64_t *nested(NtpKs1
*pNK
, uint32_t sizePNK
, uint32_t authuid
, uint32_t *keyCount
) {
157 uint32_t i
, j
, manyThread
;
158 uint64_t *keys
= (uint64_t *)NULL
;
160 manyThread
= THREAD_MAX
;
161 if (manyThread
> sizePNK
) {
162 manyThread
= sizePNK
;
166 pthread_t
*threads
= calloc(sizePNK
, sizeof(pthread_t
));
167 if (threads
== NULL
) return NULL
;
170 RecPar
*pRPs
= calloc(sizePNK
, sizeof(RecPar
));
176 uint32_t average
= sizePNK
/ manyThread
;
177 uint32_t modules
= sizePNK
% manyThread
;
180 for (i
= 0, j
= 0; i
< manyThread
; i
++, j
+= average
) {
182 pRPs
[i
].authuid
= authuid
;
183 pRPs
[i
].startPos
= j
;
184 pRPs
[i
].endPos
= j
+ average
;
186 // last thread can decrypt more pNK
187 if (i
== (manyThread
- 1) && modules
> 0) {
188 (pRPs
[i
].endPos
) += modules
;
190 pthread_create(&threads
[i
], NULL
, nested_revover
, &(pRPs
[i
]));
193 for (i
= 0; i
< manyThread
; i
++) {
194 // wait thread exit...
195 pthread_join(threads
[i
], NULL
);
196 *keyCount
+= pRPs
[i
].keyCount
;
200 if (*keyCount
== 0) {
201 printf("Didn't recover any keys.\r\n");
206 keys
= calloc((*keyCount
) * sizeof(uint64_t), sizeof(uint8_t));
208 printf("Cannot allocate memory to merge keys.\r\n");
213 for (i
= 0, j
= 0; i
< manyThread
; i
++) {
214 if (pRPs
[i
].keyCount
> 0) {
215 // printf("The thread %d recover %d keys.\r\n", i, pRPs[i].keyCount);
216 if (pRPs
[i
].keys
!= NULL
) {
220 pRPs
[i
].keyCount
* sizeof(uint64_t)
222 j
+= pRPs
[i
].keyCount
;
228 countKeys
*ck
= uniqsort(keys
, *keyCount
);
230 keys
= (uint64_t *)NULL
;
234 printf("Cannot allocate memory for ck on uniqsort.");
240 for (i
= 0; i
< TRY_KEYS
; i
++) {
241 // We don't known this key, try to break it
242 // This key can be found here two or more times
243 if (ck
[i
].count
> 0) {
245 void *tmp
= realloc(keys
, sizeof(uint64_t) * (*keyCount
));
247 printf("Cannot allocate memory for keys on merge.");
255 keys
[*keyCount
- 1] = ck
[i
].key
;
264 // Return 1 if the nonce is invalid else return 0
265 uint8_t valid_nonce(uint32_t Nt
, uint32_t NtEnc
, uint32_t Ks1
, uint8_t *parity
) {
267 (oddparity8((Nt
>> 24) & 0xFF) == ((parity
[0]) ^ oddparity8((NtEnc
>> 24) & 0xFF) ^ BIT(Ks1
, 16))) && \
268 (oddparity8((Nt
>> 16) & 0xFF) == ((parity
[1]) ^ oddparity8((NtEnc
>> 16) & 0xFF) ^ BIT(Ks1
, 8))) && \
269 (oddparity8((Nt
>> 8) & 0xFF) == ((parity
[2]) ^ oddparity8((NtEnc
>> 8) & 0xFF) ^ BIT(Ks1
, 0)))