summaryrefslogtreecommitdiffstats
path: root/engines/ccgost/gost_crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'engines/ccgost/gost_crypt.c')
-rw-r--r--engines/ccgost/gost_crypt.c833
1 files changed, 454 insertions, 379 deletions
diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c
index 9b3803d8fd..5ea02d1063 100644
--- a/engines/ccgost/gost_crypt.c
+++ b/engines/ccgost/gost_crypt.c
@@ -1,32 +1,31 @@
/**********************************************************************
-* gost_crypt.c *
-* Copyright (c) 2005-2006 Cryptocom LTD *
-* This file is distributed under the same license as OpenSSL *
-* *
-* OpenSSL interface to GOST 28147-89 cipher functions *
-* Requires OpenSSL 0.9.9 for compilation *
-**********************************************************************/
+ * gost_crypt.c *
+ * Copyright (c) 2005-2006 Cryptocom LTD *
+ * This file is distributed under the same license as OpenSSL *
+ * *
+ * OpenSSL interface to GOST 28147-89 cipher functions *
+ * Requires OpenSSL 0.9.9 for compilation *
+ **********************************************************************/
#include <string.h>
-#include "crypt.h"
#include "gost89.h"
#include <openssl/rand.h>
#include "e_gost_err.h"
-#include "gost_asn1.h"
+#include "gost_lcl.h"
static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
+ const unsigned char *iv, int enc);
#ifdef USE_SSL
/* Specialized init functions which set specific parameters */
static int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
+ const unsigned char *iv, int enc);
static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
+ const unsigned char *iv, int enc);
#endif
/* Handles block of data in CFB mode */
static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl);
+ const unsigned char *in, unsigned int inl);
/* Handles block of data in CNT mode */
static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl);
+ const unsigned char *in, unsigned int inl);
/* Cleanup function */
static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
/* set/get cipher parameters */
@@ -37,57 +36,57 @@ static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr);
EVP_CIPHER cipher_gost =
{
- NID_id_Gost28147_89,
- 1,/*block_size*/
- 32,/*key_size*/
- 8,/*iv_len - синхропосылка*/
- EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
- EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
- gost_cipher_init,
- gost_cipher_do_cfb,
- gost_cipher_cleanup,
- sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
- gost89_set_asn1_parameters,
- gost89_get_asn1_parameters,
- gost_cipher_ctl,
- NULL,
+ NID_id_Gost28147_89,
+ 1,/*block_size*/
+ 32,/*key_size*/
+ 8,/*iv_len - синхропосылка*/
+ EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
+ EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
+ gost_cipher_init,
+ gost_cipher_do_cfb,
+ gost_cipher_cleanup,
+ sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */
+ gost89_set_asn1_parameters,
+ gost89_get_asn1_parameters,
+ gost_cipher_ctl,
+ NULL,
};
#ifdef USE_SSL
static EVP_CIPHER cipher_gost_vizircfb =
{
- NID_undef,
- 1,/*block_size*/
- 32,/*key_size*/
- 8,/*iv_len - синхропосылка*/
- EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
- EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
- gost_cipher_init_vizir,
- gost_cipher_do_cfb,
- gost_cipher_cleanup,
- sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
- gost89_set_asn1_parameters,
- gost89_get_asn1_parameters,
- gost_cipher_ctl,
- NULL,
+ NID_undef,
+ 1,/*block_size*/
+ 32,/*key_size*/
+ 8,/*iv_len - синхропосылка*/
+ EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING |
+ EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
+ gost_cipher_init_vizir,
+ gost_cipher_do_cfb,
+ gost_cipher_cleanup,
+ sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
+ gost89_set_asn1_parameters,
+ gost89_get_asn1_parameters,
+ gost_cipher_ctl,
+ NULL,
};
static EVP_CIPHER cipher_gost_cpacnt =
{
- NID_undef,
- 1,/*block_size*/
- 32,/*key_size*/
- 8,/*iv_len - синхропосылка*/
- EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
- EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
- gost_cipher_init_cpa,
- gost_cipher_do_cnt,
- gost_cipher_cleanup,
- sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
- gost89_set_asn1_parameters,
- gost89_get_asn1_parameters,
- gost_cipher_ctl,
- NULL,
+ NID_undef,
+ 1,/*block_size*/
+ 32,/*key_size*/
+ 8,/*iv_len - синхропосылка*/
+ EVP_CIPH_OFB_MODE| EVP_CIPH_NO_PADDING |
+ EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT,
+ gost_cipher_init_cpa,
+ gost_cipher_do_cnt,
+ gost_cipher_cleanup,
+ sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */
+ gost89_set_asn1_parameters,
+ gost89_get_asn1_parameters,
+ gost_cipher_ctl,
+ NULL,
};
/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
/* Init functions which set specific parameters */
@@ -143,130 +142,154 @@ EVP_MD imit_gost_cpa =
#endif
/*
-* Correspondence between gost parameter OIDs and substitution blocks
-* NID field is filed by register_gost_NID function in engine.c
-* upon engine initialization
-*/
+ * Correspondence between gost parameter OIDs and substitution blocks
+ * NID field is filed by register_gost_NID function in engine.c
+ * upon engine initialization
+ */
-struct gost_cipher_info gost_cipher_list[]={
+struct gost_cipher_info gost_cipher_list[]=
+ {
/* NID */ /* Subst block */ /* Key meshing*/
/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
-{NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
-{NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
-{NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
-{NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
-{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
-{NID_undef,NULL,0}
-};
+ {NID_id_Gost28147_89_cc,&GostR3411_94_CryptoProParamSet,0},
+ {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
+ {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1},
+ {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
+ {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
+ {NID_undef,NULL,0}
+ };
/* get encryption parameters from crypto network settings
-FIXME For now we use environment var CRYPT_PARAMS as place to
-store these settings. Actually, it is better to use engine control command, read from configuration file to set them */
-const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj) {
-int nid;
-struct gost_cipher_info *param;
-if (!obj) {
- const char * params = getenv("CRYPT_PARAMS");
- if (!params || !strlen(params))
- return &gost_cipher_list[0];
-
- nid = OBJ_txt2nid(params);
- if (nid == NID_undef) {
- GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
+ FIXME For now we use environment var CRYPT_PARAMS as place to
+ store these settings. Actually, it is better to use engine control command, read from configuration file to set them */
+const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
+ {
+ int nid;
+ struct gost_cipher_info *param;
+ if (!obj)
+ {
+ const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
+ if (!params || !strlen(params))
+ return &gost_cipher_list[0];
+
+ nid = OBJ_txt2nid(params);
+ if (nid == NID_undef)
+ {
+ GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
GOST_R_INVALID_CIPHER_PARAM_OID);
+ return NULL;
+ }
+ }
+ else
+ {
+ nid= OBJ_obj2nid(obj);
+ }
+ for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid;
+ param++);
+ if (!param->sblock)
+ {
+ GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
return NULL;
- }
-} else {
- nid= OBJ_obj2nid(obj);
-}
-for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid;
- param++);
-if (!param->sblock) {
- GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
- return NULL;
-
-}
-return param;
-
-}
+ }
+ return param;
+ }
+
/* Sets cipher param from paramset NID. */
-int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid) {
-const struct gost_cipher_info *param;
-param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
-if (!param) return 0;
+int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid)
+ {
+ const struct gost_cipher_info *param;
+ param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid)));
+ if (!param) return 0;
-c->paramNID = param->nid;
-c->key_meshing=param->key_meshing;
-c->count=0;
-gost_init(&(c->cctx), param->sblock);
-return 1;
-}
+ c->paramNID = param->nid;
+ c->key_meshing=param->key_meshing;
+ c->count=0;
+ gost_init(&(c->cctx), param->sblock);
+ return 1;
+ }
+
/* Initializes EVP_CIPHER_CTX by paramset NID */
static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc, int paramNID,int mode) {
-struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
-if (!gost_cipher_set_param(c,paramNID)) return 0;
-if (key) gost_key(&(c->cctx),key);
-if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-return 1;
-}
+ const unsigned char *iv, int enc, int paramNID,int mode)
+ {
+ struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+ if (ctx->app_data == NULL)
+ {
+ if (!gost_cipher_set_param(c,paramNID)) return 0;
+ ctx->app_data = ctx->cipher_data;
+ }
+ if (key) gost_key(&(c->cctx),key);
+ if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+ return 1;
+ }
/* Initializes EVP_CIPHER_CTX with fixed cryptopro A paramset */
int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc) {
-struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
-gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
-c->key_meshing=1;
-c->count=0;
-gost_key(&(c->cctx),key);
-if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-return 1;
-}
+ const unsigned char *iv, int enc)
+ {
+ struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+ gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
+ c->key_meshing=1;
+ c->count=0;
+ gost_key(&(c->cctx),key);
+ if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+ return 1;
+ }
+
/* Initializes EVP_CIPHER_CTX with fixed vizir paramset */
int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc) {
-struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
-gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
-c->key_meshing=0;
-c->count=0;
-gost_key(&(c->cctx),key);
-
-if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-return 1;
-}
+ const unsigned char *iv, int enc)
+ {
+ struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+ gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
+ c->key_meshing=0;
+ c->count=0;
+ gost_key(&(c->cctx),key);
+
+ if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+ return 1;
+ }
/* Initializes EVP_CIPHER_CTX with default values */
int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc) {
-return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
-}
+ const unsigned char *iv, int enc)
+ {
+ return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
+ }
/* Wrapper around gostcrypt function from gost89.c which perform
-* key meshing when nesseccary
-*/
-static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) {
+ * key meshing when nesseccary
+ */
+static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
+ {
struct ossl_gost_cipher_ctx *c = ctx;
- if (c->count&&c->key_meshing && c->count%1024==0) {
+ if (c->count&&c->key_meshing && c->count%1024==0)
+ {
cryptopro_key_meshing(&(c->cctx),iv);
- }
+ }
gostcrypt(&(c->cctx),iv,buf);
c->count+=8;
-}
-
-static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) {
-struct ossl_gost_cipher_ctx *c = ctx;
-word32 g,go;
-unsigned char buf1[8];
-if (c->count && c->key_meshing && c->count %1024 ==0) {
- cryptopro_key_meshing(&(c->cctx),iv);
-}
-if (c->count==0) {
-gostcrypt(&(c->cctx),iv,buf1);
-} else {
- memcpy(buf1,iv,8);
-}
+ }
+
+static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
+ {
+ struct ossl_gost_cipher_ctx *c = ctx;
+ word32 g,go;
+ unsigned char buf1[8];
+ if (c->count && c->key_meshing && c->count %1024 ==0)
+ {
+ cryptopro_key_meshing(&(c->cctx),iv);
+ }
+ if (c->count==0)
+ {
+ gostcrypt(&(c->cctx),iv,buf1);
+ }
+ else
+ {
+ memcpy(buf1,iv,8);
+ }
g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
g += 0x01010101;
buf1[0]=g&0xff; buf1[1]=(g>>8)&0xff; buf1[2]=(g>>16)&0xff; buf1[3]=(g>>24)&0xff;
@@ -278,302 +301,354 @@ gostcrypt(&(c->cctx),iv,buf1);
buf1[4]=g&0xff; buf1[5]=(g>>8)&0xff; buf1[6]=(g>>16)&0xff; buf1[7]=(g>>24)&0xff;
memcpy(iv,buf1,8);
gostcrypt(&(c->cctx),buf1,buf);
-c->count +=8;
-}
+ c->count +=8;
+ }
/* GOST encryption in CFB mode */
int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl) {
-const unsigned char *in_ptr=in;
-unsigned char *out_ptr=out;
-int i=0;
-int j;
-/* process partial block if any */
-if (ctx->num)
-{
- for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
+ const unsigned char *in, unsigned int inl)
{
- if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
- *out_ptr=ctx->buf[j]^(*in_ptr);
- if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
- }
- if (j==8) {
- memcpy(ctx->iv,ctx->buf+8,8);
- ctx->num=0;
- } else {
- ctx->num=j;
- return 1;
- }
-}
-
-for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) {
- /*block cipher current iv */
- gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
- /*xor next block of input text with it and output it*/
- /*output this block */
- if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
- for (j=0;j<8;j++) {
+ const unsigned char *in_ptr=in;
+ unsigned char *out_ptr=out;
+ int i=0;
+ int j=0;
+/* process partial block if any */
+ if (ctx->num)
+ {
+ for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
+ {
+ if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
+ *out_ptr=ctx->buf[j]^(*in_ptr);
+ if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
+ }
+ if (j==8)
+ {
+ memcpy(ctx->iv,ctx->buf+8,8);
+ ctx->num=0;
+ }
+ else
+ {
+ ctx->num=j;
+ return 1;
+ }
+ }
+
+ for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
+ {
+ /*block cipher current iv */
+ gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
+ /*xor next block of input text with it and output it*/
+ /*output this block */
+ if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
+ for (j=0;j<8;j++)
+ {
out_ptr[j]=ctx->buf[j]^in_ptr[j];
- }
- /* Encrypt */
- /* Next iv is next block of cipher text*/
- if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
-}
+ }
+ /* Encrypt */
+ /* Next iv is next block of cipher text*/
+ if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
+ }
/* Process rest of buffer */
-if (i<inl) {
- gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
- if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
- for (j=0;i<inl;j++,i++) {
+ if (i<inl)
+ {
+ gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
+ if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
+ for (j=0;i<inl;j++,i++)
+ {
out_ptr[j]=ctx->buf[j]^in_ptr[j];
- }
- ctx->num = j;
- if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
-} else {
- ctx->num = 0;
-}
-return 1;
-}
+ }
+ ctx->num = j;
+ if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
+ }
+ else
+ {
+ ctx->num = 0;
+ }
+ return 1;
+ }
+
int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl) {
-const unsigned char *in_ptr=in;
-unsigned char *out_ptr=out;
-int i=0;
-int j;
-/* process partial block if any */
-if (ctx->num)
-{
- for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
+ const unsigned char *in, unsigned int inl)
{
- *out_ptr=ctx->buf[j]^(*in_ptr);
- }
- if (j==8) {
- ctx->num=0;
- } else {
- ctx->num=j;
- return 1;
- }
-}
-
-for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) {
- /*block cipher current iv */
- /* Encrypt */
- gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
- /*xor next block of input text with it and output it*/
- /*output this block */
- for (j=0;j<8;j++) {
+ const unsigned char *in_ptr=in;
+ unsigned char *out_ptr=out;
+ int i=0;
+ int j;
+/* process partial block if any */
+ if (ctx->num)
+ {
+ for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
+ {
+ *out_ptr=ctx->buf[j]^(*in_ptr);
+ }
+ if (j==8)
+ {
+ ctx->num=0;
+ }
+ else
+ {
+ ctx->num=j;
+ return 1;
+ }
+ }
+
+ for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
+ {
+ /*block cipher current iv */
+ /* Encrypt */
+ gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
+ /*xor next block of input text with it and output it*/
+ /*output this block */
+ for (j=0;j<8;j++)
+ {
out_ptr[j]=ctx->buf[j]^in_ptr[j];
- }
-}
+ }
+ }
/* Process rest of buffer */
-if (i<inl) {
- gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
- for (j=0;i<inl;j++,i++) {
+ if (i<inl)
+ {
+ gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
+ for (j=0;i<inl;j++,i++)
+ {
out_ptr[j]=ctx->buf[j]^in_ptr[j];
- }
- ctx->num = j;
-} else {
- ctx->num = 0;
-}
-return 1;
-}
+ }
+ ctx->num = j;
+ }
+ else
+ {
+ ctx->num = 0;
+ }
+ return 1;
+ }
+
/* Cleaning up of EVP_CIPHER_CTX */
int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx)
-{
-gost_destroy((gost_ctx *)ctx->cipher_data);
-return 1;
+ {
+ gost_destroy((gost_ctx *)ctx->cipher_data);
+ ctx->app_data = NULL;
+ return 1;
+ }
-}
/* Control function for gost cipher */
int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
-{
-switch (type)
-{
- case EVP_CTRL_RAND_KEY:
- {
- if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
- {
- GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
- return -1;
- }
- break;
+ {
+ switch (type)
+ {
+ case EVP_CTRL_RAND_KEY:
+ {
+ if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
+ {
+ GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR);
+ return -1;
}
- default:
- GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
+ break;
+ }
+ default:
+ GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
return -1;
-}
-return 1;
-}
+ }
+ return 1;
+ }
/* Set cipher parameters from ASN1 structure */
int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
-{
-int len=0;
-unsigned char *buf=NULL;
-unsigned char *p=NULL;
-struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
-GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
-ASN1_OCTET_STRING *os = NULL;
-if (!gcp) {
- GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
- return 0;
-}
-if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) {
- GOST_CIPHER_PARAMS_free(gcp);
- GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
- return 0;
-}
-ASN1_OBJECT_free(gcp->enc_param_set);
-gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
-
-len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
-p = buf = (unsigned char*)OPENSSL_malloc(len);
-if (!buf) {
+ {
+ int len=0;
+ unsigned char *buf=NULL;
+ unsigned char *p=NULL;
+ struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
+ GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
+ ASN1_OCTET_STRING *os = NULL;
+ if (!gcp)
+ {
+ GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+ return 0;
+ }
+ if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
+ {
+ GOST_CIPHER_PARAMS_free(gcp);
+ GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+ return 0;
+ }
+ ASN1_OBJECT_free(gcp->enc_param_set);
+ gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
+
+ len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
+ p = buf = (unsigned char*)OPENSSL_malloc(len);
+ if (!buf)
+ {
+ GOST_CIPHER_PARAMS_free(gcp);
+ GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+ return 0;
+ }
+ i2d_GOST_CIPHER_PARAMS(gcp, &p);
GOST_CIPHER_PARAMS_free(gcp);
- GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
- return 0;
-}
-i2d_GOST_CIPHER_PARAMS(gcp, &p);
-GOST_CIPHER_PARAMS_free(gcp);
-os = ASN1_OCTET_STRING_new();
+ os = ASN1_OCTET_STRING_new();
-if(!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
+ if(!os || !ASN1_OCTET_STRING_set(os, buf, len))
+ {
+ OPENSSL_free(buf);
+ GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
+ return 0;
+ }
OPENSSL_free(buf);
- GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
- return 0;
-}
-OPENSSL_free(buf);
-
-ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
-return 1;
-}
+
+ ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
+ return 1;
+ }
+
/* Store parameters into ASN1 structure */
int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
-{
-int ret = -1;
-int len;
-GOST_CIPHER_PARAMS *gcp = NULL;
-unsigned char *p = params->value.sequence->data;
-struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
-if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
- return ret;
-}
-
-gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
+ {
+ int ret = -1;
+ int len;
+ GOST_CIPHER_PARAMS *gcp = NULL;
+ unsigned char *p = params->value.sequence->data;
+ struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
+ if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
+ {
+ return ret;
+ }
+
+ gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
params->value.sequence->length);
-len = gcp->iv->length;
-if (len != ctx->cipher->iv_len) {
- GOST_CIPHER_PARAMS_free(gcp);
- GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
+ len = gcp->iv->length;
+ if (len != ctx->cipher->iv_len)
+ {
+ GOST_CIPHER_PARAMS_free(gcp);
+ GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
GOST_R_INVALID_IV_LENGTH);
- return -1;
-}
-if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set))) {
- GOST_CIPHER_PARAMS_free(gcp);
- return -1;
-}
-memcpy(ctx->oiv, gcp->iv->data, len);
+ return -1;
+ }
+ if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
+ {
+ GOST_CIPHER_PARAMS_free(gcp);
+ return -1;
+ }
+ memcpy(ctx->oiv, gcp->iv->data, len);
-GOST_CIPHER_PARAMS_free(gcp);
+ GOST_CIPHER_PARAMS_free(gcp);
-return 1;
-
-}
+ return 1;
+ }
#ifdef USE_SSL
-int gost_imit_init_vizir(EVP_MD_CTX *ctx) {
-struct ossl_gost_imit_ctx *c = ctx->md_data;
-memset(c,0,sizeof(struct ossl_gost_imit_ctx));
-gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
-return 1;
-}
-int gost_imit_init_cpa(EVP_MD_CTX *ctx) {
-struct ossl_gost_imit_ctx *c = ctx->md_data;
-memset(c,0,sizeof(struct ossl_gost_imit_ctx));
-c->key_meshing=1;
-gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
-return 1;
-}
+int gost_imit_init_vizir(EVP_MD_CTX *ctx)
+ {
+ struct ossl_gost_imit_ctx *c = ctx->md_data;
+ memset(c,0,sizeof(struct ossl_gost_imit_ctx));
+ gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
+ return 1;
+ }
+
+int gost_imit_init_cpa(EVP_MD_CTX *ctx)
+ {
+ struct ossl_gost_imit_ctx *c = ctx->md_data;
+ memset(c,0,sizeof(struct ossl_gost_imit_ctx));
+ c->key_meshing=1;
+ gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
+ return 1;
+ }
static void mac_block_mesh(struct ossl_gost_imit_ctx *c,unsigned char *data)
-{
+ {
char buffer[8];
/* We are using local buffer for iv because CryptoPro doesn't
* interpret internal state of MAC algorithm as iv during keymeshing
* (but does initialize internal state from iv in key transport
*/
- if (c->key_meshing&& c->count && c->count %1024 ==0) {
+ if (c->key_meshing&& c->count && c->count %1024 ==0)
+ {
cryptopro_key_meshing(&(c->cctx),buffer);
- }
+ }
mac_block(&(c->cctx),c->buffer,data);
c->count +=8;
-}
+ }
-int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
+int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+ {
struct ossl_gost_imit_ctx *c = ctx->md_data;
const unsigned char *p = data;
size_t bytes = count,i;
if (!(c->key_set)) return 0;
- if (c->bytes_left) {
- for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++) {
+ if (c->bytes_left)
+ {
+ for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
+ {
c->partial_block[i]=*p;
- }
- if (i==8) {
+ }
+ if (i==8)
+ {
mac_block_mesh(c,c->partial_block);
- } else {
+ }
+ else
+ {
c->bytes_left = i;
return 1;
- }
- }
- while (bytes>8) {
+ }
+ }
+ while (bytes>8)
+ {
mac_block_mesh(c,p);
p+=8;
bytes-=8;
- }
- if (bytes>0) {
+ }
+ if (bytes>0)
+ {
memcpy(c->partial_block,p,bytes);
c->bytes_left=bytes;
- }
+ }
return 1;
-}
+ }
-int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md) {
+int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
+ {
struct ossl_gost_imit_ctx *c = ctx->md_data;
- if (c->bytes_left) {
+ if (c->bytes_left)
+ {
int i;
- for (i=c->bytes_left;i<8;i++) {
+ for (i=c->bytes_left;i<8;i++)
+ {
c->partial_block[i]=0;
- }
+ }
mac_block_mesh(c,c->partial_block);
- }
+ }
get_mac(c->buffer,32,md);
return 1;
-}
-int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr) {
- switch (type) {
- case EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH:
- *((unsigned int*)(ptr)) = 32;
- return 1;
- case EVP_MD_CTRL_SET_KEY:
- {
- gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ;
- ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
+ }
+
+int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr)
+ {
+ switch (type)
+ {
+ case EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH:
+ *((unsigned int*)(ptr)) = 32;
+ return 1;
+ case EVP_MD_CTRL_SET_KEY:
+ {
+ gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ;
+ ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
}
- default:
- return 0;
- }
-}
-int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) {
+ default:
+ return 0;
+ }
+ }
+
+int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+ {
memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
return 1;
-}
+ }
+
/* Clean up imit ctx */
-int gost_imit_cleanup(EVP_MD_CTX *ctx) {
+int gost_imit_cleanup(EVP_MD_CTX *ctx)
+ {
memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
return 1;
-
-}
+ }
+
#endif