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