Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions gost_ameth.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,135 @@ static ASN1_STRING *gost_encode_cms_params(int ka_nid)
return ret;
}

static int gost_set_raw_pub_key(EVP_PKEY *pk, const unsigned char *pub, size_t len)
{
int ret = 0;
BIGNUM *X = NULL;
BIGNUM *Y = NULL;
EC_POINT *pub_key = NULL;
EC_KEY *ec;
const EC_GROUP *group;
const BIGNUM *order;
int half;

if (pub == NULL || len == 0) {
return 0;
}

if ((ec = EVP_PKEY_get0(pk)) == NULL
|| (group = EC_KEY_get0_group(ec)) == NULL
|| (order = EC_GROUP_get0_order(group)) == NULL) {
return 0;
}

half = len / 2;
if ((X = BN_lebin2bn(pub, half, NULL)) == NULL
|| (Y = BN_lebin2bn(pub + half, half, NULL)) == NULL
|| (pub_key = EC_POINT_new(group)) == NULL) {
goto end;
}

if (EC_POINT_set_affine_coordinates(group, pub_key, X, Y, NULL) != 1) {
goto end;
}

if (EC_KEY_set_public_key(ec, pub_key) != 1) {
goto end;
}

ret = 1;
end:
EC_POINT_free(pub_key);
BN_free(Y);
BN_free(X);
return ret;
}

static int gost_get_raw_priv_key(const EVP_PKEY *pk, unsigned char *priv, size_t *len)
{
const EC_KEY *ec;
const EC_GROUP *group;
const BIGNUM *order;
const BIGNUM *priv_key;
int half;

if (len == NULL) {
return 0;
}

if ((ec = EVP_PKEY_get0(pk)) == NULL
|| (group = EC_KEY_get0_group(ec)) == NULL
|| (order = EC_GROUP_get0_order(group)) == NULL
|| (priv_key = EC_KEY_get0_private_key(ec)) == NULL) {
return 0;
}

half = BN_num_bytes(order);
if (priv == NULL) {
*len = half;
return 1;
}

if (BN_bn2lebinpad(priv_key, priv, half) != half) {
return 0;
}

return 1;
}

static int gost_get_raw_pub_key(const EVP_PKEY *pk, unsigned char *pub, size_t *len)
{
int ret = 0;
BIGNUM *X = NULL;
BIGNUM *Y = NULL;
const EC_KEY *ec;
const EC_GROUP *group;
const BIGNUM *order;
const EC_POINT *pub_key;
int half;

if (len == NULL) {
return 0;
}

if ((ec = EVP_PKEY_get0(pk)) == NULL
|| (group = EC_KEY_get0_group(ec)) == NULL
|| (order = EC_GROUP_get0_order(group)) == NULL
|| (pub_key = EC_KEY_get0_public_key(ec)) == NULL) {
return 0;
}

half = BN_num_bytes(order);
if (pub == NULL) {
*len = 2 * half;
return 1;
}

if (*len < 2 * half) {
return 0;
}

if ((X = BN_new()) == NULL
|| (Y = BN_new()) == NULL) {
goto end;
}

if (EC_POINT_get_affine_coordinates(group, pub_key, X, Y, NULL) != 1) {
goto end;
}

if (BN_bn2lebinpad(X, pub, half) != half
|| BN_bn2lebinpad(Y, pub + half, half) != half) {
goto end;
}

ret = 1;
end:
BN_free(Y);
BN_free(X);
return ret;
}

/*
* Control function
*/
Expand Down Expand Up @@ -531,6 +660,26 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
*(int *)arg2 = md_nid;
return 2;
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
{
unsigned char **dup = (unsigned char **)arg2;
unsigned char *buf = NULL;
size_t len;

if (dup == NULL
|| gost_get_raw_pub_key(pkey, NULL, &len) != 1
|| (buf = OPENSSL_malloc(len)) == NULL
|| gost_get_raw_pub_key(pkey, buf, &len) != 1) {
if (buf)
OPENSSL_free(buf);
return 0;
}

*dup = buf;
return len;
}
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
return gost_set_raw_pub_key(pkey, (const unsigned char *)arg2, arg1);
}

return -2;
Expand Down Expand Up @@ -1196,6 +1345,10 @@ int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
pub_cmp_gost_ec, pub_print_gost_ec,
pkey_size_gost, pkey_bits_gost);

EVP_PKEY_asn1_set_set_pub_key(*ameth, gost_set_raw_pub_key);
EVP_PKEY_asn1_set_get_priv_key(*ameth, gost_get_raw_priv_key);
EVP_PKEY_asn1_set_get_pub_key(*ameth, gost_get_raw_pub_key);

EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
EVP_PKEY_asn1_set_security_bits(*ameth, pkey_bits_gost);
break;
Expand Down
17 changes: 12 additions & 5 deletions gost_crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ static int magma_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
c->key_meshing = 0;
}

c->count = 0;
return 1;
}

Expand All @@ -529,6 +530,7 @@ static int magma_cipher_init_ctr_acpkm_omac(EVP_CIPHER_CTX *ctx, const unsigned
if (key) {
struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
unsigned char cipher_key[32];
int ret;
c->omac_ctx = EVP_MD_CTX_new();

if (c->omac_ctx == NULL) {
Expand All @@ -543,7 +545,9 @@ static int magma_cipher_init_ctr_acpkm_omac(EVP_CIPHER_CTX *ctx, const unsigned
return 0;
}

return magma_cipher_init(ctx, cipher_key, iv, enc);
ret = magma_cipher_init(ctx, cipher_key, iv, enc);
OPENSSL_cleanse(cipher_key, sizeof(cipher_key));
return ret;
}

return magma_cipher_init(ctx, key, iv, enc);
Expand Down Expand Up @@ -1273,10 +1277,6 @@ static int magma_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
return -1;
}

if (c->count != 0) {
return -1;
}

c->key_meshing = arg;
return 1;
}
Expand Down Expand Up @@ -1324,6 +1324,7 @@ static int magma_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 8);

