summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-11-10 19:52:00 +0100
committerMiloslav Trmač <mitr@redhat.com>2010-11-11 00:19:05 +0100
commite61cf3bf79883fe9dd98371fee543c61b89330bf (patch)
treedd1f66abbda16ffc009441192f7d447f9eb371fd
parentbd08fece6e5c509dc22588c93303b067c6900b56 (diff)
downloadncrypto-e61cf3bf79883fe9dd98371fee543c61b89330bf.tar.gz
ncrypto-e61cf3bf79883fe9dd98371fee543c61b89330bf.tar.xz
ncrypto-e61cf3bf79883fe9dd98371fee543c61b89330bf.zip
Port symmetric encryption to AF_ALG
-rw-r--r--lib/ncrypto_alg.c429
-rw-r--r--lib/ncrypto_local.c289
2 files changed, 429 insertions, 289 deletions
diff --git a/lib/ncrypto_alg.c b/lib/ncrypto_alg.c
index d3a8393..7d91b40 100644
--- a/lib/ncrypto_alg.c
+++ b/lib/ncrypto_alg.c
@@ -802,3 +802,432 @@ ncr_symm_signature_verify (struct ncr_symm_signature_session *sess,
sess->state = NSSS_FINISHED;
return ret;
}
+
+ /* Symmetric encryption */
+
+static CK_RV
+cipher_params_from_mech (CK_MECHANISM_TYPE mech,
+ const struct sockaddr_alg **sa_ptr)
+{
+ const struct sockaddr_alg *sa;
+
+ switch (mech)
+ {
+#define E(MECH, NAME) \
+ case CKM_##MECH: \
+ { \
+ static const struct sockaddr_alg addr = \
+ { \
+ .salg_family = AF_ALG, .salg_type = "skcipher", \
+ .salg_name = (NAME) \
+ }; \
+ \
+ sa = &addr; \
+ break; \
+ } \
+
+ E(AES_ECB, "ecb(aes)");
+ E(AES_CBC, "cbc(aes)");
+ E(DES3_ECB, "ecb(des3_ede)");
+ E(DES3_CBC, "cbc(des3_ede)");
+
+ default:
+ g_return_val_if_reached (CKR_MECHANISM_INVALID);
+ }
+ *sa_ptr = sa;
+ return CKR_OK;
+}
+
+struct ncr_symm_cipher_session
+{
+ int parent_fd, child_fd;
+ CK_MECHANISM_TYPE mech;
+ bool encrypting;
+ /* Debugging only */
+ enum { NSCS_NEW, NSCS_INITIALIZED, NSCS_UPDATED, NSCS_FINISHED } state;
+};
+
+CK_RV
+ncr_symm_cipher_alloc (struct ncr_symm_cipher_session **sess,
+ CK_MECHANISM_TYPE mech)
+{
+ struct ncr_symm_cipher_session *s;
+ const struct sockaddr_alg *sa;
+ CK_RV res;
+
+ g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
+
+ res = cipher_params_from_mech (mech, &sa);
+ if (res != CKR_OK)
+ return res;
+
+ s = malloc (sizeof (*s));
+ if (s == NULL)
+ return CKR_HOST_MEMORY;
+
+ s->parent_fd = socket (AF_ALG, SOCK_SEQPACKET, 0);
+ if (s->parent_fd == -1)
+ {
+ res = ckr_errno ();
+ goto err_s;
+ }
+ if (bind (s->parent_fd, (struct sockaddr *)sa, sizeof (*sa)) != 0)
+ {
+ res = ckr_errno ();
+ goto err_parent_fd;
+ }
+
+ s->child_fd = -1;
+ s->mech = mech;
+ s->state = NSCS_NEW;
+ *sess = s;
+ return CKR_OK;
+
+ err_parent_fd:
+ (void)close (s->parent_fd);
+ err_s:
+ free (s);
+ return res;
+}
+
+CK_RV
+ncr_symm_cipher_free (struct ncr_symm_cipher_session *sess)
+{
+ g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
+
+ if (sess->child_fd != -1)
+ (void)close (sess->child_fd);
+ (void)close (sess->parent_fd);
+ free (sess);
+ return CKR_OK;
+}
+
+static CK_RV
+symm_cipher_init (struct ncr_symm_cipher_session *sess, bool encrypt,
+ struct ncr_symm_key *key, const void *param,
+ size_t param_size)
+{
+ uint8_t cmsg_buf[4096]; /* The size is arbitrary. */
+ size_t cmsg_space;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct af_alg_iv iv;
+
+ g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
+ g_return_val_if_fail (sess->state == NSCS_NEW || sess->state == NSCS_FINISHED,
+ CKR_OPERATION_ACTIVE);
+ g_return_val_if_fail (key != NULL, CKR_KEY_HANDLE_INVALID);
+ /* We need key->size to fit into socklen_t. There is no SOCKLEN_MAX, but
+ it is at least INT32_MAX, which is plenty. */
+ g_return_val_if_fail (key->size <= INT32_MAX, CKR_KEY_SIZE_RANGE);
+ g_return_val_if_fail (param != NULL || param_size == 0, CKR_ARGUMENTS_BAD);
+ /* Implicitly restricts param_size so that it fits into iv.ivlen */
+ cmsg_space = CMSG_SPACE (sizeof (iv) + param_size);
+ g_return_val_if_fail (cmsg_space <= sizeof (cmsg_buf),
+ CKR_MECHANISM_PARAM_INVALID);
+
+ switch (sess->mech)
+ {
+ case CKM_AES_ECB:
+ case CKM_AES_CBC:
+ g_return_val_if_fail (key->type == CKK_AES, CKR_KEY_TYPE_INCONSISTENT);
+ break;
+
+ case CKM_DES3_ECB:
+ case CKM_DES3_CBC:
+ g_return_val_if_fail (key->type == CKK_DES3, CKR_KEY_TYPE_INCONSISTENT);
+ break;
+
+ default:
+ g_return_val_if_reached (CKR_MECHANISM_INVALID);
+ }
+
+ if (setsockopt (sess->parent_fd, SOL_ALG, ALG_SET_KEY, key->value,
+ key->size) != 0)
+ return ckr_errno ();
+
+ sess->child_fd = accept (sess->parent_fd, NULL, 0);
+ if (sess->child_fd == -1)
+ return ckr_errno ();
+
+ /* The IV might be left pending until the first actual data arrives, saving
+ one system call, but we prefer reporting invalid IV immediately. */
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = NULL;
+ msg.msg_iovlen = 0;
+ msg.msg_control = cmsg_buf;
+ msg.msg_controllen = cmsg_space;
+
+ iv.ivlen = param_size;
+ cmsg = CMSG_FIRSTHDR (&msg);
+ g_return_val_if_fail (cmsg != NULL, CKR_GENERAL_ERROR); /* What? */
+ cmsg->cmsg_len = CMSG_LEN (sizeof (iv) + param_size);
+ cmsg->cmsg_level = SOL_ALG;
+ cmsg->cmsg_type = ALG_SET_IV;
+ memcpy (CMSG_DATA (cmsg), &iv, sizeof (iv));
+ memcpy (CMSG_DATA (cmsg) + sizeof (iv), param, param_size);
+
+ if (sendmsg (sess->child_fd, &msg, MSG_MORE) != 0)
+ {
+ CK_RV res;
+
+ res = ckr_errno ();
+ (void)close (sess->child_fd);
+ sess->child_fd = -1;
+ return res;
+ }
+
+ sess->encrypting = encrypt;
+ sess->state = NSCS_INITIALIZED;
+ return CKR_OK;
+}
+
+static CK_RV
+symm_cipher_update (struct ncr_symm_cipher_session *sess, bool encrypt,
+ void *dest, size_t *dest_size_ptr, const void *src,
+ size_t src_size)
+{
+ size_t done;
+ uint32_t alg_op;
+ uint8_t cmsg_buf[CMSG_SPACE (sizeof (alg_op))];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+
+ g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
+ g_return_val_if_fail (dest_size_ptr != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (src_size <= SSIZE_MAX, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess->state == NSCS_INITIALIZED
+ || sess->state == NSCS_UPDATED,
+ CKR_OPERATION_NOT_INITIALIZED);
+ g_return_val_if_fail (sess->encrypting == encrypt,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ if (dest == NULL)
+ {
+ *dest_size_ptr = src_size;
+ return CKR_OK;
+ }
+ if (*dest_size_ptr < src_size)
+ {
+ *dest_size_ptr = src_size;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ g_return_val_if_fail (dest != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (src != NULL || src_size == 0, CKR_ARGUMENTS_BAD);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsg_buf;
+ msg.msg_controllen = sizeof (cmsg_buf);
+
+ alg_op = sess->encrypting ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT;
+ cmsg = CMSG_FIRSTHDR (&msg);
+ cmsg->cmsg_len = CMSG_LEN (sizeof (alg_op));
+ cmsg->cmsg_level = SOL_ALG;
+ cmsg->cmsg_type = ALG_SET_OP;
+ memcpy (CMSG_DATA (cmsg), &alg_op, sizeof (alg_op));
+
+ done = 0;
+ while (done < src_size)
+ {
+ ssize_t run, ret;
+
+ iov.iov_base = (uint8_t *)src + done;
+ iov.iov_len = src_size - done;
+ run = sendmsg (sess->child_fd, &msg, MSG_DONTWAIT | MSG_MORE);
+ if (run < 0)
+ /* The IV may have already been changed if some partial data was
+ previously accepted, too bad. */
+ return ckr_errno ();
+ g_return_val_if_fail (run != 0, CKR_GENERAL_ERROR); /* What? */
+ ret = recvfrom (sess->child_fd, (uint8_t *)dest + done, run, MSG_DONTWAIT,
+ NULL, 0);
+ if (ret < 0)
+ return ckr_errno ();
+ g_return_val_if_fail (ret == run, CKR_GENERAL_ERROR);
+ done += run;
+ }
+
+ *dest_size_ptr = src_size;
+ sess->state = NSCS_UPDATED;
+ return CKR_OK;
+}
+
+/* EVP_CipherUpdate + EVP_CipherFinal_ex */
+static CK_RV
+do_symm_cipher_update_final (struct ncr_symm_cipher_session *sess,
+ bool encrypt, void *dest, size_t *dest_size_ptr,
+ const void *src, size_t src_size)
+{
+ size_t done;
+ uint32_t alg_op;
+ uint8_t cmsg_buf[CMSG_SPACE (sizeof (alg_op))];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+ CK_RV res;
+
+ /* The caller has verified session and its state. */
+ g_return_val_if_fail (dest_size_ptr != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (src_size <= SSIZE_MAX, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess->encrypting == encrypt,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ if (dest == NULL)
+ {
+ *dest_size_ptr = src_size;
+ return CKR_OK;
+ }
+ if (*dest_size_ptr < src_size)
+ {
+ *dest_size_ptr = src_size;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ g_return_val_if_fail (dest != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (src != NULL || src_size == 0, CKR_ARGUMENTS_BAD);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = cmsg_buf;
+ msg.msg_controllen = sizeof (cmsg_buf);
+
+ alg_op = sess->encrypting ? ALG_OP_ENCRYPT : ALG_OP_DECRYPT;
+ cmsg = CMSG_FIRSTHDR (&msg);
+ cmsg->cmsg_len = CMSG_LEN (sizeof (alg_op));
+ cmsg->cmsg_level = SOL_ALG;
+ cmsg->cmsg_type = ALG_SET_OP;
+ memcpy (CMSG_DATA (cmsg), &alg_op, sizeof (alg_op));
+
+ done = 0;
+ while (done < src_size)
+ {
+ ssize_t run, ret;
+
+ iov.iov_base = (uint8_t *)src + done;
+ iov.iov_len = src_size - done;
+ run = sendmsg (sess->child_fd, &msg, MSG_DONTWAIT /* no MSG_MORE */);
+ if (run < 0)
+ {
+ /* The IV may have already been changed if some partial data was
+ previously accepted, too bad. */
+ res = ckr_errno ();
+ goto err;
+ }
+ g_return_val_if_fail (run != 0, CKR_GENERAL_ERROR); /* What? */
+ ret = recvfrom (sess->child_fd, (uint8_t *)dest + done, run, MSG_DONTWAIT,
+ NULL, 0);
+ if (ret < 0)
+ {
+ res = ckr_errno ();
+ goto err;
+ }
+ g_return_val_if_fail (ret == run, CKR_GENERAL_ERROR);
+ done += run;
+ }
+
+ *dest_size_ptr = src_size;
+ res = CKR_OK;
+ err:
+ (void)close (sess->child_fd);
+ sess->child_fd = -1;
+ sess->state = NSCS_FINISHED;
+ return res;
+}
+
+static CK_RV
+symm_cipher_final (struct ncr_symm_cipher_session *sess, bool encrypt,
+ void *dest, size_t *dest_size_ptr, const void *src,
+ size_t src_size)
+{
+ g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
+ g_return_val_if_fail (sess->state == NSCS_INITIALIZED
+ || sess->state == NSCS_UPDATED,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ return do_symm_cipher_update_final (sess, encrypt, dest, dest_size_ptr, src,
+ src_size);
+}
+
+static CK_RV
+symm_cipher (struct ncr_symm_cipher_session *sess, bool encrypt, void *dest,
+ size_t *dest_size_ptr, const void *src, size_t src_size)
+{
+ g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
+ g_return_val_if_fail (sess->state == NSCS_INITIALIZED,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ return do_symm_cipher_update_final (sess, encrypt, dest, dest_size_ptr, src,
+ src_size);
+}
+
+CK_RV
+ncr_symm_cipher_encrypt_init (struct ncr_symm_cipher_session *sess,
+ struct ncr_symm_key *key, const void *param,
+ size_t param_size)
+{
+ return symm_cipher_init (sess, true, key, param, param_size);
+}
+
+CK_RV
+ncr_symm_cipher_encrypt_update (struct ncr_symm_cipher_session *sess,
+ void *dest, size_t *dest_size_ptr,
+ const void *src, size_t src_size)
+{
+ return symm_cipher_update (sess, true, dest, dest_size_ptr, src, src_size);
+}
+
+CK_RV
+ncr_symm_cipher_encrypt_final (struct ncr_symm_cipher_session *sess, void *dest,
+ size_t *dest_size_ptr, const void *src,
+ size_t src_size)
+{
+ return symm_cipher_final (sess, true, dest, dest_size_ptr, src, src_size);
+}
+
+CK_RV
+ncr_symm_cipher_encrypt (struct ncr_symm_cipher_session *sess, void *dest,
+ size_t *dest_size_ptr, const void *src,
+ size_t src_size)
+{
+ return symm_cipher (sess, true, dest, dest_size_ptr, src, src_size);
+}
+
+CK_RV
+ncr_symm_cipher_decrypt_init (struct ncr_symm_cipher_session *sess,
+ struct ncr_symm_key *key, const void *param,
+ size_t param_size)
+{
+ return symm_cipher_init (sess, false, key, param, param_size);
+}
+
+CK_RV
+ncr_symm_cipher_decrypt_update (struct ncr_symm_cipher_session *sess,
+ void *dest, size_t *dest_size_ptr,
+ const void *src, size_t src_size)
+{
+ return symm_cipher_update (sess, false, dest, dest_size_ptr, src, src_size);
+}
+
+CK_RV
+ncr_symm_cipher_decrypt_final (struct ncr_symm_cipher_session *sess, void *dest,
+ size_t *dest_size_ptr, const void *src,
+ size_t src_size)
+{
+ return symm_cipher_final (sess, false, dest, dest_size_ptr, src, src_size);
+}
+
+CK_RV
+ncr_symm_cipher_decrypt (struct ncr_symm_cipher_session *sess, void *dest,
+ size_t *dest_size_ptr, const void *src,
+ size_t src_size)
+{
+ return symm_cipher (sess, false, dest, dest_size_ptr, src, src_size);
+}
diff --git a/lib/ncrypto_local.c b/lib/ncrypto_local.c
index 6d7af27..b06808d 100644
--- a/lib/ncrypto_local.c
+++ b/lib/ncrypto_local.c
@@ -31,8 +31,6 @@ Red Hat author: Miloslav Trmač <mitr@redhat.com> */
#include <string.h>
#include <glib.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <ncrypto/ncrypto.h>
@@ -239,290 +237,3 @@ ncr_symm_key_destroy (struct ncr_symm_key *key)
free (key);
return CKR_OK;
}
-
- /* Symmetric encryption */
-
-struct ncr_symm_cipher_session
-{
- EVP_CIPHER_CTX ctx;
- CK_MECHANISM_TYPE mech;
- bool encrypting;
- /* Debugging only */
- enum { NSCS_NEW, NSCS_INITIALIZED, NSCS_UPDATED, NSCS_FINISHED } state;
-};
-
-CK_RV
-ncr_symm_cipher_alloc (struct ncr_symm_cipher_session **sess,
- CK_MECHANISM_TYPE mech)
-{
- struct ncr_symm_cipher_session *s;
-
- g_return_val_if_fail (sess != NULL, CKR_ARGUMENTS_BAD);
- /* FIXME? Validate "mech" */
-
- s = malloc (sizeof (*s));
- if (s == NULL)
- return CKR_HOST_MEMORY;
-
- EVP_CIPHER_CTX_init (&s->ctx);
- s->mech = mech;
- s->state = NSCS_NEW;
- *sess = s;
- return CKR_OK;
-}
-
-CK_RV
-ncr_symm_cipher_free (struct ncr_symm_cipher_session *sess)
-{
- g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
-
- EVP_CIPHER_CTX_cleanup (&sess->ctx);
- free (sess);
- return CKR_OK;
-}
-
-static CK_RV
-symm_cipher_init (struct ncr_symm_cipher_session *sess, bool encrypt,
- struct ncr_symm_key *key, const void *param,
- size_t param_size)
-{
- const EVP_CIPHER *type;
-
- g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
- g_return_val_if_fail (sess->state == NSCS_NEW || sess->state == NSCS_FINISHED,
- CKR_OPERATION_ACTIVE);
- g_return_val_if_fail (key != NULL, CKR_KEY_HANDLE_INVALID);
- g_return_val_if_fail (param != NULL || param_size == 0, CKR_ARGUMENTS_BAD);
-
- switch (sess->mech)
- {
-#define AES_SWITCH(MODE) \
- switch (key->size) \
- { \
- AES_ENTRY (MODE, 128); \
- AES_ENTRY (MODE, 192); \
- AES_ENTRY (MODE, 256); \
- default: \
- g_return_val_if_reached (CKR_KEY_SIZE_RANGE); \
- }
-#define AES_ENTRY(MODE, SIZE) \
- case (SIZE) / 8: \
- type = EVP_aes_##SIZE##_##MODE (); \
- break;
-
- case CKM_AES_ECB:
- g_return_val_if_fail (key->type == CKK_AES, CKR_KEY_TYPE_INCONSISTENT);
- g_return_val_if_fail (param_size == 0, CKR_MECHANISM_PARAM_INVALID);
- AES_SWITCH (ecb);
- break;
-
- case CKM_AES_CBC:
- g_return_val_if_fail (key->type == CKK_AES, CKR_KEY_TYPE_INCONSISTENT);
- g_return_val_if_fail (param_size == 16, CKR_MECHANISM_PARAM_INVALID);
- AES_SWITCH (cbc);
- break;
-#undef AES_ENTRY
-
- case CKM_DES3_ECB:
- g_return_val_if_fail (key->type == CKK_DES3, CKR_KEY_TYPE_INCONSISTENT);
- g_return_val_if_fail (key->size == 24, CKR_KEY_SIZE_RANGE);
- g_return_val_if_fail (param_size == 0, CKR_MECHANISM_PARAM_INVALID);
- type = EVP_des_ede3 ();
- break;
-
- case CKM_DES3_CBC:
- g_return_val_if_fail (key->type == CKK_DES3, CKR_KEY_TYPE_INCONSISTENT);
- g_return_val_if_fail (key->size == 24, CKR_KEY_SIZE_RANGE);
- g_return_val_if_fail (param_size == 8, CKR_MECHANISM_PARAM_INVALID);
- type = EVP_des_ede3_cbc ();
- break;
-
- default:
- g_return_val_if_reached (CKR_MECHANISM_INVALID);
- }
-
- if (EVP_CipherInit_ex (&sess->ctx, type, NULL, key->value,
- param_size != 0 ? param : NULL, encrypt ? 1 : 0) == 0)
- return ckr_openssl ();
- if (EVP_CIPHER_CTX_set_padding (&sess->ctx, 0) == 0)
- return ckr_openssl ();
-
- sess->encrypting = encrypt;
- sess->state = NSCS_INITIALIZED;
- return CKR_OK;
-}
-
-static CK_RV
-symm_cipher_update (struct ncr_symm_cipher_session *sess, bool encrypt,
- void *dest, size_t *dest_size_ptr, const void *src,
- size_t src_size)
-{
- int outl;
-
- g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
- g_return_val_if_fail (dest_size_ptr != NULL, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (sess->state == NSCS_INITIALIZED
- || sess->state == NSCS_UPDATED,
- CKR_OPERATION_NOT_INITIALIZED);
- g_return_val_if_fail (sess->encrypting == encrypt,
- CKR_OPERATION_NOT_INITIALIZED);
-
- if (dest == NULL)
- {
- *dest_size_ptr = src_size;
- return CKR_OK;
- }
- if (*dest_size_ptr < src_size) /* FIXME? this does not handle partial data */
- {
- *dest_size_ptr = src_size;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- g_return_val_if_fail (dest != NULL, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (src != NULL || src_size == 0, CKR_ARGUMENTS_BAD);
-
- if (EVP_CipherUpdate (&sess->ctx, dest, &outl, src, src_size) == 0)
- return ckr_openssl ();
-
- *dest_size_ptr = outl;
- sess->state = NSCS_UPDATED;
- return CKR_OK;
-}
-
-/* EVP_CipherUpdate + EVP_CipherFinal_ex */
-static CK_RV
-do_symm_cipher_update_final (struct ncr_symm_cipher_session *sess,
- bool encrypt, void *dest, size_t *dest_size_ptr,
- const void *src, size_t src_size)
-{
- int outl;
- size_t dest_size;
-
- /* The caller has verified session and its state. */
- g_return_val_if_fail (dest_size_ptr != NULL, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (sess->encrypting == encrypt,
- CKR_OPERATION_NOT_INITIALIZED);
-
- if (dest == NULL)
- {
- *dest_size_ptr = src_size;
- return CKR_OK;
- }
- if (*dest_size_ptr < src_size)
- {
- *dest_size_ptr = src_size;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- g_return_val_if_fail (dest != NULL, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (src != NULL || src_size == 0, CKR_ARGUMENTS_BAD);
-
- if (EVP_CipherUpdate (&sess->ctx, dest, &outl, src, src_size) == 0)
- {
- sess->state = NSCS_FINISHED;
- return ckr_openssl ();
- }
-
- dest_size = outl;
-
- if (EVP_CipherFinal_ex (&sess->ctx, (uint8_t *)dest + outl, &outl) == 0)
- {
- sess->state = NSCS_FINISHED;
- return ckr_openssl ();
- }
-
- *dest_size_ptr = dest_size + outl;
-
- sess->state = NSCS_FINISHED;
- return CKR_OK;
-}
-
-static CK_RV
-symm_cipher_final (struct ncr_symm_cipher_session *sess, bool encrypt,
- void *dest, size_t *dest_size_ptr, const void *src,
- size_t src_size)
-{
- g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
- g_return_val_if_fail (sess->state == NSCS_INITIALIZED
- || sess->state == NSCS_UPDATED,
- CKR_OPERATION_NOT_INITIALIZED);
-
- return do_symm_cipher_update_final (sess, encrypt, dest, dest_size_ptr, src,
- src_size);
-}
-
-static CK_RV
-symm_cipher (struct ncr_symm_cipher_session *sess, bool encrypt, void *dest,
- size_t *dest_size_ptr, const void *src, size_t src_size)
-{
- g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
- g_return_val_if_fail (sess->state == NSCS_INITIALIZED,
- CKR_OPERATION_NOT_INITIALIZED);
-
- return do_symm_cipher_update_final (sess, encrypt, dest, dest_size_ptr, src,
- src_size);
-}
-
-CK_RV
-ncr_symm_cipher_encrypt_init (struct ncr_symm_cipher_session *sess,
- struct ncr_symm_key *key, const void *param,
- size_t param_size)
-{
- return symm_cipher_init (sess, true, key, param, param_size);
-}
-
-CK_RV
-ncr_symm_cipher_encrypt_update (struct ncr_symm_cipher_session *sess,
- void *dest, size_t *dest_size_ptr,
- const void *src, size_t src_size)
-{
- return symm_cipher_update (sess, true, dest, dest_size_ptr, src, src_size);
-}
-
-CK_RV
-ncr_symm_cipher_encrypt_final (struct ncr_symm_cipher_session *sess, void *dest,
- size_t *dest_size_ptr, const void *src,
- size_t src_size)
-{
- return symm_cipher_final (sess, true, dest, dest_size_ptr, src, src_size);
-}
-
-CK_RV
-ncr_symm_cipher_encrypt (struct ncr_symm_cipher_session *sess, void *dest,
- size_t *dest_size_ptr, const void *src,
- size_t src_size)
-{
- return symm_cipher (sess, true, dest, dest_size_ptr, src, src_size);
-}
-
-CK_RV
-ncr_symm_cipher_decrypt_init (struct ncr_symm_cipher_session *sess,
- struct ncr_symm_key *key, const void *param,
- size_t param_size)
-{
- return symm_cipher_init (sess, false, key, param, param_size);
-}
-
-CK_RV
-ncr_symm_cipher_decrypt_update (struct ncr_symm_cipher_session *sess,
- void *dest, size_t *dest_size_ptr,
- const void *src, size_t src_size)
-{
- return symm_cipher_update (sess, false, dest, dest_size_ptr, src, src_size);
-}
-
-CK_RV
-ncr_symm_cipher_decrypt_final (struct ncr_symm_cipher_session *sess, void *dest,
- size_t *dest_size_ptr, const void *src,
- size_t src_size)
-{
- return symm_cipher_final (sess, false, dest, dest_size_ptr, src, src_size);
-}
-
-CK_RV
-ncr_symm_cipher_decrypt (struct ncr_symm_cipher_session *sess, void *dest,
- size_t *dest_size_ptr, const void *src,
- size_t src_size)
-{
- return symm_cipher (sess, false, dest, dest_size_ptr, src, src_size);
-}