rc2.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /* rc2.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /*
  22. DESCRIPTION
  23. This library provides the interface to the RC2 encryption algorithm (RFC 2268)
  24. */
  25. #ifdef HAVE_CONFIG_H
  26. #include <config.h>
  27. #endif
  28. #include <wolfssl/wolfcrypt/settings.h>
  29. #ifdef WC_RC2
  30. #ifdef NO_INLINE
  31. #include <wolfssl/wolfcrypt/misc.h>
  32. #else
  33. #define WOLFSSL_MISC_INCLUDED
  34. #include <wolfcrypt/src/misc.c>
  35. #endif
  36. #include <wolfssl/wolfcrypt/rc2.h>
  37. #include <wolfssl/wolfcrypt/error-crypt.h>
  38. /* Table based on value of PI, defined in RFC 2268 */
  39. static const byte pitable[256] = {
  40. 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed,
  41. 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
  42. 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
  43. 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
  44. 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13,
  45. 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
  46. 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b,
  47. 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
  48. 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
  49. 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
  50. 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1,
  51. 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
  52. 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57,
  53. 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
  54. 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
  55. 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
  56. 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7,
  57. 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
  58. 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74,
  59. 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
  60. 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
  61. 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
  62. 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a,
  63. 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
  64. 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae,
  65. 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
  66. 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
  67. 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
  68. 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0,
  69. 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
  70. 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77,
  71. 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad
  72. };
  73. /**
  74. Sets RC2 IV, for use with CBC mode.
  75. rc2 RC2 structure to load IV into
  76. iv IV, of size RC2_BLOCK_SIZE octets
  77. return 0 on success, negative on error
  78. */
  79. int wc_Rc2SetIV(Rc2* rc2, const byte* iv)
  80. {
  81. if (rc2 == NULL)
  82. return BAD_FUNC_ARG;
  83. if (iv)
  84. XMEMCPY(rc2->reg, iv, RC2_BLOCK_SIZE);
  85. else
  86. XMEMSET(rc2->reg, 0, RC2_BLOCK_SIZE);
  87. return 0;
  88. }
  89. /**
  90. Set RC2 key, performing key expansion operation
  91. rc2 RC2 structure to load expanded key into
  92. key User key, up to 64 bytes
  93. length Length of key, octets
  94. bits Effective RC2 key length in bits (max 1024 bits)
  95. return 0 on success, negative on error
  96. */
  97. int wc_Rc2SetKey(Rc2* rc2, const byte* key, word32 length,
  98. const byte* iv, word32 bits)
  99. {
  100. int i;
  101. unsigned int T8, TM;
  102. byte* L = NULL;
  103. if (rc2 == NULL || key == NULL) {
  104. return BAD_FUNC_ARG;
  105. }
  106. if (length == 0 || length > 128 || bits == 0 || bits > 1024) {
  107. return WC_KEY_SIZE_E;
  108. }
  109. rc2->keylen = length;
  110. rc2->bits = bits;
  111. L = (byte*)rc2->key;
  112. XMEMCPY(L, key, length);
  113. /* compute effective key length in bytes (T8) */
  114. T8 = (bits + 7) >> 3;
  115. /* TM mask has 8 - (8*T8 - T1) least significant bits set */
  116. TM = 0xff >> (8*T8 - bits);
  117. /* key expansion */
  118. for (i = length; i < RC2_MAX_KEY_SIZE; i++) {
  119. L[i] = pitable[(L[i-1] + L[i-length]) & 255];
  120. }
  121. L[RC2_MAX_KEY_SIZE - T8] = pitable[L[RC2_MAX_KEY_SIZE - T8] & TM];
  122. for (i = RC2_MAX_KEY_SIZE-T8-1; i >= 0; i--) {
  123. L[i] = pitable[L[i+1] ^ L[i+T8]];
  124. }
  125. /* store key into 16-bit word format */
  126. for (i = 0; i < RC2_MAX_KEY_SIZE/2; i++) {
  127. rc2->key[i] = (word16)L[2*i] + ((word16)L[2*i+1] << 8);
  128. }
  129. return wc_Rc2SetIV(rc2, iv);
  130. }
  131. /**
  132. RC2 ECB encrypt operation on one single RC2_BLOCK_SIZE block.
  133. rc2 Initialized RC2 structure
  134. out [out] Destination for the encrypted ciphertext
  135. in Input plaintext to be encrypted
  136. sz Size of the output buffer, out
  137. return 0 on success, negative on error
  138. */
  139. int wc_Rc2EcbEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
  140. {
  141. int i, j = 0;
  142. word16 r10, r32, r54, r76;
  143. word16* key;
  144. if (rc2 == NULL || out == NULL || in == NULL) {
  145. return BAD_FUNC_ARG;
  146. }
  147. key = rc2->key;
  148. if (sz != RC2_BLOCK_SIZE) {
  149. return BUFFER_E;
  150. }
  151. r10 = (in[1] << 8) | in[0]; /* R[0] */
  152. r32 = (in[3] << 8) | in[2]; /* R[1] */
  153. r54 = (in[5] << 8) | in[4]; /* R[2] */
  154. r76 = (in[7] << 8) | in[6]; /* R[3] */
  155. for (i = 0; i < 16; i++) {
  156. j = i * 4;
  157. /* mixing round */
  158. r10 = r10 + key[j] + (r76 & r54) + (~r76 & r32);
  159. r10 = rotlFixed16(r10, 1);
  160. r32 = r32 + key[j+1] + (r10 & r76) + (~r10 & r54);
  161. r32 = rotlFixed16(r32, 2);
  162. r54 = r54 + key[j+2] + (r32 & r10) + (~r32 & r76);
  163. r54 = rotlFixed16(r54, 3);
  164. r76 = r76 + key[j+3] + (r54 & r32) + (~r54 & r10);
  165. r76 = rotlFixed16(r76, 5);
  166. /* mashing round on loop 5, 11 */
  167. if (i == 4 || i == 10) {
  168. r10 = r10 + key[r76 & 63];
  169. r32 = r32 + key[r10 & 63];
  170. r54 = r54 + key[r32 & 63];
  171. r76 = r76 + key[r54 & 63];
  172. }
  173. }
  174. out[0] = (byte)r10;
  175. out[1] = (byte)(r10 >> 8);
  176. out[2] = (byte)r32;
  177. out[3] = (byte)(r32 >> 8);
  178. out[4] = (byte)r54;
  179. out[5] = (byte)(r54 >> 8);
  180. out[6] = (byte)r76;
  181. out[7] = (byte)(r76 >> 8);
  182. return 0;
  183. }
  184. /**
  185. RC2 ECB decrypt operation on one single RC2_BLOCK_SIZE block.
  186. rc2 Initialized RC2 structure
  187. out [out] Destination for decrypted plaintext
  188. in Input ciphertext to be decrypted
  189. sz Size of the output buffer, out
  190. return 0 on success, negative on error
  191. */
  192. int wc_Rc2EcbDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
  193. {
  194. int i, j = 63;
  195. word16 r0, r1, r2, r3;
  196. word16* key;
  197. if (rc2 == NULL || out == NULL || in == NULL) {
  198. return BAD_FUNC_ARG;
  199. }
  200. key = rc2->key;
  201. if (sz != RC2_BLOCK_SIZE) {
  202. return BUFFER_E;
  203. }
  204. r0 = (in[1] << 8) | in[0];
  205. r1 = (in[3] << 8) | in[2];
  206. r2 = (in[5] << 8) | in[4];
  207. r3 = (in[7] << 8) | in[6];
  208. for (i = 16; i > 0; i--) {
  209. j = 4*i - 1;
  210. r3 = rotrFixed16(r3, 5);
  211. r3 = r3 - key[j] - (r2 & r1) - (~r2 & r0);
  212. r2 = rotrFixed16(r2, 3);
  213. r2 = r2 - key[j-1] - (r1 & r0) - (~r1 & r3);
  214. r1 = rotrFixed16(r1, 2);
  215. r1 = r1 - key[j-2] - (r0 & r3) - (~r0 & r2);
  216. r0 = rotrFixed16(r0, 1);
  217. r0 = r0 - key[j-3] - (r3 & r2) - (~r3 & r1);
  218. if (i == 12 || i == 6) {
  219. r3 = r3 - key[r2 & 63];
  220. r2 = r2 - key[r1 & 63];
  221. r1 = r1 - key[r0 & 63];
  222. r0 = r0 - key[r3 & 63];
  223. }
  224. }
  225. out[0] = (byte)r0;
  226. out[1] = (byte)(r0 >> 8);
  227. out[2] = (byte)r1;
  228. out[3] = (byte)(r1 >> 8);
  229. out[4] = (byte)r2;
  230. out[5] = (byte)(r2 >> 8);
  231. out[6] = (byte)r3;
  232. out[7] = (byte)(r3 >> 8);
  233. return 0;
  234. }
  235. int wc_Rc2CbcEncrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
  236. {
  237. int ret;
  238. word32 blocks = (sz / RC2_BLOCK_SIZE);
  239. if (rc2 == NULL || out == NULL || in == NULL) {
  240. return BAD_FUNC_ARG;
  241. }
  242. if (sz == 0) {
  243. return 0;
  244. }
  245. while (blocks--) {
  246. xorbuf((byte*)rc2->reg, in, RC2_BLOCK_SIZE);
  247. ret = wc_Rc2EcbEncrypt(rc2, (byte*)rc2->reg, (byte*)rc2->reg,
  248. RC2_BLOCK_SIZE);
  249. if (ret != 0) {
  250. return ret;
  251. }
  252. XMEMCPY(out, rc2->reg, RC2_BLOCK_SIZE);
  253. out += RC2_BLOCK_SIZE;
  254. in += RC2_BLOCK_SIZE;
  255. }
  256. return 0;
  257. }
  258. int wc_Rc2CbcDecrypt(Rc2* rc2, byte* out, const byte* in, word32 sz)
  259. {
  260. int ret;
  261. word32 blocks = (sz / RC2_BLOCK_SIZE);
  262. if (rc2 == NULL || out == NULL || in == NULL) {
  263. return BAD_FUNC_ARG;
  264. }
  265. if (sz == 0) {
  266. return 0;
  267. }
  268. while (blocks--) {
  269. XMEMCPY(rc2->tmp, in, RC2_BLOCK_SIZE);
  270. ret = wc_Rc2EcbDecrypt(rc2, out, (byte*)rc2->tmp, RC2_BLOCK_SIZE);
  271. if (ret != 0) {
  272. return ret;
  273. }
  274. xorbuf(out, (byte*)rc2->reg, RC2_BLOCK_SIZE);
  275. /* store iv for next call */
  276. XMEMCPY(rc2->reg, rc2->tmp, RC2_BLOCK_SIZE);
  277. out += RC2_BLOCK_SIZE;
  278. in += RC2_BLOCK_SIZE;
  279. }
  280. return 0;
  281. }
  282. #endif /* WC_RC2 */