magma_key(c, newkey);
OPENSSL_cleanse(newkey, sizeof(newkey));
return 1;
}
}
Expand Down Expand Up @@ -1650,4 +1651,10 @@ static int gost_imit_cleanup(EVP_MD_CTX *ctx)
memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(struct ossl_gost_imit_ctx));
return 1;
}

/* Called directly by CMAC_ACPKM_Init() */
const EVP_CIPHER *cipher_gost_magma_ctracpkm()
{
return GOST_init_cipher(&magma_ctr_acpkm_cipher);
}
/* vim: set expandtab cinoptions=\:0,l1,t0,g0,(0 sw=4 : */
1 change: 1 addition & 0 deletions gost_eng.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ GOST_digest *gost_digest_array[] = {
&magma_mac_digest,
&grasshopper_mac_digest,
&kuznyechik_ctracpkm_omac_digest,
&magma_ctracpkm_omac_digest,
};

GOST_cipher *gost_cipher_array[] = {
Expand Down
7 changes: 6 additions & 1 deletion gost_grasshopper_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ static void acpkm_next(gost_grasshopper_cipher_ctx * c)
&c->buffer);
}
gost_grasshopper_cipher_key(c, newkey);
OPENSSL_cleanse(newkey, sizeof(newkey));
}

/* Set 256 bit key into context */
Expand Down Expand Up @@ -351,6 +352,7 @@ gost_grasshopper_cipher_init_ctracpkm_omac(EVP_CIPHER_CTX

if (key) {
unsigned char cipher_key[32];
int ret;
c->omac_ctx = EVP_MD_CTX_new();

if (c->omac_ctx == NULL) {
Expand All @@ -365,7 +367,9 @@ gost_grasshopper_cipher_init_ctracpkm_omac(EVP_CIPHER_CTX
return 0;
}

return gost_grasshopper_cipher_init(ctx, cipher_key, iv, enc);
ret = gost_grasshopper_cipher_init(ctx, cipher_key, iv, enc);
OPENSSL_cleanse(cipher_key, sizeof(cipher_key));
return ret;
}

return gost_grasshopper_cipher_init(ctx, key, iv, enc);
Expand Down Expand Up @@ -1158,6 +1162,7 @@ static int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, v
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);

gost_grasshopper_cipher_key(c, newkey);
OPENSSL_cleanse(newkey, sizeof(newkey));
return 1;
}
}
Expand Down
10 changes: 6 additions & 4 deletions gost_keyexpimp.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ int gost_tlstree(int cipher_nid, const unsigned char *in, unsigned char *out,
uint64_t seed1, seed2, seed3;
uint64_t seq;
unsigned char ko1[32], ko2[32];
int ret;

switch (cipher_nid) {
case NID_magma_cbc:
Expand All @@ -293,15 +294,16 @@ int gost_tlstree(int cipher_nid, const unsigned char *in, unsigned char *out,
seed2 = seq & c2;
seed3 = seq & c3;

if (gost_kdftree2012_256(ko1, 32, in, 32, (const unsigned char *)"level1", 6,
ret = !(gost_kdftree2012_256(ko1, 32, in, 32, (const unsigned char *)"level1", 6,
(const unsigned char *)&seed1, 8, 1) <= 0
|| gost_kdftree2012_256(ko2, 32, ko1, 32, (const unsigned char *)"level2", 6,
(const unsigned char *)&seed2, 8, 1) <= 0
|| gost_kdftree2012_256(out, 32, ko2, 32, (const unsigned char *)"level3", 6,
(const unsigned char *)&seed3, 8, 1) <= 0)
return 0;
(const unsigned char *)&seed3, 8, 1) <= 0);

return 1;
OPENSSL_cleanse(ko1, sizeof(ko1));
OPENSSL_cleanse(ko2, sizeof(ko2));
return ret;
}

#define GOST_WRAP_FLAGS EVP_CIPH_CTRL_INIT | EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_DEFAULT_ASN1
Expand Down
3 changes: 3 additions & 0 deletions gost_lcl.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ typedef struct gost_cipher_st GOST_cipher;
EVP_CIPHER *GOST_init_cipher(GOST_cipher *c);
void GOST_deinit_cipher(GOST_cipher *c);

const EVP_CIPHER *cipher_gost_magma_ctracpkm();

/* ENGINE implementation data */
extern GOST_cipher Gost28147_89_cipher;
extern GOST_cipher Gost28147_89_cbc_cipher;
Expand Down Expand Up @@ -398,6 +400,7 @@ extern GOST_digest GostR3411_2012_512_digest;
extern GOST_digest magma_mac_digest;
extern GOST_digest grasshopper_mac_digest;
extern GOST_digest kuznyechik_ctracpkm_omac_digest;
extern GOST_digest magma_ctracpkm_omac_digest;

/* Provider implementation data */
extern const OSSL_ALGORITHM GOST_prov_digests[];
Expand Down
1 change: 1 addition & 0 deletions gost_omac.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
|| (cipher = EVP_CIPHER_fetch(NULL, c->cipher_name, NULL)))
ret = omac_key(c, cipher, diversed_key, 32);
EVP_CIPHER_free(cipher);
OPENSSL_cleanse(diversed_key, sizeof(diversed_key));
}
return ret;
}
Expand Down
Loading
Loading