Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Side by Side Diff: fusl/src/crypt/crypt_sha512.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * public domain sha512 crypt implementation 2 * public domain sha512 crypt implementation
3 * 3 *
4 * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt 4 * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
5 * in this implementation at least 32bit int is assumed, 5 * in this implementation at least 32bit int is assumed,
6 * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected 6 * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected
7 * in the salt and rounds= setting must contain a valid iteration count, 7 * in the salt and rounds= setting must contain a valid iteration count,
8 * on error "*" is returned. 8 * on error "*" is returned.
9 */ 9 */
10 #include <ctype.h> 10 #include <ctype.h>
11 #include <stdlib.h> 11 #include <stdlib.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 #include <string.h> 13 #include <string.h>
14 #include <stdint.h> 14 #include <stdint.h>
15 15
16 /* public domain sha512 implementation based on fips180-3 */ 16 /* public domain sha512 implementation based on fips180-3 */
17 /* >=2^64 bits messages are not supported (about 2000 peta bytes) */ 17 /* >=2^64 bits messages are not supported (about 2000 peta bytes) */
18 18
19 struct sha512 { 19 struct sha512 {
20 » uint64_t len; /* processed message length */ 20 uint64_t len; /* processed message length */
21 » uint64_t h[8]; /* hash state */ 21 uint64_t h[8]; /* hash state */
22 » uint8_t buf[128]; /* message block buffer */ 22 uint8_t buf[128]; /* message block buffer */
23 }; 23 };
24 24
25 static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); } 25 static uint64_t ror(uint64_t n, int k) {
26 #define Ch(x,y,z) (z ^ (x & (y ^ z))) 26 return (n >> k) | (n << (64 - k));
27 #define Maj(x,y,z) ((x & y) | (z & (x | y))) 27 }
28 #define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39)) 28 #define Ch(x, y, z) (z ^ (x & (y ^ z)))
29 #define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41)) 29 #define Maj(x, y, z) ((x & y) | (z & (x | y)))
30 #define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7)) 30 #define S0(x) (ror(x, 28) ^ ror(x, 34) ^ ror(x, 39))
31 #define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6)) 31 #define S1(x) (ror(x, 14) ^ ror(x, 18) ^ ror(x, 41))
32 #define R0(x) (ror(x, 1) ^ ror(x, 8) ^ (x >> 7))
33 #define R1(x) (ror(x, 19) ^ ror(x, 61) ^ (x >> 6))
32 34
33 static const uint64_t K[80] = { 35 static const uint64_t K[80] = {
34 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58 189dbbcULL, 36 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
35 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5d a6d8118ULL, 37 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
36 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d 5ffb4e2ULL, 38 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
37 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174c f692694ULL, 39 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
38 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc7 7ac9c65ULL, 40 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
39 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da8 31153b5ULL, 41 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
40 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7b eef0ee4ULL, 42 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
41 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670 a0e6e70ULL, 43 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
42 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139 d95b3dfULL, 44 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
43 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851 482353bULL, 45 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
44 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30 654be30ULL, 46 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
45 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa0703 2bbd1b8ULL, 47 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
46 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e 19b48a8ULL, 48 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
47 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d 6b2b8a3ULL, 49 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
48 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081 a6439ecULL, 50 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
49 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e 372532bULL, 51 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
50 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fe e6ed178ULL, 52 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
51 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b351 31c471bULL, 53 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
52 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49 c100d4cULL, 54 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
53 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4 a475817ULL 55 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
54 }; 56 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
57 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
58 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
59 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
60 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
61 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
62 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
55 63
56 static void processblock(struct sha512 *s, const uint8_t *buf) 64 static void processblock(struct sha512* s, const uint8_t* buf) {
57 { 65 uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
58 » uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h; 66 int i;
59 » int i;
60 67
61 » for (i = 0; i < 16; i++) { 68 for (i = 0; i < 16; i++) {
62 » » W[i] = (uint64_t)buf[8*i]<<56; 69 W[i] = (uint64_t)buf[8 * i] << 56;
63 » » W[i] |= (uint64_t)buf[8*i+1]<<48; 70 W[i] |= (uint64_t)buf[8 * i + 1] << 48;
64 » » W[i] |= (uint64_t)buf[8*i+2]<<40; 71 W[i] |= (uint64_t)buf[8 * i + 2] << 40;
65 » » W[i] |= (uint64_t)buf[8*i+3]<<32; 72 W[i] |= (uint64_t)buf[8 * i + 3] << 32;
66 » » W[i] |= (uint64_t)buf[8*i+4]<<24; 73 W[i] |= (uint64_t)buf[8 * i + 4] << 24;
67 » » W[i] |= (uint64_t)buf[8*i+5]<<16; 74 W[i] |= (uint64_t)buf[8 * i + 5] << 16;
68 » » W[i] |= (uint64_t)buf[8*i+6]<<8; 75 W[i] |= (uint64_t)buf[8 * i + 6] << 8;
69 » » W[i] |= buf[8*i+7]; 76 W[i] |= buf[8 * i + 7];
70 » } 77 }
71 » for (; i < 80; i++) 78 for (; i < 80; i++)
72 » » W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; 79 W[i] = R1(W[i - 2]) + W[i - 7] + R0(W[i - 15]) + W[i - 16];
73 » a = s->h[0]; 80 a = s->h[0];
74 » b = s->h[1]; 81 b = s->h[1];
75 » c = s->h[2]; 82 c = s->h[2];
76 » d = s->h[3]; 83 d = s->h[3];
77 » e = s->h[4]; 84 e = s->h[4];
78 » f = s->h[5]; 85 f = s->h[5];
79 » g = s->h[6]; 86 g = s->h[6];
80 » h = s->h[7]; 87 h = s->h[7];
81 » for (i = 0; i < 80; i++) { 88 for (i = 0; i < 80; i++) {
82 » » t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; 89 t1 = h + S1(e) + Ch(e, f, g) + K[i] + W[i];
83 » » t2 = S0(a) + Maj(a,b,c); 90 t2 = S0(a) + Maj(a, b, c);
84 » » h = g; 91 h = g;
85 » » g = f; 92 g = f;
86 » » f = e; 93 f = e;
87 » » e = d + t1; 94 e = d + t1;
88 » » d = c; 95 d = c;
89 » » c = b; 96 c = b;
90 » » b = a; 97 b = a;
91 » » a = t1 + t2; 98 a = t1 + t2;
92 » } 99 }
93 » s->h[0] += a; 100 s->h[0] += a;
94 » s->h[1] += b; 101 s->h[1] += b;
95 » s->h[2] += c; 102 s->h[2] += c;
96 » s->h[3] += d; 103 s->h[3] += d;
97 » s->h[4] += e; 104 s->h[4] += e;
98 » s->h[5] += f; 105 s->h[5] += f;
99 » s->h[6] += g; 106 s->h[6] += g;
100 » s->h[7] += h; 107 s->h[7] += h;
101 } 108 }
102 109
103 static void pad(struct sha512 *s) 110 static void pad(struct sha512* s) {
104 { 111 unsigned r = s->len % 128;
105 » unsigned r = s->len % 128;
106 112
107 » s->buf[r++] = 0x80; 113 s->buf[r++] = 0x80;
108 » if (r > 112) { 114 if (r > 112) {
109 » » memset(s->buf + r, 0, 128 - r); 115 memset(s->buf + r, 0, 128 - r);
110 » » r = 0; 116 r = 0;
111 » » processblock(s, s->buf); 117 processblock(s, s->buf);
112 » } 118 }
113 » memset(s->buf + r, 0, 120 - r); 119 memset(s->buf + r, 0, 120 - r);
114 » s->len *= 8; 120 s->len *= 8;
115 » s->buf[120] = s->len >> 56; 121 s->buf[120] = s->len >> 56;
116 » s->buf[121] = s->len >> 48; 122 s->buf[121] = s->len >> 48;
117 » s->buf[122] = s->len >> 40; 123 s->buf[122] = s->len >> 40;
118 » s->buf[123] = s->len >> 32; 124 s->buf[123] = s->len >> 32;
119 » s->buf[124] = s->len >> 24; 125 s->buf[124] = s->len >> 24;
120 » s->buf[125] = s->len >> 16; 126 s->buf[125] = s->len >> 16;
121 » s->buf[126] = s->len >> 8; 127 s->buf[126] = s->len >> 8;
122 » s->buf[127] = s->len; 128 s->buf[127] = s->len;
123 » processblock(s, s->buf); 129 processblock(s, s->buf);
124 } 130 }
125 131
126 static void sha512_init(struct sha512 *s) 132 static void sha512_init(struct sha512* s) {
127 { 133 s->len = 0;
128 » s->len = 0; 134 s->h[0] = 0x6a09e667f3bcc908ULL;
129 » s->h[0] = 0x6a09e667f3bcc908ULL; 135 s->h[1] = 0xbb67ae8584caa73bULL;
130 » s->h[1] = 0xbb67ae8584caa73bULL; 136 s->h[2] = 0x3c6ef372fe94f82bULL;
131 » s->h[2] = 0x3c6ef372fe94f82bULL; 137 s->h[3] = 0xa54ff53a5f1d36f1ULL;
132 » s->h[3] = 0xa54ff53a5f1d36f1ULL; 138 s->h[4] = 0x510e527fade682d1ULL;
133 » s->h[4] = 0x510e527fade682d1ULL; 139 s->h[5] = 0x9b05688c2b3e6c1fULL;
134 » s->h[5] = 0x9b05688c2b3e6c1fULL; 140 s->h[6] = 0x1f83d9abfb41bd6bULL;
135 » s->h[6] = 0x1f83d9abfb41bd6bULL; 141 s->h[7] = 0x5be0cd19137e2179ULL;
136 » s->h[7] = 0x5be0cd19137e2179ULL;
137 } 142 }
138 143
139 static void sha512_sum(struct sha512 *s, uint8_t *md) 144 static void sha512_sum(struct sha512* s, uint8_t* md) {
140 { 145 int i;
141 » int i;
142 146
143 » pad(s); 147 pad(s);
144 » for (i = 0; i < 8; i++) { 148 for (i = 0; i < 8; i++) {
145 » » md[8*i] = s->h[i] >> 56; 149 md[8 * i] = s->h[i] >> 56;
146 » » md[8*i+1] = s->h[i] >> 48; 150 md[8 * i + 1] = s->h[i] >> 48;
147 » » md[8*i+2] = s->h[i] >> 40; 151 md[8 * i + 2] = s->h[i] >> 40;
148 » » md[8*i+3] = s->h[i] >> 32; 152 md[8 * i + 3] = s->h[i] >> 32;
149 » » md[8*i+4] = s->h[i] >> 24; 153 md[8 * i + 4] = s->h[i] >> 24;
150 » » md[8*i+5] = s->h[i] >> 16; 154 md[8 * i + 5] = s->h[i] >> 16;
151 » » md[8*i+6] = s->h[i] >> 8; 155 md[8 * i + 6] = s->h[i] >> 8;
152 » » md[8*i+7] = s->h[i]; 156 md[8 * i + 7] = s->h[i];
153 » } 157 }
154 } 158 }
155 159
156 static void sha512_update(struct sha512 *s, const void *m, unsigned long len) 160 static void sha512_update(struct sha512* s, const void* m, unsigned long len) {
157 { 161 const uint8_t* p = m;
158 » const uint8_t *p = m; 162 unsigned r = s->len % 128;
159 » unsigned r = s->len % 128;
160 163
161 » s->len += len; 164 s->len += len;
162 » if (r) { 165 if (r) {
163 » » if (len < 128 - r) { 166 if (len < 128 - r) {
164 » » » memcpy(s->buf + r, p, len); 167 memcpy(s->buf + r, p, len);
165 » » » return; 168 return;
166 » » } 169 }
167 » » memcpy(s->buf + r, p, 128 - r); 170 memcpy(s->buf + r, p, 128 - r);
168 » » len -= 128 - r; 171 len -= 128 - r;
169 » » p += 128 - r; 172 p += 128 - r;
170 » » processblock(s, s->buf); 173 processblock(s, s->buf);
171 » } 174 }
172 » for (; len >= 128; len -= 128, p += 128) 175 for (; len >= 128; len -= 128, p += 128)
173 » » processblock(s, p); 176 processblock(s, p);
174 » memcpy(s->buf, p, len); 177 memcpy(s->buf, p, len);
175 } 178 }
176 179
177 static const unsigned char b64[] = 180 static const unsigned char b64[] =
178 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 181 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
179 182
180 static char *to64(char *s, unsigned int u, int n) 183 static char* to64(char* s, unsigned int u, int n) {
181 { 184 while (--n >= 0) {
182 » while (--n >= 0) { 185 *s++ = b64[u % 64];
183 » » *s++ = b64[u % 64]; 186 u /= 64;
184 » » u /= 64; 187 }
185 » } 188 return s;
186 » return s;
187 } 189 }
188 190
189 /* key limit is not part of the original design, added for DoS protection. 191 /* key limit is not part of the original design, added for DoS protection.
190 * rounds limit has been lowered (versus the reference/spec), also for DoS 192 * rounds limit has been lowered (versus the reference/spec), also for DoS
191 * protection. runtime is O(klen^2 + klen*rounds) */ 193 * protection. runtime is O(klen^2 + klen*rounds) */
192 #define KEY_MAX 256 194 #define KEY_MAX 256
193 #define SALT_MAX 16 195 #define SALT_MAX 16
194 #define ROUNDS_DEFAULT 5000 196 #define ROUNDS_DEFAULT 5000
195 #define ROUNDS_MIN 1000 197 #define ROUNDS_MIN 1000
196 #define ROUNDS_MAX 9999999 198 #define ROUNDS_MAX 9999999
197 199
198 /* hash n bytes of the repeated md message digest */ 200 /* hash n bytes of the repeated md message digest */
199 static void hashmd(struct sha512 *s, unsigned int n, const void *md) 201 static void hashmd(struct sha512* s, unsigned int n, const void* md) {
200 { 202 unsigned int i;
201 » unsigned int i;
202 203
203 » for (i = n; i > 64; i -= 64) 204 for (i = n; i > 64; i -= 64)
204 » » sha512_update(s, md, 64); 205 sha512_update(s, md, 64);
205 » sha512_update(s, md, i); 206 sha512_update(s, md, i);
206 } 207 }
207 208
208 static char *sha512crypt(const char *key, const char *setting, char *output) 209 static char* sha512crypt(const char* key, const char* setting, char* output) {
209 { 210 struct sha512 ctx;
210 » struct sha512 ctx; 211 unsigned char md[64], kmd[64], smd[64];
211 » unsigned char md[64], kmd[64], smd[64]; 212 unsigned int i, r, klen, slen;
212 » unsigned int i, r, klen, slen; 213 char rounds[20] = "";
213 » char rounds[20] = ""; 214 const char* salt;
214 » const char *salt; 215 char* p;
215 » char *p;
216 216
217 » /* reject large keys */ 217 /* reject large keys */
218 » for (i = 0; i <= KEY_MAX && key[i]; i++); 218 for (i = 0; i <= KEY_MAX && key[i]; i++)
219 » if (i > KEY_MAX) 219 ;
220 » » return 0; 220 if (i > KEY_MAX)
221 » klen = i; 221 return 0;
222 klen = i;
222 223
223 » /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */ 224 /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
224 » if (strncmp(setting, "$6$", 3) != 0) 225 if (strncmp(setting, "$6$", 3) != 0)
225 » » return 0; 226 return 0;
226 » salt = setting + 3; 227 salt = setting + 3;
227 228
228 » r = ROUNDS_DEFAULT; 229 r = ROUNDS_DEFAULT;
229 » if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) { 230 if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
230 » » unsigned long u; 231 unsigned long u;
231 » » char *end; 232 char* end;
232 233
233 » » /* 234 /*
234 » » * this is a deviation from the reference: 235 * this is a deviation from the reference:
235 » » * bad rounds setting is rejected if it is 236 * bad rounds setting is rejected if it is
236 » » * - empty 237 * - empty
237 » » * - unterminated (missing '$') 238 * - unterminated (missing '$')
238 » » * - begins with anything but a decimal digit 239 * - begins with anything but a decimal digit
239 » » * the reference implementation treats these bad 240 * the reference implementation treats these bad
240 » » * rounds as part of the salt or parse them with 241 * rounds as part of the salt or parse them with
241 » » * strtoul semantics which may cause problems 242 * strtoul semantics which may cause problems
242 » » * including non-portable hashes that depend on 243 * including non-portable hashes that depend on
243 » » * the host's value of ULONG_MAX. 244 * the host's value of ULONG_MAX.
244 » » */ 245 */
245 » » salt += sizeof "rounds=" - 1; 246 salt += sizeof "rounds=" - 1;
246 » » if (!isdigit(*salt)) 247 if (!isdigit(*salt))
247 » » » return 0; 248 return 0;
248 » » u = strtoul(salt, &end, 10); 249 u = strtoul(salt, &end, 10);
249 » » if (*end != '$') 250 if (*end != '$')
250 » » » return 0; 251 return 0;
251 » » salt = end+1; 252 salt = end + 1;
252 » » if (u < ROUNDS_MIN) 253 if (u < ROUNDS_MIN)
253 » » » r = ROUNDS_MIN; 254 r = ROUNDS_MIN;
254 » » else if (u > ROUNDS_MAX) 255 else if (u > ROUNDS_MAX)
255 » » » r = ROUNDS_MAX; 256 r = ROUNDS_MAX;
256 » » else 257 else
257 » » » r = u; 258 r = u;
258 » » /* needed when rounds is zero prefixed or out of bounds */ 259 /* needed when rounds is zero prefixed or out of bounds */
259 » » sprintf(rounds, "rounds=%u$", r); 260 sprintf(rounds, "rounds=%u$", r);
260 » } 261 }
261 262
262 » for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++) 263 for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
263 » » /* reject characters that interfere with /etc/shadow parsing */ 264 /* reject characters that interfere with /etc/shadow parsing */
264 » » if (salt[i] == '\n' || salt[i] == ':') 265 if (salt[i] == '\n' || salt[i] == ':')
265 » » » return 0; 266 return 0;
266 » slen = i; 267 slen = i;
267 268
268 » /* B = sha(key salt key) */ 269 /* B = sha(key salt key) */
269 » sha512_init(&ctx); 270 sha512_init(&ctx);
270 » sha512_update(&ctx, key, klen); 271 sha512_update(&ctx, key, klen);
271 » sha512_update(&ctx, salt, slen); 272 sha512_update(&ctx, salt, slen);
272 » sha512_update(&ctx, key, klen); 273 sha512_update(&ctx, key, klen);
273 » sha512_sum(&ctx, md); 274 sha512_sum(&ctx, md);
274 275
275 » /* A = sha(key salt repeat-B alternate-B-key) */ 276 /* A = sha(key salt repeat-B alternate-B-key) */
276 » sha512_init(&ctx); 277 sha512_init(&ctx);
277 » sha512_update(&ctx, key, klen); 278 sha512_update(&ctx, key, klen);
278 » sha512_update(&ctx, salt, slen); 279 sha512_update(&ctx, salt, slen);
279 » hashmd(&ctx, klen, md); 280 hashmd(&ctx, klen, md);
280 » for (i = klen; i > 0; i >>= 1) 281 for (i = klen; i > 0; i >>= 1)
281 » » if (i & 1) 282 if (i & 1)
282 » » » sha512_update(&ctx, md, sizeof md); 283 sha512_update(&ctx, md, sizeof md);
283 » » else 284 else
284 » » » sha512_update(&ctx, key, klen); 285 sha512_update(&ctx, key, klen);
285 » sha512_sum(&ctx, md); 286 sha512_sum(&ctx, md);
286 287
287 » /* DP = sha(repeat-key), this step takes O(klen^2) time */ 288 /* DP = sha(repeat-key), this step takes O(klen^2) time */
288 » sha512_init(&ctx); 289 sha512_init(&ctx);
289 » for (i = 0; i < klen; i++) 290 for (i = 0; i < klen; i++)
290 » » sha512_update(&ctx, key, klen); 291 sha512_update(&ctx, key, klen);
291 » sha512_sum(&ctx, kmd); 292 sha512_sum(&ctx, kmd);
292 293
293 » /* DS = sha(repeat-salt) */ 294 /* DS = sha(repeat-salt) */
294 » sha512_init(&ctx); 295 sha512_init(&ctx);
295 » for (i = 0; i < 16 + md[0]; i++) 296 for (i = 0; i < 16 + md[0]; i++)
296 » » sha512_update(&ctx, salt, slen); 297 sha512_update(&ctx, salt, slen);
297 » sha512_sum(&ctx, smd); 298 sha512_sum(&ctx, smd);
298 299
299 » /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */ 300 /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
300 » for (i = 0; i < r; i++) { 301 for (i = 0; i < r; i++) {
301 » » sha512_init(&ctx); 302 sha512_init(&ctx);
302 » » if (i % 2) 303 if (i % 2)
303 » » » hashmd(&ctx, klen, kmd); 304 hashmd(&ctx, klen, kmd);
304 » » else 305 else
305 » » » sha512_update(&ctx, md, sizeof md); 306 sha512_update(&ctx, md, sizeof md);
306 » » if (i % 3) 307 if (i % 3)
307 » » » sha512_update(&ctx, smd, slen); 308 sha512_update(&ctx, smd, slen);
308 » » if (i % 7) 309 if (i % 7)
309 » » » hashmd(&ctx, klen, kmd); 310 hashmd(&ctx, klen, kmd);
310 » » if (i % 2) 311 if (i % 2)
311 » » » sha512_update(&ctx, md, sizeof md); 312 sha512_update(&ctx, md, sizeof md);
312 » » else 313 else
313 » » » hashmd(&ctx, klen, kmd); 314 hashmd(&ctx, klen, kmd);
314 » » sha512_sum(&ctx, md); 315 sha512_sum(&ctx, md);
315 » } 316 }
316 317
317 » /* output is $6$rounds=n$salt$hash */ 318 /* output is $6$rounds=n$salt$hash */
318 » p = output; 319 p = output;
319 » p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt); 320 p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt);
320 #if 1 321 #if 1
321 » static const unsigned char perm[][3] = { 322 static const unsigned char perm[][3] = {
322 » » 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4, 323 0, 21, 42, 22, 43, 1, 44, 2, 23, 3, 24, 45, 25, 46, 4, 47,
323 » » 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51, 324 5, 26, 6, 27, 48, 28, 49, 7, 50, 8, 29, 9, 30, 51, 31, 52,
324 » » 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35, 325 10, 53, 11, 32, 12, 33, 54, 34, 55, 13, 56, 14, 35, 15, 36, 57,
325 » » 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19, 326 37, 58, 16, 59, 17, 38, 18, 39, 60, 40, 61, 19, 62, 20, 41};
326 » » 62,20,41 }; 327 for (i = 0; i < 21; i++)
327 » for (i=0; i<21; i++) p = to64(p, 328 p = to64(p, (md[perm[i][0]] << 16) | (md[perm[i][1]] << 8) | md[perm[i][2]],
328 » » (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4); 329 4);
329 #else 330 #else
330 » p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4); 331 p = to64(p, (md[0] << 16) | (md[21] << 8) | md[42], 4);
331 » p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4); 332 p = to64(p, (md[22] << 16) | (md[43] << 8) | md[1], 4);
332 » p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4); 333 p = to64(p, (md[44] << 16) | (md[2] << 8) | md[23], 4);
333 » p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4); 334 p = to64(p, (md[3] << 16) | (md[24] << 8) | md[45], 4);
334 » p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4); 335 p = to64(p, (md[25] << 16) | (md[46] << 8) | md[4], 4);
335 » p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4); 336 p = to64(p, (md[47] << 16) | (md[5] << 8) | md[26], 4);
336 » p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4); 337 p = to64(p, (md[6] << 16) | (md[27] << 8) | md[48], 4);
337 » p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4); 338 p = to64(p, (md[28] << 16) | (md[49] << 8) | md[7], 4);
338 » p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4); 339 p = to64(p, (md[50] << 16) | (md[8] << 8) | md[29], 4);
339 » p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4); 340 p = to64(p, (md[9] << 16) | (md[30] << 8) | md[51], 4);
340 » p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4); 341 p = to64(p, (md[31] << 16) | (md[52] << 8) | md[10], 4);
341 » p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4); 342 p = to64(p, (md[53] << 16) | (md[11] << 8) | md[32], 4);
342 » p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4); 343 p = to64(p, (md[12] << 16) | (md[33] << 8) | md[54], 4);
343 » p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4); 344 p = to64(p, (md[34] << 16) | (md[55] << 8) | md[13], 4);
344 » p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4); 345 p = to64(p, (md[56] << 16) | (md[14] << 8) | md[35], 4);
345 » p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4); 346 p = to64(p, (md[15] << 16) | (md[36] << 8) | md[57], 4);
346 » p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4); 347 p = to64(p, (md[37] << 16) | (md[58] << 8) | md[16], 4);
347 » p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4); 348 p = to64(p, (md[59] << 16) | (md[17] << 8) | md[38], 4);
348 » p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4); 349 p = to64(p, (md[18] << 16) | (md[39] << 8) | md[60], 4);
349 » p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4); 350 p = to64(p, (md[40] << 16) | (md[61] << 8) | md[19], 4);
350 » p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4); 351 p = to64(p, (md[62] << 16) | (md[20] << 8) | md[41], 4);
351 #endif 352 #endif
352 » p = to64(p, md[63], 2); 353 p = to64(p, md[63], 2);
353 » *p = 0; 354 *p = 0;
354 » return output; 355 return output;
355 } 356 }
356 357
357 char *__crypt_sha512(const char *key, const char *setting, char *output) 358 char* __crypt_sha512(const char* key, const char* setting, char* output) {
358 { 359 static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
359 » static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !"; 360 static const char testsetting[] = "$6$rounds=1234$abc0123456789$";
360 » static const char testsetting[] = "$6$rounds=1234$abc0123456789$"; 361 static const char testhash[] =
361 » static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/R cyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1"; 362 "$6$rounds=1234$abc0123456789$BCpt8zLrc/"
362 » char testbuf[128]; 363 "RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/"
363 » char *p, *q; 364 "oOu6reg1";
365 char testbuf[128];
366 char *p, *q;
364 367
365 » p = sha512crypt(key, setting, output); 368 p = sha512crypt(key, setting, output);
366 » /* self test and stack cleanup */ 369 /* self test and stack cleanup */
367 » q = sha512crypt(testkey, testsetting, testbuf); 370 q = sha512crypt(testkey, testsetting, testbuf);
368 » if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash)) 371 if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
369 » » return "*"; 372 return "*";
370 » return p; 373 return p;
371 } 374 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698