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