Coverage Report

Created: 2024-02-25 06:16

/src/nettle-with-libgmp/ocb.c
Line
Count
Source (jump to first uncovered line)
1
/* ocb.c
2
3
   OCB AEAD mode, RFC 7253
4
5
   Copyright (C) 2021 Niels Möller
6
7
   This file is part of GNU Nettle.
8
9
   GNU Nettle is free software: you can redistribute it and/or
10
   modify it under the terms of either:
11
12
     * the GNU Lesser General Public License as published by the Free
13
       Software Foundation; either version 3 of the License, or (at your
14
       option) any later version.
15
16
   or
17
18
     * the GNU General Public License as published by the Free
19
       Software Foundation; either version 2 of the License, or (at your
20
       option) any later version.
21
22
   or both in parallel, as here.
23
24
   GNU Nettle is distributed in the hope that it will be useful,
25
   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
   General Public License for more details.
28
29
   You should have received copies of the GNU General Public License and
30
   the GNU Lesser General Public License along with this program.  If
31
   not, see http://www.gnu.org/licenses/.
32
*/
33
34
#if HAVE_CONFIG_H
35
# include "config.h"
36
#endif
37
38
#include <string.h>
39
40
#include "ocb.h"
41
#include "block-internal.h"
42
#include "bswap-internal.h"
43
#include "memops.h"
44
45
4.41k
#define OCB_MAX_BLOCKS 16
46
47
/* Returns 64 bits from the concatenation (u0, u1), starting from bit offset. */
48
static inline uint64_t
49
extract(uint64_t u0, uint64_t u1, unsigned offset)
50
2.53k
{
51
2.53k
  if (offset == 0)
52
792
    return u0;
53
1.73k
  u0 = bswap64_if_le(u0);
54
1.73k
  u1 = bswap64_if_le(u1);
55
1.73k
  return bswap64_if_le((u0 << offset) | (u1 >> (64 - offset)));
56
2.53k
}
57
58
void
59
ocb_set_key (struct ocb_key *key, const void *cipher, nettle_cipher_func *f)
60
1.26k
{
61
1.26k
  static const union nettle_block16 zero_block;
62
1.26k
  f (cipher, OCB_BLOCK_SIZE, key->L[0].b, zero_block.b);
63
1.26k
  block16_mulx_be (&key->L[1], &key->L[0]);
64
1.26k
  block16_mulx_be (&key->L[2], &key->L[1]);
65
1.26k
}
66
67
/* Add x^k L[2], where k is the number of trailing zero bits in i. */
68
static void
69
update_offset(const struct ocb_key *key,
70
        union nettle_block16 *offset, size_t i)
71
912
{
72
912
  if (i & 1)
73
0
    block16_xor (offset, &key->L[2]);
74
912
  else
75
912
    {
76
912
      assert (i > 0);
77
912
      union nettle_block16 diff;
78
912
      block16_mulx_be (&diff, &key->L[2]);
79
1.40k
      for (i >>= 1; !(i&1); i >>= 1)
80
497
  block16_mulx_be (&diff, &diff);
81
82
912
      block16_xor (offset, &diff);
83
912
    }
84
912
}
85
86
static void
87
pad_block (union nettle_block16 *block, size_t length, const uint8_t *data)
88
1.79k
{
89
1.79k
  memcpy (block->b, data, length);
90
1.79k
  block->b[length] = 0x80;
91
1.79k
  memset (block->b + length + 1, 0, OCB_BLOCK_SIZE - 1 - length);
92
1.79k
}
93
94
void
95
ocb_set_nonce (struct ocb_ctx *ctx,
96
         const void *cipher, nettle_cipher_func *f,
97
         size_t tag_length,
98
         size_t nonce_length, const uint8_t *nonce)
