1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "%Z%%M% %I% %E% SMI"
7
8 /*
9 * The basic framework for this code came from the reference
10 * implementation for MD5. That implementation is Copyright (C)
11 * 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
12 *
13 * License to copy and use this software is granted provided that it
14 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
15 * Algorithm" in all material mentioning or referencing this software
16 * or this function.
17 *
18 * License is also granted to make and use derivative works provided
19 * that such works are identified as "derived from the RSA Data
20 * Security, Inc. MD5 Message-Digest Algorithm" in all material
21 * mentioning or referencing the derived work.
22 *
23 * RSA Data Security, Inc. makes no representations concerning either
24 * the merchantability of this software or the suitability of this
25 * software for any particular purpose. It is provided "as is"
26 * without express or implied warranty of any kind.
27 *
28 * These notices must be retained in any copies of any part of this
29 * documentation and/or software.
30 *
31 * NOTE: Cleaned-up and optimized, version of SHA2, based on the FIPS 180-2
32 * standard, available at http://www.itl.nist.gov/div897/pubs/fip180-2.htm
33 * Not as fast as one would like -- further optimizations are encouraged
34 * and appreciated.
35 */
36
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/sysmacros.h>
41 #define _SHA2_IMPL
42 #include <sys/sha2.h>
43 #include <sys/sha2_consts.h>
44
45 #ifdef _KERNEL
46 #include <sys/cmn_err.h>
47
48 #else
49 #include <strings.h>
50 #include <stdlib.h>
51 #include <errno.h>
52
53 #pragma weak SHA256Update = SHA2Update
54 #pragma weak SHA384Update = SHA2Update
55 #pragma weak SHA512Update = SHA2Update
56
57 #pragma weak SHA256Final = SHA2Final
58 #pragma weak SHA384Final = SHA2Final
59 #pragma weak SHA512Final = SHA2Final
60
61 #endif /* _KERNEL */
62
63 static void Encode(uint8_t *, uint32_t *, size_t);
64 static void Encode64(uint8_t *, uint64_t *, size_t);
65
66 #if defined(__amd64)
67 #define SHA512Transform(ctx, in) SHA512TransformBlocks((ctx), (in), 1)
68 #define SHA256Transform(ctx, in) SHA256TransformBlocks((ctx), (in), 1)
69
70 void SHA512TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num);
71 void SHA256TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num);
72
73 #else
74 static void SHA256Transform(SHA2_CTX *, const uint8_t *);
75 static void SHA512Transform(SHA2_CTX *, const uint8_t *);
76 #endif /* __amd64 */
77
78 static uint8_t PADDING[128] = { 0x80, /* all zeros */ };
79
80 /* Ch and Maj are the basic SHA2 functions. */
81 #define Ch(b, c, d) (((b) & (c)) ^ ((~b) & (d)))
82 #define Maj(b, c, d) (((b) & (c)) ^ ((b) & (d)) ^ ((c) & (d)))
104 #define BIGSIGMA0(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
105 #define BIGSIGMA1(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
106 #define SIGMA0(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ SHR((x), 7))
107 #define SIGMA1(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ SHR((x), 6))
108 #define SHA512ROUND(a, b, c, d, e, f, g, h, i, w) \
109 T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + SHA512_CONST(i) + w; \
110 d += T1; \
111 T2 = BIGSIGMA0(a) + Maj(a, b, c); \
112 h = T1 + T2
113
114 /*
115 * sparc optimization:
116 *
117 * on the sparc, we can load big endian 32-bit data easily. note that
118 * special care must be taken to ensure the address is 32-bit aligned.
119 * in the interest of speed, we don't check to make sure, since
120 * careful programming can guarantee this for us.
121 */
122
123 #if defined(_BIG_ENDIAN)
124
125 #define LOAD_BIG_32(addr) (*(uint32_t *)(addr))
126
127 #else /* little endian -- will work on big endian, but slowly */
128
129 #define LOAD_BIG_32(addr) \
130 (((addr)[0] << 24) | ((addr)[1] << 16) | ((addr)[2] << 8) | (addr)[3])
131 #endif
132
133
134 #if defined(_BIG_ENDIAN)
135
136 #define LOAD_BIG_64(addr) (*(uint64_t *)(addr))
137
138 #else /* little endian -- will work on big endian, but slowly */
139
140 #define LOAD_BIG_64(addr) \
141 (((uint64_t)(addr)[0] << 56) | ((uint64_t)(addr)[1] << 48) | \
142 ((uint64_t)(addr)[2] << 40) | ((uint64_t)(addr)[3] << 32) | \
143 ((uint64_t)(addr)[4] << 24) | ((uint64_t)(addr)[5] << 16) | \
144 ((uint64_t)(addr)[6] << 8) | (uint64_t)(addr)[7])
145 #endif
146
147
148 #if !defined(__amd64)
149 /* SHA256 Transform */
150
151 static void
152 SHA256Transform(SHA2_CTX *ctx, const uint8_t *blk)
153 {
154 uint32_t a = ctx->state.s32[0];
155 uint32_t b = ctx->state.s32[1];
156 uint32_t c = ctx->state.s32[2];
157 uint32_t d = ctx->state.s32[3];
158 uint32_t e = ctx->state.s32[4];
159 uint32_t f = ctx->state.s32[5];
160 uint32_t g = ctx->state.s32[6];
161 uint32_t h = ctx->state.s32[7];
162
163 uint32_t w0, w1, w2, w3, w4, w5, w6, w7;
164 uint32_t w8, w9, w10, w11, w12, w13, w14, w15;
165 uint32_t T1, T2;
698 ctx->state.s64[3] = 0x152fecd8f70e5939ULL;
699 ctx->state.s64[4] = 0x67332667ffc00b31ULL;
700 ctx->state.s64[5] = 0x8eb44a8768581511ULL;
701 ctx->state.s64[6] = 0xdb0c2e0d64f98fa7ULL;
702 ctx->state.s64[7] = 0x47b5481dbefa4fa4ULL;
703 break;
704 case SHA512_MECH_INFO_TYPE:
705 case SHA512_HMAC_MECH_INFO_TYPE:
706 case SHA512_HMAC_GEN_MECH_INFO_TYPE:
707 ctx->state.s64[0] = 0x6a09e667f3bcc908ULL;
708 ctx->state.s64[1] = 0xbb67ae8584caa73bULL;
709 ctx->state.s64[2] = 0x3c6ef372fe94f82bULL;
710 ctx->state.s64[3] = 0xa54ff53a5f1d36f1ULL;
711 ctx->state.s64[4] = 0x510e527fade682d1ULL;
712 ctx->state.s64[5] = 0x9b05688c2b3e6c1fULL;
713 ctx->state.s64[6] = 0x1f83d9abfb41bd6bULL;
714 ctx->state.s64[7] = 0x5be0cd19137e2179ULL;
715 break;
716 #ifdef _KERNEL
717 default:
718 cmn_err(CE_PANIC, "sha2_init: "
719 "failed to find a supported algorithm: 0x%x",
720 (uint32_t)mech);
721
722 #endif /* _KERNEL */
723 }
724
725 ctx->algotype = mech;
726 ctx->count.c64[0] = ctx->count.c64[1] = 0;
727 }
728
729 #ifndef _KERNEL
730
731 #pragma inline(SHA256Init, SHA384Init, SHA512Init)
732 void
733 SHA256Init(SHA256_CTX *ctx)
734 {
735 SHA2Init(SHA256, ctx);
736 }
737
738 void
739 SHA384Init(SHA384_CTX *ctx)
|
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * The basic framework for this code came from the reference
8 * implementation for MD5. That implementation is Copyright (C)
9 * 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
10 *
11 * License to copy and use this software is granted provided that it
12 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
13 * Algorithm" in all material mentioning or referencing this software
14 * or this function.
15 *
16 * License is also granted to make and use derivative works provided
17 * that such works are identified as "derived from the RSA Data
18 * Security, Inc. MD5 Message-Digest Algorithm" in all material
19 * mentioning or referencing the derived work.
20 *
21 * RSA Data Security, Inc. makes no representations concerning either
22 * the merchantability of this software or the suitability of this
23 * software for any particular purpose. It is provided "as is"
24 * without express or implied warranty of any kind.
25 *
26 * These notices must be retained in any copies of any part of this
27 * documentation and/or software.
28 *
29 * NOTE: Cleaned-up and optimized, version of SHA2, based on the FIPS 180-2
30 * standard, available at
31 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
32 * Not as fast as one would like -- further optimizations are encouraged
33 * and appreciated.
34 */
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/sysmacros.h>
40 #define _SHA2_IMPL
41 #include <sys/sha2.h>
42 #include <sys/sha2_consts.h>
43
44 #ifdef _KERNEL
45 #include <sys/cmn_err.h>
46
47 #else
48 #include <strings.h>
49 #include <stdlib.h>
50 #include <errno.h>
51
52 #pragma weak SHA256Update = SHA2Update
53 #pragma weak SHA384Update = SHA2Update
54 #pragma weak SHA512Update = SHA2Update
55
56 #pragma weak SHA256Final = SHA2Final
57 #pragma weak SHA384Final = SHA2Final
58 #pragma weak SHA512Final = SHA2Final
59
60 #endif /* _KERNEL */
61
62 #ifdef _LITTLE_ENDIAN
63 #include <sys/byteorder.h>
64 #define HAVE_HTONL
65 #endif
66
67 static void Encode(uint8_t *, uint32_t *, size_t);
68 static void Encode64(uint8_t *, uint64_t *, size_t);
69
70 #if defined(__amd64)
71 #define SHA512Transform(ctx, in) SHA512TransformBlocks((ctx), (in), 1)
72 #define SHA256Transform(ctx, in) SHA256TransformBlocks((ctx), (in), 1)
73
74 void SHA512TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num);
75 void SHA256TransformBlocks(SHA2_CTX *ctx, const void *in, size_t num);
76
77 #else
78 static void SHA256Transform(SHA2_CTX *, const uint8_t *);
79 static void SHA512Transform(SHA2_CTX *, const uint8_t *);
80 #endif /* __amd64 */
81
82 static uint8_t PADDING[128] = { 0x80, /* all zeros */ };
83
84 /* Ch and Maj are the basic SHA2 functions. */
85 #define Ch(b, c, d) (((b) & (c)) ^ ((~b) & (d)))
86 #define Maj(b, c, d) (((b) & (c)) ^ ((b) & (d)) ^ ((c) & (d)))
108 #define BIGSIGMA0(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
109 #define BIGSIGMA1(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
110 #define SIGMA0(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ SHR((x), 7))
111 #define SIGMA1(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ SHR((x), 6))
112 #define SHA512ROUND(a, b, c, d, e, f, g, h, i, w) \
113 T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + SHA512_CONST(i) + w; \
114 d += T1; \
115 T2 = BIGSIGMA0(a) + Maj(a, b, c); \
116 h = T1 + T2
117
118 /*
119 * sparc optimization:
120 *
121 * on the sparc, we can load big endian 32-bit data easily. note that
122 * special care must be taken to ensure the address is 32-bit aligned.
123 * in the interest of speed, we don't check to make sure, since
124 * careful programming can guarantee this for us.
125 */
126
127 #if defined(_BIG_ENDIAN)
128 #define LOAD_BIG_32(addr) (*(uint32_t *)(addr))
129 #define LOAD_BIG_64(addr) (*(uint64_t *)(addr))
130
131 #elif defined(HAVE_HTONL)
132 #define LOAD_BIG_32(addr) htonl(*((uint32_t *)(addr)))
133 #define LOAD_BIG_64(addr) htonll(*((uint64_t *)(addr)))
134
135 #else
136 /* little endian -- will work on big endian, but slowly */
137 #define LOAD_BIG_32(addr) \
138 (((addr)[0] << 24) | ((addr)[1] << 16) | ((addr)[2] << 8) | (addr)[3])
139 #define LOAD_BIG_64(addr) \
140 (((uint64_t)(addr)[0] << 56) | ((uint64_t)(addr)[1] << 48) | \
141 ((uint64_t)(addr)[2] << 40) | ((uint64_t)(addr)[3] << 32) | \
142 ((uint64_t)(addr)[4] << 24) | ((uint64_t)(addr)[5] << 16) | \
143 ((uint64_t)(addr)[6] << 8) | (uint64_t)(addr)[7])
144 #endif /* _BIG_ENDIAN */
145
146
147 #if !defined(__amd64)
148 /* SHA256 Transform */
149
150 static void
151 SHA256Transform(SHA2_CTX *ctx, const uint8_t *blk)
152 {
153 uint32_t a = ctx->state.s32[0];
154 uint32_t b = ctx->state.s32[1];
155 uint32_t c = ctx->state.s32[2];
156 uint32_t d = ctx->state.s32[3];
157 uint32_t e = ctx->state.s32[4];
158 uint32_t f = ctx->state.s32[5];
159 uint32_t g = ctx->state.s32[6];
160 uint32_t h = ctx->state.s32[7];
161
162 uint32_t w0, w1, w2, w3, w4, w5, w6, w7;
163 uint32_t w8, w9, w10, w11, w12, w13, w14, w15;
164 uint32_t T1, T2;
697 ctx->state.s64[3] = 0x152fecd8f70e5939ULL;
698 ctx->state.s64[4] = 0x67332667ffc00b31ULL;
699 ctx->state.s64[5] = 0x8eb44a8768581511ULL;
700 ctx->state.s64[6] = 0xdb0c2e0d64f98fa7ULL;
701 ctx->state.s64[7] = 0x47b5481dbefa4fa4ULL;
702 break;
703 case SHA512_MECH_INFO_TYPE:
704 case SHA512_HMAC_MECH_INFO_TYPE:
705 case SHA512_HMAC_GEN_MECH_INFO_TYPE:
706 ctx->state.s64[0] = 0x6a09e667f3bcc908ULL;
707 ctx->state.s64[1] = 0xbb67ae8584caa73bULL;
708 ctx->state.s64[2] = 0x3c6ef372fe94f82bULL;
709 ctx->state.s64[3] = 0xa54ff53a5f1d36f1ULL;
710 ctx->state.s64[4] = 0x510e527fade682d1ULL;
711 ctx->state.s64[5] = 0x9b05688c2b3e6c1fULL;
712 ctx->state.s64[6] = 0x1f83d9abfb41bd6bULL;
713 ctx->state.s64[7] = 0x5be0cd19137e2179ULL;
714 break;
715 #ifdef _KERNEL
716 default:
717 cmn_err(CE_PANIC,
718 "sha2_init: failed to find a supported algorithm: 0x%x",
719 (uint32_t)mech);
720
721 #endif /* _KERNEL */
722 }
723
724 ctx->algotype = mech;
725 ctx->count.c64[0] = ctx->count.c64[1] = 0;
726 }
727
728 #ifndef _KERNEL
729
730 #pragma inline(SHA256Init, SHA384Init, SHA512Init)
731 void
732 SHA256Init(SHA256_CTX *ctx)
733 {
734 SHA2Init(SHA256, ctx);
735 }
736
737 void
738 SHA384Init(SHA384_CTX *ctx)
|