Coverage Report

Created: 2024-06-20 06:28

/src/gnutls/lib/nettle/mac.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2008-2012 Free Software Foundation, Inc.
3
 *
4
 * Author: Nikos Mavrogiannopoulos
5
 *
6
 * This file is part of GNUTLS.
7
 *
8
 * The GNUTLS library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
/* This file provides the backend hash/mac API for nettle.
24
 */
25
26
#include "gnutls_int.h"
27
#include "hash_int.h"
28
#include "errors.h"
29
#include <nettle/md5.h>
30
#include <nettle/md2.h>
31
#include <nettle/sha.h>
32
#include <nettle/sha3.h>
33
#include <nettle/hmac.h>
34
#include <nettle/umac.h>
35
#include <nettle/hkdf.h>
36
#include <nettle/pbkdf2.h>
37
#include <nettle/cmac.h>
38
#if ENABLE_GOST
39
#include "gost/hmac-gost.h"
40
#ifndef HAVE_NETTLE_GOST28147_SET_KEY
41
#include "gost/gost28147.h"
42
#endif
43
#include "gost/cmac.h"
44
#endif
45
#include <nettle/gcm.h>
46
47
typedef void (*update_func)(void *, size_t, const uint8_t *);
48
typedef void (*digest_func)(void *, size_t, uint8_t *);
49
typedef void (*set_key_func)(void *, size_t, const uint8_t *);
50
typedef void (*set_nonce_func)(void *, size_t, const uint8_t *);
51
52
static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, void **_ctx);
53
54
struct md5_sha1_ctx {
55
  struct md5_ctx md5;
56
  struct sha1_ctx sha1;
57
};
58
59
struct gmac_ctx {
60
  unsigned int pos;
61
  uint8_t buffer[GCM_BLOCK_SIZE];
62
  struct gcm_key key;
63
  struct gcm_ctx ctx;
64
  nettle_cipher_func *encrypt;
65
  union {
66
    struct aes128_ctx aes128;
67
    struct aes192_ctx aes192;
68
    struct aes256_ctx aes256;
69
  } cipher;
70
};
71
72
struct nettle_hash_ctx {
73
  union {
74
    struct md5_ctx md5;
75
    struct sha224_ctx sha224;
76
    struct sha256_ctx sha256;
77
    struct sha384_ctx sha384;
78
    struct sha512_ctx sha512;
79
    struct sha3_224_ctx sha3_224;
80
    struct sha3_256_ctx sha3_256;
81
    struct sha3_384_ctx sha3_384;
82
    struct sha3_512_ctx sha3_512;
83
    struct sha1_ctx sha1;
84
    struct md2_ctx md2;
85
    struct md5_sha1_ctx md5_sha1;
86
#if ENABLE_GOST
87
    struct gosthash94cp_ctx gosthash94cp;
88
    struct streebog256_ctx streebog256;
89
    struct streebog512_ctx streebog512;
90
#endif
91
  } ctx;
92
  void *ctx_ptr;
93
  gnutls_digest_algorithm_t algo;
94
  size_t length;
95
  update_func update;
96
  digest_func digest;
97
};
98
99
struct nettle_mac_ctx {
100
  union {
101
    struct hmac_md5_ctx md5;
102
    struct hmac_sha224_ctx sha224;
103
    struct hmac_sha256_ctx sha256;
104
    struct hmac_sha384_ctx sha384;
105
    struct hmac_sha512_ctx sha512;
106
    struct hmac_sha1_ctx sha1;
107
#if ENABLE_GOST
108
    struct hmac_gosthash94cp_ctx gosthash94cp;
109
    struct hmac_streebog256_ctx streebog256;
110
    struct hmac_streebog512_ctx streebog512;
111
    struct gost28147_imit_ctx gost28147_imit;
112
    struct cmac_magma_ctx magma;
113
    struct cmac_kuznyechik_ctx kuznyechik;
114
#endif
115
    struct umac96_ctx umac96;
116
    struct umac128_ctx umac128;
117
    struct cmac_aes128_ctx cmac128;
118
    struct cmac_aes256_ctx cmac256;
119
    struct gmac_ctx gmac;
120
  } ctx;
121
122
  void *ctx_ptr;
123
  gnutls_mac_algorithm_t algo;
124
  size_t length;
125
  update_func update;
126
  digest_func digest;
127
  set_key_func set_key;
128
  set_nonce_func set_nonce;
129
};
130
131
#if ENABLE_GOST
132
static void _wrap_gost28147_imit_set_key_tc26z(void *ctx, size_t len,
133
                 const uint8_t *key)
134
0
{
135
0
  gost28147_imit_set_param(ctx, &gost28147_param_TC26_Z);
136
0
  gost28147_imit_set_key(ctx, len, key);
137
0
}
138
139
static void _wrap_cmac_magma_set_key(void *ctx, size_t len, const uint8_t *key)
140
0
{
141
0
  cmac_magma_set_key(ctx, key);
142
0
}
143
144
static void _wrap_cmac_kuznyechik_set_key(void *ctx, size_t len,
145
            const uint8_t *key)
