/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
#include "prinit.h"
#include "prerr.h"
#include "secerr.h"
#include "prtypes.h"
#include "blapi.h"
#include "camellia.h"
#include "sha_fast.h" /* for SHA_HTONL and related configuration macros */
/* 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
*/
#if defined (HAVE_UNALIGNED_ACCESS)
/* require a CPU that allows unaligned access */
#if defined (SHA_NEED_TMP_VARIABLE)
#define CAMELLIA_NEED_TMP_VARIABLE
1
#endif
#define GETU32(p) SHA_HTONL(*((PRUint32 *)(p)))
#define PUTU32(ct, st) \
{ \
*((PRUint32 *)(ct)) = SHA_HTONL(st); \
}
#else /* no unaligned access */
#define GETU32(pt) \
(((PRUint32)(pt)[
0 ] <<
24 ) ^ ((PRUint32)(pt)[
1 ] <<
16 ) ^ ((PRUint32)(pt)[
2 ] <<
8 ) ^ ((PRUint32)(pt
)[3 ]))
#define PUTU32(ct, st) \
{ \
(ct)[0 ] = (PRUint8)((st) >> 24 ); \
(ct)[1 ] = (PRUint8)((st) >> 16 ); \
(ct)[2 ] = (PRUint8)((st) >> 8 ); \
(ct)[3 ] = (PRUint8)(st); \
}
#endif
#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2 ])
#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1 ])
/* rotation right shift 1byte */
#define CAMELLIA_RR8(x) (((x) >> 8 ) + ((x) << 24 ))
/* rotation left shift 1bit */
#define CAMELLIA_RL1(x) (((x) << 1 ) + ((x) >> 31 ))
/* rotation left shift 1byte */
#define CAMELLIA_RL8(x) (((x) << 8 ) + ((x) >> 24 ))
#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
do { \
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)); \
} while (0 )
#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
do { \
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)); \
} while (0 )
#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
do { \
il = xl ^ kl; \
ir = xr ^ kr; \
t0 = il >> 16 ; \
t1 = ir >> 16 ; \
yl = CAMELLIA_SP1110(ir & 0 xff) ^ \
CAMELLIA_SP0222((t1 >> 8 ) & 0 xff) ^ \
CAMELLIA_SP3033(t1 & 0 xff) ^ \
CAMELLIA_SP4404((ir >> 8 ) & 0 xff); \
yr = CAMELLIA_SP1110((t0 >> 8 ) & 0 xff) ^ \
CAMELLIA_SP0222(t0 & 0 xff) ^ \
CAMELLIA_SP3033((il >> 8 ) & 0 xff) ^ \
CAMELLIA_SP4404(il & 0 xff); \
yl ^= yr; \
yr = CAMELLIA_RR8(yr); \
yr ^= yl; \
} while (0 )
/*
* for speed up
*
*/
#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
do { \
t0 = kll; \
t0 &= ll; \
lr ^= CAMELLIA_RL1(t0); \
t1 = klr; \
t1 |= lr; \
ll ^= t1; \
\
t2 = krr; \
t2 |= rr; \
rl ^= t2; \
t3 = krl; \
t3 &= rl; \
rr ^= CAMELLIA_RL1(t3); \
} while (0 )
#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
do { \
ir = CAMELLIA_SP1110(xr & 0 xff) ^ \
CAMELLIA_SP0222((xr >> 24 ) & 0 xff) ^ \
CAMELLIA_SP3033((xr >> 16 ) & 0 xff) ^ \
CAMELLIA_SP4404((xr >> 8 ) & 0 xff); \
il = CAMELLIA_SP1110((xl >> 24 ) & 0 xff) ^ \
CAMELLIA_SP0222((xl >> 16 ) & 0 xff) ^ \
CAMELLIA_SP3033((xl >> 8 ) & 0 xff) ^ \
CAMELLIA_SP4404(xl & 0 xff); \
il ^= kl; \
ir ^= kr; \
ir ^= il; \
il = CAMELLIA_RR8(il); \
il ^= ir; \
yl ^= ir; \
yr ^= il; \
} while (0 )
static const PRUint32 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 PRUint32 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 PRUint32 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 PRUint32 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
};
/**
* Stuff related to the Camellia key schedule
*/
#define subl(x) subL[(x)]
#define subr(x) subR[(x)]
void
camellia_setup128(const unsigned char *key, PRUint32 *subkey)
{
PRUint32 kll, klr, krl, krr;
PRUint32 il, ir, t0, t1, w0, w1;
PRUint32 kw4l, kw4r, dw, tl, tr;
PRUint32 subL[26 ];
PRUint32 subR[26 ];
#if defined (CAMELLIA_NEED_TMP_VARIABLE)
PRUint32 tmp;
#endif
/**
* k == kll || klr || krl || krr (|| is concatination)
*/
kll = GETU32(key);
klr = GETU32(key + 4 );
krl = GETU32(key + 8 );
krr = GETU32(key + 12 );
/**
* generate KL dependent subkeys
*/
subl(0 ) = kll;
subr(0 ) = klr;
subl(1 ) = krl;
subr(1 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(4 ) = kll;
subr(4 ) = klr;
subl(5 ) = krl;
subr(5 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30 );
subl(10 ) = kll;
subr(10 ) = klr;
subl(11 ) = krl;
subr(11 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(13 ) = krl;
subr(13 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
subl(16 ) = kll;
subr(16 ) = klr;
subl(17 ) = krl;
subr(17 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
subl(18 ) = kll;
subr(18 ) = klr;
subl(19 ) = krl;
subr(19 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
subl(22 ) = kll;
subr(22 ) = klr;
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);
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 */
subl(2 ) = kll;
subr(2 ) = klr;
subl(3 ) = krl;
subr(3 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(6 ) = kll;
subr(6 ) = klr;
subl(7 ) = krl;
subr(7 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(8 ) = kll;
subr(8 ) = klr;
subl(9 ) = krl;
subr(9 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(12 ) = kll;
subr(12 ) = klr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(14 ) = kll;
subr(14 ) = klr;
subl(15 ) = krl;
subr(15 ) = krr;
CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34 );
subl(20 ) = kll;
subr(20 ) = klr;
subl(21 ) = krl;
subr(21 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
subl(24 ) = kll;
subr(24 ) = klr;
subl(25 ) = krl;
subr(25 ) = krr;
/* absorb kw2 to other subkeys */
subl(3 ) ^= subl(1 );
subr(3 ) ^= subr(1 );
subl(5 ) ^= subl(1 );
subr(5 ) ^= subr(1 );
subl(7 ) ^= subl(1 );
subr(7 ) ^= subr(1 );
subl(1 ) ^= subr(1 ) & ~subr(9 );
dw = subl(1 ) & subl(9 ), subr(1 ) ^= CAMELLIA_RL1(dw);
subl(11 ) ^= subl(1 );
subr(11 ) ^= subr(1 );
subl(13 ) ^= subl(1 );
subr(13 ) ^= subr(1 );
subl(15 ) ^= subl(1 );
subr(15 ) ^= subr(1 );
subl(1 ) ^= subr(1 ) & ~subr(17 );
dw = subl(1 ) & subl(17 ), subr(1 ) ^= CAMELLIA_RL1(dw);
subl(19 ) ^= subl(1 );
subr(19 ) ^= subr(1 );
subl(21 ) ^= subl(1 );
subr(21 ) ^= subr(1 );
subl(23 ) ^= subl(1 );
subr(23 ) ^= subr(1 );
subl(24 ) ^= subl(1 );
subr(24 ) ^= subr(1 );
/* absorb kw4 to other subkeys */
kw4l = subl(25 );
kw4r = subr(25 );
subl(22 ) ^= kw4l;
subr(22 ) ^= kw4r;
subl(20 ) ^= kw4l;
subr(20 ) ^= kw4r;
subl(18 ) ^= kw4l;
subr(18 ) ^= kw4r;
kw4l ^= kw4r & ~subr(16 );
dw = kw4l & subl(16 ), kw4r ^= CAMELLIA_RL1(dw);
subl(14 ) ^= kw4l;
subr(14 ) ^= kw4r;
subl(12 ) ^= kw4l;
subr(12 ) ^= kw4r;
subl(10 ) ^= kw4l;
subr(10 ) ^= kw4r;
kw4l ^= kw4r & ~subr(8 );
dw = kw4l & subl(8 ), kw4r ^= CAMELLIA_RL1(dw);
subl(6 ) ^= kw4l;
subr(6 ) ^= kw4r;
subl(4 ) ^= kw4l;
subr(4 ) ^= kw4r;
subl(2 ) ^= kw4l;
subr(2 ) ^= kw4r;
subl(0 ) ^= kw4l;
subr(0 ) ^= kw4r;
/* key XOR is end of F-function */
CamelliaSubkeyL(0 ) = subl(0 ) ^ subl(2 );
CamelliaSubkeyR(0 ) = subr(0 ) ^ subr(2 );
CamelliaSubkeyL(2 ) = subl(3 );
CamelliaSubkeyR(2 ) = subr(3 );
CamelliaSubkeyL(3 ) = subl(2 ) ^ subl(4 );
CamelliaSubkeyR(3 ) = subr(2 ) ^ subr(4 );
CamelliaSubkeyL(4 ) = subl(3 ) ^ subl(5 );
CamelliaSubkeyR(4 ) = subr(3 ) ^ subr(5 );
CamelliaSubkeyL(5 ) = subl(4 ) ^ subl(6 );
CamelliaSubkeyR(5 ) = subr(4 ) ^ subr(6 );
CamelliaSubkeyL(6 ) = subl(5 ) ^ subl(7 );
CamelliaSubkeyR(6 ) = subr(5 ) ^ subr(7 );
tl = subl(10 ) ^ (subr(10 ) & ~subr(8 ));
dw = tl & subl(8 ), tr = subr(10 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(7 ) = subl(6 ) ^ tl;
CamelliaSubkeyR(7 ) = subr(6 ) ^ tr;
CamelliaSubkeyL(8 ) = subl(8 );
CamelliaSubkeyR(8 ) = subr(8 );
CamelliaSubkeyL(9 ) = subl(9 );
CamelliaSubkeyR(9 ) = subr(9 );
tl = subl(7 ) ^ (subr(7 ) & ~subr(9 ));
dw = tl & subl(9 ), tr = subr(7 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(10 ) = tl ^ subl(11 );
CamelliaSubkeyR(10 ) = tr ^ subr(11 );
CamelliaSubkeyL(11 ) = subl(10 ) ^ subl(12 );
CamelliaSubkeyR(11 ) = subr(10 ) ^ subr(12 );
CamelliaSubkeyL(12 ) = subl(11 ) ^ subl(13 );
CamelliaSubkeyR(12 ) = subr(11 ) ^ subr(13 );
CamelliaSubkeyL(13 ) = subl(12 ) ^ subl(14 );
CamelliaSubkeyR(13 ) = subr(12 ) ^ subr(14 );
CamelliaSubkeyL(14 ) = subl(13 ) ^ subl(15 );
CamelliaSubkeyR(14 ) = subr(13 ) ^ subr(15 );
tl = subl(18 ) ^ (subr(18 ) & ~subr(16 ));
dw = tl & subl(16 ), tr = subr(18 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(15 ) = subl(14 ) ^ tl;
CamelliaSubkeyR(15 ) = subr(14 ) ^ tr;
CamelliaSubkeyL(16 ) = subl(16 );
CamelliaSubkeyR(16 ) = subr(16 );
CamelliaSubkeyL(17 ) = subl(17 );
CamelliaSubkeyR(17 ) = subr(17 );
tl = subl(15 ) ^ (subr(15 ) & ~subr(17 ));
dw = tl & subl(17 ), tr = subr(15 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(18 ) = tl ^ subl(19 );
CamelliaSubkeyR(18 ) = tr ^ subr(19 );
CamelliaSubkeyL(19 ) = subl(18 ) ^ subl(20 );
CamelliaSubkeyR(19 ) = subr(18 ) ^ subr(20 );
CamelliaSubkeyL(20 ) = subl(19 ) ^ subl(21 );
CamelliaSubkeyR(20 ) = subr(19 ) ^ subr(21 );
CamelliaSubkeyL(21 ) = subl(20 ) ^ subl(22 );
CamelliaSubkeyR(21 ) = subr(20 ) ^ subr(22 );
CamelliaSubkeyL(22 ) = subl(21 ) ^ subl(23 );
CamelliaSubkeyR(22 ) = subr(21 ) ^ subr(23 );
CamelliaSubkeyL(23 ) = subl(22 );
CamelliaSubkeyR(23 ) = subr(22 );
CamelliaSubkeyL(24 ) = subl(24 ) ^ subl(23 );
CamelliaSubkeyR(24 ) = subr(24 ) ^ subr(23 );
/* apply the inverse of the last half of P-function */
dw = CamelliaSubkeyL(2 ) ^ CamelliaSubkeyR(2 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(2 ) = CamelliaSubkeyL(2 ) ^ dw, CamelliaSubkeyL(2 ) = dw;
dw = CamelliaSubkeyL(3 ) ^ CamelliaSubkeyR(3 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(3 ) = CamelliaSubkeyL(3 ) ^ dw, CamelliaSubkeyL(3 ) = dw;
dw = CamelliaSubkeyL(4 ) ^ CamelliaSubkeyR(4 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(4 ) = CamelliaSubkeyL(4 ) ^ dw, CamelliaSubkeyL(4 ) = dw;
dw = CamelliaSubkeyL(5 ) ^ CamelliaSubkeyR(5 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(5 ) = CamelliaSubkeyL(5 ) ^ dw, CamelliaSubkeyL(5 ) = dw;
dw = CamelliaSubkeyL(6 ) ^ CamelliaSubkeyR(6 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(6 ) = CamelliaSubkeyL(6 ) ^ dw, CamelliaSubkeyL(6 ) = dw;
dw = CamelliaSubkeyL(7 ) ^ CamelliaSubkeyR(7 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(7 ) = CamelliaSubkeyL(7 ) ^ dw, CamelliaSubkeyL(7 ) = dw;
dw = CamelliaSubkeyL(10 ) ^ CamelliaSubkeyR(10 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(10 ) = CamelliaSubkeyL(10 ) ^ dw, CamelliaSubkeyL(10 ) = dw;
dw = CamelliaSubkeyL(11 ) ^ CamelliaSubkeyR(11 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(11 ) = CamelliaSubkeyL(11 ) ^ dw, CamelliaSubkeyL(11 ) = dw;
dw = CamelliaSubkeyL(12 ) ^ CamelliaSubkeyR(12 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(12 ) = CamelliaSubkeyL(12 ) ^ dw, CamelliaSubkeyL(12 ) = dw;
dw = CamelliaSubkeyL(13 ) ^ CamelliaSubkeyR(13 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(13 ) = CamelliaSubkeyL(13 ) ^ dw, CamelliaSubkeyL(13 ) = dw;
dw = CamelliaSubkeyL(14 ) ^ CamelliaSubkeyR(14 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(14 ) = CamelliaSubkeyL(14 ) ^ dw, CamelliaSubkeyL(14 ) = dw;
dw = CamelliaSubkeyL(15 ) ^ CamelliaSubkeyR(15 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(15 ) = CamelliaSubkeyL(15 ) ^ dw, CamelliaSubkeyL(15 ) = dw;
dw = CamelliaSubkeyL(18 ) ^ CamelliaSubkeyR(18 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(18 ) = CamelliaSubkeyL(18 ) ^ dw, CamelliaSubkeyL(18 ) = dw;
dw = CamelliaSubkeyL(19 ) ^ CamelliaSubkeyR(19 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(19 ) = CamelliaSubkeyL(19 ) ^ dw, CamelliaSubkeyL(19 ) = dw;
dw = CamelliaSubkeyL(20 ) ^ CamelliaSubkeyR(20 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(20 ) = CamelliaSubkeyL(20 ) ^ dw, CamelliaSubkeyL(20 ) = dw;
dw = CamelliaSubkeyL(21 ) ^ CamelliaSubkeyR(21 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(21 ) = CamelliaSubkeyL(21 ) ^ dw, CamelliaSubkeyL(21 ) = dw;
dw = CamelliaSubkeyL(22 ) ^ CamelliaSubkeyR(22 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(22 ) = CamelliaSubkeyL(22 ) ^ dw, CamelliaSubkeyL(22 ) = dw;
dw = CamelliaSubkeyL(23 ) ^ CamelliaSubkeyR(23 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(23 ) = CamelliaSubkeyL(23 ) ^ dw, CamelliaSubkeyL(23 ) = dw;
return ;
}
void
camellia_setup256(const unsigned char *key, PRUint32 *subkey)
{
PRUint32 kll, klr, krl, krr; /* left half of key */
PRUint32 krll, krlr, krrl, krrr; /* right half of key */
PRUint32 il, ir, t0, t1, w0, w1; /* temporary variables */
PRUint32 kw4l, kw4r, dw, tl, tr;
PRUint32 subL[34 ];
PRUint32 subR[34 ];
#if defined (CAMELLIA_NEED_TMP_VARIABLE)
PRUint32 tmp;
#endif
/**
* key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
* (|| is concatination)
*/
kll = GETU32(key);
klr = GETU32(key + 4 );
krl = GETU32(key + 8 );
krr = GETU32(key + 12 );
krll = GETU32(key + 16 );
krlr = GETU32(key + 20 );
krrl = GETU32(key + 24 );
krrr = GETU32(key + 28 );
/* generate KL dependent subkeys */
subl(0 ) = kll;
subr(0 ) = klr;
subl(1 ) = krl;
subr(1 ) = krr;
CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45 );
subl(12 ) = kll;
subr(12 ) = klr;
subl(13 ) = krl;
subr(13 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(16 ) = kll;
subr(16 ) = klr;
subl(17 ) = krl;
subr(17 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17 );
subl(22 ) = kll;
subr(22 ) = klr;
subl(23 ) = krl;
subr(23 ) = krr;
CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34 );
subl(30 ) = kll;
subr(30 ) = klr;
subl(31 ) = krl;
subr(31 ) = krr;
/* generate KR dependent subkeys */
CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15 );
subl(4 ) = krll;
subr(4 ) = krlr;
subl(5 ) = krrl;
subr(5 ) = krrr;
CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15 );
subl(8 ) = krll;
subr(8 ) = krlr;
subl(9 ) = krrl;
subr(9 ) = krrr;
CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30 );
subl(18 ) = krll;
subr(18 ) = krlr;
subl(19 ) = krrl;
subr(19 ) = krrr;
CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34 );
subl(26 ) = krll;
subr(26 ) = krlr;
subl(27 ) = krrl;
subr(27 ) = krrr;
CAMELLIA_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 */
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15 );
subl(6 ) = kll;
subr(6 ) = klr;
subl(7 ) = krl;
subr(7 ) = krr;
CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30 );
subl(14 ) = kll;
subr(14 ) = klr;
subl(15 ) = krl;
subr(15 ) = krr;
subl(24 ) = klr;
subr(24 ) = krl;
subl(25 ) = krr;
subr(25 ) = kll;
CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49 );
subl(28 ) = kll;
subr(28 ) = klr;
subl(29 ) = krl;
subr(29 ) = krr;
/* generate KB dependent subkeys */
subl(2 ) = krll;
subr(2 ) = krlr;
subl(3 ) = krrl;
subr(3 ) = krrr;
CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30 );
subl(10 ) = krll;
subr(10 ) = krlr;
subl(11 ) = krrl;
subr(11 ) = krrr;
CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30 );
subl(20 ) = krll;
subr(20 ) = krlr;
subl(21 ) = krrl;
subr(21 ) = krrr;
CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51 );
subl(32 ) = krll;
subr(32 ) = krlr;
subl(33 ) = krrl;
subr(33 ) = krrr;
/* absorb kw2 to other subkeys */
subl(3 ) ^= subl(1 );
subr(3 ) ^= subr(1 );
subl(5 ) ^= subl(1 );
subr(5 ) ^= subr(1 );
subl(7 ) ^= subl(1 );
subr(7 ) ^= subr(1 );
subl(1 ) ^= subr(1 ) & ~subr(9 );
dw = subl(1 ) & subl(9 ), subr(1 ) ^= CAMELLIA_RL1(dw);
subl(11 ) ^= subl(1 );
subr(11 ) ^= subr(1 );
subl(13 ) ^= subl(1 );
subr(13 ) ^= subr(1 );
subl(15 ) ^= subl(1 );
subr(15 ) ^= subr(1 );
subl(1 ) ^= subr(1 ) & ~subr(17 );
dw = subl(1 ) & subl(17 ), subr(1 ) ^= CAMELLIA_RL1(dw);
subl(19 ) ^= subl(1 );
subr(19 ) ^= subr(1 );
subl(21 ) ^= subl(1 );
subr(21 ) ^= subr(1 );
subl(23 ) ^= subl(1 );
subr(23 ) ^= subr(1 );
subl(1 ) ^= subr(1 ) & ~subr(25 );
dw = subl(1 ) & subl(25 ), subr(1 ) ^= CAMELLIA_RL1(dw);
subl(27 ) ^= subl(1 );
subr(27 ) ^= subr(1 );
subl(29 ) ^= subl(1 );
subr(29 ) ^= subr(1 );
subl(31 ) ^= subl(1 );
subr(31 ) ^= subr(1 );
subl(32 ) ^= subl(1 );
subr(32 ) ^= subr(1 );
/* absorb kw4 to other subkeys */
kw4l = subl(33 );
kw4r = subr(33 );
subl(30 ) ^= kw4l;
subr(30 ) ^= kw4r;
subl(28 ) ^= kw4l;
subr(28 ) ^= kw4r;
subl(26 ) ^= kw4l;
subr(26 ) ^= kw4r;
kw4l ^= kw4r & ~subr(24 );
dw = kw4l & subl(24 ), kw4r ^= CAMELLIA_RL1(dw);
subl(22 ) ^= kw4l;
subr(22 ) ^= kw4r;
subl(20 ) ^= kw4l;
subr(20 ) ^= kw4r;
subl(18 ) ^= kw4l;
subr(18 ) ^= kw4r;
kw4l ^= kw4r & ~subr(16 );
dw = kw4l & subl(16 ), kw4r ^= CAMELLIA_RL1(dw);
subl(14 ) ^= kw4l;
subr(14 ) ^= kw4r;
subl(12 ) ^= kw4l;
subr(12 ) ^= kw4r;
subl(10 ) ^= kw4l;
subr(10 ) ^= kw4r;
kw4l ^= kw4r & ~subr(8 );
dw = kw4l & subl(8 ), kw4r ^= CAMELLIA_RL1(dw);
subl(6 ) ^= kw4l;
subr(6 ) ^= kw4r;
subl(4 ) ^= kw4l;
subr(4 ) ^= kw4r;
subl(2 ) ^= kw4l;
subr(2 ) ^= kw4r;
subl(0 ) ^= kw4l;
subr(0 ) ^= kw4r;
/* key XOR is end of F-function */
CamelliaSubkeyL(0 ) = subl(0 ) ^ subl(2 );
CamelliaSubkeyR(0 ) = subr(0 ) ^ subr(2 );
CamelliaSubkeyL(2 ) = subl(3 );
CamelliaSubkeyR(2 ) = subr(3 );
CamelliaSubkeyL(3 ) = subl(2 ) ^ subl(4 );
CamelliaSubkeyR(3 ) = subr(2 ) ^ subr(4 );
CamelliaSubkeyL(4 ) = subl(3 ) ^ subl(5 );
CamelliaSubkeyR(4 ) = subr(3 ) ^ subr(5 );
CamelliaSubkeyL(5 ) = subl(4 ) ^ subl(6 );
CamelliaSubkeyR(5 ) = subr(4 ) ^ subr(6 );
CamelliaSubkeyL(6 ) = subl(5 ) ^ subl(7 );
CamelliaSubkeyR(6 ) = subr(5 ) ^ subr(7 );
tl = subl(10 ) ^ (subr(10 ) & ~subr(8 ));
dw = tl & subl(8 ), tr = subr(10 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(7 ) = subl(6 ) ^ tl;
CamelliaSubkeyR(7 ) = subr(6 ) ^ tr;
CamelliaSubkeyL(8 ) = subl(8 );
CamelliaSubkeyR(8 ) = subr(8 );
CamelliaSubkeyL(9 ) = subl(9 );
CamelliaSubkeyR(9 ) = subr(9 );
tl = subl(7 ) ^ (subr(7 ) & ~subr(9 ));
dw = tl & subl(9 ), tr = subr(7 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(10 ) = tl ^ subl(11 );
CamelliaSubkeyR(10 ) = tr ^ subr(11 );
CamelliaSubkeyL(11 ) = subl(10 ) ^ subl(12 );
CamelliaSubkeyR(11 ) = subr(10 ) ^ subr(12 );
CamelliaSubkeyL(12 ) = subl(11 ) ^ subl(13 );
CamelliaSubkeyR(12 ) = subr(11 ) ^ subr(13 );
CamelliaSubkeyL(13 ) = subl(12 ) ^ subl(14 );
CamelliaSubkeyR(13 ) = subr(12 ) ^ subr(14 );
CamelliaSubkeyL(14 ) = subl(13 ) ^ subl(15 );
CamelliaSubkeyR(14 ) = subr(13 ) ^ subr(15 );
tl = subl(18 ) ^ (subr(18 ) & ~subr(16 ));
dw = tl & subl(16 ), tr = subr(18 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(15 ) = subl(14 ) ^ tl;
CamelliaSubkeyR(15 ) = subr(14 ) ^ tr;
CamelliaSubkeyL(16 ) = subl(16 );
CamelliaSubkeyR(16 ) = subr(16 );
CamelliaSubkeyL(17 ) = subl(17 );
CamelliaSubkeyR(17 ) = subr(17 );
tl = subl(15 ) ^ (subr(15 ) & ~subr(17 ));
dw = tl & subl(17 ), tr = subr(15 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(18 ) = tl ^ subl(19 );
CamelliaSubkeyR(18 ) = tr ^ subr(19 );
CamelliaSubkeyL(19 ) = subl(18 ) ^ subl(20 );
CamelliaSubkeyR(19 ) = subr(18 ) ^ subr(20 );
CamelliaSubkeyL(20 ) = subl(19 ) ^ subl(21 );
CamelliaSubkeyR(20 ) = subr(19 ) ^ subr(21 );
CamelliaSubkeyL(21 ) = subl(20 ) ^ subl(22 );
CamelliaSubkeyR(21 ) = subr(20 ) ^ subr(22 );
CamelliaSubkeyL(22 ) = subl(21 ) ^ subl(23 );
CamelliaSubkeyR(22 ) = subr(21 ) ^ subr(23 );
tl = subl(26 ) ^ (subr(26 ) & ~subr(24 ));
dw = tl & subl(24 ), tr = subr(26 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(23 ) = subl(22 ) ^ tl;
CamelliaSubkeyR(23 ) = subr(22 ) ^ tr;
CamelliaSubkeyL(24 ) = subl(24 );
CamelliaSubkeyR(24 ) = subr(24 );
CamelliaSubkeyL(25 ) = subl(25 );
CamelliaSubkeyR(25 ) = subr(25 );
tl = subl(23 ) ^ (subr(23 ) & ~subr(25 ));
dw = tl & subl(25 ), tr = subr(23 ) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(26 ) = tl ^ subl(27 );
CamelliaSubkeyR(26 ) = tr ^ subr(27 );
CamelliaSubkeyL(27 ) = subl(26 ) ^ subl(28 );
CamelliaSubkeyR(27 ) = subr(26 ) ^ subr(28 );
CamelliaSubkeyL(28 ) = subl(27 ) ^ subl(29 );
CamelliaSubkeyR(28 ) = subr(27 ) ^ subr(29 );
CamelliaSubkeyL(29 ) = subl(28 ) ^ subl(30 );
CamelliaSubkeyR(29 ) = subr(28 ) ^ subr(30 );
CamelliaSubkeyL(30 ) = subl(29 ) ^ subl(31 );
CamelliaSubkeyR(30 ) = subr(29 ) ^ subr(31 );
CamelliaSubkeyL(31 ) = subl(30 );
CamelliaSubkeyR(31 ) = subr(30 );
CamelliaSubkeyL(32 ) = subl(32 ) ^ subl(31 );
CamelliaSubkeyR(32 ) = subr(32 ) ^ subr(31 );
/* apply the inverse of the last half of P-function */
dw = CamelliaSubkeyL(2 ) ^ CamelliaSubkeyR(2 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(2 ) = CamelliaSubkeyL(2 ) ^ dw, CamelliaSubkeyL(2 ) = dw;
dw = CamelliaSubkeyL(3 ) ^ CamelliaSubkeyR(3 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(3 ) = CamelliaSubkeyL(3 ) ^ dw, CamelliaSubkeyL(3 ) = dw;
dw = CamelliaSubkeyL(4 ) ^ CamelliaSubkeyR(4 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(4 ) = CamelliaSubkeyL(4 ) ^ dw, CamelliaSubkeyL(4 ) = dw;
dw = CamelliaSubkeyL(5 ) ^ CamelliaSubkeyR(5 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(5 ) = CamelliaSubkeyL(5 ) ^ dw, CamelliaSubkeyL(5 ) = dw;
dw = CamelliaSubkeyL(6 ) ^ CamelliaSubkeyR(6 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(6 ) = CamelliaSubkeyL(6 ) ^ dw, CamelliaSubkeyL(6 ) = dw;
dw = CamelliaSubkeyL(7 ) ^ CamelliaSubkeyR(7 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(7 ) = CamelliaSubkeyL(7 ) ^ dw, CamelliaSubkeyL(7 ) = dw;
dw = CamelliaSubkeyL(10 ) ^ CamelliaSubkeyR(10 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(10 ) = CamelliaSubkeyL(10 ) ^ dw, CamelliaSubkeyL(10 ) = dw;
dw = CamelliaSubkeyL(11 ) ^ CamelliaSubkeyR(11 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(11 ) = CamelliaSubkeyL(11 ) ^ dw, CamelliaSubkeyL(11 ) = dw;
dw = CamelliaSubkeyL(12 ) ^ CamelliaSubkeyR(12 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(12 ) = CamelliaSubkeyL(12 ) ^ dw, CamelliaSubkeyL(12 ) = dw;
dw = CamelliaSubkeyL(13 ) ^ CamelliaSubkeyR(13 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(13 ) = CamelliaSubkeyL(13 ) ^ dw, CamelliaSubkeyL(13 ) = dw;
dw = CamelliaSubkeyL(14 ) ^ CamelliaSubkeyR(14 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(14 ) = CamelliaSubkeyL(14 ) ^ dw, CamelliaSubkeyL(14 ) = dw;
dw = CamelliaSubkeyL(15 ) ^ CamelliaSubkeyR(15 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(15 ) = CamelliaSubkeyL(15 ) ^ dw, CamelliaSubkeyL(15 ) = dw;
dw = CamelliaSubkeyL(18 ) ^ CamelliaSubkeyR(18 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(18 ) = CamelliaSubkeyL(18 ) ^ dw, CamelliaSubkeyL(18 ) = dw;
dw = CamelliaSubkeyL(19 ) ^ CamelliaSubkeyR(19 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(19 ) = CamelliaSubkeyL(19 ) ^ dw, CamelliaSubkeyL(19 ) = dw;
dw = CamelliaSubkeyL(20 ) ^ CamelliaSubkeyR(20 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(20 ) = CamelliaSubkeyL(20 ) ^ dw, CamelliaSubkeyL(20 ) = dw;
dw = CamelliaSubkeyL(21 ) ^ CamelliaSubkeyR(21 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(21 ) = CamelliaSubkeyL(21 ) ^ dw, CamelliaSubkeyL(21 ) = dw;
dw = CamelliaSubkeyL(22 ) ^ CamelliaSubkeyR(22 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(22 ) = CamelliaSubkeyL(22 ) ^ dw, CamelliaSubkeyL(22 ) = dw;
dw = CamelliaSubkeyL(23 ) ^ CamelliaSubkeyR(23 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(23 ) = CamelliaSubkeyL(23 ) ^ dw, CamelliaSubkeyL(23 ) = dw;
dw = CamelliaSubkeyL(26 ) ^ CamelliaSubkeyR(26 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(26 ) = CamelliaSubkeyL(26 ) ^ dw, CamelliaSubkeyL(26 ) = dw;
dw = CamelliaSubkeyL(27 ) ^ CamelliaSubkeyR(27 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(27 ) = CamelliaSubkeyL(27 ) ^ dw, CamelliaSubkeyL(27 ) = dw;
dw = CamelliaSubkeyL(28 ) ^ CamelliaSubkeyR(28 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(28 ) = CamelliaSubkeyL(28 ) ^ dw, CamelliaSubkeyL(28 ) = dw;
dw = CamelliaSubkeyL(29 ) ^ CamelliaSubkeyR(29 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(29 ) = CamelliaSubkeyL(29 ) ^ dw, CamelliaSubkeyL(29 ) = dw;
dw = CamelliaSubkeyL(30 ) ^ CamelliaSubkeyR(30 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(30 ) = CamelliaSubkeyL(30 ) ^ dw, CamelliaSubkeyL(30 ) = dw;
dw = CamelliaSubkeyL(31 ) ^ CamelliaSubkeyR(31 ), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(31 ) = CamelliaSubkeyL(31 ) ^ dw, CamelliaSubkeyL(31 ) = dw;
return ;
}
void
camellia_setup192(const unsigned char *key, PRUint32 *subkey)
{
unsigned char kk[32 ];
PRUint32 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);
return ;
}
/**
* Stuff related to camellia encryption/decryption
*
*/
SECStatus NO_SANITIZE_ALIGNMENT
camellia_encrypt128(const PRUint32 *subkey,
unsigned char *output,
const unsigned char *input)
{
PRUint32 il, ir, t0, t1;
PRUint32 io[4 ];
#if defined (CAMELLIA_NEED_TMP_VARIABLE)
PRUint32 tmp;
#endif
io[0 ] = GETU32(input);
io[1 ] = GETU32(input + 4 );
io[2 ] = GETU32(input + 8 );
io[3 ] = GETU32(input + 12 );
/* pre whitening but absorb kw2*/
io[0 ] ^= CamelliaSubkeyL(0 );
io[1 ] ^= CamelliaSubkeyR(0 );
/* main iteration */
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(2 ), CamelliaSubkeyR(2 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(3 ), CamelliaSubkeyR(3 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(4 ), CamelliaSubkeyR(4 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(5 ), CamelliaSubkeyR(5 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(6 ), CamelliaSubkeyR(6 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(7 ), CamelliaSubkeyR(7 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(8 ), CamelliaSubkeyR(8 ),
CamelliaSubkeyL(9 ), CamelliaSubkeyR(9 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(10 ), CamelliaSubkeyR(10 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(11 ), CamelliaSubkeyR(11 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(12 ), CamelliaSubkeyR(12 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(13 ), CamelliaSubkeyR(13 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(14 ), CamelliaSubkeyR(14 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(15 ), CamelliaSubkeyR(15 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(16 ), CamelliaSubkeyR(16 ),
CamelliaSubkeyL(17 ), CamelliaSubkeyR(17 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(18 ), CamelliaSubkeyR(18 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(19 ), CamelliaSubkeyR(19 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(20 ), CamelliaSubkeyR(20 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(21 ), CamelliaSubkeyR(21 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(22 ), CamelliaSubkeyR(22 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(23 ), CamelliaSubkeyR(23 ),
io[0 ], io[1 ], il, ir, t0, t1);
/* post whitening but kw4 */
io[2 ] ^= CamelliaSubkeyL(24 );
io[3 ] ^= CamelliaSubkeyR(24 );
t0 = io[0 ];
t1 = io[1 ];
io[0 ] = io[2 ];
io[1 ] = io[3 ];
io[2 ] = t0;
io[3 ] = t1;
PUTU32(output, io[0 ]);
PUTU32(output + 4 , io[1 ]);
PUTU32(output + 8 , io[2 ]);
PUTU32(output + 12 , io[3 ]);
return SECSuccess;
}
SECStatus NO_SANITIZE_ALIGNMENT
camellia_decrypt128(const PRUint32 *subkey,
unsigned char *output,
const unsigned char *input)
{
PRUint32 il, ir, t0, t1; /* temporary valiables */
PRUint32 io[4 ];
#if defined (CAMELLIA_NEED_TMP_VARIABLE)
PRUint32 tmp;
#endif
io[0 ] = GETU32(input);
io[1 ] = GETU32(input + 4 );
io[2 ] = GETU32(input + 8 );
io[3 ] = GETU32(input + 12 );
/* pre whitening but absorb kw2*/
io[0 ] ^= CamelliaSubkeyL(24 );
io[1 ] ^= CamelliaSubkeyR(24 );
/* main iteration */
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(23 ), CamelliaSubkeyR(23 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(22 ), CamelliaSubkeyR(22 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(21 ), CamelliaSubkeyR(21 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(20 ), CamelliaSubkeyR(20 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(19 ), CamelliaSubkeyR(19 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(18 ), CamelliaSubkeyR(18 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(17 ), CamelliaSubkeyR(17 ),
CamelliaSubkeyL(16 ), CamelliaSubkeyR(16 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(15 ), CamelliaSubkeyR(15 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(14 ), CamelliaSubkeyR(14 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(13 ), CamelliaSubkeyR(13 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(12 ), CamelliaSubkeyR(12 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(11 ), CamelliaSubkeyR(11 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(10 ), CamelliaSubkeyR(10 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(9 ), CamelliaSubkeyR(9 ),
CamelliaSubkeyL(8 ), CamelliaSubkeyR(8 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(7 ), CamelliaSubkeyR(7 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(6 ), CamelliaSubkeyR(6 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(5 ), CamelliaSubkeyR(5 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(4 ), CamelliaSubkeyR(4 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(3 ), CamelliaSubkeyR(3 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(2 ), CamelliaSubkeyR(2 ),
io[0 ], io[1 ], il, ir, t0, t1);
/* post whitening but kw4 */
io[2 ] ^= CamelliaSubkeyL(0 );
io[3 ] ^= CamelliaSubkeyR(0 );
t0 = io[0 ];
t1 = io[1 ];
io[0 ] = io[2 ];
io[1 ] = io[3 ];
io[2 ] = t0;
io[3 ] = t1;
PUTU32(output, io[0 ]);
PUTU32(output + 4 , io[1 ]);
PUTU32(output + 8 , io[2 ]);
PUTU32(output + 12 , io[3 ]);
return SECSuccess;
}
/**
* stuff for 192 and 256bit encryption/decryption
*/
SECStatus NO_SANITIZE_ALIGNMENT
camellia_encrypt256(const PRUint32 *subkey,
unsigned char *output,
const unsigned char *input)
{
PRUint32 il, ir, t0, t1; /* temporary valiables */
PRUint32 io[4 ];
#if defined (CAMELLIA_NEED_TMP_VARIABLE)
PRUint32 tmp;
#endif
io[0 ] = GETU32(input);
io[1 ] = GETU32(input + 4 );
io[2 ] = GETU32(input + 8 );
io[3 ] = GETU32(input + 12 );
/* pre whitening but absorb kw2*/
io[0 ] ^= CamelliaSubkeyL(0 );
io[1 ] ^= CamelliaSubkeyR(0 );
/* main iteration */
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(2 ), CamelliaSubkeyR(2 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(3 ), CamelliaSubkeyR(3 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(4 ), CamelliaSubkeyR(4 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(5 ), CamelliaSubkeyR(5 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(6 ), CamelliaSubkeyR(6 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(7 ), CamelliaSubkeyR(7 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(8 ), CamelliaSubkeyR(8 ),
CamelliaSubkeyL(9 ), CamelliaSubkeyR(9 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(10 ), CamelliaSubkeyR(10 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(11 ), CamelliaSubkeyR(11 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(12 ), CamelliaSubkeyR(12 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(13 ), CamelliaSubkeyR(13 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(14 ), CamelliaSubkeyR(14 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(15 ), CamelliaSubkeyR(15 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(16 ), CamelliaSubkeyR(16 ),
CamelliaSubkeyL(17 ), CamelliaSubkeyR(17 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(18 ), CamelliaSubkeyR(18 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(19 ), CamelliaSubkeyR(19 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(20 ), CamelliaSubkeyR(20 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(21 ), CamelliaSubkeyR(21 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(22 ), CamelliaSubkeyR(22 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(23 ), CamelliaSubkeyR(23 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(24 ), CamelliaSubkeyR(24 ),
CamelliaSubkeyL(25 ), CamelliaSubkeyR(25 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(26 ), CamelliaSubkeyR(26 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(27 ), CamelliaSubkeyR(27 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(28 ), CamelliaSubkeyR(28 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(29 ), CamelliaSubkeyR(29 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(30 ), CamelliaSubkeyR(30 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(31 ), CamelliaSubkeyR(31 ),
io[0 ], io[1 ], il, ir, t0, t1);
/* post whitening but kw4 */
io[2 ] ^= CamelliaSubkeyL(32 );
io[3 ] ^= CamelliaSubkeyR(32 );
t0 = io[0 ];
t1 = io[1 ];
io[0 ] = io[2 ];
io[1 ] = io[3 ];
io[2 ] = t0;
io[3 ] = t1;
PUTU32(output, io[0 ]);
PUTU32(output + 4 , io[1 ]);
PUTU32(output + 8 , io[2 ]);
PUTU32(output + 12 , io[3 ]);
return SECSuccess;
}
SECStatus NO_SANITIZE_ALIGNMENT
camellia_decrypt256(const PRUint32 *subkey,
unsigned char *output,
const unsigned char *input)
{
PRUint32 il, ir, t0, t1; /* temporary valiables */
PRUint32 io[4 ];
#if defined (CAMELLIA_NEED_TMP_VARIABLE)
PRUint32 tmp;
#endif
io[0 ] = GETU32(input);
io[1 ] = GETU32(input + 4 );
io[2 ] = GETU32(input + 8 );
io[3 ] = GETU32(input + 12 );
/* pre whitening but absorb kw2*/
io[0 ] ^= CamelliaSubkeyL(32 );
io[1 ] ^= CamelliaSubkeyR(32 );
/* main iteration */
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(31 ), CamelliaSubkeyR(31 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(30 ), CamelliaSubkeyR(30 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(29 ), CamelliaSubkeyR(29 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(28 ), CamelliaSubkeyR(28 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(27 ), CamelliaSubkeyR(27 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(26 ), CamelliaSubkeyR(26 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(25 ), CamelliaSubkeyR(25 ),
CamelliaSubkeyL(24 ), CamelliaSubkeyR(24 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(23 ), CamelliaSubkeyR(23 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(22 ), CamelliaSubkeyR(22 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(21 ), CamelliaSubkeyR(21 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(20 ), CamelliaSubkeyR(20 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(19 ), CamelliaSubkeyR(19 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(18 ), CamelliaSubkeyR(18 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(17 ), CamelliaSubkeyR(17 ),
CamelliaSubkeyL(16 ), CamelliaSubkeyR(16 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(15 ), CamelliaSubkeyR(15 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(14 ), CamelliaSubkeyR(14 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(13 ), CamelliaSubkeyR(13 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(12 ), CamelliaSubkeyR(12 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(11 ), CamelliaSubkeyR(11 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(10 ), CamelliaSubkeyR(10 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_FLS(io[0 ], io[1 ], io[2 ], io[3 ],
CamelliaSubkeyL(9 ), CamelliaSubkeyR(9 ),
CamelliaSubkeyL(8 ), CamelliaSubkeyR(8 ),
t0, t1, il, ir);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(7 ), CamelliaSubkeyR(7 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(6 ), CamelliaSubkeyR(6 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(5 ), CamelliaSubkeyR(5 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(4 ), CamelliaSubkeyR(4 ),
io[0 ], io[1 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[0 ], io[1 ],
CamelliaSubkeyL(3 ), CamelliaSubkeyR(3 ),
io[2 ], io[3 ], il, ir, t0, t1);
CAMELLIA_ROUNDSM(io[2 ], io[3 ],
CamelliaSubkeyL(2 ), CamelliaSubkeyR(2 ),
io[0 ], io[1 ], il, ir, t0, t1);
/* post whitening but kw4 */
io[2 ] ^= CamelliaSubkeyL(0 );
io[3 ] ^= CamelliaSubkeyR(0 );
t0 = io[0 ];
t1 = io[1 ];
io[0 ] = io[2 ];
io[1 ] = io[3 ];
io[2 ] = t0;
io[3 ] = t1;
PUTU32(output, io[0 ]);
PUTU32(output + 4 , io[1 ]);
PUTU32(output + 8 , io[2 ]);
PUTU32(output + 12 , io[3 ]);
return SECSuccess;
}
/**************************************************************************
*
* Stuff related to the Camellia key schedule
*
*************************************************************************/
SECStatus
camellia_key_expansion(CamelliaContext *cx,
const unsigned char *key,
const unsigned int keysize)
{
cx->keysize = keysize;
switch (keysize) {
case 16 :
camellia_setup128(key, cx->expandedKey);
break ;
case 24 :
camellia_setup192(key, cx->expandedKey);
break ;
case 32 :
camellia_setup256(key, cx->expandedKey);
break ;
default :
break ;
}
return SECSuccess;
}
/**************************************************************************
*
* Camellia modes of operation (ECB and CBC)
*
*************************************************************************/
SECStatus
camellia_encryptECB(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
CamelliaBlockFunc *encryptor;
encryptor = (cx->keysize == 16 )
? &camellia_encrypt128
: &camellia_encrypt256;
while (inputLen > 0 ) {
(*encryptor)(cx->expandedKey, output, input);
output += CAMELLIA_BLOCK_SIZE;
input += CAMELLIA_BLOCK_SIZE;
inputLen -= CAMELLIA_BLOCK_SIZE;
}
return SECSuccess;
}
SECStatus
camellia_encryptCBC(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
unsigned int j;
unsigned char *lastblock;
unsigned char inblock[CAMELLIA_BLOCK_SIZE];
CamelliaBlockFunc *encryptor;
if (!inputLen)
return SECSuccess;
lastblock = cx->iv;
encryptor = (cx->keysize == 16 )
? &camellia_encrypt128
: &camellia_encrypt256;
while (inputLen > 0 ) {
/* XOR with the last block (IV if first block) */
for (j = 0 ; j < CAMELLIA_BLOCK_SIZE; ++j)
inblock[j] = input[j] ^ lastblock[j];
/* encrypt */
(*encryptor)(cx->expandedKey, output, inblock);
/* move to the next block */
lastblock = output;
output += CAMELLIA_BLOCK_SIZE;
input += CAMELLIA_BLOCK_SIZE;
inputLen -= CAMELLIA_BLOCK_SIZE;
}
memcpy(cx->iv, lastblock, CAMELLIA_BLOCK_SIZE);
return SECSuccess;
}
SECStatus
camellia_decryptECB(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
CamelliaBlockFunc *decryptor;
decryptor = (cx->keysize == 16 )
? &camellia_decrypt128
: &camellia_decrypt256;
while (inputLen > 0 ) {
(*decryptor)(cx->expandedKey, output, input);
output += CAMELLIA_BLOCK_SIZE;
input += CAMELLIA_BLOCK_SIZE;
inputLen -= CAMELLIA_BLOCK_SIZE;
}
return SECSuccess;
}
SECStatus
camellia_decryptCBC(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
const unsigned char *in;
unsigned char *out;
unsigned int j;
unsigned char newIV[CAMELLIA_BLOCK_SIZE];
CamelliaBlockFunc *decryptor;
if (!inputLen)
return SECSuccess;
PORT_Assert(output - input >= 0 || input - output >= (int )inputLen);
in = input + (inputLen - CAMELLIA_BLOCK_SIZE);
memcpy(newIV, in, CAMELLIA_BLOCK_SIZE);
out = output + (inputLen - CAMELLIA_BLOCK_SIZE);
decryptor = (cx->keysize == 16 )
? &camellia_decrypt128
: &camellia_decrypt256;
while (inputLen > CAMELLIA_BLOCK_SIZE) {
(*decryptor)(cx->expandedKey, out, in);
for (j = 0 ; j < CAMELLIA_BLOCK_SIZE; ++j)
out[j] ^= in[(int )(j - CAMELLIA_BLOCK_SIZE)];
out -= CAMELLIA_BLOCK_SIZE;
in -= CAMELLIA_BLOCK_SIZE;
inputLen -= CAMELLIA_BLOCK_SIZE;
}
if (in == input) {
(*decryptor)(cx->expandedKey, out, in);
for (j = 0 ; j < CAMELLIA_BLOCK_SIZE; ++j)
out[j] ^= cx->iv[j];
}
memcpy(cx->iv, newIV, CAMELLIA_BLOCK_SIZE);
return SECSuccess;
}
/**************************************************************************
*
* BLAPI Interface functions
*
*************************************************************************/
CamelliaContext *
Camellia_AllocateContext(void )
{
return PORT_ZNew(CamelliaContext);
}
SECStatus
Camellia_InitContext(CamelliaContext *cx, const unsigned char *key,
unsigned int keysize,
const unsigned char *iv, int mode, unsigned int encrypt,
unsigned int unused)
{
if (key == NULL ||
(keysize != 16 && keysize != 24 && keysize != 32 )) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (mode != NSS_CAMELLIA && mode != NSS_CAMELLIA_CBC) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (mode == NSS_CAMELLIA_CBC && iv == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (!cx) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (mode == NSS_CAMELLIA_CBC) {
memcpy(cx->iv, iv, CAMELLIA_BLOCK_SIZE);
cx->worker = (encrypt) ? &camellia_encryptCBC : &camellia_decryptCBC;
} else {
cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
}
/* Generate expanded key */
if (camellia_key_expansion(cx, key, keysize) != SECSuccess)
goto cleanup;
return SECSuccess;
cleanup:
return SECFailure;
}
/*
* Camellia_CreateContext
* create a new context for Camellia operations
*/
CamelliaContext *
Camellia_CreateContext(const unsigned char *key, const unsigned char *iv,
int mode, int encrypt,
unsigned int keysize)
{
CamelliaContext *cx;
if (key == NULL ||
(keysize != 16 && keysize != 24 && keysize != 32 )) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
if (mode != NSS_CAMELLIA && mode != NSS_CAMELLIA_CBC) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
if (mode == NSS_CAMELLIA_CBC && iv == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
cx = PORT_ZNew(CamelliaContext);
if (!cx) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return NULL;
}
/* copy in the iv, if neccessary */
if (mode == NSS_CAMELLIA_CBC) {
memcpy(cx->iv, iv, CAMELLIA_BLOCK_SIZE);
cx->worker = (encrypt) ? &camellia_encryptCBC : &camellia_decryptCBC;
} else {
cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
}
/* copy keysize */
cx->keysize = keysize;
/* Generate expanded key */
if (camellia_key_expansion(cx, key, keysize) != SECSuccess)
goto cleanup;
return cx;
cleanup:
PORT_ZFree(cx, sizeof *cx);
return NULL;
}
/*
* Camellia_DestroyContext
*
* Zero an Camellia cipher context. If freeit is true, also free the pointer
* to the context.
*/
void
Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit)
{
if (cx)
memset(cx, 0 , sizeof *cx);
if (freeit)
PORT_Free(cx);
}
/*
* Camellia_Encrypt
*
* Encrypt an arbitrary-length buffer. The output buffer must already be
* allocated to at least inputLen.
*/
SECStatus
Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
/* Check args */
if (cx == NULL || output == NULL || input == NULL ||
outputLen == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (inputLen % CAMELLIA_BLOCK_SIZE != 0 ) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
*outputLen = inputLen;
return (*cx->worker)(cx, output, outputLen, maxOutputLen,
input, inputLen);
}
/*
* Camellia_Decrypt
*
* Decrypt and arbitrary-length buffer. The output buffer must already be
* allocated to at least inputLen.
*/
SECStatus
Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
/* Check args */
if (cx == NULL || output == NULL || input == NULL || outputLen == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (inputLen % CAMELLIA_BLOCK_SIZE != 0 ) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
*outputLen = inputLen;
return (*cx->worker)(cx, output, outputLen, maxOutputLen,
input, inputLen);
}
Messung V0.5 in Prozent C=89 H=88 G=88
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet am 2026-06-06)
¤
*© Formatika GbR, Deutschland