/*
* 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 <sys/sysmacros.h>
/*
* Encryption and decryption routines.
*/
/*
* The following are the possible returned values common to all the routines
* below. The applicability of some of these return values depends on the
* presence of the arguments.
*
* CRYPTO_SUCCESS: The operation completed successfully.
* CRYPTO_QUEUED: A request was submitted successfully. The callback
* routine will be called when the operation is done.
* CRYPTO_INVALID_MECH_NUMBER, CRYPTO_INVALID_MECH_PARAM, or
* CRYPTO_INVALID_MECH for problems with the 'mech'.
* CRYPTO_INVALID_DATA for bogus 'data'
* CRYPTO_HOST_MEMORY for failure to allocate memory to handle this work.
* CRYPTO_INVALID_CONTEXT: Not a valid context.
* CRYPTO_BUSY: Cannot process the request now. Schedule a
* crypto_bufcall(), or try later.
* CRYPTO_NOT_SUPPORTED and CRYPTO_MECH_NOT_SUPPORTED: No provider is
* capable of a function or a mechanism.
* CRYPTO_INVALID_KEY: bogus 'key' argument.
* CRYPTO_INVALID_PLAINTEXT: bogus 'plaintext' argument.
* CRYPTO_INVALID_CIPHERTEXT: bogus 'ciphertext' argument.
*/
/*
* crypto_cipher_init_prov()
*
* Arguments:
*
* pd: provider descriptor
* sid: session id
* mech: crypto_mechanism_t pointer.
* mech_type is a valid value previously returned by
* crypto_mech2id();
* When the mech's parameter is not NULL, its definition depends
* on the standard definition of the mechanism.
* key: pointer to a crypto_key_t structure.
* tmpl: a crypto_ctx_template_t, opaque template of a context of an
* encryption or decryption with the 'mech' using 'key'.
* 'tmpl' is created by a previous call to
* crypto_create_ctx_template().
* ctxp: Pointer to a crypto_context_t.
* func: CRYPTO_FG_ENCRYPT or CRYPTO_FG_DECRYPT.
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* This is a common function invoked internally by both
* crypto_encrypt_init() and crypto_decrypt_init().
* Asynchronously submits a request for, or synchronously performs the
* initialization of an encryption or a decryption operation.
* When possible and applicable, will internally use the pre-expanded key
* schedule from the context template, tmpl.
* When complete and successful, 'ctxp' will contain a crypto_context_t
* valid for later calls to encrypt_update() and encrypt_final(), or
* decrypt_update() and decrypt_final().
* The caller should hold a reference on the specified provider
* descriptor before calling this function.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
static int
{
int error;
if (func == CRYPTO_FG_ENCRYPT) {
} else {
}
if (error != CRYPTO_SUCCESS)
return (error);
}
/* Allocate and initialize the canonical context */
return (CRYPTO_HOST_MEMORY);
}
/* The fast path for SW providers. */
if (func == CRYPTO_FG_ENCRYPT)
else {
}
goto done;
}
/* Check if context sharing is possible */
B_FALSE) == CRYPTO_SUCCESS)) {
int tlen;
/*
* key->ck_length from the consumer is always in bits.
* We convert it to be in the same unit registered by
* the provider in order to do a comparison.
*/
else
/*
* Check if the software provider can support context
* sharing and support this key length.
*/
} else
}
}
if (func == CRYPTO_FG_ENCRYPT) {
} else {
}
B_FALSE);
done:
else {
/* Release the hold done in kcf_new_ctx(). */
}
return (error);
}
/*
* Same as crypto_cipher_init_prov(), but relies on the scheduler to pick
* an appropriate provider. See crypto_cipher_init_prov() comments for more
* details.
*/
static int
{
int error;
/* pd is returned held */
return (error);
}
/*
* For SW providers, check the validity of the context template
* It is very rare that the generation number mis-matches, so
* is acceptable to fail here, and let the consumer recover by
* freeing this tmpl and create a new one for the key and new SW
* provider
*/
return (CRYPTO_OLD_CTX_TEMPLATE);
} else {
}
}
IS_RECOVERABLE(error)) {
/* Add pd to the linked list of providers tried. */
goto retry;
}
return (error);
}
/*
* crypto_encrypt_prov()
*
* Arguments:
* pd: provider descriptor
* sid: session id
* mech: crypto_mechanism_t pointer.
* mech_type is a valid value previously returned by
* crypto_mech2id();
* When the mech's parameter is not NULL, its definition depends
* on the standard definition of the mechanism.
* key: pointer to a crypto_key_t structure.
* plaintext: The message to be encrypted
* ciphertext: Storage for the encrypted message. The length needed
* depends on the mechanism, and the plaintext's size.
* tmpl: a crypto_ctx_template_t, opaque template of a context of an
* encryption with the 'mech' using 'key'. 'tmpl' is created by
* a previous call to crypto_create_ctx_template().
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* Asynchronously submits a request for, or synchronously performs a
* single-part encryption of 'plaintext' with the mechanism 'mech', using
* the key 'key'.
* When complete and successful, 'ciphertext' will contain the encrypted
* message.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
int
{
int error;
if (error != CRYPTO_SUCCESS)
return (error);
}
return (error);
}
/*
* Same as crypto_encrypt_prov(), but relies on the scheduler to pick
* a provider. See crypto_encrypt_prov() for more details.
*/
int
{
int error;
/* pd is returned held */
return (error);
}
/*
* For SW providers, check the validity of the context template
* It is very rare that the generation number mis-matches, so
* is acceptable to fail here, and let the consumer recover by
* freeing this tmpl and create a new one for the key and new SW
* provider
*/
return (CRYPTO_OLD_CTX_TEMPLATE);
} else {
}
}
/* The fast path for SW providers. */
} else {
}
IS_RECOVERABLE(error)) {
/* Add pd to the linked list of providers tried. */
goto retry;
}
return (error);
}
/*
* crypto_encrypt_init_prov()
*
* Calls crypto_cipher_init_prov() to initialize an encryption operation.
*/
int
{
}
/*
* crypto_encrypt_init()
*
* Calls crypto_cipher_init() to initialize an encryption operation
*/
int
{
}
/*
* crypto_encrypt_update()
*
* Arguments:
* context: A crypto_context_t initialized by encrypt_init().
* plaintext: The message part to be encrypted
* ciphertext: Storage for the encrypted message part.
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* Asynchronously submits a request for, or synchronously performs a
* part of an encryption operation.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
int
{
int error;
return (CRYPTO_INVALID_CONTEXT);
}
/* The fast path for SW providers. */
ciphertext, NULL);
return (error);
}
/* Check if we should use a software provider for small jobs */
}
}
return (error);
}
/*
* crypto_encrypt_final()
*
* Arguments:
* context: A crypto_context_t initialized by encrypt_init().
* ciphertext: Storage for the last part of encrypted message
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* Asynchronously submits a request for, or synchronously performs the
* final part of an encryption operation.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
int
{
int error;
return (CRYPTO_INVALID_CONTEXT);
}
/* The fast path for SW providers. */
} else {
}
/* Release the hold done in kcf_new_ctx() during init step. */
return (error);
}
/*
* crypto_decrypt_prov()
*
* Arguments:
* pd: provider descriptor
* sid: session id
* mech: crypto_mechanism_t pointer.
* mech_type is a valid value previously returned by
* crypto_mech2id();
* When the mech's parameter is not NULL, its definition depends
* on the standard definition of the mechanism.
* key: pointer to a crypto_key_t structure.
* ciphertext: The message to be encrypted
* plaintext: Storage for the encrypted message. The length needed
* depends on the mechanism, and the plaintext's size.
* tmpl: a crypto_ctx_template_t, opaque template of a context of an
* encryption with the 'mech' using 'key'. 'tmpl' is created by
* a previous call to crypto_create_ctx_template().
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* Asynchronously submits a request for, or synchronously performs a
* single-part decryption of 'ciphertext' with the mechanism 'mech', using
* the key 'key'.
* When complete and successful, 'plaintext' will contain the decrypted
* message.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
int
{
int rv;
if (rv != CRYPTO_SUCCESS)
return (rv);
}
return (rv);
}
/*
* Same as crypto_decrypt_prov(), but relies on the KCF scheduler to
* choose a provider. See crypto_decrypt_prov() comments for more
* information.
*/
int
{
int error;
/* pd is returned held */
return (error);
}
/*
* For SW providers, check the validity of the context template
* It is very rare that the generation number mis-matches, so
* is acceptable to fail here, and let the consumer recover by
* freeing this tmpl and create a new one for the key and new SW
* provider
*/
return (CRYPTO_OLD_CTX_TEMPLATE);
} else {
}
}
/* The fast path for SW providers. */
} else {
}
IS_RECOVERABLE(error)) {
/* Add pd to the linked list of providers tried. */
goto retry;
}
return (error);
}
/*
* crypto_decrypt_init_prov()
*
* Calls crypto_cipher_init_prov() to initialize a decryption operation
*/
int
{
}
/*
* crypto_decrypt_init()
*
* Calls crypto_cipher_init() to initialize a decryption operation
*/
int
{
}
/*
* crypto_decrypt_update()
*
* Arguments:
* context: A crypto_context_t initialized by decrypt_init().
* ciphertext: The message part to be decrypted
* plaintext: Storage for the decrypted message part.
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* Asynchronously submits a request for, or synchronously performs a
* part of an decryption operation.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
int
{
int error;
return (CRYPTO_INVALID_CONTEXT);
}
/* The fast path for SW providers. */
return (error);
}
/* Check if we should use a software provider for small jobs */
}
}
return (error);
}
/*
* crypto_decrypt_final()
*
* Arguments:
* context: A crypto_context_t initialized by decrypt_init().
* plaintext: Storage for the last part of the decrypted message
* cr: crypto_call_req_t calling conditions and call back info.
*
* Description:
* Asynchronously submits a request for, or synchronously performs the
* final part of a decryption operation.
*
* Context:
* Process or interrupt, according to the semantics dictated by the 'cr'.
*
* Returns:
* See comment in the beginning of the file.
*/
int
{
int error;
return (CRYPTO_INVALID_CONTEXT);
}
/* The fast path for SW providers. */
NULL);
} else {
}
/* Release the hold done in kcf_new_ctx() during init step. */
return (error);
}
/*
* See comments for crypto_encrypt_update().
*/
int
{
int error;
return (CRYPTO_INVALID_CONTEXT);
}
/* The fast path for SW providers. */
ciphertext, NULL);
} else {
}
/* Release the hold done in kcf_new_ctx() during init step. */
return (error);
}
/*
* See comments for crypto_decrypt_update().
*/
int
{
int error;
return (CRYPTO_INVALID_CONTEXT);
}
/* The fast path for SW providers. */
} else {
}
/* Release the hold done in kcf_new_ctx() during init step. */
return (error);
}