gost89.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /**********************************************************************
  2. * gost89.c *
  3. * Copyright (c) 2005-2006 Cryptocom LTD *
  4. * This file is distributed under the same license as OpenSSL *
  5. * *
  6. * Implementation of GOST 28147-89 encryption algorithm *
  7. * No OpenSSL libraries required to compile and use *
  8. * this code *
  9. **********************************************************************/
  10. #include <string.h>
  11. #include "gost89.h"
  12. /*-
  13. Substitution blocks from RFC 4357
  14. Note: our implementation of gost 28147-89 algorithm
  15. uses S-box matrix rotated 90 degrees counterclockwise, relative to
  16. examples given in RFC.
  17. */
  18. /* Substitution blocks from test examples for GOST R 34.11-94*/
  19. gost_subst_block GostR3411_94_TestParamSet = {
  20. {0X1, 0XF, 0XD, 0X0, 0X5, 0X7, 0XA, 0X4, 0X9, 0X2, 0X3, 0XE, 0X6, 0XB,
  21. 0X8, 0XC}
  22. ,
  23. {0XD, 0XB, 0X4, 0X1, 0X3, 0XF, 0X5, 0X9, 0X0, 0XA, 0XE, 0X7, 0X6, 0X8,
  24. 0X2, 0XC}
  25. ,
  26. {0X4, 0XB, 0XA, 0X0, 0X7, 0X2, 0X1, 0XD, 0X3, 0X6, 0X8, 0X5, 0X9, 0XC,
  27. 0XF, 0XE}
  28. ,
  29. {0X6, 0XC, 0X7, 0X1, 0X5, 0XF, 0XD, 0X8, 0X4, 0XA, 0X9, 0XE, 0X0, 0X3,
  30. 0XB, 0X2}
  31. ,
  32. {0X7, 0XD, 0XA, 0X1, 0X0, 0X8, 0X9, 0XF, 0XE, 0X4, 0X6, 0XC, 0XB, 0X2,
  33. 0X5, 0X3}
  34. ,
  35. {0X5, 0X8, 0X1, 0XD, 0XA, 0X3, 0X4, 0X2, 0XE, 0XF, 0XC, 0X7, 0X6, 0X0,
  36. 0X9, 0XB}
  37. ,
  38. {0XE, 0XB, 0X4, 0XC, 0X6, 0XD, 0XF, 0XA, 0X2, 0X3, 0X8, 0X1, 0X0, 0X7,
  39. 0X5, 0X9}
  40. ,
  41. {0X4, 0XA, 0X9, 0X2, 0XD, 0X8, 0X0, 0XE, 0X6, 0XB, 0X1, 0XC, 0X7, 0XF,
  42. 0X5, 0X3}
  43. };
  44. /* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */
  45. gost_subst_block GostR3411_94_CryptoProParamSet = {
  46. {0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0,
  47. 0x2, 0xC}
  48. ,
  49. {0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2,
  50. 0x9, 0xB}
  51. ,
  52. {0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE,
  53. 0xC, 0x3}
  54. ,
  55. {0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD,
  56. 0x3, 0x5}
  57. ,
  58. {0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB,
  59. 0x9, 0x3}
  60. ,
  61. {0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA,
  62. 0x8, 0xD}
  63. ,
  64. {0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE,
  65. 0xA, 0x8}
  66. ,
  67. {0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2,
  68. 0xB, 0xF}
  69. };
  70. /* Test paramset from GOST 28147 */
  71. gost_subst_block Gost28147_TestParamSet = {
  72. {0xC, 0x6, 0x5, 0x2, 0xB, 0x0, 0x9, 0xD, 0x3, 0xE, 0x7, 0xA, 0xF, 0x4,
  73. 0x1, 0x8}
  74. ,
  75. {0x9, 0xB, 0xC, 0x0, 0x3, 0x6, 0x7, 0x5, 0x4, 0x8, 0xE, 0xF, 0x1, 0xA,
  76. 0x2, 0xD}
  77. ,
  78. {0x8, 0xF, 0x6, 0xB, 0x1, 0x9, 0xC, 0x5, 0xD, 0x3, 0x7, 0xA, 0x0, 0xE,
  79. 0x2, 0x4}
  80. ,
  81. {0x3, 0xE, 0x5, 0x9, 0x6, 0x8, 0x0, 0xD, 0xA, 0xB, 0x7, 0xC, 0x2, 0x1,
  82. 0xF, 0x4}
  83. ,
  84. {0xE, 0x9, 0xB, 0x2, 0x5, 0xF, 0x7, 0x1, 0x0, 0xD, 0xC, 0x6, 0xA, 0x4,
  85. 0x3, 0x8}
  86. ,
  87. {0xD, 0x8, 0xE, 0xC, 0x7, 0x3, 0x9, 0xA, 0x1, 0x5, 0x2, 0x4, 0x6, 0xF,
  88. 0x0, 0xB}
  89. ,
  90. {0xC, 0x9, 0xF, 0xE, 0x8, 0x1, 0x3, 0xA, 0x2, 0x7, 0x4, 0xD, 0x6, 0x0,
  91. 0xB, 0x5}
  92. ,
  93. {0x4, 0x2, 0xF, 0x5, 0x9, 0x1, 0x0, 0x8, 0xE, 0x3, 0xB, 0xC, 0xD, 0x7,
  94. 0xA, 0x6}
  95. };
  96. /* 1.2.643.2.2.31.1 */
  97. gost_subst_block Gost28147_CryptoProParamSetA = {
  98. {0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7,
  99. 0xD, 0x4}
  100. ,
  101. {0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3,
  102. 0xB, 0xE}
  103. ,
  104. {0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF,
  105. 0xE, 0x6}
  106. ,
  107. {0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7,
  108. 0xA, 0x6}
  109. ,
  110. {0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8,
  111. 0x5, 0x6}
  112. ,
  113. {0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7,
  114. 0x1, 0x9}
  115. ,
  116. {0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4,
  117. 0xD, 0x1}
  118. ,
  119. {0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0,
  120. 0xD, 0x5}
  121. };
  122. /* 1.2.643.2.2.31.2 */
  123. gost_subst_block Gost28147_CryptoProParamSetB = {
  124. {0x0, 0x4, 0xB, 0xE, 0x8, 0x3, 0x7, 0x1, 0xA, 0x2, 0x9, 0x6, 0xF, 0xD,
  125. 0x5, 0xC}
  126. ,
  127. {0x5, 0x2, 0xA, 0xB, 0x9, 0x1, 0xC, 0x3, 0x7, 0x4, 0xD, 0x0, 0x6, 0xF,
  128. 0x8, 0xE}
  129. ,
  130. {0x8, 0x3, 0x2, 0x6, 0x4, 0xD, 0xE, 0xB, 0xC, 0x1, 0x7, 0xF, 0xA, 0x0,
  131. 0x9, 0x5}
  132. ,
  133. {0x2, 0x7, 0xC, 0xF, 0x9, 0x5, 0xA, 0xB, 0x1, 0x4, 0x0, 0xD, 0x6, 0x8,
  134. 0xE, 0x3}
  135. ,
  136. {0x7, 0x5, 0x0, 0xD, 0xB, 0x6, 0x1, 0x2, 0x3, 0xA, 0xC, 0xF, 0x4, 0xE,
  137. 0x9, 0x8}
  138. ,
  139. {0xE, 0xC, 0x0, 0xA, 0x9, 0x2, 0xD, 0xB, 0x7, 0x5, 0x8, 0xF, 0x3, 0x6,
  140. 0x1, 0x4}
  141. ,
  142. {0x0, 0x1, 0x2, 0xA, 0x4, 0xD, 0x5, 0xC, 0x9, 0x7, 0x3, 0xF, 0xB, 0x8,
  143. 0x6, 0xE}
  144. ,
  145. {0x8, 0x4, 0xB, 0x1, 0x3, 0x5, 0x0, 0x9, 0x2, 0xE, 0xA, 0xC, 0xD, 0x6,
  146. 0x7, 0xF}
  147. };
  148. /* 1.2.643.2.2.31.3 */
  149. gost_subst_block Gost28147_CryptoProParamSetC = {
  150. {0x7, 0x4, 0x0, 0x5, 0xA, 0x2, 0xF, 0xE, 0xC, 0x6, 0x1, 0xB, 0xD, 0x9,
  151. 0x3, 0x8}
  152. ,
  153. {0xA, 0x9, 0x6, 0x8, 0xD, 0xE, 0x2, 0x0, 0xF, 0x3, 0x5, 0xB, 0x4, 0x1,
  154. 0xC, 0x7}
  155. ,
  156. {0xC, 0x9, 0xB, 0x1, 0x8, 0xE, 0x2, 0x4, 0x7, 0x3, 0x6, 0x5, 0xA, 0x0,
  157. 0xF, 0xD}
  158. ,
  159. {0x8, 0xD, 0xB, 0x0, 0x4, 0x5, 0x1, 0x2, 0x9, 0x3, 0xC, 0xE, 0x6, 0xF,
  160. 0xA, 0x7}
  161. ,
  162. {0x3, 0x6, 0x0, 0x1, 0x5, 0xD, 0xA, 0x8, 0xB, 0x2, 0x9, 0x7, 0xE, 0xF,
  163. 0xC, 0x4}
  164. ,
  165. {0x8, 0x2, 0x5, 0x0, 0x4, 0x9, 0xF, 0xA, 0x3, 0x7, 0xC, 0xD, 0x6, 0xE,
  166. 0x1, 0xB}
  167. ,
  168. {0x0, 0x1, 0x7, 0xD, 0xB, 0x4, 0x5, 0x2, 0x8, 0xE, 0xF, 0xC, 0x9, 0xA,
  169. 0x6, 0x3}
  170. ,
  171. {0x1, 0xB, 0xC, 0x2, 0x9, 0xD, 0x0, 0xF, 0x4, 0x5, 0x8, 0xE, 0xA, 0x7,
  172. 0x6, 0x3}
  173. };
  174. /* 1.2.643.2.2.31.4 */
  175. gost_subst_block Gost28147_CryptoProParamSetD = {
  176. {0x1, 0xA, 0x6, 0x8, 0xF, 0xB, 0x0, 0x4, 0xC, 0x3, 0x5, 0x9, 0x7, 0xD,
  177. 0x2, 0xE}
  178. ,
  179. {0x3, 0x0, 0x6, 0xF, 0x1, 0xE, 0x9, 0x2, 0xD, 0x8, 0xC, 0x4, 0xB, 0xA,
  180. 0x5, 0x7}
  181. ,
  182. {0x8, 0x0, 0xF, 0x3, 0x2, 0x5, 0xE, 0xB, 0x1, 0xA, 0x4, 0x7, 0xC, 0x9,
  183. 0xD, 0x6}
  184. ,
  185. {0x0, 0xC, 0x8, 0x9, 0xD, 0x2, 0xA, 0xB, 0x7, 0x3, 0x6, 0x5, 0x4, 0xE,
  186. 0xF, 0x1}
  187. ,
  188. {0x1, 0x5, 0xE, 0xC, 0xA, 0x7, 0x0, 0xD, 0x6, 0x2, 0xB, 0x4, 0x9, 0x3,
  189. 0xF, 0x8}
  190. ,
  191. {0x1, 0xC, 0xB, 0x0, 0xF, 0xE, 0x6, 0x5, 0xA, 0xD, 0x4, 0x8, 0x9, 0x3,
  192. 0x7, 0x2}
  193. ,
  194. {0xB, 0x6, 0x3, 0x4, 0xC, 0xF, 0xE, 0x2, 0x7, 0xD, 0x8, 0x0, 0x5, 0xA,
  195. 0x9, 0x1}
  196. ,
  197. {0xF, 0xC, 0x2, 0xA, 0x6, 0x4, 0x5, 0x0, 0x7, 0x9, 0xE, 0xD, 0x1, 0xB,
  198. 0x8, 0x3}
  199. };
  200. const byte CryptoProKeyMeshingKey[] = {
  201. 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
  202. 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
  203. 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
  204. 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
  205. };
  206. /* Initialization of gost_ctx subst blocks*/
  207. static void kboxinit(gost_ctx * c, const gost_subst_block * b)
  208. {
  209. int i;
  210. for (i = 0; i < 256; i++) {
  211. c->k87[i] = (b->k8[i >> 4] << 4 | b->k7[i & 15]) << 24;
  212. c->k65[i] = (b->k6[i >> 4] << 4 | b->k5[i & 15]) << 16;
  213. c->k43[i] = (b->k4[i >> 4] << 4 | b->k3[i & 15]) << 8;
  214. c->k21[i] = b->k2[i >> 4] << 4 | b->k1[i & 15];
  215. }
  216. }
  217. /* Part of GOST 28147 algorithm moved into separate function */
  218. static word32 f(gost_ctx * c, word32 x)
  219. {
  220. x = c->k87[x >> 24 & 255] | c->k65[x >> 16 & 255] |
  221. c->k43[x >> 8 & 255] | c->k21[x & 255];
  222. /* Rotate left 11 bits */
  223. return x << 11 | x >> (32 - 11);
  224. }
  225. /* Low-level encryption routine - encrypts one 64 bit block*/
  226. void gostcrypt(gost_ctx * c, const byte * in, byte * out)
  227. {
  228. register word32 n1, n2; /* As named in the GOST */
  229. n1 = in[0] | (in[1] << 8) | (in[2] << 16) | (in[3] << 24);
  230. n2 = in[4] | (in[5] << 8) | (in[6] << 16) | (in[7] << 24);
  231. /* Instead of swapping halves, swap names each round */
  232. n2 ^= f(c, n1 + c->k[0]);
  233. n1 ^= f(c, n2 + c->k[1]);
  234. n2 ^= f(c, n1 + c->k[2]);
  235. n1 ^= f(c, n2 + c->k[3]);
  236. n2 ^= f(c, n1 + c->k[4]);
  237. n1 ^= f(c, n2 + c->k[5]);
  238. n2 ^= f(c, n1 + c->k[6]);
  239. n1 ^= f(c, n2 + c->k[7]);
  240. n2 ^= f(c, n1 + c->k[0]);
  241. n1 ^= f(c, n2 + c->k[1]);
  242. n2 ^= f(c, n1 + c->k[2]);
  243. n1 ^= f(c, n2 + c->k[3]);
  244. n2 ^= f(c, n1 + c->k[4]);
  245. n1 ^= f(c, n2 + c->k[5]);
  246. n2 ^= f(c, n1 + c->k[6]);
  247. n1 ^= f(c, n2 + c->k[7]);
  248. n2 ^= f(c, n1 + c->k[0]);
  249. n1 ^= f(c, n2 + c->k[1]);
  250. n2 ^= f(c, n1 + c->k[2]);
  251. n1 ^= f(c, n2 + c->k[3]);
  252. n2 ^= f(c, n1 + c->k[4]);
  253. n1 ^= f(c, n2 + c->k[5]);
  254. n2 ^= f(c, n1 + c->k[6]);
  255. n1 ^= f(c, n2 + c->k[7]);
  256. n2 ^= f(c, n1 + c->k[7]);
  257. n1 ^= f(c, n2 + c->k[6]);
  258. n2 ^= f(c, n1 + c->k[5]);
  259. n1 ^= f(c, n2 + c->k[4]);
  260. n2 ^= f(c, n1 + c->k[3]);
  261. n1 ^= f(c, n2 + c->k[2]);
  262. n2 ^= f(c, n1 + c->k[1]);
  263. n1 ^= f(c, n2 + c->k[0]);
  264. out[0] = (byte) (n2 & 0xff);
  265. out[1] = (byte) ((n2 >> 8) & 0xff);
  266. out[2] = (byte) ((n2 >> 16) & 0xff);
  267. out[3] = (byte) (n2 >> 24);
  268. out[4] = (byte) (n1 & 0xff);
  269. out[5] = (byte) ((n1 >> 8) & 0xff);
  270. out[6] = (byte) ((n1 >> 16) & 0xff);
  271. out[7] = (byte) (n1 >> 24);
  272. }
  273. /* Low-level decryption routine. Decrypts one 64-bit block */
  274. void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
  275. {
  276. register word32 n1, n2; /* As named in the GOST */
  277. n1 = in[0] | (in[1] << 8) | (in[2] << 16) | (in[3] << 24);
  278. n2 = in[4] | (in[5] << 8) | (in[6] << 16) | (in[7] << 24);
  279. n2 ^= f(c, n1 + c->k[0]);
  280. n1 ^= f(c, n2 + c->k[1]);
  281. n2 ^= f(c, n1 + c->k[2]);
  282. n1 ^= f(c, n2 + c->k[3]);
  283. n2 ^= f(c, n1 + c->k[4]);
  284. n1 ^= f(c, n2 + c->k[5]);
  285. n2 ^= f(c, n1 + c->k[6]);
  286. n1 ^= f(c, n2 + c->k[7]);
  287. n2 ^= f(c, n1 + c->k[7]);
  288. n1 ^= f(c, n2 + c->k[6]);
  289. n2 ^= f(c, n1 + c->k[5]);
  290. n1 ^= f(c, n2 + c->k[4]);
  291. n2 ^= f(c, n1 + c->k[3]);
  292. n1 ^= f(c, n2 + c->k[2]);
  293. n2 ^= f(c, n1 + c->k[1]);
  294. n1 ^= f(c, n2 + c->k[0]);
  295. n2 ^= f(c, n1 + c->k[7]);
  296. n1 ^= f(c, n2 + c->k[6]);
  297. n2 ^= f(c, n1 + c->k[5]);
  298. n1 ^= f(c, n2 + c->k[4]);
  299. n2 ^= f(c, n1 + c->k[3]);
  300. n1 ^= f(c, n2 + c->k[2]);
  301. n2 ^= f(c, n1 + c->k[1]);
  302. n1 ^= f(c, n2 + c->k[0]);
  303. n2 ^= f(c, n1 + c->k[7]);
  304. n1 ^= f(c, n2 + c->k[6]);
  305. n2 ^= f(c, n1 + c->k[5]);
  306. n1 ^= f(c, n2 + c->k[4]);
  307. n2 ^= f(c, n1 + c->k[3]);
  308. n1 ^= f(c, n2 + c->k[2]);
  309. n2 ^= f(c, n1 + c->k[1]);
  310. n1 ^= f(c, n2 + c->k[0]);
  311. out[0] = (byte) (n2 & 0xff);
  312. out[1] = (byte) ((n2 >> 8) & 0xff);
  313. out[2] = (byte) ((n2 >> 16) & 0xff);
  314. out[3] = (byte) (n2 >> 24);
  315. out[4] = (byte) (n1 & 0xff);
  316. out[5] = (byte) ((n1 >> 8) & 0xff);
  317. out[6] = (byte) ((n1 >> 16) & 0xff);
  318. out[7] = (byte) (n1 >> 24);
  319. }
  320. /* Encrypts several blocks in ECB mode */
  321. void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks)
  322. {
  323. int i;
  324. for (i = 0; i < blocks; i++) {
  325. gostcrypt(c, clear, cipher);
  326. clear += 8;
  327. cipher += 8;
  328. }
  329. }
  330. /* Decrypts several blocks in ECB mode */
  331. void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks)
  332. {
  333. int i;
  334. for (i = 0; i < blocks; i++) {
  335. gostdecrypt(c, cipher, clear);
  336. clear += 8;
  337. cipher += 8;
  338. }
  339. }
  340. /* Encrypts several full blocks in CFB mode using 8byte IV */
  341. void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear,
  342. byte * cipher, int blocks)
  343. {
  344. byte cur_iv[8];
  345. byte gamma[8];
  346. int i, j;
  347. const byte *in;
  348. byte *out;
  349. memcpy(cur_iv, iv, 8);
  350. for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) {
  351. gostcrypt(ctx, cur_iv, gamma);
  352. for (j = 0; j < 8; j++) {
  353. cur_iv[j] = out[j] = in[j] ^ gamma[j];
  354. }
  355. }
  356. }
  357. /* Decrypts several full blocks in CFB mode using 8byte IV */
  358. void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher,
  359. byte * clear, int blocks)
  360. {
  361. byte cur_iv[8];
  362. byte gamma[8];
  363. int i, j;
  364. const byte *in;
  365. byte *out;
  366. memcpy(cur_iv, iv, 8);
  367. for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) {
  368. gostcrypt(ctx, cur_iv, gamma);
  369. for (j = 0; j < 8; j++) {
  370. out[j] = (cur_iv[j] = in[j]) ^ gamma[j];
  371. }
  372. }
  373. }
  374. /* Encrypts one block using specified key */
  375. void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
  376. byte * outblock)
  377. {
  378. gost_key(c, key);
  379. gostcrypt(c, inblock, outblock);
  380. }
  381. /* Set 256 bit key into context */
  382. void gost_key(gost_ctx * c, const byte * k)
  383. {
  384. int i, j;
  385. for (i = 0, j = 0; i < 8; i++, j += 4) {
  386. c->k[i] =
  387. k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | (k[j + 3] << 24);
  388. }
  389. }
  390. /* Retrieve 256-bit key from context */
  391. void gost_get_key(gost_ctx * c, byte * k)
  392. {
  393. int i, j;
  394. for (i = 0, j = 0; i < 8; i++, j += 4) {
  395. k[j] = (byte) (c->k[i] & 0xFF);
  396. k[j + 1] = (byte) ((c->k[i] >> 8) & 0xFF);
  397. k[j + 2] = (byte) ((c->k[i] >> 16) & 0xFF);
  398. k[j + 3] = (byte) ((c->k[i] >> 24) & 0xFF);
  399. }
  400. }
  401. /* Initalize context. Provides default value for subst_block */
  402. void gost_init(gost_ctx * c, const gost_subst_block * b)
  403. {
  404. if (!b) {
  405. b = &GostR3411_94_TestParamSet;
  406. }
  407. kboxinit(c, b);
  408. }
  409. /* Cleans up key from context */
  410. void gost_destroy(gost_ctx * c)
  411. {
  412. int i;
  413. for (i = 0; i < 8; i++)
  414. c->k[i] = 0;
  415. }
  416. /*
  417. * Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized
  418. * with substitution blocks and key buffer - 8-byte mac state buffer block
  419. * 8-byte block to process.
  420. */
  421. void mac_block(gost_ctx * c, byte * buffer, const byte * block)
  422. {
  423. register word32 n1, n2; /* As named in the GOST */
  424. int i;
  425. for (i = 0; i < 8; i++) {
  426. buffer[i] ^= block[i];
  427. }
  428. n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
  429. n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
  430. /* Instead of swapping halves, swap names each round */
  431. n2 ^= f(c, n1 + c->k[0]);
  432. n1 ^= f(c, n2 + c->k[1]);
  433. n2 ^= f(c, n1 + c->k[2]);
  434. n1 ^= f(c, n2 + c->k[3]);
  435. n2 ^= f(c, n1 + c->k[4]);
  436. n1 ^= f(c, n2 + c->k[5]);
  437. n2 ^= f(c, n1 + c->k[6]);
  438. n1 ^= f(c, n2 + c->k[7]);
  439. n2 ^= f(c, n1 + c->k[0]);
  440. n1 ^= f(c, n2 + c->k[1]);
  441. n2 ^= f(c, n1 + c->k[2]);
  442. n1 ^= f(c, n2 + c->k[3]);
  443. n2 ^= f(c, n1 + c->k[4]);
  444. n1 ^= f(c, n2 + c->k[5]);
  445. n2 ^= f(c, n1 + c->k[6]);
  446. n1 ^= f(c, n2 + c->k[7]);
  447. buffer[0] = (byte) (n1 & 0xff);
  448. buffer[1] = (byte) ((n1 >> 8) & 0xff);
  449. buffer[2] = (byte) ((n1 >> 16) & 0xff);
  450. buffer[3] = (byte) (n1 >> 24);
  451. buffer[4] = (byte) (n2 & 0xff);
  452. buffer[5] = (byte) ((n2 >> 8) & 0xff);
  453. buffer[6] = (byte) ((n2 >> 16) & 0xff);
  454. buffer[7] = (byte) (n2 >> 24);
  455. }
  456. /* Get mac with specified number of bits from MAC state buffer */
  457. void get_mac(byte * buffer, int nbits, byte * out)
  458. {
  459. int nbytes = nbits >> 3;
  460. int rembits = nbits & 7;
  461. int mask = rembits ? ((1 < rembits) - 1) : 0;
  462. int i;
  463. for (i = 0; i < nbytes; i++)
  464. out[i] = buffer[i];
  465. if (rembits)
  466. out[i] = buffer[i] & mask;
  467. }
  468. /*
  469. * Compute mac of specified length (in bits) from data. Context should be
  470. * initialized with key and subst blocks
  471. */
  472. int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data,
  473. unsigned int data_len, unsigned char *mac)
  474. {
  475. byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  476. byte buf2[8];
  477. unsigned int i;
  478. for (i = 0; i + 8 <= data_len; i += 8)
  479. mac_block(ctx, buffer, data + i);
  480. if (i < data_len) {
  481. memset(buf2, 0, 8);
  482. memcpy(buf2, data + i, data_len - i);
  483. mac_block(ctx, buffer, buf2);
  484. i += 8;
  485. }
  486. if (i == 8) {
  487. memset(buf2, 0, 8);
  488. mac_block(ctx, buffer, buf2);
  489. }
  490. get_mac(buffer, mac_len, mac);
  491. return 1;
  492. }
  493. /* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
  494. int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv,
  495. const unsigned char *data, unsigned int data_len,
  496. unsigned char *mac)
  497. {
  498. byte buffer[8];
  499. byte buf2[8];
  500. unsigned int i;
  501. memcpy(buffer, iv, 8);
  502. for (i = 0; i + 8 <= data_len; i += 8)
  503. mac_block(ctx, buffer, data + i);
  504. if (i < data_len) {
  505. memset(buf2, 0, 8);
  506. memcpy(buf2, data + i, data_len - i);
  507. mac_block(ctx, buffer, buf2);
  508. i += 8;
  509. }
  510. if (i == 8) {
  511. memset(buf2, 0, 8);
  512. mac_block(ctx, buffer, buf2);
  513. }
  514. get_mac(buffer, mac_len, mac);
  515. return 1;
  516. }
  517. /* Implements key meshing algorithm by modifing ctx and IV in place */
  518. void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv)
  519. {
  520. unsigned char newkey[32], newiv[8];
  521. /* Set static keymeshing key */
  522. /* "Decrypt" key with keymeshing key */
  523. gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4);
  524. /* set new key */
  525. gost_key(ctx, newkey);
  526. /* Encrypt iv with new key */
  527. gostcrypt(ctx, iv, newiv);
  528. memcpy(iv, newiv, 8);
  529. }