// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright ( C ) 2006
* NTT ( Nippon Telegraph and Telephone Corporation ) .
*/
/*
* Algorithm Specification
* https : //info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
*/
#include <crypto/algapi.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/unaligned.h>
static const u32 camellia_sp1110[256 ] = {
0 x70707000, 0 x82828200, 0 x2c2c2c00, 0 xececec00,
0 xb3b3b300, 0 x27272700, 0 xc0c0c000, 0 xe5e5e500,
0 xe4e4e400, 0 x85858500, 0 x57575700, 0 x35353500,
0 xeaeaea00, 0 x0c0c0c00, 0 xaeaeae00, 0 x41414100,
0 x23232300, 0 xefefef00, 0 x6b6b6b00, 0 x93939300,
0 x45454500, 0 x19191900, 0 xa5a5a500, 0 x21212100,
0 xededed00, 0 x0e0e0e00, 0 x4f4f4f00, 0 x4e4e4e00,
0 x1d1d1d00, 0 x65656500, 0 x92929200, 0 xbdbdbd00,
0 x86868600, 0 xb8b8b800, 0 xafafaf00, 0 x8f8f8f00,
0 x7c7c7c00, 0 xebebeb00, 0 x1f1f1f00, 0 xcecece00,
0 x3e3e3e00, 0 x30303000, 0 xdcdcdc00, 0 x5f5f5f00,
0 x5e5e5e00, 0 xc5c5c500, 0 x0b0b0b00, 0 x1a1a1a00,
0 xa6a6a600, 0 xe1e1e100, 0 x39393900, 0 xcacaca00,
0 xd5d5d500, 0 x47474700, 0 x5d5d5d00, 0 x3d3d3d00,
0 xd9d9d900, 0 x01010100, 0 x5a5a5a00, 0 xd6d6d600,
0 x51515100, 0 x56565600, 0 x6c6c6c00, 0 x4d4d4d00,
0 x8b8b8b00, 0 x0d0d0d00, 0 x9a9a9a00, 0 x66666600,
0 xfbfbfb00, 0 xcccccc00, 0 xb0b0b000, 0 x2d2d2d00,
0 x74747400, 0 x12121200, 0 x2b2b2b00, 0 x20202000,
0 xf0f0f000, 0 xb1b1b100, 0 x84848400, 0 x99999900,
0 xdfdfdf00, 0 x4c4c4c00, 0 xcbcbcb00, 0 xc2c2c200,
0 x34343400, 0 x7e7e7e00, 0 x76767600, 0 x05050500,
0 x6d6d6d00, 0 xb7b7b700, 0 xa9a9a900, 0 x31313100,
0 xd1d1d100, 0 x17171700, 0 x04040400, 0 xd7d7d700,
0 x14141400, 0 x58585800, 0 x3a3a3a00, 0 x61616100,
0 xdedede00, 0 x1b1b1b00, 0 x11111100, 0 x1c1c1c00,
0 x32323200, 0 x0f0f0f00, 0 x9c9c9c00, 0 x16161600,
0 x53535300, 0 x18181800, 0 xf2f2f200, 0 x22222200,
0 xfefefe00, 0 x44444400, 0 xcfcfcf00, 0 xb2b2b200,
0 xc3c3c300, 0 xb5b5b500, 0 x7a7a7a00, 0 x91919100,
0 x24242400, 0 x08080800, 0 xe8e8e800, 0 xa8a8a800,
0 x60606000, 0 xfcfcfc00, 0 x69696900, 0 x50505000,
0 xaaaaaa00, 0 xd0d0d000, 0 xa0a0a000, 0 x7d7d7d00,
0 xa1a1a100, 0 x89898900, 0 x62626200, 0 x97979700,
0 x54545400, 0 x5b5b5b00, 0 x1e1e1e00, 0 x95959500,
0 xe0e0e000, 0 xffffff00, 0 x64646400, 0 xd2d2d200,
0 x10101000, 0 xc4c4c400, 0 x00000000, 0 x48484800,
0 xa3a3a300, 0 xf7f7f700, 0 x75757500, 0 xdbdbdb00,
0 x8a8a8a00, 0 x03030300, 0 xe6e6e600, 0 xdadada00,
0 x09090900, 0 x3f3f3f00, 0 xdddddd00, 0 x94949400,
0 x87878700, 0 x5c5c5c00, 0 x83838300, 0 x02020200,
0 xcdcdcd00, 0 x4a4a4a00, 0 x90909000, 0 x33333300,
0 x73737300, 0 x67676700, 0 xf6f6f600, 0 xf3f3f300,
0 x9d9d9d00, 0 x7f7f7f00, 0 xbfbfbf00, 0 xe2e2e200,
0 x52525200, 0 x9b9b9b00, 0 xd8d8d800, 0 x26262600,
0 xc8c8c800, 0 x37373700, 0 xc6c6c600, 0 x3b3b3b00,
0 x81818100, 0 x96969600, 0 x6f6f6f00, 0 x4b4b4b00,
0 x13131300, 0 xbebebe00, 0 x63636300, 0 x2e2e2e00,
0 xe9e9e900, 0 x79797900, 0 xa7a7a700, 0 x8c8c8c00,
0 x9f9f9f00, 0 x6e6e6e00, 0 xbcbcbc00, 0 x8e8e8e00,
0 x29292900, 0 xf5f5f500, 0 xf9f9f900, 0 xb6b6b600,
0 x2f2f2f00, 0 xfdfdfd00, 0 xb4b4b400, 0 x59595900,
0 x78787800, 0 x98989800, 0 x06060600, 0 x6a6a6a00,
0 xe7e7e700, 0 x46464600, 0 x71717100, 0 xbababa00,
0 xd4d4d400, 0 x25252500, 0 xababab00, 0 x42424200,
0 x88888800, 0 xa2a2a200, 0 x8d8d8d00, 0 xfafafa00,
0 x72727200, 0 x07070700, 0 xb9b9b900, 0 x55555500,
0 xf8f8f800, 0 xeeeeee00, 0 xacacac00, 0 x0a0a0a00,
0 x36363600, 0 x49494900, 0 x2a2a2a00, 0 x68686800,
0 x3c3c3c00, 0 x38383800, 0 xf1f1f100, 0 xa4a4a400,
0 x40404000, 0 x28282800, 0 xd3d3d300, 0 x7b7b7b00,
0 xbbbbbb00, 0 xc9c9c900, 0 x43434300, 0 xc1c1c100,
0 x15151500, 0 xe3e3e300, 0 xadadad00, 0 xf4f4f400,
0 x77777700, 0 xc7c7c700, 0 x80808000, 0 x9e9e9e00,
};
static const u32 camellia_sp0222[256 ] = {
0 x00e0e0e0, 0 x00050505, 0 x00585858, 0 x00d9d9d9,
0 x00676767, 0 x004e4e4e, 0 x00818181, 0 x00cbcbcb,
0 x00c9c9c9, 0 x000b0b0b, 0 x00aeaeae, 0 x006a6a6a,
0 x00d5d5d5, 0 x00181818, 0 x005d5d5d, 0 x00828282,
0 x00464646, 0 x00dfdfdf, 0 x00d6d6d6, 0 x00272727,
0 x008a8a8a, 0 x00323232, 0 x004b4b4b, 0 x00424242,
0 x00dbdbdb, 0 x001c1c1c, 0 x009e9e9e, 0 x009c9c9c,
0 x003a3a3a, 0 x00cacaca, 0 x00252525, 0 x007b7b7b,
0 x000d0d0d, 0 x00717171, 0 x005f5f5f, 0 x001f1f1f,
0 x00f8f8f8, 0 x00d7d7d7, 0 x003e3e3e, 0 x009d9d9d,
0 x007c7c7c, 0 x00606060, 0 x00b9b9b9, 0 x00bebebe,
0 x00bcbcbc, 0 x008b8b8b, 0 x00161616, 0 x00343434,
0 x004d4d4d, 0 x00c3c3c3, 0 x00727272, 0 x00959595,
0 x00ababab, 0 x008e8e8e, 0 x00bababa, 0 x007a7a7a,
0 x00b3b3b3, 0 x00020202, 0 x00b4b4b4, 0 x00adadad,
0 x00a2a2a2, 0 x00acacac, 0 x00d8d8d8, 0 x009a9a9a,
0 x00171717, 0 x001a1a1a, 0 x00353535, 0 x00cccccc,
0 x00f7f7f7, 0 x00999999, 0 x00616161, 0 x005a5a5a,
0 x00e8e8e8, 0 x00242424, 0 x00565656, 0 x00404040,
0 x00e1e1e1, 0 x00636363, 0 x00090909, 0 x00333333,
0 x00bfbfbf, 0 x00989898, 0 x00979797, 0 x00858585,
0 x00686868, 0 x00fcfcfc, 0 x00ececec, 0 x000a0a0a,
0 x00dadada, 0 x006f6f6f, 0 x00535353, 0 x00626262,
0 x00a3a3a3, 0 x002e2e2e, 0 x00080808, 0 x00afafaf,
0 x00282828, 0 x00b0b0b0, 0 x00747474, 0 x00c2c2c2,
0 x00bdbdbd, 0 x00363636, 0 x00222222, 0 x00383838,
0 x00646464, 0 x001e1e1e, 0 x00393939, 0 x002c2c2c,
0 x00a6a6a6, 0 x00303030, 0 x00e5e5e5, 0 x00444444,
0 x00fdfdfd, 0 x00888888, 0 x009f9f9f, 0 x00656565,
0 x00878787, 0 x006b6b6b, 0 x00f4f4f4, 0 x00232323,
0 x00484848, 0 x00101010, 0 x00d1d1d1, 0 x00515151,
0 x00c0c0c0, 0 x00f9f9f9, 0 x00d2d2d2, 0 x00a0a0a0,
0 x00555555, 0 x00a1a1a1, 0 x00414141, 0 x00fafafa,
0 x00434343, 0 x00131313, 0 x00c4c4c4, 0 x002f2f2f,
0 x00a8a8a8, 0 x00b6b6b6, 0 x003c3c3c, 0 x002b2b2b,
0 x00c1c1c1, 0 x00ffffff, 0 x00c8c8c8, 0 x00a5a5a5,
0 x00202020, 0 x00898989, 0 x00000000, 0 x00909090,
0 x00474747, 0 x00efefef, 0 x00eaeaea, 0 x00b7b7b7,
0 x00151515, 0 x00060606, 0 x00cdcdcd, 0 x00b5b5b5,
0 x00121212, 0 x007e7e7e, 0 x00bbbbbb, 0 x00292929,
0 x000f0f0f, 0 x00b8b8b8, 0 x00070707, 0 x00040404,
0 x009b9b9b, 0 x00949494, 0 x00212121, 0 x00666666,
0 x00e6e6e6, 0 x00cecece, 0 x00ededed, 0 x00e7e7e7,
0 x003b3b3b, 0 x00fefefe, 0 x007f7f7f, 0 x00c5c5c5,
0 x00a4a4a4, 0 x00373737, 0 x00b1b1b1, 0 x004c4c4c,
0 x00919191, 0 x006e6e6e, 0 x008d8d8d, 0 x00767676,
0 x00030303, 0 x002d2d2d, 0 x00dedede, 0 x00969696,
0 x00262626, 0 x007d7d7d, 0 x00c6c6c6, 0 x005c5c5c,
0 x00d3d3d3, 0 x00f2f2f2, 0 x004f4f4f, 0 x00191919,
0 x003f3f3f, 0 x00dcdcdc, 0 x00797979, 0 x001d1d1d,
0 x00525252, 0 x00ebebeb, 0 x00f3f3f3, 0 x006d6d6d,
0 x005e5e5e, 0 x00fbfbfb, 0 x00696969, 0 x00b2b2b2,
0 x00f0f0f0, 0 x00313131, 0 x000c0c0c, 0 x00d4d4d4,
0 x00cfcfcf, 0 x008c8c8c, 0 x00e2e2e2, 0 x00757575,
0 x00a9a9a9, 0 x004a4a4a, 0 x00575757, 0 x00848484,
0 x00111111, 0 x00454545, 0 x001b1b1b, 0 x00f5f5f5,
0 x00e4e4e4, 0 x000e0e0e, 0 x00737373, 0 x00aaaaaa,
0 x00f1f1f1, 0 x00dddddd, 0 x00595959, 0 x00141414,
0 x006c6c6c, 0 x00929292, 0 x00545454, 0 x00d0d0d0,
0 x00787878, 0 x00707070, 0 x00e3e3e3, 0 x00494949,
0 x00808080, 0 x00505050, 0 x00a7a7a7, 0 x00f6f6f6,
0 x00777777, 0 x00939393, 0 x00868686, 0 x00838383,
0 x002a2a2a, 0 x00c7c7c7, 0 x005b5b5b, 0 x00e9e9e9,
0 x00eeeeee, 0 x008f8f8f, 0 x00010101, 0 x003d3d3d,
};
static const u32 camellia_sp3033[256 ] = {
0 x38003838, 0 x41004141, 0 x16001616, 0 x76007676,
0 xd900d9d9, 0 x93009393, 0 x60006060, 0 xf200f2f2,
0 x72007272, 0 xc200c2c2, 0 xab00abab, 0 x9a009a9a,
0 x75007575, 0 x06000606, 0 x57005757, 0 xa000a0a0,
0 x91009191, 0 xf700f7f7, 0 xb500b5b5, 0 xc900c9c9,
0 xa200a2a2, 0 x8c008c8c, 0 xd200d2d2, 0 x90009090,
0 xf600f6f6, 0 x07000707, 0 xa700a7a7, 0 x27002727,
0 x8e008e8e, 0 xb200b2b2, 0 x49004949, 0 xde00dede,
0 x43004343, 0 x5c005c5c, 0 xd700d7d7, 0 xc700c7c7,
0 x3e003e3e, 0 xf500f5f5, 0 x8f008f8f, 0 x67006767,
0 x1f001f1f, 0 x18001818, 0 x6e006e6e, 0 xaf00afaf,
0 x2f002f2f, 0 xe200e2e2, 0 x85008585, 0 x0d000d0d,
0 x53005353, 0 xf000f0f0, 0 x9c009c9c, 0 x65006565,
0 xea00eaea, 0 xa300a3a3, 0 xae00aeae, 0 x9e009e9e,
0 xec00ecec, 0 x80008080, 0 x2d002d2d, 0 x6b006b6b,
0 xa800a8a8, 0 x2b002b2b, 0 x36003636, 0 xa600a6a6,
0 xc500c5c5, 0 x86008686, 0 x4d004d4d, 0 x33003333,
0 xfd00fdfd, 0 x66006666, 0 x58005858, 0 x96009696,
0 x3a003a3a, 0 x09000909, 0 x95009595, 0 x10001010,
0 x78007878, 0 xd800d8d8, 0 x42004242, 0 xcc00cccc,
0 xef00efef, 0 x26002626, 0 xe500e5e5, 0 x61006161,
0 x1a001a1a, 0 x3f003f3f, 0 x3b003b3b, 0 x82008282,
0 xb600b6b6, 0 xdb00dbdb, 0 xd400d4d4, 0 x98009898,
0 xe800e8e8, 0 x8b008b8b, 0 x02000202, 0 xeb00ebeb,
0 x0a000a0a, 0 x2c002c2c, 0 x1d001d1d, 0 xb000b0b0,
0 x6f006f6f, 0 x8d008d8d, 0 x88008888, 0 x0e000e0e,
0 x19001919, 0 x87008787, 0 x4e004e4e, 0 x0b000b0b,
0 xa900a9a9, 0 x0c000c0c, 0 x79007979, 0 x11001111,
0 x7f007f7f, 0 x22002222, 0 xe700e7e7, 0 x59005959,
0 xe100e1e1, 0 xda00dada, 0 x3d003d3d, 0 xc800c8c8,
0 x12001212, 0 x04000404, 0 x74007474, 0 x54005454,
0 x30003030, 0 x7e007e7e, 0 xb400b4b4, 0 x28002828,
0 x55005555, 0 x68006868, 0 x50005050, 0 xbe00bebe,
0 xd000d0d0, 0 xc400c4c4, 0 x31003131, 0 xcb00cbcb,
0 x2a002a2a, 0 xad00adad, 0 x0f000f0f, 0 xca00caca,
0 x70007070, 0 xff00ffff, 0 x32003232, 0 x69006969,
0 x08000808, 0 x62006262, 0 x00000000, 0 x24002424,
0 xd100d1d1, 0 xfb00fbfb, 0 xba00baba, 0 xed00eded,
0 x45004545, 0 x81008181, 0 x73007373, 0 x6d006d6d,
0 x84008484, 0 x9f009f9f, 0 xee00eeee, 0 x4a004a4a,
0 xc300c3c3, 0 x2e002e2e, 0 xc100c1c1, 0 x01000101,
0 xe600e6e6, 0 x25002525, 0 x48004848, 0 x99009999,
0 xb900b9b9, 0 xb300b3b3, 0 x7b007b7b, 0 xf900f9f9,
0 xce00cece, 0 xbf00bfbf, 0 xdf00dfdf, 0 x71007171,
0 x29002929, 0 xcd00cdcd, 0 x6c006c6c, 0 x13001313,
0 x64006464, 0 x9b009b9b, 0 x63006363, 0 x9d009d9d,
0 xc000c0c0, 0 x4b004b4b, 0 xb700b7b7, 0 xa500a5a5,
0 x89008989, 0 x5f005f5f, 0 xb100b1b1, 0 x17001717,
0 xf400f4f4, 0 xbc00bcbc, 0 xd300d3d3, 0 x46004646,
0 xcf00cfcf, 0 x37003737, 0 x5e005e5e, 0 x47004747,
0 x94009494, 0 xfa00fafa, 0 xfc00fcfc, 0 x5b005b5b,
0 x97009797, 0 xfe00fefe, 0 x5a005a5a, 0 xac00acac,
0 x3c003c3c, 0 x4c004c4c, 0 x03000303, 0 x35003535,
0 xf300f3f3, 0 x23002323, 0 xb800b8b8, 0 x5d005d5d,
0 x6a006a6a, 0 x92009292, 0 xd500d5d5, 0 x21002121,
0 x44004444, 0 x51005151, 0 xc600c6c6, 0 x7d007d7d,
0 x39003939, 0 x83008383, 0 xdc00dcdc, 0 xaa00aaaa,
0 x7c007c7c, 0 x77007777, 0 x56005656, 0 x05000505,
0 x1b001b1b, 0 xa400a4a4, 0 x15001515, 0 x34003434,
0 x1e001e1e, 0 x1c001c1c, 0 xf800f8f8, 0 x52005252,
0 x20002020, 0 x14001414, 0 xe900e9e9, 0 xbd00bdbd,
0 xdd00dddd, 0 xe400e4e4, 0 xa100a1a1, 0 xe000e0e0,
0 x8a008a8a, 0 xf100f1f1, 0 xd600d6d6, 0 x7a007a7a,
0 xbb00bbbb, 0 xe300e3e3, 0 x40004040, 0 x4f004f4f,
};
static const u32 camellia_sp4404[256 ] = {
0 x70700070, 0 x2c2c002c, 0 xb3b300b3, 0 xc0c000c0,
0 xe4e400e4, 0 x57570057, 0 xeaea00ea, 0 xaeae00ae,
0 x23230023, 0 x6b6b006b, 0 x45450045, 0 xa5a500a5,
0 xeded00ed, 0 x4f4f004f, 0 x1d1d001d, 0 x92920092,
0 x86860086, 0 xafaf00af, 0 x7c7c007c, 0 x1f1f001f,
0 x3e3e003e, 0 xdcdc00dc, 0 x5e5e005e, 0 x0b0b000b,
0 xa6a600a6, 0 x39390039, 0 xd5d500d5, 0 x5d5d005d,
0 xd9d900d9, 0 x5a5a005a, 0 x51510051, 0 x6c6c006c,
0 x8b8b008b, 0 x9a9a009a, 0 xfbfb00fb, 0 xb0b000b0,
0 x74740074, 0 x2b2b002b, 0 xf0f000f0, 0 x84840084,
0 xdfdf00df, 0 xcbcb00cb, 0 x34340034, 0 x76760076,
0 x6d6d006d, 0 xa9a900a9, 0 xd1d100d1, 0 x04040004,
0 x14140014, 0 x3a3a003a, 0 xdede00de, 0 x11110011,
0 x32320032, 0 x9c9c009c, 0 x53530053, 0 xf2f200f2,
0 xfefe00fe, 0 xcfcf00cf, 0 xc3c300c3, 0 x7a7a007a,
0 x24240024, 0 xe8e800e8, 0 x60600060, 0 x69690069,
0 xaaaa00aa, 0 xa0a000a0, 0 xa1a100a1, 0 x62620062,
0 x54540054, 0 x1e1e001e, 0 xe0e000e0, 0 x64640064,
0 x10100010, 0 x00000000, 0 xa3a300a3, 0 x75750075,
0 x8a8a008a, 0 xe6e600e6, 0 x09090009, 0 xdddd00dd,
0 x87870087, 0 x83830083, 0 xcdcd00cd, 0 x90900090,
0 x73730073, 0 xf6f600f6, 0 x9d9d009d, 0 xbfbf00bf,
0 x52520052, 0 xd8d800d8, 0 xc8c800c8, 0 xc6c600c6,
0 x81810081, 0 x6f6f006f, 0 x13130013, 0 x63630063,
0 xe9e900e9, 0 xa7a700a7, 0 x9f9f009f, 0 xbcbc00bc,
0 x29290029, 0 xf9f900f9, 0 x2f2f002f, 0 xb4b400b4,
0 x78780078, 0 x06060006, 0 xe7e700e7, 0 x71710071,
0 xd4d400d4, 0 xabab00ab, 0 x88880088, 0 x8d8d008d,
0 x72720072, 0 xb9b900b9, 0 xf8f800f8, 0 xacac00ac,
0 x36360036, 0 x2a2a002a, 0 x3c3c003c, 0 xf1f100f1,
0 x40400040, 0 xd3d300d3, 0 xbbbb00bb, 0 x43430043,
0 x15150015, 0 xadad00ad, 0 x77770077, 0 x80800080,
0 x82820082, 0 xecec00ec, 0 x27270027, 0 xe5e500e5,
0 x85850085, 0 x35350035, 0 x0c0c000c, 0 x41410041,
0 xefef00ef, 0 x93930093, 0 x19190019, 0 x21210021,
0 x0e0e000e, 0 x4e4e004e, 0 x65650065, 0 xbdbd00bd,
0 xb8b800b8, 0 x8f8f008f, 0 xebeb00eb, 0 xcece00ce,
0 x30300030, 0 x5f5f005f, 0 xc5c500c5, 0 x1a1a001a,
0 xe1e100e1, 0 xcaca00ca, 0 x47470047, 0 x3d3d003d,
0 x01010001, 0 xd6d600d6, 0 x56560056, 0 x4d4d004d,
0 x0d0d000d, 0 x66660066, 0 xcccc00cc, 0 x2d2d002d,
0 x12120012, 0 x20200020, 0 xb1b100b1, 0 x99990099,
0 x4c4c004c, 0 xc2c200c2, 0 x7e7e007e, 0 x05050005,
0 xb7b700b7, 0 x31310031, 0 x17170017, 0 xd7d700d7,
0 x58580058, 0 x61610061, 0 x1b1b001b, 0 x1c1c001c,
0 x0f0f000f, 0 x16160016, 0 x18180018, 0 x22220022,
0 x44440044, 0 xb2b200b2, 0 xb5b500b5, 0 x91910091,
0 x08080008, 0 xa8a800a8, 0 xfcfc00fc, 0 x50500050,
0 xd0d000d0, 0 x7d7d007d, 0 x89890089, 0 x97970097,
0 x5b5b005b, 0 x95950095, 0 xffff00ff, 0 xd2d200d2,
0 xc4c400c4, 0 x48480048, 0 xf7f700f7, 0 xdbdb00db,
0 x03030003, 0 xdada00da, 0 x3f3f003f, 0 x94940094,
0 x5c5c005c, 0 x02020002, 0 x4a4a004a, 0 x33330033,
0 x67670067, 0 xf3f300f3, 0 x7f7f007f, 0 xe2e200e2,
0 x9b9b009b, 0 x26260026, 0 x37370037, 0 x3b3b003b,
0 x96960096, 0 x4b4b004b, 0 xbebe00be, 0 x2e2e002e,
0 x79790079, 0 x8c8c008c, 0 x6e6e006e, 0 x8e8e008e,
0 xf5f500f5, 0 xb6b600b6, 0 xfdfd00fd, 0 x59590059,
0 x98980098, 0 x6a6a006a, 0 x46460046, 0 xbaba00ba,
0 x25250025, 0 x42420042, 0 xa2a200a2, 0 xfafa00fa,
0 x07070007, 0 x55550055, 0 xeeee00ee, 0 x0a0a000a,
0 x49490049, 0 x68680068, 0 x38380038, 0 xa4a400a4,
0 x28280028, 0 x7b7b007b, 0 xc9c900c9, 0 xc1c100c1,
0 xe3e300e3, 0 xf4f400f4, 0 xc7c700c7, 0 x9e9e009e,
};
#define CAMELLIA_MIN_KEY_SIZE 16
#define CAMELLIA_MAX_KEY_SIZE 32
#define CAMELLIA_BLOCK_SIZE 16
#define CAMELLIA_TABLE_BYTE_LEN 272
/*
* NB : L and R below stand for ' left ' and ' right ' as in written numbers .
* That is , in ( xxxL , xxxR ) pair xxxL holds most significant digits ,
* _ not_ least significant ones !
*/
/* key constants */
#define CAMELLIA_SIGMA1L (0 xA09E667FL)
#define CAMELLIA_SIGMA1R (0 x3BCC908BL)
#define CAMELLIA_SIGMA2L (0 xB67AE858L)
#define CAMELLIA_SIGMA2R (0 x4CAA73B2L)
#define CAMELLIA_SIGMA3L (0 xC6EF372FL)
#define CAMELLIA_SIGMA3R (0 xE94F82BEL)
#define CAMELLIA_SIGMA4L (0 x54FF53A5L)
#define CAMELLIA_SIGMA4R (0 xF1D36F1CL)
#define CAMELLIA_SIGMA5L (0 x10E527FAL)
#define CAMELLIA_SIGMA5R (0 xDE682D1DL)
#define CAMELLIA_SIGMA6L (0 xB05688C2L)
#define CAMELLIA_SIGMA6R (0 xB3E6C1FDL)
/*
* macros
*/
#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) ({ \
w0 = ll; \
ll = (ll << bits) + (lr >> (32 - bits)); \
lr = (lr << bits) + (rl >> (32 - bits)); \
rl = (rl << bits) + (rr >> (32 - bits)); \
rr = (rr << bits) + (w0 >> (32 - bits)); \
})
#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) ({ \
w0 = ll; \
w1 = lr; \
ll = (lr << (bits - 32 )) + (rl >> (64 - bits)); \
lr = (rl << (bits - 32 )) + (rr >> (64 - bits)); \
rl = (rr << (bits - 32 )) + (w0 >> (64 - bits)); \
rr = (w0 << (bits - 32 )) + (w1 >> (64 - bits)); \
})
#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) ({ \
il = xl ^ kl; \
ir = xr ^ kr; \
t0 = il >> 16 ; \
t1 = ir >> 16 ; \
yl = camellia_sp1110[(u8)(ir)] \
^ camellia_sp0222[(u8)(t1 >> 8 )] \
^ camellia_sp3033[(u8)(t1)] \
^ camellia_sp4404[(u8)(ir >> 8 )]; \
yr = camellia_sp1110[(u8)(t0 >> 8 )] \
^ camellia_sp0222[(u8)(t0)] \
^ camellia_sp3033[(u8)(il >> 8 )] \
^ camellia_sp4404[(u8)(il)]; \
yl ^= yr; \
yr = ror32(yr, 8 ); \
yr ^= yl; \
})
#define SUBKEY_L(INDEX) (subkey[(INDEX)*2 ])
#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1 ])
static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
{
u32 dw, tl, tr;
u32 kw4l, kw4r;
/* absorb kw2 to other subkeys */
/* round 2 */
subL[3 ] ^= subL[1 ]; subR[3 ] ^= subR[1 ];
/* round 4 */
subL[5 ] ^= subL[1 ]; subR[5 ] ^= subR[1 ];
/* round 6 */
subL[7 ] ^= subL[1 ]; subR[7 ] ^= subR[1 ];
subL[1 ] ^= subR[1 ] & ~subR[9 ];
dw = subL[1 ] & subL[9 ];
subR[1 ] ^= rol32(dw, 1 ); /* modified for FLinv(kl2) */
/* round 8 */
subL[11 ] ^= subL[1 ]; subR[11 ] ^= subR[1 ];
/* round 10 */
subL[13 ] ^= subL[1 ]; subR[13 ] ^= subR[1 ];
/* round 12 */
subL[15 ] ^= subL[1 ]; subR[15 ] ^= subR[1 ];
subL[1 ] ^= subR[1 ] & ~subR[17 ];
dw = subL[1 ] & subL[17 ];
subR[1 ] ^= rol32(dw, 1 ); /* modified for FLinv(kl4) */
/* round 14 */
subL[19 ] ^= subL[1 ]; subR[19 ] ^= subR[1 ];
/* round 16 */
subL[21 ] ^= subL[1 ]; subR[21 ] ^= subR[1 ];
/* round 18 */
subL[23 ] ^= subL[1 ]; subR[23 ] ^= subR[1 ];
if (max == 24 ) {
/* kw3 */
subL[24 ] ^= subL[1 ]; subR[24 ] ^= subR[1 ];
/* absorb kw4 to other subkeys */
kw4l = subL[25 ]; kw4r = subR[25 ];
} else {
subL[1 ] ^= subR[1 ] & ~subR[25 ];
dw = subL[1 ] & subL[25 ];
subR[1 ] ^= rol32(dw, 1 ); /* modified for FLinv(kl6) */
/* round 20 */
subL[27 ] ^= subL[1 ]; subR[27 ] ^= subR[1 ];
/* round 22 */
subL[29 ] ^= subL[1 ]; subR[29 ] ^= subR[1 ];
/* round 24 */
subL[31 ] ^= subL[1 ]; subR[31 ] ^= subR[1 ];
/* kw3 */
subL[32 ] ^= subL[1 ]; subR[32 ] ^= subR[1 ];
/* absorb kw4 to other subkeys */
kw4l = subL[33 ]; kw4r = subR[33 ];
/* round 23 */
subL[30 ] ^= kw4l; subR[30 ] ^= kw4r;
/* round 21 */
subL[28 ] ^= kw4l; subR[28 ] ^= kw4r;
/* round 19 */
subL[26 ] ^= kw4l; subR[26 ] ^= kw4r;
kw4l ^= kw4r & ~subR[24 ];
dw = kw4l & subL[24 ];
kw4r ^= rol32(dw, 1 ); /* modified for FL(kl5) */
}
/* round 17 */
subL[22 ] ^= kw4l; subR[22 ] ^= kw4r;
/* round 15 */
subL[20 ] ^= kw4l; subR[20 ] ^= kw4r;
/* round 13 */
subL[18 ] ^= kw4l; subR[18 ] ^= kw4r;
kw4l ^= kw4r & ~subR[16 ];
dw = kw4l & subL[16 ];
kw4r ^= rol32(dw, 1 ); /* modified for FL(kl3) */
/* round 11 */
subL[14 ] ^= kw4l; subR[14 ] ^= kw4r;
/* round 9 */
subL[12 ] ^= kw4l; subR[12 ] ^= kw4r;
/* round 7 */
subL[10 ] ^= kw4l; subR[10 ] ^= kw4r;
kw4l ^= kw4r & ~subR[8 ];
dw = kw4l & subL[8 ];
kw4r ^= rol32(dw, 1 ); /* modified for FL(kl1) */
/* round 5 */
subL[6 ] ^= kw4l; subR[6 ] ^= kw4r;
/* round 3 */
subL[4 ] ^= kw4l; subR[4 ] ^= kw4r;
/* round 1 */
subL[2 ] ^= kw4l; subR[2 ] ^= kw4r;
/* kw1 */
subL[0 ] ^= kw4l; subR[0 ] ^= kw4r;
/* key XOR is end of F-function */
SUBKEY_L(0 ) = subL[0 ] ^ subL[2 ];/* kw1 */
SUBKEY_R(0 ) = subR[0 ] ^ subR[2 ];
SUBKEY_L(2 ) = subL[3 ]; /* round 1 */
SUBKEY_R(2 ) = subR[3 ];
SUBKEY_L(3 ) = subL[2 ] ^ subL[4 ]; /* round 2 */
SUBKEY_R(3 ) = subR[2 ] ^ subR[4 ];
SUBKEY_L(4 ) = subL[3 ] ^ subL[5 ]; /* round 3 */
SUBKEY_R(4 ) = subR[3 ] ^ subR[5 ];
SUBKEY_L(5 ) = subL[4 ] ^ subL[6 ]; /* round 4 */
SUBKEY_R(5 ) = subR[4 ] ^ subR[6 ];
SUBKEY_L(6 ) = subL[5 ] ^ subL[7 ]; /* round 5 */
SUBKEY_R(6 ) = subR[5 ] ^ subR[7 ];
tl = subL[10 ] ^ (subR[10 ] & ~subR[8 ]);
dw = tl & subL[8 ]; /* FL(kl1) */
tr = subR[10 ] ^ rol32(dw, 1 );
SUBKEY_L(7 ) = subL[6 ] ^ tl; /* round 6 */
SUBKEY_R(7 ) = subR[6 ] ^ tr;
SUBKEY_L(8 ) = subL[8 ]; /* FL(kl1) */
SUBKEY_R(8 ) = subR[8 ];
SUBKEY_L(9 ) = subL[9 ]; /* FLinv(kl2) */
SUBKEY_R(9 ) = subR[9 ];
tl = subL[7 ] ^ (subR[7 ] & ~subR[9 ]);
dw = tl & subL[9 ]; /* FLinv(kl2) */
tr = subR[7 ] ^ rol32(dw, 1 );
SUBKEY_L(10 ) = tl ^ subL[11 ]; /* round 7 */
SUBKEY_R(10 ) = tr ^ subR[11 ];
SUBKEY_L(11 ) = subL[10 ] ^ subL[12 ]; /* round 8 */
SUBKEY_R(11 ) = subR[10 ] ^ subR[12 ];
SUBKEY_L(12 ) = subL[11 ] ^ subL[13 ]; /* round 9 */
SUBKEY_R(12 ) = subR[11 ] ^ subR[13 ];
SUBKEY_L(13 ) = subL[12 ] ^ subL[14 ]; /* round 10 */
SUBKEY_R(13 ) = subR[12 ] ^ subR[14 ];
SUBKEY_L(14 ) = subL[13 ] ^ subL[15 ]; /* round 11 */
SUBKEY_R(14 ) = subR[13 ] ^ subR[15 ];
tl = subL[18 ] ^ (subR[18 ] & ~subR[16 ]);
dw = tl & subL[16 ]; /* FL(kl3) */
tr = subR[18 ] ^ rol32(dw, 1 );
SUBKEY_L(15 ) = subL[14 ] ^ tl; /* round 12 */
SUBKEY_R(15 ) = subR[14 ] ^ tr;
SUBKEY_L(16 ) = subL[16 ]; /* FL(kl3) */
SUBKEY_R(16 ) = subR[16 ];
SUBKEY_L(17 ) = subL[17 ]; /* FLinv(kl4) */
SUBKEY_R(17 ) = subR[17 ];
tl = subL[15 ] ^ (subR[15 ] & ~subR[17 ]);
dw = tl & subL[17 ]; /* FLinv(kl4) */
tr = subR[15 ] ^ rol32(dw, 1 );
SUBKEY_L(18 ) = tl ^ subL[19 ]; /* round 13 */
SUBKEY_R(18 ) = tr ^ subR[19 ];
SUBKEY_L(19 ) = subL[18 ] ^ subL[20 ]; /* round 14 */
SUBKEY_R(19 ) = subR[18 ] ^ subR[20 ];
SUBKEY_L(20 ) = subL[19 ] ^ subL[21 ]; /* round 15 */
SUBKEY_R(20 ) = subR[19 ] ^ subR[21 ];
SUBKEY_L(21 ) = subL[20 ] ^ subL[22 ]; /* round 16 */
SUBKEY_R(21 ) = subR[20 ] ^ subR[22 ];
SUBKEY_L(22 ) = subL[21 ] ^ subL[23 ]; /* round 17 */
SUBKEY_R(22 ) = subR[21 ] ^ subR[23 ];
if (max == 24 ) {
SUBKEY_L(23 ) = subL[22 ]; /* round 18 */
SUBKEY_R(23 ) = subR[22 ];
SUBKEY_L(24 ) = subL[24 ] ^ subL[23 ]; /* kw3 */
SUBKEY_R(24 ) = subR[24 ] ^ subR[23 ];
} else {
tl = subL[26 ] ^ (subR[26 ] & ~subR[24 ]);
dw = tl & subL[24 ]; /* FL(kl5) */
tr = subR[26 ] ^ rol32(dw, 1 );
SUBKEY_L(23 ) = subL[22 ] ^ tl; /* round 18 */
SUBKEY_R(23 ) = subR[22 ] ^ tr;
SUBKEY_L(24 ) = subL[24 ]; /* FL(kl5) */
SUBKEY_R(24 ) = subR[24 ];
SUBKEY_L(25 ) = subL[25 ]; /* FLinv(kl6) */
SUBKEY_R(25 ) = subR[25 ];
tl = subL[23 ] ^ (subR[23 ] & ~subR[25 ]);
dw = tl & subL[25 ]; /* FLinv(kl6) */
tr = subR[23 ] ^ rol32(dw, 1 );
SUBKEY_L(26 ) = tl ^ subL[27 ]; /* round 19 */
SUBKEY_R(26 ) = tr ^ subR[27 ];
SUBKEY_L(27 ) = subL[26 ] ^ subL[28 ]; /* round 20 */
SUBKEY_R(27 ) = subR[26 ] ^ subR[28 ];
SUBKEY_L(28 ) = subL[27 ] ^ subL[29 ]; /* round 21 */
SUBKEY_R(28 ) = subR[27 ] ^ subR[29 ];
SUBKEY_L(29 ) = subL[28 ] ^ subL[30 ]; /* round 22 */
SUBKEY_R(29 ) = subR[28 ] ^ subR[30 ];
SUBKEY_L(30 ) = subL[29 ] ^ subL[31 ]; /* round 23 */
SUBKEY_R(30 ) = subR[29 ] ^ subR[31 ];
SUBKEY_L(31 ) = subL[30 ]; /* round 24 */
SUBKEY_R(31 ) = subR[30 ];
SUBKEY_L(32 ) = subL[32 ] ^ subL[31 ]; /* kw3 */
SUBKEY_R(32 ) = subR[32 ] ^ subR[31 ];
}
}
static void camellia_setup128(const unsigned char *key, u32 *subkey)
{
u32 kll, klr, krl, krr;
u32 il, ir, t0, t1, w0, w1;
u32 subL[26 ];
u32 subR[26 ];
/**
* k = = kll | | klr | | krl | | krr ( | | is concatenation )
*/
kll = get_unaligned_be32(key);
klr = get_unaligned_be32(key + 4 );
krl = get_unaligned_be32(key + 8 );
krr = get_unaligned_be32(key + 12 );
/* generate KL dependent subkeys */
/* kw1 */
subL[0 ] = kll; subR[0 ] = klr;
/* kw2 */
subL[1 ] = krl; subR[1 ] = krr;
/* rotation left shift 15bit */
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* k3 */
subL[4 ] = kll; subR[4 ] = klr;
/* k4 */
subL[5 ] = krl; subR[5 ] = krr;
/* rotation left shift 15+30bit */
ROLDQ(kll, klr, krl, krr, w0, w1, 30 );
/* k7 */
subL[10 ] = kll; subR[10 ] = klr;
/* k8 */
subL[11 ] = krl; subR[11 ] = krr;
/* rotation left shift 15+30+15bit */
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* k10 */
subL[13 ] = krl; subR[13 ] = krr;
/* rotation left shift 15+30+15+17 bit */
ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
/* kl3 */
subL[16 ] = kll; subR[16 ] = klr;
/* kl4 */
subL[17 ] = krl; subR[17 ] = krr;
/* rotation left shift 15+30+15+17+17 bit */
ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
/* k13 */
subL[18 ] = kll; subR[18 ] = klr;
/* k14 */
subL[19 ] = krl; subR[19 ] = krr;
/* rotation left shift 15+30+15+17+17+17 bit */
ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
/* k17 */
subL[22 ] = kll; subR[22 ] = klr;
/* k18 */
subL[23 ] = krl; subR[23 ] = krr;
/* generate KA */
kll = subL[0 ]; klr = subR[0 ];
krl = subL[1 ]; krr = subR[1 ];
CAMELLIA_F(kll, klr,
CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
w0, w1, il, ir, t0, t1);
krl ^= w0; krr ^= w1;
CAMELLIA_F(krl, krr,
CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
kll, klr, il, ir, t0, t1);
/* current status == (kll, klr, w0, w1) */
CAMELLIA_F(kll, klr,
CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
krl, krr, il, ir, t0, t1);
krl ^= w0; krr ^= w1;
CAMELLIA_F(krl, krr,
CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
w0, w1, il, ir, t0, t1);
kll ^= w0; klr ^= w1;
/* generate KA dependent subkeys */
/* k1, k2 */
subL[2 ] = kll; subR[2 ] = klr;
subL[3 ] = krl; subR[3 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* k5,k6 */
subL[6 ] = kll; subR[6 ] = klr;
subL[7 ] = krl; subR[7 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* kl1, kl2 */
subL[8 ] = kll; subR[8 ] = klr;
subL[9 ] = krl; subR[9 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* k9 */
subL[12 ] = kll; subR[12 ] = klr;
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* k11, k12 */
subL[14 ] = kll; subR[14 ] = klr;
subL[15 ] = krl; subR[15 ] = krr;
ROLDQo32(kll, klr, krl, krr, w0, w1, 34 );
/* k15, k16 */
subL[20 ] = kll; subR[20 ] = klr;
subL[21 ] = krl; subR[21 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
/* kw3, kw4 */
subL[24 ] = kll; subR[24 ] = klr;
subL[25 ] = krl; subR[25 ] = krr;
camellia_setup_tail(subkey, subL, subR, 24 );
}
static void camellia_setup256(const unsigned char *key, u32 *subkey)
{
u32 kll, klr, krl, krr; /* left half of key */
u32 krll, krlr, krrl, krrr; /* right half of key */
u32 il, ir, t0, t1, w0, w1; /* temporary variables */
u32 subL[34 ];
u32 subR[34 ];
/**
* key = ( kll | | klr | | krl | | krr | | krll | | krlr | | krrl | | krrr )
* ( | | is concatenation )
*/
kll = get_unaligned_be32(key);
klr = get_unaligned_be32(key + 4 );
krl = get_unaligned_be32(key + 8 );
krr = get_unaligned_be32(key + 12 );
krll = get_unaligned_be32(key + 16 );
krlr = get_unaligned_be32(key + 20 );
krrl = get_unaligned_be32(key + 24 );
krrr = get_unaligned_be32(key + 28 );
/* generate KL dependent subkeys */
/* kw1 */
subL[0 ] = kll; subR[0 ] = klr;
/* kw2 */
subL[1 ] = krl; subR[1 ] = krr;
ROLDQo32(kll, klr, krl, krr, w0, w1, 45 );
/* k9 */
subL[12 ] = kll; subR[12 ] = klr;
/* k10 */
subL[13 ] = krl; subR[13 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* kl3 */
subL[16 ] = kll; subR[16 ] = klr;
/* kl4 */
subL[17 ] = krl; subR[17 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
/* k17 */
subL[22 ] = kll; subR[22 ] = klr;
/* k18 */
subL[23 ] = krl; subR[23 ] = krr;
ROLDQo32(kll, klr, krl, krr, w0, w1, 34 );
/* k23 */
subL[30 ] = kll; subR[30 ] = klr;
/* k24 */
subL[31 ] = krl; subR[31 ] = krr;
/* generate KR dependent subkeys */
ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15 );
/* k3 */
subL[4 ] = krll; subR[4 ] = krlr;
/* k4 */
subL[5 ] = krrl; subR[5 ] = krrr;
ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15 );
/* kl1 */
subL[8 ] = krll; subR[8 ] = krlr;
/* kl2 */
subL[9 ] = krrl; subR[9 ] = krrr;
ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30 );
/* k13 */
subL[18 ] = krll; subR[18 ] = krlr;
/* k14 */
subL[19 ] = krrl; subR[19 ] = krrr;
ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34 );
/* k19 */
subL[26 ] = krll; subR[26 ] = krlr;
/* k20 */
subL[27 ] = krrl; subR[27 ] = krrr;
ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34 );
/* generate KA */
kll = subL[0 ] ^ krll; klr = subR[0 ] ^ krlr;
krl = subL[1 ] ^ krrl; krr = subR[1 ] ^ krrr;
CAMELLIA_F(kll, klr,
CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
w0, w1, il, ir, t0, t1);
krl ^= w0; krr ^= w1;
CAMELLIA_F(krl, krr,
CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
kll, klr, il, ir, t0, t1);
kll ^= krll; klr ^= krlr;
CAMELLIA_F(kll, klr,
CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
krl, krr, il, ir, t0, t1);
krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
CAMELLIA_F(krl, krr,
CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
w0, w1, il, ir, t0, t1);
kll ^= w0; klr ^= w1;
/* generate KB */
krll ^= kll; krlr ^= klr;
krrl ^= krl; krrr ^= krr;
CAMELLIA_F(krll, krlr,
CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
w0, w1, il, ir, t0, t1);
krrl ^= w0; krrr ^= w1;
CAMELLIA_F(krrl, krrr,
CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
w0, w1, il, ir, t0, t1);
krll ^= w0; krlr ^= w1;
/* generate KA dependent subkeys */
ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
/* k5 */
subL[6 ] = kll; subR[6 ] = klr;
/* k6 */
subL[7 ] = krl; subR[7 ] = krr;
ROLDQ(kll, klr, krl, krr, w0, w1, 30 );
/* k11 */
subL[14 ] = kll; subR[14 ] = klr;
/* k12 */
subL[15 ] = krl; subR[15 ] = krr;
/* rotation left shift 32bit */
/* kl5 */
subL[24 ] = klr; subR[24 ] = krl;
/* kl6 */
subL[25 ] = krr; subR[25 ] = kll;
/* rotation left shift 49 from k11,k12 -> k21,k22 */
ROLDQo32(kll, klr, krl, krr, w0, w1, 49 );
/* k21 */
subL[28 ] = kll; subR[28 ] = klr;
/* k22 */
subL[29 ] = krl; subR[29 ] = krr;
/* generate KB dependent subkeys */
/* k1 */
subL[2 ] = krll; subR[2 ] = krlr;
/* k2 */
subL[3 ] = krrl; subR[3 ] = krrr;
ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30 );
/* k7 */
subL[10 ] = krll; subR[10 ] = krlr;
/* k8 */
subL[11 ] = krrl; subR[11 ] = krrr;
ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30 );
/* k15 */
subL[20 ] = krll; subR[20 ] = krlr;
/* k16 */
subL[21 ] = krrl; subR[21 ] = krrr;
ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51 );
/* kw3 */
subL[32 ] = krll; subR[32 ] = krlr;
/* kw4 */
subL[33 ] = krrl; subR[33 ] = krrr;
camellia_setup_tail(subkey, subL, subR, 32 );
}
static void camellia_setup192(const unsigned char *key, u32 *subkey)
{
unsigned char kk[32 ];
u32 krll, krlr, krrl, krrr;
memcpy(kk, key, 24 );
memcpy((unsigned char *)&krll, key+16 , 4 );
memcpy((unsigned char *)&krlr, key+20 , 4 );
krrl = ~krll;
krrr = ~krlr;
memcpy(kk+24 , (unsigned char *)&krrl, 4 );
memcpy(kk+28 , (unsigned char *)&krrr, 4 );
camellia_setup256(kk, subkey);
}
/*
* Encrypt / decrypt
*/
#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) ({ \
t0 = kll; \
t2 = krr; \
t0 &= ll; \
t2 |= rr; \
rl ^= t2; \
lr ^= rol32(t0, 1 ); \
t3 = krl; \
t1 = klr; \
t3 &= rl; \
t1 |= lr; \
ll ^= t1; \
rr ^= rol32(t3, 1 ); \
})
#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) ({ \
yl ^= kl; \
yr ^= kr; \
ir = camellia_sp1110[(u8)xr]; \
il = camellia_sp1110[(u8)(xl >> 24 )]; \
ir ^= camellia_sp0222[(u8)(xr >> 24 )]; \
il ^= camellia_sp0222[(u8)(xl >> 16 )]; \
ir ^= camellia_sp3033[(u8)(xr >> 16 )]; \
il ^= camellia_sp3033[(u8)(xl >> 8 )]; \
ir ^= camellia_sp4404[(u8)(xr >> 8 )]; \
il ^= camellia_sp4404[(u8)xl]; \
ir ^= il; \
yl ^= ir; \
yr ^= ror32(il, 8 ) ^ ir; \
})
/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
{
u32 il, ir, t0, t1; /* temporary variables */
/* pre whitening but absorb kw2 */
io[0 ] ^= SUBKEY_L(0 );
io[1 ] ^= SUBKEY_R(0 );
/* main iteration */
#define ROUNDS(i) ({ \
CAMELLIA_ROUNDSM(io[0 ], io[1 ], \
SUBKEY_L(i + 2 ), SUBKEY_R(i + 2 ), \
io[2 ], io[3 ], il, ir); \
CAMELLIA_ROUNDSM(io[2 ], io[3 ], \
SUBKEY_L(i + 3 ), SUBKEY_R(i + 3 ), \
io[0 ], io[1 ], il, ir); \
CAMELLIA_ROUNDSM(io[0 ], io[1 ], \
SUBKEY_L(i + 4 ), SUBKEY_R(i + 4 ), \
io[2 ], io[3 ], il, ir); \
CAMELLIA_ROUNDSM(io[2 ], io[3 ], \
SUBKEY_L(i + 5 ), SUBKEY_R(i + 5 ), \
io[0 ], io[1 ], il, ir); \
CAMELLIA_ROUNDSM(io[0 ], io[1 ], \
SUBKEY_L(i + 6 ), SUBKEY_R(i + 6 ), \
io[2 ], io[3 ], il, ir); \
CAMELLIA_ROUNDSM(io[2 ], io[3 ], \
SUBKEY_L(i + 7 ), SUBKEY_R(i + 7 ), \
io[0 ], io[1 ], il, ir); \
})
#define FLS(i) ({ \
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ], \
SUBKEY_L(i + 0 ), SUBKEY_R(i + 0 ), \
SUBKEY_L(i + 1 ), SUBKEY_R(i + 1 ), \
t0, t1, il, ir); \
})
ROUNDS(0 );
FLS(8 );
ROUNDS(8 );
FLS(16 );
ROUNDS(16 );
if (max == 32 ) {
FLS(24 );
ROUNDS(24 );
}
#undef ROUNDS
#undef FLS
/* post whitening but kw4 */
io[2 ] ^= SUBKEY_L(max);
io[3 ] ^= SUBKEY_R(max);
/* NB: io[0],[1] should be swapped with [2],[3] by caller! */
}
static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
{
u32 il, ir, t0, t1; /* temporary variables */
/* pre whitening but absorb kw2 */
io[0 ] ^= SUBKEY_L(i);
io[1 ] ^= SUBKEY_R(i);
/* main iteration */
#define ROUNDS(i) ({ \
CAMELLIA_ROUNDSM(io[0 ], io[1 ], \
SUBKEY_L(i + 7 ), SUBKEY_R(i + 7 ), \
io[2 ], io[3 ], il, ir); \
CAMELLIA_ROUNDSM(io[2 ], io[3 ], \
SUBKEY_L(i + 6 ), SUBKEY_R(i + 6 ), \
io[0 ], io[1 ], il, ir); \
CAMELLIA_ROUNDSM(io[0 ], io[1 ], \
SUBKEY_L(i + 5 ), SUBKEY_R(i + 5 ), \
io[2 ], io[3 ], il, ir); \
CAMELLIA_ROUNDSM(io[2 ], io[3 ], \
SUBKEY_L(i + 4 ), SUBKEY_R(i + 4 ), \
io[0 ], io[1 ], il, ir); \
CAMELLIA_ROUNDSM(io[0 ], io[1 ], \
SUBKEY_L(i + 3 ), SUBKEY_R(i + 3 ), \
io[2 ], io[3 ], il, ir); \
CAMELLIA_ROUNDSM(io[2 ], io[3 ], \
SUBKEY_L(i + 2 ), SUBKEY_R(i + 2 ), \
io[0 ], io[1 ], il, ir); \
})
#define FLS(i) ({ \
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ], \
SUBKEY_L(i + 1 ), SUBKEY_R(i + 1 ), \
SUBKEY_L(i + 0 ), SUBKEY_R(i + 0 ), \
t0, t1, il, ir); \
})
if (i == 32 ) {
ROUNDS(24 );
FLS(24 );
}
ROUNDS(16 );
FLS(16 );
ROUNDS(8 );
FLS(8 );
ROUNDS(0 );
#undef ROUNDS
#undef FLS
/* post whitening but kw4 */
io[2 ] ^= SUBKEY_L(0 );
io[3 ] ^= SUBKEY_R(0 );
/* NB: 0,1 should be swapped with 2,3 by caller! */
}
struct camellia_ctx {
int key_length;
u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof (u32)];
};
static int
camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
{
struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
const unsigned char *key = (const unsigned char *)in_key;
if (key_len != 16 && key_len != 24 && key_len != 32 )
return -EINVAL;
cctx->key_length = key_len;
switch (key_len) {
case 16 :
camellia_setup128(key, cctx->key_table);
break ;
case 24 :
camellia_setup192(key, cctx->key_table);
break ;
case 32 :
camellia_setup256(key, cctx->key_table);
break ;
}
return 0 ;
}
static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
unsigned int max;
u32 tmp[4 ];
tmp[0 ] = get_unaligned_be32(in);
tmp[1 ] = get_unaligned_be32(in + 4 );
tmp[2 ] = get_unaligned_be32(in + 8 );
tmp[3 ] = get_unaligned_be32(in + 12 );
if (cctx->key_length == 16 )
max = 24 ;
else
max = 32 ; /* for key lengths of 24 and 32 */
camellia_do_encrypt(cctx->key_table, tmp, max);
/* do_encrypt returns 0,1 swapped with 2,3 */
put_unaligned_be32(tmp[2 ], out);
put_unaligned_be32(tmp[3 ], out + 4 );
put_unaligned_be32(tmp[0 ], out + 8 );
put_unaligned_be32(tmp[1 ], out + 12 );
}
static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
unsigned int max;
u32 tmp[4 ];
tmp[0 ] = get_unaligned_be32(in);
tmp[1 ] = get_unaligned_be32(in + 4 );
tmp[2 ] = get_unaligned_be32(in + 8 );
tmp[3 ] = get_unaligned_be32(in + 12 );
if (cctx->key_length == 16 )
max = 24 ;
else
max = 32 ; /* for key lengths of 24 and 32 */
camellia_do_decrypt(cctx->key_table, tmp, max);
/* do_decrypt returns 0,1 swapped with 2,3 */
put_unaligned_be32(tmp[2 ], out);
put_unaligned_be32(tmp[3 ], out + 4 );
put_unaligned_be32(tmp[0 ], out + 8 );
put_unaligned_be32(tmp[1 ], out + 12 );
}
static struct crypto_alg camellia_alg = {
.cra_name = "camellia" ,
.cra_driver_name = "camellia-generic" ,
.cra_priority = 100 ,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAMELLIA_BLOCK_SIZE,
.cra_ctxsize = sizeof (struct camellia_ctx),
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
.cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
.cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
.cia_setkey = camellia_set_key,
.cia_encrypt = camellia_encrypt,
.cia_decrypt = camellia_decrypt
}
}
};
static int __init camellia_init(void )
{
return crypto_register_alg(&camellia_alg);
}
static void __exit camellia_fini(void )
{
crypto_unregister_alg(&camellia_alg);
}
module_init(camellia_init);
module_exit(camellia_fini);
MODULE_DESCRIPTION("Camellia Cipher Algorithm" );
MODULE_LICENSE("GPL" );
MODULE_ALIAS_CRYPTO("camellia" );
MODULE_ALIAS_CRYPTO("camellia-generic" );
Messung V0.5 in Prozent C=84 H=100 G=92
¤ Dauer der Verarbeitung: 0.48 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland