Commit f2ea0f5f04c97b48c88edccba52b0682fbe45087
Committed by
Herbert Xu
1 parent
3a92d687c8
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
crypto: sha512 - use standard ror64()
Use standard ror64() instead of hand-written. There is no standard ror64, so create it. The difference is shift value being "unsigned int" instead of uint64_t (for which there is no reason). gcc starts to emit native ROR instructions which it doesn't do for some reason currently. This should make the code faster. Patch survives in-tree crypto test and ping flood with hmac(sha512) on. Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Showing 2 changed files with 24 additions and 9 deletions Inline Diff
crypto/sha512_generic.c
1 | /* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com> | 1 | /* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com> |
2 | * | 2 | * |
3 | * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> | 3 | * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> |
4 | * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> | 4 | * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> |
5 | * Copyright (c) 2003 Kyle McMartin <kyle@debian.org> | 5 | * Copyright (c) 2003 Kyle McMartin <kyle@debian.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
9 | * Free Software Foundation; either version 2, or (at your option) any | 9 | * Free Software Foundation; either version 2, or (at your option) any |
10 | * later version. | 10 | * later version. |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | #include <crypto/internal/hash.h> | 13 | #include <crypto/internal/hash.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/crypto.h> | 18 | #include <linux/crypto.h> |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <crypto/sha.h> | 20 | #include <crypto/sha.h> |
21 | #include <linux/percpu.h> | 21 | #include <linux/percpu.h> |
22 | #include <asm/byteorder.h> | 22 | #include <asm/byteorder.h> |
23 | 23 | ||
24 | static inline u64 Ch(u64 x, u64 y, u64 z) | 24 | static inline u64 Ch(u64 x, u64 y, u64 z) |
25 | { | 25 | { |
26 | return z ^ (x & (y ^ z)); | 26 | return z ^ (x & (y ^ z)); |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline u64 Maj(u64 x, u64 y, u64 z) | 29 | static inline u64 Maj(u64 x, u64 y, u64 z) |
30 | { | 30 | { |
31 | return (x & y) | (z & (x | y)); | 31 | return (x & y) | (z & (x | y)); |
32 | } | 32 | } |
33 | 33 | ||
34 | static inline u64 RORu64(u64 x, u64 y) | ||
35 | { | ||
36 | return (x >> y) | (x << (64 - y)); | ||
37 | } | ||
38 | |||
39 | static const u64 sha512_K[80] = { | 34 | static const u64 sha512_K[80] = { |
40 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, | 35 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, |
41 | 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, | 36 | 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, |
42 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, | 37 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, |
43 | 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, | 38 | 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, |
44 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, | 39 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, |
45 | 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, | 40 | 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, |
46 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, | 41 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, |
47 | 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, | 42 | 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, |
48 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, | 43 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, |
49 | 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, | 44 | 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, |
50 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, | 45 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, |
51 | 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, | 46 | 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, |
52 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, | 47 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, |
53 | 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, | 48 | 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, |
54 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, | 49 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, |
55 | 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, | 50 | 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, |
56 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, | 51 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, |
57 | 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, | 52 | 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, |
58 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, | 53 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, |
59 | 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, | 54 | 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, |
60 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, | 55 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, |
61 | 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, | 56 | 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, |
62 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, | 57 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, |
63 | 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, | 58 | 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, |
64 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, | 59 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, |
65 | 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, | 60 | 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, |
66 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, | 61 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, |
67 | }; | 62 | }; |
68 | 63 | ||
69 | #define e0(x) (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39)) | 64 | #define e0(x) (ror64(x,28) ^ ror64(x,34) ^ ror64(x,39)) |
70 | #define e1(x) (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41)) | 65 | #define e1(x) (ror64(x,14) ^ ror64(x,18) ^ ror64(x,41)) |
71 | #define s0(x) (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7)) | 66 | #define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) |
72 | #define s1(x) (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6)) | 67 | #define s1(x) (ror64(x,19) ^ ror64(x,61) ^ (x >> 6)) |
73 | 68 | ||
74 | static inline void LOAD_OP(int I, u64 *W, const u8 *input) | 69 | static inline void LOAD_OP(int I, u64 *W, const u8 *input) |
75 | { | 70 | { |
76 | W[I] = __be64_to_cpu( ((__be64*)(input))[I] ); | 71 | W[I] = __be64_to_cpu( ((__be64*)(input))[I] ); |
77 | } | 72 | } |
78 | 73 | ||
79 | static inline void BLEND_OP(int I, u64 *W) | 74 | static inline void BLEND_OP(int I, u64 *W) |
80 | { | 75 | { |
81 | W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]); | 76 | W[I & 15] += s1(W[(I-2) & 15]) + W[(I-7) & 15] + s0(W[(I-15) & 15]); |
82 | } | 77 | } |
83 | 78 | ||
84 | static void | 79 | static void |
85 | sha512_transform(u64 *state, const u8 *input) | 80 | sha512_transform(u64 *state, const u8 *input) |
86 | { | 81 | { |
87 | u64 a, b, c, d, e, f, g, h, t1, t2; | 82 | u64 a, b, c, d, e, f, g, h, t1, t2; |
88 | 83 | ||
89 | int i; | 84 | int i; |
90 | u64 W[16]; | 85 | u64 W[16]; |
91 | 86 | ||
92 | /* load the state into our registers */ | 87 | /* load the state into our registers */ |
93 | a=state[0]; b=state[1]; c=state[2]; d=state[3]; | 88 | a=state[0]; b=state[1]; c=state[2]; d=state[3]; |
94 | e=state[4]; f=state[5]; g=state[6]; h=state[7]; | 89 | e=state[4]; f=state[5]; g=state[6]; h=state[7]; |
95 | 90 | ||
96 | /* now iterate */ | 91 | /* now iterate */ |
97 | for (i=0; i<80; i+=8) { | 92 | for (i=0; i<80; i+=8) { |
98 | if (!(i & 8)) { | 93 | if (!(i & 8)) { |
99 | int j; | 94 | int j; |
100 | 95 | ||
101 | if (i < 16) { | 96 | if (i < 16) { |
102 | /* load the input */ | 97 | /* load the input */ |
103 | for (j = 0; j < 16; j++) | 98 | for (j = 0; j < 16; j++) |
104 | LOAD_OP(i + j, W, input); | 99 | LOAD_OP(i + j, W, input); |
105 | } else { | 100 | } else { |
106 | for (j = 0; j < 16; j++) { | 101 | for (j = 0; j < 16; j++) { |
107 | BLEND_OP(i + j, W); | 102 | BLEND_OP(i + j, W); |
108 | } | 103 | } |
109 | } | 104 | } |
110 | } | 105 | } |
111 | 106 | ||
112 | t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)]; | 107 | t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[(i & 15)]; |
113 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; | 108 | t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; |
114 | t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1]; | 109 | t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[(i & 15) + 1]; |
115 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; | 110 | t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; |
116 | t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2]; | 111 | t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[(i & 15) + 2]; |
117 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; | 112 | t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; |
118 | t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3]; | 113 | t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[(i & 15) + 3]; |
119 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; | 114 | t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; |
120 | t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4]; | 115 | t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[(i & 15) + 4]; |
121 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; | 116 | t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; |
122 | t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5]; | 117 | t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[(i & 15) + 5]; |
123 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; | 118 | t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; |
124 | t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6]; | 119 | t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[(i & 15) + 6]; |
125 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; | 120 | t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; |
126 | t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7]; | 121 | t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[(i & 15) + 7]; |
127 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; | 122 | t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; |
128 | } | 123 | } |
129 | 124 | ||
130 | state[0] += a; state[1] += b; state[2] += c; state[3] += d; | 125 | state[0] += a; state[1] += b; state[2] += c; state[3] += d; |
131 | state[4] += e; state[5] += f; state[6] += g; state[7] += h; | 126 | state[4] += e; state[5] += f; state[6] += g; state[7] += h; |
132 | 127 | ||
133 | /* erase our data */ | 128 | /* erase our data */ |
134 | a = b = c = d = e = f = g = h = t1 = t2 = 0; | 129 | a = b = c = d = e = f = g = h = t1 = t2 = 0; |
135 | } | 130 | } |
136 | 131 | ||
137 | static int | 132 | static int |
138 | sha512_init(struct shash_desc *desc) | 133 | sha512_init(struct shash_desc *desc) |
139 | { | 134 | { |
140 | struct sha512_state *sctx = shash_desc_ctx(desc); | 135 | struct sha512_state *sctx = shash_desc_ctx(desc); |
141 | sctx->state[0] = SHA512_H0; | 136 | sctx->state[0] = SHA512_H0; |
142 | sctx->state[1] = SHA512_H1; | 137 | sctx->state[1] = SHA512_H1; |
143 | sctx->state[2] = SHA512_H2; | 138 | sctx->state[2] = SHA512_H2; |
144 | sctx->state[3] = SHA512_H3; | 139 | sctx->state[3] = SHA512_H3; |
145 | sctx->state[4] = SHA512_H4; | 140 | sctx->state[4] = SHA512_H4; |
146 | sctx->state[5] = SHA512_H5; | 141 | sctx->state[5] = SHA512_H5; |
147 | sctx->state[6] = SHA512_H6; | 142 | sctx->state[6] = SHA512_H6; |
148 | sctx->state[7] = SHA512_H7; | 143 | sctx->state[7] = SHA512_H7; |
149 | sctx->count[0] = sctx->count[1] = 0; | 144 | sctx->count[0] = sctx->count[1] = 0; |
150 | 145 | ||
151 | return 0; | 146 | return 0; |
152 | } | 147 | } |
153 | 148 | ||
154 | static int | 149 | static int |
155 | sha384_init(struct shash_desc *desc) | 150 | sha384_init(struct shash_desc *desc) |
156 | { | 151 | { |
157 | struct sha512_state *sctx = shash_desc_ctx(desc); | 152 | struct sha512_state *sctx = shash_desc_ctx(desc); |
158 | sctx->state[0] = SHA384_H0; | 153 | sctx->state[0] = SHA384_H0; |
159 | sctx->state[1] = SHA384_H1; | 154 | sctx->state[1] = SHA384_H1; |
160 | sctx->state[2] = SHA384_H2; | 155 | sctx->state[2] = SHA384_H2; |
161 | sctx->state[3] = SHA384_H3; | 156 | sctx->state[3] = SHA384_H3; |
162 | sctx->state[4] = SHA384_H4; | 157 | sctx->state[4] = SHA384_H4; |
163 | sctx->state[5] = SHA384_H5; | 158 | sctx->state[5] = SHA384_H5; |
164 | sctx->state[6] = SHA384_H6; | 159 | sctx->state[6] = SHA384_H6; |
165 | sctx->state[7] = SHA384_H7; | 160 | sctx->state[7] = SHA384_H7; |
166 | sctx->count[0] = sctx->count[1] = 0; | 161 | sctx->count[0] = sctx->count[1] = 0; |
167 | 162 | ||
168 | return 0; | 163 | return 0; |
169 | } | 164 | } |
170 | 165 | ||
171 | static int | 166 | static int |
172 | sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) | 167 | sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) |
173 | { | 168 | { |
174 | struct sha512_state *sctx = shash_desc_ctx(desc); | 169 | struct sha512_state *sctx = shash_desc_ctx(desc); |
175 | 170 | ||
176 | unsigned int i, index, part_len; | 171 | unsigned int i, index, part_len; |
177 | 172 | ||
178 | /* Compute number of bytes mod 128 */ | 173 | /* Compute number of bytes mod 128 */ |
179 | index = sctx->count[0] & 0x7f; | 174 | index = sctx->count[0] & 0x7f; |
180 | 175 | ||
181 | /* Update number of bytes */ | 176 | /* Update number of bytes */ |
182 | if (!(sctx->count[0] += len)) | 177 | if (!(sctx->count[0] += len)) |
183 | sctx->count[1]++; | 178 | sctx->count[1]++; |
184 | 179 | ||
185 | part_len = 128 - index; | 180 | part_len = 128 - index; |
186 | 181 | ||
187 | /* Transform as many times as possible. */ | 182 | /* Transform as many times as possible. */ |
188 | if (len >= part_len) { | 183 | if (len >= part_len) { |
189 | memcpy(&sctx->buf[index], data, part_len); | 184 | memcpy(&sctx->buf[index], data, part_len); |
190 | sha512_transform(sctx->state, sctx->buf); | 185 | sha512_transform(sctx->state, sctx->buf); |
191 | 186 | ||
192 | for (i = part_len; i + 127 < len; i+=128) | 187 | for (i = part_len; i + 127 < len; i+=128) |
193 | sha512_transform(sctx->state, &data[i]); | 188 | sha512_transform(sctx->state, &data[i]); |
194 | 189 | ||
195 | index = 0; | 190 | index = 0; |
196 | } else { | 191 | } else { |
197 | i = 0; | 192 | i = 0; |
198 | } | 193 | } |
199 | 194 | ||
200 | /* Buffer remaining input */ | 195 | /* Buffer remaining input */ |
201 | memcpy(&sctx->buf[index], &data[i], len - i); | 196 | memcpy(&sctx->buf[index], &data[i], len - i); |
202 | 197 | ||
203 | return 0; | 198 | return 0; |
204 | } | 199 | } |
205 | 200 | ||
206 | static int | 201 | static int |
207 | sha512_final(struct shash_desc *desc, u8 *hash) | 202 | sha512_final(struct shash_desc *desc, u8 *hash) |
208 | { | 203 | { |
209 | struct sha512_state *sctx = shash_desc_ctx(desc); | 204 | struct sha512_state *sctx = shash_desc_ctx(desc); |
210 | static u8 padding[128] = { 0x80, }; | 205 | static u8 padding[128] = { 0x80, }; |
211 | __be64 *dst = (__be64 *)hash; | 206 | __be64 *dst = (__be64 *)hash; |
212 | __be64 bits[2]; | 207 | __be64 bits[2]; |
213 | unsigned int index, pad_len; | 208 | unsigned int index, pad_len; |
214 | int i; | 209 | int i; |
215 | 210 | ||
216 | /* Save number of bits */ | 211 | /* Save number of bits */ |
217 | bits[1] = cpu_to_be64(sctx->count[0] << 3); | 212 | bits[1] = cpu_to_be64(sctx->count[0] << 3); |
218 | bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61); | 213 | bits[0] = cpu_to_be64(sctx->count[1] << 3 | sctx->count[0] >> 61); |
219 | 214 | ||
220 | /* Pad out to 112 mod 128. */ | 215 | /* Pad out to 112 mod 128. */ |
221 | index = sctx->count[0] & 0x7f; | 216 | index = sctx->count[0] & 0x7f; |
222 | pad_len = (index < 112) ? (112 - index) : ((128+112) - index); | 217 | pad_len = (index < 112) ? (112 - index) : ((128+112) - index); |
223 | sha512_update(desc, padding, pad_len); | 218 | sha512_update(desc, padding, pad_len); |
224 | 219 | ||
225 | /* Append length (before padding) */ | 220 | /* Append length (before padding) */ |
226 | sha512_update(desc, (const u8 *)bits, sizeof(bits)); | 221 | sha512_update(desc, (const u8 *)bits, sizeof(bits)); |
227 | 222 | ||
228 | /* Store state in digest */ | 223 | /* Store state in digest */ |
229 | for (i = 0; i < 8; i++) | 224 | for (i = 0; i < 8; i++) |
230 | dst[i] = cpu_to_be64(sctx->state[i]); | 225 | dst[i] = cpu_to_be64(sctx->state[i]); |
231 | 226 | ||
232 | /* Zeroize sensitive information. */ | 227 | /* Zeroize sensitive information. */ |
233 | memset(sctx, 0, sizeof(struct sha512_state)); | 228 | memset(sctx, 0, sizeof(struct sha512_state)); |
234 | 229 | ||
235 | return 0; | 230 | return 0; |
236 | } | 231 | } |
237 | 232 | ||
238 | static int sha384_final(struct shash_desc *desc, u8 *hash) | 233 | static int sha384_final(struct shash_desc *desc, u8 *hash) |
239 | { | 234 | { |
240 | u8 D[64]; | 235 | u8 D[64]; |
241 | 236 | ||
242 | sha512_final(desc, D); | 237 | sha512_final(desc, D); |
243 | 238 | ||
244 | memcpy(hash, D, 48); | 239 | memcpy(hash, D, 48); |
245 | memset(D, 0, 64); | 240 | memset(D, 0, 64); |
246 | 241 | ||
247 | return 0; | 242 | return 0; |
248 | } | 243 | } |
249 | 244 | ||
250 | static struct shash_alg sha512 = { | 245 | static struct shash_alg sha512 = { |
251 | .digestsize = SHA512_DIGEST_SIZE, | 246 | .digestsize = SHA512_DIGEST_SIZE, |
252 | .init = sha512_init, | 247 | .init = sha512_init, |
253 | .update = sha512_update, | 248 | .update = sha512_update, |
254 | .final = sha512_final, | 249 | .final = sha512_final, |
255 | .descsize = sizeof(struct sha512_state), | 250 | .descsize = sizeof(struct sha512_state), |
256 | .base = { | 251 | .base = { |
257 | .cra_name = "sha512", | 252 | .cra_name = "sha512", |
258 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | 253 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, |
259 | .cra_blocksize = SHA512_BLOCK_SIZE, | 254 | .cra_blocksize = SHA512_BLOCK_SIZE, |
260 | .cra_module = THIS_MODULE, | 255 | .cra_module = THIS_MODULE, |
261 | } | 256 | } |
262 | }; | 257 | }; |
263 | 258 | ||
264 | static struct shash_alg sha384 = { | 259 | static struct shash_alg sha384 = { |
265 | .digestsize = SHA384_DIGEST_SIZE, | 260 | .digestsize = SHA384_DIGEST_SIZE, |
266 | .init = sha384_init, | 261 | .init = sha384_init, |
267 | .update = sha512_update, | 262 | .update = sha512_update, |
268 | .final = sha384_final, | 263 | .final = sha384_final, |
269 | .descsize = sizeof(struct sha512_state), | 264 | .descsize = sizeof(struct sha512_state), |
270 | .base = { | 265 | .base = { |
271 | .cra_name = "sha384", | 266 | .cra_name = "sha384", |
272 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | 267 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, |
273 | .cra_blocksize = SHA384_BLOCK_SIZE, | 268 | .cra_blocksize = SHA384_BLOCK_SIZE, |
274 | .cra_module = THIS_MODULE, | 269 | .cra_module = THIS_MODULE, |
275 | } | 270 | } |
276 | }; | 271 | }; |
277 | 272 | ||
278 | static int __init sha512_generic_mod_init(void) | 273 | static int __init sha512_generic_mod_init(void) |
279 | { | 274 | { |
280 | int ret = 0; | 275 | int ret = 0; |
281 | 276 | ||
282 | if ((ret = crypto_register_shash(&sha384)) < 0) | 277 | if ((ret = crypto_register_shash(&sha384)) < 0) |
283 | goto out; | 278 | goto out; |
284 | if ((ret = crypto_register_shash(&sha512)) < 0) | 279 | if ((ret = crypto_register_shash(&sha512)) < 0) |
285 | crypto_unregister_shash(&sha384); | 280 | crypto_unregister_shash(&sha384); |
286 | out: | 281 | out: |
287 | return ret; | 282 | return ret; |
288 | } | 283 | } |
289 | 284 | ||
290 | static void __exit sha512_generic_mod_fini(void) | 285 | static void __exit sha512_generic_mod_fini(void) |
291 | { | 286 | { |
292 | crypto_unregister_shash(&sha384); | 287 | crypto_unregister_shash(&sha384); |
293 | crypto_unregister_shash(&sha512); | 288 | crypto_unregister_shash(&sha512); |
294 | } | 289 | } |
295 | 290 | ||
296 | module_init(sha512_generic_mod_init); | 291 | module_init(sha512_generic_mod_init); |
297 | module_exit(sha512_generic_mod_fini); | 292 | module_exit(sha512_generic_mod_fini); |
298 | 293 | ||
299 | MODULE_LICENSE("GPL"); | 294 | MODULE_LICENSE("GPL"); |
300 | MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms"); | 295 | MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms"); |
301 | 296 | ||
302 | MODULE_ALIAS("sha384"); | 297 | MODULE_ALIAS("sha384"); |
303 | MODULE_ALIAS("sha512"); | 298 | MODULE_ALIAS("sha512"); |
304 | 299 |
include/linux/bitops.h
1 | #ifndef _LINUX_BITOPS_H | 1 | #ifndef _LINUX_BITOPS_H |
2 | #define _LINUX_BITOPS_H | 2 | #define _LINUX_BITOPS_H |
3 | #include <asm/types.h> | 3 | #include <asm/types.h> |
4 | 4 | ||
5 | #ifdef __KERNEL__ | 5 | #ifdef __KERNEL__ |
6 | #define BIT(nr) (1UL << (nr)) | 6 | #define BIT(nr) (1UL << (nr)) |
7 | #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) | 7 | #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) |
8 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) | 8 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) |
9 | #define BITS_PER_BYTE 8 | 9 | #define BITS_PER_BYTE 8 |
10 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) | 10 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) |
11 | #endif | 11 | #endif |
12 | 12 | ||
13 | extern unsigned int __sw_hweight8(unsigned int w); | 13 | extern unsigned int __sw_hweight8(unsigned int w); |
14 | extern unsigned int __sw_hweight16(unsigned int w); | 14 | extern unsigned int __sw_hweight16(unsigned int w); |
15 | extern unsigned int __sw_hweight32(unsigned int w); | 15 | extern unsigned int __sw_hweight32(unsigned int w); |
16 | extern unsigned long __sw_hweight64(__u64 w); | 16 | extern unsigned long __sw_hweight64(__u64 w); |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Include this here because some architectures need generic_ffs/fls in | 19 | * Include this here because some architectures need generic_ffs/fls in |
20 | * scope | 20 | * scope |
21 | */ | 21 | */ |
22 | #include <asm/bitops.h> | 22 | #include <asm/bitops.h> |
23 | 23 | ||
24 | #define for_each_set_bit(bit, addr, size) \ | 24 | #define for_each_set_bit(bit, addr, size) \ |
25 | for ((bit) = find_first_bit((addr), (size)); \ | 25 | for ((bit) = find_first_bit((addr), (size)); \ |
26 | (bit) < (size); \ | 26 | (bit) < (size); \ |
27 | (bit) = find_next_bit((addr), (size), (bit) + 1)) | 27 | (bit) = find_next_bit((addr), (size), (bit) + 1)) |
28 | 28 | ||
29 | static __inline__ int get_bitmask_order(unsigned int count) | 29 | static __inline__ int get_bitmask_order(unsigned int count) |
30 | { | 30 | { |
31 | int order; | 31 | int order; |
32 | 32 | ||
33 | order = fls(count); | 33 | order = fls(count); |
34 | return order; /* We could be slightly more clever with -1 here... */ | 34 | return order; /* We could be slightly more clever with -1 here... */ |
35 | } | 35 | } |
36 | 36 | ||
37 | static __inline__ int get_count_order(unsigned int count) | 37 | static __inline__ int get_count_order(unsigned int count) |
38 | { | 38 | { |
39 | int order; | 39 | int order; |
40 | 40 | ||
41 | order = fls(count) - 1; | 41 | order = fls(count) - 1; |
42 | if (count & (count - 1)) | 42 | if (count & (count - 1)) |
43 | order++; | 43 | order++; |
44 | return order; | 44 | return order; |
45 | } | 45 | } |
46 | 46 | ||
47 | static inline unsigned long hweight_long(unsigned long w) | 47 | static inline unsigned long hweight_long(unsigned long w) |
48 | { | 48 | { |
49 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); | 49 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); |
50 | } | 50 | } |
51 | 51 | ||
52 | /** | 52 | /** |
53 | * rol64 - rotate a 64-bit value left | ||
54 | * @word: value to rotate | ||
55 | * @shift: bits to roll | ||
56 | */ | ||
57 | static inline __u64 rol64(__u64 word, unsigned int shift) | ||
58 | { | ||
59 | return (word << shift) | (word >> (64 - shift)); | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * ror64 - rotate a 64-bit value right | ||
64 | * @word: value to rotate | ||
65 | * @shift: bits to roll | ||
66 | */ | ||
67 | static inline __u64 ror64(__u64 word, unsigned int shift) | ||
68 | { | ||
69 | return (word >> shift) | (word << (64 - shift)); | ||
70 | } | ||
71 | |||
72 | /** | ||
53 | * rol32 - rotate a 32-bit value left | 73 | * rol32 - rotate a 32-bit value left |
54 | * @word: value to rotate | 74 | * @word: value to rotate |
55 | * @shift: bits to roll | 75 | * @shift: bits to roll |
56 | */ | 76 | */ |
57 | static inline __u32 rol32(__u32 word, unsigned int shift) | 77 | static inline __u32 rol32(__u32 word, unsigned int shift) |
58 | { | 78 | { |
59 | return (word << shift) | (word >> (32 - shift)); | 79 | return (word << shift) | (word >> (32 - shift)); |
60 | } | 80 | } |
61 | 81 | ||
62 | /** | 82 | /** |
63 | * ror32 - rotate a 32-bit value right | 83 | * ror32 - rotate a 32-bit value right |
64 | * @word: value to rotate | 84 | * @word: value to rotate |
65 | * @shift: bits to roll | 85 | * @shift: bits to roll |
66 | */ | 86 | */ |
67 | static inline __u32 ror32(__u32 word, unsigned int shift) | 87 | static inline __u32 ror32(__u32 word, unsigned int shift) |
68 | { | 88 | { |
69 | return (word >> shift) | (word << (32 - shift)); | 89 | return (word >> shift) | (word << (32 - shift)); |
70 | } | 90 | } |
71 | 91 | ||
72 | /** | 92 | /** |
73 | * rol16 - rotate a 16-bit value left | 93 | * rol16 - rotate a 16-bit value left |
74 | * @word: value to rotate | 94 | * @word: value to rotate |
75 | * @shift: bits to roll | 95 | * @shift: bits to roll |
76 | */ | 96 | */ |
77 | static inline __u16 rol16(__u16 word, unsigned int shift) | 97 | static inline __u16 rol16(__u16 word, unsigned int shift) |
78 | { | 98 | { |
79 | return (word << shift) | (word >> (16 - shift)); | 99 | return (word << shift) | (word >> (16 - shift)); |
80 | } | 100 | } |
81 | 101 | ||
82 | /** | 102 | /** |
83 | * ror16 - rotate a 16-bit value right | 103 | * ror16 - rotate a 16-bit value right |
84 | * @word: value to rotate | 104 | * @word: value to rotate |
85 | * @shift: bits to roll | 105 | * @shift: bits to roll |
86 | */ | 106 | */ |
87 | static inline __u16 ror16(__u16 word, unsigned int shift) | 107 | static inline __u16 ror16(__u16 word, unsigned int shift) |
88 | { | 108 | { |
89 | return (word >> shift) | (word << (16 - shift)); | 109 | return (word >> shift) | (word << (16 - shift)); |
90 | } | 110 | } |
91 | 111 | ||
92 | /** | 112 | /** |
93 | * rol8 - rotate an 8-bit value left | 113 | * rol8 - rotate an 8-bit value left |
94 | * @word: value to rotate | 114 | * @word: value to rotate |
95 | * @shift: bits to roll | 115 | * @shift: bits to roll |
96 | */ | 116 | */ |
97 | static inline __u8 rol8(__u8 word, unsigned int shift) | 117 | static inline __u8 rol8(__u8 word, unsigned int shift) |
98 | { | 118 | { |
99 | return (word << shift) | (word >> (8 - shift)); | 119 | return (word << shift) | (word >> (8 - shift)); |
100 | } | 120 | } |
101 | 121 | ||
102 | /** | 122 | /** |
103 | * ror8 - rotate an 8-bit value right | 123 | * ror8 - rotate an 8-bit value right |
104 | * @word: value to rotate | 124 | * @word: value to rotate |
105 | * @shift: bits to roll | 125 | * @shift: bits to roll |
106 | */ | 126 | */ |
107 | static inline __u8 ror8(__u8 word, unsigned int shift) | 127 | static inline __u8 ror8(__u8 word, unsigned int shift) |
108 | { | 128 | { |
109 | return (word >> shift) | (word << (8 - shift)); | 129 | return (word >> shift) | (word << (8 - shift)); |
110 | } | 130 | } |
111 | 131 | ||
112 | /** | 132 | /** |
113 | * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit | 133 | * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit |
114 | * @value: value to sign extend | 134 | * @value: value to sign extend |
115 | * @index: 0 based bit index (0<=index<32) to sign bit | 135 | * @index: 0 based bit index (0<=index<32) to sign bit |
116 | */ | 136 | */ |
117 | static inline __s32 sign_extend32(__u32 value, int index) | 137 | static inline __s32 sign_extend32(__u32 value, int index) |
118 | { | 138 | { |
119 | __u8 shift = 31 - index; | 139 | __u8 shift = 31 - index; |
120 | return (__s32)(value << shift) >> shift; | 140 | return (__s32)(value << shift) >> shift; |
121 | } | 141 | } |
122 | 142 | ||
123 | static inline unsigned fls_long(unsigned long l) | 143 | static inline unsigned fls_long(unsigned long l) |
124 | { | 144 | { |
125 | if (sizeof(l) == 4) | 145 | if (sizeof(l) == 4) |
126 | return fls(l); | 146 | return fls(l); |
127 | return fls64(l); | 147 | return fls64(l); |
128 | } | 148 | } |
129 | 149 | ||
130 | /** | 150 | /** |
131 | * __ffs64 - find first set bit in a 64 bit word | 151 | * __ffs64 - find first set bit in a 64 bit word |
132 | * @word: The 64 bit word | 152 | * @word: The 64 bit word |
133 | * | 153 | * |
134 | * On 64 bit arches this is a synomyn for __ffs | 154 | * On 64 bit arches this is a synomyn for __ffs |
135 | * The result is not defined if no bits are set, so check that @word | 155 | * The result is not defined if no bits are set, so check that @word |
136 | * is non-zero before calling this. | 156 | * is non-zero before calling this. |
137 | */ | 157 | */ |
138 | static inline unsigned long __ffs64(u64 word) | 158 | static inline unsigned long __ffs64(u64 word) |
139 | { | 159 | { |
140 | #if BITS_PER_LONG == 32 | 160 | #if BITS_PER_LONG == 32 |
141 | if (((u32)word) == 0UL) | 161 | if (((u32)word) == 0UL) |
142 | return __ffs((u32)(word >> 32)) + 32; | 162 | return __ffs((u32)(word >> 32)) + 32; |
143 | #elif BITS_PER_LONG != 64 | 163 | #elif BITS_PER_LONG != 64 |
144 | #error BITS_PER_LONG not 32 or 64 | 164 | #error BITS_PER_LONG not 32 or 64 |
145 | #endif | 165 | #endif |
146 | return __ffs((unsigned long)word); | 166 | return __ffs((unsigned long)word); |
147 | } | 167 | } |
148 | 168 | ||
149 | #ifdef __KERNEL__ | 169 | #ifdef __KERNEL__ |
150 | 170 | ||
151 | #ifndef find_last_bit | 171 | #ifndef find_last_bit |
152 | /** | 172 | /** |
153 | * find_last_bit - find the last set bit in a memory region | 173 | * find_last_bit - find the last set bit in a memory region |
154 | * @addr: The address to start the search at | 174 | * @addr: The address to start the search at |
155 | * @size: The maximum size to search | 175 | * @size: The maximum size to search |
156 | * | 176 | * |
157 | * Returns the bit number of the first set bit, or size. | 177 | * Returns the bit number of the first set bit, or size. |
158 | */ | 178 | */ |
159 | extern unsigned long find_last_bit(const unsigned long *addr, | 179 | extern unsigned long find_last_bit(const unsigned long *addr, |
160 | unsigned long size); | 180 | unsigned long size); |
161 | #endif | 181 | #endif |
162 | 182 | ||
163 | #endif /* __KERNEL__ */ | 183 | #endif /* __KERNEL__ */ |
164 | #endif | 184 | #endif |
165 | 185 |