146
0
{
147
0
  cmac_kuznyechik_set_key(ctx, key);
148
0
}
149
#endif
150
151
static void _wrap_umac96_set_key(void *ctx, size_t len, const uint8_t *key)
152
0
{
153
0
  if (unlikely(len != 16))
154
0
    abort();
155
0
  umac96_set_key(ctx, key);
156
0
}
157
158
static void _wrap_umac128_set_key(void *ctx, size_t len, const uint8_t *key)
159
0
{
160
0
  if (unlikely(len != 16))
161
0
    abort();
162
0
  umac128_set_key(ctx, key);
163
0
}
164
165
static void _wrap_cmac128_set_key(void *ctx, size_t len, const uint8_t *key)
166
0
{
167
0
  if (unlikely(len != 16))
168
0
    abort();
169
0
  cmac_aes128_set_key(ctx, key);
170
0
}
171
172
static void _wrap_cmac256_set_key(void *ctx, size_t len, const uint8_t *key)
173
0
{
174
0
  if (unlikely(len != 32))
175
0
    abort();
176
0
  cmac_aes256_set_key(ctx, key);
177
0
}
178
179
static void _wrap_gmac_aes128_set_key(void *_ctx, size_t len,
180
              const uint8_t *key)
181
0
{
182
0
  struct gmac_ctx *ctx = _ctx;
183
184
0
  if (unlikely(len != 16))
185
0
    abort();
186
0
  aes128_set_encrypt_key(&ctx->cipher.aes128, key);
187
0
  gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt);
188
0
  ctx->pos = 0;
189
0
}
190
191
static void _wrap_gmac_aes192_set_key(void *_ctx, size_t len,
192
              const uint8_t *key)
193
0
{
194
0
  struct gmac_ctx *ctx = _ctx;
195
196
0
  if (unlikely(len != 24))
197
0
    abort();
198
0
  aes192_set_encrypt_key(&ctx->cipher.aes192, key);
199
0
  gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt);
200
0
  ctx->pos = 0;
201
0
}
202
203
static void _wrap_gmac_aes256_set_key(void *_ctx, size_t len,
204
              const uint8_t *key)
205
0
{
206
0
  struct gmac_ctx *ctx = _ctx;
207
208
0
  if (unlikely(len != 32))
209
0
    abort();
210
0
  aes256_set_encrypt_key(&ctx->cipher.aes256, key);
211
0
  gcm_set_key(&ctx->key, &ctx->cipher, ctx->encrypt);
212
0
  ctx->pos = 0;
213
0
}
214
215
static void _wrap_gmac_set_nonce(void *_ctx, size_t nonce_length,
216
         const uint8_t *nonce)
217
0
{
218
0
  struct gmac_ctx *ctx = _ctx;
219
220
0
  gcm_set_iv(&ctx->ctx, &ctx->key, nonce_length, nonce);
221
0
}
222
223
static void _wrap_gmac_update(void *_ctx, size_t length, const uint8_t *data)
224
0
{
225
0
  struct gmac_ctx *ctx = _ctx;
226
227
0
  if (ctx->pos + length < GCM_BLOCK_SIZE) {
228
0
    memcpy(&ctx->buffer[ctx->pos], data, length);
229
0
    ctx->pos += length;
230
0
    return;
231
0
  }
232
233
0
  if (ctx->pos) {
234
0
    memcpy(&ctx->buffer[ctx->pos], data, GCM_BLOCK_SIZE - ctx->pos);
235
0
    gcm_update(&ctx->ctx, &ctx->key, GCM_BLOCK_SIZE, ctx->buffer);
236
0
    data += GCM_BLOCK_SIZE - ctx->pos;
237
0
    length -= GCM_BLOCK_SIZE - ctx->pos;
238
0
  }
239
240
0
  if (length >= GCM_BLOCK_SIZE) {
241
0
    gcm_update(&ctx->ctx, &ctx->key,
242
0
         length / GCM_BLOCK_SIZE * GCM_BLOCK_SIZE, data);
243
0
    data += length / GCM_BLOCK_SIZE * GCM_BLOCK_SIZE;
244
0
    length %= GCM_BLOCK_SIZE;
245
0
  }
246
247
0
  memcpy(ctx->buffer, data, length);
248
0
  ctx->pos = length;
249
0
}
250
251
static void _wrap_gmac_digest(void *_ctx, size_t length, uint8_t *digest)
252
0
{
253
0
  struct gmac_ctx *ctx = _ctx;
254
255
0
  if (ctx->pos)
256
0
    gcm_update(&ctx->ctx, &ctx->key, ctx->pos, ctx->buffer);
257
0
  gcm_digest(&ctx->ctx, &ctx->key, &ctx->cipher, ctx->encrypt, length,
258
0
       digest);
259
0
  ctx->pos = 0;
260
0
}
261
262
static int _mac_ctx_init(gnutls_mac_algorithm_t algo,
263
       struct nettle_mac_ctx *ctx)
