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