sha2.c revision f66d273d14eede3a1bb803a39414588d8f143a98
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Use is subject to license terms.
843e19887f64dde75055cf8842fc4db2171eff45johnlev#pragma ident "%Z%%M% %I% %E% SMI"
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The basic framework for this code came from the reference
843e19887f64dde75055cf8842fc4db2171eff45johnlev * implementation for MD5. That implementation is Copyright (C)
843e19887f64dde75055cf8842fc4db2171eff45johnlev * 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * License to copy and use this software is granted provided that it
843e19887f64dde75055cf8842fc4db2171eff45johnlev * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Algorithm" in all material mentioning or referencing this software
843e19887f64dde75055cf8842fc4db2171eff45johnlev * or this function.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * License is also granted to make and use derivative works provided
843e19887f64dde75055cf8842fc4db2171eff45johnlev * that such works are identified as "derived from the RSA Data
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Security, Inc. MD5 Message-Digest Algorithm" in all material
843e19887f64dde75055cf8842fc4db2171eff45johnlev * mentioning or referencing the derived work.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * RSA Data Security, Inc. makes no representations concerning either
843e19887f64dde75055cf8842fc4db2171eff45johnlev * the merchantability of this software or the suitability of this
843e19887f64dde75055cf8842fc4db2171eff45johnlev * software for any particular purpose. It is provided "as is"
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * without express or implied warranty of any kind.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * These notices must be retained in any copies of any part of this
843e19887f64dde75055cf8842fc4db2171eff45johnlev * documentation and/or software.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * NOTE: Cleaned-up and optimized, version of SHA2, based on the FIPS 180-2
843e19887f64dde75055cf8842fc4db2171eff45johnlev * standard, available at http://www.itl.nist.gov/div897/pubs/fip180-2.htm
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * Not as fast as one would like -- further optimizations are encouraged
843e19887f64dde75055cf8842fc4db2171eff45johnlev * and appreciated.
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab * The sha2 module is created with two modlinkages:
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab * - a modlmisc that allows consumers to directly call the entry points
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab * SHA2Init, SHA2Update, and SHA2Final.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * - a modlcrypto that allows the module to register with the Kernel
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Cryptographic Framework (KCF) as a software provider for the SHA2
843e19887f64dde75055cf8842fc4db2171eff45johnlev * mechanisms.
843e19887f64dde75055cf8842fc4db2171eff45johnlev#endif /* !_KERNEL */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void SHA256Transform(SHA2_CTX *, const uint8_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void SHA512Transform(SHA2_CTX *, const uint8_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic uint8_t PADDING[128] = { 0x80, /* all zeros */ };
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* Ch and Maj are the basic SHA2 functions. */
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define Ch(b, c, d) (((b) & (c)) ^ ((~b) & (d)))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define Maj(b, c, d) (((b) & (c)) ^ ((b) & (d)) ^ ((c) & (d)))
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* Rotates x right n bits. */
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define ROTR(x, n) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* Shift x right n bits */
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SHR(x, n) ((x) >> (n))
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* SHA256 Functions */
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define BIGSIGMA0_256(x) (ROTR((x), 2) ^ ROTR((x), 13) ^ ROTR((x), 22))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define BIGSIGMA1_256(x) (ROTR((x), 6) ^ ROTR((x), 11) ^ ROTR((x), 25))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SIGMA0_256(x) (ROTR((x), 7) ^ ROTR((x), 18) ^ SHR((x), 3))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SIGMA1_256(x) (ROTR((x), 17) ^ ROTR((x), 19) ^ SHR((x), 10))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SHA256ROUND(a, b, c, d, e, f, g, h, i, w) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_CONST(i) + w; \
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* SHA384/512 Functions */
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define BIGSIGMA0(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define BIGSIGMA1(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SIGMA0(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ SHR((x), 7))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SIGMA1(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ SHR((x), 6))
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define SHA512ROUND(a, b, c, d, e, f, g, h, i, w) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + SHA512_CONST(i) + w; \
843e19887f64dde75055cf8842fc4db2171eff45johnlev "SHA2 Message-Digest Algorithm"
843e19887f64dde75055cf8842fc4db2171eff45johnlev "SHA2 Kernel SW Provider %I%"
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CSPI information (entry points, provider info, etc.)
843e19887f64dde75055cf8842fc4db2171eff45johnlev#endif /* _KERNEL */
843e19887f64dde75055cf8842fc4db2171eff45johnlev * List of support mechanisms in this module.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * It is important to note that in the module, division or modulus calculations
843e19887f64dde75055cf8842fc4db2171eff45johnlev * are used on the enumerated type to determine which mechanism is being used;
843e19887f64dde75055cf8842fc4db2171eff45johnlev * therefore, changing the order or additional mechanisms should be done
843e19887f64dde75055cf8842fc4db2171eff45johnlev * carefully
843e19887f64dde75055cf8842fc4db2171eff45johnlev SHA256_HMAC_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC */
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab SHA256_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA256_HMAC_GENERAL */
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab SHA384_HMAC_GEN_MECH_INFO_TYPE, /* SUN_CKM_SHA384_HMAC_GENERAL */
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab SHA512_HMAC_GEN_MECH_INFO_TYPE /* SUN_CKM_SHA512_HMAC_GENERAL */
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Context for SHA2 mechanism.
843e19887f64dde75055cf8842fc4db2171eff45johnlevtypedef struct sha2_ctx {
843e19887f64dde75055cf8842fc4db2171eff45johnlev sha2_mech_type_t sc_mech_type; /* type of context */
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Context for SHA2 HMAC and HMAC GENERAL mechanisms.
843e19887f64dde75055cf8842fc4db2171eff45johnlevtypedef struct sha2_hmac_ctx {
843e19887f64dde75055cf8842fc4db2171eff45johnlev sha2_mech_type_t hc_mech_type; /* type of context */
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Macros to access the SHA2 or SHA2-HMAC contexts from a context passed
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee * by KCF to one of the entry points.
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye#define PROV_SHA2_CTX(ctx) ((sha2_ctx_t *)(ctx)->cc_provider_private)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye#define PROV_SHA2_HMAC_CTX(ctx) ((sha2_hmac_ctx_t *)(ctx)->cc_provider_private)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* to extract the digest length passed as mechanism parameter */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (IS_P2ALIGNED((m)->cm_param, sizeof (ulong_t))) \
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (len) = (uint32_t)*((ulong_t *)(m)->cm_param); \
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye bcopy((m)->cm_param, &tmp_ulong, sizeof (ulong_t)); \
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define PROV_SHA2_DIGEST_KEY(mech, ctx, key, len, digest) { \
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Mechanism info structure passed to KCF during registration.
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA256 */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /* SHA256-HMAC */
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA256-HMAC GENERAL */
843e19887f64dde75055cf8842fc4db2171eff45johnlev {SUN_CKM_SHA256_HMAC_GENERAL, SHA256_HMAC_GEN_MECH_INFO_TYPE,
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA384 */
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA384-HMAC */
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA384-HMAC GENERAL */
843e19887f64dde75055cf8842fc4db2171eff45johnlev {SUN_CKM_SHA384_HMAC_GENERAL, SHA384_HMAC_GEN_MECH_INFO_TYPE,
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA512 */
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA512-HMAC */
843e19887f64dde75055cf8842fc4db2171eff45johnlev /* SHA512-HMAC GENERAL */
843e19887f64dde75055cf8842fc4db2171eff45johnlev {SUN_CKM_SHA512_HMAC_GENERAL, SHA512_HMAC_GEN_MECH_INFO_TYPE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
{&modlinkage},
NULL,
_init()
int ret;
return (ret);
#if defined(_BIG_ENDIAN)
#if defined(_BIG_ENDIAN)
#if defined(__sparc)
#if defined(__sparc)
#if defined(__sparc)
#if defined(__sparc)
#ifdef __RESTRICT
#define restrict _Restrict
size_t i, j;
#if defined(__sparc)
#if defined(__sparc)
size_t i, j;
#if defined(__sparc)
#if defined(__sparc)
#ifdef _KERNEL
return (CRYPTO_HOST_MEMORY);
return (CRYPTO_SUCCESS);
return (CRYPTO_ARGUMENTS_BAD);
return (CRYPTO_DATA_LEN_RANGE);
vec_idx++;
offset = 0;
return (CRYPTO_DATA_LEN_RANGE);
return (CRYPTO_SUCCESS);
return (CRYPTO_ARGUMENTS_BAD);
return (CRYPTO_DATA_LEN_RANGE);
sha2_ctx);
cur_len =
cur_len);
vec_idx++;
offset = 0;
return (CRYPTO_DATA_LEN_RANGE);
return (CRYPTO_SUCCESS);
return (CRYPTO_DATA_LEN_RANGE);
offset = 0;
return (CRYPTO_DATA_LEN_RANGE);
return (CRYPTO_SUCCESS);
return (CRYPTO_DATA_LEN_RANGE);
offset = 0;
return (CRYPTO_DATA_LEN_RANGE);
return (CRYPTO_SUCCESS);
case SHA256_MECH_INFO_TYPE:
case SHA384_MECH_INFO_TYPE:
case SHA512_MECH_INFO_TYPE:
return (CRYPTO_MECHANISM_INVALID);
return (CRYPTO_BUFFER_TOO_SMALL);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
data);
case CRYPTO_DATA_MBLK:
data);
return (ret);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (ret);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
data);
case CRYPTO_DATA_MBLK:
data);
return (ret);
case SHA256_MECH_INFO_TYPE:
case SHA384_MECH_INFO_TYPE:
case SHA512_MECH_INFO_TYPE:
return (CRYPTO_MECHANISM_INVALID);
return (CRYPTO_BUFFER_TOO_SMALL);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (ret);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (ret);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (ret);
for (i = 0; i < blocks_per_int64; i ++) {
return (CRYPTO_MECHANISM_INVALID);
return (CRYPTO_ARGUMENTS_BAD);
return (CRYPTO_HOST_MEMORY);
sizeof (sha2_hmac_ctx_t));
return (ret);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (ret);
return (CRYPTO_BUFFER_TOO_SMALL);
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (ret);
case CRYPTO_DATA_RAW: \
case CRYPTO_DATA_UIO: \
case CRYPTO_DATA_MBLK: \
data); \
return (CRYPTO_MECHANISM_INVALID);
return (CRYPTO_ARGUMENTS_BAD);
goto bail;
goto bail;
goto bail;
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO:
case CRYPTO_DATA_MBLK:
return (CRYPTO_SUCCESS);
bail:
return (ret);
return (CRYPTO_MECHANISM_INVALID);
return (CRYPTO_ARGUMENTS_BAD);
goto bail;
goto bail;
goto bail;
goto bail;
case CRYPTO_DATA_RAW:
case CRYPTO_DATA_UIO: {
return (CRYPTO_ARGUMENTS_BAD);
for (vec_idx = 0;
cur_len) != 0) {
vec_idx++;
offset = 0;
case CRYPTO_DATA_MBLK: {
offset = 0;
return (ret);
bail:
return (ret);
return (CRYPTO_MECHANISM_INVALID);
return (CRYPTO_ARGUMENTS_BAD);
return (CRYPTO_HOST_MEMORY);
return (CRYPTO_SUCCESS);
return (CRYPTO_SUCCESS);
return (CRYPTO_SUCCESS);
switch (mech) {
case SHA256_MECH_INFO_TYPE:
case SHA384_MECH_INFO_TYPE:
case SHA512_MECH_INFO_TYPE:
#ifdef _KERNEL
if (input_len == 0)
if (buf_index) {
i = buf_len;
if (input_len == i)
buf_index = 0;
sizeof (bitcount_be64));