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_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;
+ data->mac_size = key->mac_size;
+ }
+ }
+
EVP_PKEY_CTX_set_data(ctx, data);
return 1;
}
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;
+ 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) {
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);
}
+ case EVP_PKEY_CTRL_MAC_LEN:
+ {
+ if (p1 < 1 || p1 > 8) {
+
+ GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_SIZE);
+ return 0;
+ }
+ data->mac_size = p1;
+ return 1;
+ }
}
return -2;
}
return ret;
}
+ if (!strcmp(type, maclen_ctrl_string)) {
+ char *endptr;
+ long size = strtol(value, &endptr, 10);
+ if (*endptr != '\0') {
+ GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE);
+ return 0;
+ }
+ 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);
+ ASN1_OBJECT_free(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;
}
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;
+ keydata->mac_size = data->mac_size;
EVP_PKEY_assign(pkey, mac_nid, keydata);
return 1;
}
static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
+ struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+ if (data == NULL) {
+ pkey_gost_mac_init(ctx);
+ }
+
+ data = EVP_PKEY_CTX_get_data(ctx);
+ if (!data) {
+ GOSTerr(GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
+ return 0;
+ }
+
return 1;
}
{
unsigned int tmpsiglen;
int ret;
+ struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
if (!siglen)
return 0;
* sizeof(size_t) */
if (!sig) {
- *siglen = 4;
+ *siglen = data->mac_size;
return 1;
}
+
+ mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_MAC_LEN, data->mac_size, NULL);
ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
- *siglen = tmpsiglen;
+ *siglen = data->mac_size;
return ret;
}