264
0
{
265
  /* Any FIPS140-2 related enforcement is performed on
266
   * gnutls_hash_init() and gnutls_hmac_init() */
267
268
0
  ctx->set_nonce = NULL;
269
0
  switch (algo) {
270
0
  case GNUTLS_MAC_MD5:
271
0
    ctx->update = (update_func)hmac_md5_update;
272
0
    ctx->digest = (digest_func)hmac_md5_digest;
273
0
    ctx->set_key = (set_key_func)hmac_md5_set_key;
274
0
    ctx->ctx_ptr = &ctx->ctx.md5;
275
0
    ctx->length = MD5_DIGEST_SIZE;
276
0
    break;
277
0
  case GNUTLS_MAC_SHA1:
278
0
    ctx->update = (update_func)hmac_sha1_update;
279
0
    ctx->digest = (digest_func)hmac_sha1_digest;
280
0
    ctx->set_key = (set_key_func)hmac_sha1_set_key;
281
0
    ctx->ctx_ptr = &ctx->ctx.sha1;
282
0
    ctx->length = SHA1_DIGEST_SIZE;
283
0
    break;
284
0
  case GNUTLS_MAC_SHA224:
285
0
    ctx->update = (update_func)hmac_sha224_update;
286
0
    ctx->digest = (digest_func)hmac_sha224_digest;
287
0
    ctx->set_key = (set_key_func)hmac_sha224_set_key;
288
0
    ctx->ctx_ptr = &ctx->ctx.sha224;
289
0
    ctx->length = SHA224_DIGEST_SIZE;
290
0
    break;
291
0
  case GNUTLS_MAC_SHA256:
292
0
    ctx->update = (update_func)hmac_sha256_update;
293
0
    ctx->digest = (digest_func)hmac_sha256_digest;
294
0
    ctx->set_key = (set_key_func)hmac_sha256_set_key;
295
0
    ctx->ctx_ptr = &ctx->ctx.sha256;
296
0
    ctx->length = SHA256_DIGEST_SIZE;
297
0
    break;
298
0
  case GNUTLS_MAC_SHA384:
299
0
    ctx->update = (update_func)hmac_sha384_update;
300
0
    ctx->digest = (digest_func)hmac_sha384_digest;
301
0
    ctx->set_key = (set_key_func)hmac_sha384_set_key;
302
0
    ctx->ctx_ptr = &ctx->ctx.sha384;
303
0
    ctx->length = SHA384_DIGEST_SIZE;
304
0
    break;
305
0
  case GNUTLS_MAC_SHA512:
306
0
    ctx->update = (update_func)hmac_sha512_update;
307
0
    ctx->digest = (digest_func)hmac_sha512_digest;
308
0
    ctx->set_key = (set_key_func)hmac_sha512_set_key;
309
0
    ctx->ctx_ptr = &ctx->ctx.sha512;
310
0
    ctx->length = SHA512_DIGEST_SIZE;
311
0
    break;
312
0
#if ENABLE_GOST
313
0
  case GNUTLS_MAC_GOSTR_94:
314
0
    ctx->update = (update_func)hmac_gosthash94cp_update;
315
0
    ctx->digest = (digest_func)hmac_gosthash94cp_digest;
316
0
    ctx->set_key = (set_key_func)hmac_gosthash94cp_set_key;
317
0
    ctx->ctx_ptr = &ctx->ctx.gosthash94cp;
318
0
    ctx->length = GOSTHASH94CP_DIGEST_SIZE;
319
0
    break;
320
0
  case GNUTLS_MAC_STREEBOG_256:
321
0
    ctx->update = (update_func)hmac_streebog256_update;
322
0
    ctx->digest = (digest_func)hmac_streebog256_digest;
323
0
    ctx->set_key = (set_key_func)hmac_streebog256_set_key;
324
0
    ctx->ctx_ptr = &ctx->ctx.streebog256;
325
0
    ctx->length = STREEBOG256_DIGEST_SIZE;
326
0
    break;
327
0
  case GNUTLS_MAC_STREEBOG_512:
328
0
    ctx->update = (update_func)hmac_streebog512_update;
329
0
    ctx->digest = (digest_func)hmac_streebog512_digest;
330
0
    ctx->set_key = (set_key_func)hmac_streebog512_set_key;
331
0
    ctx->ctx_ptr = &ctx->ctx.streebog512;
332
0
    ctx->length = STREEBOG512_DIGEST_SIZE;
333
0
    break;
334
0
  case GNUTLS_MAC_GOST28147_TC26Z_IMIT:
335
0
    ctx->update = (update_func)gost28147_imit_update;
336
0
    ctx->digest = (digest_func)gost28147_imit_digest;
337
0
    ctx->set_key = _wrap_gost28147_imit_set_key_tc26z;
338
0
    ctx->ctx_ptr = &ctx->ctx.gost28147_imit;
339
0
    ctx->length = GOST28147_IMIT_DIGEST_SIZE;
340
0
    break;
341
0
  case GNUTLS_MAC_MAGMA_OMAC:
342
0
    ctx->update = (update_func)cmac_magma_update;
343
0
    ctx->digest = (digest_func)cmac_magma_digest;
344
0
    ctx->set_key = _wrap_cmac_magma_set_key;
345
0
    ctx->ctx_ptr = &ctx->ctx.magma;
346
0
    ctx->length = CMAC64_DIGEST_SIZE;
347
0
    break;
348
0
  case GNUTLS_MAC_KUZNYECHIK_OMAC:
349
0
    ctx->update = (update_func)cmac_kuznyechik_update;
350
0
    ctx->digest = (digest_func)cmac_kuznyechik_digest;
351
0
    ctx->set_key = _wrap_cmac_kuznyechik_set_key;
352
0
    ctx->ctx_ptr = &ctx->ctx.kuznyechik;
353
0
    ctx->length = CMAC128_DIGEST_SIZE;
354
0
    break;
355
0
#endif
356
0
  case GNUTLS_MAC_UMAC_96:
357
0
    ctx->update = (update_func)umac96_update;
358
0
    ctx->digest = (digest_func)umac96_digest;
359
0
    ctx->set_key = _wrap_umac96_set_key;
360
0
    ctx->set_nonce = (set_nonce_func)umac96_set_nonce;
361
0
    ctx->ctx_ptr = &ctx->ctx.umac96;
362
0
    ctx->length = 12;
363
0
    break;
364
0
  case GNUTLS_MAC_UMAC_128:
365
0
    ctx->update = (update_func)umac128_update;
366
0
    ctx->digest = (digest_func)umac128_digest;
367
0
    ctx->set_key = _wrap_umac128_set_key;
368
0
    ctx->set_nonce = (set_nonce_func)umac128_set_nonce;
369
0
    ctx->ctx_ptr = &ctx->ctx.umac128;
370
0
    ctx->length = 16;
371
0
    break;
372
0
  case GNUTLS_MAC_AES_CMAC_128:
373
0
    ctx->update = (update_func)cmac_aes128_update;
374
0
    ctx->digest = (digest_func)cmac_aes128_digest;
375
0
    ctx->set_key = _wrap_cmac128_set_key;
376
0
    ctx->ctx_ptr = &ctx->ctx.cmac128;
377
0
    ctx->length = CMAC128_DIGEST_SIZE;
378
0
    break;
379
0
  case GNUTLS_MAC_AES_CMAC_256:
380
0
    ctx->update = (update_func)cmac_aes256_update;
381
0
    ctx->digest = (digest_func)cmac_aes256_digest;
382
0
    ctx->set_key = _wrap_cmac256_set_key;
383
0
    ctx->ctx_ptr = &ctx->ctx.cmac256;
384
0
    ctx->length = CMAC128_DIGEST_SIZE;
385
0
    break;
386
0
  case GNUTLS_MAC_AES_GMAC_128:
387
0
    ctx->set_key = _wrap_gmac_aes128_set_key;
388
0
    ctx->set_nonce = _wrap_gmac_set_nonce;
389
0
    ctx->update = _wrap_gmac_update;
390
0
    ctx->digest = _wrap_gmac_digest;
391
0
    ctx->ctx_ptr = &ctx->ctx.gmac;
392
0
    ctx->length = GCM_DIGEST_SIZE;
393
0
    ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes128_encrypt;
394
0
    break;
395
0
  case GNUTLS_MAC_AES_GMAC_192:
396
0
    ctx->set_key = _wrap_gmac_aes192_set_key;
397
0
    ctx->set_nonce = _wrap_gmac_set_nonce;
398
0
    ctx->update = _wrap_gmac_update;
399
0
    ctx->digest = _wrap_gmac_digest;
400
0
    ctx->ctx_ptr = &ctx->ctx.gmac;
401
0
    ctx->length = GCM_DIGEST_SIZE;
402
0
    ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes192_encrypt;
403
0
    break;
404
0
  case GNUTLS_MAC_AES_GMAC_256:
405
0
    ctx->set_key = _wrap_gmac_aes256_set_key;
406
0
    ctx->set_nonce = _wrap_gmac_set_nonce;
407
0
    ctx->update = _wrap_gmac_update;
408
0
    ctx->digest = _wrap_gmac_digest;
409
0
    ctx->ctx_ptr = &ctx->ctx.gmac;
410
0
    ctx->length = GCM_DIGEST_SIZE;
411
0
    ctx->ctx.gmac.encrypt = (nettle_cipher_func *)aes256_encrypt;
412
0
    break;
413
0
  default:
414
0
    gnutls_assert();
415
0
    return GNUTLS_E_INVALID_REQUEST;
416
0
  }
417
418
0
  return 0;
419
0
}
420
421
static int wrap_nettle_mac_fast(gnutls_mac_algorithm_t algo, const void *nonce,
422
        size_t nonce_size, const void *key,
423
        size_t key_size, const void *text,
424
        size_t text_size, void *digest)
