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 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 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 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 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 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 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 706 void camellia_done(symmetric_key *skey) 707 { 708 LTC_UNUSED_PARAM(skey); 709 } 710 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