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