]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_gost2015.c
Magma/Kuznyechik ASN1 parameters and functions
[openssl-gost/engine.git] / gost_gost2015.c
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 }