Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/nettle/gost/gost-wrap.c
Line
Count
Source (jump to first uncovered line)
1
/* GOST 28147-89 (Magma) implementation
2
 *
3
 * Copyright: 2015, 2016 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
4
 * Copyright: 2009-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sublicense, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included
15
 * in all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
26
#if HAVE_CONFIG_H
27
# include "config.h"
28
#endif
29
30
#include <gnutls_int.h>
31
32
#include <string.h>
33
34
#include <nettle/macros.h>
35
#include "gost28147.h"
36
#include <nettle/cfb.h>
37
#include <nettle/memops.h>
38
39
void
40
gost28147_kdf_cryptopro(const struct gost28147_param *param,
41
      const uint8_t * in, const uint8_t * ukm, uint8_t * out)
42
0
{
43
0
  struct gost28147_ctx ctx;
44
0
  int i;
45
46
0
  memcpy(out, in, GOST28147_KEY_SIZE);
47
0
  for (i = 0; i < 8; i++) {
48
0
    uint8_t mask;
49
0
    uint8_t *p;
50
0
    uint8_t iv[GOST28147_BLOCK_SIZE];
51
0
    uint32_t block[2] = { 0, 0 };
52
0
    uint32_t t;
53
54
0
    for (p = out, mask = 1; mask; mask <<= 1) {
55
0
      t = LE_READ_UINT32(p);
56
0
      p += 4;
57
0
      if (mask & ukm[i])
58
0
        block[0] += t;
59
0
      else
60
0
        block[1] += t;
61
0
    }
62
63
0
    LE_WRITE_UINT32(iv + 0, block[0]);
64
0
    LE_WRITE_UINT32(iv + 4, block[1]);
65
66
0
    gost28147_set_key(&ctx, out);
67
0
    gost28147_set_param(&ctx, param);
68
0
    cfb_encrypt(&ctx,
69
0
          (nettle_cipher_func *) gost28147_encrypt_for_cfb,
70
0
          GOST28147_BLOCK_SIZE, iv,
71
0
          GOST28147_KEY_SIZE, out, out);
72
0
  }
73
0
}
74
75
void
76
gost28147_key_wrap_cryptopro(const struct gost28147_param *param,
77
           const uint8_t * kek,
78
           const uint8_t * ukm, size_t ukm_size,
79
           const uint8_t * cek, uint8_t * enc, uint8_t * imit)
80
0
{
81
0
  uint8_t kd[GOST28147_KEY_SIZE];
82
0
  struct gost28147_ctx ctx;
83
0
  struct gost28147_imit_ctx ictx;
84
85
0
  assert(ukm_size >= GOST28147_IMIT_BLOCK_SIZE);
86
87
0
  gost28147_kdf_cryptopro(param, kek, ukm, kd);
88
0
  gost28147_set_key(&ctx, kd);
89
0
  gost28147_set_param(&ctx, param);
90
0
  gost28147_encrypt(&ctx, GOST28147_KEY_SIZE, enc, cek);
91
92
0
  gost28147_imit_set_key(&ictx, GOST28147_KEY_SIZE, kd);
93
0
  gost28147_imit_set_param(&ictx, param);
94
0
  gost28147_imit_set_nonce(&ictx, ukm);
95
0
  gost28147_imit_update(&ictx, GOST28147_KEY_SIZE, cek);
96
0
  gost28147_imit_digest(&ictx, GOST28147_IMIT_DIGEST_SIZE, imit);
97
0
}
98
99
int
100
gost28147_key_unwrap_cryptopro(const struct gost28147_param *param,
101
             const uint8_t * kek,
102
             const uint8_t * ukm, size_t ukm_size,
103
             const uint8_t * enc,
104
             const uint8_t * imit, uint8_t * cek)
105
0
{
106
0
  uint8_t kd[GOST28147_KEY_SIZE];
107
0
  uint8_t mac[GOST28147_IMIT_DIGEST_SIZE];
108
0
  struct gost28147_ctx ctx;
109
0
  struct gost28147_imit_ctx ictx;
110
111
0
  assert(ukm_size >= GOST28147_IMIT_BLOCK_SIZE);
112
113
0
  gost28147_kdf_cryptopro(param, kek, ukm, kd);
114
0
  gost28147_set_key(&ctx, kd);
115
0
  gost28147_set_param(&ctx, param);
116
0
  gost28147_decrypt(&ctx, GOST28147_KEY_SIZE, cek, enc);
117
118
0
  gost28147_imit_set_key(&ictx, GOST28147_KEY_SIZE, kd);
119
0
  gost28147_imit_set_param(&ictx, param);
120
0
  gost28147_imit_set_nonce(&ictx, ukm);
121
0
  gost28147_imit_update(&ictx, GOST28147_KEY_SIZE, cek);
122
0
  gost28147_imit_digest(&ictx, GOST28147_IMIT_DIGEST_SIZE, mac);
123
124
0
  return memeql_sec(mac, imit, GOST28147_IMIT_DIGEST_SIZE);
125
0
}