425
0
{
426
0
  struct nettle_mac_ctx ctx;
427
0
  int ret;
428
429
0
  ret = _mac_ctx_init(algo, &ctx);
430
0
  if (ret < 0)
431
0
    return gnutls_assert_val(ret);
432
433
0
  ctx.set_key(&ctx, key_size, key);
434
0
  if (ctx.set_nonce) {
435
0
    if (nonce == NULL || nonce_size == 0)
436
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
437
438
0
    ctx.set_nonce(&ctx, nonce_size, nonce);
439
0
  }
440
0
  ctx.update(&ctx, text_size, text);
441
0
  ctx.digest(&ctx, ctx.length, digest);
442
443
0
  zeroize_temp_key(&ctx, sizeof(ctx));
444
445
0
  return 0;
446
0
}
447
448
static int wrap_nettle_mac_exists(gnutls_mac_algorithm_t algo)
449
0
{
450
0
  switch (algo) {
451
0
  case GNUTLS_MAC_MD5:
452
0
  case GNUTLS_MAC_SHA1:
453
0
  case GNUTLS_MAC_SHA224:
454
0
  case GNUTLS_MAC_SHA256:
455
0
  case GNUTLS_MAC_SHA384:
456
0
  case GNUTLS_MAC_SHA512:
457
0
  case GNUTLS_MAC_UMAC_96:
458
0
  case GNUTLS_MAC_UMAC_128:
459
0
  case GNUTLS_MAC_AES_CMAC_128:
460
0
  case GNUTLS_MAC_AES_CMAC_256:
461
0
  case GNUTLS_MAC_AES_GMAC_128:
462
0
  case GNUTLS_MAC_AES_GMAC_192:
463
0
  case GNUTLS_MAC_AES_GMAC_256:
464
0
#if ENABLE_GOST
465
0
  case GNUTLS_MAC_GOSTR_94:
466
0
  case GNUTLS_MAC_STREEBOG_256:
467
0
  case GNUTLS_MAC_STREEBOG_512:
468
0
  case GNUTLS_MAC_GOST28147_TC26Z_IMIT:
469
0
  case GNUTLS_MAC_MAGMA_OMAC:
470
0
  case GNUTLS_MAC_KUZNYECHIK_OMAC:
471
0
#endif
472
0
    return 1;
473
0
  default:
474
0
    return 0;
475
0
  }
476
0
}
477
478
static int wrap_nettle_mac_init(gnutls_mac_algorithm_t algo, void **_ctx)
479
0
{
480
0
  struct nettle_mac_ctx *ctx;
481
0
  int ret;
482
483
0
  ctx = gnutls_calloc(1, sizeof(struct nettle_mac_ctx));
484
0
  if (ctx == NULL) {
485
0
    gnutls_assert();
486
0
    return GNUTLS_E_MEMORY_ERROR;
487
0
  }
488
489
0
  ctx->algo = algo;
490
491
0
  ret = _mac_ctx_init(algo, ctx);
492
0
  if (ret < 0) {
493
0
    gnutls_free(ctx);
494
0
    return gnutls_assert_val(ret);
495
0
  }
496
497
0
  *_ctx = ctx;
498
499
0
  return 0;
500
0
}
501
502
static void *wrap_nettle_mac_copy(const void *_ctx)
503
0
{
504
0
  const struct nettle_mac_ctx *ctx = _ctx;
505
0
  struct nettle_mac_ctx *new_ctx;
506
0
  ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx);
