2 * Copyright (c) 2020 Dmitry Belyavskiy <beldmit@gmail.com>
4 * Contents licensed under the terms of the OpenSSL license
5 * See https://www.openssl.org/source/license.html for details
8 #include "gost_gost2015.h"
9 #include "gost_grasshopper_defines.h"
10 #include "gost_grasshopper_math.h"
11 #include "e_gost_err.h"
13 #include <openssl/rand.h>
15 int gost2015_final_call(EVP_CIPHER_CTX *ctx, EVP_MD_CTX *omac_ctx, size_t mac_size,
16 unsigned char *encrypted_mac,
17 int (*do_cipher) (EVP_CIPHER_CTX *ctx,
19 const unsigned char *in,
22 unsigned char calculated_mac[KUZNYECHIK_MAC_MAX_SIZE];
23 memset(calculated_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
25 if (EVP_CIPHER_CTX_encrypting(ctx)) {
26 EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
28 if (do_cipher(ctx, encrypted_mac, calculated_mac, mac_size) <= 0) {
32 unsigned char expected_mac[KUZNYECHIK_MAC_MAX_SIZE];
34 memset(expected_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
35 EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
37 if (do_cipher(ctx, expected_mac, encrypted_mac, mac_size) <= 0) {
41 if (CRYPTO_memcmp(expected_mac, calculated_mac, mac_size) != 0)
50 #define MAX_GOST2015_UKM_SIZE 16
51 #define KDF_SEED_SIZE 8
52 int gost2015_get_asn1_params(const ASN1_TYPE *params, size_t ukm_size,
53 unsigned char *iv, size_t ukm_offset, unsigned char *kdf_seed)
56 GOST2015_CIPHER_PARAMS *gcp = NULL;
58 unsigned char *p = NULL;
60 memset(iv, 0, iv_len);
62 /* Проверяем тип params */
63 if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
64 GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
68 p = params->value.sequence->data;
69 /* Извлекаем структуру параметров */
70 gcp = d2i_GOST2015_CIPHER_PARAMS(NULL, (const unsigned char **)&p, params->value.sequence->length);
72 GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
76 /* Проверяем длину синхропосылки */
77 if (gcp->ukm->length != (int)ukm_size) {
78 GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
79 GOST2015_CIPHER_PARAMS_free(gcp);
83 memcpy(iv, gcp->ukm->data, ukm_offset);
84 memcpy(kdf_seed, gcp->ukm->data+ukm_offset, KDF_SEED_SIZE);
86 GOST2015_CIPHER_PARAMS_free(gcp);
90 int gost2015_set_asn1_params(ASN1_TYPE *params,
91 const unsigned char *iv, size_t iv_size, const unsigned char *kdf_seed)
93 GOST2015_CIPHER_PARAMS *gcp = GOST2015_CIPHER_PARAMS_new();
96 ASN1_OCTET_STRING *os = NULL;
97 unsigned char ukm_buf[MAX_GOST2015_UKM_SIZE];
98 unsigned char *buf = NULL;
101 GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
105 memcpy(ukm_buf, iv, iv_size);
106 memcpy(ukm_buf+iv_size, kdf_seed, KDF_SEED_SIZE);
108 if (ASN1_STRING_set(gcp->ukm, ukm_buf, iv_size + KDF_SEED_SIZE) == 0) {
109 GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
113 len = i2d_GOST2015_CIPHER_PARAMS(gcp, &buf);
116 || (os = ASN1_OCTET_STRING_new()) == NULL
117 || ASN1_OCTET_STRING_set(os, buf, len) == 0) {
121 ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
127 ASN1_OCTET_STRING_free(os);
129 GOST2015_CIPHER_PARAMS_free(gcp);
133 int gost2015_process_unprotected_attributes(
134 STACK_OF(X509_ATTRIBUTE) *attrs,
135 int encryption, size_t mac_len, unsigned char *final_tag)
137 if (encryption == 0) /*Decrypting*/ {
138 ASN1_OCTET_STRING *osExpectedMac = X509at_get0_data_by_OBJ(attrs,
139 OBJ_txt2obj(OID_GOST_CMS_MAC, 1), -3, V_ASN1_OCTET_STRING);
141 if (!osExpectedMac || osExpectedMac->length != (int)mac_len)
144 memcpy(final_tag, osExpectedMac->data, osExpectedMac->length);
148 return (X509at_add1_attr_by_OBJ(&attrs,
149 OBJ_txt2obj(OID_GOST_CMS_MAC, 1),
150 V_ASN1_OCTET_STRING, final_tag,
151 mac_len) == NULL) ? -1 : 1;
156 int gost2015_acpkm_omac_init(int nid, int enc, const unsigned char *inkey,
157 EVP_MD_CTX *omac_ctx,
158 unsigned char *outkey, unsigned char *kdf_seed)
161 unsigned char keys[64];
162 const EVP_MD *md = EVP_get_digestbynid(nid);
169 if (RAND_bytes(kdf_seed, 8) != 1)
173 if (gost_kdftree2012_256(keys, 64, inkey, 32,
174 (const unsigned char *)"kdf tree", 8, kdf_seed, 8, 1) <= 0)
177 mac_key = EVP_PKEY_new_mac_key(nid, NULL, keys+32, 32);
182 if (EVP_DigestInit_ex(omac_ctx, md, NULL) <= 0 ||
183 EVP_DigestSignInit(omac_ctx, NULL, md, NULL, mac_key) <= 0)
186 memcpy(outkey, keys, 32);
190 EVP_PKEY_free(mac_key);
191 OPENSSL_cleanse(keys, sizeof(keys));
196 int init_zero_kdf_seed(unsigned char *kdf_seed)
198 int is_zero_kdfseed = 1, i;
199 for (i = 0; i < 8; i++) {
200 if (kdf_seed[i] != 0)
204 return is_zero_kdfseed ? RAND_bytes(kdf_seed, 8) : 1;
207 void gost_mgm128_init(mgm128_context *ctx, void *key, block128_f block, mul128_f mul_gf, int blen)
209 memset(ctx, 0, sizeof(*ctx));
211 ctx->mul_gf = mul_gf;
213 ctx->blocklen = blen;
215 /* some precalculations place here
220 int gost_mgm128_setiv(mgm128_context *ctx, const unsigned char *iv,
223 ctx->len.u[0] = 0; /* AAD length */
224 ctx->len.u[1] = 0; /* message length */
233 memcpy(ctx->nonce.c, iv, ctx->blocklen);
234 ctx->nonce.c[0] &= 0x7f; /* IV - random vector, but 1st bit should be 0 */
238 int gost_mgm128_aad(mgm128_context *ctx, const unsigned char *aad,
243 uint64_t alen = ctx->len.u[0];
244 block128_f block = ctx->block;
245 mul128_f mul_gf = ctx->mul_gf;
246 void *key = ctx->key;
247 int bl = ctx->blocklen;
250 GOSTerr(GOST_F_GOST_MGM128_AAD,
256 ctx->nonce.c[0] |= 0x80;
257 (*block) (ctx->nonce.c, ctx->Zi.c, key); // Z_1 = E_K(1 || nonce)
261 if (alen > ((ossl_uintmax_t)(1) << (bl * 4 - 3)) || // < 2^(n/2) (len stores in bytes)
262 (sizeof(len) == 8 && alen < len)) {
263 GOSTerr(GOST_F_GOST_MGM128_AAD,
264 GOST_R_DATA_TOO_LARGE);
267 ctx->len.u[0] = alen;
271 /* Finalize partial_data */
273 ctx->ACi.c[n] = *(aad++);
278 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
279 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->ACi.u); // H_i (x) A_i
280 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
281 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
282 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
289 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
290 mul_gf(ctx->mul.u, ctx->Hi.u, (uint64_t *)aad); // H_i (x) A_i
291 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
292 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
293 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
298 n = (unsigned int)len;
299 for (i = 0; i < len; ++i)
300 ctx->ACi.c[i] = aad[i];
307 int gost_mgm128_encrypt(mgm128_context *ctx, const unsigned char *in,
308 unsigned char *out, size_t len)
311 unsigned int n, mres;
312 uint64_t alen = ctx->len.u[0];
313 uint64_t mlen = ctx->len.u[1];
314 block128_f block = ctx->block;
315 mul128_f mul_gf = ctx->mul_gf;
316 void *key = ctx->key;
317 int bl = ctx->blocklen;
321 ctx->nonce.c[0] |= 0x80;
322 (*block) (ctx->nonce.c, ctx->Zi.c, key); // Z_1 = E_K(1 || nonce)
324 ctx->nonce.c[0] &= 0x7f;
325 (*block) (ctx->nonce.c, ctx->Yi.c, key); // Y_1 = E_K(0 || nonce)
330 if (mlen > ((ossl_uintmax_t)(1) << (bl * 4 - 3)) || // < 2^(n/2) (len stores in bytes)
331 (sizeof(len) == 8 && mlen < len) ||
332 (mlen + alen) > ((ossl_uintmax_t)(1) << (bl * 4 - 3))) {
333 GOSTerr(GOST_F_GOST_MGM128_ENCRYPT,
334 GOST_R_DATA_TOO_LARGE);
337 ctx->len.u[1] = mlen;
342 /* First call to encrypt finalizes AAD */
343 memset(ctx->ACi.c + ctx->ares, 0, bl - ctx->ares);
344 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
345 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->ACi.u); // H_i (x) A_i
346 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
347 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
348 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
354 // TODO: replace with full blocks processing
355 for (i = 0; i < len; ++i) {
357 (*block) (ctx->Yi.c, ctx->EKi.c, key); // E_K(Y_i)
358 inc_counter(ctx->Yi.c + bl / 2, bl / 2); // Y_i = incr_r(Y_{i-1})
360 ctx->ACi.c[n] = out[i] = in[i] ^ ctx->EKi.c[n]; // C_i = P_i (xor) E_K(Y_i)
361 mres = n = (n + 1) % bl;
363 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
364 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->ACi.u); // H_i (x) C_i
365 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
366 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
367 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
375 int gost_mgm128_decrypt(mgm128_context *ctx, const unsigned char *in,
376 unsigned char *out, size_t len)
379 unsigned int n, mres;
380 uint64_t alen = ctx->len.u[0];
381 uint64_t mlen = ctx->len.u[1];
382 block128_f block = ctx->block;
383 mul128_f mul_gf = ctx->mul_gf;
384 void *key = ctx->key;
385 int bl = ctx->blocklen;
388 ctx->nonce.c[0] &= 0x7f;
389 (*block) (ctx->nonce.c, ctx->Yi.c, key); // Y_1 = E_K(0 || nonce)
393 if (mlen > ((ossl_uintmax_t)(1) << (bl * 4 - 3)) || // < 2^(n/2) (len stores in bytes)
394 (sizeof(len) == 8 && mlen < len) ||
395 (mlen + alen) > ((ossl_uintmax_t)(1) << (bl * 4 - 3))) {
396 GOSTerr(GOST_F_GOST_MGM128_DECRYPT,
397 GOST_R_DATA_TOO_LARGE);
400 ctx->len.u[1] = mlen;
405 /* First call to encrypt finalizes AAD */
406 memset(ctx->ACi.c + ctx->ares, 0, bl - ctx->ares);
407 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
408 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->ACi.u); // H_i (x) A_i
409 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
410 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
411 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
417 // TODO: replace with full blocks processing
418 for (i = 0; i < len; ++i) {
421 (*block) (ctx->Yi.c, ctx->EKi.c, key); // E_K(Y_i)
422 inc_counter(ctx->Yi.c + bl / 2, bl / 2); // Y_i = incr_r(Y_{i-1})
424 ctx->ACi.c[n] = c = in[i];
425 out[i] = c ^ ctx->EKi.c[n]; // P_i = C_i (xor) E_K(Y_i)
426 mres = n = (n + 1) % bl;
428 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
429 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->ACi.u); // H_i (x) C_i
430 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
431 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
432 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
440 int gost_mgm128_finish(mgm128_context *ctx, const unsigned char *tag,
443 uint64_t alen = ctx->len.u[0] << 3;
444 uint64_t clen = ctx->len.u[1] << 3;
445 block128_f block = ctx->block;
446 mul128_f mul_gf = ctx->mul_gf;
447 void *key = ctx->key;
448 int bl = ctx->blocklen;
450 if (ctx->mres || ctx->ares) {
451 /* First call to encrypt finalizes AAD/ENC */
452 memset(ctx->ACi.c + ctx->ares + ctx->mres, 0, bl - (ctx->ares + ctx->mres));
453 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
454 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->ACi.u); // H_i (x) [A_i or C_i]
455 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
456 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
457 inc_counter(ctx->Zi.c, bl / 2); // Z_{i+1} = incr_l(Z_i)
461 alen = BSWAP64(alen);
462 clen = BSWAP64(clen);
465 ctx->len.u[0] = alen;
466 ctx->len.u[1] = clen;
469 ctx->len.u[0] = (alen >> 32) | clen;
471 ctx->len.u[0] = (alen << 32) | clen;
476 (*block) (ctx->Zi.c, ctx->Hi.c, key); // H_i = E_K(Z_i)
477 mul_gf(ctx->mul.u, ctx->Hi.u, ctx->len.u); // H_i (x) (len(A) || len(C))
478 grasshopper_plus128((grasshopper_w128_t*)ctx->sum.u, // acc XOR
479 (grasshopper_w128_t*)ctx->sum.u, (grasshopper_w128_t*)ctx->mul.u);
480 (*block) (ctx->sum.c, ctx->tag.c, key); // E_K(sum)
482 if (tag && len <= sizeof(ctx->tag))
483 return CRYPTO_memcmp(ctx->tag.c, tag, len); // MSB_S(E_K(sum))
488 void gost_mgm128_tag(mgm128_context *ctx, unsigned char *tag, size_t len)
490 gost_mgm128_finish(ctx, NULL, 0);
491 memcpy(tag, ctx->tag.c,
492 len <= sizeof(ctx->tag.c) ? len : sizeof(ctx->tag.c));