]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_gost2015.c
tcl_tests: ca.try: Ignore openssl crl exit status for 'corrupted CRL' test
[openssl-gost/engine.git] / gost_gost2015.c
1 /*
2  * Copyright (c) 2020 Dmitry Belyavskiy <beldmit@gmail.com>
3  *
4  * Contents licensed under the terms of the OpenSSL license
5  * See https://www.openssl.org/source/license.html for details
6  */
7 #include "gost_lcl.h"
8 #include "gost_gost2015.h"
9 #include "gost_grasshopper_defines.h"
10 #include "gost_grasshopper_math.h"
11 #include "e_gost_err.h"
12 #include <string.h>
13 #include <openssl/rand.h>
14
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,
18     unsigned char *out,
19     const unsigned char *in,
20     size_t inl))
21 {
22     unsigned char calculated_mac[KUZNYECHIK_MAC_MAX_SIZE];
23     memset(calculated_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
24
25     if (EVP_CIPHER_CTX_encrypting(ctx)) {
26         EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
27
28         if (do_cipher(ctx, encrypted_mac, calculated_mac, mac_size) <= 0) {
29             return -1;
30         }
31     } else {
32         unsigned char expected_mac[KUZNYECHIK_MAC_MAX_SIZE];
33
34         memset(expected_mac, 0, KUZNYECHIK_MAC_MAX_SIZE);
35         EVP_DigestSignFinal(omac_ctx, calculated_mac, &mac_size);
36
37         if (do_cipher(ctx, expected_mac, encrypted_mac, mac_size) <= 0) {
38             return -1;
39         }
40
41         if (CRYPTO_memcmp(expected_mac, calculated_mac, mac_size) != 0)
42             return -1;
43     }
44     return 0;
45 }
46
47 /*
48  * UKM = iv|kdf_seed
49  * */
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)
54 {
55     int iv_len = 16;
56     GOST2015_CIPHER_PARAMS *gcp = NULL;
57
58     unsigned char *p = NULL;
59
60     memset(iv, 0, iv_len);
61
62     /* Проверяем тип params */
63     if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
64         GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
65         return 0;
66     }
67
68     p = params->value.sequence->data;
69     /* Извлекаем структуру параметров */
70     gcp = d2i_GOST2015_CIPHER_PARAMS(NULL, (const unsigned char **)&p, params->value.sequence->length);
71     if (gcp == NULL) {
72         GOSTerr(GOST_F_GOST2015_GET_ASN1_PARAMS, GOST_R_INVALID_CIPHER_PARAMS);
73         return 0;
74     }
75
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);
80         return 0;
81     }
82
83     memcpy(iv, gcp->ukm->data, ukm_offset);
84     memcpy(kdf_seed, gcp->ukm->data+ukm_offset, KDF_SEED_SIZE);
85
86     GOST2015_CIPHER_PARAMS_free(gcp);
87     return 1;
88 }
89
90 int gost2015_set_asn1_params(ASN1_TYPE *params,
91     const unsigned char *iv, size_t iv_size, const unsigned char *kdf_seed)
92 {
93     GOST2015_CIPHER_PARAMS *gcp = GOST2015_CIPHER_PARAMS_new();
94     int ret = 0, len = 0;
95
96     ASN1_OCTET_STRING *os = NULL;
97     unsigned char ukm_buf[MAX_GOST2015_UKM_SIZE];
98     unsigned char *buf = NULL;
99
100     if (gcp == NULL) {
101         GOSTerr(GOST_F_GOST2015_SET_ASN1_PARAMS, ERR_R_MALLOC_FAILURE);
102         return 0;
103     }
104
105     memcpy(ukm_buf, iv, iv_size);
106     memcpy(ukm_buf+iv_size, kdf_seed, KDF_SEED_SIZE);
107
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);
110         goto end;
111     }
112
113     len = i2d_GOST2015_CIPHER_PARAMS(gcp, &buf);
114
115     if (len <= 0
116        || (os = ASN1_OCTET_STRING_new()) == NULL
117        || ASN1_OCTET_STRING_set(os, buf, len) == 0) {
118         goto end;
119   }
120
121     ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
122     ret = 1;
123
124 end:
125     OPENSSL_free(buf);
126     if (ret <= 0 && os)
127         ASN1_OCTET_STRING_free(os);
128
129     GOST2015_CIPHER_PARAMS_free(gcp);
130     return ret;
131 }
132
133 int gost2015_process_unprotected_attributes(
134     STACK_OF(X509_ATTRIBUTE) *attrs,
135     int encryption, size_t mac_len, unsigned char *final_tag)
136 {
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);
140
141         if (!osExpectedMac || osExpectedMac->length != (int)mac_len)
142             return -1;
143
144         memcpy(final_tag, osExpectedMac->data, osExpectedMac->length);
145     } else {
146         if (attrs == NULL)
147             return -1;
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;
152     }
153     return 1;
154 }
155
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)
159 {
160     int ret = 0;
161     unsigned char keys[64];
162     const EVP_MD *md = EVP_get_digestbynid(nid);
163     EVP_PKEY *mac_key;
164
165     if (md == NULL)
166         return 0;
167
168     if (enc) {
169         if (RAND_bytes(kdf_seed, 8) != 1)
170             return 0;
171     }
172
173     if (gost_kdftree2012_256(keys, 64, inkey, 32,
174        (const unsigned char *)"kdf tree", 8, kdf_seed, 8, 1) <= 0)
175         return 0;
176
177     mac_key = EVP_PKEY_new_mac_key(nid, NULL, keys+32, 32);
178
179     if (mac_key == NULL)
180         goto end;
181
182     if (EVP_DigestInit_ex(omac_ctx, md, NULL) <= 0 ||
183        EVP_DigestSignInit(omac_ctx, NULL, md, NULL, mac_key) <= 0)
184         goto end;
185
186     memcpy(outkey, keys, 32);
187
188     ret = 1;
189 end:
190     EVP_PKEY_free(mac_key);
191     OPENSSL_cleanse(keys, sizeof(keys));
192
193     return ret;
194 }
195
196 int init_zero_kdf_seed(unsigned char *kdf_seed)
197 {
198     int is_zero_kdfseed = 1, i;
199     for (i = 0; i < 8; i++) {
200         if (kdf_seed[i] != 0)
201             is_zero_kdfseed = 0;
202     }
203
204     return is_zero_kdfseed ? RAND_bytes(kdf_seed, 8) : 1;
205 }
206
207 void gost_mgm128_init(mgm128_context *ctx, void *key, block128_f block, mul128_f mul_gf, int blen)
208 {
209     memset(ctx, 0, sizeof(*ctx));
210     ctx->block = block;
211     ctx->mul_gf = mul_gf;
212     ctx->key = key;
213     ctx->blocklen = blen;
214
215     /* some precalculations place here
216      *
217      */
218 }
219
220 int gost_mgm128_setiv(mgm128_context *ctx, const unsigned char *iv,
221                          size_t len)
222 {
223     ctx->len.u[0] = 0;          /* AAD length */
224     ctx->len.u[1] = 0;          /* message length */
225     ctx->ares = 0;
226     ctx->mres = 0;
227
228     ctx->ACi.u[0] = 0;
229     ctx->ACi.u[1] = 0;
230     ctx->sum.u[0] = 0;
231     ctx->sum.u[1] = 0;
232
233     memcpy(ctx->nonce.c, iv, ctx->blocklen);
234     ctx->nonce.c[0] &= 0x7f;    /* IV - random vector, but 1st bit should be 0 */
235     return 1;
236 }
237
238 int gost_mgm128_aad(mgm128_context *ctx, const unsigned char *aad,
239                       size_t len)
240 {
241     size_t i;
242     unsigned int n;
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;
248
249     if (ctx->len.u[1]) {
250         GOSTerr(GOST_F_GOST_MGM128_AAD,
251                 GOST_R_BAD_ORDER);
252         return -2;
253     }
254
255     if (alen == 0) {
256         ctx->nonce.c[0] |= 0x80;
257         (*block) (ctx->nonce.c, ctx->Zi.c, key);    // Z_1 = E_K(1 || nonce)
258     }
259
260     alen += len;
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);
265             return -1;
266         }
267     ctx->len.u[0] = alen;
268
269     n = ctx->ares;
270     if (n) {
271         /* Finalize partial_data */
272         while (n && len) {
273             ctx->ACi.c[n] = *(aad++);
274             --len;
275             n = (n + 1) % bl;
276         }
277         if (n == 0) {
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)
283         } else {
284             ctx->ares = n;
285             return 0;
286         }
287     }
288     while (len >= bl) {
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)
294         aad += bl;
295         len -= bl;
296     }
297     if (len) {
298         n = (unsigned int)len;
299         for (i = 0; i < len; ++i)
300             ctx->ACi.c[i] = aad[i];
301     }
302
303     ctx->ares = n;
304     return 0;
305 }
306
307 int gost_mgm128_encrypt(mgm128_context *ctx, const unsigned char *in,
308                           unsigned char *out, size_t len)
309 {
310     size_t i;
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;
318
319     if (mlen == 0) {
320         if (alen == 0) {
321             ctx->nonce.c[0] |= 0x80;
322             (*block) (ctx->nonce.c, ctx->Zi.c, key);    // Z_1 = E_K(1 || nonce)
323         }
324         ctx->nonce.c[0] &= 0x7f;
325         (*block) (ctx->nonce.c, ctx->Yi.c, key);    // Y_1 = E_K(0 || nonce)
326     }
327
328     mlen += len;
329
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);
335             return -1;
336         }
337     ctx->len.u[1] = mlen;
338
339     mres = ctx->mres;
340
341     if (ctx->ares) {
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)
349
350         ctx->ares = 0;
351     }
352
353     n = mres % bl;
354     // TODO: replace with full blocks processing
355     for (i = 0; i < len; ++i) {
356         if (n == 0) {
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})
359         }
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;
362         if (n == 0) {
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)
368         }
369     }
370
371     ctx->mres = mres;
372     return 0;
373 }
374
375 int gost_mgm128_decrypt(mgm128_context *ctx, const unsigned char *in,
376                           unsigned char *out, size_t len)
377 {
378     size_t i;
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;
386
387     if (mlen == 0) {
388         ctx->nonce.c[0] &= 0x7f;
389         (*block) (ctx->nonce.c, ctx->Yi.c, key);  // Y_1 = E_K(0 || nonce)
390     }
391
392     mlen += len;
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);
398             return -1;
399         }
400     ctx->len.u[1] = mlen;
401
402     mres = ctx->mres;
403
404     if (ctx->ares) {
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)
412
413         ctx->ares = 0;
414     }
415
416     n = mres % bl;
417     // TODO: replace with full blocks processing
418     for (i = 0; i < len; ++i) {
419         uint8_t c;
420         if (n == 0) {
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})
423         }
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;
427         if (n == 0) {
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)
433         }
434     }
435
436     ctx->mres = mres;
437     return 0;
438 }
439
440 int gost_mgm128_finish(mgm128_context *ctx, const unsigned char *tag,
441                          size_t len)
442 {
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;
449
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)
458     }
459
460 #ifdef L_ENDIAN
461     alen = BSWAP64(alen);
462     clen = BSWAP64(clen);
463 #endif
464     if (bl == 16) {
465         ctx->len.u[0] = alen;
466         ctx->len.u[1] = clen;
467     } else {
468 #ifdef L_ENDIAN
469         ctx->len.u[0] = (alen >> 32) | clen;
470 #else
471         ctx->len.u[0] = (alen << 32) | clen;
472 #endif
473         ctx->len.u[1] = 0;
474     }
475
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)
481
482     if (tag && len <= sizeof(ctx->tag))
483         return CRYPTO_memcmp(ctx->tag.c, tag, len);         // MSB_S(E_K(sum))
484     else
485         return -1;
486 }
487
488 void gost_mgm128_tag(mgm128_context *ctx, unsigned char *tag, size_t len)
489 {
490     gost_mgm128_finish(ctx, NULL, 0);
491     memcpy(tag, ctx->tag.c,
492            len <= sizeof(ctx->tag.c) ? len : sizeof(ctx->tag.c));
493 }