2
0

gost_crypt.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. /**********************************************************************
  2. * gost_crypt.c *
  3. * Copyright (c) 2005-2006 Cryptocom LTD *
  4. * This file is distributed under the same license as OpenSSL *
  5. * *
  6. * OpenSSL interface to GOST 28147-89 cipher functions *
  7. * Requires OpenSSL 0.9.9 for compilation *
  8. **********************************************************************/
  9. #include <string.h>
  10. #include "gost89.h"
  11. #include <openssl/rand.h>
  12. #include "e_gost_err.h"
  13. #include "gost_lcl.h"
  14. static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  15. const unsigned char *iv, int enc);
  16. static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  17. const unsigned char *iv, int enc);
  18. /* Handles block of data in CFB mode */
  19. static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
  20. const unsigned char *in, size_t inl);
  21. /* Handles block of data in CNT mode */
  22. static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
  23. const unsigned char *in, size_t inl);
  24. /* Cleanup function */
  25. static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
  26. /* set/get cipher parameters */
  27. static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
  28. static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params);
  29. /* Control function */
  30. static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr);
  31. EVP_CIPHER cipher_gost =
  32. {
  33. NID_id_Gost28147_89,
  34. 1,/*block_size*/
  35. 32,/*key_size*/
  36. 8,/*iv_len */
  37. EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
  38. EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
  39. gost_cipher_init,
  40. gost_cipher_do_cfb,
  41. gost_cipher_cleanup,
  42. sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
  43. gost89_set_asn1_parameters,
  44. gost89_get_asn1_parameters,
  45. gost_cipher_ctl,
  46. NULL,
  47. };
  48. EVP_CIPHER cipher_gost_cpacnt =
  49. {
  50. NID_gost89_cnt,
  51. 1,/*block_size*/
  52. 32,/*key_size*/
  53. 8,/*iv_len */
  54. EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
  55. EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
  56. gost_cipher_init_cpa,
  57. gost_cipher_do_cnt,
  58. gost_cipher_cleanup,
  59. sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
  60. gost89_set_asn1_parameters,
  61. gost89_get_asn1_parameters,
  62. gost_cipher_ctl,
  63. NULL,
  64. };
  65. /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
  66. /* Init functions which set specific parameters */
  67. static int gost_imit_init_cpa(EVP_MD_CTX *ctx);
  68. /* process block of data */
  69. static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count);
  70. /* Return computed value */
  71. static int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md);
  72. /* Copies context */
  73. static int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
  74. static int gost_imit_cleanup(EVP_MD_CTX *ctx);
  75. /* Control function, knows how to set MAC key.*/
  76. static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr);
  77. EVP_MD imit_gost_cpa =
  78. {
  79. NID_id_Gost28147_89_MAC,
  80. NID_undef,
  81. 4,
  82. 0,
  83. gost_imit_init_cpa,
  84. gost_imit_update,
  85. gost_imit_final,
  86. gost_imit_copy,
  87. gost_imit_cleanup,
  88. NULL,
  89. NULL,
  90. {0,0,0,0,0},
  91. 8,
  92. sizeof(struct ossl_gost_imit_ctx),
  93. gost_imit_ctrl
  94. };
  95. /*
  96. * Correspondence between gost parameter OIDs and substitution blocks
  97. * NID field is filed by register_gost_NID function in engine.c
  98. * upon engine initialization
  99. */
  100. struct gost_cipher_info gost_cipher_list[]=
  101. {
  102. /* NID */ /* Subst block */ /* Key meshing*/
  103. /*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
  104. {NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
  105. {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
  106. {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
  107. {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
  108. {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
  109. {NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,1},
  110. {NID_undef,NULL,0}
  111. };
  112. /* get encryption parameters from crypto network settings
  113. FIXME For now we use environment var CRYPT_PARAMS as place to
  114. store these settings. Actually, it is better to use engine control command, read from configuration file to set them */
  115. const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
  116. {
  117. int nid;
  118. struct gost_cipher_info *param;
  119. if (!obj)
  120. {
  121. const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
  122. if (!params || !strlen(params))
  123. return &gost_cipher_list[1];
  124. nid = OBJ_txt2nid(params);
  125. if (nid == NID_undef)
  126. {
  127. GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
  128. GOST_R_INVALID_CIPHER_PARAM_OID);
  129. return NULL;
  130. }
  131. }
  132. else
  133. {
  134. nid= OBJ_obj2nid(obj);
  135. }
  136. for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid;
  137. param++);
  138. if (!param->sblock)
  139. {
  140. GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
  141. return NULL;
  142. }
  143. return param;
  144. }
  145. /* Sets cipher param from paramset NID. */
  146. static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid)
  147. {
  148. const struct gost_cipher_info *param;
  149. param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
  150. if (!param) return 0;
  151. c->paramNID = param->nid;
  152. c->key_meshing=param->key_meshing;
  153. c->count=0;
  154. gost_init(&(c->cctx), param->sblock);
  155. return 1;
  156. }
  157. /* Initializes EVP_CIPHER_CTX by paramset NID */
  158. static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  159. const unsigned char *iv, int enc, int paramNID,int mode)
  160. {
  161. struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
  162. if (ctx->app_data == NULL)
  163. {
  164. if (!gost_cipher_set_param(c,paramNID)) return 0;
  165. ctx->app_data = ctx->cipher_data;
  166. }
  167. if (key) gost_key(&(c->cctx),key);
  168. if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
  169. memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
  170. return 1;
  171. }
  172. static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  173. const unsigned char *iv, int enc)
  174. {
  175. struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
  176. gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
  177. c->key_meshing=1;
  178. c->count=0;
  179. if(key) gost_key(&(c->cctx),key);
  180. if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
  181. memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
  182. return 1;
  183. }
  184. /* Initializes EVP_CIPHER_CTX with default values */
  185. int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
  186. const unsigned char *iv, int enc)
  187. {
  188. return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
  189. }
  190. /* Wrapper around gostcrypt function from gost89.c which perform
  191. * key meshing when nesseccary
  192. */
  193. static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
  194. {
  195. struct ossl_gost_cipher_ctx *c = ctx;
  196. if (c->count&&c->key_meshing && c->count%1024==0)
  197. {
  198. cryptopro_key_meshing(&(c->cctx),iv);
  199. }
  200. gostcrypt(&(c->cctx),iv,buf);
  201. c->count+=8;
  202. }
  203. static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
  204. {
  205. struct ossl_gost_cipher_ctx *c = ctx;
  206. word32 g,go;
  207. unsigned char buf1[8];
  208. if (c->count && c->key_meshing && c->count %1024 ==0)
  209. {
  210. cryptopro_key_meshing(&(c->cctx),iv);
  211. }
  212. if (c->count==0)
  213. {
  214. gostcrypt(&(c->cctx),iv,buf1);
  215. }
  216. else
  217. {
  218. memcpy(buf1,iv,8);
  219. }
  220. g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
  221. g += 0x01010101;
  222. buf1[0]=(unsigned char)(g&0xff);
  223. buf1[1]=(unsigned char)((g>>8)&0xff);
  224. buf1[2]=(unsigned char)((g>>16)&0xff);
  225. buf1[3]=(unsigned char)((g>>24)&0xff);
  226. g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|(buf1[7]<<24);
  227. go = g;
  228. g += 0x01010104;
  229. if (go > g) /* overflow*/
  230. g++;
  231. buf1[4]=(unsigned char)(g&0xff);
  232. buf1[5]=(unsigned char)((g>>8)&0xff);
  233. buf1[6]=(unsigned char)((g>>16)&0xff);
  234. buf1[7]=(unsigned char)((g>>24)&0xff);
  235. memcpy(iv,buf1,8);
  236. gostcrypt(&(c->cctx),buf1,buf);
  237. c->count +=8;
  238. }
  239. /* GOST encryption in CFB mode */
  240. int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
  241. const unsigned char *in, size_t inl)
  242. {
  243. const unsigned char *in_ptr=in;
  244. unsigned char *out_ptr=out;
  245. size_t i=0;
  246. size_t j=0;
  247. /* process partial block if any */
  248. if (ctx->num)
  249. {
  250. for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
  251. {
  252. if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
  253. *out_ptr=ctx->buf[j]^(*in_ptr);
  254. if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
  255. }
  256. if (j==8)
  257. {
  258. memcpy(ctx->iv,ctx->buf+8,8);
  259. ctx->num=0;
  260. }
  261. else
  262. {
  263. ctx->num=j;
  264. return 1;
  265. }
  266. }
  267. for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
  268. {
  269. /*block cipher current iv */
  270. gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
  271. /*xor next block of input text with it and output it*/
  272. /*output this block */
  273. if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
  274. for (j=0;j<8;j++)
  275. {
  276. out_ptr[j]=ctx->buf[j]^in_ptr[j];
  277. }
  278. /* Encrypt */
  279. /* Next iv is next block of cipher text*/
  280. if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
  281. }
  282. /* Process rest of buffer */
  283. if (i<inl)
  284. {
  285. gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
  286. if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
  287. for (j=0;i<inl;j++,i++)
  288. {
  289. out_ptr[j]=ctx->buf[j]^in_ptr[j];
  290. }
  291. ctx->num = j;
  292. if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
  293. }
  294. else
  295. {
  296. ctx->num = 0;
  297. }
  298. return 1;
  299. }
  300. static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
  301. const unsigned char *in, size_t inl)
  302. {
  303. const unsigned char *in_ptr=in;
  304. unsigned char *out_ptr=out;
  305. size_t i=0;
  306. size_t j;
  307. /* process partial block if any */
  308. if (ctx->num)
  309. {
  310. for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
  311. {
  312. *out_ptr=ctx->buf[j]^(*in_ptr);
  313. }
  314. if (j==8)
  315. {
  316. ctx->num=0;
  317. }
  318. else
  319. {
  320. ctx->num=j;
  321. return 1;
  322. }
  323. }
  324. for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
  325. {
  326. /*block cipher current iv */
  327. /* Encrypt */
  328. gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
  329. /*xor next block of input text with it and output it*/
  330. /*output this block */
  331. for (j=0;j<8;j++)
  332. {
  333. out_ptr[j]=ctx->buf[j]^in_ptr[j];
  334. }
  335. }
  336. /* Process rest of buffer */
  337. if (i<inl)
  338. {
  339. gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
  340. for (j=0;i<inl;j++,i++)
  341. {
  342. out_ptr[j]=ctx->buf[j]^in_ptr[j];
  343. }
  344. ctx->num = j;
  345. }
  346. else
  347. {
  348. ctx->num = 0;
  349. }
  350. return 1;
  351. }
  352. /* Cleaning up of EVP_CIPHER_CTX */
  353. int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx)
  354. {
  355. gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx);
  356. ctx->app_data = NULL;
  357. return 1;
  358. }
  359. /* Control function for gost cipher */
  360. int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
  361. {
  362. switch (type)
  363. {
  364. case EVP_CTRL_RAND_KEY:
  365. {
  366. if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
  367. {
  368. GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
  369. return -1;
  370. }
  371. break;
  372. }
  373. case EVP_CTRL_PBE_PRF_NID:
  374. if (ptr) {
  375. *((int *)ptr)= NID_id_HMACGostR3411_94;
  376. return 1;
  377. } else {
  378. return 0;
  379. }
  380. default:
  381. GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
  382. return -1;
  383. }
  384. return 1;
  385. }
  386. /* Set cipher parameters from ASN1 structure */
  387. int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
  388. {
  389. int len=0;
  390. unsigned char *buf=NULL;
  391. unsigned char *p=NULL;
  392. struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
  393. GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
  394. ASN1_OCTET_STRING *os = NULL;
  395. if (!gcp)
  396. {
  397. GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
  398. return 0;
  399. }
  400. if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
  401. {
  402. GOST_CIPHER_PARAMS_free(gcp);
  403. GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
  404. return 0;
  405. }
  406. ASN1_OBJECT_free(gcp->enc_param_set);
  407. gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
  408. len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
  409. p = buf = (unsigned char*)OPENSSL_malloc(len);
  410. if (!buf)
  411. {
  412. GOST_CIPHER_PARAMS_free(gcp);
  413. GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
  414. return 0;
  415. }
  416. i2d_GOST_CIPHER_PARAMS(gcp, &p);
  417. GOST_CIPHER_PARAMS_free(gcp);
  418. os = ASN1_OCTET_STRING_new();
  419. if(!os || !ASN1_OCTET_STRING_set(os, buf, len))
  420. {
  421. OPENSSL_free(buf);
  422. GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
  423. return 0;
  424. }
  425. OPENSSL_free(buf);
  426. ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
  427. return 1;
  428. }
  429. /* Store parameters into ASN1 structure */
  430. int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
  431. {
  432. int ret = -1;
  433. int len;
  434. GOST_CIPHER_PARAMS *gcp = NULL;
  435. unsigned char *p = params->value.sequence->data;
  436. struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
  437. if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
  438. {
  439. return ret;
  440. }
  441. gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
  442. params->value.sequence->length);
  443. len = gcp->iv->length;
  444. if (len != ctx->cipher->iv_len)
  445. {
  446. GOST_CIPHER_PARAMS_free(gcp);
  447. GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
  448. GOST_R_INVALID_IV_LENGTH);
  449. return -1;
  450. }
  451. if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
  452. {
  453. GOST_CIPHER_PARAMS_free(gcp);
  454. return -1;
  455. }
  456. memcpy(ctx->oiv, gcp->iv->data, len);
  457. GOST_CIPHER_PARAMS_free(gcp);
  458. return 1;
  459. }
  460. int gost_imit_init_cpa(EVP_MD_CTX *ctx)
  461. {
  462. struct ossl_gost_imit_ctx *c = ctx->md_data;
  463. memset(c->buffer,0,16);
  464. c->count = 0;
  465. c->bytes_left=0;
  466. c->key_meshing=1;
  467. gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
  468. return 1;
  469. }
  470. static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data)
  471. {
  472. unsigned char buffer[8];
  473. /* We are using local buffer for iv because CryptoPro doesn't
  474. * interpret internal state of MAC algorithm as iv during keymeshing
  475. * (but does initialize internal state from iv in key transport
  476. */
  477. if (c->key_meshing&& c->count && c->count %1024 ==0)
  478. {
  479. cryptopro_key_meshing(&(c->cctx),buffer);
  480. }
  481. mac_block(&(c->cctx),c->buffer,data);
  482. c->count +=8;
  483. }
  484. int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
  485. {
  486. struct ossl_gost_imit_ctx *c = ctx->md_data;
  487. const unsigned char *p = data;
  488. size_t bytes = count,i;
  489. if (!(c->key_set)) {
  490. GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
  491. return 0;
  492. }
  493. if (c->bytes_left)
  494. {
  495. for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
  496. {
  497. c->partial_block[i]=*p;
  498. }
  499. if (i==8)
  500. {
  501. mac_block_mesh(c,c->partial_block);
  502. }
  503. else
  504. {
  505. c->bytes_left = i;
  506. return 1;
  507. }
  508. }
  509. while (bytes>8)
  510. {
  511. mac_block_mesh(c,p);
  512. p+=8;
  513. bytes-=8;
  514. }
  515. if (bytes>0)
  516. {
  517. memcpy(c->partial_block,p,bytes);
  518. }
  519. c->bytes_left=bytes;
  520. return 1;
  521. }
  522. int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
  523. {
  524. struct ossl_gost_imit_ctx *c = ctx->md_data;
  525. if (!c->key_set) {
  526. GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
  527. return 0;
  528. }
  529. if (c->bytes_left)
  530. {
  531. int i;
  532. for (i=c->bytes_left;i<8;i++)
  533. {
  534. c->partial_block[i]=0;
  535. }
  536. mac_block_mesh(c,c->partial_block);
  537. }
  538. get_mac(c->buffer,32,md);
  539. return 1;
  540. }
  541. int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr)
  542. {
  543. switch (type)
  544. {
  545. case EVP_MD_CTRL_KEY_LEN:
  546. *((unsigned int*)(ptr)) = 32;
  547. return 1;
  548. case EVP_MD_CTRL_SET_KEY:
  549. {
  550. if (arg!=32) {
  551. GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
  552. return 0;
  553. }
  554. gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ;
  555. ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
  556. return 1;
  557. }
  558. default:
  559. return 0;
  560. }
  561. }
  562. int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
  563. {
  564. memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
  565. return 1;
  566. }
  567. /* Clean up imit ctx */
  568. int gost_imit_cleanup(EVP_MD_CTX *ctx)
  569. {
  570. memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
  571. return 1;
  572. }