CamelliaLightEngine.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  7. {
  8. /**
  9. * Camellia - based on RFC 3713, smaller implementation, about half the size of CamelliaEngine.
  10. */
  11. public class CamelliaLightEngine
  12. : IBlockCipher
  13. {
  14. private const int BLOCK_SIZE = 16;
  15. // private const int MASK8 = 0xff;
  16. private bool initialised;
  17. private bool _keyis128;
  18. private uint[] subkey = new uint[24 * 4];
  19. private uint[] kw = new uint[4 * 2]; // for whitening
  20. private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1)
  21. private static readonly uint[] SIGMA = {
  22. 0xa09e667f, 0x3bcc908b,
  23. 0xb67ae858, 0x4caa73b2,
  24. 0xc6ef372f, 0xe94f82be,
  25. 0x54ff53a5, 0xf1d36f1c,
  26. 0x10e527fa, 0xde682d1d,
  27. 0xb05688c2, 0xb3e6c1fd
  28. };
  29. /*
  30. *
  31. * S-box data
  32. *
  33. */
  34. private static readonly byte[] SBOX1 = {
  35. (byte)112, (byte)130, (byte)44, (byte)236,
  36. (byte)179, (byte)39, (byte)192, (byte)229,
  37. (byte)228, (byte)133, (byte)87, (byte)53,
  38. (byte)234, (byte)12, (byte)174, (byte)65,
  39. (byte)35, (byte)239, (byte)107, (byte)147,
  40. (byte)69, (byte)25, (byte)165, (byte)33,
  41. (byte)237, (byte)14, (byte)79, (byte)78,
  42. (byte)29, (byte)101, (byte)146, (byte)189,
  43. (byte)134, (byte)184, (byte)175, (byte)143,
  44. (byte)124, (byte)235, (byte)31, (byte)206,
  45. (byte)62, (byte)48, (byte)220, (byte)95,
  46. (byte)94, (byte)197, (byte)11, (byte)26,
  47. (byte)166, (byte)225, (byte)57, (byte)202,
  48. (byte)213, (byte)71, (byte)93, (byte)61,
  49. (byte)217, (byte)1, (byte)90, (byte)214,
  50. (byte)81, (byte)86, (byte)108, (byte)77,
  51. (byte)139, (byte)13, (byte)154, (byte)102,
  52. (byte)251, (byte)204, (byte)176, (byte)45,
  53. (byte)116, (byte)18, (byte)43, (byte)32,
  54. (byte)240, (byte)177, (byte)132, (byte)153,
  55. (byte)223, (byte)76, (byte)203, (byte)194,
  56. (byte)52, (byte)126, (byte)118, (byte)5,
  57. (byte)109, (byte)183, (byte)169, (byte)49,
  58. (byte)209, (byte)23, (byte)4, (byte)215,
  59. (byte)20, (byte)88, (byte)58, (byte)97,
  60. (byte)222, (byte)27, (byte)17, (byte)28,
  61. (byte)50, (byte)15, (byte)156, (byte)22,
  62. (byte)83, (byte)24, (byte)242, (byte)34,
  63. (byte)254, (byte)68, (byte)207, (byte)178,
  64. (byte)195, (byte)181, (byte)122, (byte)145,
  65. (byte)36, (byte)8, (byte)232, (byte)168,
  66. (byte)96, (byte)252, (byte)105, (byte)80,
  67. (byte)170, (byte)208, (byte)160, (byte)125,
  68. (byte)161, (byte)137, (byte)98, (byte)151,
  69. (byte)84, (byte)91, (byte)30, (byte)149,
  70. (byte)224, (byte)255, (byte)100, (byte)210,
  71. (byte)16, (byte)196, (byte)0, (byte)72,
  72. (byte)163, (byte)247, (byte)117, (byte)219,
  73. (byte)138, (byte)3, (byte)230, (byte)218,
  74. (byte)9, (byte)63, (byte)221, (byte)148,
  75. (byte)135, (byte)92, (byte)131, (byte)2,
  76. (byte)205, (byte)74, (byte)144, (byte)51,
  77. (byte)115, (byte)103, (byte)246, (byte)243,
  78. (byte)157, (byte)127, (byte)191, (byte)226,
  79. (byte)82, (byte)155, (byte)216, (byte)38,
  80. (byte)200, (byte)55, (byte)198, (byte)59,
  81. (byte)129, (byte)150, (byte)111, (byte)75,
  82. (byte)19, (byte)190, (byte)99, (byte)46,
  83. (byte)233, (byte)121, (byte)167, (byte)140,
  84. (byte)159, (byte)110, (byte)188, (byte)142,
  85. (byte)41, (byte)245, (byte)249, (byte)182,
  86. (byte)47, (byte)253, (byte)180, (byte)89,
  87. (byte)120, (byte)152, (byte)6, (byte)106,
  88. (byte)231, (byte)70, (byte)113, (byte)186,
  89. (byte)212, (byte)37, (byte)171, (byte)66,
  90. (byte)136, (byte)162, (byte)141, (byte)250,
  91. (byte)114, (byte)7, (byte)185, (byte)85,
  92. (byte)248, (byte)238, (byte)172, (byte)10,
  93. (byte)54, (byte)73, (byte)42, (byte)104,
  94. (byte)60, (byte)56, (byte)241, (byte)164,
  95. (byte)64, (byte)40, (byte)211, (byte)123,
  96. (byte)187, (byte)201, (byte)67, (byte)193,
  97. (byte)21, (byte)227, (byte)173, (byte)244,
  98. (byte)119, (byte)199, (byte)128, (byte)158
  99. };
  100. private static uint rightRotate(uint x, int s)
  101. {
  102. return ((x >> s) + (x << (32 - s)));
  103. }
  104. private static uint leftRotate(uint x, int s)
  105. {
  106. return (x << s) + (x >> (32 - s));
  107. }
  108. private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
  109. {
  110. ko[0 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot));
  111. ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot));
  112. ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot));
  113. ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot));
  114. ki[0 + ioff] = ko[0 + ooff];
  115. ki[1 + ioff] = ko[1 + ooff];
  116. ki[2 + ioff] = ko[2 + ooff];
  117. ki[3 + ioff] = ko[3 + ooff];
  118. }
  119. private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
  120. {
  121. ko[2 + ooff] = (ki[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot));
  122. ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot));
  123. ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot));
  124. ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot));
  125. ki[0 + ioff] = ko[2 + ooff];
  126. ki[1 + ioff] = ko[3 + ooff];
  127. ki[2 + ioff] = ko[0 + ooff];
  128. ki[3 + ioff] = ko[1 + ooff];
  129. }
  130. private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
  131. {
  132. ko[0 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot));
  133. ko[1 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot));
  134. ko[2 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot));
  135. ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
  136. ki[0 + ioff] = ko[0 + ooff];
  137. ki[1 + ioff] = ko[1 + ooff];
  138. ki[2 + ioff] = ko[2 + ooff];
  139. ki[3 + ioff] = ko[3 + ooff];
  140. }
  141. private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
  142. {
  143. ko[2 + ooff] = (ki[1 + ioff] << (rot - 32)) | (ki[2 + ioff] >> (64 - rot));
  144. ko[3 + ooff] = (ki[2 + ioff] << (rot - 32)) | (ki[3 + ioff] >> (64 - rot));
  145. ko[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot));
  146. ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
  147. ki[0 + ioff] = ko[2 + ooff];
  148. ki[1 + ioff] = ko[3 + ooff];
  149. ki[2 + ioff] = ko[0 + ooff];
  150. ki[3 + ioff] = ko[1 + ooff];
  151. }
  152. private byte lRot8(byte v, int rot)
  153. {
  154. return (byte)(((uint)v << rot) | ((uint)v >> (8 - rot)));
  155. }
  156. private uint sbox2(int x)
  157. {
  158. return (uint)lRot8(SBOX1[x], 1);
  159. }
  160. private uint sbox3(int x)
  161. {
  162. return (uint)lRot8(SBOX1[x], 7);
  163. }
  164. private uint sbox4(int x)
  165. {
  166. return (uint)SBOX1[lRot8((byte)x, 1)];
  167. }
  168. private void camelliaF2(uint[] s, uint[] skey, int keyoff)
  169. {
  170. uint t1, t2, u, v;
  171. t1 = s[0] ^ skey[0 + keyoff];
  172. u = sbox4((byte)t1);
  173. u |= (sbox3((byte)(t1 >> 8)) << 8);
  174. u |= (sbox2((byte)(t1 >> 16)) << 16);
  175. u |= ((uint)(SBOX1[(byte)(t1 >> 24)]) << 24);
  176. t2 = s[1] ^ skey[1 + keyoff];
  177. v = (uint)SBOX1[(byte)t2];
  178. v |= (sbox4((byte)(t2 >> 8)) << 8);
  179. v |= (sbox3((byte)(t2 >> 16)) << 16);
  180. v |= (sbox2((byte)(t2 >> 24)) << 24);
  181. v = leftRotate(v, 8);
  182. u ^= v;
  183. v = leftRotate(v, 8) ^ u;
  184. u = rightRotate(u, 8) ^ v;
  185. s[2] ^= leftRotate(v, 16) ^ u;
  186. s[3] ^= leftRotate(u, 8);
  187. t1 = s[2] ^ skey[2 + keyoff];
  188. u = sbox4((byte)t1);
  189. u |= sbox3((byte)(t1 >> 8)) << 8;
  190. u |= sbox2((byte)(t1 >> 16)) << 16;
  191. u |= ((uint)SBOX1[(byte)(t1 >> 24)]) << 24;
  192. t2 = s[3] ^ skey[3 + keyoff];
  193. v = (uint)SBOX1[(byte)t2];
  194. v |= sbox4((byte)(t2 >> 8)) << 8;
  195. v |= sbox3((byte)(t2 >> 16)) << 16;
  196. v |= sbox2((byte)(t2 >> 24)) << 24;
  197. v = leftRotate(v, 8);
  198. u ^= v;
  199. v = leftRotate(v, 8) ^ u;
  200. u = rightRotate(u, 8) ^ v;
  201. s[0] ^= leftRotate(v, 16) ^ u;
  202. s[1] ^= leftRotate(u, 8);
  203. }
  204. private void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
  205. {
  206. s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1);
  207. s[0] ^= fkey[1 + keyoff] | s[1];
  208. s[2] ^= fkey[3 + keyoff] | s[3];
  209. s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1);
  210. }
  211. private void setKey(bool forEncryption, byte[] key)
  212. {
  213. uint[] k = new uint[8];
  214. uint[] ka = new uint[4];
  215. uint[] kb = new uint[4];
  216. uint[] t = new uint[4];
  217. switch (key.Length)
  218. {
  219. case 16:
  220. _keyis128 = true;
  221. Pack.BE_To_UInt32(key, 0, k, 0, 4);
  222. k[4] = k[5] = k[6] = k[7] = 0;
  223. break;
  224. case 24:
  225. Pack.BE_To_UInt32(key, 0, k, 0, 6);
  226. k[6] = ~k[4];
  227. k[7] = ~k[5];
  228. _keyis128 = false;
  229. break;
  230. case 32:
  231. Pack.BE_To_UInt32(key, 0, k, 0, 8);
  232. _keyis128 = false;
  233. break;
  234. default:
  235. throw new ArgumentException("key sizes are only 16/24/32 bytes.");
  236. }
  237. for (int i = 0; i < 4; i++)
  238. {
  239. ka[i] = k[i] ^ k[i + 4];
  240. }
  241. /* compute KA */
  242. camelliaF2(ka, SIGMA, 0);
  243. for (int i = 0; i < 4; i++)
  244. {
  245. ka[i] ^= k[i];
  246. }
  247. camelliaF2(ka, SIGMA, 4);
  248. if (_keyis128)
  249. {
  250. if (forEncryption)
  251. {
  252. /* KL dependant keys */
  253. kw[0] = k[0];
  254. kw[1] = k[1];
  255. kw[2] = k[2];
  256. kw[3] = k[3];
  257. roldq(15, k, 0, subkey, 4);
  258. roldq(30, k, 0, subkey, 12);
  259. roldq(15, k, 0, t, 0);
  260. subkey[18] = t[2];
  261. subkey[19] = t[3];
  262. roldq(17, k, 0, ke, 4);
  263. roldq(17, k, 0, subkey, 24);
  264. roldq(17, k, 0, subkey, 32);
  265. /* KA dependant keys */
  266. subkey[0] = ka[0];
  267. subkey[1] = ka[1];
  268. subkey[2] = ka[2];
  269. subkey[3] = ka[3];
  270. roldq(15, ka, 0, subkey, 8);
  271. roldq(15, ka, 0, ke, 0);
  272. roldq(15, ka, 0, t, 0);
  273. subkey[16] = t[0];
  274. subkey[17] = t[1];
  275. roldq(15, ka, 0, subkey, 20);
  276. roldqo32(34, ka, 0, subkey, 28);
  277. roldq(17, ka, 0, kw, 4);
  278. }
  279. else
  280. { // decryption
  281. /* KL dependant keys */
  282. kw[4] = k[0];
  283. kw[5] = k[1];
  284. kw[6] = k[2];
  285. kw[7] = k[3];
  286. decroldq(15, k, 0, subkey, 28);
  287. decroldq(30, k, 0, subkey, 20);
  288. decroldq(15, k, 0, t, 0);
  289. subkey[16] = t[0];
  290. subkey[17] = t[1];
  291. decroldq(17, k, 0, ke, 0);
  292. decroldq(17, k, 0, subkey, 8);
  293. decroldq(17, k, 0, subkey, 0);
  294. /* KA dependant keys */
  295. subkey[34] = ka[0];
  296. subkey[35] = ka[1];
  297. subkey[32] = ka[2];
  298. subkey[33] = ka[3];
  299. decroldq(15, ka, 0, subkey, 24);
  300. decroldq(15, ka, 0, ke, 4);
  301. decroldq(15, ka, 0, t, 0);
  302. subkey[18] = t[2];
  303. subkey[19] = t[3];
  304. decroldq(15, ka, 0, subkey, 12);
  305. decroldqo32(34, ka, 0, subkey, 4);
  306. roldq(17, ka, 0, kw, 0);
  307. }
  308. }
  309. else
  310. { // 192bit or 256bit
  311. /* compute KB */
  312. for (int i = 0; i < 4; i++)
  313. {
  314. kb[i] = ka[i] ^ k[i + 4];
  315. }
  316. camelliaF2(kb, SIGMA, 8);
  317. if (forEncryption)
  318. {
  319. /* KL dependant keys */
  320. kw[0] = k[0];
  321. kw[1] = k[1];
  322. kw[2] = k[2];
  323. kw[3] = k[3];
  324. roldqo32(45, k, 0, subkey, 16);
  325. roldq(15, k, 0, ke, 4);
  326. roldq(17, k, 0, subkey, 32);
  327. roldqo32(34, k, 0, subkey, 44);
  328. /* KR dependant keys */
  329. roldq(15, k, 4, subkey, 4);
  330. roldq(15, k, 4, ke, 0);
  331. roldq(30, k, 4, subkey, 24);
  332. roldqo32(34, k, 4, subkey, 36);
  333. /* KA dependant keys */
  334. roldq(15, ka, 0, subkey, 8);
  335. roldq(30, ka, 0, subkey, 20);
  336. /* 32bit rotation */
  337. ke[8] = ka[1];
  338. ke[9] = ka[2];
  339. ke[10] = ka[3];
  340. ke[11] = ka[0];
  341. roldqo32(49, ka, 0, subkey, 40);
  342. /* KB dependant keys */
  343. subkey[0] = kb[0];
  344. subkey[1] = kb[1];
  345. subkey[2] = kb[2];
  346. subkey[3] = kb[3];
  347. roldq(30, kb, 0, subkey, 12);
  348. roldq(30, kb, 0, subkey, 28);
  349. roldqo32(51, kb, 0, kw, 4);
  350. }
  351. else
  352. { // decryption
  353. /* KL dependant keys */
  354. kw[4] = k[0];
  355. kw[5] = k[1];
  356. kw[6] = k[2];
  357. kw[7] = k[3];
  358. decroldqo32(45, k, 0, subkey, 28);
  359. decroldq(15, k, 0, ke, 4);
  360. decroldq(17, k, 0, subkey, 12);
  361. decroldqo32(34, k, 0, subkey, 0);
  362. /* KR dependant keys */
  363. decroldq(15, k, 4, subkey, 40);
  364. decroldq(15, k, 4, ke, 8);
  365. decroldq(30, k, 4, subkey, 20);
  366. decroldqo32(34, k, 4, subkey, 8);
  367. /* KA dependant keys */
  368. decroldq(15, ka, 0, subkey, 36);
  369. decroldq(30, ka, 0, subkey, 24);
  370. /* 32bit rotation */
  371. ke[2] = ka[1];
  372. ke[3] = ka[2];
  373. ke[0] = ka[3];
  374. ke[1] = ka[0];
  375. decroldqo32(49, ka, 0, subkey, 4);
  376. /* KB dependant keys */
  377. subkey[46] = kb[0];
  378. subkey[47] = kb[1];
  379. subkey[44] = kb[2];
  380. subkey[45] = kb[3];
  381. decroldq(30, kb, 0, subkey, 32);
  382. decroldq(30, kb, 0, subkey, 16);
  383. roldqo32(51, kb, 0, kw, 0);
  384. }
  385. }
  386. }
  387. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  388. private int ProcessBlock128(ReadOnlySpan<byte> input, Span<byte> output)
  389. {
  390. uint[] state = new uint[4];
  391. Pack.BE_To_UInt32(input, state);
  392. state[0] ^= kw[0];
  393. state[1] ^= kw[1];
  394. state[2] ^= kw[2];
  395. state[3] ^= kw[3];
  396. camelliaF2(state, subkey, 0);
  397. camelliaF2(state, subkey, 4);
  398. camelliaF2(state, subkey, 8);
  399. camelliaFLs(state, ke, 0);
  400. camelliaF2(state, subkey, 12);
  401. camelliaF2(state, subkey, 16);
  402. camelliaF2(state, subkey, 20);
  403. camelliaFLs(state, ke, 4);
  404. camelliaF2(state, subkey, 24);
  405. camelliaF2(state, subkey, 28);
  406. camelliaF2(state, subkey, 32);
  407. Pack.UInt32_To_BE(state[2] ^ kw[4], output);
  408. Pack.UInt32_To_BE(state[3] ^ kw[5], output[4..]);
  409. Pack.UInt32_To_BE(state[0] ^ kw[6], output[8..]);
  410. Pack.UInt32_To_BE(state[1] ^ kw[7], output[12..]);
  411. return BLOCK_SIZE;
  412. }
  413. private int ProcessBlock192or256(ReadOnlySpan<byte> input, Span<byte> output)
  414. {
  415. uint[] state = new uint[4];
  416. Pack.BE_To_UInt32(input, state);
  417. state[0] ^= kw[0];
  418. state[1] ^= kw[1];
  419. state[2] ^= kw[2];
  420. state[3] ^= kw[3];
  421. camelliaF2(state, subkey, 0);
  422. camelliaF2(state, subkey, 4);
  423. camelliaF2(state, subkey, 8);
  424. camelliaFLs(state, ke, 0);
  425. camelliaF2(state, subkey, 12);
  426. camelliaF2(state, subkey, 16);
  427. camelliaF2(state, subkey, 20);
  428. camelliaFLs(state, ke, 4);
  429. camelliaF2(state, subkey, 24);
  430. camelliaF2(state, subkey, 28);
  431. camelliaF2(state, subkey, 32);
  432. camelliaFLs(state, ke, 8);
  433. camelliaF2(state, subkey, 36);
  434. camelliaF2(state, subkey, 40);
  435. camelliaF2(state, subkey, 44);
  436. Pack.UInt32_To_BE(state[2] ^ kw[4], output);
  437. Pack.UInt32_To_BE(state[3] ^ kw[5], output[4..]);
  438. Pack.UInt32_To_BE(state[0] ^ kw[6], output[8..]);
  439. Pack.UInt32_To_BE(state[1] ^ kw[7], output[12..]);
  440. return BLOCK_SIZE;
  441. }
  442. #else
  443. private int ProcessBlock128(byte[] input, int inOff, byte[] output, int outOff)
  444. {
  445. uint[] state = new uint[4];
  446. for (int i = 0; i < 4; i++)
  447. {
  448. state[i] = Pack.BE_To_UInt32(input, inOff + (i * 4)) ^ kw[i];
  449. }
  450. camelliaF2(state, subkey, 0);
  451. camelliaF2(state, subkey, 4);
  452. camelliaF2(state, subkey, 8);
  453. camelliaFLs(state, ke, 0);
  454. camelliaF2(state, subkey, 12);
  455. camelliaF2(state, subkey, 16);
  456. camelliaF2(state, subkey, 20);
  457. camelliaFLs(state, ke, 4);
  458. camelliaF2(state, subkey, 24);
  459. camelliaF2(state, subkey, 28);
  460. camelliaF2(state, subkey, 32);
  461. Pack.UInt32_To_BE(state[2] ^ kw[4], output, outOff);
  462. Pack.UInt32_To_BE(state[3] ^ kw[5], output, outOff + 4);
  463. Pack.UInt32_To_BE(state[0] ^ kw[6], output, outOff + 8);
  464. Pack.UInt32_To_BE(state[1] ^ kw[7], output, outOff + 12);
  465. return BLOCK_SIZE;
  466. }
  467. private int ProcessBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
  468. {
  469. uint[] state = new uint[4];
  470. for (int i = 0; i < 4; i++)
  471. {
  472. state[i] = Pack.BE_To_UInt32(input, inOff + (i * 4)) ^ kw[i];
  473. }
  474. camelliaF2(state, subkey, 0);
  475. camelliaF2(state, subkey, 4);
  476. camelliaF2(state, subkey, 8);
  477. camelliaFLs(state, ke, 0);
  478. camelliaF2(state, subkey, 12);
  479. camelliaF2(state, subkey, 16);
  480. camelliaF2(state, subkey, 20);
  481. camelliaFLs(state, ke, 4);
  482. camelliaF2(state, subkey, 24);
  483. camelliaF2(state, subkey, 28);
  484. camelliaF2(state, subkey, 32);
  485. camelliaFLs(state, ke, 8);
  486. camelliaF2(state, subkey, 36);
  487. camelliaF2(state, subkey, 40);
  488. camelliaF2(state, subkey, 44);
  489. Pack.UInt32_To_BE(state[2] ^ kw[4], output, outOff);
  490. Pack.UInt32_To_BE(state[3] ^ kw[5], output, outOff + 4);
  491. Pack.UInt32_To_BE(state[0] ^ kw[6], output, outOff + 8);
  492. Pack.UInt32_To_BE(state[1] ^ kw[7], output, outOff + 12);
  493. return BLOCK_SIZE;
  494. }
  495. #endif
  496. public CamelliaLightEngine()
  497. {
  498. initialised = false;
  499. }
  500. public virtual string AlgorithmName
  501. {
  502. get { return "Camellia"; }
  503. }
  504. public virtual int GetBlockSize()
  505. {
  506. return BLOCK_SIZE;
  507. }
  508. public virtual void Init(
  509. bool forEncryption,
  510. ICipherParameters parameters)
  511. {
  512. if (!(parameters is KeyParameter))
  513. throw new ArgumentException("only simple KeyParameter expected.");
  514. setKey(forEncryption, ((KeyParameter)parameters).GetKey());
  515. initialised = true;
  516. }
  517. public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
  518. {
  519. if (!initialised)
  520. throw new InvalidOperationException("Camellia engine not initialised");
  521. Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
  522. Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
  523. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  524. if (_keyis128)
  525. {
  526. return ProcessBlock128(input.AsSpan(inOff), output.AsSpan(outOff));
  527. }
  528. else
  529. {
  530. return ProcessBlock192or256(input.AsSpan(inOff), output.AsSpan(outOff));
  531. }
  532. #else
  533. if (_keyis128)
  534. {
  535. return ProcessBlock128(input, inOff, output, outOff);
  536. }
  537. else
  538. {
  539. return ProcessBlock192or256(input, inOff, output, outOff);
  540. }
  541. #endif
  542. }
  543. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  544. public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
  545. {
  546. if (!initialised)
  547. throw new InvalidOperationException("Camellia engine not initialised");
  548. Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
  549. Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
  550. if (_keyis128)
  551. {
  552. return ProcessBlock128(input, output);
  553. }
  554. else
  555. {
  556. return ProcessBlock192or256(input, output);
  557. }
  558. }
  559. #endif
  560. }
  561. }
  562. #pragma warning restore
  563. #endif