Coverage Report

Created: 2024-06-28 06:39

/src/nettle-with-mini-gmp/gcm.c
Line
Count
Source
1
/* gcm.c
2
3
   Galois counter mode, specified by NIST,
4
   http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
5
6
   See also the gcm paper at
7
   http://www.cryptobarn.com/papers/gcm-spec.pdf.
8
9
   Copyright (C) 2011 Katholieke Universiteit Leuven
10
   Copyright (C) 2011, 2013, 2018 Niels Möller
11
   Copyright (C) 2018 Red Hat, Inc.
12
   
13
   Contributed by Nikos Mavrogiannopoulos
14
15
   This file is part of GNU Nettle.
16
17
   GNU Nettle is free software: you can redistribute it and/or
18
   modify it under the terms of either:
19
20
     * the GNU Lesser General Public License as published by the Free
21
       Software Foundation; either version 3 of the License, or (at your
22
       option) any later version.
23
24
   or
25
26
     * the GNU General Public License as published by the Free
27
       Software Foundation; either version 2 of the License, or (at your
28
       option) any later version.
29
30
   or both in parallel, as here.
31
32
   GNU Nettle is distributed in the hope that it will be useful,
33
   but WITHOUT ANY WARRANTY; without even the implied warranty of
34
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
35
   General Public License for more details.
36
37
   You should have received copies of the GNU General Public License and
38
   the GNU Lesser General Public License along with this program.  If
39
   not, see http://www.gnu.org/licenses/.
40
*/
41
42
#if HAVE_CONFIG_H
43
# include "config.h"
44
#endif
45
46
#include <assert.h>
47
#include <stdlib.h>
48
#include <string.h>
49
50
#include "gcm.h"
51
52
#include "ghash-internal.h"
53
#include "memxor.h"
54
#include "nettle-internal.h"
55
#include "macros.h"
56
#include "ctr-internal.h"
57
#include "block-internal.h"
58
#include "bswap-internal.h"
59
60
/* Initialization of GCM.
61
 * @ctx: The context of GCM
62
 * @cipher: The context of the underlying block cipher
63
 * @f: The underlying cipher encryption function
64
 */
65
void
66
gcm_set_key(struct gcm_key *key,
67
      const void *cipher, nettle_cipher_func *f)
68
2.43k
{
69
2.43k
  static const union nettle_block16 zero_block;
70
2.43k
  union nettle_block16 key_block;
71
2.43k
  f (cipher, GCM_BLOCK_SIZE, key_block.b, zero_block.b);
72
73
2.43k
  _ghash_set_key (key, &key_block);
74
2.43k
}
75
76
/* Call _ghash_update, with zero padding of any partial final block. */
77
static void
78
gcm_hash (const struct gcm_key *key, union nettle_block16 *x,
79
43.6k
    size_t length, const uint8_t *data) {
80
43.6k
  data = _ghash_update (key, x, length / GCM_BLOCK_SIZE, data);
81
43.6k
  length &= (GCM_BLOCK_SIZE - 1);
82
43.6k
  if (length > 0)
83
4.39k
    {
84
4.39k
      union nettle_block16 block;
85
4.39k
      block16_zero (&block);
86
4.39k
      memcpy (block.b, data, length);
87
4.39k
      _ghash_update (key, x, 1, block.b);
88
4.39k
    }
89
43.6k
}
90
91
static void
92
gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x,
93
         uint64_t auth_size, uint64_t data_size)
94
4.52k
{
95
4.52k
  union nettle_block16 buffer;
96
97
4.52k
  data_size *= 8;
98
4.52k
  auth_size *= 8;
99
100
4.52k
  buffer.u64[0] = bswap64_if_le (auth_size);
101
4.52k
  buffer.u64[1] = bswap64_if_le (data_size);
102
103
4.52k
  _ghash_update (key, x, 1, buffer.b);
104
4.52k
}
105
106
/* NOTE: The key is needed only if length != GCM_IV_SIZE */
107
void
108
gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
109
     size_t length, const uint8_t *iv)
110
2.43k
{
111
2.43k
  if (length == GCM_IV_SIZE)
112
331
    {
113
331
      memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4);
114
331
      ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0;
115
331
      ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0;
116
331
      ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0;
117
331
      ctx->iv.b[GCM_BLOCK_SIZE - 1] = 1;
118
331
    }
119
2.09k
  else
120
2.09k
    {
121
2.09k
      block16_zero(&ctx->iv);
122
2.09k
      gcm_hash(key, &ctx->iv, length, iv);
123
2.09k
      gcm_hash_sizes(key, &ctx->iv, 0, length);
124
2.09k
    }