507
508
0
  new_ctx = gnutls_calloc(1, sizeof(struct nettle_mac_ctx));
509
0
  if (new_ctx == NULL)
510
0
    return NULL;
511
512
0
  memcpy(new_ctx, ctx, sizeof(*ctx));
513
0
  new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off;
514
515
0
  return new_ctx;
516
0
}
517
518
static int wrap_nettle_mac_set_key(void *_ctx, const void *key, size_t keylen)
519
0
{
520
0
  struct nettle_mac_ctx *ctx = _ctx;
521
522
0
  ctx->set_key(ctx->ctx_ptr, keylen, key);
523
0
  return 0;
524
0
}
525
526
static int wrap_nettle_mac_set_nonce(void *_ctx, const void *nonce,
527
             size_t noncelen)
528
0
{
529
0
  struct nettle_mac_ctx *ctx = _ctx;
530
531
0
  if (ctx->set_nonce == NULL)
532
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
533
534
0
  if (nonce == NULL || noncelen == 0)
535
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
536
537
0
  ctx->set_nonce(ctx->ctx_ptr, noncelen, nonce);
538
539
0
  return GNUTLS_E_SUCCESS;
540
0
}
541
542
static int wrap_nettle_mac_update(void *_ctx, const void *text, size_t textsize)
543
0
{
544
0
  struct nettle_mac_ctx *ctx = _ctx;
545
546
0
  ctx->update(ctx->ctx_ptr, textsize, text);
547
548
0
  return GNUTLS_E_SUCCESS;
549
0
}
550
551
static int wrap_nettle_mac_output(void *src_ctx, void *digest,
552
          size_t digestsize)
553
0
{
554
0
  struct nettle_mac_ctx *ctx;
555
0
  ctx = src_ctx;
556
557
0
  if (digestsize < ctx->length) {
558
0
    gnutls_assert();
559
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
560
0
  }
561
562
0
  ctx->digest(ctx->ctx_ptr, digestsize, digest);
563
564
0
  return 0;
565
0
}
566
567
static void wrap_nettle_mac_deinit(void *hd)
568
0
{
569
0
  struct nettle_mac_ctx *ctx = hd;
570
571
0
  zeroize_temp_key(ctx, sizeof(*ctx));
572
0
  gnutls_free(ctx);
573
0
}
574
575
/* Hash functions 
576
 */
577
static int wrap_nettle_hash_update(void *_ctx, const void *text,
578
           size_t textsize)
