/*
* 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 <cryptoutil.h>
#include <syslog.h>
#define _AES_FIPS_POST
#define _RSA_FIPS_POST
#include <aes/aes_impl.h>
#include <rsa/rsa_impl.h>
#include "libsoftcrypto.h"
/*
* IMPORTANT: Each feature enhancement must be accompanied by an increment
* in the version.
*/
typedef enum ucrypto_op {
UCRYPTO_NOOP = 0,
} ucrypto_op_t;
typedef struct ucrypto_ctx {
#pragma init(ucrypto_init)
static void ucrypto_init();
#pragma inline(create_context)
static int
{
int rv;
int blocksize;
case CRYPTO_AES_CBC_PAD:
break;
default:
blocksize = 0; /* i.e., no padding needed */
break;
}
case CRYPTO_AES_ECB:
case CRYPTO_AES_CBC:
case CRYPTO_AES_CTR:
case CRYPTO_AES_CCM:
case CRYPTO_AES_GCM:
case CRYPTO_AES_CFB128:
case CRYPTO_AES_XTS:
/* UCRYPTO_SIGN and UCRYPTO_VERIFY ops are invalid here */
break;
}
break;
case CRYPTO_RSA_PKCS:
case CRYPTO_RSA_X_509:
case CRYPTO_MD5_RSA_PKCS:
case CRYPTO_SHA1_RSA_PKCS:
case CRYPTO_SHA224_RSA_PKCS:
case CRYPTO_SHA256_RSA_PKCS:
case CRYPTO_SHA384_RSA_PKCS:
case CRYPTO_SHA512_RSA_PKCS:
/* UCRYPTO_ENCRYPT and UCRYPTO_DECRYPT ops are invalid here */
break;
}
break;
default:
}
if (rv != CRYPTO_SUCCESS)
return (rv);
/* Create framework context */
return (CRYPTO_HOST_MEMORY);
return (CRYPTO_SUCCESS);
}
/*
* This function frees the context for ucrypto, not for the provider
* the module code handles that.
*/
#pragma inline(free_context)
static void
{
}
#pragma inline(set_key)
static int
{
switch (mech_type) {
case CRYPTO_AES_ECB:
case CRYPTO_AES_CBC:
case CRYPTO_AES_CBC_PAD:
case CRYPTO_AES_CTR:
case CRYPTO_AES_CCM:
case CRYPTO_AES_GCM:
case CRYPTO_AES_CFB128:
case CRYPTO_AES_XTS:
case CRYPTO_AES_XCBC_MAC:
break;
case CRYPTO_RSA_PKCS:
case CRYPTO_RSA_X_509:
case CRYPTO_MD5_RSA_PKCS:
case CRYPTO_SHA1_RSA_PKCS:
case CRYPTO_SHA224_RSA_PKCS:
case CRYPTO_SHA256_RSA_PKCS:
case CRYPTO_SHA384_RSA_PKCS:
case CRYPTO_SHA512_RSA_PKCS:
break;
default:
return (CRYPTO_MECH_NOT_SUPPORTED);
}
return (CRYPTO_SUCCESS);
}
/*
* If the mechanism is defined in this function, then it is supported.
* If it is supported, sets up the initialization vector in crypto_mechanism_t.
*/
#pragma inline(set_mechanism)
static int
{
return (CRYPTO_MECHANISM_PARAM_INVALID);
return (CRYPTO_SUCCESS);
}
/* Return the version of this library */
int
ucrypto_version(void)
{
return (UCRYPTO_VERSION);
}
/*
* UCRYPTO common internal functions.
*/
#pragma inline(ucrypto_common_init)
static int
{
int rv;
if (rv != CRYPTO_SUCCESS)
return (rv);
if (rv != CRYPTO_SUCCESS)
return (rv);
if (rv != CRYPTO_SUCCESS)
return (rv);
return (CRYPTO_SUCCESS);
}
#pragma inline(ucrypto_common_update)
static int
{
int rv;
case CRYPTO_AES_ECB:
case CRYPTO_AES_CBC:
case CRYPTO_AES_CTR:
case CRYPTO_AES_CCM:
case CRYPTO_AES_GCM:
case CRYPTO_AES_CFB128:
case CRYPTO_AES_XTS:
goto cleanup;
}
if (op_type == UCRYPTO_ENCRYPT)
else if (op_type == UCRYPTO_DECRYPT)
else
if (rv != CRYPTO_SUCCESS)
goto cleanup;
break;
case CRYPTO_RSA_PKCS:
case CRYPTO_RSA_X_509:
case CRYPTO_MD5_RSA_PKCS:
case CRYPTO_SHA1_RSA_PKCS:
case CRYPTO_SHA224_RSA_PKCS:
case CRYPTO_SHA256_RSA_PKCS:
case CRYPTO_SHA384_RSA_PKCS:
case CRYPTO_SHA512_RSA_PKCS:
if (op_type == UCRYPTO_SIGN)
else if (op_type == UCRYPTO_VERIFY)
else
if (rv != CRYPTO_SUCCESS)
goto cleanup;
break;
default:
goto cleanup;
}
/* Reset remainder bytes for padded mechs only if update successful. */
return (CRYPTO_SUCCESS);
return (rv);
}
#pragma inline(ucrypto_common_final)
static int
{
int rv;
goto cleanup;
}
case CRYPTO_AES_ECB:
case CRYPTO_AES_CBC:
case CRYPTO_AES_CTR:
case CRYPTO_AES_CCM:
case CRYPTO_AES_GCM:
case CRYPTO_AES_CFB128:
case CRYPTO_AES_XTS:
/*
* If this is a padded mech, do one more update op on the
* padding buffer instead of the final op; the padding will
* guarantee no more residual data, so the final op becomes
* unnecessary.
*/
/*
* Remember, mechs were remapped to their unpadded
* counterparts; blocksize != 0 means padded mech.
*/
case CRYPTO_AES_CBC:
break;
default:
break;
}
if (rv != CRYPTO_SUCCESS)
goto cleanup;
goto cleanup;
}
}
if (op_type == UCRYPTO_ENCRYPT)
else if (op_type == UCRYPTO_DECRYPT)
else
if (rv != CRYPTO_SUCCESS)
goto cleanup;
goto cleanup;
}
}
break;
case CRYPTO_RSA_PKCS:
case CRYPTO_RSA_X_509:
case CRYPTO_MD5_RSA_PKCS:
case CRYPTO_SHA1_RSA_PKCS:
case CRYPTO_SHA224_RSA_PKCS:
case CRYPTO_SHA256_RSA_PKCS:
case CRYPTO_SHA384_RSA_PKCS:
case CRYPTO_SHA512_RSA_PKCS:
if (op_type == UCRYPTO_SIGN)
else if (op_type == UCRYPTO_VERIFY)
else
if (rv != CRYPTO_SUCCESS)
goto cleanup;
break;
default:
goto cleanup;
}
return (rv);
}
#pragma inline(ucrypto_atomic)
static int
{
int rv;
return (CRYPTO_ARGUMENTS_BAD);
switch (mech_type) {
case CRYPTO_AES_CBC_PAD:
if (op_type == UCRYPTO_ENCRYPT) {
return (CRYPTO_BUFFER_TOO_SMALL);
/*
* Copy data to allocated buffer big enough to hold
* it plus extra padding.
*/
return (CRYPTO_HOST_MEMORY);
} else if (op_type == UCRYPTO_DECRYPT) {
/*
* Copy data to temporary allocated buffer.
*/
padded_len = *out_len;
return (CRYPTO_HOST_MEMORY);
} else
return (CRYPTO_MECH_NOT_SUPPORTED);
break;
default:
break;
}
if (rv != CRYPTO_SUCCESS)
goto out_atomic;
if (rv != CRYPTO_SUCCESS)
goto out_atomic;
} else {
}
} else {
}
switch (mech_type) {
case CRYPTO_AES_ECB:
case CRYPTO_AES_CBC:
case CRYPTO_AES_CTR:
case CRYPTO_AES_CCM:
case CRYPTO_AES_GCM:
case CRYPTO_AES_CFB128:
case CRYPTO_AES_XTS:
case CRYPTO_AES_XCBC_MAC:
if (op_type == UCRYPTO_ENCRYPT)
else if (op_type == UCRYPTO_DECRYPT)
else
break;
case CRYPTO_RSA_PKCS:
case CRYPTO_RSA_X_509:
case CRYPTO_MD5_RSA_PKCS:
case CRYPTO_SHA1_RSA_PKCS:
case CRYPTO_SHA224_RSA_PKCS:
case CRYPTO_SHA256_RSA_PKCS:
case CRYPTO_SHA384_RSA_PKCS:
case CRYPTO_SHA512_RSA_PKCS:
if (op_type == UCRYPTO_ENCRYPT)
else if (op_type == UCRYPTO_DECRYPT)
else if (op_type == UCRYPTO_SIGN)
else if (op_type == UCRYPTO_VERIFY)
else
break;
default:
break;
}
goto out_atomic;
}
}
return (rv);
}
/*
* UCRYPTO exported functions.
*/
/* Encrypt API */
int
{
}
int
{
if (update_func != NULL) {
} else {
}
}
}
int
{
}
switch (mech_type) { \
case CRYPTO_AES_CBC: \
case CRYPTO_AES_ECB: \
case CRYPTO_AES_CFB128: \
case CRYPTO_AES_CTR: \
break; \
default: \
break; \
}
int
{
if (funcs) {
}
}
}
/* Decrypt API */
int
{
}
int
{
if (update_func != NULL) {
} else {
}
}
}
int
{
}
int
{
if (funcs) {
}
}
}
/* Sign API */
int
{
}
int
{
}
int
{
UCRYPTO_SIGN));
}
int
{
}
/* Verify API */
int
{
}
int
{
}
int
{
}
int
{
}
static void
{
int rv;
/*
* Perform POST when fips mode is enabled.
*/
(void) get_fips_mode(&ucrypto_fips_mode);
if (ucrypto_fips_mode == CRYPTO_FIPS_MODE_ENABLED) {
/* AES Power-On SelfTest for 128-bit key. */
"Test (AES-128) failed, rv= %d", rv);
abort();
}
/* AES Power-On SelfTest for 192-bit key. */
"Test (AES-192) failed, rv= %d", rv);
abort();
}
/* AES Power-On SelfTest for 256-bit key. */
"Test (AES-256) failed, rv= %d", rv);
abort();
}
/*
* RSA Power-On SelfTest
*/
if ((rv = fips_rsa_post()) != 0) {
"Test (RSA) failed, rv= %d", rv);
abort();
}
}
}