99
1.26k
{
100
1.26k
  union nettle_block16 top;
101
1.26k
  uint64_t stretch;
102
103
1.26k
  unsigned bottom;
104
1.26k
  assert (nonce_length < 16);
105
1.26k
  assert (tag_length > 0);
106
1.26k
  assert (tag_length <= 16);
107
108
  /* Bit size, or zero for tag_length == 16 */
109
1.26k
  top.b[0] = (tag_length & 15) << 4;
110
1.26k
  memset (top.b + 1, 0, 15 - nonce_length);
111
1.26k
  top.b[15 - nonce_length] |= 1;
112
1.26k
  memcpy (top.b + 16 - nonce_length, nonce, nonce_length);
113
1.26k
  bottom = top.b[15] & 0x3f;
114
1.26k
  top.b[15] &= 0xc0;
115
116
1.26k
  f (cipher, OCB_BLOCK_SIZE, top.b, top.b);
117
118
1.26k
  stretch = top.u64[0];
119
#if WORDS_BIGENDIAN
120
  stretch ^= (top.u64[0] << 8) | (top.u64[1] >> 56);
121
#else
122
1.26k
  stretch ^= (top.u64[0] >> 8) | (top.u64[1] << 56);
123
1.26k
#endif
124
125
1.26k
  ctx->initial.u64[0] = extract(top.u64[0], top.u64[1], bottom);
126
1.26k
  ctx->initial.u64[1] = extract(top.u64[1], stretch, bottom);
127
1.26k
  ctx->sum.u64[0] = ctx->sum.u64[1] = 0;
128
1.26k
  ctx->checksum.u64[0] = ctx->checksum.u64[1] = 0;
129
130
1.26k
  ctx->data_count = ctx->message_count = 0;
131
1.26k
}
132
133
static void
134
ocb_fill_n (const struct ocb_key *key,
135
      union nettle_block16 *offset, size_t count,
136
      size_t n, union nettle_block16 *o)
137
3.68k
{
138
3.68k
  assert (n > 0);
139
3.68k
  union nettle_block16 *prev;
140
3.68k
  if (count & 1)
141
1.38k
    prev = offset;
142
2.30k
  else
143
2.30k
    {
144
      /* Do a single block to align block count. */
145
2.30k
      count++; /* Always odd. */
146
2.30k
      block16_xor (offset, &key->L[2]);
147
2.30k
      block16_set (&o[0], offset);
148
2.30k
      prev = o;
149
2.30k
      n--; o++;
150
2.30k
    }
151
152
13.6k
  for (; n >= 2; n -= 2, o += 2)
153
9.96k
    {
154
9.96k
      size_t i;
155
9.96k
      count += 2; /* Always odd. */
156
157
      /* Based on trailing zeros of ctx->message_count - 1, the
158
         initial shift below discards a one bit. */
159
9.96k
      block16_mulx_be (&o[0], &key->L[2]);
160
18.0k
      for (i = count >> 1; !(i&1); i >>= 1)
161
8.12k
  block16_mulx_be (&o[0], &o[0]);
162
163
9.96k
      block16_xor (&o[0], prev);
164
9.96k
      block16_xor3 (&o[1], &o[0], &key->L[2]);
165
9.96k
      prev = &o[1];
166
9.96k
    }
167
3.68k
  block16_set(offset, prev);
168
169
3.68k
  if (n > 0)
170
912
    {
171
912
      update_offset (key, offset, ++count);
172
912
      block16_set (o, offset);
173
912
    }
174
3.68k
}
175
176
void
177
ocb_update (struct ocb_ctx *ctx, const struct ocb_key *key,
178
      const void *cipher, nettle_cipher_func *f,
179
      size_t length, const uint8_t *data)
