gost_crypt.c 15 KB

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