// 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=96 H=93 G=94
¤ Dauer der Verarbeitung: 0.43 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland