Skip to content

Commit 41b4121

Browse files
committed
Magma/Kuznyechik ASN1 parameters and functions
1 parent ff31ce4 commit 41b4121

8 files changed

+164
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ set(GOST_ENGINE_SOURCE_FILES
160160
gost_pmeth.c
161161
gost_omac.c
162162
gost_omac_acpkm.c
163+
gost_gost2015.c
163164
)
164165

165166
add_executable(test_digest test_digest.c)

e_gost_err.c

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ static ERR_STRING_DATA GOST_str_functs[] = {
2020
"encode_gost_algor_params"},
2121
{ERR_PACK(0, GOST_F_FILL_GOST_EC_PARAMS, 0), "fill_GOST_EC_params"},
2222
{ERR_PACK(0, GOST_F_GET_ENCRYPTION_PARAMS, 0), "get_encryption_params"},
23+
{ERR_PACK(0, GOST_F_GOST2015_GET_ASN1_PARAMS, 0),
24+
"gost2015_get_asn1_params"},
25+
{ERR_PACK(0, GOST_F_GOST2015_SET_ASN1_PARAMS, 0),
26+
"gost2015_set_asn1_params"},
2327
{ERR_PACK(0, GOST_F_GOST89_GET_ASN1_PARAMETERS, 0),
2428
"gost89_get_asn1_parameters"},
2529
{ERR_PACK(0, GOST_F_GOST89_SET_ASN1_PARAMETERS, 0),

e_gost_err.h

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ void ERR_GOST_error(int function, int reason, char *file, int line);
3333
# define GOST_F_ENCODE_GOST_ALGOR_PARAMS 101
3434
# define GOST_F_FILL_GOST_EC_PARAMS 102
3535
# define GOST_F_GET_ENCRYPTION_PARAMS 103
36+
# define GOST_F_GOST2015_GET_ASN1_PARAMS 158
37+
# define GOST_F_GOST2015_SET_ASN1_PARAMS 159
3638
# define GOST_F_GOST89_GET_ASN1_PARAMETERS 104
3739
# define GOST_F_GOST89_SET_ASN1_PARAMETERS 105
3840
# define GOST_F_GOST_CIPHER_CTL 106

gost.txt

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ GOST_F_DECODE_GOST_ALGOR_PARAMS:100:decode_gost_algor_params
1010
GOST_F_ENCODE_GOST_ALGOR_PARAMS:101:encode_gost_algor_params
1111
GOST_F_FILL_GOST_EC_PARAMS:102:fill_GOST_EC_params
1212
GOST_F_GET_ENCRYPTION_PARAMS:103:get_encryption_params
13+
GOST_F_GOST2015_GET_ASN1_PARAMS:158:gost2015_get_asn1_params
14+
GOST_F_GOST2015_SET_ASN1_PARAMS:159:gost2015_set_asn1_params
1315
GOST_F_GOST89_GET_ASN1_PARAMETERS:104:gost89_get_asn1_parameters
1416
GOST_F_GOST89_SET_ASN1_PARAMETERS:105:gost89_set_asn1_parameters
1517
GOST_F_GOST_CIPHER_CTL:106:gost_cipher_ctl

gost_asn1.c

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) =
4848
} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)
4949
IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
5050

51+
ASN1_NDEF_SEQUENCE(GOST2015_CIPHER_PARAMS) = {
52+
ASN1_SIMPLE(GOST2015_CIPHER_PARAMS, ukm, ASN1_OCTET_STRING),
53+
} ASN1_NDEF_SEQUENCE_END(GOST2015_CIPHER_PARAMS)
54+
IMPLEMENT_ASN1_FUNCTIONS(GOST2015_CIPHER_PARAMS)
55+
5156
ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) =
5257
{ /* FIXME incomplete */
5358
ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)

gost_gost2015.c

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#include "gost_lcl.h"
2+
#include "gost_gost2015.h"
3+
#include "e_gost_err.h"
4+
#include <string.h>
5+
6+
int gost2015_final_call(EVP_CIPHER_CTX *ctx, EVP_MD_CTX *omac_ctx, size_t mac_size,
7+
unsigned char *encrypted_mac,
8+
int (*do_cipher) (EVP_CIPHER_CTX *ctx,
9+
unsigned char *out,
10+
const unsigned char *in,
11+
size_t inl))
12+
{
13+
unsigned char calculated_mac[KUZNYECHIK_MAC_MAX_SIZE];
14+
memset(calculated_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
15+
16+
if (EVP_CIPHER_CTX_encrypting(ctx)) {
17+
EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
18+
19+
if (do_cipher(ctx, encrypted_mac, calculated_mac, mac_size) <= 0) {
20+
return -1;
21+
}
22+
} else {
23+
unsigned char expected_mac[KUZNYECHIK_MAC_MAX_SIZE];
24+
25+
memset(expected_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
26+
EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
27+
28+
if (do_cipher(ctx, expected_mac, encrypted_mac, mac_size) <= 0) {
29+
return -1;
30+
}
31+
32+
if (CRYPTO_memcmp(expected_mac, calculated_mac, mac_size) != 0)
33+
return -1;
34+
}
35+
return 0;
36+
}
37+
38+
/*
39+
* UKM = iv|kdf_seed
40+
* */
41+
#define MAX_GOST2015_UKM_SIZE 16
42+
#define KDF_SEED_SIZE 8
43+
int gost2015_get_asn1_params(const ASN1_TYPE *params, size_t ukm_size,
44+
unsigned char *iv, size_t ukm_offset, unsigned char *kdf_seed)
45+
{
46+
int iv_len = 16;
47+
GOST2015_CIPHER_PARAMS *gcp = NULL;
48+
49+
unsigned char *p = NULL;
50+
51+
memset(iv, 0, iv_len);
52+
53+
/* Проверяем тип params */
54+
if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
55+
GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
56+
return 0;
57+
}
58+
59+
p = params->value.sequence->data;
60+
/* Извлекаем структуру параметров */
61+
gcp = d2i_GOST2015_CIPHER_PARAMS(NULL, (const unsigned char **)&p, params->value.sequence->length);
62+
if (gcp == NULL) {
63+
GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
64+
return 0;
65+
}
66+
67+
/* Проверяем длину синхропосылки */
68+
if (gcp->ukm->length != (int)ukm_size) {
69+
GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
70+
GOST2015_CIPHER_PARAMS_free(gcp);
71+
return 0;
72+
}
73+
74+
memcpy(iv, gcp->ukm->data, ukm_offset);
75+
memcpy(kdf_seed, gcp->ukm->data+ukm_offset, KDF_SEED_SIZE);
76+
77+
GOST2015_CIPHER_PARAMS_free(gcp);
78+
return 1;
79+
}
80+
81+
int gost2015_set_asn1_params(ASN1_TYPE *params,
82+
const unsigned char *iv, size_t iv_size, const unsigned char *kdf_seed)
83+
{
84+
GOST2015_CIPHER_PARAMS *gcp = GOST2015_CIPHER_PARAMS_new();
85+
int ret = 0, len = 0;
86+
87+
ASN1_OCTET_STRING *os = NULL;
88+
unsigned char ukm_buf[MAX_GOST2015_UKM_SIZE];
89+
unsigned char *buf = NULL;
90+
91+
if (gcp == NULL) {
92+
GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
93+
return 0;
94+
}
95+
96+
memcpy(ukm_buf, iv, iv_size);
97+
memcpy(ukm_buf+iv_size, kdf_seed, KDF_SEED_SIZE);
98+
99+
if (ASN1_STRING_set(gcp->ukm, ukm_buf, iv_size + KDF_SEED_SIZE) == 0) {
100+
GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
101+
goto end;
102+
}
103+
104+
len = i2d_GOST2015_CIPHER_PARAMS(gcp, &buf);
105+
106+
if (len <= 0
107+
|| (os = ASN1_OCTET_STRING_new()) == NULL
108+
|| ASN1_OCTET_STRING_set(os, buf, len) == 0) {
109+
goto end;
110+
}
111+
112+
ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
113+
ret = 1;
114+
115+
end:
116+
OPENSSL_free(buf);
117+
if (ret <= 0 && os)
118+
ASN1_OCTET_STRING_free(os);
119+
120+
GOST2015_CIPHER_PARAMS_free(gcp);
121+
return ret;
122+
}

gost_gost2015.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef GOST_GOST2015_H
2+
#define GOST_GOST2015_H
3+
4+
#include <openssl/evp.h>
5+
6+
#define MAGMA_MAC_MAX_SIZE 8
7+
#define KUZNYECHIK_MAC_MAX_SIZE 16
8+
9+
int gost2015_final_call(EVP_CIPHER_CTX *ctx, EVP_MD_CTX *omac_ctx, size_t mac_size,
10+
unsigned char *encrypted_mac,
11+
int (*do_cipher) (EVP_CIPHER_CTX *ctx,
12+
unsigned char *out,
13+
const unsigned char *in,
14+
size_t inl));
15+
16+
/* IV is expected to be 16 bytes*/
17+
int gost2015_get_asn1_params(const ASN1_TYPE *params, size_t ukm_size,
18+
unsigned char *iv, size_t ukm_offset, unsigned char *kdf_seed);
19+
20+
int gost2015_set_asn1_params(ASN1_TYPE *params,
21+
const unsigned char *iv, size_t iv_size, const unsigned char *kdf_seed);
22+
#endif

gost_lcl.h

+6
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ typedef struct {
167167

168168
DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
169169

170+
typedef struct {
171+
ASN1_OCTET_STRING *ukm;
172+
} GOST2015_CIPHER_PARAMS;
173+
174+
DECLARE_ASN1_FUNCTIONS(GOST2015_CIPHER_PARAMS)
175+
170176
typedef struct {
171177
ASN1_OCTET_STRING *masked_priv_key;
172178
ASN1_OCTET_STRING *public_key;

0 commit comments

Comments
 (0)