579
0
{
580
0
  struct nettle_hash_ctx *ctx = _ctx;
581
582
0
  ctx->update(ctx->ctx_ptr, textsize, text);
583
584
0
  return GNUTLS_E_SUCCESS;
585
0
}
586
587
static void wrap_nettle_hash_deinit(void *hd)
588
0
{
589
0
  gnutls_free(hd);
590
0
}
591
592
static int wrap_nettle_hash_exists(gnutls_digest_algorithm_t algo)
593
0
{
594
0
  switch (algo) {
595
0
  case GNUTLS_DIG_MD5:
596
0
  case GNUTLS_DIG_SHA1:
597
0
  case GNUTLS_DIG_MD5_SHA1:
598
599
0
  case GNUTLS_DIG_SHA224:
600
0
  case GNUTLS_DIG_SHA256:
601
0
  case GNUTLS_DIG_SHA384:
602
0
  case GNUTLS_DIG_SHA512:
603
604
0
#ifdef NETTLE_SHA3_FIPS202
605
0
  case GNUTLS_DIG_SHA3_224:
606
0
  case GNUTLS_DIG_SHA3_256:
607
0
  case GNUTLS_DIG_SHA3_384:
608
0
  case GNUTLS_DIG_SHA3_512:
609
0
#endif
610
611
0
  case GNUTLS_DIG_SHAKE_128:
612
0
  case GNUTLS_DIG_SHAKE_256:
613
614
0
  case GNUTLS_DIG_MD2:
615
0
  case GNUTLS_DIG_RMD160:
616
617
0
#if ENABLE_GOST
618
0
  case GNUTLS_DIG_GOSTR_94:
619
0
  case GNUTLS_DIG_STREEBOG_256:
620
0
  case GNUTLS_DIG_STREEBOG_512:
621
0
#endif
622
0
    return 1;
623
0
  default:
624
0
    return 0;
625
0
  }
626
0
}
627
628
static void _md5_sha1_update(void *_ctx, size_t len, const uint8_t *data)
629
0
{
630
0
  struct md5_sha1_ctx *ctx = _ctx;
631
632
0
  md5_update(&ctx->md5, len, data);
633
0
  sha1_update(&ctx->sha1, len, data);
634
0
}
635
636
static void _md5_sha1_digest(void *_ctx, size_t len, uint8_t *digest)
637
0
{
638
0
  struct md5_sha1_ctx *ctx = _ctx;
639
640
0
  md5_digest(&ctx->md5, len <= MD5_DIGEST_SIZE ? len : MD5_DIGEST_SIZE,
641
0
       digest);
642
643
0
  if (len > MD5_DIGEST_SIZE)
644
0
    sha1_digest(&ctx->sha1, len - MD5_DIGEST_SIZE,
645
0
          digest + MD5_DIGEST_SIZE);
646
0
}
647
648
static int _ctx_init(gnutls_digest_algorithm_t algo,
649
         struct nettle_hash_ctx *ctx)
