saferp.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. /* SAFER+ Implementation by Tom St Denis */
  12. #include "mycrypt.h"
  13. #ifdef SAFERP
  14. const struct _cipher_descriptor saferp_desc =
  15. {
  16. "safer+",
  17. 4,
  18. 16, 32, 16, 8,
  19. &saferp_setup,
  20. &saferp_ecb_encrypt,
  21. &saferp_ecb_decrypt,
  22. &saferp_test,
  23. &saferp_keysize
  24. };
  25. /* ROUND(b,i)
  26. *
  27. * This is one forward key application. Note the basic form is
  28. * key addition, substitution, key addition. The safer_ebox and safer_lbox
  29. * are the exponentiation box and logarithm boxes respectively.
  30. * The value of 'i' is the current round number which allows this
  31. * function to be unrolled massively. Most of SAFER+'s speed
  32. * comes from not having to compute indirect accesses into the
  33. * array of 16 bytes b[0..15] which is the block of data
  34. */
  35. extern const unsigned char safer_ebox[], safer_lbox[];
  36. #define ROUND(b, i) \
  37. b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \
  38. b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \
  39. b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \
  40. b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \
  41. b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \
  42. b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \
  43. b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \
  44. b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \
  45. b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \
  46. b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \
  47. b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \
  48. b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \
  49. b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \
  50. b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \
  51. b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \
  52. b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255;
  53. /* This is one inverse key application */
  54. #define iROUND(b, i) \
  55. b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \
  56. b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \
  57. b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \
  58. b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \
  59. b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \
  60. b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \
  61. b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \
  62. b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \
  63. b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \
  64. b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \
  65. b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \
  66. b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \
  67. b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \
  68. b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \
  69. b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \
  70. b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15];
  71. /* This is a forward single layer PHT transform. */
  72. #define PHT(b) \
  73. b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \
  74. b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \
  75. b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \
  76. b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \
  77. b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \
  78. b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \
  79. b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \
  80. b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255;
  81. /* This is an inverse single layer PHT transform */
  82. #define iPHT(b) \
  83. b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \
  84. b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \
  85. b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \
  86. b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \
  87. b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \
  88. b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \
  89. b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \
  90. b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \
  91. /* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */
  92. #define SHUF(b, b2) \
  93. b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \
  94. b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \
  95. b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \
  96. b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3];
  97. /* This is the inverse shuffle. It takes from b and gives to b2 */
  98. #define iSHUF(b, b2) \
  99. b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \
  100. b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \
  101. b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \
  102. b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3];
  103. /* The complete forward Linear Transform layer.
  104. * Note that alternating usage of b and b2.
  105. * Each round of LT starts in 'b' and ends in 'b2'.
  106. */
  107. #define LT(b, b2) \
  108. PHT(b); SHUF(b, b2); \
  109. PHT(b2); SHUF(b2, b); \
  110. PHT(b); SHUF(b, b2); \
  111. PHT(b2);
  112. /* This is the inverse linear transform layer. */
  113. #define iLT(b, b2) \
  114. iPHT(b); \
  115. iSHUF(b, b2); iPHT(b2); \
  116. iSHUF(b2, b); iPHT(b); \
  117. iSHUF(b, b2); iPHT(b2);
  118. #ifdef SMALL_CODE
  119. static void _round(unsigned char *b, int i, symmetric_key *skey)
  120. {
  121. ROUND(b, i);
  122. }
  123. static void _iround(unsigned char *b, int i, symmetric_key *skey)
  124. {
  125. iROUND(b, i);
  126. }
  127. static void _lt(unsigned char *b, unsigned char *b2)
  128. {
  129. LT(b, b2);
  130. }
  131. static void _ilt(unsigned char *b, unsigned char *b2)
  132. {
  133. iLT(b, b2);
  134. }
  135. #undef ROUND
  136. #define ROUND(b, i) _round(b, i, skey)
  137. #undef iROUND
  138. #define iROUND(b, i) _iround(b, i, skey)
  139. #undef LT
  140. #define LT(b, b2) _lt(b, b2)
  141. #undef iLT
  142. #define iLT(b, b2) _ilt(b, b2)
  143. #endif
  144. /* These are the 33, 128-bit bias words for the key schedule */
  145. static const unsigned char safer_bias[33][16] = {
  146. { 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100},
  147. { 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61},
  148. { 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160},
  149. { 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148},
  150. { 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143},
  151. { 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202},
  152. { 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44},
  153. { 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51},
  154. { 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56},
  155. { 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215},
  156. { 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210},
  157. { 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53},
  158. { 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244},
  159. { 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131},
  160. { 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241},
  161. { 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172},
  162. { 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239},
  163. { 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202},
  164. { 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246},
  165. { 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152},
  166. { 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236},
  167. { 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150},
  168. { 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30},
  169. { 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6},
  170. { 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104},
  171. { 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175},
  172. { 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35},
  173. { 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7},
  174. { 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207},
  175. { 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247},
  176. { 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255},
  177. { 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}};
  178. int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
  179. {
  180. unsigned x, y, z;
  181. unsigned char t[33];
  182. static const int rounds[3] = { 8, 12, 16 };
  183. _ARGCHK(key != NULL);
  184. _ARGCHK(skey != NULL);
  185. /* check arguments */
  186. if (keylen != 16 && keylen != 24 && keylen != 32) {
  187. return CRYPT_INVALID_KEYSIZE;
  188. }
  189. /* Is the number of rounds valid? Either use zero for default or
  190. * 8,12,16 rounds for 16,24,32 byte keys
  191. */
  192. if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) {
  193. return CRYPT_INVALID_ROUNDS;
  194. }
  195. /* 128 bit key version */
  196. if (keylen == 16) {
  197. /* copy key into t */
  198. for (x = y = 0; x < 16; x++) {
  199. t[x] = key[x];
  200. y ^= key[x];
  201. }
  202. t[16] = y;
  203. /* make round keys */
  204. for (x = 0; x < 16; x++) {
  205. skey->saferp.K[0][x] = t[x];
  206. }
  207. /* make the 16 other keys as a transformation of the first key */
  208. for (x = 1; x < 17; x++) {
  209. /* rotate 3 bits each */
  210. for (y = 0; y < 17; y++) {
  211. t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
  212. }
  213. /* select and add */
  214. z = x;
  215. for (y = 0; y < 16; y++) {
  216. skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
  217. if (++z == 17) { z = 0; }
  218. }
  219. }
  220. skey->saferp.rounds = 8;
  221. } else if (keylen == 24) {
  222. /* copy key into t */
  223. for (x = y = 0; x < 24; x++) {
  224. t[x] = key[x];
  225. y ^= key[x];
  226. }
  227. t[24] = y;
  228. /* make round keys */
  229. for (x = 0; x < 16; x++) {
  230. skey->saferp.K[0][x] = t[x];
  231. }
  232. for (x = 1; x < 25; x++) {
  233. /* rotate 3 bits each */
  234. for (y = 0; y < 25; y++) {
  235. t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
  236. }
  237. /* select and add */
  238. z = x;
  239. for (y = 0; y < 16; y++) {
  240. skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
  241. if (++z == 25) { z = 0; }
  242. }
  243. }
  244. skey->saferp.rounds = 12;
  245. } else {
  246. /* copy key into t */
  247. for (x = y = 0; x < 32; x++) {
  248. t[x] = key[x];
  249. y ^= key[x];
  250. }
  251. t[32] = y;
  252. /* make round keys */
  253. for (x = 0; x < 16; x++) {
  254. skey->saferp.K[0][x] = t[x];
  255. }
  256. for (x = 1; x < 33; x++) {
  257. /* rotate 3 bits each */
  258. for (y = 0; y < 33; y++) {
  259. t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
  260. }
  261. /* select and add */
  262. z = x;
  263. for (y = 0; y < 16; y++) {
  264. skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
  265. if (++z == 33) { z = 0; }
  266. }
  267. }
  268. skey->saferp.rounds = 16;
  269. }
  270. #ifdef CLEAN_STACK
  271. zeromem(t, sizeof(t));
  272. #endif
  273. return CRYPT_OK;
  274. }
  275. void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
  276. {
  277. unsigned char b[16];
  278. int x;
  279. _ARGCHK(pt != NULL);
  280. _ARGCHK(ct != NULL);
  281. _ARGCHK(skey != NULL);
  282. /* do eight rounds */
  283. for (x = 0; x < 16; x++) {
  284. b[x] = pt[x];
  285. }
  286. ROUND(b, 0); LT(b, ct);
  287. ROUND(ct, 2); LT(ct, b);
  288. ROUND(b, 4); LT(b, ct);
  289. ROUND(ct, 6); LT(ct, b);
  290. ROUND(b, 8); LT(b, ct);
  291. ROUND(ct, 10); LT(ct, b);
  292. ROUND(b, 12); LT(b, ct);
  293. ROUND(ct, 14); LT(ct, b);
  294. /* 192-bit key? */
  295. if (skey->saferp.rounds > 8) {
  296. ROUND(b, 16); LT(b, ct);
  297. ROUND(ct, 18); LT(ct, b);
  298. ROUND(b, 20); LT(b, ct);
  299. ROUND(ct, 22); LT(ct, b);
  300. }
  301. /* 256-bit key? */
  302. if (skey->saferp.rounds > 12) {
  303. ROUND(b, 24); LT(b, ct);
  304. ROUND(ct, 26); LT(ct, b);
  305. ROUND(b, 28); LT(b, ct);
  306. ROUND(ct, 30); LT(ct, b);
  307. }
  308. ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
  309. ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
  310. ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
  311. ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
  312. ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
  313. ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
  314. ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
  315. ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
  316. ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
  317. ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
  318. ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
  319. ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
  320. ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
  321. ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
  322. ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
  323. ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
  324. #ifdef CLEAN_STACK
  325. zeromem(b, sizeof(b));
  326. #endif
  327. }
  328. void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
  329. {
  330. unsigned char b[16];
  331. int x;
  332. _ARGCHK(pt != NULL);
  333. _ARGCHK(ct != NULL);
  334. _ARGCHK(skey != NULL);
  335. /* do eight rounds */
  336. b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
  337. b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
  338. b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
  339. b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
  340. b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
  341. b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
  342. b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
  343. b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
  344. b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
  345. b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
  346. b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
  347. b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
  348. b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
  349. b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
  350. b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
  351. b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
  352. /* 256-bit key? */
  353. if (skey->saferp.rounds > 12) {
  354. iLT(b, pt); iROUND(pt, 30);
  355. iLT(pt, b); iROUND(b, 28);
  356. iLT(b, pt); iROUND(pt, 26);
  357. iLT(pt, b); iROUND(b, 24);
  358. }
  359. /* 192-bit key? */
  360. if (skey->saferp.rounds > 8) {
  361. iLT(b, pt); iROUND(pt, 22);
  362. iLT(pt, b); iROUND(b, 20);
  363. iLT(b, pt); iROUND(pt, 18);
  364. iLT(pt, b); iROUND(b, 16);
  365. }
  366. iLT(b, pt); iROUND(pt, 14);
  367. iLT(pt, b); iROUND(b, 12);
  368. iLT(b, pt); iROUND(pt,10);
  369. iLT(pt, b); iROUND(b, 8);
  370. iLT(b, pt); iROUND(pt,6);
  371. iLT(pt, b); iROUND(b, 4);
  372. iLT(b, pt); iROUND(pt,2);
  373. iLT(pt, b); iROUND(b, 0);
  374. for (x = 0; x < 16; x++) {
  375. pt[x] = b[x];
  376. }
  377. #ifdef CLEAN_STACK
  378. zeromem(b, sizeof(b));
  379. #endif
  380. }
  381. int saferp_test(void)
  382. {
  383. #ifndef LTC_TEST
  384. return CRYPT_NOP;
  385. #else
  386. static const struct {
  387. int keylen;
  388. unsigned char key[32], pt[16], ct[16];
  389. } tests[] = {
  390. {
  391. 16,
  392. { 41, 35, 190, 132, 225, 108, 214, 174,
  393. 82, 144, 73, 241, 241, 187, 233, 235 },
  394. { 179, 166, 219, 60, 135, 12, 62, 153,
  395. 36, 94, 13, 28, 6, 183, 71, 222 },
  396. { 224, 31, 182, 10, 12, 255, 84, 70,
  397. 127, 13, 89, 249, 9, 57, 165, 220 }
  398. }, {
  399. 24,
  400. { 72, 211, 143, 117, 230, 217, 29, 42,
  401. 229, 192, 247, 43, 120, 129, 135, 68,
  402. 14, 95, 80, 0, 212, 97, 141, 190 },
  403. { 123, 5, 21, 7, 59, 51, 130, 31,
  404. 24, 112, 146, 218, 100, 84, 206, 177 },
  405. { 92, 136, 4, 63, 57, 95, 100, 0,
  406. 150, 130, 130, 16, 193, 111, 219, 133 }
  407. }, {
  408. 32,
  409. { 243, 168, 141, 254, 190, 242, 235, 113,
  410. 255, 160, 208, 59, 117, 6, 140, 126,
  411. 135, 120, 115, 77, 208, 190, 130, 190,
  412. 219, 194, 70, 65, 43, 140, 250, 48 },
  413. { 127, 112, 240, 167, 84, 134, 50, 149,
  414. 170, 91, 104, 19, 11, 230, 252, 245 },
  415. { 88, 11, 25, 36, 172, 229, 202, 213,
  416. 170, 65, 105, 153, 220, 104, 153, 138 }
  417. }
  418. };
  419. unsigned char tmp[2][16];
  420. symmetric_key skey;
  421. int err, i, y;
  422. for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
  423. if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) {
  424. return err;
  425. }
  426. saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey);
  427. saferp_ecb_decrypt(tmp[0], tmp[1], &skey);
  428. /* compare */
  429. if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
  430. return CRYPT_FAIL_TESTVECTOR;
  431. }
  432. /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
  433. for (y = 0; y < 16; y++) tmp[0][y] = 0;
  434. for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey);
  435. for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey);
  436. for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
  437. }
  438. return CRYPT_OK;
  439. #endif
  440. }
  441. int saferp_keysize(int *desired_keysize)
  442. {
  443. _ARGCHK(desired_keysize != NULL);
  444. if (*desired_keysize < 16)
  445. return CRYPT_INVALID_KEYSIZE;
  446. if (*desired_keysize < 24) {
  447. *desired_keysize = 16;
  448. } else if (*desired_keysize < 32) {
  449. *desired_keysize = 24;
  450. } else {
  451. *desired_keysize = 32;
  452. }
  453. return CRYPT_OK;
  454. }
  455. #endif