Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/accelerated/x86/hmac-padlock.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2008, 2010-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 implementation for
24
 * VIA Padlock hardware acceleration.
25
 */
26
27
#include "gnutls_int.h"
28
#include <hash_int.h>
29
#include "errors.h"
30
#include <nettle/sha.h>
31
#include <nettle/hmac.h>
32
#include <nettle/macros.h>
33
#include <nettle/memxor.h>
34
#include <aes-padlock.h>
35
#include <sha-padlock.h>
36
#include <algorithms.h>
37
38
#ifdef HAVE_LIBNETTLE
39
40
0
# define IPAD 0x36
41
0
# define OPAD 0x5c
42
# define MAX_SHA_DIGEST_SIZE (512/8)
43
44
typedef void (*update_func)(void *, size_t, const uint8_t *);
45
typedef void (*digest_func)(void *, size_t, uint8_t *);
46
typedef void (*set_key_func)(void *, size_t, const uint8_t *);
47
48
struct padlock_hmac_ctx {
49
  union {
50
    struct hmac_sha224_ctx sha224;
51
    struct hmac_sha256_ctx sha256;
52
    struct hmac_sha384_ctx sha384;
53
    struct hmac_sha512_ctx sha512;
54
    struct hmac_sha1_ctx sha1;
55
  } ctx;
56
57
  void *ctx_ptr;
58
  gnutls_mac_algorithm_t algo;
59
  size_t length;
60
  update_func update;
61
  digest_func digest;
62
  set_key_func setkey;
63
};
64
65
static void
66
padlock_hmac_sha1_set_key(struct hmac_sha1_ctx *ctx,
67
        size_t key_length, const uint8_t * key)
68
0
{
69
0
  HMAC_SET_KEY(ctx, &padlock_sha1, key_length, key);
70
0
}
71
72
static void
73
padlock_hmac_sha1_update(struct hmac_sha1_ctx *ctx,
74
       size_t length, const uint8_t * data)
75
0
{
76
0
  padlock_sha1_update(&ctx->state, length, data);
77
0
}
78
79
static void
80
padlock_hmac_sha1_digest(struct hmac_sha1_ctx *ctx,
81
       size_t length, uint8_t * digest)
82
0
{
83
0
  HMAC_DIGEST(ctx, &padlock_sha1, length, digest);
84
0
}
85
86
static void
87
padlock_hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
88
          size_t key_length, const uint8_t * key)
89
0
{
90
0
  HMAC_SET_KEY(ctx, &padlock_sha256, key_length, key);
91
0
}
92
93
static void
94
padlock_hmac_sha256_update(struct hmac_sha256_ctx *ctx,
95
         size_t length, const uint8_t * data)
96
0
{
97
0
  padlock_sha256_update(&ctx->state, length, data);
98
0
}
99
100
static void
101
padlock_hmac_sha256_digest(struct hmac_sha256_ctx *ctx,
102
         size_t length, uint8_t * digest)
103
0
{
104
0
  HMAC_DIGEST(ctx, &padlock_sha256, length, digest);
105
0
}
106
107
static void
108
padlock_hmac_sha224_set_key(struct hmac_sha224_ctx *ctx,
109
          size_t key_length, const uint8_t * key)
110
0
{
111
0
  HMAC_SET_KEY(ctx, &padlock_sha224, key_length, key);
112
0
}
113
114
static void
115
padlock_hmac_sha224_digest(struct hmac_sha224_ctx *ctx,
116
         size_t length, uint8_t * digest)
117
0
{
118
0
  HMAC_DIGEST(ctx, &padlock_sha224, length, digest);
119
0
}
120
121
static void
122
padlock_hmac_sha384_set_key(struct hmac_sha384_ctx *ctx,
123
          size_t key_length, const uint8_t * key)
124
0
{
125
0
  HMAC_SET_KEY(ctx, &padlock_sha384, key_length, key);
126
0
}
127
128
static void
129
padlock_hmac_sha384_digest(struct hmac_sha384_ctx *ctx,
130
         size_t length, uint8_t * digest)
131
0
{
132
0
  HMAC_DIGEST(ctx, &padlock_sha384, length, digest);
133
0
}
134
135
static void
136
padlock_hmac_sha512_set_key(struct hmac_sha512_ctx *ctx,
137
          size_t key_length, const uint8_t * key)
138
0
{
139
0
  HMAC_SET_KEY(ctx, &padlock_sha512, key_length, key);
140
0
}
141
142
static void
143
padlock_hmac_sha512_update(struct hmac_sha512_ctx *ctx,
144
         size_t length, const uint8_t * data)
145
0
{
146
0
  padlock_sha512_update(&ctx->state, length, data);
147
0
}
148
149
static void
150
padlock_hmac_sha512_digest(struct hmac_sha512_ctx *ctx,
151
         size_t length, uint8_t * digest)