125
126
2.43k
  ctx->ctr = ctx->iv;
127
  /* Increment the rightmost 32 bits. */
128
2.43k
  INCREMENT (4, ctx->ctr.b + GCM_BLOCK_SIZE - 4);
129
130
  /* Reset the rest of the message-dependent state. */
131
2.43k
  block16_zero(&ctx->x);
132
2.43k
  ctx->auth_size = ctx->data_size = 0;
133
2.43k
}
134
135
void
136
gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
137
     size_t length, const uint8_t *data)
138
7.81k
{
139
7.81k
  assert(ctx->auth_size % GCM_BLOCK_SIZE == 0);
140
7.81k
  assert(ctx->data_size == 0);
141
142
7.81k
  gcm_hash(key, &ctx->x, length, data);
143
144
7.81k
  ctx->auth_size += length;
145
7.81k
}
146
147
static nettle_fill16_func gcm_fill;
148
#if WORDS_BIGENDIAN
149
static void
150
gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
151
{
152
  uint64_t hi, mid;
153
  uint32_t lo;
154
  size_t i;
155
  hi = READ_UINT64(ctr);
156
  mid = (uint64_t) READ_UINT32(ctr + 8) << 32;
157
  lo = READ_UINT32(ctr + 12);
158
159
  for (i = 0; i < blocks; i++)
160
    {
161
      buffer[i].u64[0] = hi;
162
      buffer[i].u64[1] = mid + lo++;
163
    }
164
  WRITE_UINT32(ctr + 12, lo);
165
166
}
167
#elif HAVE_BUILTIN_BSWAP64
168
/* Assume __builtin_bswap32 is also available */
169
static void
170
gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
171
35.0k
{
172
35.0k
  uint64_t hi, mid;
173
35.0k
  uint32_t lo;
174
35.0k
  size_t i;
175
35.0k
  hi = LE_READ_UINT64(ctr);
176
35.0k
  mid = LE_READ_UINT32(ctr + 8);
177
35.0k
  lo = READ_UINT32(ctr + 12);
178
179
61.3k
  for (i = 0; i < blocks; i++)
180
26.2k
    {
181
26.2k
      buffer[i].u64[0] = hi;
182
26.2k
      buffer[i].u64[1] = mid + ((uint64_t)__builtin_bswap32(lo) << 32);
183
26.2k
      lo++;
184
26.2k
    }
185
35.0k
  WRITE_UINT32(ctr + 12, lo);
186
35.0k
}
187
#else
188
static void
189
gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
190
{
191
  uint32_t c;
192
193
  c = READ_UINT32(ctr + GCM_BLOCK_SIZE - 4);
194
195
  for (; blocks-- > 0; buffer++, c++)
196
    {
197
      memcpy(buffer->b, ctr, GCM_BLOCK_SIZE - 4);
198
      WRITE_UINT32(buffer->b + GCM_BLOCK_SIZE - 4, c);
199
    }
200
201
  WRITE_UINT32(ctr + GCM_BLOCK_SIZE - 4, c);
202
}
203
#endif
204
205
void
206
gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key,
207
       const void *cipher, nettle_cipher_func *f,
208
       size_t length, uint8_t *dst, const uint8_t *src)
209
19.1k
{
210
19.1k
  assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
211
212
19.1k
  _nettle_ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src);
213
19.1k
  gcm_hash(key, &ctx->x, length, dst);
214
215
19.1k
  ctx->data_size += length;
216
19.1k
}
217
218
void
219
gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
220
      const void *cipher, nettle_cipher_func *f,
221
      size_t length, uint8_t *dst, const uint8_t *src)
222
14.5k
{
223
14.5k
  assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
224
225
14.5k
  gcm_hash(key, &ctx->x, length, src);
226
14.5k
  _nettle_ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src);
227
228
14.5k
  ctx->data_size += length;
229
14.5k
}
230
231
void
232
gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
233
     const void *cipher, nettle_cipher_func *f,
234
     size_t length, uint8_t *digest)
235
2.43k
{
236
2.43k
  union nettle_block16 buffer;
237
238
2.43k
  assert (length <= GCM_BLOCK_SIZE);
239
240
2.43k
  gcm_hash_sizes(key, &ctx->x, ctx->auth_size, ctx->data_size);
241
242
2.43k
  f (cipher, GCM_BLOCK_SIZE, buffer.b, ctx->iv.b);
243
2.43k
  block16_xor (&buffer, &ctx->x);
244
2.43k
  memcpy (digest, buffer.b, length);
245
246
2.43k
  return;
247
2.43k
}