]> pd.if.org Git - zpackage/blob - libtomcrypt/src/ciphers/camellia.c
0a75087b44e59d50a8752333a6596e18a8a7123b
[zpackage] / libtomcrypt / src / ciphers / camellia.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9
10 /**
11   @file camellia.c
12   Implementation by Tom St Denis of Elliptic Semiconductor
13 */
14
15 #include "tomcrypt.h"
16
17 #ifdef LTC_CAMELLIA
18
19 const struct ltc_cipher_descriptor camellia_desc = {
20    "camellia",
21    23,
22    16, 32, 16, 18,
23    &camellia_setup,
24    &camellia_ecb_encrypt,
25    &camellia_ecb_decrypt,
26    &camellia_test,
27    &camellia_done,
28    &camellia_keysize,
29    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
30 };
31
32 static const ulong32 SP1110[] = {
33 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
34 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
35 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
36 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
37 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
38 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
39 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
40 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
41 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
42 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
43 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
44 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
45 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
46 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
47 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
48 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
49 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
50 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
51 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
52 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
53 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
54 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
55 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
56 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
57 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
58 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
59 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
60 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
61 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
62 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
63 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
64 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
65 };
66
67 static const ulong32 SP0222[] = {
68 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
69 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
70 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
71 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
72 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
73 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
74 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
75 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
76 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
77 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
78 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
79 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
80 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
81 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
82 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
83 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
84 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
85 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
86 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
87 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
88 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
89 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
90 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
91 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
92 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
93 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
94 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
95 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
96 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
97 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
98 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383,
99 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
100 };
101
102 static const ulong32 SP3033[] = {
103 0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
104 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
105 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
106 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
107 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
108 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
109 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
110 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
111 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
112 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
113 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
114 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
115 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
116 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
117 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
118 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
119 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
120 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
121 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
122 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
123 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
124 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
125 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
126 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
127 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
128 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
129 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
130 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
131 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
132 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
133 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
134 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
135 };
136
137 static const ulong32 SP4404[] = {
138 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
139 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
140 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
141 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
142 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
143 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
144 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
145 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
146 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
147 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
148 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
149 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
150 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
151 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
152 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
153 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
154 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
155 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
156 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
157 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
158 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
159 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
160 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
161 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
162 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
163 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
164 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
165 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
166 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
167 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
168 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
169 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
170 };
171
172 static const ulong64 key_sigma[] = {
173    CONST64(0xA09E667F3BCC908B),
174    CONST64(0xB67AE8584CAA73B2),
175    CONST64(0xC6EF372FE94F82BE),
176    CONST64(0x54FF53A5F1D36F1C),
177    CONST64(0x10E527FADE682D1D),
178    CONST64(0xB05688C2B3E6C1FD)
179 };
180
181 static ulong64 F(ulong64 x)
182 {
183    ulong32 D, U;
184
185 #define loc(i) ((8-i)*8)
186
187    D = SP1110[(x >> loc(8)) & 0xFF] ^ SP0222[(x >> loc(5)) & 0xFF] ^ SP3033[(x >> loc(6)) & 0xFF] ^ SP4404[(x >> loc(7)) & 0xFF];
188    U = SP1110[(x >> loc(1)) & 0xFF] ^ SP0222[(x >> loc(2)) & 0xFF] ^ SP3033[(x >> loc(3)) & 0xFF] ^ SP4404[(x >> loc(4)) & 0xFF];
189
190    D ^= U;
191    U = D ^ RORc(U, 8);
192
193    return ((ulong64)U) | (((ulong64)D) << CONST64(32));
194 }
195
196 static void rot_128(unsigned char *in, unsigned count, unsigned char *out)
197 {
198    unsigned x, w, b;
199
200    w = count >> 3;
201    b = count & 7;
202
203    for (x = 0; x < 16; x++) {
204       out[x] = (in[(x+w)&15] << b) | (in[(x+w+1)&15] >> (8 - b));
205    }
206 }
207
208 int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
209 {
210    unsigned char T[48], kA[16], kB[16], kR[16], kL[16];
211    int           x;
212    ulong64       A, B;
213
214    LTC_ARGCHK(key  != NULL);
215    LTC_ARGCHK(skey != NULL);
216
217    /* Valid sizes (in bytes) are 16, 24, 32 */
218    if (keylen != 16 && keylen != 24 && keylen != 32) {
219       return CRYPT_INVALID_KEYSIZE;
220    }
221
222    /* number of rounds */
223    skey->camellia.R = (keylen == 16) ? 18 : 24;
224
225    if (num_rounds != 0 && num_rounds != skey->camellia.R) {
226       return CRYPT_INVALID_ROUNDS;
227    }
228
229    /* expand key */
230    if (keylen == 16) {
231       for (x = 0; x < 16; x++) {
232           T[x]      = key[x];
233           T[x + 16] = 0;
234       }
235    } else if (keylen == 24) {
236       for (x = 0; x < 24; x++) {
237           T[x]      = key[x];
238       }
239       for (x = 24; x < 32; x++) {
240           T[x]      = key[x-8] ^ 0xFF;
241       }
242    } else {
243       for (x = 0; x < 32; x++) {
244           T[x]      = key[x];
245       }
246    }
247
248    for (x = 0; x < 16; x++) {
249       kL[x] = T[x];
250       kR[x] = T[x + 16];
251    }
252
253    for (x = 32; x < 48; x++) {
254       T[x] = T[x - 32] ^ T[x - 16];
255    }
256
257    /* first two rounds */
258    LOAD64H(A, T+32); LOAD64H(B, T+40);
259    B ^= F(A ^ key_sigma[0]);
260    A ^= F(B ^ key_sigma[1]);
261    STORE64H(A, T+32); STORE64H(B, T+40);
262
263    /* xor kL in */
264    for (x = 0; x < 16; x++) { T[x+32] ^= kL[x]; }
265
266    /* next two rounds */
267    LOAD64H(A, T+32); LOAD64H(B, T+40);
268    B ^= F(A ^ key_sigma[2]);
269    A ^= F(B ^ key_sigma[3]);
270    STORE64H(A, T+32); STORE64H(B, T+40);
271
272    /* grab KA */
273    for (x = 0; x < 16; x++) { kA[x] = T[x+32]; }
274
275    /* xor kR in */
276    for (x = 0; x < 16; x++) { T[x+32] ^= kR[x]; }
277
278    if (keylen == 16) {
279       /* grab whitening keys kw1 and kw2 */
280       LOAD64H(skey->camellia.kw[0], kL);
281       LOAD64H(skey->camellia.kw[1], kL+8);
282
283       /* k1-k2 */
284       LOAD64H(skey->camellia.k[0], kA);
285       LOAD64H(skey->camellia.k[1], kA+8);
286
287       /* rotate kL by 15, k3/k4 */
288       rot_128(kL, 15, T+32);
289       LOAD64H(skey->camellia.k[2], T+32);
290       LOAD64H(skey->camellia.k[3], T+40);
291
292       /* rotate kA by 15, k5/k6 */
293       rot_128(kA, 15, T+32);
294       LOAD64H(skey->camellia.k[4], T+32);
295       LOAD64H(skey->camellia.k[5], T+40);
296
297       /* rotate kA by 30, kl1, kl2 */
298       rot_128(kA, 30, T+32);
299       LOAD64H(skey->camellia.kl[0], T+32);
300       LOAD64H(skey->camellia.kl[1], T+40);
301
302       /* rotate kL by 45, k7/k8 */
303       rot_128(kL, 45, T+32);
304       LOAD64H(skey->camellia.k[6], T+32);
305       LOAD64H(skey->camellia.k[7], T+40);
306
307       /* rotate kA by 45, k9/k10 */
308       rot_128(kA, 45, T+32);
309       LOAD64H(skey->camellia.k[8], T+32);
310       rot_128(kL, 60, T+32);
311       LOAD64H(skey->camellia.k[9], T+40);
312
313       /* rotate kA by 60, k11/k12 */
314       rot_128(kA, 60, T+32);
315       LOAD64H(skey->camellia.k[10], T+32);
316       LOAD64H(skey->camellia.k[11], T+40);
317
318       /* rotate kL by 77, kl3, kl4 */
319       rot_128(kL, 77, T+32);
320       LOAD64H(skey->camellia.kl[2], T+32);
321       LOAD64H(skey->camellia.kl[3], T+40);
322
323       /* rotate kL by 94, k13/k14 */
324       rot_128(kL, 94, T+32);
325       LOAD64H(skey->camellia.k[12], T+32);
326       LOAD64H(skey->camellia.k[13], T+40);
327
328       /* rotate kA by 94, k15/k16 */
329       rot_128(kA, 94, T+32);
330       LOAD64H(skey->camellia.k[14], T+32);
331       LOAD64H(skey->camellia.k[15], T+40);
332
333       /* rotate kL by 111, k17/k18 */
334       rot_128(kL, 111, T+32);
335       LOAD64H(skey->camellia.k[16], T+32);
336       LOAD64H(skey->camellia.k[17], T+40);
337
338       /* rotate kA by 111, kw3/kw4 */
339       rot_128(kA, 111, T+32);
340       LOAD64H(skey->camellia.kw[2], T+32);
341       LOAD64H(skey->camellia.kw[3], T+40);
342    } else {
343       /* last two rounds */
344       LOAD64H(A, T+32); LOAD64H(B, T+40);
345       B ^= F(A ^ key_sigma[4]);
346       A ^= F(B ^ key_sigma[5]);
347       STORE64H(A, T+32); STORE64H(B, T+40);
348
349       /* grab kB */
350       for (x = 0; x < 16; x++) { kB[x] = T[x+32]; }
351
352       /* kw1/2 from kL*/
353       LOAD64H(skey->camellia.kw[0], kL);
354       LOAD64H(skey->camellia.kw[1], kL+8);
355
356       /* k1/k2 = kB */
357       LOAD64H(skey->camellia.k[0], kB);
358       LOAD64H(skey->camellia.k[1], kB+8);
359
360       /* k3/k4 = kR by 15 */
361       rot_128(kR, 15, T+32);
362       LOAD64H(skey->camellia.k[2], T+32);
363       LOAD64H(skey->camellia.k[3], T+40);
364
365       /* k5/k7 = kA by 15 */
366       rot_128(kA, 15, T+32);
367       LOAD64H(skey->camellia.k[4], T+32);
368       LOAD64H(skey->camellia.k[5], T+40);
369
370       /* kl1/2 = kR by 30 */
371       rot_128(kR, 30, T+32);
372       LOAD64H(skey->camellia.kl[0], T+32);
373       LOAD64H(skey->camellia.kl[1], T+40);
374
375       /* k7/k8 = kB by 30 */
376       rot_128(kB, 30, T+32);
377       LOAD64H(skey->camellia.k[6], T+32);
378       LOAD64H(skey->camellia.k[7], T+40);
379
380       /* k9/k10 = kL by 45 */
381       rot_128(kL, 45, T+32);
382       LOAD64H(skey->camellia.k[8], T+32);
383       LOAD64H(skey->camellia.k[9], T+40);
384
385       /* k11/k12 = kA by 45 */
386       rot_128(kA, 45, T+32);
387       LOAD64H(skey->camellia.k[10], T+32);
388       LOAD64H(skey->camellia.k[11], T+40);
389
390       /* kl3/4 = kL by 60 */
391       rot_128(kL, 60, T+32);
392       LOAD64H(skey->camellia.kl[2], T+32);
393       LOAD64H(skey->camellia.kl[3], T+40);
394
395       /* k13/k14 = kR by 60 */
396       rot_128(kR, 60, T+32);
397       LOAD64H(skey->camellia.k[12], T+32);
398       LOAD64H(skey->camellia.k[13], T+40);
399
400       /* k15/k16 = kB by 15 */
401       rot_128(kB, 60, T+32);
402       LOAD64H(skey->camellia.k[14], T+32);
403       LOAD64H(skey->camellia.k[15], T+40);
404
405       /* k17/k18 = kL by 77 */
406       rot_128(kL, 77, T+32);
407       LOAD64H(skey->camellia.k[16], T+32);
408       LOAD64H(skey->camellia.k[17], T+40);
409
410       /* kl5/6 = kA by 77  */
411       rot_128(kA, 77, T+32);
412       LOAD64H(skey->camellia.kl[4], T+32);
413       LOAD64H(skey->camellia.kl[5], T+40);
414
415       /* k19/k20 = kR by 94 */
416       rot_128(kR, 94, T+32);
417       LOAD64H(skey->camellia.k[18], T+32);
418       LOAD64H(skey->camellia.k[19], T+40);
419
420       /* k21/k22 = kA by 94 */
421       rot_128(kA, 94, T+32);
422       LOAD64H(skey->camellia.k[20], T+32);
423       LOAD64H(skey->camellia.k[21], T+40);
424
425       /* k23/k24 = kL by 111 */
426       rot_128(kL, 111, T+32);
427       LOAD64H(skey->camellia.k[22], T+32);
428       LOAD64H(skey->camellia.k[23], T+40);
429
430       /* kw2/kw3 = kB by 111 */
431       rot_128(kB, 111, T+32);
432       LOAD64H(skey->camellia.kw[2], T+32);
433       LOAD64H(skey->camellia.kw[3], T+40);
434    }
435
436    return CRYPT_OK;
437 }
438
439 int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
440 {
441    ulong64 L, R;
442    ulong32 a, b;
443
444    LOAD64H(L, pt+0); LOAD64H(R, pt+8);
445    L ^= skey->camellia.kw[0];
446    R ^= skey->camellia.kw[1];
447
448    /* first 6 rounds */
449    R ^= F(L ^ skey->camellia.k[0]);
450    L ^= F(R ^ skey->camellia.k[1]);
451    R ^= F(L ^ skey->camellia.k[2]);
452    L ^= F(R ^ skey->camellia.k[3]);
453    R ^= F(L ^ skey->camellia.k[4]);
454    L ^= F(R ^ skey->camellia.k[5]);
455
456    /* FL */
457    a = (ulong32)(L >> 32);
458    b = (ulong32)(L & 0xFFFFFFFFUL);
459    b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
460    a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
461    L = (((ulong64)a) << 32) | b;
462
463    /* FL^-1 */
464    a = (ulong32)(R >> 32);
465    b = (ulong32)(R & 0xFFFFFFFFUL);
466    a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
467    b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
468    R = (((ulong64)a) << 32) | b;
469
470    /* second 6 rounds */
471    R ^= F(L ^ skey->camellia.k[6]);
472    L ^= F(R ^ skey->camellia.k[7]);
473    R ^= F(L ^ skey->camellia.k[8]);
474    L ^= F(R ^ skey->camellia.k[9]);
475    R ^= F(L ^ skey->camellia.k[10]);
476    L ^= F(R ^ skey->camellia.k[11]);
477
478    /* FL */
479    a = (ulong32)(L >> 32);
480    b = (ulong32)(L & 0xFFFFFFFFUL);
481    b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
482    a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
483    L = (((ulong64)a) << 32) | b;
484
485    /* FL^-1 */
486    a = (ulong32)(R >> 32);
487    b = (ulong32)(R & 0xFFFFFFFFUL);
488    a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
489    b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
490    R = (((ulong64)a) << 32) | b;
491
492    /* third 6 rounds */
493    R ^= F(L ^ skey->camellia.k[12]);
494    L ^= F(R ^ skey->camellia.k[13]);
495    R ^= F(L ^ skey->camellia.k[14]);
496    L ^= F(R ^ skey->camellia.k[15]);
497    R ^= F(L ^ skey->camellia.k[16]);
498    L ^= F(R ^ skey->camellia.k[17]);
499
500    /* next FL */
501    if (skey->camellia.R == 24) {
502       /* FL */
503       a = (ulong32)(L >> 32);
504       b = (ulong32)(L & 0xFFFFFFFFUL);
505       b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
506       a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
507       L = (((ulong64)a) << 32) | b;
508
509       /* FL^-1 */
510       a = (ulong32)(R >> 32);
511       b = (ulong32)(R & 0xFFFFFFFFUL);
512       a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
513       b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
514       R = (((ulong64)a) << 32) | b;
515
516       /* fourth 6 rounds */
517       R ^= F(L ^ skey->camellia.k[18]);
518       L ^= F(R ^ skey->camellia.k[19]);
519       R ^= F(L ^ skey->camellia.k[20]);
520       L ^= F(R ^ skey->camellia.k[21]);
521       R ^= F(L ^ skey->camellia.k[22]);
522       L ^= F(R ^ skey->camellia.k[23]);
523    }
524
525    L ^= skey->camellia.kw[3];
526    R ^= skey->camellia.kw[2];
527
528    STORE64H(R, ct+0); STORE64H(L, ct+8);
529
530    return CRYPT_OK;
531 }
532
533 int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
534 {
535    ulong64 L, R;
536    ulong32 a, b;
537
538    LOAD64H(R, ct+0); LOAD64H(L, ct+8);
539    L ^= skey->camellia.kw[3];
540    R ^= skey->camellia.kw[2];
541
542    /* next FL */
543    if (skey->camellia.R == 24) {
544       /* fourth 6 rounds */
545       L ^= F(R ^ skey->camellia.k[23]);
546       R ^= F(L ^ skey->camellia.k[22]);
547       L ^= F(R ^ skey->camellia.k[21]);
548       R ^= F(L ^ skey->camellia.k[20]);
549       L ^= F(R ^ skey->camellia.k[19]);
550       R ^= F(L ^ skey->camellia.k[18]);
551
552       /* FL */
553       a = (ulong32)(L >> 32);
554       b = (ulong32)(L & 0xFFFFFFFFUL);
555       a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
556       b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
557       L = (((ulong64)a) << 32) | b;
558
559       /* FL^-1 */
560       a = (ulong32)(R >> 32);
561       b = (ulong32)(R & 0xFFFFFFFFUL);
562       b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
563       a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
564       R = (((ulong64)a) << 32) | b;
565
566    }
567
568    /* third 6 rounds */
569    L ^= F(R ^ skey->camellia.k[17]);
570    R ^= F(L ^ skey->camellia.k[16]);
571    L ^= F(R ^ skey->camellia.k[15]);
572    R ^= F(L ^ skey->camellia.k[14]);
573    L ^= F(R ^ skey->camellia.k[13]);
574    R ^= F(L ^ skey->camellia.k[12]);
575
576    /* FL */
577    a = (ulong32)(L >> 32);
578    b = (ulong32)(L & 0xFFFFFFFFUL);
579    a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
580    b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
581    L = (((ulong64)a) << 32) | b;
582
583    /* FL^-1 */
584    a = (ulong32)(R >> 32);
585    b = (ulong32)(R & 0xFFFFFFFFUL);
586    b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
587    a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
588    R = (((ulong64)a) << 32) | b;
589
590    /* second 6 rounds */
591    L ^= F(R ^ skey->camellia.k[11]);
592    R ^= F(L ^ skey->camellia.k[10]);
593    L ^= F(R ^ skey->camellia.k[9]);
594    R ^= F(L ^ skey->camellia.k[8]);
595    L ^= F(R ^ skey->camellia.k[7]);
596    R ^= F(L ^ skey->camellia.k[6]);
597
598    /* FL */
599    a = (ulong32)(L >> 32);
600    b = (ulong32)(L & 0xFFFFFFFFUL);
601    a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
602    b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
603    L = (((ulong64)a) << 32) | b;
604
605    /* FL^-1 */
606    a = (ulong32)(R >> 32);
607    b = (ulong32)(R & 0xFFFFFFFFUL);
608    b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
609    a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
610    R = (((ulong64)a) << 32) | b;
611
612    /* first 6 rounds */
613    L ^= F(R ^ skey->camellia.k[5]);
614    R ^= F(L ^ skey->camellia.k[4]);
615    L ^= F(R ^ skey->camellia.k[3]);
616    R ^= F(L ^ skey->camellia.k[2]);
617    L ^= F(R ^ skey->camellia.k[1]);
618    R ^= F(L ^ skey->camellia.k[0]);
619
620    R ^= skey->camellia.kw[1];
621    L ^= skey->camellia.kw[0];
622
623    STORE64H(R, pt+8); STORE64H(L, pt+0);
624
625    return CRYPT_OK;
626 }
627
628 int camellia_test(void)
629 {
630    static const struct {
631       int keylen;
632       unsigned char key[32], pt[16], ct[16];
633    } tests[] = {
634
635 {
636    16,
637    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
638      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
639    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
640      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
641    { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
642      0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }
643 },
644
645 {
646    24,
647    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
648      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
649      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
650    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
651      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
652    { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
653      0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }
654 },
655
656
657 {
658    32,
659    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
660      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
661      0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
662      0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
663    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
664      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
665    { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
666      0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }
667 },
668
669 {
670    32,
671    { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
672      0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
673      0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
674      0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 },
675    { 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
676      0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 },
677    { 0x79, 0x60, 0x10, 0x9F, 0xB6, 0xDC, 0x42, 0x94,
678      0x7F, 0xCF, 0xE5, 0x9E, 0xA3, 0xC5, 0xEB, 0x6B  }
679 }
680 };
681    unsigned char buf[2][16];
682    symmetric_key skey;
683    int err;
684    unsigned int x;
685
686    for (x = 0; x < sizeof(tests)/sizeof(tests[0]); x++) {
687       zeromem(&skey, sizeof(skey));
688       if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
689          return err;
690       }
691       if ((err = camellia_ecb_encrypt(tests[x].pt, buf[0], &skey)) != CRYPT_OK) {
692          camellia_done(&skey);
693          return err;
694       }
695       if ((err = camellia_ecb_decrypt(tests[x].ct, buf[1], &skey)) != CRYPT_OK) {
696          camellia_done(&skey);
697          return err;
698       }
699       camellia_done(&skey);
700       if (compare_testvector(tests[x].ct, 16, buf[0], 16, "Camellia Encrypt", x) ||
701             compare_testvector(tests[x].pt, 16, buf[1], 16, "Camellia Decrypt", x)) {
702          return CRYPT_FAIL_TESTVECTOR;
703       }
704    }
705    return CRYPT_OK;
706 }
707
708 void camellia_done(symmetric_key *skey)
709 {
710   LTC_UNUSED_PARAM(skey);
711 }
712
713 int camellia_keysize(int *keysize)
714 {
715    if (*keysize >= 32) { *keysize = 32; }
716    else if (*keysize >= 24) { *keysize = 24; }
717    else if (*keysize >= 16) { *keysize = 16; }
718    else return CRYPT_INVALID_KEYSIZE;
719    return CRYPT_OK;
720 }
721
722 #endif
723
724 /* ref:         $Format:%D$ */
725 /* git commit:  $Format:%H$ */
726 /* commit time: $Format:%ai$ */