/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <security/cryptoki.h>
#include "softSession.h"
#include "softObject.h"
#include "softCrypt.h"
#include <aes/aes_impl.h>
#ifdef _aes_amd64
#endif
#ifdef _aes_amd64
#define AESNI_aes_ecb_SMALL_JOB \
if ((out_len < AESNI_MODES_THRESHOLD) || \
/* \
* AES-NI for small buffers - \
* call block-level AES encrypt function directly. \
*/ \
ulong_t i; \
uint8_t *tmp_outbuf; \
\
for (i = 0; i < out_len; i += AES_BLOCK_LEN) { \
tmp_outbuf = &out_buf[i]; \
/* Crunch one block of data for AES. */ \
(void) aes_encrypt_block( \
tmp_inbuf, tmp_outbuf); \
} \
goto end_small_job;
}
#else
#define AESNI_aes_ecb_SMALL_JOB
#endif
/* there is no small job shortcut for non-AES_ECB */
#define AESNI_aes_cbc_SMALL_JOB
#define AESNI_aes_ctr_SMALL_JOB
#define AESNI_des_common_SMALL_JOB
#define AESNI_des3_common_SMALL_JOB
/* datasz must be multiple of blocksz for block ciphers */
if ((is_encrypt)) { \
rv = CKR_DATA_LEN_RANGE; \
} else { \
} \
goto cleanup; \
}
/* datasz can be of any length for stream cipher (CTR) */
#define FREE_aes_CTX \
#define FREE_des_CTX \
#define FREE_des3_CTX FREE_des_CTX
#define GET_aes_keysched(op) \
#define GET_des_keysched(op) \
#define GET_des3_keysched(op) \
#if defined(__sparc)
yf_functions_t *funcs; \
\
#else
#endif
#define soft_des3_ctx_t soft_des_ctx_t
#define des3_ctx_t des_ctx_t
CK_RV \
{ \
int rc = 0; \
crypto_data_t out; \
\
if (ulDataLen == 0) { \
*pulEncryptedLen = 0; \
return (CKR_OK); \
} \
\
\
\
/* \
* If application asks for the length of the output buffer \
* to hold the ciphertext? \
*/ \
if (pEncrypted == NULL) { \
*pulEncryptedLen = out_len; \
return (CKR_OK); \
} \
\
/* Is the application-supplied buffer large enough? */ \
if (*pulEncryptedLen < out_len) { \
*pulEncryptedLen = out_len; \
return (CKR_BUFFER_TOO_SMALL); \
} \
\
out_buf = pEncrypted; \
\
/* \
* Begin Encryption now. \
*/ \
\
/* \
* For intel, AES ECB small jobs are optimized by calling \
* block-level AES encrypt function directly. It goes to \
* 'end_small_job' when the job is done. \
* It is NOP for other algorithms and modes. \
*/ \
\
\
/* Encrypt multiple blocks of data. */ \
if ((soft_alg_ctx->remain_len == 0) && \
} else { \
} \
} else { \
} \
\
if (rc != 0) { \
*pulEncryptedLen = 0; \
rv = CKR_FUNCTION_FAILED; \
goto cleanup; \
} \
\
\
*pulEncryptedLen = out_len; \
\
/* \
* The encryption operation will be terminated so we need \
* to do some cleanup. \
*/ \
cleanup: \
} \
\
\
\
return (rv); \
}
/*
* Define:
* soft_aes_cbc_encrypt()
* soft_aes_ecb_encrypt()
* soft_aes_ctr_encrypt()
* soft_des_common_encrypt()
* soft_des3_common_encrypt()
*/
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
CK_RV \
{ \
int rc = 0; \
crypto_data_t out; \
\
if (ulDataLen == 0) { \
*pulEncryptedLen = 0; \
return (CKR_OK); \
} \
\
if (is_block_cipher) { \
/* \
* Add the lengths of last remaining data and current \
* plaintext together to get the total input length. \
*/ \
\
/* \
* If the total input length is less than one \
* blocksize, we will need to delay encryption until \
* when more data comes in the next C_EncryptUpdate or \
* when C_EncryptFinal is called. \
*/ \
if (pEncrypted != NULL) { \
/* \
* Save input data and its length in \
* the remaining buffer of the context. \
*/ \
ulDataLen); \
} \
\
/* Set encrypted data length to 0. */ \
*pulEncryptedLen = 0; \
return (CKR_OK); \
} \
\
/* Compute the length of remaining data. */ \
\
/* \
* Make sure that the output length is a multiple of \
* blocksize. \
*/ \
} \
\
/* \
* If application asks for the length of the output buffer \
* to hold the ciphertext? \
*/ \
if (pEncrypted == NULL) { \
*pulEncryptedLen = out_len; \
return (CKR_OK); \
} \
\
/* Is the application-supplied buffer large enough? */ \
if (*pulEncryptedLen < out_len) { \
*pulEncryptedLen = out_len; \
return (CKR_BUFFER_TOO_SMALL); \
} \
\
if (is_block_cipher) { \
if (soft_alg_ctx->remain_len != 0) { \
/* \
* Copy last remaining data and current \
* input data to the output buffer. \
*/ \
(void) memmove(pEncrypted + \
soft_alg_ctx->remain_len); \
soft_alg_ctx->remain_len); \
\
in_buf = pEncrypted; \
} else { \
} \
out_buf = pEncrypted; \
} \
\
/* \
* Begin Encryption now. \
*/ \
\
/* Encrypt multiple blocks of data. */ \
\
if ((soft_alg_ctx->remain_len == 0) && \
} else { \
} \
} else { \
} \
\
if (rc != 0) { \
*pulEncryptedLen = 0; \
rv = CKR_FUNCTION_FAILED; \
goto cleanup; \
} \
*pulEncryptedLen = out_len; \
\
/* \
* For encrypt update, if there is remaining data, \
* save it and its length in the context. \
*/ \
if (remain != 0) \
\
return (CKR_OK); \
\
/* \
* The encryption operation will be terminated so we need \
* to do some cleanup. \
*/ \
cleanup: \
} \
\
\
\
return (rv); \
\
}
/*
* Define:
* soft_aes_cbc_encrypt_update()
* soft_aes_ecb_encrypt_update()
* soft_aes_ctr_encrypt_update()
* soft_des_common_encrypt_update()
* soft_des3_common_encrypt_update()
*/
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
CK_RV \
{ \
int rc = 0; \
crypto_data_t out; \
\
if (ulEncryptedLen == 0) { \
*pulDataLen = 0; \
return (CKR_OK); \
} \
\
\
/* \
* If application asks for the length of the output buffer \
* to hold the plaintext? \
*/ \
*pulDataLen = ulEncryptedLen; \
return (CKR_OK); \
} \
\
if (*pulDataLen < ulEncryptedLen) { \
*pulDataLen = ulEncryptedLen; \
return (CKR_BUFFER_TOO_SMALL); \
} \
out_len = ulEncryptedLen; \
\
in_buf = pEncrypted; \
\
\
/* Decrypt multiple blocks of data. */ \
if ((soft_alg_ctx->remain_len == 0) && \
} else { \
} \
} else { \
} \
if (rc != 0) { \
*pulDataLen = 0; \
rv = CKR_FUNCTION_FAILED; \
goto cleanup; \
} \
*pulDataLen = out_len; \
\
/* Decryption is terminated. Cleanup */ \
cleanup: \
} \
\
\
\
return (rv); \
}
/*
* Define:
* soft_aes_cbc_decrypt()
* soft_aes_ecb_decrypt()
* soft_aes_ctr_decrypt()
* soft_des_common_decrypt()
* soft_des3_common_decrypt()
*/
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
CK_RV \
{ \
int rc = 0; \
crypto_data_t out; \
\
if (ulEncryptedLen == 0) { \
*pulDataLen = 0; \
return (CKR_OK); \
} \
\
if (is_block_cipher) { \
/* \
* Add the lengths of last remaining data and current \
* input data together to get the total input length. \
*/ \
\
/* \
* If the total input length is less than one \
* blocksize, we will need to delay decryption until \
* when more data comes in next C_DecryptUpdate or when \
* C_DecryptFinal is called. \
*/ \
/* \
* Save input data and its length in \
* the remaining buffer of context. \
*/ \
pEncrypted, ulEncryptedLen); \
soft_alg_ctx->remain_len += \
} \
\
/* Set output data length to 0. */ \
*pulDataLen = 0; \
return (CKR_OK); \
} \
\
/* Compute the length of remaining data. */ \
\
/* \
* Make sure that the output length is a \
* multiple of blocksize. \
*/ \
} \
\
/* \
* If application asks for the length of the output buffer \
* to hold the plaintext? \
*/ \
*pulDataLen = out_len; \
return (CKR_OK); \
} \
\
/* \
* Is the application-supplied buffer large enough? \
*/ \
if (*pulDataLen < out_len) { \
*pulDataLen = out_len; \
return (CKR_BUFFER_TOO_SMALL); \
} \
\
if (is_block_cipher) { \
if (soft_alg_ctx->remain_len != 0) { \
/* \
* Copy last remaining data and current input \
* data to the output buffer. \
*/ \
soft_alg_ctx->remain_len); \
soft_alg_ctx->remain_len); \
\
} else { \
in_buf = pEncrypted; \
} \
} \
\
\
/* Decrypt multiple blocks of data. */ \
if ((soft_alg_ctx->remain_len == 0) && \
} else { \
} \
} else { \
} \
\
if (rc != 0) { \
*pulDataLen = 0; \
rv = CKR_FUNCTION_FAILED; \
goto cleanup; \
} \
*pulDataLen = out_len; \
\
/* \
* For decrypt update, if there is remaining data \
* save it and its length in the context. \
*/ \
if (remain != 0) \
\
return (CKR_OK); \
\
cleanup: \
} \
\
\
\
return (rv); \
}
/*
* Define:
* soft_aes_cbc_decrypt_update()
* soft_aes_ecb_decrypt_update()
* soft_aes_ctr_decrypt_update()
* soft_des_common_decrypt_update()
* soft_des3_common_decrypt_update()
*/
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
/* LINTED E_CONSTANT_CONDITION */
};
};
};
};
};