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