180
9.60k
{
181
9.60k
  union nettle_block16 block[OCB_MAX_BLOCKS];
182
9.60k
  size_t n = length / OCB_BLOCK_SIZE;
183
9.60k
  assert (ctx->message_count == 0);
184
185
9.60k
  if (ctx->data_count == 0)
186
2.54k
    ctx->offset.u64[0] = ctx->offset.u64[1] = 0;
187
188
11.0k
  while (n > 0)
189
1.43k
    {
190
1.43k
      size_t size, i;
191
1.43k
      size_t blocks = (n <= OCB_MAX_BLOCKS) ? n
192
1.43k
  : OCB_MAX_BLOCKS - 1 + (ctx->data_count & 1);
193
194
1.43k
      ocb_fill_n (key, &ctx->offset, ctx->data_count, blocks, block);
195
1.43k
      ctx->data_count += blocks;
196
197
1.43k
      size = blocks * OCB_BLOCK_SIZE;
198
1.43k
      memxor (block[0].b, data, size);
199
1.43k
      f (cipher, size, block[0].b, block[0].b);
200
9.29k
      for (i = 0; i < blocks; i++)
201
7.85k
  block16_xor(&ctx->sum, &block[i]);
202
203
1.43k
      n -= blocks; data += size;
204
1.43k
    }
205
206
9.60k
  length &= 15;
207
9.60k
  if (length > 0)
208
700
    {
209
700
      union nettle_block16 block;
210
700
      pad_block (&block, length, data);
211
700
      block16_xor (&ctx->offset, &key->L[0]);
212
700
      block16_xor (&block, &ctx->offset);
213
214
700
      f (cipher, OCB_BLOCK_SIZE, block.b, block.b);
215
700
      block16_xor (&ctx->sum, &block);
216
700
    }
217
9.60k
}
218
219
static void
220
ocb_crypt_n (struct ocb_ctx *ctx, const struct ocb_key *key,
221
       const void *cipher, nettle_cipher_func *f,
222
       size_t n, uint8_t *dst, const uint8_t *src)
223
1.71k
{
224
1.71k
  union nettle_block16 o[OCB_MAX_BLOCKS], block[OCB_MAX_BLOCKS];
225
1.71k
  size_t size;
226
227
3.96k
  while (n > 0)
228
2.24k
    {
229
2.24k
      size_t blocks = (n <= OCB_MAX_BLOCKS) ? n
230
2.24k
  : OCB_MAX_BLOCKS - 1 + (ctx->message_count & 1);
231
232
2.24k
      ocb_fill_n (key, &ctx->offset, ctx->message_count, blocks, o);
233
2.24k
      ctx->message_count += blocks;
234
235
2.24k
      size = blocks * OCB_BLOCK_SIZE;
236
2.24k
      memxor3 (block[0].b, o[0].b, src, size);
237
2.24k
      f (cipher, size, block[0].b, block[0].b);
238
2.24k
      memxor3 (dst, block[0].b, o[0].b, size);
239
240
2.24k
      n -= blocks; src += size; dst += size;
241
2.24k
    }
242
1.71k
}
243
244
/* Rotate bytes c positions to the right, in memory order. */
245
#if WORDS_BIGENDIAN
246
# define MEM_ROTATE_RIGHT(c, s0, s1) do {       \
247
    uint64_t __rotate_t = ((s0) >> (8*(c))) | ((s1) << (64-8*(c))); \
248
    (s1) = ((s1) >> (8*(c))) | ((s0) << (64-8*(c)));      \
249
    (s0) = __rotate_t;              \
250
  } while (0)
251
#else
252
0
# define MEM_ROTATE_RIGHT(c, s0, s1) do {       \
253
0
    uint64_t __rotate_t = ((s0) << (8*(c))) | ((s1) >> (64-8*(c))); \
254
0
    (s1) = ((s1) << (8*(c))) | ((s0) >> (64-8*(c)));      \
255
0
    (s0) = __rotate_t;              \
256
0
  } while (0)
257
#endif
258
259
/* Mask for the first c bytes in memory */
260
#if WORDS_BIGENDIAN
261
# define MEM_MASK(c) (-((uint64_t) 1 << (64 - 8*(c))))
262
#else
263
0
# define MEM_MASK(c) (((uint64_t) 1 << (8*(c))) - 1)
264
#endif
265
266
/* Checksum of n complete blocks. */
267
static void
268
ocb_checksum_n (union nettle_block16 *checksum,
269
    size_t n, const uint8_t *src)
