return 0;
}
+static int
+aead_cipher_encryptv_fallback(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)
+{
+ struct iov_store_st auth;
+ struct iov_store_st ptext;
+ int ret;
-/**
- * gnutls_aead_cipher_encryptv:
- * @handle: is a #gnutls_aead_cipher_hd_t type.
- * @nonce: the nonce to set
- * @nonce_len: The length of the nonce
- * @auth_iov: additional data to be authenticated
- * @auth_iovcnt: The number of buffers in @auth_iov
- * @tag_size: The size of the tag to use (use zero for the default)
- * @iov: the data to be encrypted
- * @iovcnt: The number of buffers in @iov
- * @ctext: the encrypted data including authentication tag
- * @ctext_len: the length of encrypted data (initially must hold the maximum available size, including space for tag)
- *
- * This function will encrypt the provided data buffers using the algorithm
- * specified by the context. The output data will contain the
- * authentication tag.
- *
- * Returns: Zero or a negative error code on error.
- *
- * Since: 3.6.3
- **/
-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)
+ if (tag_size == 0)
+ tag_size = _gnutls_cipher_get_tag_size(handle->ctx_enc.e);
+ else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(handle->ctx_enc.e)) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+
+ ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(ret);
+ }
+
+ ret = copy_from_iov(&ptext, iov, iovcnt);
+ if (ret < 0) {
+ iov_store_free(&auth);
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(ret);
+ }
+
+ ret = gnutls_aead_cipher_encrypt(handle, nonce, nonce_len,
+ auth.data, auth.size,
+ tag_size,
+ ptext.data, ptext.size,
+ ctext, ctext_len);
+ iov_store_free(&auth);
+ iov_store_free(&ptext);
+
+ /* FIPS operation state is set by gnutls_aead_cipher_encrypt */
+ return ret;
+}
+
+static int
+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)
{
- api_aead_cipher_hd_st *h = handle;
- ssize_t ret;
+ int ret;
uint8_t *dst;
size_t dst_size, total = 0;
uint8_t *p;
size_t blocksize = handle->ctx_enc.e->blocksize;
struct iov_iter_st iter;
- /* Limitation: this function provides an optimization under the internally registered
- * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
- * then this becomes a convenience function as it missed the lower-level primitives
- * necessary for piecemeal encryption. */
-
if (tag_size == 0)
- tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
- else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e)) {
+ tag_size = _gnutls_cipher_get_tag_size(handle->ctx_enc.e);
+ else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(handle->ctx_enc.e)) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
- if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
- /* ciphertext cannot be produced in a piecemeal approach */
- struct iov_store_st auth;
- struct iov_store_st ptext;
-
- ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
- if (ret < 0) {
- _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
- return gnutls_assert_val(ret);
- }
-
- ret = copy_from_iov(&ptext, iov, iovcnt);
- if (ret < 0) {
- iov_store_free(&auth);
- _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
- return gnutls_assert_val(ret);
- }
-
- ret = gnutls_aead_cipher_encrypt(handle, nonce, nonce_len,
- auth.data, auth.size,
- tag_size,
- ptext.data, ptext.size,
- ctext, ctext_len);
- iov_store_free(&auth);
- iov_store_free(&ptext);
-
- /* FIPS operation state is set by gnutls_aead_cipher_encrypt */
- return ret;
- }
-
ret = _gnutls_cipher_setiv(&handle->ctx_enc, nonce, nonce_len);
if (unlikely(ret < 0)) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
}
/**
- * gnutls_aead_cipher_encryptv2:
+ * gnutls_aead_cipher_encryptv:
* @handle: is a #gnutls_aead_cipher_hd_t type.
* @nonce: the nonce to set
* @nonce_len: The length of the nonce
* @auth_iov: additional data to be authenticated
* @auth_iovcnt: The number of buffers in @auth_iov
+ * @tag_size: The size of the tag to use (use zero for the default)
* @iov: the data to be encrypted
* @iovcnt: The number of buffers in @iov
- * @tag: The authentication tag
- * @tag_size: The size of the tag to use (use zero for the default)
+ * @ctext: the encrypted data including authentication tag
+ * @ctext_len: the length of encrypted data (initially must hold the maximum available size, including space for tag)
*
- * This is similar to gnutls_aead_cipher_encrypt(), but it performs
- * in-place encryption on the provided data buffers.
+ * This function will encrypt the provided data buffers using the algorithm
+ * specified by the context. The output data will contain the
+ * authentication tag.
*
* Returns: Zero or a negative error code on error.
*
- * Since: 3.6.10
+ * Since: 3.6.3
**/
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)
+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)
+{
+ /* Limitation: this function provides an optimization under the internally registered
+ * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
+ * then this becomes a convenience function as it missed the lower-level primitives
+ * necessary for piecemeal encryption. */
+ if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) ||
+ handle->ctx_enc.encrypt == NULL) {
+ return aead_cipher_encryptv_fallback(handle,
+ nonce, nonce_len,
+ auth_iov, auth_iovcnt,
+ tag_size,
+ iov, iovcnt,
+ ctext, ctext_len);
+ } else {
+ return aead_cipher_encryptv(handle,
+ nonce, nonce_len,
+ auth_iov, auth_iovcnt,
+ tag_size,
+ iov, iovcnt,
+ ctext, ctext_len);
+ }
+}
+
+static int
+aead_cipher_encryptv2_fallback(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)
{
- api_aead_cipher_hd_st *h = handle;
- ssize_t ret;
- uint8_t *p;
- size_t len;
- ssize_t blocksize = handle->ctx_enc.e->blocksize;
- struct iov_iter_st iter;
size_t _tag_size;
+ struct iov_store_st auth;
+ struct iov_store_st ptext;
+ size_t ptext_size;
+ int ret;
if (tag_size == NULL || *tag_size == 0)
- _tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
+ _tag_size = _gnutls_cipher_get_tag_size(handle->ctx_enc.e);
else
_tag_size = *tag_size;
- if (_tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e)) {
+ if (_tag_size > (unsigned)_gnutls_cipher_get_tag_size(handle->ctx_enc.e)) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
- /* Limitation: this function provides an optimization under the internally registered
- * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
- * then this becomes a convenience function as it missed the lower-level primitives
- * necessary for piecemeal encryption. */
- if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
- /* ciphertext cannot be produced in a piecemeal approach */
- struct iov_store_st auth;
- struct iov_store_st ptext;
- size_t ptext_size;
+ ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(ret);
+ }
- ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
- if (ret < 0) {
- _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
- return gnutls_assert_val(ret);
- }
+ ret = copy_from_iov(&ptext, iov, iovcnt);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- ret = copy_from_iov(&ptext, iov, iovcnt);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ ptext_size = ptext.size;
- ptext_size = ptext.size;
+ /* append space for tag */
+ ret = iov_store_grow(&ptext, _tag_size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- /* append space for tag */
- ret = iov_store_grow(&ptext, _tag_size);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ ret = gnutls_aead_cipher_encrypt(handle, nonce, nonce_len,
+ auth.data, auth.size,
+ _tag_size,
+ ptext.data, ptext_size,
+ ptext.data, &ptext.size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- ret = gnutls_aead_cipher_encrypt(handle, nonce, nonce_len,
- auth.data, auth.size,
- _tag_size,
- ptext.data, ptext_size,
- ptext.data, &ptext.size);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ ret = copy_to_iov(&ptext, ptext_size, iov, iovcnt);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- ret = copy_to_iov(&ptext, ptext_size, iov, iovcnt);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ if (tag != NULL)
+ memcpy(tag,
+ (uint8_t *) ptext.data + ptext_size,
+ _tag_size);
+ if (tag_size != NULL)
+ *tag_size = _tag_size;
- if (tag != NULL)
- memcpy(tag,
- (uint8_t *) ptext.data + ptext_size,
- _tag_size);
- if (tag_size != NULL)
- *tag_size = _tag_size;
+ error:
+ iov_store_free(&auth);
+ iov_store_free(&ptext);
- fallback_fail:
- iov_store_free(&auth);
- iov_store_free(&ptext);
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ }
+ /* FIPS operation state is set by gnutls_aead_cipher_encrypt */
+ return ret;
+}
- if (ret < 0) {
- _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
- }
- /* FIPS operation state is set by gnutls_aead_cipher_encrypt */
- return ret;
+static int
+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)
+{
+ api_aead_cipher_hd_st *h = handle;
+ int ret;
+ uint8_t *p;
+ size_t len;
+ size_t blocksize = handle->ctx_enc.e->blocksize;
+ struct iov_iter_st iter;
+ size_t _tag_size;
+
+ if (tag_size == NULL || *tag_size == 0)
+ _tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
+ else
+ _tag_size = *tag_size;
+
+ if (_tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e)) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
ret = _gnutls_cipher_setiv(&handle->ctx_enc, nonce, nonce_len);
}
/**
- * gnutls_aead_cipher_decryptv2:
+ * gnutls_aead_cipher_encryptv2:
* @handle: is a #gnutls_aead_cipher_hd_t type.
* @nonce: the nonce to set
* @nonce_len: The length of the nonce
* @auth_iov: additional data to be authenticated
* @auth_iovcnt: The number of buffers in @auth_iov
- * @iov: the data to decrypt
+ * @iov: the data to be encrypted
* @iovcnt: The number of buffers in @iov
* @tag: The authentication tag
* @tag_size: The size of the tag to use (use zero for the default)
*
- * This is similar to gnutls_aead_cipher_decrypt(), but it performs
+ * This is similar to gnutls_aead_cipher_encrypt(), but it performs
* in-place encryption on the provided data buffers.
*
* Returns: Zero or a negative error code on error.
* Since: 3.6.10
**/
int
-gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
+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)
+ void *tag, size_t *tag_size)
{
- api_aead_cipher_hd_st *h = handle;
- ssize_t ret;
- uint8_t *p;
- size_t len;
- ssize_t blocksize = handle->ctx_enc.e->blocksize;
- struct iov_iter_st iter;
- uint8_t _tag[MAX_HASH_SIZE];
+ /* Limitation: this function provides an optimization under the internally registered
+ * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
+ * then this becomes a convenience function as it missed the lower-level primitives
+ * necessary for piecemeal encryption. */
+ if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) ||
+ handle->ctx_enc.encrypt == NULL) {
+ return aead_cipher_encryptv2_fallback(handle,
+ nonce, nonce_len,
+ auth_iov, auth_iovcnt,
+ iov, iovcnt,
+ tag, tag_size);
+ } else {
+ return aead_cipher_encryptv2(handle,
+ nonce, nonce_len,
+ auth_iov, auth_iovcnt,
+ iov, iovcnt,
+ tag, tag_size);
+ }
+}
+
+static int
+aead_cipher_decryptv2_fallback(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)
+{
+ struct iov_store_st auth;
+ struct iov_store_st ctext;
+ size_t ctext_size;
+ int ret;
if (tag_size == 0)
- tag_size = _gnutls_cipher_get_tag_size(h->ctx_enc.e);
- else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(h->ctx_enc.e)) {
+ tag_size = _gnutls_cipher_get_tag_size(handle->ctx_enc.e);
+ else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(handle->ctx_enc.e)) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
- /* Limitation: this function provides an optimization under the internally registered
- * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
- * then this becomes a convenience function as it missed the lower-level primitives
- * necessary for piecemeal encryption. */
- if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) || handle->ctx_enc.encrypt == NULL) {
- /* ciphertext cannot be produced in a piecemeal approach */
- struct iov_store_st auth;
- struct iov_store_st ctext;
- size_t ctext_size;
+ ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(ret);
+ }
- ret = copy_from_iov(&auth, auth_iov, auth_iovcnt);
- if (ret < 0) {
- _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
- return gnutls_assert_val(ret);
- }
+ ret = copy_from_iov(&ctext, iov, iovcnt);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- ret = copy_from_iov(&ctext, iov, iovcnt);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ ctext_size = ctext.size;
- ctext_size = ctext.size;
+ /* append tag */
+ ret = iov_store_grow(&ctext, tag_size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
+ memcpy((uint8_t *) ctext.data + ctext_size, tag, tag_size);
- /* append tag */
- ret = iov_store_grow(&ctext, tag_size);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
- memcpy((uint8_t *) ctext.data + ctext_size, tag, tag_size);
+ ret = gnutls_aead_cipher_decrypt(handle, nonce, nonce_len,
+ auth.data, auth.size,
+ tag_size,
+ ctext.data, ctext.size,
+ ctext.data, &ctext_size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- ret = gnutls_aead_cipher_decrypt(handle, nonce, nonce_len,
- auth.data, auth.size,
- tag_size,
- ctext.data, ctext.size,
- ctext.data, &ctext_size);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ ret = copy_to_iov(&ctext, ctext_size, iov, iovcnt);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
- ret = copy_to_iov(&ctext, ctext_size, iov, iovcnt);
- if (ret < 0) {
- gnutls_assert();
- goto fallback_fail;
- }
+ error:
+ iov_store_free(&auth);
+ iov_store_free(&ctext);
- fallback_fail:
- iov_store_free(&auth);
- iov_store_free(&ctext);
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ }
+ /* FIPS operation state is set by gnutls_aead_cipher_decrypt */
+ return ret;
+}
- if (ret < 0) {
- _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
- }
- /* FIPS operation state is set by gnutls_aead_cipher_decrypt */
- return ret;
+static int
+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)
+{
+ int ret;
+ uint8_t *p;
+ size_t len;
+ ssize_t blocksize = handle->ctx_enc.e->blocksize;
+ struct iov_iter_st iter;
+ uint8_t _tag[MAX_HASH_SIZE];
+
+ if (tag_size == 0)
+ tag_size = _gnutls_cipher_get_tag_size(handle->ctx_enc.e);
+ else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(handle->ctx_enc.e)) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
ret = _gnutls_cipher_setiv(&handle->ctx_enc, nonce, nonce_len);
return 0;
}
+/**
+ * gnutls_aead_cipher_decryptv2:
+ * @handle: is a #gnutls_aead_cipher_hd_t type.
+ * @nonce: the nonce to set
+ * @nonce_len: The length of the nonce
+ * @auth_iov: additional data to be authenticated
+ * @auth_iovcnt: The number of buffers in @auth_iov
+ * @iov: the data to decrypt
+ * @iovcnt: The number of buffers in @iov
+ * @tag: The authentication tag
+ * @tag_size: The size of the tag to use (use zero for the default)
+ *
+ * This is similar to gnutls_aead_cipher_decrypt(), but it performs
+ * in-place encryption on the provided data buffers.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.6.10
+ **/
+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)
+{
+ /* Limitation: this function provides an optimization under the internally registered
+ * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
+ * then this becomes a convenience function as it missed the lower-level primitives
+ * necessary for piecemeal encryption. */
+ if ((handle->ctx_enc.e->flags & GNUTLS_CIPHER_FLAG_ONLY_AEAD) ||
+ handle->ctx_enc.encrypt == NULL) {
+ return aead_cipher_decryptv2_fallback(handle,
+ nonce, nonce_len,
+ auth_iov, auth_iovcnt,
+ iov, iovcnt,
+ tag, tag_size);
+ } else {
+ return aead_cipher_decryptv2(handle,
+ nonce, nonce_len,
+ auth_iov, auth_iovcnt,
+ iov, iovcnt,
+ tag, tag_size);
+ }
+}
+
/**
* gnutls_aead_cipher_deinit:
* @handle: is a #gnutls_aead_cipher_hd_t type.