650
0
{
651
  /* Any FIPS140-2 related enforcement is performed on
652
   * gnutls_hash_init() and gnutls_hmac_init() */
653
0
  switch (algo) {
654
0
  case GNUTLS_DIG_MD5:
655
0
    md5_init(&ctx->ctx.md5);
656
0
    ctx->update = (update_func)md5_update;
657
0
    ctx->digest = (digest_func)md5_digest;
658
0
    ctx->ctx_ptr = &ctx->ctx.md5;
659
0
    ctx->length = MD5_DIGEST_SIZE;
660
0
    break;
661
0
  case GNUTLS_DIG_SHA1:
662
0
    sha1_init(&ctx->ctx.sha1);
663
0
    ctx->update = (update_func)sha1_update;
664
0
    ctx->digest = (digest_func)sha1_digest;
665
0
    ctx->ctx_ptr = &ctx->ctx.sha1;
666
0
    ctx->length = SHA1_DIGEST_SIZE;
667
0
    break;
668
0
  case GNUTLS_DIG_MD5_SHA1:
669
0
    md5_init(&ctx->ctx.md5_sha1.md5);
670
0
    sha1_init(&ctx->ctx.md5_sha1.sha1);
671
0
    ctx->update = (update_func)_md5_sha1_update;
672
0
    ctx->digest = (digest_func)_md5_sha1_digest;
673
0
    ctx->ctx_ptr = &ctx->ctx.md5_sha1;
674
0
    ctx->length = MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE;
675
0
    break;
676
0
  case GNUTLS_DIG_SHA224:
677
0
    sha224_init(&ctx->ctx.sha224);
678
0
    ctx->update = (update_func)sha224_update;
679
0
    ctx->digest = (digest_func)sha224_digest;
680
0
    ctx->ctx_ptr = &ctx->ctx.sha224;
681
0
    ctx->length = SHA224_DIGEST_SIZE;
682
0
    break;
683
0
  case GNUTLS_DIG_SHA256:
684
0
    sha256_init(&ctx->ctx.sha256);
685
0
    ctx->update = (update_func)sha256_update;
686
0
    ctx->digest = (digest_func)sha256_digest;
687
0
    ctx->ctx_ptr = &ctx->ctx.sha256;
688
0
    ctx->length = SHA256_DIGEST_SIZE;
689
0
    break;
690
0
  case GNUTLS_DIG_SHA384:
691
0
    sha384_init(&ctx->ctx.sha384);
692
0
    ctx->update = (update_func)sha384_update;
693
0
    ctx->digest = (digest_func)sha384_digest;
694
0
    ctx->ctx_ptr = &ctx->ctx.sha384;
695
0
    ctx->length = SHA384_DIGEST_SIZE;
696
0
    break;
697
0
  case GNUTLS_DIG_SHA512:
698
0
    sha512_init(&ctx->ctx.sha512);
699
0
    ctx->update = (update_func)sha512_update;
700
0
    ctx->digest = (digest_func)sha512_digest;
701
0
    ctx->ctx_ptr = &ctx->ctx.sha512;
702
0
    ctx->length = SHA512_DIGEST_SIZE;
703
0
    break;
704
0
#ifdef NETTLE_SHA3_FIPS202
705
0
  case GNUTLS_DIG_SHA3_224:
706
0
    sha3_224_init(&ctx->ctx.sha3_224);
707
0
    ctx->update = (update_func)sha3_224_update;
708
0
    ctx->digest = (digest_func)sha3_224_digest;
709
0
    ctx->ctx_ptr = &ctx->ctx.sha3_224;
710
0
    ctx->length = SHA3_224_DIGEST_SIZE;
711
0
    break;
712
0
  case GNUTLS_DIG_SHA3_256:
713
0
    sha3_256_init(&ctx->ctx.sha3_256);
714
0
    ctx->update = (update_func)sha3_256_update;
715
0
    ctx->digest = (digest_func)sha3_256_digest;
716
0
    ctx->ctx_ptr = &ctx->ctx.sha3_256;
717
0
    ctx->length = SHA3_256_DIGEST_SIZE;
718
0
    break;
719
0
  case GNUTLS_DIG_SHA3_384:
720
0
    sha3_384_init(&ctx->ctx.sha3_384);
721
0
    ctx->update = (update_func)sha3_384_update;
722
0
    ctx->digest = (digest_func)sha3_384_digest;
723
0
    ctx->ctx_ptr = &ctx->ctx.sha3_384;
724
0
    ctx->length = SHA3_384_DIGEST_SIZE;
725
0
    break;
726
0
  case GNUTLS_DIG_SHA3_512:
727
0
    sha3_512_init(&ctx->ctx.sha3_512);
728
0
    ctx->update = (update_func)sha3_512_update;
729
0
    ctx->digest = (digest_func)sha3_512_digest;
730
0
    ctx->ctx_ptr = &ctx->ctx.sha3_512;
731
0
    ctx->length = SHA3_512_DIGEST_SIZE;
732
0
    break;
733
0
#endif
734
0
  case GNUTLS_DIG_MD2:
735
0
    md2_init(&ctx->ctx.md2);
736
0
    ctx->update = (update_func)md2_update;
737
0
    ctx->digest = (digest_func)md2_digest;
738
0
    ctx->ctx_ptr = &ctx->ctx.md2;
739
0
    ctx->length = MD2_DIGEST_SIZE;
740
0
    break;
741
0
#if ENABLE_GOST
742
0
  case GNUTLS_DIG_GOSTR_94:
743
0
    gosthash94cp_init(&ctx->ctx.gosthash94cp);
744
0
    ctx->update = (update_func)gosthash94cp_update;
745
0
    ctx->digest = (digest_func)gosthash94cp_digest;
746
0
    ctx->ctx_ptr = &ctx->ctx.gosthash94cp;
747
0
    ctx->length = GOSTHASH94_DIGEST_SIZE;
748
0
    break;
749
0
  case GNUTLS_DIG_STREEBOG_256:
750
0
    streebog256_init(&ctx->ctx.streebog256);
751
0
    ctx->update = (update_func)streebog256_update;
752
0
    ctx->digest = (digest_func)streebog256_digest;
753
0
    ctx->ctx_ptr = &ctx->ctx.streebog256;
754
0
    ctx->length = STREEBOG256_DIGEST_SIZE;
755
0
    break;
756
0
  case GNUTLS_DIG_STREEBOG_512:
757
0
    streebog512_init(&ctx->ctx.streebog512);
758
0
    ctx->update = (update_func)streebog512_update;
759
0
    ctx->digest = (digest_func)streebog512_digest;
760
0
    ctx->ctx_ptr = &ctx->ctx.streebog512;
761
0
    ctx->length = STREEBOG512_DIGEST_SIZE;
762
0
    break;
763
0
#endif
764
0
  default:
765
0
    gnutls_assert();
766
0
    return GNUTLS_E_INVALID_REQUEST;
767
0
  }
768
769
0
  return 0;
770
0
}
771
772
static int wrap_nettle_hash_fast(gnutls_digest_algorithm_t algo,
773
         const void *text, size_t text_size,
774
         void *digest)
775
0
{
776
0
  struct nettle_hash_ctx ctx;
777
0
  int ret;
778
779
0
  ret = _ctx_init(algo, &ctx);
780
0
  if (ret < 0)
781
0
    return gnutls_assert_val(ret);
782
783
0
  if (text_size > 0) {
784
0
    ctx.update(&ctx, text_size, text);
785
0
  }
786
0
  ctx.digest(&ctx, ctx.length, digest);
787
0
  zeroize_temp_key(&ctx, sizeof(ctx));
788
789
0
  return 0;
790
0
}
791
792
static int wrap_nettle_hash_init(gnutls_digest_algorithm_t algo, void **_ctx)
793
0
{
794
0
  struct nettle_hash_ctx *ctx;
795
0
  int ret;
796
797
0
  ctx = gnutls_malloc(sizeof(struct nettle_hash_ctx));
798
0
  if (ctx == NULL) {
799
0
    gnutls_assert();
800
0
    return GNUTLS_E_MEMORY_ERROR;
801
0
  }
802
803
0
  ctx->algo = algo;
804
805
0
  if ((ret = _ctx_init(algo, ctx)) < 0) {
806
0
    gnutls_assert();
807
0
    gnutls_free(ctx);
808
0
    return ret;
809
0
  }
810
811
0
  *_ctx = ctx;
812
813
0
  return 0;
814
0
}
815
816
static void *wrap_nettle_hash_copy(const void *_ctx)
817
0
{
818
0
  const struct nettle_hash_ctx *ctx = _ctx;
819
0
  struct nettle_hash_ctx *new_ctx;
820
0
  ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx);