270
1.71k
{
271
1.71k
  unsigned initial;
272
1.71k
  uint64_t edge_word = 0;
273
1.71k
  uint64_t s0, s1;
274
275
1.71k
  if (n == 1)
276
719
    {
277
719
      memxor (checksum->b, src, OCB_BLOCK_SIZE);
278
719
      return;
279
719
    }
280
281
  /* Initial unaligned bytes. */
282
999
  initial = -(uintptr_t) src & 7;
283
284
999
  if (initial > 0)
285
0
    {
286
      /* Input not 64-bit aligned. Read initial bytes. */
287
0
      unsigned i;
288
      /* Edge word is read in big-endian order */
289
0
      for (i = initial; i > 0; i--)
290
0
  edge_word = (edge_word << 8) + *src++;
291
0
      n--;
292
0
    }
293
294
  /* Now src is 64-bit aligned, so do 64-bit reads. */
295
15.5k
  for (s0 = s1 = 0 ; n > 0; n--, src += OCB_BLOCK_SIZE)
296
14.5k
    {
297
14.5k
      s0 ^= ((const uint64_t *) src)[0];
298
14.5k
      s1 ^= ((const uint64_t *) src)[1];
299
14.5k
    }
300
999
  if (initial > 0)
301
0
    {
302
0
      unsigned i;
303
0
      uint64_t mask;
304
0
      s0 ^= ((const uint64_t *) src)[0];
305
0
      for (i = 8 - initial, src += 8; i > 0; i--)
306
0
  edge_word = (edge_word << 8) + *src++;
307
308
      /* Rotate [s0, s1] right initial bytes. */
309
0
      MEM_ROTATE_RIGHT(initial, s0, s1);
310
      /* Add in the edge bytes.  */
311
0
      mask = MEM_MASK(initial);
312
0
      edge_word = bswap64_if_le (edge_word);
313
0
      s0 ^= (edge_word & mask);
314
0
      s1 ^= (edge_word & ~mask);
315
0
    }
316
999
  checksum->u64[0] ^= s0;
317
999
  checksum->u64[1] ^= s1;
318
999
}
319
320
void
321
ocb_encrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
322
       const void *cipher, nettle_cipher_func *f,
323
       size_t length, uint8_t *dst, const uint8_t *src)
324
9.51k
{
325
9.51k
  size_t n = length / OCB_BLOCK_SIZE;
326
327
9.51k
  if (ctx->message_count == 0)
328
5.07k
    ctx->offset = ctx->initial;
329
330
9.51k
  if (n > 0)
331
990
    {
332
990
      ocb_checksum_n (&ctx->checksum, n, src);
333
990
      ocb_crypt_n (ctx, key, cipher, f, n, dst, src);
334
990
      length &= 15;
335
990
    }
336
9.51k
  if (length > 0)
337
444
    {
338
444
      union nettle_block16 block;
339
340
444
      src += n*OCB_BLOCK_SIZE; dst += n*OCB_BLOCK_SIZE;
341
342
444
      pad_block (&block, length, src);
343
444
      block16_xor (&ctx->checksum, &block);
344
345
444
      block16_xor (&ctx->offset, &key->L[0]);
346
444
      f (cipher, OCB_BLOCK_SIZE, block.b, ctx->offset.b);
347
444
      memxor3 (dst, block.b, src, length);
348
444
      ctx->message_count++;
349
444
    }
350
9.51k
}
351
352
void
353
ocb_decrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
354
       const void *encrypt_ctx, nettle_cipher_func *encrypt,
355
       const void *decrypt_ctx, nettle_cipher_func *decrypt,
356
       size_t length, uint8_t *dst, const uint8_t *src)
