icp: remove digest entry points
For whatever reason, we call digest mechanisms directly, not through the KCF digest provider. So we can remove those entry points entirely. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #16209
This commit is contained in:
parent
94f1e56e41
commit
1291c46ea4
|
@ -152,25 +152,16 @@ typedef struct skein_param {
|
||||||
|
|
||||||
/* Module definitions */
|
/* Module definitions */
|
||||||
#ifdef SKEIN_MODULE_IMPL
|
#ifdef SKEIN_MODULE_IMPL
|
||||||
#define CKM_SKEIN_256 "CKM_SKEIN_256"
|
|
||||||
#define CKM_SKEIN_512 "CKM_SKEIN_512"
|
|
||||||
#define CKM_SKEIN1024 "CKM_SKEIN1024"
|
|
||||||
#define CKM_SKEIN_256_MAC "CKM_SKEIN_256_MAC"
|
#define CKM_SKEIN_256_MAC "CKM_SKEIN_256_MAC"
|
||||||
#define CKM_SKEIN_512_MAC "CKM_SKEIN_512_MAC"
|
#define CKM_SKEIN_512_MAC "CKM_SKEIN_512_MAC"
|
||||||
#define CKM_SKEIN1024_MAC "CKM_SKEIN1024_MAC"
|
#define CKM_SKEIN1024_MAC "CKM_SKEIN1024_MAC"
|
||||||
|
|
||||||
typedef enum skein_mech_type {
|
typedef enum skein_mech_type {
|
||||||
SKEIN_256_MECH_INFO_TYPE,
|
|
||||||
SKEIN_512_MECH_INFO_TYPE,
|
|
||||||
SKEIN1024_MECH_INFO_TYPE,
|
|
||||||
SKEIN_256_MAC_MECH_INFO_TYPE,
|
SKEIN_256_MAC_MECH_INFO_TYPE,
|
||||||
SKEIN_512_MAC_MECH_INFO_TYPE,
|
SKEIN_512_MAC_MECH_INFO_TYPE,
|
||||||
SKEIN1024_MAC_MECH_INFO_TYPE
|
SKEIN1024_MAC_MECH_INFO_TYPE
|
||||||
} skein_mech_type_t;
|
} skein_mech_type_t;
|
||||||
|
|
||||||
#define VALID_SKEIN_DIGEST_MECH(__mech) \
|
|
||||||
((int)(__mech) >= SKEIN_256_MECH_INFO_TYPE && \
|
|
||||||
(__mech) <= SKEIN1024_MECH_INFO_TYPE)
|
|
||||||
#define VALID_SKEIN_MAC_MECH(__mech) \
|
#define VALID_SKEIN_MAC_MECH(__mech) \
|
||||||
((int)(__mech) >= SKEIN_256_MAC_MECH_INFO_TYPE && \
|
((int)(__mech) >= SKEIN_256_MAC_MECH_INFO_TYPE && \
|
||||||
(__mech) <= SKEIN1024_MAC_MECH_INFO_TYPE)
|
(__mech) <= SKEIN1024_MAC_MECH_INFO_TYPE)
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
* mech_index is the index for that mechanism in the table.
|
* mech_index is the index for that mechanism in the table.
|
||||||
* A mechanism belongs to exactly 1 table.
|
* A mechanism belongs to exactly 1 table.
|
||||||
* The tables are:
|
* The tables are:
|
||||||
* . digest_mechs_tab[] for the msg digest mechs.
|
|
||||||
* . cipher_mechs_tab[] for encrypt/decrypt and wrap/unwrap mechs.
|
* . cipher_mechs_tab[] for encrypt/decrypt and wrap/unwrap mechs.
|
||||||
* . mac_mechs_tab[] for MAC mechs.
|
* . mac_mechs_tab[] for MAC mechs.
|
||||||
* . sign_mechs_tab[] for sign & verify mechs.
|
* . sign_mechs_tab[] for sign & verify mechs.
|
||||||
|
@ -75,13 +74,11 @@
|
||||||
|
|
||||||
/* RFE 4687834 Will deal with the extensibility of these tables later */
|
/* RFE 4687834 Will deal with the extensibility of these tables later */
|
||||||
|
|
||||||
static kcf_mech_entry_t kcf_digest_mechs_tab[KCF_MAXDIGEST];
|
|
||||||
static kcf_mech_entry_t kcf_cipher_mechs_tab[KCF_MAXCIPHER];
|
static kcf_mech_entry_t kcf_cipher_mechs_tab[KCF_MAXCIPHER];
|
||||||
static kcf_mech_entry_t kcf_mac_mechs_tab[KCF_MAXMAC];
|
static kcf_mech_entry_t kcf_mac_mechs_tab[KCF_MAXMAC];
|
||||||
|
|
||||||
const kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = {
|
const kcf_mech_entry_tab_t kcf_mech_tabs_tab[KCF_LAST_OPSCLASS + 1] = {
|
||||||
{0, NULL}, /* No class zero */
|
{0, NULL}, /* No class zero */
|
||||||
{KCF_MAXDIGEST, kcf_digest_mechs_tab},
|
|
||||||
{KCF_MAXCIPHER, kcf_cipher_mechs_tab},
|
{KCF_MAXCIPHER, kcf_cipher_mechs_tab},
|
||||||
{KCF_MAXMAC, kcf_mac_mechs_tab},
|
{KCF_MAXMAC, kcf_mac_mechs_tab},
|
||||||
};
|
};
|
||||||
|
@ -220,9 +217,7 @@ kcf_add_mech_provider(short mech_indx,
|
||||||
crypto_func_group_t fg = mech_info->cm_func_group_mask;
|
crypto_func_group_t fg = mech_info->cm_func_group_mask;
|
||||||
kcf_ops_class_t class;
|
kcf_ops_class_t class;
|
||||||
|
|
||||||
if (fg & CRYPTO_FG_DIGEST || fg & CRYPTO_FG_DIGEST_ATOMIC)
|
if (fg & CRYPTO_FG_ENCRYPT_ATOMIC ||
|
||||||
class = KCF_DIGEST_CLASS;
|
|
||||||
else if (fg & CRYPTO_FG_ENCRYPT_ATOMIC ||
|
|
||||||
fg & CRYPTO_FG_DECRYPT_ATOMIC)
|
fg & CRYPTO_FG_DECRYPT_ATOMIC)
|
||||||
class = KCF_CIPHER_CLASS;
|
class = KCF_CIPHER_CLASS;
|
||||||
else if (fg & CRYPTO_FG_MAC || fg & CRYPTO_FG_MAC_ATOMIC)
|
else if (fg & CRYPTO_FG_MAC || fg & CRYPTO_FG_MAC_ATOMIC)
|
||||||
|
|
|
@ -55,7 +55,7 @@ extern "C" {
|
||||||
* When impl.h is broken up (bug# 4703218), this will be done. For now,
|
* When impl.h is broken up (bug# 4703218), this will be done. For now,
|
||||||
* we hardcode these values.
|
* we hardcode these values.
|
||||||
*/
|
*/
|
||||||
#define KCF_OPS_CLASSSIZE 4
|
#define KCF_OPS_CLASSSIZE 3
|
||||||
#define KCF_MAXMECHTAB 32
|
#define KCF_MAXMECHTAB 32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -200,12 +200,11 @@ _Static_assert(KCF_MAXCIPHER == KCF_MAXMECHTAB,
|
||||||
"KCF_MAXCIPHER != KCF_MAXMECHTAB"); /* See KCF_MAXMECHTAB comment */
|
"KCF_MAXCIPHER != KCF_MAXMECHTAB"); /* See KCF_MAXMECHTAB comment */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
KCF_DIGEST_CLASS = 1,
|
KCF_CIPHER_CLASS = 1,
|
||||||
KCF_CIPHER_CLASS,
|
|
||||||
KCF_MAC_CLASS,
|
KCF_MAC_CLASS,
|
||||||
} kcf_ops_class_t;
|
} kcf_ops_class_t;
|
||||||
|
|
||||||
#define KCF_FIRST_OPSCLASS KCF_DIGEST_CLASS
|
#define KCF_FIRST_OPSCLASS KCF_CIPHER_CLASS
|
||||||
#define KCF_LAST_OPSCLASS KCF_MAC_CLASS
|
#define KCF_LAST_OPSCLASS KCF_MAC_CLASS
|
||||||
_Static_assert(
|
_Static_assert(
|
||||||
KCF_OPS_CLASSSIZE == (KCF_LAST_OPSCLASS - KCF_FIRST_OPSCLASS + 2),
|
KCF_OPS_CLASSSIZE == (KCF_LAST_OPSCLASS - KCF_FIRST_OPSCLASS + 2),
|
||||||
|
|
|
@ -66,22 +66,6 @@ typedef struct crypto_ctx {
|
||||||
void *cc_framework_private; /* owned by framework */
|
void *cc_framework_private; /* owned by framework */
|
||||||
} crypto_ctx_t;
|
} crypto_ctx_t;
|
||||||
|
|
||||||
/*
|
|
||||||
* The crypto_digest_ops structure contains pointers to digest
|
|
||||||
* operations for cryptographic providers. It is passed through
|
|
||||||
* the crypto_ops(9S) structure when providers register with the
|
|
||||||
* kernel using crypto_register_provider(9F).
|
|
||||||
*/
|
|
||||||
typedef struct crypto_digest_ops {
|
|
||||||
int (*digest_init)(crypto_ctx_t *, crypto_mechanism_t *);
|
|
||||||
int (*digest)(crypto_ctx_t *, crypto_data_t *, crypto_data_t *);
|
|
||||||
int (*digest_update)(crypto_ctx_t *, crypto_data_t *);
|
|
||||||
int (*digest_key)(crypto_ctx_t *, crypto_key_t *);
|
|
||||||
int (*digest_final)(crypto_ctx_t *, crypto_data_t *);
|
|
||||||
int (*digest_atomic)(crypto_mechanism_t *, crypto_data_t *,
|
|
||||||
crypto_data_t *);
|
|
||||||
} __no_const crypto_digest_ops_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The crypto_cipher_ops structure contains pointers to encryption
|
* The crypto_cipher_ops structure contains pointers to encryption
|
||||||
* and decryption operations for cryptographic providers. It is
|
* and decryption operations for cryptographic providers. It is
|
||||||
|
@ -137,7 +121,6 @@ typedef struct crypto_ctx_ops {
|
||||||
* by calling crypto_register_provider(9F).
|
* by calling crypto_register_provider(9F).
|
||||||
*/
|
*/
|
||||||
typedef struct crypto_ops {
|
typedef struct crypto_ops {
|
||||||
const crypto_digest_ops_t *co_digest_ops;
|
|
||||||
const crypto_cipher_ops_t *co_cipher_ops;
|
const crypto_cipher_ops_t *co_cipher_ops;
|
||||||
const crypto_mac_ops_t *co_mac_ops;
|
const crypto_mac_ops_t *co_mac_ops;
|
||||||
const crypto_ctx_ops_t *co_ctx_ops;
|
const crypto_ctx_ops_t *co_ctx_ops;
|
||||||
|
@ -153,12 +136,10 @@ typedef struct crypto_ops {
|
||||||
typedef uint32_t crypto_func_group_t;
|
typedef uint32_t crypto_func_group_t;
|
||||||
|
|
||||||
|
|
||||||
#define CRYPTO_FG_DIGEST 0x00000004 /* digest_init() */
|
|
||||||
#define CRYPTO_FG_MAC 0x00001000 /* mac_init() */
|
#define CRYPTO_FG_MAC 0x00001000 /* mac_init() */
|
||||||
#define CRYPTO_FG_ENCRYPT_ATOMIC 0x00008000 /* encrypt_atomic() */
|
#define CRYPTO_FG_ENCRYPT_ATOMIC 0x00008000 /* encrypt_atomic() */
|
||||||
#define CRYPTO_FG_DECRYPT_ATOMIC 0x00010000 /* decrypt_atomic() */
|
#define CRYPTO_FG_DECRYPT_ATOMIC 0x00010000 /* decrypt_atomic() */
|
||||||
#define CRYPTO_FG_MAC_ATOMIC 0x00020000 /* mac_atomic() */
|
#define CRYPTO_FG_MAC_ATOMIC 0x00020000 /* mac_atomic() */
|
||||||
#define CRYPTO_FG_DIGEST_ATOMIC 0x00040000 /* digest_atomic() */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum length of the pi_provider_description field of the
|
* Maximum length of the pi_provider_description field of the
|
||||||
|
|
|
@ -72,7 +72,6 @@ static const crypto_ctx_ops_t aes_ctx_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const crypto_ops_t aes_crypto_ops = {
|
static const crypto_ops_t aes_crypto_ops = {
|
||||||
NULL,
|
|
||||||
&aes_cipher_ops,
|
&aes_cipher_ops,
|
||||||
NULL,
|
NULL,
|
||||||
&aes_ctx_ops,
|
&aes_ctx_ops,
|
||||||
|
|
|
@ -61,8 +61,7 @@
|
||||||
*/
|
*/
|
||||||
static const crypto_mech_info_t sha2_mech_info_tab[] = {
|
static const crypto_mech_info_t sha2_mech_info_tab[] = {
|
||||||
/* SHA256 */
|
/* SHA256 */
|
||||||
{SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE,
|
{SUN_CKM_SHA256, SHA256_MECH_INFO_TYPE, 0},
|
||||||
CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC},
|
|
||||||
/* SHA256-HMAC */
|
/* SHA256-HMAC */
|
||||||
{SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
|
{SUN_CKM_SHA256_HMAC, SHA256_HMAC_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
|
@ -70,8 +69,7 @@ static const crypto_mech_info_t sha2_mech_info_tab[] = {
|
||||||
{SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
|
{SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
/* SHA384 */
|
/* SHA384 */
|
||||||
{SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE,
|
{SUN_CKM_SHA384, SHA384_MECH_INFO_TYPE, 0},
|
||||||
CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC},
|
|
||||||
/* SHA384-HMAC */
|
/* SHA384-HMAC */
|
||||||
{SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
|
{SUN_CKM_SHA384_HMAC, SHA384_HMAC_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
|
@ -79,8 +77,7 @@ static const crypto_mech_info_t sha2_mech_info_tab[] = {
|
||||||
{SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
|
{SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
/* SHA512 */
|
/* SHA512 */
|
||||||
{SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE,
|
{SUN_CKM_SHA512, SHA512_MECH_INFO_TYPE, 0},
|
||||||
CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC},
|
|
||||||
/* SHA512-HMAC */
|
/* SHA512-HMAC */
|
||||||
{SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
|
{SUN_CKM_SHA512_HMAC, SHA512_HMAC_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
|
@ -89,21 +86,6 @@ static const crypto_mech_info_t sha2_mech_info_tab[] = {
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sha2_digest_init(crypto_ctx_t *, crypto_mechanism_t *);
|
|
||||||
static int sha2_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *);
|
|
||||||
static int sha2_digest_update(crypto_ctx_t *, crypto_data_t *);
|
|
||||||
static int sha2_digest_final(crypto_ctx_t *, crypto_data_t *);
|
|
||||||
static int sha2_digest_atomic(crypto_mechanism_t *, crypto_data_t *,
|
|
||||||
crypto_data_t *);
|
|
||||||
|
|
||||||
static const crypto_digest_ops_t sha2_digest_ops = {
|
|
||||||
.digest_init = sha2_digest_init,
|
|
||||||
.digest = sha2_digest,
|
|
||||||
.digest_update = sha2_digest_update,
|
|
||||||
.digest_final = sha2_digest_final,
|
|
||||||
.digest_atomic = sha2_digest_atomic
|
|
||||||
};
|
|
||||||
|
|
||||||
static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
|
static int sha2_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
|
||||||
crypto_spi_ctx_template_t);
|
crypto_spi_ctx_template_t);
|
||||||
static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *);
|
static int sha2_mac_update(crypto_ctx_t *, crypto_data_t *);
|
||||||
|
@ -132,7 +114,6 @@ static const crypto_ctx_ops_t sha2_ctx_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const crypto_ops_t sha2_crypto_ops = {
|
static const crypto_ops_t sha2_crypto_ops = {
|
||||||
&sha2_digest_ops,
|
|
||||||
NULL,
|
NULL,
|
||||||
&sha2_mac_ops,
|
&sha2_mac_ops,
|
||||||
&sha2_ctx_ops,
|
&sha2_ctx_ops,
|
||||||
|
@ -184,27 +165,6 @@ sha2_mod_fini(void)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* KCF software provider digest entry points.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
sha2_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate and initialize SHA2 context.
|
|
||||||
*/
|
|
||||||
ctx->cc_provider_private = kmem_alloc(sizeof (sha2_ctx_t), KM_SLEEP);
|
|
||||||
if (ctx->cc_provider_private == NULL)
|
|
||||||
return (CRYPTO_HOST_MEMORY);
|
|
||||||
|
|
||||||
PROV_SHA2_CTX(ctx)->sc_mech_type = mechanism->cm_type;
|
|
||||||
SHA2Init(mechanism->cm_type, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
|
|
||||||
|
|
||||||
return (CRYPTO_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper SHA2 digest update function for uio data.
|
* Helper SHA2 digest update function for uio data.
|
||||||
*/
|
*/
|
||||||
|
@ -360,246 +320,6 @@ sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest,
|
||||||
return (CRYPTO_SUCCESS);
|
return (CRYPTO_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
sha2_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest)
|
|
||||||
{
|
|
||||||
int ret = CRYPTO_SUCCESS;
|
|
||||||
uint_t sha_digest_len;
|
|
||||||
|
|
||||||
ASSERT(ctx->cc_provider_private != NULL);
|
|
||||||
|
|
||||||
switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
|
|
||||||
case SHA256_MECH_INFO_TYPE:
|
|
||||||
sha_digest_len = SHA256_DIGEST_LENGTH;
|
|
||||||
break;
|
|
||||||
case SHA384_MECH_INFO_TYPE:
|
|
||||||
sha_digest_len = SHA384_DIGEST_LENGTH;
|
|
||||||
break;
|
|
||||||
case SHA512_MECH_INFO_TYPE:
|
|
||||||
sha_digest_len = SHA512_DIGEST_LENGTH;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (CRYPTO_MECHANISM_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need to just return the length needed to store the output.
|
|
||||||
* We should not destroy the context for the following cases.
|
|
||||||
*/
|
|
||||||
if ((digest->cd_length == 0) ||
|
|
||||||
(digest->cd_length < sha_digest_len)) {
|
|
||||||
digest->cd_length = sha_digest_len;
|
|
||||||
return (CRYPTO_BUFFER_TOO_SMALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the SHA2 update on the specified input data.
|
|
||||||
*/
|
|
||||||
switch (data->cd_format) {
|
|
||||||
case CRYPTO_DATA_RAW:
|
|
||||||
SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
|
|
||||||
(uint8_t *)data->cd_raw.iov_base + data->cd_offset,
|
|
||||||
data->cd_length);
|
|
||||||
break;
|
|
||||||
case CRYPTO_DATA_UIO:
|
|
||||||
ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
|
|
||||||
data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = CRYPTO_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != CRYPTO_SUCCESS) {
|
|
||||||
/* the update failed, free context and bail */
|
|
||||||
kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
|
|
||||||
ctx->cc_provider_private = NULL;
|
|
||||||
digest->cd_length = 0;
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do a SHA2 final, must be done separately since the digest
|
|
||||||
* type can be different than the input data type.
|
|
||||||
*/
|
|
||||||
switch (digest->cd_format) {
|
|
||||||
case CRYPTO_DATA_RAW:
|
|
||||||
SHA2Final((unsigned char *)digest->cd_raw.iov_base +
|
|
||||||
digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
|
|
||||||
break;
|
|
||||||
case CRYPTO_DATA_UIO:
|
|
||||||
ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
|
|
||||||
digest, sha_digest_len, NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = CRYPTO_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* all done, free context and return */
|
|
||||||
|
|
||||||
if (ret == CRYPTO_SUCCESS)
|
|
||||||
digest->cd_length = sha_digest_len;
|
|
||||||
else
|
|
||||||
digest->cd_length = 0;
|
|
||||||
|
|
||||||
kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
|
|
||||||
ctx->cc_provider_private = NULL;
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sha2_digest_update(crypto_ctx_t *ctx, crypto_data_t *data)
|
|
||||||
{
|
|
||||||
int ret = CRYPTO_SUCCESS;
|
|
||||||
|
|
||||||
ASSERT(ctx->cc_provider_private != NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the SHA2 update on the specified input data.
|
|
||||||
*/
|
|
||||||
switch (data->cd_format) {
|
|
||||||
case CRYPTO_DATA_RAW:
|
|
||||||
SHA2Update(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
|
|
||||||
(uint8_t *)data->cd_raw.iov_base + data->cd_offset,
|
|
||||||
data->cd_length);
|
|
||||||
break;
|
|
||||||
case CRYPTO_DATA_UIO:
|
|
||||||
ret = sha2_digest_update_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
|
|
||||||
data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = CRYPTO_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sha2_digest_final(crypto_ctx_t *ctx, crypto_data_t *digest)
|
|
||||||
{
|
|
||||||
int ret = CRYPTO_SUCCESS;
|
|
||||||
uint_t sha_digest_len;
|
|
||||||
|
|
||||||
ASSERT(ctx->cc_provider_private != NULL);
|
|
||||||
|
|
||||||
switch (PROV_SHA2_CTX(ctx)->sc_mech_type) {
|
|
||||||
case SHA256_MECH_INFO_TYPE:
|
|
||||||
sha_digest_len = SHA256_DIGEST_LENGTH;
|
|
||||||
break;
|
|
||||||
case SHA384_MECH_INFO_TYPE:
|
|
||||||
sha_digest_len = SHA384_DIGEST_LENGTH;
|
|
||||||
break;
|
|
||||||
case SHA512_MECH_INFO_TYPE:
|
|
||||||
sha_digest_len = SHA512_DIGEST_LENGTH;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (CRYPTO_MECHANISM_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need to just return the length needed to store the output.
|
|
||||||
* We should not destroy the context for the following cases.
|
|
||||||
*/
|
|
||||||
if ((digest->cd_length == 0) ||
|
|
||||||
(digest->cd_length < sha_digest_len)) {
|
|
||||||
digest->cd_length = sha_digest_len;
|
|
||||||
return (CRYPTO_BUFFER_TOO_SMALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do a SHA2 final.
|
|
||||||
*/
|
|
||||||
switch (digest->cd_format) {
|
|
||||||
case CRYPTO_DATA_RAW:
|
|
||||||
SHA2Final((unsigned char *)digest->cd_raw.iov_base +
|
|
||||||
digest->cd_offset, &PROV_SHA2_CTX(ctx)->sc_sha2_ctx);
|
|
||||||
break;
|
|
||||||
case CRYPTO_DATA_UIO:
|
|
||||||
ret = sha2_digest_final_uio(&PROV_SHA2_CTX(ctx)->sc_sha2_ctx,
|
|
||||||
digest, sha_digest_len, NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = CRYPTO_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* all done, free context and return */
|
|
||||||
|
|
||||||
if (ret == CRYPTO_SUCCESS)
|
|
||||||
digest->cd_length = sha_digest_len;
|
|
||||||
else
|
|
||||||
digest->cd_length = 0;
|
|
||||||
|
|
||||||
kmem_free(ctx->cc_provider_private, sizeof (sha2_ctx_t));
|
|
||||||
ctx->cc_provider_private = NULL;
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
sha2_digest_atomic(crypto_mechanism_t *mechanism, crypto_data_t *data,
|
|
||||||
crypto_data_t *digest)
|
|
||||||
{
|
|
||||||
int ret = CRYPTO_SUCCESS;
|
|
||||||
SHA2_CTX sha2_ctx;
|
|
||||||
uint32_t sha_digest_len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the SHA inits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SHA2Init(mechanism->cm_type, &sha2_ctx);
|
|
||||||
|
|
||||||
switch (data->cd_format) {
|
|
||||||
case CRYPTO_DATA_RAW:
|
|
||||||
SHA2Update(&sha2_ctx, (uint8_t *)data->
|
|
||||||
cd_raw.iov_base + data->cd_offset, data->cd_length);
|
|
||||||
break;
|
|
||||||
case CRYPTO_DATA_UIO:
|
|
||||||
ret = sha2_digest_update_uio(&sha2_ctx, data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = CRYPTO_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the SHA updates on the specified input data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ret != CRYPTO_SUCCESS) {
|
|
||||||
/* the update failed, bail */
|
|
||||||
digest->cd_length = 0;
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mechanism->cm_type <= SHA256_HMAC_GEN_MECH_INFO_TYPE)
|
|
||||||
sha_digest_len = SHA256_DIGEST_LENGTH;
|
|
||||||
else
|
|
||||||
sha_digest_len = SHA512_DIGEST_LENGTH;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do a SHA2 final, must be done separately since the digest
|
|
||||||
* type can be different than the input data type.
|
|
||||||
*/
|
|
||||||
switch (digest->cd_format) {
|
|
||||||
case CRYPTO_DATA_RAW:
|
|
||||||
SHA2Final((unsigned char *)digest->cd_raw.iov_base +
|
|
||||||
digest->cd_offset, &sha2_ctx);
|
|
||||||
break;
|
|
||||||
case CRYPTO_DATA_UIO:
|
|
||||||
ret = sha2_digest_final_uio(&sha2_ctx, digest,
|
|
||||||
sha_digest_len, NULL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = CRYPTO_ARGUMENTS_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == CRYPTO_SUCCESS)
|
|
||||||
digest->cd_length = sha_digest_len;
|
|
||||||
else
|
|
||||||
digest->cd_length = 0;
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* KCF software provider mac entry points.
|
* KCF software provider mac entry points.
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,34 +31,16 @@
|
||||||
#include <sys/skein.h>
|
#include <sys/skein.h>
|
||||||
|
|
||||||
static const crypto_mech_info_t skein_mech_info_tab[] = {
|
static const crypto_mech_info_t skein_mech_info_tab[] = {
|
||||||
{CKM_SKEIN_256, SKEIN_256_MECH_INFO_TYPE,
|
|
||||||
CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC},
|
|
||||||
{CKM_SKEIN_256_MAC, SKEIN_256_MAC_MECH_INFO_TYPE,
|
{CKM_SKEIN_256_MAC, SKEIN_256_MAC_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
{CKM_SKEIN_512, SKEIN_512_MECH_INFO_TYPE,
|
|
||||||
CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC},
|
|
||||||
{CKM_SKEIN_512_MAC, SKEIN_512_MAC_MECH_INFO_TYPE,
|
{CKM_SKEIN_512_MAC, SKEIN_512_MAC_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
{CKM_SKEIN1024, SKEIN1024_MECH_INFO_TYPE,
|
|
||||||
CRYPTO_FG_DIGEST | CRYPTO_FG_DIGEST_ATOMIC},
|
|
||||||
{CKM_SKEIN1024_MAC, SKEIN1024_MAC_MECH_INFO_TYPE,
|
{CKM_SKEIN1024_MAC, SKEIN1024_MAC_MECH_INFO_TYPE,
|
||||||
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int skein_digest_init(crypto_ctx_t *, crypto_mechanism_t *);
|
|
||||||
static int skein_digest(crypto_ctx_t *, crypto_data_t *, crypto_data_t *);
|
|
||||||
static int skein_update(crypto_ctx_t *, crypto_data_t *);
|
static int skein_update(crypto_ctx_t *, crypto_data_t *);
|
||||||
static int skein_final(crypto_ctx_t *, crypto_data_t *);
|
static int skein_final(crypto_ctx_t *, crypto_data_t *);
|
||||||
static int skein_digest_atomic(crypto_mechanism_t *, crypto_data_t *,
|
|
||||||
crypto_data_t *);
|
|
||||||
|
|
||||||
static const crypto_digest_ops_t skein_digest_ops = {
|
|
||||||
.digest_init = skein_digest_init,
|
|
||||||
.digest = skein_digest,
|
|
||||||
.digest_update = skein_update,
|
|
||||||
.digest_final = skein_final,
|
|
||||||
.digest_atomic = skein_digest_atomic
|
|
||||||
};
|
|
||||||
|
|
||||||
static int skein_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
|
static int skein_mac_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
|
||||||
crypto_spi_ctx_template_t);
|
crypto_spi_ctx_template_t);
|
||||||
|
@ -84,7 +66,6 @@ static const crypto_ctx_ops_t skein_ctx_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const crypto_ops_t skein_crypto_ops = {
|
static const crypto_ops_t skein_crypto_ops = {
|
||||||
&skein_digest_ops,
|
|
||||||
NULL,
|
NULL,
|
||||||
&skein_mac_ops,
|
&skein_mac_ops,
|
||||||
&skein_ctx_ops,
|
&skein_ctx_ops,
|
||||||
|
@ -115,15 +96,12 @@ typedef struct skein_ctx {
|
||||||
do { \
|
do { \
|
||||||
skein_ctx_t *sc = (_skein_ctx); \
|
skein_ctx_t *sc = (_skein_ctx); \
|
||||||
switch (sc->sc_mech_type) { \
|
switch (sc->sc_mech_type) { \
|
||||||
case SKEIN_256_MECH_INFO_TYPE: \
|
|
||||||
case SKEIN_256_MAC_MECH_INFO_TYPE: \
|
case SKEIN_256_MAC_MECH_INFO_TYPE: \
|
||||||
(void) Skein_256_ ## _op(&sc->sc_256, __VA_ARGS__);\
|
(void) Skein_256_ ## _op(&sc->sc_256, __VA_ARGS__);\
|
||||||
break; \
|
break; \
|
||||||
case SKEIN_512_MECH_INFO_TYPE: \
|
|
||||||
case SKEIN_512_MAC_MECH_INFO_TYPE: \
|
case SKEIN_512_MAC_MECH_INFO_TYPE: \
|
||||||
(void) Skein_512_ ## _op(&sc->sc_512, __VA_ARGS__);\
|
(void) Skein_512_ ## _op(&sc->sc_512, __VA_ARGS__);\
|
||||||
break; \
|
break; \
|
||||||
case SKEIN1024_MECH_INFO_TYPE: \
|
|
||||||
case SKEIN1024_MAC_MECH_INFO_TYPE: \
|
case SKEIN1024_MAC_MECH_INFO_TYPE: \
|
||||||
(void) Skein1024_ ## _op(&sc->sc_1024, __VA_ARGS__);\
|
(void) Skein1024_ ## _op(&sc->sc_1024, __VA_ARGS__);\
|
||||||
break; \
|
break; \
|
||||||
|
@ -143,19 +121,7 @@ skein_get_digest_bitlen(const crypto_mechanism_t *mechanism, size_t *result)
|
||||||
}
|
}
|
||||||
*result = param->sp_digest_bitlen;
|
*result = param->sp_digest_bitlen;
|
||||||
} else {
|
} else {
|
||||||
switch (mechanism->cm_type) {
|
return (CRYPTO_MECHANISM_INVALID);
|
||||||
case SKEIN_256_MECH_INFO_TYPE:
|
|
||||||
*result = 256;
|
|
||||||
break;
|
|
||||||
case SKEIN_512_MECH_INFO_TYPE:
|
|
||||||
*result = 512;
|
|
||||||
break;
|
|
||||||
case SKEIN1024_MECH_INFO_TYPE:
|
|
||||||
*result = 1024;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (CRYPTO_MECHANISM_INVALID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (CRYPTO_SUCCESS);
|
return (CRYPTO_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -320,73 +286,6 @@ skein_digest_final_uio(skein_ctx_t *ctx, crypto_data_t *digest)
|
||||||
* KCF software provider digest entry points.
|
* KCF software provider digest entry points.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Initializes a skein digest context to the configuration in `mechanism'.
|
|
||||||
* The mechanism cm_type must be one of SKEIN_*_MECH_INFO_TYPE. The cm_param
|
|
||||||
* field may contain a skein_param_t structure indicating the length of the
|
|
||||||
* digest the algorithm should produce. Otherwise the default output lengths
|
|
||||||
* are applied (32 bytes for Skein-256, 64 bytes for Skein-512 and 128 bytes
|
|
||||||
* for Skein-1024).
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
skein_digest_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism)
|
|
||||||
{
|
|
||||||
int error = CRYPTO_SUCCESS;
|
|
||||||
|
|
||||||
if (!VALID_SKEIN_DIGEST_MECH(mechanism->cm_type))
|
|
||||||
return (CRYPTO_MECHANISM_INVALID);
|
|
||||||
|
|
||||||
SKEIN_CTX_LVALUE(ctx) = kmem_alloc(sizeof (*SKEIN_CTX(ctx)), KM_SLEEP);
|
|
||||||
if (SKEIN_CTX(ctx) == NULL)
|
|
||||||
return (CRYPTO_HOST_MEMORY);
|
|
||||||
|
|
||||||
SKEIN_CTX(ctx)->sc_mech_type = mechanism->cm_type;
|
|
||||||
error = skein_get_digest_bitlen(mechanism,
|
|
||||||
&SKEIN_CTX(ctx)->sc_digest_bitlen);
|
|
||||||
if (error != CRYPTO_SUCCESS)
|
|
||||||
goto errout;
|
|
||||||
SKEIN_OP(SKEIN_CTX(ctx), Init, SKEIN_CTX(ctx)->sc_digest_bitlen);
|
|
||||||
|
|
||||||
return (CRYPTO_SUCCESS);
|
|
||||||
errout:
|
|
||||||
memset(SKEIN_CTX(ctx), 0, sizeof (*SKEIN_CTX(ctx)));
|
|
||||||
kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
|
|
||||||
SKEIN_CTX_LVALUE(ctx) = NULL;
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Executes a skein_update and skein_digest on a pre-initialized crypto
|
|
||||||
* context in a single step. See the documentation to these functions to
|
|
||||||
* see what to pass here.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
skein_digest(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *digest)
|
|
||||||
{
|
|
||||||
int error = CRYPTO_SUCCESS;
|
|
||||||
|
|
||||||
ASSERT(SKEIN_CTX(ctx) != NULL);
|
|
||||||
|
|
||||||
if (digest->cd_length <
|
|
||||||
CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen)) {
|
|
||||||
digest->cd_length =
|
|
||||||
CRYPTO_BITS2BYTES(SKEIN_CTX(ctx)->sc_digest_bitlen);
|
|
||||||
return (CRYPTO_BUFFER_TOO_SMALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = skein_update(ctx, data);
|
|
||||||
if (error != CRYPTO_SUCCESS) {
|
|
||||||
memset(SKEIN_CTX(ctx), 0, sizeof (*SKEIN_CTX(ctx)));
|
|
||||||
kmem_free(SKEIN_CTX(ctx), sizeof (*SKEIN_CTX(ctx)));
|
|
||||||
SKEIN_CTX_LVALUE(ctx) = NULL;
|
|
||||||
digest->cd_length = 0;
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
error = skein_final(ctx, digest);
|
|
||||||
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs a skein Update with the input message in `data' (successive calls
|
* Performs a skein Update with the input message in `data' (successive calls
|
||||||
* can push more data). This is used both for digest and MAC operation.
|
* can push more data). This is used both for digest and MAC operation.
|
||||||
|
@ -470,46 +369,6 @@ skein_final(crypto_ctx_t *ctx, crypto_data_t *digest)
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Performs a full skein digest computation in a single call, configuring the
|
|
||||||
* algorithm according to `mechanism', reading the input to be digested from
|
|
||||||
* `data' and writing the output to `digest'.
|
|
||||||
* Supported input/output formats are raw, uio and mblk.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
skein_digest_atomic(crypto_mechanism_t *mechanism, crypto_data_t *data,
|
|
||||||
crypto_data_t *digest)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
skein_ctx_t skein_ctx;
|
|
||||||
crypto_ctx_t ctx;
|
|
||||||
SKEIN_CTX_LVALUE(&ctx) = &skein_ctx;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
if (!VALID_SKEIN_DIGEST_MECH(mechanism->cm_type))
|
|
||||||
return (CRYPTO_MECHANISM_INVALID);
|
|
||||||
skein_ctx.sc_mech_type = mechanism->cm_type;
|
|
||||||
error = skein_get_digest_bitlen(mechanism, &skein_ctx.sc_digest_bitlen);
|
|
||||||
if (error != CRYPTO_SUCCESS)
|
|
||||||
goto out;
|
|
||||||
SKEIN_OP(&skein_ctx, Init, skein_ctx.sc_digest_bitlen);
|
|
||||||
|
|
||||||
if ((error = skein_update(&ctx, data)) != CRYPTO_SUCCESS)
|
|
||||||
goto out;
|
|
||||||
if ((error = skein_final_nofree(&ctx, data)) != CRYPTO_SUCCESS)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (error == CRYPTO_SUCCESS)
|
|
||||||
digest->cd_length =
|
|
||||||
CRYPTO_BITS2BYTES(skein_ctx.sc_digest_bitlen);
|
|
||||||
else
|
|
||||||
digest->cd_length = 0;
|
|
||||||
memset(&skein_ctx, 0, sizeof (skein_ctx));
|
|
||||||
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function that builds a Skein MAC context from the provided
|
* Helper function that builds a Skein MAC context from the provided
|
||||||
* mechanism and key.
|
* mechanism and key.
|
||||||
|
|
Loading…
Reference in New Issue