summaryrefslogtreecommitdiff
path: root/lib/crypto-api.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2014-10-25 14:55:48 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2014-10-25 15:24:10 +0200
commit959361023776b857c4a397e1cd301561e88f2e93 (patch)
treee07b16a292b15aee74336d2761c9017014e9d0df /lib/crypto-api.c
parent4aa59d7daa95f7ee40dfeb61fdfa331a1d33eb63 (diff)
downloadgnutls-959361023776b857c4a397e1cd301561e88f2e93.tar.gz
Added a new simple to use AEAD API
Diffstat (limited to 'lib/crypto-api.c')
-rw-r--r--lib/crypto-api.c225
1 files changed, 221 insertions, 4 deletions
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
index 3353a261c9..9b6c79c084 100644
--- a/lib/crypto-api.c
+++ b/lib/crypto-api.c
@@ -185,8 +185,8 @@ gnutls_cipher_encrypt(gnutls_cipher_hd_t handle, void *text,
/**
* gnutls_cipher_decrypt:
* @handle: is a #gnutls_cipher_hd_t structure.
- * @ciphertext: the data to encrypt
- * @ciphertextlen: The length of data to encrypt
+ * @ciphertext: the data to decrypt
+ * @ciphertextlen: The length of data to decrypt
*
* This function will decrypt the given data using the algorithm
* specified by the context.
@@ -241,8 +241,8 @@ gnutls_cipher_encrypt2(gnutls_cipher_hd_t handle, const void *text,
/**
* gnutls_cipher_decrypt2:
* @handle: is a #gnutls_cipher_hd_t structure.
- * @ciphertext: the data to encrypt
- * @ciphertextlen: The length of data to encrypt
+ * @ciphertext: the data to decrypt
+ * @ciphertextlen: The length of data to decrypt
* @text: the decrypted data
* @textlen: The available length for decrypted data
*
@@ -613,3 +613,220 @@ int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size)
return 0;
}
+
+/* AEAD API */
+typedef struct api_aead_cipher_hd_st {
+ cipher_hd_st ctx_enc;
+ unsigned tag_size;
+ unsigned nonce_set;
+} api_aead_cipher_hd_st;
+
+/**
+ * gnutls_aead_cipher_init:
+ * @handle: is a #gnutls_aead_cipher_hd_t structure.
+ * @cipher: the authenticated-encryption algorithm to use
+ * @key: The key to be used for encryption
+ * @tag_size: The size of the tag to use (use zero for the default)
+ *
+ * This function will initialize an context that can be used for
+ * encryption/decryption of data. This will effectively use the
+ * current crypto backend in use by gnutls or the cryptographic
+ * accelerator in use.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.4.0
+ **/
+int gnutls_aead_cipher_init(gnutls_aead_cipher_hd_t * handle,
+ gnutls_cipher_algorithm_t cipher,
+ const gnutls_datum_t * key,
+ unsigned tag_size)
+{
+ api_aead_cipher_hd_st *h;
+ const cipher_entry_st* e;
+
+ e = cipher_to_entry(cipher);
+ if (e == NULL || e->aead == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ if (tag_size == 0)
+ tag_size = _gnutls_cipher_get_tag_size(e);
+ else if (tag_size > (unsigned)_gnutls_cipher_get_tag_size(e))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ *handle = gnutls_calloc(1, sizeof(api_aead_cipher_hd_st));
+ if (*handle == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ h = *handle;
+ h->tag_size = tag_size;
+
+ return
+ _gnutls_cipher_init(&h->ctx_enc, e, key,
+ NULL, 1);
+}
+
+/**
+ * gnutls_aead_cipher_decrypt:
+ * @handle: is a #gnutls_aead_cipher_hd_t structure.
+ * @ciphertext: the data to decrypt
+ * @ciphertextlen: the length of data to decrypt
+ * @text: the decrypted data
+ * @textlen: the length of decrypted data (initially must hold the maximum available size)
+ *
+ * This function will decrypt the given data using the algorithm
+ * specified by the context. This function must be provided the whole
+ * data to be decrypted, including the tag, and will fail if the tag
+ * verification fails.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.4.0
+ **/
+int
+gnutls_aead_cipher_decrypt(gnutls_aead_cipher_hd_t handle,
+ const void *ciphertext, size_t ciphertextlen,
+ void *text, size_t *textlen)
+{
+ int ret;
+ api_aead_cipher_hd_st *h = handle;
+ uint8_t tag[MAX_HASH_SIZE];
+ const uint8_t *ptr;
+
+ if (ciphertextlen < h->tag_size)
+ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
+ ciphertextlen -= h->tag_size;
+
+ if (ciphertextlen > 0) {
+ ret = _gnutls_cipher_decrypt2(&h->ctx_enc, ciphertext,
+ ciphertextlen, text, *textlen);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
+ /* That assumes that AEAD ciphers are stream */
+ *textlen = ciphertextlen;
+
+ _gnutls_cipher_tag(&h->ctx_enc, tag, h->tag_size);
+
+ ptr = ciphertext;
+ ptr += ciphertextlen;
+ if (memcmp(ptr, tag, h->tag_size) != 0)
+ return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
+
+ return 0;
+}
+
+
+/**
+ * gnutls_aead_cipher_encrypt:
+ * @handle: is a #gnutls_aead_cipher_hd_t structure.
+ * @text: the data to encrypt
+ * @textlen: The length of data to encrypt
+ * @ciphertext: the encrypted data
+ * @ciphertextlen: the length of encrypted data (initially must hold the maximum available size)
+ *
+ * This function will encrypt the given data 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.4.0
+ **/
+int
+gnutls_aead_cipher_encrypt(gnutls_aead_cipher_hd_t handle,
+ const void *text, size_t textlen,
+ void *ciphertext, size_t *ciphertextlen)
+{
+ api_aead_cipher_hd_st *h = handle;
+ uint8_t *ptr;
+ int ret;
+
+ if (*ciphertextlen < textlen + h->tag_size)
+ return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ if (h->nonce_set == 0)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret = _gnutls_cipher_encrypt2(&h->ctx_enc, text, textlen,
+ ciphertext, *ciphertextlen);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ /* That assumes that AEAD ciphers are stream */
+ *ciphertextlen = textlen + h->tag_size;
+
+ ptr = ciphertext;
+ ptr += textlen;
+ _gnutls_cipher_tag(&h->ctx_enc, ptr, h->tag_size);
+ h->nonce_set = 0;
+
+ return 0;
+}
+
+/**
+ * gnutls_aead_cipher_set_nonce:
+ * @handle: is a #gnutls_aead_cipher_hd_t structure.
+ * @nonce: the nonce to set
+ * @nonce_len: The length of the nonce
+ *
+ * This function will set the nonce to be used for the next
+ * encryption block. The recommended size of the nonce is
+ * returned by gnutls_cipher_get_iv_size().
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.4.0
+ **/
+int
+gnutls_aead_cipher_set_nonce(gnutls_aead_cipher_hd_t handle, void *nonce, size_t nonce_len)
+{
+ api_aead_cipher_hd_st *h = handle;
+
+ h->nonce_set = 1;
+ return _gnutls_cipher_setiv(&h->ctx_enc, nonce, nonce_len);
+}
+
+
+/**
+ * gnutls_aead_cipher_add_auth:
+ * @handle: is a #gnutls_aead_cipher_hd_t structure.
+ * @text: the data to be authenticated
+ * @text_size: The length of the data
+ *
+ * This function operates on authenticated encryption with
+ * associated data (AEAD) ciphers and authenticate the
+ * input data. This function can only be called once
+ * and before any encryption operations.
+ *
+ * Returns: Zero or a negative error code on error.
+ *
+ * Since: 3.4.0
+ **/
+int
+gnutls_aead_cipher_add_auth(gnutls_aead_cipher_hd_t handle, const void *text,
+ size_t text_size)
+{
+ api_aead_cipher_hd_st *h = handle;
+
+ _gnutls_cipher_auth(&h->ctx_enc, text, text_size);
+ return 0;
+}
+
+/**
+ * gnutls_aead_cipher_deinit:
+ * @handle: is a #gnutls_aead_cipher_hd_t structure.
+ *
+ * This function will deinitialize all resources occupied by the given
+ * authenticated-encryption context.
+ *
+ * Since: 3.4.0
+ **/
+void gnutls_aead_cipher_deinit(gnutls_aead_cipher_hd_t handle)
+{
+ api_aead_cipher_hd_st *h = handle;
+
+ _gnutls_cipher_deinit(&h->ctx_enc);
+ gnutls_free(handle);
+}