1 /*
2 * Copyright (C) 2000-2016 Free Software Foundation, Inc.
3 * Copyright (C) 2016 Red Hat, Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
6 *
7 * This file is part of GnuTLS.
8 *
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>
21 *
22 */
23
24 #include "gnutls_int.h"
25 #include "errors.h"
26 #include <cipher_int.h>
27 #include <datum.h>
28 #include <gnutls/crypto.h>
29 #include <algorithms.h>
30 #include <random.h>
31 #include <crypto.h>
32 #include <fips.h>
33 #include "crypto-api.h"
34 #include "iov.h"
35
36 typedef struct api_cipher_hd_st {
37 cipher_hd_st ctx_enc;
38 cipher_hd_st ctx_dec;
39 } api_cipher_hd_st;
40
41 /**
42 * gnutls_cipher_init:
43 * @handle: is a #gnutls_cipher_hd_t type
44 * @cipher: the encryption algorithm to use
45 * @key: the key to be used for encryption/decryption
46 * @iv: the IV to use (if not applicable set NULL)
47 *
48 * This function will initialize the @handle context to be usable
49 * for encryption/decryption of data. This will effectively use the
50 * current crypto backend in use by gnutls or the cryptographic
51 * accelerator in use.
52 *
53 * Returns: Zero or a negative error code on error.
54 *
55 * Since: 2.10.0
56 **/
57 int
gnutls_cipher_init(gnutls_cipher_hd_t * handle,gnutls_cipher_algorithm_t cipher,const gnutls_datum_t * key,const gnutls_datum_t * iv)58 gnutls_cipher_init(gnutls_cipher_hd_t * handle,
59 gnutls_cipher_algorithm_t cipher,
60 const gnutls_datum_t * key, const gnutls_datum_t * iv)
61 {
62 api_cipher_hd_st *h;
63 int ret;
64 const cipher_entry_st* e;
65
66 if (is_cipher_algo_forbidden(cipher))
67 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
68
69 e = cipher_to_entry(cipher);
70 if (e == NULL || (e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD))
71 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
72
73 h = gnutls_calloc(1, sizeof(api_cipher_hd_st));
74 if (h == NULL) {
75 gnutls_assert();
76 return GNUTLS_E_MEMORY_ERROR;
77 }
78
79 ret =
80 _gnutls_cipher_init(&h->ctx_enc, e, key,
81 iv, 1);
82 if (ret < 0) {
83 gnutls_free(h);
84 return ret;
85 }
86
87 if (_gnutls_cipher_type(e) == CIPHER_BLOCK) {
88 ret =
89 _gnutls_cipher_init(&h->ctx_dec, e, key, iv, 0);
90 if (ret < 0) {
91 gnutls_free(h);
92 return ret;
93 }
94 }
95
96 *handle = h;
97
98 return ret;
99 }
100
101 /**
102 * gnutls_cipher_tag:
103 * @handle: is a #gnutls_cipher_hd_t type
104 * @tag: will hold the tag
105 * @tag_size: the length of the tag to return
106 *
107 * This function operates on authenticated encryption with
108 * associated data (AEAD) ciphers and will return the
109 * output tag.
110 *
111 * Returns: Zero or a negative error code on error.
112 *
113 * Since: 3.0
114 **/
115 int
gnutls_cipher_tag(gnutls_cipher_hd_t handle,void * tag,size_t tag_size)116 gnutls_cipher_tag(gnutls_cipher_hd_t handle, void *tag, size_t tag_size)
117 {
118 api_cipher_hd_st *h = handle;
119
120 if (_gnutls_cipher_is_aead(&h->ctx_enc) == 0)
121 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
122
123 _gnutls_cipher_tag(&h->ctx_enc, tag, tag_size);
124
125 return 0;
126 }
127
128 /**
129 * gnutls_cipher_add_auth:
130 * @handle: is a #gnutls_cipher_hd_t type
131 * @ptext: the data to be authenticated
132 * @ptext_size: the length of the data
133 *
134 * This function operates on authenticated encryption with
135 * associated data (AEAD) ciphers and authenticate the
136 * input data. This function can only be called once
137 * and before any encryption operations.
138 *
139 * Returns: Zero or a negative error code on error.
140 *
141 * Since: 3.0
142 **/
143 int
gnutls_cipher_add_auth(gnutls_cipher_hd_t handle,const void * ptext,size_t ptext_size)144 gnutls_cipher_add_auth(gnutls_cipher_hd_t handle, const void *ptext,
145 size_t ptext_size)
146 {
147 api_cipher_hd_st *h = handle;
148
149 if (_gnutls_cipher_is_aead(&h->ctx_enc) == 0)
150 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
151
152 return _gnutls_cipher_auth(&h->ctx_enc, ptext, ptext_size);
153 }
154
155 /**
156 * gnutls_cipher_set_iv:
157 * @handle: is a #gnutls_cipher_hd_t type
158 * @iv: the IV to set
159 * @ivlen: the length of the IV
160 *
161 * This function will set the IV to be used for the next
162 * encryption block.
163 *
164 * Since: 3.0
165 **/
166 void
gnutls_cipher_set_iv(gnutls_cipher_hd_t handle,void * iv,size_t ivlen)167 gnutls_cipher_set_iv(gnutls_cipher_hd_t handle, void *iv, size_t ivlen)
168 {
169 api_cipher_hd_st *h = handle;
170
171 if (_gnutls_cipher_setiv(&h->ctx_enc, iv, ivlen) < 0) {
172 _gnutls_switch_lib_state(LIB_STATE_ERROR);
173 }
174
175 if (_gnutls_cipher_type(h->ctx_enc.e) == CIPHER_BLOCK)
176 if (_gnutls_cipher_setiv(&h->ctx_dec, iv, ivlen) < 0) {
177 _gnutls_switch_lib_state(LIB_STATE_ERROR);
178 }
179 }
180
181 /*-
182 * _gnutls_cipher_get_iv:
183 * @handle: is a #gnutls_cipher_hd_t type
184 * @iv: the IV to set
185 * @ivlen: the length of the IV
186 *
187 * This function will retrieve the internally calculated IV value. It is
188 * intended to be used for modes like CFB. @iv must have @ivlen length
189 * at least.
190 *
191 * This is solely for validation purposes of our crypto
192 * implementation. For other purposes, the IV can be typically
193 * calculated from the initial IV value and the subsequent ciphertext
194 * values. As such, this function only works with the internally
195 * registered ciphers.
196 *
197 * Returns: The length of IV or a negative error code on error.
198 *
199 * Since: 3.6.8
200 -*/
201 int
_gnutls_cipher_get_iv(gnutls_cipher_hd_t handle,void * iv,size_t ivlen)202 _gnutls_cipher_get_iv(gnutls_cipher_hd_t handle, void *iv, size_t ivlen)
203 {
204 api_cipher_hd_st *h = handle;
205
206 return _gnutls_cipher_getiv(&h->ctx_enc, iv, ivlen);
207 }
208
209 /**
210 * gnutls_cipher_encrypt:
211 * @handle: is a #gnutls_cipher_hd_t type
212 * @ptext: the data to encrypt
213 * @ptext_len: the length of data to encrypt
214 *
215 * This function will encrypt the given data using the algorithm
216 * specified by the context.
217 *
218 * Returns: Zero or a negative error code on error.
219 *
220 * Since: 2.10.0
221 **/
222 int
gnutls_cipher_encrypt(gnutls_cipher_hd_t handle,void * ptext,size_t ptext_len)223 gnutls_cipher_encrypt(gnutls_cipher_hd_t handle, void *ptext,
224 size_t ptext_len)
225 {
226 api_cipher_hd_st *h = handle;
227
228 return _gnutls_cipher_encrypt(&h->ctx_enc, ptext, ptext_len);
229 }
230
231 /**
232 * gnutls_cipher_decrypt:
233 * @handle: is a #gnutls_cipher_hd_t type
234 * @ctext: the data to decrypt
235 * @ctext_len: the length of data to decrypt
236 *
237 * This function will decrypt the given data using the algorithm
238 * specified by the context.
239 *
240 * Note that in AEAD ciphers, this will not check the tag. You will
241 * need to compare the tag sent with the value returned from gnutls_cipher_tag().
242 *
243 * Returns: Zero or a negative error code on error.
244 *
245 * Since: 2.10.0
246 **/
247 int
gnutls_cipher_decrypt(gnutls_cipher_hd_t handle,void * ctext,size_t ctext_len)248 gnutls_cipher_decrypt(gnutls_cipher_hd_t handle, void *ctext,
249 size_t ctext_len)
250 {
251 api_cipher_hd_st *h = handle;
252
253 if (_gnutls_cipher_type(h->ctx_enc.e) != CIPHER_BLOCK)
254 return _gnutls_cipher_decrypt(&h->ctx_enc, ctext,
255 ctext_len);
256 else
257 return _gnutls_cipher_decrypt(&h->ctx_dec, ctext,
258 ctext_len);
259 }
260
261 /**
262 * gnutls_cipher_encrypt2:
263 * @handle: is a #gnutls_cipher_hd_t type
264 * @ptext: the data to encrypt
265 * @ptext_len: the length of data to encrypt
266 * @ctext: the encrypted data
267 * @ctext_len: the available length for encrypted data
268 *
269 * This function will encrypt the given data using the algorithm
270 * specified by the context. For block ciphers the @ptext_len must be
271 * a multiple of the block size. For the supported ciphers the encrypted
272 * data length will equal the plaintext size.
273 *
274 * Returns: Zero or a negative error code on error.
275 *
276 * Since: 2.12.0
277 **/
278 int
gnutls_cipher_encrypt2(gnutls_cipher_hd_t handle,const void * ptext,size_t ptext_len,void * ctext,size_t ctext_len)279 gnutls_cipher_encrypt2(gnutls_cipher_hd_t handle, const void *ptext,
280 size_t ptext_len, void *ctext,
281 size_t ctext_len)
282 {
283 api_cipher_hd_st *h = handle;
284
285 return _gnutls_cipher_encrypt2(&h->ctx_enc, ptext, ptext_len,
286 ctext, ctext_len);
287 }
288
289 /**
290 * gnutls_cipher_decrypt2:
291 * @handle: is a #gnutls_cipher_hd_t type
292 * @ctext: the data to decrypt
293 * @ctext_len: the length of data to decrypt
294 * @ptext: the decrypted data
295 * @ptext_len: the available length for decrypted data
296 *
297 * This function will decrypt the given data using the algorithm
298 * specified by the context. For block ciphers the @ctext_len must be
299 * a multiple of the block size. For the supported ciphers the plaintext
300 * data length will equal the ciphertext size.
301 *
302 * Note that in AEAD ciphers, this will not check the tag. You will
303 * need to compare the tag sent with the value returned from gnutls_cipher_tag().
304 *
305 * Returns: Zero or a negative error code on error.
306 *
307 * Since: 2.12.0
308 **/
309 int
gnutls_cipher_decrypt2(gnutls_cipher_hd_t handle,const void * ctext,size_t ctext_len,void * ptext,size_t ptext_len)310 gnutls_cipher_decrypt2(gnutls_cipher_hd_t handle, const void *ctext,
311 size_t ctext_len, void *ptext, size_t ptext_len)
312 {
313 api_cipher_hd_st *h = handle;
314
315 if (_gnutls_cipher_type(h->ctx_enc.e) != CIPHER_BLOCK)
316 return _gnutls_cipher_decrypt2(&h->ctx_enc, ctext,
317 ctext_len, ptext,
318 ptext_len);
319 else
320 return _gnutls_cipher_decrypt2(&h->ctx_dec, ctext,
321 ctext_len, ptext,
322 ptext_len);
323 }
324
325 /**
326 * gnutls_cipher_deinit:
327 * @handle: is a #gnutls_cipher_hd_t type
328 *
329 * This function will deinitialize all resources occupied by the given
330 * encryption context.
331 *
332 * Since: 2.10.0
333 **/
gnutls_cipher_deinit(gnutls_cipher_hd_t handle)334 void gnutls_cipher_deinit(gnutls_cipher_hd_t handle)
335 {
336 api_cipher_hd_st *h = handle;
337
338 _gnutls_cipher_deinit(&h->ctx_enc);
339 if (_gnutls_cipher_type(h->ctx_enc.e) == CIPHER_BLOCK)
340 _gnutls_cipher_deinit(&h->ctx_dec);
341 gnutls_free(handle);
342 }
343
344
345 /* HMAC */
346
347
348 /**
349 * gnutls_hmac_init:
350 * @dig: is a #gnutls_hmac_hd_t type
351 * @algorithm: the HMAC algorithm to use
352 * @key: the key to be used for encryption
353 * @keylen: the length of the key
354 *
355 * This function will initialize an context that can be used to
356 * produce a Message Authentication Code (MAC) of data. This will
357 * effectively use the current crypto backend in use by gnutls or the
358 * cryptographic accelerator in use.
359 *
360 * Note that despite the name of this function, it can be used
361 * for other MAC algorithms than HMAC.
362 *
363 * Returns: Zero or a negative error code on error.
364 *
365 * Since: 2.10.0
366 **/
367 int
gnutls_hmac_init(gnutls_hmac_hd_t * dig,gnutls_mac_algorithm_t algorithm,const void * key,size_t keylen)368 gnutls_hmac_init(gnutls_hmac_hd_t * dig,
369 gnutls_mac_algorithm_t algorithm,
370 const void *key, size_t keylen)
371 {
372 /* MD5 is only allowed internally for TLS */
373 if (is_mac_algo_forbidden(algorithm))
374 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
375
376 *dig = gnutls_malloc(sizeof(mac_hd_st));
377 if (*dig == NULL) {
378 gnutls_assert();
379 return GNUTLS_E_MEMORY_ERROR;
380 }
381
382 return _gnutls_mac_init(((mac_hd_st *) * dig),
383 mac_to_entry(algorithm), key, keylen);
384 }
385
386 /**
387 * gnutls_hmac_set_nonce:
388 * @handle: is a #gnutls_hmac_hd_t type
389 * @nonce: the data to set as nonce
390 * @nonce_len: the length of data
391 *
392 * This function will set the nonce in the MAC algorithm.
393 *
394 * Since: 3.2.0
395 **/
396 void
gnutls_hmac_set_nonce(gnutls_hmac_hd_t handle,const void * nonce,size_t nonce_len)397 gnutls_hmac_set_nonce(gnutls_hmac_hd_t handle, const void *nonce,
398 size_t nonce_len)
399 {
400 _gnutls_mac_set_nonce((mac_hd_st *) handle, nonce, nonce_len);
401 }
402
403 /**
404 * gnutls_hmac:
405 * @handle: is a #gnutls_hmac_hd_t type
406 * @ptext: the data to hash
407 * @ptext_len: the length of data to hash
408 *
409 * This function will hash the given data using the algorithm
410 * specified by the context.
411 *
412 * Returns: Zero or a negative error code on error.
413 *
414 * Since: 2.10.0
415 **/
gnutls_hmac(gnutls_hmac_hd_t handle,const void * ptext,size_t ptext_len)416 int gnutls_hmac(gnutls_hmac_hd_t handle, const void *ptext, size_t ptext_len)
417 {
418 return _gnutls_mac((mac_hd_st *) handle, ptext, ptext_len);
419 }
420
421 /**
422 * gnutls_hmac_output:
423 * @handle: is a #gnutls_hmac_hd_t type
424 * @digest: is the output value of the MAC
425 *
426 * This function will output the current MAC value
427 * and reset the state of the MAC.
428 *
429 * Since: 2.10.0
430 **/
gnutls_hmac_output(gnutls_hmac_hd_t handle,void * digest)431 void gnutls_hmac_output(gnutls_hmac_hd_t handle, void *digest)
432 {
433 _gnutls_mac_output((mac_hd_st *) handle, digest);
434 }
435
436 /**
437 * gnutls_hmac_deinit:
438 * @handle: is a #gnutls_hmac_hd_t type
439 * @digest: is the output value of the MAC
440 *
441 * This function will deinitialize all resources occupied by
442 * the given hmac context.
443 *
444 * Since: 2.10.0
445 **/
gnutls_hmac_deinit(gnutls_hmac_hd_t handle,void * digest)446 void gnutls_hmac_deinit(gnutls_hmac_hd_t handle, void *digest)
447 {
448 _gnutls_mac_deinit((mac_hd_st *) handle, digest);
449 gnutls_free(handle);
450 }
451
452 /**
453 * gnutls_hmac_get_len:
454 * @algorithm: the hmac algorithm to use
455 *
456 * This function will return the length of the output data
457 * of the given hmac algorithm.
458 *
459 * Returns: The length or zero on error.
460 *
461 * Since: 2.10.0
462 **/
gnutls_hmac_get_len(gnutls_mac_algorithm_t algorithm)463 unsigned gnutls_hmac_get_len(gnutls_mac_algorithm_t algorithm)
464 {
465 return _gnutls_mac_get_algo_len(mac_to_entry(algorithm));
466 }
467
468 /**
469 * gnutls_hmac_get_key_size:
470 * @algorithm: the mac algorithm to use
471 *
472 * This function will return the size of the key to be used with this
473 * algorithm. On the algorithms which may accept arbitrary key sizes,
474 * the returned size is the MAC key size used in the TLS protocol.
475 *
476 * Returns: The key size or zero on error.
477 *
478 * Since: 3.6.12
479 **/
gnutls_hmac_get_key_size(gnutls_mac_algorithm_t algorithm)480 unsigned gnutls_hmac_get_key_size(gnutls_mac_algorithm_t algorithm)
481 {
482 return _gnutls_mac_get_key_size(mac_to_entry(algorithm));
483 }
484
485 /**
486 * gnutls_hmac_fast:
487 * @algorithm: the hash algorithm to use
488 * @key: the key to use
489 * @keylen: the length of the key
490 * @ptext: the data to hash
491 * @ptext_len: the length of data to hash
492 * @digest: is the output value of the hash
493 *
494 * This convenience function will hash the given data and return output
495 * on a single call. Note, this call will not work for MAC algorithms
496 * that require nonce (like UMAC or GMAC).
497 *
498 * Returns: Zero or a negative error code on error.
499 *
500 * Since: 2.10.0
501 **/
502 int
gnutls_hmac_fast(gnutls_mac_algorithm_t algorithm,const void * key,size_t keylen,const void * ptext,size_t ptext_len,void * digest)503 gnutls_hmac_fast(gnutls_mac_algorithm_t algorithm,
504 const void *key, size_t keylen,
505 const void *ptext, size_t ptext_len, void *digest)
506 {
507 if (is_mac_algo_forbidden(algorithm))
508 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
509
510 return _gnutls_mac_fast(algorithm, key, keylen, ptext, ptext_len,
511 digest);
512 }
513
514 /**
515 * gnutls_hmac_copy:
516 * @handle: is a #gnutls_hmac_hd_t type
517 *
518 * This function will create a copy of MAC context, containing all its current
519 * state. Copying contexts for MACs registered using
520 * gnutls_crypto_register_mac() is not supported and will always result in an
521 * error.
522 *
523 * Returns: new MAC context or NULL in case of an error.
524 *
525 * Since: 3.6.9
526 */
gnutls_hmac_copy(gnutls_hmac_hd_t handle)527 gnutls_hmac_hd_t gnutls_hmac_copy(gnutls_hmac_hd_t handle)
528 {
529 gnutls_hmac_hd_t dig;
530
531 dig = gnutls_malloc(sizeof(mac_hd_st));
532 if (dig == NULL) {
533 gnutls_assert();
534 return NULL;
535 }
536
537 if (_gnutls_mac_copy((const mac_hd_st *) handle, (mac_hd_st *)dig) != GNUTLS_E_SUCCESS) {
538 gnutls_assert();
539 gnutls_free(dig);
540 return NULL;
541 }
542
543 return dig;
544 }
545
546 /* HASH */
547
548 /**
549 * gnutls_hash_init:
550 * @dig: is a #gnutls_hash_hd_t type
551 * @algorithm: the hash algorithm to use
552 *
553 * This function will initialize an context that can be used to
554 * produce a Message Digest of data. This will effectively use the
555 * current crypto backend in use by gnutls or the cryptographic
556 * accelerator in use.
557 *
558 * Returns: Zero or a negative error code on error.
559 *
560 * Since: 2.10.0
561 **/
562 int
gnutls_hash_init(gnutls_hash_hd_t * dig,gnutls_digest_algorithm_t algorithm)563 gnutls_hash_init(gnutls_hash_hd_t * dig,
564 gnutls_digest_algorithm_t algorithm)
565 {
566 if (is_mac_algo_forbidden(DIG_TO_MAC(algorithm)))
567 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
568
569 *dig = gnutls_malloc(sizeof(digest_hd_st));
570 if (*dig == NULL) {
571 gnutls_assert();
572 return GNUTLS_E_MEMORY_ERROR;
573 }
574
575 return _gnutls_hash_init(((digest_hd_st *) * dig),
576 hash_to_entry(algorithm));
577 }
578
579 /**
580 * gnutls_hash:
581 * @handle: is a #gnutls_hash_hd_t type
582 * @ptext: the data to hash
583 * @ptext_len: the length of data to hash
584 *
585 * This function will hash the given data using the algorithm
586 * specified by the context.
587 *
588 * Returns: Zero or a negative error code on error.
589 *
590 * Since: 2.10.0
591 **/
gnutls_hash(gnutls_hash_hd_t handle,const void * ptext,size_t ptext_len)592 int gnutls_hash(gnutls_hash_hd_t handle, const void *ptext, size_t ptext_len)
593 {
594 return _gnutls_hash((digest_hd_st *) handle, ptext, ptext_len);
595 }
596
597 /**
598 * gnutls_hash_output:
599 * @handle: is a #gnutls_hash_hd_t type
600 * @digest: is the output value of the hash
601 *
602 * This function will output the current hash value
603 * and reset the state of the hash.
604 *
605 * Since: 2.10.0
606 **/
gnutls_hash_output(gnutls_hash_hd_t handle,void * digest)607 void gnutls_hash_output(gnutls_hash_hd_t handle, void *digest)
608 {
609 _gnutls_hash_output((digest_hd_st *) handle, digest);
610 }
611
612 /**
613 * gnutls_hash_deinit:
614 * @handle: is a #gnutls_hash_hd_t type
615 * @digest: is the output value of the hash
616 *
617 * This function will deinitialize all resources occupied by
618 * the given hash context.
619 *
620 * Since: 2.10.0
621 **/
gnutls_hash_deinit(gnutls_hash_hd_t handle,void * digest)622 void gnutls_hash_deinit(gnutls_hash_hd_t handle, void *digest)
623 {
624 _gnutls_hash_deinit((digest_hd_st *) handle, digest);
625 gnutls_free(handle);
626 }
627
628 /**
629 * gnutls_hash_get_len:
630 * @algorithm: the hash algorithm to use
631 *
632 * This function will return the length of the output data
633 * of the given hash algorithm.
634 *
635 * Returns: The length or zero on error.
636 *
637 * Since: 2.10.0
638 **/
gnutls_hash_get_len(gnutls_digest_algorithm_t algorithm)639 unsigned gnutls_hash_get_len(gnutls_digest_algorithm_t algorithm)
640 {
641 return _gnutls_hash_get_algo_len(hash_to_entry(algorithm));
642 }
643
644 /**
645 * gnutls_hash_fast:
646 * @algorithm: the hash algorithm to use
647 * @ptext: the data to hash
648 * @ptext_len: the length of data to hash
649 * @digest: is the output value of the hash
650 *
651 * This convenience function will hash the given data and return output
652 * on a single call.
653 *
654 * Returns: Zero or a negative error code on error.
655 *
656 * Since: 2.10.0
657 **/
658 int
gnutls_hash_fast(gnutls_digest_algorithm_t algorithm,const void * ptext,size_t ptext_len,void * digest)659 gnutls_hash_fast(gnutls_digest_algorithm_t algorithm,
660 const void *ptext, size_t ptext_len, void *digest)
661 {
662 if (is_mac_algo_forbidden(DIG_TO_MAC(algorithm)))
663 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
664
665 return _gnutls_hash_fast(algorithm, ptext, ptext_len, digest);
666 }
667
668 /**
669 * gnutls_hash_copy:
670 * @handle: is a #gnutls_hash_hd_t type
671 *
672 * This function will create a copy of Message Digest context, containing all
673 * its current state. Copying contexts for Message Digests registered using
674 * gnutls_crypto_register_digest() is not supported and will always result in
675 * an error.
676 *
677 * Returns: new Message Digest context or NULL in case of an error.
678 *
679 * Since: 3.6.9
680 */
gnutls_hash_copy(gnutls_hash_hd_t handle)681 gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle)
682 {
683 gnutls_hash_hd_t dig;
684
685 dig = gnutls_malloc(sizeof(digest_hd_st));
686 if (dig == NULL) {
687 gnutls_assert();
688 return NULL;
689 }
690
691 if (_gnutls_hash_copy((const digest_hd_st *) handle, (digest_hd_st *)dig) != GNUTLS_E_SUCCESS) {
692 gnutls_assert();
693 gnutls_free(dig);
694 return NULL;
695 }
696
697 return dig;
698 }
699
700 /**
701 * gnutls_key_generate:
702 * @key: is a pointer to a #gnutls_datum_t which will contain a newly
703 * created key
704 * @key_size: the number of bytes of the key
705 *
706 * Generates a random key of @key_size bytes.
707 *
708 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or an
709 * error code.
710 *
711 * Since: 3.0
712 **/
gnutls_key_generate(gnutls_datum_t * key,unsigned int key_size)713 int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
714 {
715 int ret;
716
717 FAIL_IF_LIB_ERROR;
718
719 #ifdef ENABLE_FIPS140
720 /* The FIPS140 approved RNGs are not allowed to be used
721 * to extract key sizes longer than their original seed.
722 */
723 if (_gnutls_fips_mode_enabled() != 0 &&
724 key_size > FIPS140_RND_KEY_SIZE)
725 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
726 #endif
727
728 key->size = key_size;
729 key->data = gnutls_malloc(key->size);
730 if (!key->data) {
731 gnutls_assert();
732 return GNUTLS_E_MEMORY_ERROR;
733 }
734
735 ret = gnutls_rnd(GNUTLS_RND_RANDOM, key->data, key->size);
736 if (ret < 0) {
737 gnutls_assert();
738 _gnutls_free_datum(key);
739 return ret;
740 }
741
742 return 0;
743 }
744
745 /* AEAD API */
746
747 /**
748 * gnutls_aead_cipher_init:
749 * @handle: is a #gnutls_aead_cipher_hd_t type.
750 * @cipher: the authenticated-encryption algorithm to use
751 * @key: The key to be used for encryption
752 *
753 * This function will initialize an context that can be used for
754 * encryption/decryption of data. This will effectively use the
755 * current crypto backend in use by gnutls or the cryptographic
756 * accelerator in use.
757 *
758 * Returns: Zero or a negative error code on error.
759 *
760 * Since: 3.4.0
761 **/
gnutls_aead_cipher_init(gnutls_aead_cipher_hd_t * handle,gnutls_cipher_algorithm_t cipher,const gnutls_datum_t * key)762 int gnutls_aead_cipher_init(gnutls_aead_cipher_hd_t *handle,
763 gnutls_cipher_algorithm_t cipher,
764 const gnutls_datum_t *key)
765 {
766 api_aead_cipher_hd_st *h;
767 const cipher_entry_st *e;
768 int ret;
769
770 if (is_cipher_algo_forbidden(cipher))
771 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
772
773 e = cipher_to_entry(cipher);
774 if (e == NULL || e->type != CIPHER_AEAD)
775 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
776
777 h = gnutls_calloc(1, sizeof(api_aead_cipher_hd_st));
778 if (h == NULL) {
779 gnutls_assert();
780 return GNUTLS_E_MEMORY_ERROR;
781 }
782
783 ret = _gnutls_aead_cipher_init(h, cipher, key);
784 if (ret < 0) {
785 gnutls_free(h);
786 return ret;
787 }
788
789 *handle = h;
790
791 return ret;
792 }
793
794 /**
795 * gnutls_aead_cipher_decrypt:
796 * @handle: is a #gnutls_aead_cipher_hd_t type.
797 * @nonce: the nonce to set
798 * @nonce_len: The length of the nonce
799 * @auth: additional data to be authenticated
800 * @auth_len: The length of the data
801 * @tag_size: The size of the tag to use (use zero for the default)
802 * @ctext: the data to decrypt (including the authentication tag)
803 * @ctext_len: the length of data to decrypt (includes tag size)
804 * @ptext: the decrypted data
805 * @ptext_len: the length of decrypted data (initially must hold the maximum available size)
806 *
807 * This function will decrypt the given data using the algorithm
808 * specified by the context. This function must be provided the complete
809 * data to be decrypted, including the authentication tag. On several
810 * AEAD ciphers, the authentication tag is appended to the ciphertext,
811 * though this is not a general rule. This function will fail if
812 * the tag verification fails.
813 *
814 * Returns: Zero or a negative error code on verification failure or other error.
815 *
816 * Since: 3.4.0
817 **/
818 int
gnutls_aead_cipher_decrypt(gnutls_aead_cipher_hd_t handle,const void * nonce,size_t nonce_len,const void * auth,size_t auth_len,size_t tag_size,const void * ctext,size_t ctext_len,void * ptext,size_t * ptext_len)819 gnutls_aead_cipher_decrypt(gnutls_aead_cipher_hd_t handle,
820 const void *nonce, size_t nonce_len,
821 const void *auth, size_t auth_len,
822 size_t tag_size,
823 const void *ctext, size_t ctext_len,
824 void *ptext, size_t *ptext_len)
825 {
826 int ret;
827 api_aead_cipher_hd_st *h = handle;
828
829 if (tag_size == 0)
830 tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
831 else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e))
832 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
833
834 if (unlikely(ctext_len < tag_size))
835 return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
836
837 ret = _gnutls_aead_cipher_decrypt(&h->ctx_enc,
838 nonce, nonce_len,
839 auth, auth_len,
840 tag_size,
841 ctext, ctext_len,
842 ptext, *ptext_len);
843 if (unlikely(ret < 0))
844 return gnutls_assert_val(ret);
845
846 /* That assumes that AEAD ciphers are stream */
847 *ptext_len = ctext_len - tag_size;
848
849 return 0;
850 }
851
852
853 /**
854 * gnutls_aead_cipher_encrypt:
855 * @handle: is a #gnutls_aead_cipher_hd_t type.
856 * @nonce: the nonce to set
857 * @nonce_len: The length of the nonce
858 * @auth: additional data to be authenticated
859 * @auth_len: The length of the data
860 * @tag_size: The size of the tag to use (use zero for the default)
861 * @ptext: the data to encrypt
862 * @ptext_len: The length of data to encrypt
863 * @ctext: the encrypted data including authentication tag
864 * @ctext_len: the length of encrypted data (initially must hold the maximum available size, including space for tag)
865 *
866 * This function will encrypt the given data using the algorithm
867 * specified by the context. The output data will contain the
868 * authentication tag.
869 *
870 * Returns: Zero or a negative error code on error.
871 *
872 * Since: 3.4.0
873 **/
874 int
gnutls_aead_cipher_encrypt(gnutls_aead_cipher_hd_t handle,const void * nonce,size_t nonce_len,const void * auth,size_t auth_len,size_t tag_size,const void * ptext,size_t ptext_len,void * ctext,size_t * ctext_len)875 gnutls_aead_cipher_encrypt(gnutls_aead_cipher_hd_t handle,
876 const void *nonce, size_t nonce_len,
877 const void *auth, size_t auth_len,
878 size_t tag_size,
879 const void *ptext, size_t ptext_len,
880 void *ctext, size_t *ctext_len)
881 {
882 api_aead_cipher_hd_st *h = handle;
883 int ret;
884
885 if (tag_size == 0)
886 tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
887 else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e))
888 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
889
890 if (unlikely(*ctext_len < ptext_len + tag_size))
891 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
892
893 ret = _gnutls_aead_cipher_encrypt(&h->ctx_enc,
894 nonce, nonce_len,
895 auth, auth_len,
896 tag_size,
897 ptext, ptext_len,
898 ctext, *ctext_len);
899 if (unlikely(ret < 0))
900 return gnutls_assert_val(ret);
901
902 /* That assumes that AEAD ciphers are stream */
903 *ctext_len = ptext_len + tag_size;
904
905 return 0;
906 }
907
908 struct iov_store_st {
909 void *data;
910 size_t size;
911 };
912
iov_store_free(struct iov_store_st * s)913 static void iov_store_free(struct iov_store_st *s)
914 {
915 gnutls_free(s->data);
916 }
917
iov_store_grow(struct iov_store_st * s,size_t length)918 static int iov_store_grow(struct iov_store_st *s, size_t length)
919 {
920 void *data;
921
922 s->size += length;
923 data = gnutls_realloc(s->data, s->size);
924 if (data == NULL)
925 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
926
927 s->data = data;
928 return 0;
929 }
930
931 static int
copy_from_iov(struct iov_store_st * dst,const giovec_t * iov,int iovcnt)932 copy_from_iov(struct iov_store_st *dst, const giovec_t *iov, int iovcnt)
933 {
934 memset(dst, 0, sizeof(*dst));
935 if (iovcnt == 0) {
936 return 0;
937 } else {
938 int i;
939 uint8_t *p;
940
941 dst->size = 0;
942 for (i=0;i<iovcnt;i++)
943 dst->size += iov[i].iov_len;
944 dst->data = gnutls_malloc(dst->size);
945 if (dst->data == NULL)
946 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
947
948 p = dst->data;
949 for (i=0;i<iovcnt;i++) {
950 if (iov[i].iov_len > 0)
951 memcpy(p, iov[i].iov_base, iov[i].iov_len);
952 p += iov[i].iov_len;
953 }
954
955 return 0;
956 }
957 }
958
959 static int
copy_to_iov(struct iov_store_st * src,size_t size,const giovec_t * iov,int iovcnt)960 copy_to_iov(struct iov_store_st *src, size_t size,
961 const giovec_t *iov, int iovcnt)
962 {
963 size_t offset = 0;
964 int i;
965
966 if (unlikely(src->size < size))
967 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
968
969 for (i = 0; i < iovcnt && size > 0; i++) {
970 size_t to_copy = MIN(size, iov[i].iov_len);
971 memcpy(iov[i].iov_base, (uint8_t *) src->data + offset, to_copy);
972 offset += to_copy;
973 size -= to_copy;
974 }
975 if (size > 0)
976 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
977 return 0;
978 }
979
980
981 /**
982 * gnutls_aead_cipher_encryptv:
983 * @handle: is a #gnutls_aead_cipher_hd_t type.
984 * @nonce: the nonce to set
985 * @nonce_len: The length of the nonce
986 * @auth_iov: additional data to be authenticated
987 * @auth_iovcnt: The number of buffers in @auth_iov
988 * @tag_size: The size of the tag to use (use zero for the default)
989 * @iov: the data to be encrypted
990 * @iovcnt: The number of buffers in @iov
991 * @ctext: the encrypted data including authentication tag
992 * @ctext_len: the length of encrypted data (initially must hold the maximum available size, including space for tag)
993 *
994 * This function will encrypt the provided data buffers using the algorithm
995 * specified by the context. The output data will contain the
996 * authentication tag.
997 *
998 * Returns: Zero or a negative error code on error.
999 *
1000 * Since: 3.6.3
1001 **/
1002 int
gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,const void * nonce,size_t nonce_len,const giovec_t * auth_iov,int auth_iovcnt,size_t tag_size,const giovec_t * iov,int iovcnt,void * ctext,size_t * ctext_len)1003 gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
1004 const void *nonce, size_t nonce_len,
1005 const giovec_t *auth_iov, int auth_iovcnt,
1006 size_t tag_size,
1007 const giovec_t *iov, int iovcnt,
1008 void *ctext, size_t *ctext_len)
1009 {
1010 api_aead_cipher_hd_st *h = handle;
1011 ssize_t ret;
1012 uint8_t *dst;
1013 size_t dst_size, total = 0;
1014 uint8_t *p;
1015 size_t len;
1016 size_t blocksize = handle->ctx_enc.e->blocksize;
1017 struct iov_iter_st iter;
1018
1019 /* Limitation: this function provides an optimization under the internally registered
1020 * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
1021 * then this becomes a convenience function as it missed the lower-level primitives
1022 * necessary for piecemeal encryption. */
1023
1024 if (tag_size == 0)
1025 tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
1026 else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e))
1027 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1028
1029 if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
1030 /* ciphertext cannot be produced in a piecemeal approach */
1031 struct iov_store_st auth;
1032 struct iov_store_st ptext;
1033
1034 ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
1035 if (ret < 0)
1036 return gnutls_assert_val(ret);
1037
1038 ret = copy_from_iov(&ptext, iov, iovcnt);
1039 if (ret < 0) {
1040 iov_store_free(&auth);
1041 return gnutls_assert_val(ret);
1042 }
1043
1044 ret = gnutls_aead_cipher_encrypt(handle, nonce, nonce_len,
1045 auth.data, auth.size,
1046 tag_size,
1047 ptext.data, ptext.size,
1048 ctext, ctext_len);
1049 iov_store_free(&auth);
1050 iov_store_free(&ptext);
1051
1052 return ret;
1053 }
1054
1055 ret = _gnutls_cipher_setiv(&handle->ctx_enc, nonce, nonce_len);
1056 if (unlikely(ret < 0))
1057 return gnutls_assert_val(ret);
1058
1059 ret = _gnutls_iov_iter_init(&iter, auth_iov, auth_iovcnt, blocksize);
1060 if (unlikely(ret < 0))
1061 return gnutls_assert_val(ret);
1062 while (1) {
1063 ret = _gnutls_iov_iter_next(&iter, &p);
1064 if (unlikely(ret < 0))
1065 return gnutls_assert_val(ret);
1066 if (ret == 0)
1067 break;
1068 ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
1069 if (unlikely(ret < 0))
1070 return gnutls_assert_val(ret);
1071 }
1072
1073 dst = ctext;
1074 dst_size = *ctext_len;
1075
1076 ret = _gnutls_iov_iter_init(&iter, iov, iovcnt, blocksize);
1077 if (unlikely(ret < 0))
1078 return gnutls_assert_val(ret);
1079 while (1) {
1080 ret = _gnutls_iov_iter_next(&iter, &p);
1081 if (unlikely(ret < 0))
1082 return gnutls_assert_val(ret);
1083 if (ret == 0)
1084 break;
1085 len = ret;
1086 ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
1087 p, len,
1088 dst, dst_size);
1089 if (unlikely(ret < 0))
1090 return gnutls_assert_val(ret);
1091 DECR_LEN(dst_size, len);
1092 dst += len;
1093 total += len;
1094 }
1095
1096 if (dst_size < tag_size)
1097 return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
1098
1099 _gnutls_cipher_tag(&handle->ctx_enc, dst, tag_size);
1100
1101 total += tag_size;
1102 *ctext_len = total;
1103
1104 return 0;
1105 }
1106
1107 /**
1108 * gnutls_aead_cipher_encryptv2:
1109 * @handle: is a #gnutls_aead_cipher_hd_t type.
1110 * @nonce: the nonce to set
1111 * @nonce_len: The length of the nonce
1112 * @auth_iov: additional data to be authenticated
1113 * @auth_iovcnt: The number of buffers in @auth_iov
1114 * @iov: the data to be encrypted
1115 * @iovcnt: The number of buffers in @iov
1116 * @tag: The authentication tag
1117 * @tag_size: The size of the tag to use (use zero for the default)
1118 *
1119 * This is similar to gnutls_aead_cipher_encrypt(), but it performs
1120 * in-place encryption on the provided data buffers.
1121 *
1122 * Returns: Zero or a negative error code on error.
1123 *
1124 * Since: 3.6.10
1125 **/
1126 int
gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,const void * nonce,size_t nonce_len,const giovec_t * auth_iov,int auth_iovcnt,const giovec_t * iov,int iovcnt,void * tag,size_t * tag_size)1127 gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
1128 const void *nonce, size_t nonce_len,
1129 const giovec_t *auth_iov, int auth_iovcnt,
1130 const giovec_t *iov, int iovcnt,
1131 void *tag, size_t *tag_size)
1132 {
1133 api_aead_cipher_hd_st *h = handle;
1134 ssize_t ret;
1135 uint8_t *p;
1136 size_t len;
1137 ssize_t blocksize = handle->ctx_enc.e->blocksize;
1138 struct iov_iter_st iter;
1139 size_t _tag_size;
1140
1141 if (tag_size == NULL || *tag_size == 0)
1142 _tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
1143 else
1144 _tag_size = *tag_size;
1145
1146 if (_tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e))
1147 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1148
1149 /* Limitation: this function provides an optimization under the internally registered
1150 * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
1151 * then this becomes a convenience function as it missed the lower-level primitives
1152 * necessary for piecemeal encryption. */
1153 if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
1154 /* ciphertext cannot be produced in a piecemeal approach */
1155 struct iov_store_st auth;
1156 struct iov_store_st ptext;
1157 size_t ptext_size;
1158
1159 ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
1160 if (ret < 0)
1161 return gnutls_assert_val(ret);
1162
1163 ret = copy_from_iov(&ptext, iov, iovcnt);
1164 if (ret < 0) {
1165 gnutls_assert();
1166 goto fallback_fail;
1167 }
1168
1169 ptext_size = ptext.size;
1170
1171 /* append space for tag */
1172 ret = iov_store_grow(&ptext, _tag_size);
1173 if (ret < 0) {
1174 gnutls_assert();
1175 goto fallback_fail;
1176 }
1177
1178 ret = gnutls_aead_cipher_encrypt(handle, nonce, nonce_len,
1179 auth.data, auth.size,
1180 _tag_size,
1181 ptext.data, ptext_size,
1182 ptext.data, &ptext.size);
1183 if (ret < 0) {
1184 gnutls_assert();
1185 goto fallback_fail;
1186 }
1187
1188 ret = copy_to_iov(&ptext, ptext_size, iov, iovcnt);
1189 if (ret < 0) {
1190 gnutls_assert();
1191 goto fallback_fail;
1192 }
1193
1194 if (tag != NULL)
1195 memcpy(tag,
1196 (uint8_t *) ptext.data + ptext_size,
1197 _tag_size);
1198 if (tag_size != NULL)
1199 *tag_size = _tag_size;
1200
1201 fallback_fail:
1202 iov_store_free(&auth);
1203 iov_store_free(&ptext);
1204
1205 return ret;
1206 }
1207
1208 ret = _gnutls_cipher_setiv(&handle->ctx_enc, nonce, nonce_len);
1209 if (unlikely(ret < 0))
1210 return gnutls_assert_val(ret);
1211
1212 ret = _gnutls_iov_iter_init(&iter, auth_iov, auth_iovcnt, blocksize);
1213 if (unlikely(ret < 0))
1214 return gnutls_assert_val(ret);
1215 while (1) {
1216 ret = _gnutls_iov_iter_next(&iter, &p);
1217 if (unlikely(ret < 0))
1218 return gnutls_assert_val(ret);
1219 if (ret == 0)
1220 break;
1221 ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
1222 if (unlikely(ret < 0))
1223 return gnutls_assert_val(ret);
1224 }
1225
1226 ret = _gnutls_iov_iter_init(&iter, iov, iovcnt, blocksize);
1227 if (unlikely(ret < 0))
1228 return gnutls_assert_val(ret);
1229 while (1) {
1230 ret = _gnutls_iov_iter_next(&iter, &p);
1231 if (unlikely(ret < 0))
1232 return gnutls_assert_val(ret);
1233 if (ret == 0)
1234 break;
1235
1236 len = ret;
1237 ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, len, p, len);
1238 if (unlikely(ret < 0))
1239 return gnutls_assert_val(ret);
1240
1241 ret = _gnutls_iov_iter_sync(&iter, p, len);
1242 if (unlikely(ret < 0))
1243 return gnutls_assert_val(ret);
1244 }
1245
1246 if (tag != NULL)
1247 _gnutls_cipher_tag(&handle->ctx_enc, tag, _tag_size);
1248 if (tag_size != NULL)
1249 *tag_size = _tag_size;
1250
1251 return 0;
1252 }
1253
1254 /**
1255 * gnutls_aead_cipher_decryptv2:
1256 * @handle: is a #gnutls_aead_cipher_hd_t type.
1257 * @nonce: the nonce to set
1258 * @nonce_len: The length of the nonce
1259 * @auth_iov: additional data to be authenticated
1260 * @auth_iovcnt: The number of buffers in @auth_iov
1261 * @iov: the data to decrypt
1262 * @iovcnt: The number of buffers in @iov
1263 * @tag: The authentication tag
1264 * @tag_size: The size of the tag to use (use zero for the default)
1265 *
1266 * This is similar to gnutls_aead_cipher_decrypt(), but it performs
1267 * in-place encryption on the provided data buffers.
1268 *
1269 * Returns: Zero or a negative error code on error.
1270 *
1271 * Since: 3.6.10
1272 **/
1273 int
gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,const void * nonce,size_t nonce_len,const giovec_t * auth_iov,int auth_iovcnt,const giovec_t * iov,int iovcnt,void * tag,size_t tag_size)1274 gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
1275 const void *nonce, size_t nonce_len,
1276 const giovec_t *auth_iov, int auth_iovcnt,
1277 const giovec_t *iov, int iovcnt,
1278 void *tag, size_t tag_size)
1279 {
1280 api_aead_cipher_hd_st *h = handle;
1281 ssize_t ret;
1282 uint8_t *p;
1283 size_t len;
1284 ssize_t blocksize = handle->ctx_enc.e->blocksize;
1285 struct iov_iter_st iter;
1286 uint8_t _tag[MAX_HASH_SIZE];
1287
1288 if (tag_size == 0)
1289 tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
1290 else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e))
1291 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1292
1293 /* Limitation: this function provides an optimization under the internally registered
1294 * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
1295 * then this becomes a convenience function as it missed the lower-level primitives
1296 * necessary for piecemeal encryption. */
1297 if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
1298 /* ciphertext cannot be produced in a piecemeal approach */
1299 struct iov_store_st auth;
1300 struct iov_store_st ctext;
1301 size_t ctext_size;
1302
1303 ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
1304 if (ret < 0)
1305 return gnutls_assert_val(ret);
1306
1307 ret = copy_from_iov(&ctext, iov, iovcnt);
1308 if (ret < 0) {
1309 gnutls_assert();
1310 goto fallback_fail;
1311 }
1312
1313 ctext_size = ctext.size;
1314
1315 /* append tag */
1316 ret = iov_store_grow(&ctext, tag_size);
1317 if (ret < 0) {
1318 gnutls_assert();
1319 goto fallback_fail;
1320 }
1321 memcpy((uint8_t *) ctext.data + ctext_size, tag, tag_size);
1322
1323 ret = gnutls_aead_cipher_decrypt(handle, nonce, nonce_len,
1324 auth.data, auth.size,
1325 tag_size,
1326 ctext.data, ctext.size,
1327 ctext.data, &ctext_size);
1328 if (ret < 0) {
1329 gnutls_assert();
1330 goto fallback_fail;
1331 }
1332
1333 ret = copy_to_iov(&ctext, ctext_size, iov, iovcnt);
1334 if (ret < 0) {
1335 gnutls_assert();
1336 goto fallback_fail;
1337 }
1338
1339 fallback_fail:
1340 iov_store_free(&auth);
1341 iov_store_free(&ctext);
1342
1343 return ret;
1344 }
1345
1346 ret = _gnutls_cipher_setiv(&handle->ctx_enc, nonce, nonce_len);
1347 if (unlikely(ret < 0))
1348 return gnutls_assert_val(ret);
1349
1350 ret = _gnutls_iov_iter_init(&iter, auth_iov, auth_iovcnt, blocksize);
1351 if (unlikely(ret < 0))
1352 return gnutls_assert_val(ret);
1353 while (1) {
1354 ret = _gnutls_iov_iter_next(&iter, &p);
1355 if (unlikely(ret < 0))
1356 return gnutls_assert_val(ret);
1357 if (ret == 0)
1358 break;
1359 ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
1360 if (unlikely(ret < 0))
1361 return gnutls_assert_val(ret);
1362 }
1363
1364 ret = _gnutls_iov_iter_init(&iter, iov, iovcnt, blocksize);
1365 if (unlikely(ret < 0))
1366 return gnutls_assert_val(ret);
1367 while (1) {
1368 ret = _gnutls_iov_iter_next(&iter, &p);
1369 if (unlikely(ret < 0))
1370 return gnutls_assert_val(ret);
1371 if (ret == 0)
1372 break;
1373
1374 len = ret;
1375 ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, len, p, len);
1376 if (unlikely(ret < 0))
1377 return gnutls_assert_val(ret);
1378
1379 ret = _gnutls_iov_iter_sync(&iter, p, len);
1380 if (unlikely(ret < 0))
1381 return gnutls_assert_val(ret);
1382 }
1383
1384 if (tag != NULL) {
1385 _gnutls_cipher_tag(&handle->ctx_enc, _tag, tag_size);
1386 if (gnutls_memcmp(_tag, tag, tag_size) != 0)
1387 return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
1388 }
1389
1390 return 0;
1391 }
1392
1393 /**
1394 * gnutls_aead_cipher_deinit:
1395 * @handle: is a #gnutls_aead_cipher_hd_t type.
1396 *
1397 * This function will deinitialize all resources occupied by the given
1398 * authenticated-encryption context.
1399 *
1400 * Since: 3.4.0
1401 **/
gnutls_aead_cipher_deinit(gnutls_aead_cipher_hd_t handle)1402 void gnutls_aead_cipher_deinit(gnutls_aead_cipher_hd_t handle)
1403 {
1404 _gnutls_aead_cipher_deinit(handle);
1405 gnutls_free(handle);
1406 }
1407
1408 extern gnutls_crypto_kdf_st _gnutls_kdf_ops;
1409
1410 /**
1411 * gnutls_hkdf_extract:
1412 * @mac: the mac algorithm used internally
1413 * @key: the initial keying material
1414 * @salt: the optional salt
1415 * @output: the output value of the extract operation
1416 *
1417 * This function will derive a fixed-size key using the HKDF-Extract
1418 * function as defined in RFC 5869.
1419 *
1420 * Returns: Zero or a negative error code on error.
1421 *
1422 * Since: 3.6.13
1423 */
1424 int
gnutls_hkdf_extract(gnutls_mac_algorithm_t mac,const gnutls_datum_t * key,const gnutls_datum_t * salt,void * output)1425 gnutls_hkdf_extract(gnutls_mac_algorithm_t mac,
1426 const gnutls_datum_t *key,
1427 const gnutls_datum_t *salt,
1428 void *output)
1429 {
1430 /* MD5 is only allowed internally for TLS */
1431 if (is_mac_algo_forbidden(mac))
1432 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
1433
1434 return _gnutls_kdf_ops.hkdf_extract(mac, key->data, key->size,
1435 salt ? salt->data : NULL,
1436 salt ? salt->size : 0,
1437 output);
1438 }
1439
1440 /**
1441 * gnutls_hkdf_expand:
1442 * @mac: the mac algorithm used internally
1443 * @key: the pseudorandom key created with HKDF-Extract
1444 * @info: the optional informational data
1445 * @output: the output value of the expand operation
1446 * @length: the desired length of the output key
1447 *
1448 * This function will derive a variable length keying material from
1449 * the pseudorandom key using the HKDF-Expand function as defined in
1450 * RFC 5869.
1451 *
1452 * Returns: Zero or a negative error code on error.
1453 *
1454 * Since: 3.6.13
1455 */
1456 int
gnutls_hkdf_expand(gnutls_mac_algorithm_t mac,const gnutls_datum_t * key,const gnutls_datum_t * info,void * output,size_t length)1457 gnutls_hkdf_expand(gnutls_mac_algorithm_t mac,
1458 const gnutls_datum_t *key,
1459 const gnutls_datum_t *info,
1460 void *output, size_t length)
1461 {
1462 /* MD5 is only allowed internally for TLS */
1463 if (is_mac_algo_forbidden(mac))
1464 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
1465
1466 return _gnutls_kdf_ops.hkdf_expand(mac, key->data, key->size,
1467 info->data, info->size,
1468 output, length);
1469 }
1470
1471 /**
1472 * gnutls_pbkdf2:
1473 * @mac: the mac algorithm used internally
1474 * @key: the initial keying material
1475 * @salt: the salt
1476 * @iter_count: the iteration count
1477 * @output: the output value
1478 * @length: the desired length of the output key
1479 *
1480 * This function will derive a variable length keying material from
1481 * a password according to PKCS #5 PBKDF2.
1482 *
1483 * Returns: Zero or a negative error code on error.
1484 *
1485 * Since: 3.6.13
1486 */
1487 int
gnutls_pbkdf2(gnutls_mac_algorithm_t mac,const gnutls_datum_t * key,const gnutls_datum_t * salt,unsigned iter_count,void * output,size_t length)1488 gnutls_pbkdf2(gnutls_mac_algorithm_t mac,
1489 const gnutls_datum_t *key,
1490 const gnutls_datum_t *salt,
1491 unsigned iter_count,
1492 void *output, size_t length)
1493 {
1494 /* MD5 is only allowed internally for TLS */
1495 if (is_mac_algo_forbidden(mac))
1496 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
1497
1498 return _gnutls_kdf_ops.pbkdf2(mac, key->data, key->size,
1499 salt->data, salt->size, iter_count,
1500 output, length);
1501 }
1502