aboutsummaryrefslogtreecommitdiff
path: root/gost_ec_keyx.c
diff options
context:
space:
mode:
authorDmitry Belyavskiy <beldmit@gmail.com>2020-05-10 15:14:48 +0300
committerDmitry Belyavskiy <beldmit@gmail.com>2020-05-10 17:05:15 +0300
commit9cf021b8f3cc7b0f49ecd2f165bd1864903c90d0 (patch)
treed7b377bcfe638510f20e37574e9bbc559aab324a /gost_ec_keyx.c
parentfd5447e7fca18868178b225de76b49bf3dce90c6 (diff)
downloadgost-engine-9cf021b8f3cc7b0f49ecd2f165bd1864903c90d0.zip
gost-engine-9cf021b8f3cc7b0f49ecd2f165bd1864903c90d0.tar.gz
gost-engine-9cf021b8f3cc7b0f49ecd2f165bd1864903c90d0.tar.bz2
GOST CMS encryption implementation.
Diffstat (limited to 'gost_ec_keyx.c')
-rw-r--r--gost_ec_keyx.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/gost_ec_keyx.c b/gost_ec_keyx.c
index 2b4a96e..1d13917 100644
--- a/gost_ec_keyx.c
+++ b/gost_ec_keyx.c
@@ -179,7 +179,7 @@ int pkey_gost_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
int dgst_nid = NID_undef;
- if (!data || !data->shared_ukm) {
+ if (!data || data->shared_ukm_size == 0) {
GOSTerr(GOST_F_PKEY_GOST_EC_DERIVE, GOST_R_UKM_NOT_SET);
return 0;
}
@@ -259,7 +259,7 @@ static int pkey_GOST_ECcp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
int key_is_ephemeral = 1;
gost_ctx cctx;
EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
- if (data->shared_ukm) {
+ if (data->shared_ukm_size) {
memcpy(ukm, data->shared_ukm, 8);
} else {
if (RAND_bytes(ukm, 8) <= 0) {
@@ -416,6 +416,14 @@ static int pkey_gost2018_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
key_is_ephemeral = 1;
}
+ if (data->shared_ukm_size == 0) {
+ if (RAND_bytes(data->shared_ukm, 32) <= 0) {
+ GOSTerr(GOST_F_PKEY_GOST2018_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ data->shared_ukm_size = 32;
+ }
+
if (gost_keg(data->shared_ukm, pkey_nid,
EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),
EVP_PKEY_get0(sec_key), expkeys) <= 0) {
@@ -437,6 +445,17 @@ static int pkey_gost2018_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
goto err;
}
+ pst->ukm = ASN1_OCTET_STRING_new();
+ if (pst->ukm == NULL) {
+ GOSTerr(GOST_F_PKEY_GOST2018_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!ASN1_OCTET_STRING_set(pst->ukm, data->shared_ukm, data->shared_ukm_size)) {
+ GOSTerr(GOST_F_PKEY_GOST2018_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
if (!ASN1_OCTET_STRING_set(pst->psexp, exp_buf, exp_len)) {
GOSTerr(GOST_F_PKEY_GOST2018_ENCRYPT, ERR_R_MALLOC_FAILURE);
goto err;
@@ -462,15 +481,21 @@ static int pkey_gost2018_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
int pkey_gost_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
size_t *out_len, const unsigned char *key, size_t key_len)
{
- struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
- if (data->shared_ukm == NULL || data->shared_ukm_size == 8)
- return pkey_GOST_ECcp_encrypt(pctx, out, out_len, key, key_len);
- else if (data->shared_ukm_size == 32)
- return pkey_gost2018_encrypt(pctx, out, out_len, key, key_len);
- else {
- GOSTerr(GOST_F_PKEY_GOST_ENCRYPT, ERR_R_INTERNAL_ERROR);
- return -1;
- }
+ struct gost_pmeth_data *gctx = EVP_PKEY_CTX_get_data(pctx);
+ switch (gctx->cipher_nid)
+ {
+ case NID_id_Gost28147_89:
+ case NID_undef: /* FIXME */
+ return pkey_GOST_ECcp_encrypt(pctx, out, out_len, key, key_len);
+ break;
+ case NID_kuznyechik_ctr:
+ case NID_magma_ctr:
+ return pkey_gost2018_encrypt(pctx, out, out_len, key, key_len);
+ break;
+ default:
+ GOSTerr(GOST_F_PKEY_GOST_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
}
/*
@@ -620,7 +645,7 @@ static int pkey_gost2018_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key,
o q * Q_eph is not equal to zero point.
*/
- if (data->shared_ukm == NULL && pst->ukm != NULL) {
+ if (data->shared_ukm_size == 0 && pst->ukm != NULL) {
if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_SET_IV,
ASN1_STRING_length(pst->ukm), (void *)ASN1_STRING_get0_data(pst->ukm)) < 0) {
GOSTerr(GOST_F_PKEY_GOST2018_DECRYPT, GOST_R_UKM_NOT_SET);
@@ -628,11 +653,6 @@ static int pkey_gost2018_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key,
}
}
- if (data->shared_ukm == NULL) {
- GOSTerr(GOST_F_PKEY_GOST2018_DECRYPT, GOST_R_UKM_NOT_SET);
- goto err;
- }
-
if (gost_keg(data->shared_ukm, pkey_nid,
EC_KEY_get0_public_key(EVP_PKEY_get0(eph_key)),
EVP_PKEY_get0(priv), expkeys) <= 0) {
@@ -661,16 +681,6 @@ int pkey_gost_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key,
size_t *key_len, const unsigned char *in, size_t in_len)
{
struct gost_pmeth_data *gctx = EVP_PKEY_CTX_get_data(pctx);
-#if 0
- if (data->shared_ukm == NULL || data->shared_ukm_size == 8)
- return pkey_GOST_ECcp_decrypt(pctx, key, key_len, in, in_len);
- else if (data->shared_ukm_size == 32)
- return pkey_gost2018_decrypt(pctx, key, key_len, in, in_len);
- else {
- GOSTerr(GOST_F_PKEY_GOST_DECRYPT, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-#else
switch (gctx->cipher_nid)
{
case NID_id_Gost28147_89:
@@ -683,5 +693,4 @@ int pkey_gost_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key,
GOSTerr(GOST_F_PKEY_GOST_DECRYPT, ERR_R_INTERNAL_ERROR);
return -1;
}
-#endif
}