357
3.56k
{
358
3.56k
  size_t n = length / OCB_BLOCK_SIZE;
359
360
3.56k
  if (ctx->message_count == 0)
361
1.11k
    ctx->offset = ctx->initial;
362
363
3.56k
  if (n > 0)
364
728
    {
365
728
      ocb_crypt_n (ctx, key, decrypt_ctx, decrypt, n, dst, src);
366
728
      ocb_checksum_n (&ctx->checksum, n, dst);
367
728
      length &= 15;
368
728
    }
369
3.56k
  if (length > 0)
370
651
    {
371
651
      union nettle_block16 block;
372
373
651
      src += n*OCB_BLOCK_SIZE; dst += n*OCB_BLOCK_SIZE;
374
375
651
      block16_xor (&ctx->offset, &key->L[0]);
376
651
      encrypt (encrypt_ctx, OCB_BLOCK_SIZE, block.b, ctx->offset.b);
377
651
      memxor3 (dst, block.b, src, length);
378
379
651
      pad_block (&block, length, dst);
380
651
      block16_xor (&ctx->checksum, &block);
381
651
      ctx->message_count++;
382
651
    }
383
3.56k
}
384
385
void
386
ocb_digest (const struct ocb_ctx *ctx, const struct ocb_key *key,
387
      const void *cipher, nettle_cipher_func *f,
388
      size_t length, uint8_t *digest)
389
1.26k
{
390
1.26k
  union nettle_block16 block;
391
1.26k
  assert (length <= OCB_DIGEST_SIZE);
392
1.26k
  block16_xor3 (&block,  &key->L[1],
393
1.26k
    (ctx->message_count > 0) ? &ctx->offset : &ctx->initial);
394
1.26k
  block16_xor (&block, &ctx->checksum);
395
1.26k
  f (cipher, OCB_BLOCK_SIZE, block.b, block.b);
396
1.26k
  memxor3 (digest, block.b, ctx->sum.b, length);
397
1.26k
}
398
399
void
400
ocb_encrypt_message (const struct ocb_key *key,
401
         const void *cipher, nettle_cipher_func *f,
402
         size_t nlength, const uint8_t *nonce,
403
         size_t alength, const uint8_t *adata,
404
         size_t tlength,
405
         size_t clength, uint8_t *dst, const uint8_t *src)
406
0
{
407
0
  struct ocb_ctx ctx;
408
0
  assert (clength >= tlength);
409
0
  ocb_set_nonce (&ctx, cipher, f, tlength, nlength, nonce);
410
0
  ocb_update (&ctx, key, cipher, f, alength, adata);
411
0
  ocb_encrypt (&ctx, key, cipher, f,  clength - tlength, dst, src);
412
0
  ocb_digest (&ctx, key, cipher, f, tlength, dst + clength - tlength);
413
0
}
414
415
int
416
ocb_decrypt_message (const struct ocb_key *key,
417
         const void *encrypt_ctx, nettle_cipher_func *encrypt,
418
         const void *decrypt_ctx, nettle_cipher_func *decrypt,
419
         size_t nlength, const uint8_t *nonce,
420
         size_t alength, const uint8_t *adata,
421
         size_t tlength,
422
         size_t mlength, uint8_t *dst, const uint8_t *src)
423
0
{
424
0
  struct ocb_ctx ctx;
425
0
  union nettle_block16 digest;
426
0
  ocb_set_nonce (&ctx, encrypt_ctx, encrypt, tlength, nlength, nonce);
427
0
  ocb_update (&ctx, key, encrypt_ctx, encrypt, alength, adata);
428
0
  ocb_decrypt (&ctx, key, encrypt_ctx, encrypt, decrypt_ctx, decrypt,
429
0
         mlength, dst, src);
430
0
  ocb_digest (&ctx, key, encrypt_ctx, encrypt, tlength, digest.b);
431
0
  return memeql_sec(digest.b, src + mlength, tlength);
432
0
}