152
0
{
153
0
  HMAC_DIGEST(ctx, &padlock_sha512, length, digest);
154
0
}
155
156
static int
157
_hmac_ctx_init(gnutls_mac_algorithm_t algo, struct padlock_hmac_ctx *ctx)
158
0
{
159
0
  switch (algo) {
160
0
  case GNUTLS_MAC_SHA1:
161
0
    ctx->update = (update_func) padlock_hmac_sha1_update;
162
0
    ctx->digest = (digest_func) padlock_hmac_sha1_digest;
163
0
    ctx->setkey = (set_key_func) padlock_hmac_sha1_set_key;
164
0
    ctx->ctx_ptr = &ctx->ctx.sha1;
165
0
    ctx->length = SHA1_DIGEST_SIZE;
166
0
    break;
167
0
  case GNUTLS_MAC_SHA224:
168
0
    ctx->update = (update_func) padlock_hmac_sha256_update;
169
0
    ctx->digest = (digest_func) padlock_hmac_sha224_digest;
170
0
    ctx->setkey = (set_key_func) padlock_hmac_sha224_set_key;
171
0
    ctx->ctx_ptr = &ctx->ctx.sha224;
172
0
    ctx->length = SHA224_DIGEST_SIZE;
173
0
    break;
174
0
  case GNUTLS_MAC_SHA256:
175
0
    ctx->update = (update_func) padlock_hmac_sha256_update;
176
0
    ctx->digest = (digest_func) padlock_hmac_sha256_digest;
177
0
    ctx->setkey = (set_key_func) padlock_hmac_sha256_set_key;
178
0
    ctx->ctx_ptr = &ctx->ctx.sha256;
179
0
    ctx->length = SHA256_DIGEST_SIZE;
180
0
    break;
181
0
  case GNUTLS_MAC_SHA384:
182
0
    ctx->update = (update_func) padlock_hmac_sha512_update;
183
0
    ctx->digest = (digest_func) padlock_hmac_sha384_digest;
184
0
    ctx->setkey = (set_key_func) padlock_hmac_sha384_set_key;
185
0
    ctx->ctx_ptr = &ctx->ctx.sha384;
186
0
    ctx->length = SHA384_DIGEST_SIZE;
187
0
    break;
188
0
  case GNUTLS_MAC_SHA512:
189
0
    ctx->update = (update_func) padlock_hmac_sha512_update;
190
0
    ctx->digest = (digest_func) padlock_hmac_sha512_digest;
191
0
    ctx->setkey = (set_key_func) padlock_hmac_sha512_set_key;
192
0
    ctx->ctx_ptr = &ctx->ctx.sha512;
193
0
    ctx->length = SHA512_DIGEST_SIZE;
194
0
    break;
195
0
  default:
196
0
    gnutls_assert();
197
0
    return GNUTLS_E_INVALID_REQUEST;
198
0
  }
199
200
0
  return 0;
201
0
}
202
203
static int wrap_padlock_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx)
204
0
{
205
0
  struct padlock_hmac_ctx *ctx;
206
0
  int ret;
207
208
0
  ctx = gnutls_calloc(1, sizeof(struct padlock_hmac_ctx));
209
0
  if (ctx == NULL) {
210
0
    gnutls_assert();
211
0
    return GNUTLS_E_MEMORY_ERROR;
212
0
  }
213
214
0
  ctx->algo = algo;
215
216
0
  ret = _hmac_ctx_init(algo, ctx);
217
0
  if (ret < 0)
218
0
    return gnutls_assert_val(ret);
219
220
0
  *_ctx = ctx;
221
222
0
  return 0;
223
0
}
224
225
static void *wrap_padlock_hmac_copy(const void *_ctx)
226
0
{
227
0
  struct padlock_hmac_ctx *new_ctx;
228
0
  const struct padlock_hmac_ctx *ctx = _ctx;
229
0
  ptrdiff_t off = (uint8_t *) ctx->ctx_ptr - (uint8_t *) (&ctx->ctx);
230
231
0
  new_ctx = gnutls_malloc(sizeof(struct padlock_hmac_ctx));
232
0
  if (new_ctx == NULL) {
233
0
    gnutls_assert();
234
0
    return NULL;
235
0
  }
236
237
0
  memcpy(new_ctx, ctx, sizeof(*new_ctx));
238
0
  new_ctx->ctx_ptr = (uint8_t *) & new_ctx->ctx + off;
239
240
0
  return new_ctx;
241
0
}
242
243
static int wrap_padlock_hmac_setkey(void *_ctx, const void *key, size_t keylen)
244
0
{
245
0
  struct padlock_hmac_ctx *ctx = _ctx;
246
247
0
  ctx->setkey(ctx->ctx_ptr, keylen, key);
248
249
0
  return GNUTLS_E_SUCCESS;
250
0
}
251
252
static int
253
wrap_padlock_hmac_update(void *_ctx, const void *text, size_t textsize)
254
0
{
255
0
  struct padlock_hmac_ctx *ctx = _ctx;
256
257
0
  ctx->update(ctx->ctx_ptr, textsize, text);
258
259
0
  return GNUTLS_E_SUCCESS;
260
0
}
261
262
static int
263
wrap_padlock_hmac_output(void *src_ctx, void *digest, size_t digestsize)
264
0
{
265
0
  struct padlock_hmac_ctx *ctx;
266
0
  ctx = src_ctx;
267
268
0
  if (digestsize < ctx->length) {
269
0
    gnutls_assert();
270
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
271
0
  }
272
273
0
  ctx->digest(ctx->ctx_ptr, digestsize, digest);
274
275
0
  return 0;
276
0
}
277
278
static void wrap_padlock_hmac_deinit(void *hd)
279
0
{
280
0
  struct padlock_hmac_ctx *ctx = hd;
281
282
0
  zeroize_temp_key(ctx, sizeof(*ctx));
283
0
  gnutls_free(ctx);
284
0
}
285
286
static int
287
wrap_padlock_hmac_fast(gnutls_mac_algorithm_t algo,
288
           const void *nonce, size_t nonce_size,
289
           const void *key, size_t key_size, const void *text,
290
           size_t text_size, void *digest)
