comparison libtomcrypt/src/ciphers/camellia.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
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$ */