aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Belyavskiy <beldmit@gmail.com>2016-01-02 22:58:56 +0300
committerDmitry Belyavskiy <beldmit@gmail.com>2016-01-02 22:58:56 +0300
commit557edb4e1feed3791e90d3eab7da3ae7a43d40e6 (patch)
tree45a8075594986785868b3f3097146280f85902b9
parenta0a869029241b849ea989314bd0374b0ea948e4b (diff)
downloadgost-engine-557edb4e1feed3791e90d3eab7da3ae7a43d40e6.zip
gost-engine-557edb4e1feed3791e90d3eab7da3ae7a43d40e6.tar.gz
gost-engine-557edb4e1feed3791e90d3eab7da3ae7a43d40e6.tar.bz2
Gost MAC paramset
-rw-r--r--gost_crypt.c40
-rw-r--r--gost_lcl.h8
-rw-r--r--gost_pmeth.c55
3 files changed, 87 insertions, 16 deletions
diff --git a/gost_crypt.c b/gost_crypt.c
index 3523b38..66e769d 100644
--- a/gost_crypt.c
+++ b/gost_crypt.c
@@ -766,24 +766,46 @@ int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
return 1;
case EVP_MD_CTRL_SET_KEY:
{
- if (arg != 32) {
- GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_SIZE);
- return 0;
+ struct ossl_gost_imit_ctx *gost_imit_ctx = ctx->md_data;
+
+ if (ctx->digest->init(ctx) <= 0) {
+ GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET);
+ return 0;
+ }
+ ctx->flags |= EVP_MD_CTX_FLAG_NO_INIT;
+
+ if (arg == 0) {
+ struct gost_mac_key *key = (struct gost_mac_key*) ptr;
+ if (key->mac_param_nid != NID_undef) {
+ const struct gost_cipher_info *param = get_encryption_params(OBJ_nid2obj(key->mac_param_nid));
+ if (param == NULL)
+ {
+ GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_PARAMS);
+ return 0;
+ }
+ gost_init(&(gost_imit_ctx->cctx), param->sblock);
+ }
+ gost_key(&(gost_imit_ctx->cctx), key->key);
+ gost_imit_ctx->key_set = 1;
+
+ return 1;
}
-
- gost_key(&(((struct ossl_gost_imit_ctx *)(ctx->md_data))->cctx),
- ptr);
- ((struct ossl_gost_imit_ctx *)(ctx->md_data))->key_set = 1;
+ else if (arg == 32)
+ {
+ gost_key(&(gost_imit_ctx->cctx), ptr);
+ gost_imit_ctx->key_set = 1;
return 1;
-
+ }
+ GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_SIZE);
+ return 0;
}
case EVP_MD_CTRL_MAC_LEN:
{
+ struct ossl_gost_imit_ctx *c = ctx->md_data;
if (arg < 1 || arg > 8) {
GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE);
return 0;
}
- struct ossl_gost_imit_ctx *c = ctx->md_data;
c->dgst_size=arg;
return 1;
}
diff --git a/gost_lcl.h b/gost_lcl.h
index b89c453..376e39c 100644
--- a/gost_lcl.h
+++ b/gost_lcl.h
@@ -72,10 +72,16 @@ struct gost_pmeth_data {
struct gost_mac_pmeth_data {
short int key_set;
- short int mac_size;
+ short int mac_size;
+ int mac_param_nid;
EVP_MD *md;
unsigned char key[32];
};
+
+struct gost_mac_key {
+ int mac_param_nid;
+ unsigned char key[32];
+};
/* GOST-specific ASN1 structures */
typedef struct {
diff --git a/gost_pmeth.c b/gost_pmeth.c
index 896dabb..f07c4da 100644
--- a/gost_pmeth.c
+++ b/gost_pmeth.c
@@ -466,11 +466,21 @@ static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
{
struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
if (!data)
return 0;
memset(data, 0, sizeof(*data));
- data->mac_size = 4;
+ data->mac_size = 4;
+ data->mac_param_nid = NID_undef;
+
+ if (pkey) {
+ struct gost_mac_key *key = EVP_PKEY_get0(pkey);
+ if (key) {
+ data->mac_param_nid = key->mac_param_nid;
+ }
+ }
+
EVP_PKEY_CTX_set_data(ctx, data);
return 1;
}
@@ -532,10 +542,24 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
memcpy(data->key, p2, 32);
data->key_set = 1;
return 1;
+ case EVP_PKEY_CTRL_GOST_PARAMSET:
+ {
+ struct gost_cipher_info *param = p2;
+ data->mac_param_nid = param->nid;
+ struct gost_mac_key *key = NULL;
+ EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+ if (pkey) {
+ key = EVP_PKEY_get0(pkey);
+ if (key) {
+ key->mac_param_nid = param->nid;
+ }
+ }
+ return 1;
+ }
case EVP_PKEY_CTRL_DIGESTINIT:
{
EVP_MD_CTX *mctx = p2;
- void *key;
+ struct gost_mac_key *key;
if (!data->key_set) {
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
if (!pkey) {
@@ -549,8 +573,9 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
GOST_R_MAC_KEY_NOT_SET);
return 0;
}
+ return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 0, key);
} else {
- key = &(data->key);
+ return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
}
return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key);
}
@@ -606,6 +631,23 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
}
return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN,size,NULL);
}
+ if (strcmp(type, param_ctrl_string) == 0)
+ {
+ ASN1_OBJECT *obj = OBJ_txt2obj(value, 0);
+ const struct gost_cipher_info *param = NULL;
+ if (obj == NULL) {
+ GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
+ return 0;
+ }
+
+ param = get_encryption_params(obj);
+ if (param == NULL) {
+ GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
+ return 0;
+ }
+
+ return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0, (void *)param);
+ }
return -2;
}
@@ -613,15 +655,16 @@ static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx,
EVP_PKEY *pkey, int mac_nid)
{
struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
- unsigned char *keydata;
+ struct gost_mac_key *keydata;
if (!data || !data->key_set) {
GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET);
return 0;
}
- keydata = OPENSSL_malloc(32);
+ keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
if (keydata == NULL)
return 0;
- memcpy(keydata, data->key, 32);
+ memcpy(keydata->key, data->key, 32);
+ keydata->mac_param_nid = data->mac_param_nid;
EVP_PKEY_assign(pkey, mac_nid, keydata);
return 1;
}