25int apaPassCmp(
const char *pw1,
const char *pw2)
27#ifdef APA_ENABLE_PASSWORDS
28 return memcmp(pw1, pw2, APA_PASSMAX) ? -
EACCES : 0;
37static void DESEncryptPassword(u32 id_lo, u32 id_hi,
char *password_out,
const char *password);
39void apaEncryptPassword(
const char *
id,
char *password_out,
const char *password_in)
41 char password[APA_PASSMAX];
42 memcpy(password, password_in, APA_PASSMAX);
43 DESEncryptPassword(*(u32*)(
id), *(u32*)(
id + 4), password_out, password);
51static void DESEncryptPassword(u32 id_lo, u32 id_hi,
char *password_out,
const char *password)
54 static const u8 PC1[]={ 0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09,
55 0x01, 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12,
56 0x0a, 0x02, 0x3b, 0x33, 0x2b, 0x23, 0x1b,
57 0x13, 0x0b, 0x03, 0x3c, 0x34, 0x2c, 0x24,
59 0x3f, 0x37, 0x2f, 0x27, 0x1f, 0x17, 0x0f,
60 0x07, 0x3e, 0x36, 0x2e, 0x26, 0x1e, 0x16,
61 0x0e, 0x06, 0x3d, 0x35, 0x2d, 0x25, 0x1d,
62 0x15, 0x0d, 0x05, 0x1c, 0x14, 0x0c, 0x04 };
63 static const u8 Rotations[]={ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
64 static const u8 PC2[]={ 0x0e, 0x11, 0x0b, 0x18, 0x01, 0x05,
65 0x03, 0x1c, 0x0f, 0x06, 0x15, 0x0a,
66 0x17, 0x13, 0x0c, 0x04, 0x1a, 0x08,
67 0x10, 0x07, 0x1b, 0x14, 0x0d, 0x02,
68 0x29, 0x34, 0x1f, 0x25, 0x2f, 0x37,
69 0x1e, 0x28, 0x33, 0x2d, 0x21, 0x30,
70 0x2c, 0x31, 0x27, 0x38, 0x22, 0x35,
71 0x2e, 0x2a, 0x32, 0x24, 0x1d, 0x20 };
72 static const u8 IP[]={ 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12, 0x0a, 0x02, 0x3c, 0x34, 0x2c, 0x24, 0x1c, 0x14, 0x0c, 0x04,
73 0x3e, 0x36, 0x2e, 0x26, 0x1e, 0x16, 0x0e, 0x06, 0x40, 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08,
75 0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01, 0x3b, 0x33, 0x2b, 0x23, 0x1b, 0x13, 0x0b, 0x03,
76 0x3d, 0x35, 0x2d, 0x25, 0x1d, 0x15, 0x0d, 0x05, 0x3f, 0x37, 0x2f, 0x27, 0x1f, 0x17, 0x0f, 0x07 };
77 static const u8 Expansion[]={ 0x20, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b,
78 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x14, 0x15,
79 0x16, 0x17, 0x18, 0x19, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x01 };
80 static const u8 sbox[][64]={ { 0x0e, 0x04, 0x0d, 0x01, 0x02, 0x0f, 0x0b, 0x08, 0x03, 0x0a, 0x06, 0x0c, 0x05, 0x09, 0x00, 0x07,
81 0x00, 0x0f, 0x07, 0x04, 0x0e, 0x02, 0x0d, 0x01, 0x0a, 0x06, 0x0c, 0x0b, 0x09, 0x05, 0x03, 0x08,
82 0x04, 0x01, 0x0e, 0x08, 0x0d, 0x06, 0x02, 0x0b, 0x0f, 0x0c, 0x09, 0x07, 0x03, 0x0a, 0x05, 0x00,
83 0x0f, 0x0c, 0x08, 0x02, 0x04, 0x09, 0x01, 0x07, 0x05, 0x0b, 0x03, 0x0e, 0x0a, 0x00, 0x06, 0x0d },
84 { 0x0f, 0x01, 0x08, 0x0e, 0x06, 0x0b, 0x03, 0x04, 0x09, 0x07, 0x02, 0x0d, 0x0c, 0x00, 0x05, 0x0a,
85 0x03, 0x0d, 0x04, 0x07, 0x0f, 0x02, 0x08, 0x0e, 0x0c, 0x00, 0x01, 0x0a, 0x06, 0x09, 0x0b, 0x05,
86 0x00, 0x0e, 0x07, 0x0b, 0x0a, 0x04, 0x0d, 0x01, 0x05, 0x08, 0x0c, 0x06, 0x09, 0x03, 0x02, 0x0f,
87 0x0d, 0x08, 0x0a, 0x01, 0x03, 0x0f, 0x04, 0x02, 0x0b, 0x06, 0x07, 0x0c, 0x00, 0x05, 0x0e, 0x09 },
88 { 0x0a, 0x00, 0x09, 0x0e, 0x06, 0x03, 0x0f, 0x05, 0x01, 0x0d, 0x0c, 0x07, 0x0b, 0x04, 0x02, 0x08,
89 0x0d, 0x07, 0x00, 0x09, 0x03, 0x04, 0x06, 0x0a, 0x02, 0x08, 0x05, 0x0e, 0x0c, 0x0b, 0x0f, 0x01,
90 0x0d, 0x06, 0x04, 0x09, 0x08, 0x0f, 0x03, 0x00, 0x0b, 0x01, 0x02, 0x0c, 0x05, 0x0a, 0x0e, 0x07,
91 0x01, 0x0a, 0x0d, 0x00, 0x06, 0x09, 0x08, 0x07, 0x04, 0x0f, 0x0e, 0x03, 0x0b, 0x05, 0x02, 0x0c },
92 { 0x07, 0x0d, 0x0e, 0x03, 0x00, 0x06, 0x09, 0x0a, 0x01, 0x02, 0x08, 0x05, 0x0b, 0x0c, 0x04, 0x0f,
93 0x0d, 0x08, 0x0b, 0x05, 0x06, 0x0f, 0x00, 0x03, 0x04, 0x07, 0x02, 0x0c, 0x01, 0x0a, 0x0e, 0x09,
94 0x0a, 0x06, 0x09, 0x00, 0x0c, 0x0b, 0x07, 0x0d, 0x0f, 0x01, 0x03, 0x0e, 0x05, 0x02, 0x08, 0x04,
95 0x03, 0x0f, 0x00, 0x06, 0x0a, 0x01, 0x0d, 0x08, 0x09, 0x04, 0x05, 0x0b, 0x0c, 0x07, 0x02, 0x0e },
96 { 0x02, 0x0c, 0x04, 0x01, 0x07, 0x0a, 0x0b, 0x06, 0x08, 0x05, 0x03, 0x0f, 0x0d, 0x00, 0x0e, 0x09,
97 0x0e, 0x0b, 0x02, 0x0c, 0x04, 0x07, 0x0d, 0x01, 0x05, 0x00, 0x0f, 0x0a, 0x03, 0x09, 0x08, 0x06,
98 0x04, 0x02, 0x01, 0x0b, 0x0a, 0x0d, 0x07, 0x08, 0x0f, 0x09, 0x0c, 0x05, 0x06, 0x03, 0x00, 0x0e,
99 0x0b, 0x08, 0x0c, 0x07, 0x01, 0x0e, 0x02, 0x0d, 0x06, 0x0f, 0x00, 0x09, 0x0a, 0x04, 0x05, 0x03 },
100 { 0x0c, 0x01, 0x0a, 0x0f, 0x09, 0x02, 0x06, 0x08, 0x00, 0x0d, 0x03, 0x04, 0x0e, 0x07, 0x05, 0x0b,
101 0x0a, 0x0f, 0x04, 0x02, 0x07, 0x0c, 0x09, 0x05, 0x06, 0x01, 0x0d, 0x0e, 0x00, 0x0b, 0x03, 0x08,
102 0x09, 0x0e, 0x0f, 0x05, 0x02, 0x08, 0x0c, 0x03, 0x07, 0x00, 0x04, 0x0a, 0x01, 0x0d, 0x0b, 0x06,
103 0x04, 0x03, 0x02, 0x0c, 0x09, 0x05, 0x0f, 0x0a, 0x0b, 0x0e, 0x01, 0x07, 0x06, 0x00, 0x08, 0x0d },
104 { 0x04, 0x0b, 0x02, 0x0e, 0x0f, 0x00, 0x08, 0x0d, 0x03, 0x0c, 0x09, 0x07, 0x05, 0x0a, 0x06, 0x01,
105 0x0d, 0x00, 0x0b, 0x07, 0x04, 0x09, 0x01, 0x0a, 0x0e, 0x03, 0x05, 0x0c, 0x02, 0x0f, 0x08, 0x06,
106 0x01, 0x04, 0x0b, 0x0d, 0x0c, 0x03, 0x07, 0x0e, 0x0a, 0x0f, 0x06, 0x08, 0x00, 0x05, 0x09, 0x02,
107 0x06, 0x0b, 0x0d, 0x08, 0x01, 0x04, 0x0a, 0x07, 0x09, 0x05, 0x00, 0x0f, 0x0e, 0x02, 0x03, 0x0c },
108 { 0x0d, 0x02, 0x08, 0x04, 0x06, 0x0f, 0x0b, 0x01, 0x0a, 0x09, 0x03, 0x0e, 0x05, 0x00, 0x0c, 0x07,
109 0x01, 0x0f, 0x0d, 0x08, 0x0a, 0x03, 0x07, 0x04, 0x0c, 0x05, 0x06, 0x0b, 0x00, 0x0e, 0x09, 0x02,
110 0x07, 0x0b, 0x04, 0x01, 0x09, 0x0c, 0x0e, 0x02, 0x00, 0x06, 0x0a, 0x0d, 0x0f, 0x03, 0x05, 0x08,
111 0x02, 0x01, 0x0e, 0x07, 0x04, 0x0a, 0x08, 0x0d, 0x0f, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x06, 0x0b }};
112 static const u8 Permutation[]={ 0x10, 0x07, 0x14, 0x15, 0x1d, 0x0c, 0x1c, 0x11, 0x01, 0x0f, 0x17, 0x1a, 0x05, 0x12, 0x1f, 0x0a,
113 0x02, 0x08, 0x18, 0x0e, 0x20, 0x1b, 0x03, 0x09, 0x13, 0x0d, 0x1e, 0x06, 0x16, 0x0b, 0x04, 0x19 };
114 static const u8 FP[]={ 0x28, 0x08, 0x30, 0x10, 0x38, 0x18, 0x40, 0x20, 0x27, 0x07, 0x2f, 0x0f, 0x37, 0x17, 0x3f, 0x1f,
115 0x26, 0x06, 0x2e, 0x0e, 0x36, 0x16, 0x3e, 0x1e, 0x25, 0x05, 0x2d, 0x0d, 0x35, 0x15, 0x3d, 0x1d,
116 0x24, 0x04, 0x2c, 0x0c, 0x34, 0x14, 0x3c, 0x1c, 0x23, 0x03, 0x2b, 0x0b, 0x33, 0x13, 0x3b, 0x1b,
117 0x22, 0x02, 0x2a, 0x0a, 0x32, 0x12, 0x3a, 0x1a, 0x21, 0x01, 0x29, 0x09, 0x31, 0x11, 0x39, 0x19 };
118 u32 BitMask_hi, BitMask_lo;
119 u32 PermutedKeyMask_lo, PermutedKeyMask_hi, Rot2Mask_lo, Rot1Mask_lo, Rot2Mask_hi, Rot1Mask_hi;
120 u32 BitPerm_lo, BitPerm_hi;
121 u32 password_lo, password_hi;
122 u32 key1, key2, key3, key4, input_lo, input_hi;
123 u32 PermutedKey_lo, PermutedKey_hi, kVal_lo, kVal_hi, PermutedInput_lo, PermutedInput_hi, eVal_lo, eVal_hi, sVal_lo, sVal_hi, pVal_lo, pVal_hi, output_lo, output_hi;
124 struct KeyPair pairC[17], pairD[17], pairK[17], pairL[17], pairR[17];
125 struct KeyPair *pPairC, *pPairD, *pPairK, *pPairL, *pPairR;
126 unsigned int i, j, k;
133 BitMask_hi = 0x80000000;
135 BitPerm_hi = 0x80000000;
137 password_lo = *(
const u32*)password;
138 password_hi = *(
const u32*)(password + 4);
140 for(i = 0; i < 56; i++)
144 if((shift << 26) >= 0)
146 if((shift << 26) > 0)
147 key1 = (BitMask_lo >> shift) | (BitMask_hi << (-shift));
149 key1 = BitMask_lo >> shift;
151 key2 = BitMask_hi >> shift;
154 key1 = BitMask_hi >> shift;
158 if(((password_lo & key1) | (password_hi & key2)) != 0)
160 PermutedKey_lo |= BitPerm_lo;
161 PermutedKey_hi |= BitPerm_hi;
165 BitPerm_lo = (BitPerm_lo >> 1) | (BitPerm_hi << 31);
171 PermutedKeyMask_lo = 0x0FFFFFFF;
172 PermutedKeyMask_hi = 0x00000000;
175 Rot2Mask_hi = 0x00000000;
177 Rot1Mask_hi = 0x00000000;
180 pairC[0].lo = PermutedKey_hi >> 4;
184 pairD[0].lo = ((PermutedKey_lo >> 8) | (PermutedKey_hi << 24)) & PermutedKeyMask_lo;
185 pairD[0].hi = ((PermutedKey_hi >> 8) & PermutedKeyMask_hi);
188 for(i = 0; i < 16; i++)
190 if(Rotations[i] != 1)
193 key1 = ((pairC[i].hi << 6) | (pairC[i].lo >> 26)) & Rot2Mask_lo;
196 key4 = pairC[i].lo << 2;
199 key2 = (pairC[i].hi >> 26) & Rot2Mask_hi;
202 key3 = (pairC[i].hi << 2) | (pairC[i].lo >> 30);
205 key1 = ((pairC[i].hi << 5) | (pairC[i].lo >> 27)) & Rot1Mask_lo;
208 key4 = pairC[i].lo << 1;
211 key2 = (pairC[i].hi >> 27) & Rot1Mask_hi;
214 key3 = (pairC[i].hi << 1) | (pairC[i].lo >> 31);
219 pairC[i + 1].lo = (key1 | key4) & PermutedKeyMask_lo;
220 pairC[i + 1].hi = (key2 | key3) & PermutedKeyMask_hi;
222 if(Rotations[i] != 1)
225 key1 = ((pairD[i].hi << 6) | (pairD[i].lo >> 26)) & Rot2Mask_lo;
228 key4 = pairD[i].lo << 2;
231 key2 = (pairD[i].hi >> 26) & Rot2Mask_hi;
234 key3 = (pairD[i].hi << 2) | (pairD[i].lo >> 30);
237 key1 = ((pairD[i].hi << 5) | (pairD[i].lo >> 27)) & Rot1Mask_lo;
240 key4 = pairD[i].lo << 1;
243 key2 = (pairD[i].hi >> 27) & Rot1Mask_hi;
246 key3 = (pairD[i].hi << 1) | (pairD[i].lo >> 31);
251 pairD[i + 1].lo = (key1 | key4) & PermutedKeyMask_lo;
252 pairD[i + 1].hi = (key2 | key3) & PermutedKeyMask_hi;
256 BitMask_lo = 0x00000000;
257 BitMask_hi = 0x80000000;
260 for(pPairC = &pairC[1],pPairD = &pairD[1],pPairK = &pairK[1]; pPairK < &pairK[17]; pPairC++,pPairD++,pPairK++)
264 BitPerm_lo = 0x00000000;
265 BitPerm_hi = 0x80000000;
279 input_lo = 0 | (pPairD->lo << 8);
280 input_hi = (pPairC->lo << 4) | (pPairD->hi << 8) | (pPairD->lo >> 24);
282 for(i = 0; i < 48; i++)
286 if((shift << 26) >= 0)
288 if((shift << 26) > 0)
289 key1 = (BitMask_lo >> shift) | (BitMask_hi << (-shift));
291 key1 = BitMask_lo >> shift;
293 key2 = BitMask_hi >> shift;
296 key1 = BitMask_hi >> shift;
300 if(((input_lo & key1) | (input_hi & key2)) != 0)
302 kVal_lo |= BitPerm_lo;
303 kVal_hi |= BitPerm_hi;
307 BitPerm_lo = (BitPerm_hi << 31) | (BitPerm_lo >> 1);
311 pPairK->lo = kVal_lo;
312 pPairK->hi = kVal_hi;
316 BitMask_lo = 0x00000000;
317 BitMask_hi = 0x80000000;
318 BitPerm_lo = 0x00000000;
319 BitPerm_hi = 0x80000000;
320 PermutedInput_lo = 0;
321 PermutedInput_hi = 0;
324 for(i = 0; i < 64; i++)
328 if((shift << 26) >= 0)
330 if((shift << 26) > 0)
331 key1 = (BitMask_lo >> shift) | (BitMask_hi << (-shift));
333 key1 = BitMask_lo >> shift;
335 key2 = BitMask_hi >> shift;
338 key1 = BitMask_hi >> shift;
342 if(((id_lo & key1) | (id_hi & key2)) != 0)
344 PermutedInput_lo |= BitPerm_lo;
345 PermutedInput_hi |= BitPerm_hi;
349 BitPerm_lo = (BitPerm_lo >> 1) | (BitPerm_hi << 31);
354 BitMask_lo = 0x00000000;
355 BitMask_hi = 0x80000000;
359 pairL[0].lo = PermutedInput_lo & 0x00000000;
360 pairL[0].hi = PermutedInput_hi & 0xFFFFFFFF;
361 pairR[0].lo = 0x00000000;
362 pairR[0].hi = PermutedInput_lo << 0;
364 for (j = 0, k = 1, pPairL = &pairL[1], pPairR = &pairR[1]; pPairR < &pairR[17]; j++, k++, pPairR++, pPairL++)
368 BitPerm_lo = 0x00000000;
369 BitPerm_hi = 0x80000000;
372 pPairL->lo = input_lo = pairR[j].lo;
373 pPairL->hi = input_hi = pairR[j].hi;
376 for(i = 0; i < 48; i++)
378 shift = Expansion[i] - 1;
379 if((shift << 26) >= 0)
381 if((shift << 26) > 0)
382 key1 = (BitMask_lo >> shift) | (BitMask_hi << (-shift));
384 key1 = BitMask_lo >> shift;
386 key2 = BitMask_hi >> shift;
389 key1 = BitMask_hi >> shift;
393 if(((input_lo & key1) | (input_hi & key2)) != 0)
395 eVal_lo |= BitPerm_lo;
396 eVal_hi |= BitPerm_hi;
400 BitPerm_lo = (BitPerm_hi << 31) | (BitPerm_lo >> 1);
409 eVal_lo = (eVal_lo ^ pairK[k].lo) >> 16;
410 eVal_hi = eVal_hi ^ pairK[k].hi;
411 eVal_lo |= (eVal_hi << 16);
415 for(i = 0, shift = 32; i < 8; i++, shift += 4)
417 input_lo = sbox[7 - i][((eVal_lo & 0x20) | ((eVal_lo & 0x3F) >> 1 & 0xF) | ((eVal_lo & 0x3F) << 4 & 0x10))];
419 eVal_lo = (eVal_lo >> 6) | (eVal_hi << 26);
423 if((s32)((u32)shift << 26) >= 0)
425 if((shift << 26) > 0)
426 key3 = (input_hi << shift) | (input_lo >> (-shift));
428 key3 = input_hi << shift;
430 key4 = input_lo << shift;
432 key3 = input_lo << shift;
443 BitPerm_lo = 0x00000000;
444 BitPerm_hi = 0x80000000;
447 for(i = 0; i < 32; i++)
449 shift = Permutation[i] - 1;
450 if((shift << 26) >= 0)
452 if((shift << 26) > 0)
453 key1 = (BitMask_lo >> shift) | (BitMask_hi << (-shift));
455 key1 = BitMask_lo >> shift;
457 key2 = BitMask_hi >> shift;
459 key1 = BitMask_hi >> shift;
464 if(((sVal_lo & key1) | (sVal_hi & key2)) != 0)
466 pVal_lo |= BitPerm_lo;
467 pVal_hi |= BitPerm_hi;
471 BitPerm_lo = (BitPerm_lo >> 1) | (BitPerm_hi << 31);
476 pPairR->lo = pairL[j].lo ^ pVal_lo;
477 pPairR->hi = pairL[j].hi ^ pVal_hi;
483 BitMask_lo = BitPerm_lo = 0x00000000;
484 BitMask_hi = BitPerm_hi = 0x80000000;
487 input_lo = pairR[16].lo | (pairL[16].hi >> 0);
488 input_hi = pairR[16].hi | 0;
491 for(i = 0; i < 64; i++)
494 if((shift << 26) >= 0)
496 if((shift << 26) > 0)
497 key1 = (BitMask_lo >> shift) | (BitMask_hi << (-shift));
499 key1 = BitMask_lo >> shift;
501 key2 = BitMask_hi >> shift;
503 key1 = BitMask_hi >> shift;
508 if(((input_lo & key1) | (input_hi & key2)) != 0)
510 output_lo |= BitPerm_lo;
511 output_hi |= BitPerm_hi;
515 BitPerm_lo = (BitPerm_lo >> 1) | (BitPerm_hi << 31);
520 *(u32*)password_out = output_lo;
521 *(u32*)(password_out + 4) = output_hi;