291
0
{
292
0
  if (algo == GNUTLS_MAC_SHA1 || algo == GNUTLS_MAC_SHA256) {
293
0
    unsigned char *pad;
294
0
    unsigned char pad2[SHA1_DATA_SIZE + MAX_SHA_DIGEST_SIZE];
295
0
    unsigned char hkey[MAX_SHA_DIGEST_SIZE];
296
0
    unsigned int digest_size =
297
0
        _gnutls_mac_get_algo_len(mac_to_entry(algo));
298
299
0
    if (key_size > SHA1_DATA_SIZE) {
300
0
      wrap_padlock_hash_fast((gnutls_digest_algorithm_t)
301
0
                 algo, key, key_size, hkey);
302
0
      key = hkey;
303
0
      key_size = digest_size;
304
0
    }
305
306
0
    pad = gnutls_malloc(text_size + SHA1_DATA_SIZE);
307
0
    if (pad == NULL)
308
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
309
310
0
    memset(pad, IPAD, SHA1_DATA_SIZE);
311
0
    memxor(pad, key, key_size);
312
313
0
    memcpy(&pad[SHA1_DATA_SIZE], text, text_size);
314
315
0
    wrap_padlock_hash_fast((gnutls_digest_algorithm_t) algo,
316
0
               pad, text_size + SHA1_DATA_SIZE,
317
0
               &pad2[SHA1_DATA_SIZE]);
318
319
0
    zeroize_temp_key(pad, text_size + SHA1_DATA_SIZE);
320
0
    gnutls_free(pad);
321
322
0
    memset(pad2, OPAD, SHA1_DATA_SIZE);
323
0
    memxor(pad2, key, key_size);
324
325
0
    wrap_padlock_hash_fast((gnutls_digest_algorithm_t) algo,
326
0
               pad2, digest_size + SHA1_DATA_SIZE,
327
0
               digest);
328
329
0
    zeroize_temp_key(pad2, sizeof(pad2));
330
0
    zeroize_temp_key(hkey, sizeof(hkey));
331
0
  } else {
332
0
    struct padlock_hmac_ctx ctx;
333
0
    int ret;
334
335
0
    ret = _hmac_ctx_init(algo, &ctx);
336
0
    if (ret < 0)
337
0
      return gnutls_assert_val(ret);
338
0
    ctx.algo = algo;
339
340
0
    wrap_padlock_hmac_setkey(&ctx, key, key_size);
341
342
0
    wrap_padlock_hmac_update(&ctx, text, text_size);
343
344
0
    wrap_padlock_hmac_output(&ctx, digest, ctx.length);
345
346
0
    zeroize_temp_key(&ctx, sizeof(ctx));
347
0
  }
348
349
0
  return 0;
350
0
}
351
352
const gnutls_crypto_mac_st _gnutls_hmac_sha_padlock_oneshot = {
353
  .init = NULL,
354
  .setkey = NULL,
355
  .setnonce = NULL,
356
  .hash = NULL,
357
  .output = NULL,
358
  .deinit = NULL,
359
  .fast = wrap_padlock_hmac_fast
360
};
361
362
const gnutls_crypto_mac_st _gnutls_hmac_sha_padlock = {
363
  .init = wrap_padlock_hmac_init,
364
  .setkey = wrap_padlock_hmac_setkey,
365
  .setnonce = NULL,
366
  .hash = wrap_padlock_hmac_update,
367
  .output = wrap_padlock_hmac_output,
368
  .copy = wrap_padlock_hmac_copy,
369
  .deinit = wrap_padlock_hmac_deinit,
370
  .fast = wrap_padlock_hmac_fast,
371
};
372
373
#endif        /* HAVE_LIBNETTLE */