#include <openssl/rand.h>
#include "e_gost_err.h"
#include "gost_lcl.h"
+
+#if !defined(CCGOST_DEBUG) && !defined(DEBUG)
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
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);
-#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);
-#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, size_t 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, size_t inl);
/* Cleanup function */
static int gost_cipher_cleanup(EVP_CIPHER_CTX *);
/* set/get cipher parameters */
NID_id_Gost28147_89,
1,/*block_size*/
32,/*key_size*/
- 8,/*iv_len - ñèíõðîïîñûëêà*/
+ 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,
NID_gost89_cnt,
1,/*block_size*/
32,/*key_size*/
- 8,/*iv_len - ñèíõðîïîñûëêà*/
+ 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,
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,
- };
-
/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
/* Init functions which set specific parameters */
-static int gost_imit_init_vizir(EVP_MD_CTX *ctx);
static int gost_imit_init_cpa(EVP_MD_CTX *ctx);
/* process block of data */
static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count);
/* Control function, knows how to set MAC key.*/
static int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr);
-EVP_MD imit_gost_vizir =
- {
- NID_undef,
- NID_undef,
- 4,
- EVP_MD_FLAG_NEEDS_KEY,
- gost_imit_init_vizir,
- gost_imit_update,
- gost_imit_final,
- gost_imit_copy,
- gost_imit_cleanup,
- gost_imit_ctrl,
- NULL,
- NULL,
- {0,0,0,0,0},
- 8,
- sizeof(struct ossl_gost_imit_ctx)
- };
-
EVP_MD imit_gost_cpa =
{
- NID_undef,
+ NID_id_Gost28147_89_MAC,
NID_undef,
4,
- EVP_MD_FLAG_NEEDS_KEY,
+ 0,
gost_imit_init_cpa,
gost_imit_update,
gost_imit_final,
gost_imit_copy,
gost_imit_cleanup,
- gost_imit_ctrl,
NULL,
NULL,
{0,0,0,0,0},
8,
- sizeof(struct ossl_gost_imit_ctx)
+ sizeof(struct ossl_gost_imit_ctx),
+ gost_imit_ctrl
};
-#endif
/*
* Correspondence between gost parameter OIDs and substitution blocks
* NID field is filed by register_gost_NID function in engine.c
{
const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
if (!params || !strlen(params))
- return &gost_cipher_list[0];
+ return &gost_cipher_list[1];
nid = OBJ_txt2nid(params);
if (nid == NID_undef)
gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
c->key_meshing=1;
c->count=0;
- gost_key(&(c->cctx),key);
+ 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;
}
-#ifdef USE_SSL
-/* Initializes EVP_CIPHER_CTX with fixed cryptopro A paramset */
-
-/* Initializes EVP_CIPHER_CTX with fixed vizir paramset */
-static 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;
- }
-#endif /* def USE_SSL */
/* Initializes EVP_CIPHER_CTX with default values */
int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
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)
+ assert(c->count%8 == 0 && c->count <= 1024);
+ if (c->key_meshing && c->count==1024)
{
cryptopro_key_meshing(&(c->cctx),iv);
}
gostcrypt(&(c->cctx),iv,buf);
- c->count+=8;
+ c->count = c->count%1024 + 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)
+ assert(c->count%8 == 0 && c->count <= 1024);
+ if (c->key_meshing && c->count==1024)
{
cryptopro_key_meshing(&(c->cctx),iv);
}
}
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;
+ buf1[0]=(unsigned char)(g&0xff);
+ buf1[1]=(unsigned char)((g>>8)&0xff);
+ buf1[2]=(unsigned char)((g>>16)&0xff);
+ buf1[3]=(unsigned char)((g>>24)&0xff);
g = buf1[4]|(buf1[5]<<8)|(buf1[6]<<16)|(buf1[7]<<24);
go = g;
g += 0x01010104;
if (go > g) /* overflow*/
g++;
- buf1[4]=g&0xff; buf1[5]=(g>>8)&0xff; buf1[6]=(g>>16)&0xff; buf1[7]=(g>>24)&0xff;
+ buf1[4]=(unsigned char)(g&0xff);
+ buf1[5]=(unsigned char)((g>>8)&0xff);
+ buf1[6]=(unsigned char)((g>>16)&0xff);
+ buf1[7]=(unsigned char)((g>>24)&0xff);
memcpy(iv,buf1,8);
gostcrypt(&(c->cctx),buf1,buf);
- c->count +=8;
+ c->count = c->count%1024 + 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, size_t inl)
{
const unsigned char *in_ptr=in;
unsigned char *out_ptr=out;
- int i=0;
- int j=0;
+ size_t i=0;
+ size_t j=0;
/* process partial block if any */
if (ctx->num)
{
if (i<inl)
{
gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
- if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
+ if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,inl-i);
for (j=0;i<inl;j++,i++)
{
out_ptr[j]=ctx->buf[j]^in_ptr[j];
}
static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl)
+ const unsigned char *in, size_t inl)
{
const unsigned char *in_ptr=in;
unsigned char *out_ptr=out;
- int i=0;
- int j;
+ size_t i=0;
+ size_t j;
/* process partial block if any */
if (ctx->num)
{
/* Cleaning up of EVP_CIPHER_CTX */
int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx)
{
- gost_destroy((gost_ctx *)ctx->cipher_data);
+ gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx);
ctx->app_data = NULL;
return 1;
}
}
break;
}
+ case EVP_CTRL_PBE_PRF_NID:
+ if (ptr) {
+ *((int *)ptr)= NID_id_HMACGostR3411_94;
+ return 1;
+ } else {
+ return 0;
+ }
+
default:
GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
return -1;
int ret = -1;
int len;
GOST_CIPHER_PARAMS *gcp = NULL;
- unsigned char *p = params->value.sequence->data;
+ unsigned char *p;
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
{
return ret;
}
+ p = params->value.sequence->data;
+
gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
params->value.sequence->length);
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->buffer,0,16);
+ memset(c->buffer,0,sizeof(c->buffer));
+ memset(c->partial_block,0,sizeof(c->partial_block));
c->count = 0;
c->bytes_left=0;
c->key_meshing=1;
return 1;
}
-static void mac_block_mesh(struct ossl_gost_imit_ctx *c,unsigned char *data)
+static void mac_block_mesh(struct ossl_gost_imit_ctx *c,const unsigned char *data)
{
- char buffer[8];
+ unsigned 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)
+ assert(c->count%8 == 0 && c->count <= 1024);
+ if (c->key_meshing && c->count==1024)
{
cryptopro_key_meshing(&(c->cctx),buffer);
}
mac_block(&(c->cctx),c->buffer,data);
- c->count +=8;
+ c->count = c->count%1024 + 8;
}
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->key_set)) {
+ GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
+ return 0;
+ }
if (c->bytes_left)
{
for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
if (bytes>0)
{
memcpy(c->partial_block,p,bytes);
- c->bytes_left=bytes;
}
+ c->bytes_left=bytes;
return 1;
}
int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md)
{
struct ossl_gost_imit_ctx *c = ctx->md_data;
+ if (!c->key_set) {
+ GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
+ return 0;
+ }
+ if (c->count==0 && c->bytes_left)
+ {
+ unsigned char buffer[8];
+ memset(buffer, 0, 8);
+ gost_imit_update(ctx, buffer, 8);
+ }
if (c->bytes_left)
{
int i;
{
switch (type)
{
- case EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH:
+ case EVP_MD_CTRL_KEY_LEN:
*((unsigned int*)(ptr)) = 32;
return 1;
case EVP_MD_CTRL_SET_KEY:
{
+ if (arg!=32) {
+ GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH);
+ return 0;
+ }
+
gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ;
((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1;
+ return 1;
}
default:
return 1;
}
-#endif