821
822
0
  new_ctx = gnutls_calloc(1, sizeof(struct nettle_hash_ctx));
823
0
  if (new_ctx == NULL)
824
0
    return NULL;
825
826
0
  memcpy(new_ctx, ctx, sizeof(*ctx));
827
0
  new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off;
828
829
0
  return new_ctx;
830
0
}
831
832
static int wrap_nettle_hash_output(void *src_ctx, void *digest,
833
           size_t digestsize)
834
0
{
835
0
  struct nettle_hash_ctx *ctx;
836
0
  ctx = src_ctx;
837
838
0
  if (digestsize < ctx->length) {
839
0
    gnutls_assert();
840
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
841
0
  }
842
843
0
  ctx->digest(ctx->ctx_ptr, digestsize, digest);
844
845
0
  return 0;
846
0
}
847
848
/* KDF functions based on MAC
849
 */
850
static int wrap_nettle_hkdf_extract(gnutls_mac_algorithm_t mac, const void *key,
851
            size_t keysize, const void *salt,
852
            size_t saltsize, void *output)
853
0
{
854
0
  struct nettle_mac_ctx ctx;
855
0
  int ret;
856
857
0
  ret = _mac_ctx_init(mac, &ctx);
858
0
  if (ret < 0)
859
0
    return gnutls_assert_val(ret);
860
861
0
  ctx.set_key(&ctx, saltsize, salt);
862
0
  hkdf_extract(&ctx.ctx, ctx.update, ctx.digest, ctx.length, keysize, key,
863
0
         output);
864
865
0
  zeroize_temp_key(&ctx, sizeof(ctx));
866
0
  return 0;
867
0
}
868
869
static int wrap_nettle_hkdf_expand(gnutls_mac_algorithm_t mac, const void *key,
870
           size_t keysize, const void *info,
871
           size_t infosize, void *output, size_t length)
872
0
{
873
0
  struct nettle_mac_ctx ctx;
874
0
  int ret;
875
876
0
  ret = _mac_ctx_init(mac, &ctx);
877
0
  if (ret < 0)
878
0
    return gnutls_assert_val(ret);
879
880
  /* RFC 5869 2.3: L must be <= 255 * HashLen */
881
0
  if (length > ctx.length * 255) {
882
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
883
0
  }
884
885
0
  ctx.set_key(&ctx, keysize, key);
886
0
  hkdf_expand(&ctx.ctx, ctx.update, ctx.digest, ctx.length, infosize,
887
0
        info, length, output);
888
0
  zeroize_temp_key(&ctx, sizeof(ctx));
889
890
0
  return 0;
891
0
}
892
893
static int wrap_nettle_pbkdf2(gnutls_mac_algorithm_t mac, const void *key,
894
            size_t keysize, const void *salt, size_t saltsize,
895
            unsigned iter_count, void *output, size_t length)
896
0
{
897
0
  struct nettle_mac_ctx ctx;
898
0
  int ret;
899
900
0
  ret = _mac_ctx_init(mac, &ctx);
901
0
  if (ret < 0)
902
0
    return gnutls_assert_val(ret);
903
904
0
  ctx.set_key(&ctx, keysize, key);
905
0
  pbkdf2(&ctx.ctx, ctx.update, ctx.digest, ctx.length, iter_count,
906
0
         saltsize, salt, length, output);
907
0
  zeroize_temp_key(&ctx, sizeof(ctx));
908
909
0
  return 0;
910
0
}
911
912
gnutls_crypto_mac_st _gnutls_mac_ops = {
913
  .init = wrap_nettle_mac_init,
914
  .setkey = wrap_nettle_mac_set_key,
915
  .setnonce = wrap_nettle_mac_set_nonce,
916
  .hash = wrap_nettle_mac_update,
917
  .output = wrap_nettle_mac_output,
918
  .deinit = wrap_nettle_mac_deinit,
919
  .fast = wrap_nettle_mac_fast,
920
  .exists = wrap_nettle_mac_exists,
921
  .copy = wrap_nettle_mac_copy,
922
};
923
924
gnutls_crypto_digest_st _gnutls_digest_ops = {
925
  .init = wrap_nettle_hash_init,
926
  .hash = wrap_nettle_hash_update,
927
  .output = wrap_nettle_hash_output,
928
  .deinit = wrap_nettle_hash_deinit,
929
  .fast = wrap_nettle_hash_fast,
930
  .exists = wrap_nettle_hash_exists,
931
  .copy = wrap_nettle_hash_copy,
932
};
933
934
/* These names are clashing with nettle's name mangling. */
935
#undef hkdf_extract
936
#undef hkdf_expand
937
#undef pbkdf2
938
gnutls_crypto_kdf_st _gnutls_kdf_ops = {
939
  .hkdf_extract = wrap_nettle_hkdf_extract,
940
  .hkdf_expand = wrap_nettle_hkdf_expand,
941
  .pbkdf2 = wrap_nettle_pbkdf2,
942
};