Rizin
unix-like reverse engineering framework and cli tools
crypto_cps2.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2016 esanfelix
3 // SPDX-FileCopyrightText: 2016 pof
4 // SPDX-License-Identifier: LGPL-3.0-only
5 
6 /* XXX this must be specified by the user/rom? */
7 #define UPPER_LIMIT 0x400000
8 
9 #define BIT(x, n) (((x) >> (n)) & 1)
10 
11 #define BITSWAP8(val, B7, B6, B5, B4, B3, B2, B1, B0) \
12  ((BIT(val, B7) << 7) | (BIT(val, B6) << 6) | (BIT(val, B5) << 5) | (BIT(val, B4) << 4) | \
13  (BIT(val, B3) << 3) | (BIT(val, B2) << 2) | (BIT(val, B1) << 1) | (BIT(val, B0) << 0))
14 
15 #include <rz_lib.h>
16 #include <rz_crypto.h>
17 #include <rz_util.h>
18 
19 // license:BSD-3-Clause
20 // copyright-holders:Paul Leaman, Andreas Naive, Nicola Salmoria,Charles MacDonald
21 /******************************************************************************
22 
23 CPS-2 Encryption
24 
25 All credit goes to Andreas Naive for breaking the encryption algorithm.
26 Code by Nicola Salmoria.
27 Thanks to Charles MacDonald and Razoola for extracting the data from the hardware.
28 
29 
30 The encryption only affects opcodes, not data.
31 
32 It consists of two 4-round Feistel networks (FN) and involves both
33 the 16-bit opcode and the low 16 bits of the address.
34 
35 Let be:
36 
37 E = 16-bit ciphertext
38 A = 16-bit address
39 K = 64-bit key
40 D = 16-bit plaintext
41 y = FN1(x,k) = function describing the first Feistel network (x,y = 16 bit, k = 64 bit)
42 y = FN2(x,k) = function describing the second Feistel network (x,y = 16 bit, k = 64 bit)
43 y = EX(x) = fixed function that expands the 16-bit x to the 64-bit y
44 
45 Then the cipher can be described as:
46 
47 D = FN2( E, K XOR EX( FN1(A, K ) ) )
48 
49 
50 Each round of the Feistel networks consists of four substitution boxes. The boxes
51 have 6 inputs and 2 outputs. Usually the input is the XOR of a data bit and a key
52 bit, however in some cases only the key is used.
53 
54 (TODO-notes about accuracy of s-boxes)
55 
56 The s-boxes were chosen in order to use an empty key (all FF) for the dead board.
57 
58 
59 Also, the hardware has different watchdog opcodes and address range (see below)
60 which are stored in the battery backed RAM. There doesn't appear to be any relation
61 between those and the 64-bit encryption key, so they probably use an additional
62 64 bits of battery-backed RAM.
63 
64 
65 
66 First FN:
67 
68  B(0 1 3 5 8 9 11 12) A(10 4 6 7 2 13 15 14)
69  L0 R0
70  | |
71  XOR<-----------[F1]<------------|
72  | |
73  R1 L1
74  | |
75  |------------>[F2]----------->XOR
76  | |
77  L2 R2
78  | |
79  XOR<-----------[F3]<------------|
80  | |
81  R3 L3
82  | |
83  |------------>[F4]----------->XOR
84  | |
85  L4 R4
86  (10 4 6 7 2 13 15 14) (0 1 3 5 8 9 11 12)
87 
88 
89 Second FN:
90 
91  B(3 5 9 10 8 15 12 11) A(6 0 2 13 1 4 14 7)
92  L0 R0
93  | |
94  XOR<-----------[F1]<------------|
95  | |
96  R1 L1
97  | |
98  |------------>[F2]----------->XOR
99  | |
100  L2 R2
101  | |
102  XOR<-----------[F3]<------------|
103  | |
104  R3 L3
105  | |
106  |------------>[F4]----------->XOR
107  | |
108  L4 R4
109  (6 0 2 13 1 4 14 7) (3 5 9 10 8 15 12 11)
110 
111 ******************************************************************************
112 
113 Some Encryption notes.
114 ----------------------
115 
116 Address range.
117 
118 The encryption does _not_ cover the entire address space. The range covered
119 differs per game.
120 
121 
122 Encryption Watchdog.
123 
124 The CPS2 system has a watchdog system that will disable the decryption
125 of data if the watchdog isn't triggered at least once every few seconds.
126 The trigger varies from game to game (some games do use the same) and is
127 basically a 68000 opcode/s instruction. The instruction is the same for
128 all regions of the game. The watchdog instructions are listed alongside
129 the decryption keys.
130 
131 *******************************************************************************/
132 /******************************************************************************/
133 
134 static const int fn1_groupA[8] = { 10, 4, 6, 7, 2, 13, 15, 14 };
135 static const int fn1_groupB[8] = { 0, 1, 3, 5, 8, 9, 11, 12 };
136 
137 static const int fn2_groupA[8] = { 6, 0, 2, 13, 1, 4, 14, 7 };
138 static const int fn2_groupB[8] = { 3, 5, 9, 10, 8, 15, 12, 11 };
139 
140 /******************************************************************************/
141 
142 // The order of the input and output bits in the s-boxes is arbitrary.
143 // Each s-box can be XORed with an arbitrary vale in range 0-3 (but the same value
144 // must be used for the corresponding output bits in f1 and f3 or in f2 and f4)
145 
146 struct sbox {
147  const ut8 table[64];
148  const int inputs[6]; // positions of the inputs bits, -1 means no input except from key
149  const int outputs[2]; // positions of the output bits
150 };
151 
152 // the above struct better defines how the hardware works, however
153 // to speed up the decryption at run time we convert it to the
154 // following one
157  ut8 output[64];
158 };
159 
160 static const struct sbox fn1_r1_boxes[4] = {
161  { // subkey bits 0- 5
162  {
163  0,
164  2,
165  2,
166  0,
167  1,
168  0,
169  1,
170  1,
171  3,
172  2,
173  0,
174  3,
175  0,
176  3,
177  1,
178  2,
179  1,
180  1,
181  1,
182  2,
183  1,
184  3,
185  2,
186  2,
187  2,
188  3,
189  3,
190  2,
191  1,
192  1,
193  1,
194  2,
195  2,
196  2,
197  0,
198  0,
199  3,
200  1,
201  3,
202  1,
203  1,
204  1,
205  3,
206  0,
207  0,
208  1,
209  0,
210  0,
211  1,
212  2,
213  2,
214  1,
215  2,
216  3,
217  2,
218  2,
219  2,
220  3,
221  1,
222  3,
223  2,
224  0,
225  1,
226  3,
227  },
228  { 3, 4, 5, 6, -1, -1 },
229  { 3, 6 } },
230  { // subkey bits 6-11
231  {
232  3,
233  0,
234  2,
235  2,
236  2,
237  1,
238  1,
239  1,
240  1,
241  2,
242  1,
243  0,
244  0,
245  0,
246  2,
247  3,
248  2,
249  3,
250  1,
251  3,
252  0,
253  0,
254  0,
255  2,
256  1,
257  2,
258  2,
259  3,
260  0,
261  3,
262  3,
263  3,
264  0,
265  1,
266  3,
267  2,
268  3,
269  3,
270  3,
271  1,
272  1,
273  1,
274  1,
275  2,
276  0,
277  1,
278  2,
279  1,
280  3,
281  2,
282  3,
283  1,
284  1,
285  3,
286  2,
287  2,
288  2,
289  3,
290  1,
291  3,
292  2,
293  3,
294  0,
295  0,
296  },
297  { 0, 1, 2, 4, 7, -1 },
298  { 2, 7 } },
299  { // subkey bits 12-17
300  {
301  3,
302  0,
303  3,
304  1,
305  1,
306  0,
307  2,
308  2,
309  3,
310  1,
311  2,
312  0,
313  3,
314  3,
315  2,
316  3,
317  0,
318  1,
319  0,
320  1,
321  2,
322  3,
323  0,
324  2,
325  0,
326  2,
327  0,
328  1,
329  0,
330  0,
331  1,
332  0,
333  2,
334  3,
335  1,
336  2,
337  1,
338  0,
339  2,
340  0,
341  2,
342  1,
343  0,
344  1,
345  0,
346  2,
347  1,
348  0,
349  3,
350  1,
351  2,
352  3,
353  1,
354  3,
355  1,
356  1,
357  1,
358  2,
359  0,
360  2,
361  2,
362  0,
363  0,
364  0,
365  },
366  { 0, 1, 2, 3, 6, 7 },
367  { 0, 1 } },
368  { // subkey bits 18-23
369  {
370  3,
371  2,
372  0,
373  3,
374  0,
375  2,
376  2,
377  1,
378  1,
379  2,
380  3,
381  2,
382  1,
383  3,
384  2,
385  1,
386  2,
387  2,
388  1,
389  3,
390  3,
391  2,
392  1,
393  0,
394  1,
395  0,
396  1,
397  3,
398  0,
399  0,
400  0,
401  2,
402  2,
403  1,
404  0,
405  1,
406  0,
407  1,
408  0,
409  1,
410  3,
411  1,
412  1,
413  2,
414  2,
415  3,
416  2,
417  0,
418  3,
419  3,
420  2,
421  0,
422  2,
423  1,
424  3,
425  3,
426  0,
427  0,
428  3,
429  0,
430  1,
431  1,
432  3,
433  3,
434  },
435  { 0, 1, 3, 5, 6, 7 },
436  { 4, 5 } },
437 };
438 
439 static const struct sbox fn1_rz_boxes[4] = {
440  { // subkey bits 24-29
441  {
442  3,
443  3,
444  2,
445  0,
446  3,
447  0,
448  3,
449  1,
450  0,
451  3,
452  0,
453  1,
454  0,
455  2,
456  1,
457  3,
458  1,
459  3,
460  0,
461  3,
462  3,
463  1,
464  3,
465  3,
466  3,
467  2,
468  3,
469  2,
470  2,
471  3,
472  1,
473  2,
474  0,
475  2,
476  2,
477  1,
478  0,
479  1,
480  2,
481  0,
482  3,
483  3,
484  0,
485  1,
486  3,
487  2,
488  1,
489  2,
490  3,
491  0,
492  1,
493  3,
494  0,
495  1,
496  2,
497  2,
498  1,
499  2,
500  1,
501  2,
502  0,
503  1,
504  3,
505  0,
506  },
507  { 0, 1, 2, 3, 6, -1 },
508  { 1, 6 } },
509  { // subkey bits 30-35
510  {
511  1,
512  2,
513  3,
514  2,
515  1,
516  3,
517  0,
518  1,
519  1,
520  0,
521  2,
522  0,
523  0,
524  2,
525  3,
526  2,
527  3,
528  3,
529  0,
530  1,
531  2,
532  2,
533  1,
534  0,
535  1,
536  0,
537  1,
538  2,
539  3,
540  2,
541  1,
542  3,
543  2,
544  2,
545  2,
546  0,
547  1,
548  0,
549  2,
550  3,
551  2,
552  1,
553  2,
554  1,
555  2,
556  1,
557  0,
558  3,
559  0,
560  1,
561  2,
562  3,
563  1,
564  2,
565  1,
566  3,
567  2,
568  0,
569  3,
570  2,
571  3,
572  0,
573  2,
574  0,
575  },
576  { 2, 4, 5, 6, 7, -1 },
577  { 5, 7 } },
578  { // subkey bits 36-41
579  {
580  0,
581  1,
582  0,
583  2,
584  1,
585  1,
586  0,
587  1,
588  0,
589  2,
590  2,
591  2,
592  1,
593  3,
594  0,
595  0,
596  1,
597  1,
598  3,
599  1,
600  2,
601  2,
602  2,
603  3,
604  1,
605  0,
606  3,
607  3,
608  3,
609  2,
610  2,
611  2,
612  1,
613  1,
614  3,
615  0,
616  3,
617  1,
618  3,
619  0,
620  1,
621  3,
622  3,
623  2,
624  1,
625  1,
626  0,
627  0,
628  1,
629  2,
630  2,
631  2,
632  1,
633  1,
634  1,
635  2,
636  2,
637  0,
638  0,
639  3,
640  2,
641  3,
642  1,
643  3,
644  },
645  { 1, 2, 3, 4, 5, 7 },
646  { 0, 3 } },
647  { // subkey bits 42-47
648  {
649  2,
650  1,
651  0,
652  3,
653  3,
654  3,
655  2,
656  0,
657  1,
658  2,
659  1,
660  1,
661  1,
662  0,
663  3,
664  1,
665  1,
666  3,
667  3,
668  0,
669  1,
670  2,
671  1,
672  0,
673  0,
674  0,
675  3,
676  0,
677  3,
678  0,
679  3,
680  0,
681  1,
682  3,
683  3,
684  3,
685  0,
686  3,
687  2,
688  0,
689  2,
690  1,
691  2,
692  2,
693  2,
694  1,
695  1,
696  3,
697  0,
698  1,
699  0,
700  1,
701  0,
702  1,
703  1,
704  1,
705  1,
706  3,
707  1,
708  0,
709  1,
710  2,
711  3,
712  3,
713  },
714  { 0, 1, 3, 4, 6, 7 },
715  { 2, 4 } },
716 };
717 
718 static const struct sbox fn1_r3_boxes[4] = {
719  { // subkey bits 48-53
720  {
721  0,
722  0,
723  0,
724  3,
725  3,
726  1,
727  1,
728  0,
729  2,
730  0,
731  2,
732  0,
733  0,
734  0,
735  3,
736  2,
737  0,
738  1,
739  2,
740  3,
741  2,
742  2,
743  1,
744  0,
745  3,
746  0,
747  0,
748  0,
749  0,
750  0,
751  2,
752  3,
753  3,
754  0,
755  0,
756  1,
757  1,
758  2,
759  3,
760  3,
761  0,
762  1,
763  3,
764  2,
765  0,
766  1,
767  3,
768  3,
769  2,
770  0,
771  0,
772  1,
773  0,
774  2,
775  0,
776  0,
777  0,
778  3,
779  1,
780  3,
781  3,
782  3,
783  3,
784  3,
785  },
786  { 0, 1, 5, 6, 7, -1 },
787  { 0, 5 } },
788  { // subkey bits 54-59
789  {
790  2,
791  3,
792  2,
793  3,
794  0,
795  2,
796  3,
797  0,
798  2,
799  2,
800  3,
801  0,
802  3,
803  2,
804  0,
805  2,
806  1,
807  0,
808  2,
809  3,
810  1,
811  1,
812  1,
813  0,
814  0,
815  1,
816  0,
817  2,
818  1,
819  2,
820  2,
821  1,
822  3,
823  0,
824  2,
825  1,
826  2,
827  3,
828  3,
829  0,
830  3,
831  2,
832  3,
833  1,
834  0,
835  2,
836  1,
837  0,
838  1,
839  2,
840  2,
841  3,
842  0,
843  2,
844  1,
845  3,
846  1,
847  3,
848  0,
849  2,
850  1,
851  1,
852  1,
853  3,
854  },
855  { 2, 3, 4, 6, 7, -1 },
856  { 6, 7 } },
857  { // subkey bits 60-65
858  {
859  3,
860  0,
861  2,
862  1,
863  1,
864  3,
865  1,
866  2,
867  2,
868  1,
869  2,
870  2,
871  2,
872  0,
873  0,
874  1,
875  2,
876  3,
877  1,
878  0,
879  2,
880  0,
881  0,
882  2,
883  3,
884  1,
885  2,
886  0,
887  0,
888  0,
889  3,
890  0,
891  2,
892  1,
893  1,
894  2,
895  0,
896  0,
897  1,
898  2,
899  3,
900  1,
901  1,
902  2,
903  0,
904  1,
905  3,
906  0,
907  3,
908  1,
909  1,
910  0,
911  0,
912  2,
913  3,
914  0,
915  0,
916  0,
917  0,
918  3,
919  2,
920  0,
921  0,
922  0,
923  },
924  { 0, 2, 3, 4, 5, 6 },
925  { 1, 4 } },
926  { // subkey bits 66-71
927  {
928  0,
929  1,
930  0,
931  0,
932  2,
933  1,
934  3,
935  2,
936  3,
937  3,
938  2,
939  1,
940  0,
941  1,
942  1,
943  1,
944  1,
945  1,
946  0,
947  3,
948  3,
949  1,
950  1,
951  0,
952  0,
953  2,
954  2,
955  1,
956  0,
957  3,
958  3,
959  2,
960  1,
961  3,
962  3,
963  0,
964  3,
965  0,
966  2,
967  1,
968  1,
969  2,
970  3,
971  2,
972  2,
973  2,
974  1,
975  0,
976  0,
977  3,
978  3,
979  3,
980  2,
981  2,
982  3,
983  1,
984  0,
985  2,
986  3,
987  0,
988  3,
989  1,
990  1,
991  0,
992  },
993  { 0, 1, 2, 3, 5, 7 },
994  { 2, 3 } },
995 };
996 
997 static const struct sbox fn1_r4_boxes[4] = {
998  { // subkey bits 72-77
999  {
1000  1,
1001  1,
1002  1,
1003  1,
1004  1,
1005  0,
1006  1,
1007  3,
1008  3,
1009  2,
1010  3,
1011  0,
1012  1,
1013  2,
1014  0,
1015  2,
1016  3,
1017  3,
1018  0,
1019  1,
1020  2,
1021  1,
1022  2,
1023  3,
1024  0,
1025  3,
1026  2,
1027  3,
1028  2,
1029  0,
1030  1,
1031  2,
1032  0,
1033  1,
1034  0,
1035  3,
1036  2,
1037  1,
1038  3,
1039  2,
1040  3,
1041  1,
1042  2,
1043  3,
1044  2,
1045  0,
1046  1,
1047  2,
1048  2,
1049  0,
1050  0,
1051  0,
1052  2,
1053  1,
1054  3,
1055  0,
1056  3,
1057  1,
1058  3,
1059  0,
1060  1,
1061  3,
1062  3,
1063  0,
1064  },
1065  { 1, 2, 3, 4, 5, 7 },
1066  { 0, 4 } },
1067  { // subkey bits 78-83
1068  {
1069  3,
1070  0,
1071  0,
1072  0,
1073  0,
1074  1,
1075  0,
1076  2,
1077  3,
1078  3,
1079  1,
1080  3,
1081  0,
1082  3,
1083  1,
1084  2,
1085  2,
1086  2,
1087  3,
1088  1,
1089  0,
1090  0,
1091  2,
1092  0,
1093  1,
1094  0,
1095  2,
1096  2,
1097  3,
1098  3,
1099  0,
1100  0,
1101  1,
1102  1,
1103  3,
1104  0,
1105  2,
1106  3,
1107  0,
1108  3,
1109  0,
1110  3,
1111  0,
1112  2,
1113  0,
1114  2,
1115  0,
1116  1,
1117  0,
1118  3,
1119  0,
1120  1,
1121  3,
1122  1,
1123  1,
1124  0,
1125  0,
1126  1,
1127  3,
1128  3,
1129  2,
1130  2,
1131  1,
1132  0,
1133  },
1134  { 0, 1, 2, 3, 5, 6 },
1135  { 1, 3 } },
1136  { // subkey bits 84-89
1137  {
1138  0,
1139  1,
1140  1,
1141  2,
1142  0,
1143  1,
1144  3,
1145  1,
1146  2,
1147  0,
1148  3,
1149  2,
1150  0,
1151  0,
1152  3,
1153  0,
1154  3,
1155  0,
1156  1,
1157  2,
1158  2,
1159  3,
1160  3,
1161  2,
1162  3,
1163  2,
1164  0,
1165  1,
1166  0,
1167  0,
1168  1,
1169  0,
1170  3,
1171  0,
1172  2,
1173  3,
1174  0,
1175  2,
1176  2,
1177  2,
1178  1,
1179  1,
1180  0,
1181  2,
1182  2,
1183  0,
1184  0,
1185  1,
1186  2,
1187  1,
1188  1,
1189  1,
1190  2,
1191  3,
1192  0,
1193  3,
1194  1,
1195  2,
1196  3,
1197  3,
1198  1,
1199  1,
1200  3,
1201  0,
1202  },
1203  { 0, 2, 4, 5, 6, 7 },
1204  { 2, 6 } },
1205  { // subkey bits 90-95
1206  {
1207  0,
1208  1,
1209  2,
1210  2,
1211  0,
1212  1,
1213  0,
1214  3,
1215  2,
1216  2,
1217  1,
1218  1,
1219  3,
1220  2,
1221  0,
1222  2,
1223  0,
1224  1,
1225  3,
1226  3,
1227  0,
1228  2,
1229  2,
1230  3,
1231  3,
1232  2,
1233  0,
1234  0,
1235  2,
1236  1,
1237  3,
1238  3,
1239  1,
1240  1,
1241  1,
1242  3,
1243  1,
1244  2,
1245  1,
1246  1,
1247  0,
1248  3,
1249  3,
1250  2,
1251  3,
1252  2,
1253  3,
1254  0,
1255  3,
1256  1,
1257  0,
1258  0,
1259  3,
1260  0,
1261  0,
1262  0,
1263  2,
1264  2,
1265  2,
1266  1,
1267  2,
1268  3,
1269  0,
1270  0,
1271  },
1272  { 0, 1, 3, 4, 6, 7 },
1273  { 5, 7 } },
1274 };
1275 
1276 /******************************************************************************/
1277 
1278 static const struct sbox fn2_r1_boxes[4] = {
1279  { // subkey bits 0- 5
1280  {
1281  2,
1282  0,
1283  2,
1284  0,
1285  3,
1286  0,
1287  0,
1288  3,
1289  1,
1290  1,
1291  0,
1292  1,
1293  3,
1294  2,
1295  0,
1296  1,
1297  2,
1298  0,
1299  1,
1300  2,
1301  0,
1302  2,
1303  0,
1304  2,
1305  2,
1306  2,
1307  3,
1308  0,
1309  2,
1310  1,
1311  3,
1312  0,
1313  0,
1314  1,
1315  0,
1316  1,
1317  2,
1318  2,
1319  3,
1320  3,
1321  0,
1322  3,
1323  0,
1324  2,
1325  3,
1326  0,
1327  1,
1328  2,
1329  1,
1330  1,
1331  0,
1332  2,
1333  0,
1334  3,
1335  1,
1336  1,
1337  2,
1338  2,
1339  1,
1340  3,
1341  1,
1342  1,
1343  3,
1344  1,
1345  },
1346  { 0, 3, 4, 5, 7, -1 },
1347  { 6, 7 } },
1348  { // subkey bits 6-11
1349  {
1350  1,
1351  1,
1352  0,
1353  3,
1354  0,
1355  2,
1356  0,
1357  1,
1358  3,
1359  0,
1360  2,
1361  0,
1362  1,
1363  1,
1364  0,
1365  0,
1366  1,
1367  3,
1368  2,
1369  2,
1370  0,
1371  2,
1372  2,
1373  2,
1374  2,
1375  0,
1376  1,
1377  3,
1378  3,
1379  3,
1380  1,
1381  1,
1382  1,
1383  3,
1384  1,
1385  3,
1386  2,
1387  2,
1388  2,
1389  2,
1390  2,
1391  2,
1392  0,
1393  1,
1394  0,
1395  1,
1396  1,
1397  2,
1398  3,
1399  1,
1400  1,
1401  2,
1402  0,
1403  3,
1404  3,
1405  3,
1406  2,
1407  2,
1408  3,
1409  1,
1410  1,
1411  1,
1412  3,
1413  0,
1414  },
1415  { 1, 2, 3, 4, 6, -1 },
1416  { 3, 5 } },
1417  { // subkey bits 12-17
1418  {
1419  1,
1420  0,
1421  2,
1422  2,
1423  3,
1424  3,
1425  3,
1426  3,
1427  1,
1428  2,
1429  2,
1430  1,
1431  0,
1432  1,
1433  2,
1434  1,
1435  1,
1436  2,
1437  3,
1438  1,
1439  2,
1440  0,
1441  0,
1442  1,
1443  2,
1444  3,
1445  1,
1446  2,
1447  0,
1448  0,
1449  0,
1450  2,
1451  2,
1452  0,
1453  1,
1454  1,
1455  0,
1456  0,
1457  2,
1458  0,
1459  0,
1460  0,
1461  2,
1462  3,
1463  2,
1464  3,
1465  0,
1466  1,
1467  3,
1468  0,
1469  0,
1470  0,
1471  2,
1472  3,
1473  2,
1474  0,
1475  1,
1476  3,
1477  2,
1478  1,
1479  3,
1480  1,
1481  1,
1482  3,
1483  },
1484  { 1, 2, 4, 5, 6, 7 },
1485  { 1, 4 } },
1486  { // subkey bits 18-23
1487  {
1488  1,
1489  3,
1490  3,
1491  0,
1492  3,
1493  2,
1494  3,
1495  1,
1496  3,
1497  2,
1498  1,
1499  1,
1500  3,
1501  3,
1502  2,
1503  1,
1504  2,
1505  3,
1506  0,
1507  3,
1508  1,
1509  0,
1510  0,
1511  2,
1512  3,
1513  0,
1514  0,
1515  0,
1516  3,
1517  3,
1518  0,
1519  1,
1520  2,
1521  3,
1522  0,
1523  0,
1524  0,
1525  1,
1526  2,
1527  1,
1528  3,
1529  0,
1530  0,
1531  1,
1532  0,
1533  2,
1534  2,
1535  2,
1536  3,
1537  3,
1538  1,
1539  2,
1540  1,
1541  3,
1542  0,
1543  0,
1544  0,
1545  3,
1546  0,
1547  1,
1548  3,
1549  2,
1550  2,
1551  0,
1552  },
1553  { 0, 2, 3, 5, 6, 7 },
1554  { 0, 2 } },
1555 };
1556 
1557 static const struct sbox fn2_rz_boxes[4] = {
1558  { // subkey bits 24-29
1559  {
1560  3,
1561  1,
1562  3,
1563  0,
1564  3,
1565  0,
1566  3,
1567  1,
1568  3,
1569  0,
1570  0,
1571  1,
1572  1,
1573  3,
1574  0,
1575  3,
1576  1,
1577  1,
1578  0,
1579  1,
1580  2,
1581  3,
1582  2,
1583  3,
1584  3,
1585  1,
1586  2,
1587  2,
1588  2,
1589  0,
1590  2,
1591  3,
1592  2,
1593  2,
1594  2,
1595  1,
1596  1,
1597  3,
1598  3,
1599  0,
1600  3,
1601  1,
1602  2,
1603  1,
1604  1,
1605  1,
1606  0,
1607  2,
1608  0,
1609  3,
1610  3,
1611  0,
1612  0,
1613  2,
1614  0,
1615  0,
1616  1,
1617  1,
1618  2,
1619  1,
1620  2,
1621  1,
1622  1,
1623  0,
1624  },
1625  { 0, 2, 4, 6, -1, -1 },
1626  { 4, 6 } },
1627  { // subkey bits 30-35
1628  {
1629  0,
1630  3,
1631  0,
1632  3,
1633  3,
1634  2,
1635  1,
1636  2,
1637  3,
1638  1,
1639  1,
1640  1,
1641  2,
1642  0,
1643  2,
1644  3,
1645  0,
1646  3,
1647  1,
1648  2,
1649  2,
1650  1,
1651  3,
1652  3,
1653  3,
1654  2,
1655  1,
1656  2,
1657  2,
1658  0,
1659  1,
1660  0,
1661  2,
1662  3,
1663  0,
1664  1,
1665  2,
1666  0,
1667  1,
1668  1,
1669  2,
1670  0,
1671  2,
1672  1,
1673  2,
1674  0,
1675  2,
1676  3,
1677  3,
1678  1,
1679  0,
1680  2,
1681  3,
1682  3,
1683  0,
1684  3,
1685  1,
1686  1,
1687  3,
1688  0,
1689  0,
1690  1,
1691  2,
1692  0,
1693  },
1694  { 1, 3, 4, 5, 6, 7 },
1695  { 0, 3 } },
1696  { // subkey bits 36-41
1697  {
1698  0,
1699  0,
1700  2,
1701  1,
1702  3,
1703  2,
1704  1,
1705  0,
1706  1,
1707  2,
1708  2,
1709  2,
1710  1,
1711  1,
1712  0,
1713  3,
1714  1,
1715  2,
1716  2,
1717  3,
1718  2,
1719  1,
1720  1,
1721  0,
1722  3,
1723  0,
1724  0,
1725  1,
1726  1,
1727  2,
1728  3,
1729  1,
1730  3,
1731  3,
1732  2,
1733  2,
1734  1,
1735  0,
1736  1,
1737  1,
1738  1,
1739  2,
1740  0,
1741  1,
1742  2,
1743  3,
1744  0,
1745  3,
1746  3,
1747  0,
1748  3,
1749  2,
1750  2,
1751  0,
1752  2,
1753  2,
1754  1,
1755  2,
1756  3,
1757  2,
1758  1,
1759  0,
1760  2,
1761  1,
1762  },
1763  { 0, 1, 3, 4, 5, 7 },
1764  { 1, 7 } },
1765  { // subkey bits 42-47
1766  {
1767  0,
1768  2,
1769  1,
1770  2,
1771  0,
1772  2,
1773  2,
1774  0,
1775  1,
1776  3,
1777  2,
1778  0,
1779  3,
1780  2,
1781  3,
1782  0,
1783  3,
1784  3,
1785  2,
1786  3,
1787  1,
1788  2,
1789  3,
1790  1,
1791  2,
1792  2,
1793  0,
1794  0,
1795  2,
1796  2,
1797  1,
1798  2,
1799  2,
1800  3,
1801  3,
1802  3,
1803  1,
1804  1,
1805  0,
1806  0,
1807  0,
1808  3,
1809  2,
1810  0,
1811  3,
1812  2,
1813  3,
1814  1,
1815  1,
1816  1,
1817  1,
1818  0,
1819  1,
1820  0,
1821  1,
1822  3,
1823  0,
1824  0,
1825  1,
1826  2,
1827  2,
1828  3,
1829  2,
1830  0,
1831  },
1832  { 1, 2, 3, 5, 6, 7 },
1833  { 2, 5 } },
1834 };
1835 
1836 static const struct sbox fn2_r3_boxes[4] = {
1837  { // subkey bits 48-53
1838  {
1839  2,
1840  1,
1841  2,
1842  1,
1843  2,
1844  3,
1845  1,
1846  3,
1847  2,
1848  2,
1849  1,
1850  3,
1851  3,
1852  0,
1853  0,
1854  1,
1855  0,
1856  2,
1857  0,
1858  3,
1859  3,
1860  1,
1861  0,
1862  0,
1863  1,
1864  1,
1865  0,
1866  2,
1867  3,
1868  2,
1869  1,
1870  2,
1871  1,
1872  1,
1873  2,
1874  1,
1875  1,
1876  3,
1877  2,
1878  2,
1879  0,
1880  2,
1881  2,
1882  3,
1883  3,
1884  3,
1885  2,
1886  0,
1887  0,
1888  0,
1889  0,
1890  0,
1891  3,
1892  3,
1893  3,
1894  0,
1895  1,
1896  2,
1897  1,
1898  0,
1899  2,
1900  3,
1901  3,
1902  1,
1903  },
1904  { 2, 3, 4, 6, -1, -1 },
1905  { 3, 5 } },
1906  { // subkey bits 54-59
1907  {
1908  3,
1909  2,
1910  3,
1911  3,
1912  1,
1913  0,
1914  3,
1915  0,
1916  2,
1917  0,
1918  1,
1919  1,
1920  1,
1921  0,
1922  3,
1923  0,
1924  3,
1925  1,
1926  3,
1927  1,
1928  0,
1929  1,
1930  2,
1931  3,
1932  2,
1933  2,
1934  3,
1935  2,
1936  0,
1937  1,
1938  1,
1939  2,
1940  3,
1941  0,
1942  0,
1943  2,
1944  1,
1945  0,
1946  0,
1947  2,
1948  2,
1949  0,
1950  1,
1951  0,
1952  0,
1953  2,
1954  0,
1955  0,
1956  1,
1957  3,
1958  1,
1959  3,
1960  2,
1961  0,
1962  3,
1963  3,
1964  1,
1965  0,
1966  2,
1967  2,
1968  2,
1969  3,
1970  0,
1971  0,
1972  },
1973  { 0, 1, 3, 5, 7, -1 },
1974  { 0, 2 } },
1975  { // subkey bits 60-65
1976  {
1977  2,
1978  2,
1979  1,
1980  0,
1981  2,
1982  3,
1983  3,
1984  0,
1985  0,
1986  0,
1987  1,
1988  3,
1989  1,
1990  2,
1991  3,
1992  2,
1993  2,
1994  3,
1995  1,
1996  3,
1997  0,
1998  3,
1999  0,
2000  3,
2001  3,
2002  2,
2003  2,
2004  1,
2005  0,
2006  0,
2007  0,
2008  2,
2009  1,
2010  2,
2011  2,
2012  2,
2013  0,
2014  0,
2015  1,
2016  2,
2017  0,
2018  1,
2019  3,
2020  0,
2021  2,
2022  3,
2023  2,
2024  1,
2025  3,
2026  2,
2027  2,
2028  2,
2029  3,
2030  1,
2031  3,
2032  0,
2033  2,
2034  0,
2035  2,
2036  1,
2037  0,
2038  3,
2039  3,
2040  1,
2041  },
2042  { 0, 1, 2, 3, 5, 7 },
2043  { 1, 6 } },
2044  { // subkey bits 66-71
2045  {
2046  1,
2047  2,
2048  3,
2049  2,
2050  0,
2051  2,
2052  1,
2053  3,
2054  3,
2055  1,
2056  0,
2057  1,
2058  1,
2059  2,
2060  2,
2061  0,
2062  0,
2063  1,
2064  1,
2065  1,
2066  2,
2067  1,
2068  1,
2069  2,
2070  0,
2071  1,
2072  3,
2073  3,
2074  1,
2075  1,
2076  1,
2077  2,
2078  3,
2079  3,
2080  1,
2081  0,
2082  2,
2083  1,
2084  1,
2085  1,
2086  2,
2087  1,
2088  0,
2089  0,
2090  2,
2091  2,
2092  3,
2093  2,
2094  3,
2095  2,
2096  2,
2097  0,
2098  2,
2099  2,
2100  3,
2101  3,
2102  0,
2103  2,
2104  3,
2105  0,
2106  2,
2107  2,
2108  1,
2109  1,
2110  },
2111  { 0, 2, 4, 5, 6, 7 },
2112  { 4, 7 } },
2113 };
2114 
2115 static const struct sbox fn2_r4_boxes[4] = {
2116  { // subkey bits 72-77
2117  {
2118  2,
2119  0,
2120  1,
2121  1,
2122  2,
2123  1,
2124  3,
2125  3,
2126  1,
2127  1,
2128  1,
2129  2,
2130  0,
2131  1,
2132  0,
2133  2,
2134  0,
2135  1,
2136  2,
2137  0,
2138  2,
2139  3,
2140  0,
2141  2,
2142  3,
2143  3,
2144  2,
2145  2,
2146  3,
2147  2,
2148  0,
2149  1,
2150  3,
2151  0,
2152  2,
2153  0,
2154  2,
2155  3,
2156  1,
2157  3,
2158  2,
2159  0,
2160  0,
2161  1,
2162  1,
2163  2,
2164  3,
2165  1,
2166  1,
2167  1,
2168  0,
2169  1,
2170  2,
2171  0,
2172  3,
2173  3,
2174  1,
2175  1,
2176  1,
2177  3,
2178  3,
2179  1,
2180  1,
2181  0,
2182  },
2183  { 0, 1, 3, 6, 7, -1 },
2184  { 0, 3 } },
2185  { // subkey bits 78-83
2186  {
2187  1,
2188  2,
2189  2,
2190  1,
2191  0,
2192  3,
2193  3,
2194  1,
2195  0,
2196  2,
2197  2,
2198  2,
2199  1,
2200  0,
2201  1,
2202  0,
2203  1,
2204  1,
2205  0,
2206  1,
2207  0,
2208  2,
2209  1,
2210  0,
2211  2,
2212  1,
2213  0,
2214  2,
2215  3,
2216  2,
2217  3,
2218  3,
2219  2,
2220  2,
2221  1,
2222  2,
2223  2,
2224  3,
2225  1,
2226  3,
2227  3,
2228  3,
2229  0,
2230  1,
2231  0,
2232  1,
2233  3,
2234  0,
2235  0,
2236  0,
2237  1,
2238  2,
2239  0,
2240  3,
2241  3,
2242  2,
2243  3,
2244  2,
2245  1,
2246  3,
2247  2,
2248  1,
2249  0,
2250  2,
2251  },
2252  { 0, 1, 2, 4, 5, 6 },
2253  { 4, 7 } },
2254  { // subkey bits 84-89
2255  {
2256  2,
2257  3,
2258  2,
2259  1,
2260  3,
2261  2,
2262  3,
2263  0,
2264  0,
2265  2,
2266  1,
2267  1,
2268  0,
2269  0,
2270  3,
2271  2,
2272  3,
2273  1,
2274  0,
2275  1,
2276  2,
2277  2,
2278  2,
2279  1,
2280  3,
2281  2,
2282  2,
2283  1,
2284  0,
2285  2,
2286  1,
2287  2,
2288  0,
2289  3,
2290  1,
2291  0,
2292  0,
2293  3,
2294  1,
2295  1,
2296  3,
2297  3,
2298  2,
2299  0,
2300  1,
2301  0,
2302  1,
2303  3,
2304  0,
2305  0,
2306  1,
2307  2,
2308  1,
2309  2,
2310  3,
2311  2,
2312  1,
2313  0,
2314  0,
2315  3,
2316  2,
2317  1,
2318  1,
2319  3,
2320  },
2321  { 0, 2, 3, 4, 5, 7 },
2322  { 1, 2 } },
2323  { // subkey bits 90-95
2324  {
2325  2,
2326  0,
2327  0,
2328  3,
2329  2,
2330  2,
2331  2,
2332  1,
2333  3,
2334  3,
2335  1,
2336  1,
2337  2,
2338  0,
2339  0,
2340  3,
2341  1,
2342  0,
2343  3,
2344  2,
2345  1,
2346  0,
2347  2,
2348  0,
2349  3,
2350  2,
2351  2,
2352  3,
2353  2,
2354  0,
2355  3,
2356  0,
2357  1,
2358  3,
2359  0,
2360  2,
2361  2,
2362  1,
2363  3,
2364  3,
2365  0,
2366  1,
2367  0,
2368  3,
2369  1,
2370  1,
2371  3,
2372  2,
2373  0,
2374  3,
2375  0,
2376  2,
2377  3,
2378  2,
2379  1,
2380  3,
2381  2,
2382  3,
2383  0,
2384  0,
2385  1,
2386  3,
2387  2,
2388  1,
2389  },
2390  { 2, 3, 4, 5, 6, 7 },
2391  { 5, 6 } },
2392 };
2393 
2394 /******************************************************************************/
2395 
2396 static ut8 fn(ut8 in, const struct optimised_sbox *sboxes, ut32 key) {
2397  const struct optimised_sbox *sbox1 = &sboxes[0];
2398  const struct optimised_sbox *sbox2 = &sboxes[1];
2399  const struct optimised_sbox *sbox3 = &sboxes[2];
2400  const struct optimised_sbox *sbox4 = &sboxes[3];
2401 
2402  return sbox1->output[sbox1->input_lookup[in] ^ ((key >> 0) & 0x3f)] |
2403  sbox2->output[sbox2->input_lookup[in] ^ ((key >> 6) & 0x3f)] |
2404  sbox3->output[sbox3->input_lookup[in] ^ ((key >> 12) & 0x3f)] |
2405  sbox4->output[sbox4->input_lookup[in] ^ ((key >> 18) & 0x3f)];
2406 }
2407 
2408 // srckey is the 64-bit master key (2x32 bits)
2409 // dstkey will contain the 96-bit key for the 1st FN (4x24 bits)
2410 static void expand_1st_key(ut32 *dstkey, const ut32 *srckey) {
2411  static const int bits[96] = {
2412  33,
2413  58,
2414  49,
2415  36,
2416  0,
2417  31,
2418  22,
2419  30,
2420  3,
2421  16,
2422  5,
2423  53,
2424  10,
2425  41,
2426  23,
2427  19,
2428  27,
2429  39,
2430  43,
2431  6,
2432  34,
2433  12,
2434  61,
2435  21,
2436  48,
2437  13,
2438  32,
2439  35,
2440  6,
2441  42,
2442  43,
2443  14,
2444  21,
2445  41,
2446  52,
2447  25,
2448  18,
2449  47,
2450  46,
2451  37,
2452  57,
2453  53,
2454  20,
2455  8,
2456  55,
2457  54,
2458  59,
2459  60,
2460  27,
2461  33,
2462  35,
2463  18,
2464  8,
2465  15,
2466  63,
2467  1,
2468  50,
2469  44,
2470  16,
2471  46,
2472  5,
2473  4,
2474  45,
2475  51,
2476  38,
2477  25,
2478  13,
2479  11,
2480  62,
2481  29,
2482  48,
2483  2,
2484  59,
2485  61,
2486  62,
2487  56,
2488  51,
2489  57,
2490  54,
2491  9,
2492  24,
2493  63,
2494  22,
2495  7,
2496  26,
2497  42,
2498  45,
2499  40,
2500  23,
2501  14,
2502  2,
2503  31,
2504  52,
2505  28,
2506  44,
2507  17,
2508  };
2509  int i;
2510 
2511  dstkey[0] = 0;
2512  dstkey[1] = 0;
2513  dstkey[2] = 0;
2514  dstkey[3] = 0;
2515 
2516  for (i = 0; i < 96; i++) {
2517  dstkey[i / 24] |= BIT(srckey[bits[i] / 32], bits[i] % 32) << (i % 24);
2518  }
2519 }
2520 
2521 // srckey is the 64-bit master key (2x32 bits) XORed with the subkey
2522 // dstkey will contain the 96-bit key for the 2nd FN (4x24 bits)
2523 static void expand_2nd_key(ut32 *dstkey, const ut32 *srckey) {
2524  static const int bits[96] = {
2525  34,
2526  9,
2527  32,
2528  24,
2529  44,
2530  54,
2531  38,
2532  61,
2533  47,
2534  13,
2535  28,
2536  7,
2537  29,
2538  58,
2539  18,
2540  1,
2541  20,
2542  60,
2543  15,
2544  6,
2545  11,
2546  43,
2547  39,
2548  19,
2549  63,
2550  23,
2551  16,
2552  62,
2553  54,
2554  40,
2555  31,
2556  3,
2557  56,
2558  61,
2559  17,
2560  25,
2561  47,
2562  38,
2563  55,
2564  57,
2565  5,
2566  4,
2567  15,
2568  42,
2569  22,
2570  7,
2571  2,
2572  19,
2573  46,
2574  37,
2575  29,
2576  39,
2577  12,
2578  30,
2579  49,
2580  57,
2581  31,
2582  41,
2583  26,
2584  27,
2585  24,
2586  36,
2587  11,
2588  63,
2589  33,
2590  16,
2591  56,
2592  62,
2593  48,
2594  60,
2595  59,
2596  32,
2597  12,
2598  30,
2599  53,
2600  48,
2601  10,
2602  0,
2603  50,
2604  35,
2605  3,
2606  59,
2607  14,
2608  49,
2609  51,
2610  45,
2611  44,
2612  2,
2613  21,
2614  33,
2615  55,
2616  52,
2617  23,
2618  28,
2619  8,
2620  26,
2621  };
2622  int i;
2623 
2624  dstkey[0] = 0;
2625  dstkey[1] = 0;
2626  dstkey[2] = 0;
2627  dstkey[3] = 0;
2628 
2629  for (i = 0; i < 96; i++) {
2630  dstkey[i / 24] |= BIT(srckey[bits[i] / 32], bits[i] % 32) << (i % 24);
2631  }
2632 }
2633 
2634 // seed is the 16-bit seed generated by the first FN
2635 // subkey will contain the 64-bit key to be XORed with the master key
2636 // for the 2nd FN (2x32 bits)
2637 static void expand_subkey(ut32 *subkey, ut16 seed) {
2638  // Note that each row of the table is a permutation of the seed bits.
2639  static const int bits[64] = {
2640  5,
2641  10,
2642  14,
2643  9,
2644  4,
2645  0,
2646  15,
2647  6,
2648  1,
2649  8,
2650  3,
2651  2,
2652  12,
2653  7,
2654  13,
2655  11,
2656  5,
2657  12,
2658  7,
2659  2,
2660  13,
2661  11,
2662  9,
2663  14,
2664  4,
2665  1,
2666  6,
2667  10,
2668  8,
2669  0,
2670  15,
2671  3,
2672  4,
2673  10,
2674  2,
2675  0,
2676  6,
2677  9,
2678  12,
2679  1,
2680  11,
2681  7,
2682  15,
2683  8,
2684  13,
2685  5,
2686  14,
2687  3,
2688  14,
2689  11,
2690  12,
2691  7,
2692  4,
2693  5,
2694  2,
2695  10,
2696  1,
2697  15,
2698  0,
2699  9,
2700  8,
2701  6,
2702  13,
2703  3,
2704  };
2705  int i;
2706 
2707  subkey[0] = 0;
2708  subkey[1] = 0;
2709 
2710  for (i = 0; i < 64; i++) {
2711  subkey[i / 32] |= BIT(seed, bits[i]) << (i % 32);
2712  }
2713 }
2714 
2715 static inline ut16 feistel(ut16 val, const int *bitsA, const int *bitsB,
2716  const struct optimised_sbox *boxes1, const struct optimised_sbox *boxes2,
2717  const struct optimised_sbox *boxes3, const struct optimised_sbox *boxes4,
2718  ut32 key1, ut32 key2, ut32 key3, ut32 key4) {
2719  ut8 l = BITSWAP8(val, bitsB[7], bitsB[6], bitsB[5], bitsB[4], bitsB[3], bitsB[2], bitsB[1], bitsB[0]);
2720  ut8 r = BITSWAP8(val, bitsA[7], bitsA[6], bitsA[5], bitsA[4], bitsA[3], bitsA[2], bitsA[1], bitsA[0]);
2721 
2722  l ^= fn(r, boxes1, key1);
2723  r ^= fn(l, boxes2, key2);
2724  l ^= fn(r, boxes3, key3);
2725  r ^= fn(l, boxes4, key4);
2726 
2727  return (BIT(l, 0) << bitsA[0]) |
2728  (BIT(l, 1) << bitsA[1]) |
2729  (BIT(l, 2) << bitsA[2]) |
2730  (BIT(l, 3) << bitsA[3]) |
2731  (BIT(l, 4) << bitsA[4]) |
2732  (BIT(l, 5) << bitsA[5]) |
2733  (BIT(l, 6) << bitsA[6]) |
2734  (BIT(l, 7) << bitsA[7]) |
2735  (BIT(r, 0) << bitsB[0]) |
2736  (BIT(r, 1) << bitsB[1]) |
2737  (BIT(r, 2) << bitsB[2]) |
2738  (BIT(r, 3) << bitsB[3]) |
2739  (BIT(r, 4) << bitsB[4]) |
2740  (BIT(r, 5) << bitsB[5]) |
2741  (BIT(r, 6) << bitsB[6]) |
2742  (BIT(r, 7) << bitsB[7]);
2743 }
2744 
2745 static int extract_inputs(ut32 val, const int *inputs) {
2746  int i, res = 0;
2747  for (i = 0; i < 6; i++) {
2748  if (inputs[i] != -1) {
2749  res |= BIT(val, inputs[i]) << i;
2750  }
2751  }
2752  return res;
2753 }
2754 
2755 static void optimise_sboxes(struct optimised_sbox *out, const struct sbox *in) {
2756  int i, box;
2757 
2758  for (box = 0; box < 4; box++) {
2759  // precalculate the input lookup
2760  for (i = 0; i < 256; i++) {
2761  out[box].input_lookup[i] = extract_inputs(i, in[box].inputs);
2762  }
2763  // precalculate the output masks
2764  for (i = 0; i < 64; i++) {
2765  int o = in[box].table[i];
2766  out[box].output[i] = 0;
2767  if (o & 1) {
2768  out[box].output[i] |= 1 << in[box].outputs[0];
2769  }
2770  if (o & 2) {
2771  out[box].output[i] |= 1 << in[box].outputs[1];
2772  }
2773  }
2774  }
2775 }
2776 
2777 static void cps2_crypt(int dir, const ut16 *rom, ut16 *dec, int length, const ut32 *master_key, ut32 upper_limit) {
2778  int i;
2779  ut32 key1[4];
2780  struct optimised_sbox sboxes1[4 * 4];
2781  struct optimised_sbox sboxes2[4 * 4];
2782 
2783  optimise_sboxes(&sboxes1[0 * 4], fn1_r1_boxes);
2784  optimise_sboxes(&sboxes1[1 * 4], fn1_rz_boxes);
2785  optimise_sboxes(&sboxes1[2 * 4], fn1_r3_boxes);
2786  optimise_sboxes(&sboxes1[3 * 4], fn1_r4_boxes);
2787  optimise_sboxes(&sboxes2[0 * 4], fn2_r1_boxes);
2788  optimise_sboxes(&sboxes2[1 * 4], fn2_rz_boxes);
2789  optimise_sboxes(&sboxes2[2 * 4], fn2_r3_boxes);
2790  optimise_sboxes(&sboxes2[3 * 4], fn2_r4_boxes);
2791 
2792  // expand master key to 1st FN 96-bit key
2793  expand_1st_key(key1, master_key);
2794 
2795  // add extra bits for s-boxes with less than 6 inputs
2796  key1[0] ^= BIT(key1[0], 1) << 4;
2797  key1[0] ^= BIT(key1[0], 2) << 5;
2798  key1[0] ^= BIT(key1[0], 8) << 11;
2799  key1[1] ^= BIT(key1[1], 0) << 5;
2800  key1[1] ^= BIT(key1[1], 8) << 11;
2801  key1[2] ^= BIT(key1[2], 1) << 5;
2802  key1[2] ^= BIT(key1[2], 8) << 11;
2803 
2804  for (i = 0; i < 0x10000; i++) {
2805  int a;
2806  ut16 seed;
2807  ut32 subkey[2];
2808  ut32 key2[4];
2809 
2810  if ((i & 0xff) == 0) {
2811  eprintf("Crypting %d%%\r", i * 100 / 0x10000);
2812  }
2813 
2814  // pass the address through FN1
2815  seed = feistel(i, fn1_groupA, fn1_groupB,
2816  &sboxes1[0 * 4], &sboxes1[1 * 4], &sboxes1[2 * 4], &sboxes1[3 * 4],
2817  key1[0], key1[1], key1[2], key1[3]);
2818 
2819  // expand the result to 64-bit
2820  expand_subkey(subkey, seed);
2821 
2822  // XOR with the master key
2823  subkey[0] ^= master_key[0];
2824  subkey[1] ^= master_key[1];
2825 
2826  // expand key to 2nd FN 96-bit key
2827  expand_2nd_key(key2, subkey);
2828 
2829  // add extra bits for s-boxes with less than 6 inputs
2830  key2[0] ^= BIT(key2[0], 0) << 5;
2831  key2[0] ^= BIT(key2[0], 6) << 11;
2832  key2[1] ^= BIT(key2[1], 0) << 5;
2833  key2[1] ^= BIT(key2[1], 1) << 4;
2834  key2[2] ^= BIT(key2[2], 2) << 5;
2835  key2[2] ^= BIT(key2[2], 3) << 4;
2836  key2[2] ^= BIT(key2[2], 7) << 11;
2837  key2[3] ^= BIT(key2[3], 1) << 5;
2838 
2839  // de/en-crypt the opcodes
2840  for (a = i; a < length && a < upper_limit / 2; a += 0x10000) {
2841  if (dir) {
2842  /* decrypt */
2843  dec[a] = feistel(rom[a], fn2_groupA, fn2_groupB,
2844  &sboxes2[0 * 4], &sboxes2[1 * 4], &sboxes2[2 * 4], &sboxes2[3 * 4],
2845  key2[0], key2[1], key2[2], key2[3]);
2846  dec[a] = (dec[a] << 8) | (dec[a] >> 8);
2847  } else {
2848  /* encrypt */
2849  dec[a] = (rom[a] << 8) | (rom[a] >> 8);
2850  dec[a] = feistel(dec[a], fn2_groupA, fn2_groupB,
2851  &sboxes2[3 * 4], &sboxes2[2 * 4], &sboxes2[1 * 4], &sboxes2[0 * 4],
2852  key2[3], key2[2], key2[1], key2[0]);
2853  }
2854  }
2855  // copy the unencrypted part
2856  while (a < length) {
2857  dec[a] = (rom[a] << 8) | (rom[a] >> 8);
2858  a += 0x10000;
2859  }
2860  }
2861 }
2862 
2863 #if 0
2864 main(cps_state,cps2crypt) {
2865  ut32 key[2];
2866  ut32 lower;
2867  ut32 upper;
2868 
2869  std::string skey1 = parameter("cryptkey1");;
2870  key[0] = strtoll(skey1.c_str(), nullptr, 16);
2871 
2872  std::string skey2 = parameter("cryptkey2");
2873  key[1] = strtoll(skey2.c_str(), nullptr, 16);
2874 
2875  std::string slower = parameter("cryptlower");
2876  lower = strtoll(slower.c_str(), nullptr, 16); // unused
2877 
2878  std::string supper = parameter("cryptupper");
2879  upper = strtoll(supper.c_str(), nullptr, 16);
2880 
2881  // we have a proper key so use it to decrypt
2882  if (lower != 0xff0000) {// don't run the decrypt on 'dead key' games for now
2883  cps2_decrypt( (ut16 *)memregion("maincpu")->base(), m_decrypted_opcodes, memregion("maincpu")->bytes(), key, lower,upper);
2884  }
2885 }
2886 #endif
2887 
2888 static bool set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
2889  rz_return_val_if_fail(cry->user && key, false);
2890  ut32 *cps2key = (ut32 *)cry->user;
2891 
2892  cry->dir = direction;
2893  if (keylen == 8) {
2894  /* fix key endianness */
2895  const ut32 *key32 = (const ut32 *)key;
2896  cps2key[0] = rz_read_be32(key32);
2897  cps2key[1] = rz_read_be32(key32 + 1);
2898  return true;
2899  }
2900  return false;
2901 }
2902 
2903 static int get_key_size(RzCrypto *cry) {
2904  /* 64bit key */
2905  return 8;
2906 }
2907 
2908 static bool cps2_use(const char *algo) {
2909  return !strcmp(algo, "cps2");
2910 }
2911 
2912 static bool update(RzCrypto *cry, const ut8 *buf, int len) {
2913  rz_return_val_if_fail(cry->user && len > 0, false);
2914  ut32 *cps2key = (ut32 *)cry->user;
2915 
2916  size_t slen = len / 2;
2917  ut16 *output = RZ_NEWS0(ut16, slen);
2918  if (!output) {
2919  return false;
2920  }
2921  ut16 *input = RZ_NEWS0(ut16, slen);
2922  if (!input) {
2923  free(output);
2924  return false;
2925  }
2926  for (size_t i = 0; i < slen; i++) {
2927  input[i] = rz_read_at_le16(buf, i * 2);
2928  }
2929  /* TODO : control decryption errors */
2930  cps2_crypt(cry->dir, input, output, slen, cps2key, UPPER_LIMIT);
2931  for (size_t i = 0; i < slen; i++) {
2932  rz_write_at_le16((ut8 *)output, output[i], i * 2);
2933  }
2934  rz_crypto_append(cry, (const ut8 *)output, slen * 2);
2935  free(output);
2936  free(input);
2937  return true;
2938 }
2939 
2940 static bool cps2_init(RzCrypto *cry) {
2941  rz_return_val_if_fail(cry, false);
2942 
2943  cry->user = RZ_NEWS0(ut32, 2);
2944  return cry->user != NULL;
2945 }
2946 
2947 static bool cps2_fini(RzCrypto *cry) {
2948  rz_return_val_if_fail(cry, false);
2949 
2950  free(cry->user);
2951  return true;
2952 }
2953 
2955  .name = "cps2",
2956  .author = "pancake,esanfelix,pof",
2957  .license = "LGPL-3",
2958  .set_key = set_key,
2959  .get_key_size = get_key_size,
2960  .use = cps2_use,
2961  .update = update,
2962  .init = cps2_init,
2963  .fini = cps2_fini,
2964 };
2965 
2966 #ifndef RZ_PLUGIN_INCORE
2969  .data = &rz_crypto_plugin_rol,
2970  .version = RZ_VERSION
2971 };
2972 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
static ut8 bytes[32]
Definition: asm_arc.c:23
int bits(struct state *s, int need)
Definition: blast.c:72
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API int rz_crypto_append(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto.c:175
static const struct sbox fn1_r4_boxes[4]
Definition: crypto_cps2.c:997
#define BITSWAP8(val, B7, B6, B5, B4, B3, B2, B1, B0)
Definition: crypto_cps2.c:11
static const struct sbox fn1_rz_boxes[4]
Definition: crypto_cps2.c:439
static ut8 fn(ut8 in, const struct optimised_sbox *sboxes, ut32 key)
Definition: crypto_cps2.c:2396
static bool set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction)
Definition: crypto_cps2.c:2888
static const struct sbox fn2_r1_boxes[4]
Definition: crypto_cps2.c:1278
static const int fn1_groupB[8]
Definition: crypto_cps2.c:135
static const int fn2_groupB[8]
Definition: crypto_cps2.c:138
static ut16 feistel(ut16 val, const int *bitsA, const int *bitsB, const struct optimised_sbox *boxes1, const struct optimised_sbox *boxes2, const struct optimised_sbox *boxes3, const struct optimised_sbox *boxes4, ut32 key1, ut32 key2, ut32 key3, ut32 key4)
Definition: crypto_cps2.c:2715
static bool update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto_cps2.c:2912
static void cps2_crypt(int dir, const ut16 *rom, ut16 *dec, int length, const ut32 *master_key, ut32 upper_limit)
Definition: crypto_cps2.c:2777
static const int fn1_groupA[8]
Definition: crypto_cps2.c:134
static int get_key_size(RzCrypto *cry)
Definition: crypto_cps2.c:2903
static const struct sbox fn2_rz_boxes[4]
Definition: crypto_cps2.c:1557
static const struct sbox fn1_r1_boxes[4]
Definition: crypto_cps2.c:160
static const struct sbox fn2_r3_boxes[4]
Definition: crypto_cps2.c:1836
static const struct sbox fn1_r3_boxes[4]
Definition: crypto_cps2.c:718
static bool cps2_use(const char *algo)
Definition: crypto_cps2.c:2908
RzCryptoPlugin rz_crypto_plugin_cps2
Definition: crypto_cps2.c:2954
static void optimise_sboxes(struct optimised_sbox *out, const struct sbox *in)
Definition: crypto_cps2.c:2755
static const int fn2_groupA[8]
Definition: crypto_cps2.c:137
#define UPPER_LIMIT
Definition: crypto_cps2.c:7
RZ_API RzLibStruct rizin_plugin
Definition: crypto_cps2.c:2967
static const struct sbox fn2_r4_boxes[4]
Definition: crypto_cps2.c:2115
#define BIT(x, n)
Definition: crypto_cps2.c:9
static void expand_2nd_key(ut32 *dstkey, const ut32 *srckey)
Definition: crypto_cps2.c:2523
static void expand_1st_key(ut32 *dstkey, const ut32 *srckey)
Definition: crypto_cps2.c:2410
static bool cps2_fini(RzCrypto *cry)
Definition: crypto_cps2.c:2947
static bool cps2_init(RzCrypto *cry)
Definition: crypto_cps2.c:2940
static void expand_subkey(ut32 *subkey, ut16 seed)
Definition: crypto_cps2.c:2637
static int extract_inputs(ut32 val, const int *inputs)
Definition: crypto_cps2.c:2745
#define r
Definition: crypto_rc6.c:12
RzCryptoPlugin rz_crypto_plugin_rol
Definition: crypto_rol.c:89
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint16_t ut16
uint32_t ut32
static const ut32 sbox3[64]
Definition: des.c:37
static const ut32 sbox1[64]
Definition: des.c:15
static const ut32 sbox4[64]
Definition: des.c:48
static const ut32 sbox2[64]
Definition: des.c:26
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
#define eprintf(x, y...)
Definition: rlcc.c:7
int main(int argc, char **argv)
Definition: rz-bb.c:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static ut16 rz_read_at_le16(const void *src, size_t offset)
Definition: rz_endian.h:214
static void rz_write_at_le16(void *dest, ut16 val, size_t offset)
Definition: rz_endian.h:227
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
@ RZ_LIB_TYPE_CRYPTO
Definition: rz_lib.h:81
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define RZ_VERSION
Definition: rz_version.h:8
#define a(i)
Definition: sha256.c:41
ut8 input_lookup[256]
Definition: crypto_cps2.c:156
ut8 output[64]
Definition: crypto_cps2.c:157
const char * name
Definition: rz_crypto.h:41
void * user
Definition: rz_crypto.h:36
const ut8 table[64]
Definition: crypto_cps2.c:147
const int inputs[6]
Definition: crypto_cps2.c:148
const int outputs[2]
Definition: crypto_cps2.c:149
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
diff_output_t output
Definition: zipcmp.c:237