string-crypt 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ba5c931398a8376cf8e8a13ac3c3fe7a84e5923c08b2d61adae2faf4b8182c96
4
+ data.tar.gz: 92de76e27edeaea32b3e51bd26b3e5206d4192f3943a175eb3afbb83ba79dc6f
5
+ SHA512:
6
+ metadata.gz: 3108245fc24192cb48e06d1d13d498371407d392f343ac3df81c3c73d178621cf0832058c969120418487cbcdc24425a389b754d40de701dc7bf81f9cbf994d1
7
+ data.tar.gz: 7987b1ca426ade3a11c8805ba81cf455da674c1b8f686fa77d2586843cba6fd4da3755c40b4412edfcede7d34771a2c141388dbcabc7d0af130757ccda36d60f
data/BSDL ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
@@ -0,0 +1,3 @@
1
+ === 0.9.0 (2018-07-26)
2
+
3
+ * Initial Public Release
@@ -0,0 +1,67 @@
1
+ = ruby-string-crypt
2
+
3
+ ruby-string-crypt is a backwards compatible implementation of
4
+ String#crypt for Ruby, so that the core String#crypt can be deprecated
5
+ and later removed.
6
+
7
+ String#crypt calls crypt(3) or crypt_r(3) for operating system-specific
8
+ password hashing. In cases where neither crypt(3) nor crypt_r(3) is
9
+ available, a DES-crypt implementation is used. DES-crypt should be
10
+ considered insecure, and users are strongly recommended to switch to a
11
+ secure password hashing library such as bcrypt, scrypt, or argon2.
12
+
13
+ == Usage
14
+
15
+ # Generate new password hash.
16
+ # Salt is an operating system specific string.
17
+ password_hash = "password".crypt(salt)
18
+
19
+ # Check for matching password hash.
20
+ # This is insecure as it is vulnerable to a timing attack.
21
+ "password".crypt(password_hash) == password_hash
22
+
23
+ # More secure method of checking for matching password hash
24
+ Rack::Utils.secure_compare(password_hash, "password".crypt(password_hash))
25
+
26
+ == Installing the gem
27
+
28
+ gem install string-crypt
29
+
30
+ If you want to have the library skip using crypt(3) or crypt_r(3) and
31
+ force the internal DES-crypt implementation:
32
+
33
+ STRING_CRYPT_FORCE_MISSING=1 gem install string-crypt
34
+
35
+ == Running the tests
36
+
37
+ In the repository:
38
+
39
+ rake test
40
+
41
+ This requires rake-compiler to compile the library, and minitest for
42
+ testing.
43
+
44
+ == Reporting issues/bugs
45
+
46
+ ruby-string-crypt uses GitHub Issues for tracking issues/bugs:
47
+
48
+ https://github.com/jeremyevans/ruby-string-crypt/issues
49
+
50
+ == Contributing
51
+
52
+ The source code is on GitHub:
53
+
54
+ https://github.com/jeremyevans/ruby-string-crypt
55
+
56
+ To get a copy:
57
+
58
+ git clone git://github.com/jeremyevans/ruby-string-crypt.git
59
+
60
+ == Platforms Supported
61
+
62
+ Ruby 2.1+ is supported. This library does not currently offer
63
+ support for JRuby.
64
+
65
+ == Maintainer
66
+
67
+ Jeremy Evans <code@jeremyevans.net>
@@ -0,0 +1,20 @@
1
+ require "rake"
2
+ require "rake/clean"
3
+
4
+ CLEAN.include %w'tmp string-crypt-*.gem lib'
5
+
6
+ desc "Build the gem"
7
+ task :package => :clean do
8
+ sh %{gem build string-crypt.gemspec}
9
+ end
10
+
11
+ begin
12
+ require 'rake/extensiontask'
13
+ Rake::ExtensionTask.new('string/crypt')
14
+
15
+ desc "Run tests"
16
+ task :test => :compile do
17
+ sh "#{FileUtils::RUBY} -w test/test_string_crypt.rb"
18
+ end
19
+ rescue LoadError
20
+ end
@@ -0,0 +1,103 @@
1
+ #include <errno.h>
2
+
3
+ #include "ruby.h"
4
+ #include "ruby/encoding.h"
5
+
6
+ #if defined HAVE_STRING_CRYPT_R
7
+ # if defined HAVE_STRING_CRYPT_H
8
+ # include <crypt.h>
9
+ # endif
10
+ #elif !defined HAVE_STRING_CRYPT
11
+ # include "missing/crypt.h"
12
+ # include "missing/crypt.c"
13
+ # define HAVE_STRING_CRYPT_R 1
14
+ #endif
15
+
16
+ static void
17
+ mustnot_wchar(VALUE str)
18
+ {
19
+ rb_encoding *enc = rb_enc_get(str);
20
+ if (rb_enc_mbminlen(enc) > 1) {
21
+ rb_raise(rb_eArgError, "wide char encoding: %s", rb_enc_name(enc));
22
+ }
23
+ }
24
+
25
+ /*
26
+ * call-seq:
27
+ * str.crypt(salt_str) -> new_str
28
+ *
29
+ * Applies a one-way cryptographic hash to <i>str</i> by invoking the
30
+ * standard library function <code>crypt(3)</code> with the given
31
+ * salt string. While the format and the result are system and
32
+ * implementation dependent, using a salt matching the regular
33
+ * expression <code>\A[a-zA-Z0-9./]{2}</code> should work on most
34
+ * most platforms, but on those platforms it uses insecure DES
35
+ * encryption, and only the first two characters of the salt string
36
+ * are significant.
37
+ *
38
+ * This method is for use in system specific scripts, so if you want
39
+ * a cross-platform hash function consider using Digest or OpenSSL
40
+ * instead.
41
+ */
42
+
43
+ static VALUE
44
+ rb_string_crypt(VALUE str, VALUE salt)
45
+ {
46
+ #ifdef HAVE_STRING_CRYPT_R
47
+ VALUE databuf;
48
+ struct crypt_data *data;
49
+ # define STRING_CRYPT_END() ALLOCV_END(databuf)
50
+ #else
51
+ extern char *crypt(const char *, const char *);
52
+ # define STRING_CRYPT_END() (void)0
53
+ #endif
54
+ VALUE result;
55
+ const char *s, *saltp;
56
+ char *res;
57
+ #ifdef BROKEN_STRING_CRYPT
58
+ char salt_8bit_clean[3];
59
+ #endif
60
+
61
+ StringValue(salt);
62
+ mustnot_wchar(str);
63
+ mustnot_wchar(salt);
64
+ if (RSTRING_LEN(salt) < 2) {
65
+ short_salt:
66
+ rb_raise(rb_eArgError, "salt too short (need >=2 bytes)");
67
+ }
68
+
69
+ s = StringValueCStr(str);
70
+ saltp = RSTRING_PTR(salt);
71
+ if (!saltp[0] || !saltp[1]) goto short_salt;
72
+ #ifdef BROKEN_STRING_CRYPT
73
+ if (!ISASCII((unsigned char)saltp[0]) || !ISASCII((unsigned char)saltp[1])) {
74
+ salt_8bit_clean[0] = saltp[0] & 0x7f;
75
+ salt_8bit_clean[1] = saltp[1] & 0x7f;
76
+ salt_8bit_clean[2] = '\0';
77
+ saltp = salt_8bit_clean;
78
+ }
79
+ #endif
80
+ #ifdef HAVE_STRING_CRYPT_R
81
+ data = ALLOCV(databuf, sizeof(struct crypt_data));
82
+ # ifdef HAVE_STRUCT_STRING_CRYPT_DATA_INITIALIZED
83
+ data->initialized = 0;
84
+ # endif
85
+ res = crypt_r(s, saltp, data);
86
+ #else
87
+ res = crypt(s, saltp);
88
+ #endif
89
+ if (!res) {
90
+ int err = errno;
91
+ STRING_CRYPT_END();
92
+ rb_syserr_fail(err, "crypt");
93
+ }
94
+ result = rb_str_new_cstr(res);
95
+ STRING_CRYPT_END();
96
+ FL_SET_RAW(result, OBJ_TAINTED_RAW(str) | OBJ_TAINTED_RAW(salt));
97
+ return result;
98
+ }
99
+
100
+ void Init_crypt(void) {
101
+ rb_eval_string("class String; remove_method(:crypt) if instance_methods(false).include?(:crypt); end");
102
+ rb_define_method(rb_cString, "crypt", rb_string_crypt, 1);
103
+ }
@@ -0,0 +1,61 @@
1
+ require 'mkmf'
2
+
3
+ if ENV['STRING_CRYPT_FORCE_MISSING'] == '1'
4
+ puts "forcing internal DES-crypt implementation"
5
+ else
6
+ if /darwin/ =~ RUBY_PLATFORM && try_run(<<END)
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <string.h>
10
+
11
+ void
12
+ broken_crypt(const char *salt, const char *buf1, const char *buf2)
13
+ {
14
+ #if 0
15
+ printf("%.2x%.2x: %s -> %s\n", (unsigned char)salt[0], (unsigned char)salt[1],
16
+ buf1+2, buf2+2);
17
+ #endif
18
+ }
19
+
20
+ int
21
+ main()
22
+ {
23
+ int i;
24
+ char salt[2], buf[256], *s;
25
+ for (i = 0; i < 128*128; i++) {
26
+ salt[0] = 0x80 | (i & 0x7f);
27
+ salt[1] = 0x80 | (i >> 7);
28
+ strcpy(buf, crypt("", salt));
29
+ if (strcmp(buf, s = crypt("", salt))) {
30
+ broken_crypt(salt, buf, s);
31
+ return 1;
32
+ }
33
+ }
34
+ salt[0] = salt[1] = ' ';
35
+ strcpy(buf, crypt("", salt));
36
+ salt[0] = salt[1] = 0x80 | ' ';
37
+ if (strcmp(buf, s = crypt("", salt))) {
38
+ broken_crypt(salt, buf, s);
39
+ return 1;
40
+ }
41
+ return 0;
42
+ }
43
+ END
44
+ $defs << "-DBROKEN_CRYPT"
45
+ end
46
+
47
+ if have_header('crypt.h')
48
+ have_struct_member("struct crypt_data", "initialized", "crypt.h")
49
+ end
50
+
51
+ have_library('crypt', 'crypt')
52
+ have_func('crypt_r')
53
+ have_func('crypt')
54
+ end
55
+
56
+ # Rename variables so variables from ruby/config.h are not picked up.
57
+ if $defs
58
+ $defs.map!{|s| s.sub('CRYPT', 'STRING_CRYPT')}
59
+ end
60
+
61
+ create_makefile 'string/crypt'
@@ -0,0 +1,888 @@
1
+ /*
2
+ * Copyright (c) 1989, 1993
3
+ * The Regents of the University of California. All rights reserved.
4
+ *
5
+ * This code is derived from software contributed to Berkeley by
6
+ * Tom Truscott.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions
10
+ * are met:
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * 2. Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * 3. Neither the name of the University nor the names of its contributors
17
+ * may be used to endorse or promote products derived from this software
18
+ * without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
+ * SUCH DAMAGE.
31
+ */
32
+
33
+ #if defined(LIBC_SCCS) && !defined(lint)
34
+ static char sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93";
35
+ #endif /* LIBC_SCCS and not lint */
36
+
37
+ #include "ruby/missing.h"
38
+ #include "crypt.h"
39
+ #ifdef HAVE_UNISTD_H
40
+ #include <unistd.h>
41
+ #endif
42
+ #include <limits.h>
43
+ #ifdef HAVE_PWD_H
44
+ #include <pwd.h>
45
+ #endif
46
+ #include <stdio.h>
47
+ #include <string.h>
48
+ #ifndef _PASSWORD_EFMT1
49
+ #define _PASSWORD_EFMT1 '_'
50
+ #endif
51
+
52
+ #ifndef numberof
53
+ #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
54
+ #endif
55
+
56
+ /*
57
+ * UNIX password, and DES, encryption.
58
+ * By Tom Truscott, trt@rti.rti.org,
59
+ * from algorithms by Robert W. Baldwin and James Gillogly.
60
+ *
61
+ * References:
62
+ * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
63
+ * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
64
+ *
65
+ * "Password Security: A Case History," R. Morris and Ken Thompson,
66
+ * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
67
+ *
68
+ * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
69
+ * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
70
+ */
71
+
72
+ /* ===== Configuration ==================== */
73
+
74
+ /*
75
+ * define "MUST_ALIGN" if your compiler cannot load/store
76
+ * long integers at arbitrary (e.g. odd) memory locations.
77
+ * (Either that or never pass unaligned addresses to des_cipher!)
78
+ */
79
+ #if !defined(vax)
80
+ #define MUST_ALIGN
81
+ #endif
82
+
83
+ #ifdef CHAR_BITS
84
+ #if CHAR_BITS != 8
85
+ #error C_block structure assumes 8 bit characters
86
+ #endif
87
+ #endif
88
+
89
+ #ifndef INIT_DES
90
+ # if defined DUMP || defined NO_DES_TABLES
91
+ # define INIT_DES 1
92
+ # else
93
+ # define INIT_DES 0
94
+ # endif
95
+ #endif
96
+ #if !INIT_DES
97
+ # include "des_tables.c"
98
+ # ifdef HAVE_DES_TABLES
99
+ # define init_des() ((void)0)
100
+ # else
101
+ # undef INIT_DES
102
+ # define INIT_DES 1
103
+ # endif
104
+ #endif
105
+
106
+ /*
107
+ * Convert twenty-four-bit long in host-order
108
+ * to six bits (and 2 low-order zeroes) per char little-endian format.
109
+ */
110
+ #define TO_SIX_BIT(rslt, src) { \
111
+ C_block cvt; \
112
+ cvt.b[0] = (unsigned char)(src); (src) >>= 6; \
113
+ cvt.b[1] = (unsigned char)(src); (src) >>= 6; \
114
+ cvt.b[2] = (unsigned char)(src); (src) >>= 6; \
115
+ cvt.b[3] = (unsigned char)(src); \
116
+ (rslt) = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \
117
+ }
118
+
119
+ /*
120
+ * These macros may someday permit efficient use of 64-bit integers.
121
+ */
122
+ #define ZERO(d,d0,d1) ((d0) = 0, (d1) = 0)
123
+ #define LOAD(d,d0,d1,bl) ((d0) = (bl).b32.i0, (d1) = (bl).b32.i1)
124
+ #define LOADREG(d,d0,d1,s,s0,s1) ((d0) = (s0), (d1) = (s1))
125
+ #define OR(d,d0,d1,bl) ((d0) |= (bl).b32.i0, (d1) |= (bl).b32.i1)
126
+ #define STORE(s,s0,s1,bl) ((bl).b32.i0 = (s0), (bl).b32.i1 = (s1))
127
+ #define DCL_BLOCK(d,d0,d1) long d0, d1
128
+
129
+ #if defined(LARGEDATA)
130
+ /* Waste memory like crazy. Also, do permutations in line */
131
+ #define PERM6464(d,d0,d1,cpp,p) \
132
+ LOAD((d),(d0),(d1),(p)[(0<<CHUNKBITS)+(cpp)[0]]); \
133
+ OR ((d),(d0),(d1),(p)[(1<<CHUNKBITS)+(cpp)[1]]); \
134
+ OR ((d),(d0),(d1),(p)[(2<<CHUNKBITS)+(cpp)[2]]); \
135
+ OR ((d),(d0),(d1),(p)[(3<<CHUNKBITS)+(cpp)[3]]); \
136
+ OR (d),(d0),(d1),(p)[(4<<CHUNKBITS)+(cpp)[4]]); \
137
+ OR (d),(d0),(d1),(p)[(5<<CHUNKBITS)+(cpp)[5]]); \
138
+ OR (d),(d0),(d1),(p)[(6<<CHUNKBITS)+(cpp)[6]]); \
139
+ OR (d),(d0),(d1),(p)[(7<<CHUNKBITS)+(cpp)[7]]);
140
+ #define PERM3264(d,d0,d1,cpp,p) \
141
+ LOAD((d),(d0),(d1),(p)[(0<<CHUNKBITS)+(cpp)[0]]); \
142
+ OR ((d),(d0),(d1),(p)[(1<<CHUNKBITS)+(cpp)[1]]); \
143
+ OR ((d),(d0),(d1),(p)[(2<<CHUNKBITS)+(cpp)[2]]); \
144
+ OR ((d),(d0),(d1),(p)[(3<<CHUNKBITS)+(cpp)[3]]);
145
+ #else
146
+ /* "small data" */
147
+ #define PERM6464(d,d0,d1,cpp,p) \
148
+ { C_block tblk; permute((cpp),&tblk,(p),8); LOAD ((d),(d0),(d1),tblk); }
149
+ #define PERM3264(d,d0,d1,cpp,p) \
150
+ { C_block tblk; permute((cpp),&tblk,(p),4); LOAD ((d),(d0),(d1),tblk); }
151
+
152
+ STATIC void
153
+ permute(const unsigned char *cp, C_block *out, register const C_block *p, int chars_in)
154
+ {
155
+ register DCL_BLOCK(D,D0,D1);
156
+ register const C_block *tp;
157
+ register int t;
158
+
159
+ ZERO(D,D0,D1);
160
+ do {
161
+ t = *cp++;
162
+ tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
163
+ tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
164
+ } while (--chars_in > 0);
165
+ STORE(D,D0,D1,*out);
166
+ }
167
+ #endif /* LARGEDATA */
168
+
169
+ #ifdef DEBUG
170
+ STATIC void prtab(const char *s, const unsigned char *t, int num_rows);
171
+ #endif
172
+
173
+ #if INIT_DES
174
+ /* ===== (mostly) Standard DES Tables ==================== */
175
+
176
+ static const unsigned char IP[] = { /* initial permutation */
177
+ 58, 50, 42, 34, 26, 18, 10, 2,
178
+ 60, 52, 44, 36, 28, 20, 12, 4,
179
+ 62, 54, 46, 38, 30, 22, 14, 6,
180
+ 64, 56, 48, 40, 32, 24, 16, 8,
181
+ 57, 49, 41, 33, 25, 17, 9, 1,
182
+ 59, 51, 43, 35, 27, 19, 11, 3,
183
+ 61, 53, 45, 37, 29, 21, 13, 5,
184
+ 63, 55, 47, 39, 31, 23, 15, 7,
185
+ };
186
+
187
+ /* The final permutation is the inverse of IP - no table is necessary */
188
+
189
+ static const unsigned char ExpandTr[] = { /* expansion operation */
190
+ 32, 1, 2, 3, 4, 5,
191
+ 4, 5, 6, 7, 8, 9,
192
+ 8, 9, 10, 11, 12, 13,
193
+ 12, 13, 14, 15, 16, 17,
194
+ 16, 17, 18, 19, 20, 21,
195
+ 20, 21, 22, 23, 24, 25,
196
+ 24, 25, 26, 27, 28, 29,
197
+ 28, 29, 30, 31, 32, 1,
198
+ };
199
+
200
+ static const unsigned char PC1[] = { /* permuted choice table 1 */
201
+ 57, 49, 41, 33, 25, 17, 9,
202
+ 1, 58, 50, 42, 34, 26, 18,
203
+ 10, 2, 59, 51, 43, 35, 27,
204
+ 19, 11, 3, 60, 52, 44, 36,
205
+
206
+ 63, 55, 47, 39, 31, 23, 15,
207
+ 7, 62, 54, 46, 38, 30, 22,
208
+ 14, 6, 61, 53, 45, 37, 29,
209
+ 21, 13, 5, 28, 20, 12, 4,
210
+ };
211
+ #endif
212
+
213
+ static const unsigned char Rotates[] = { /* PC1 rotation schedule */
214
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
215
+ };
216
+
217
+ #if INIT_DES
218
+ /* note: each "row" of PC2 is left-padded with bits that make it invertible */
219
+ static const unsigned char PC2[] = { /* permuted choice table 2 */
220
+ 9, 18, 14, 17, 11, 24, 1, 5,
221
+ 22, 25, 3, 28, 15, 6, 21, 10,
222
+ 35, 38, 23, 19, 12, 4, 26, 8,
223
+ 43, 54, 16, 7, 27, 20, 13, 2,
224
+
225
+ 0, 0, 41, 52, 31, 37, 47, 55,
226
+ 0, 0, 30, 40, 51, 45, 33, 48,
227
+ 0, 0, 44, 49, 39, 56, 34, 53,
228
+ 0, 0, 46, 42, 50, 36, 29, 32,
229
+ };
230
+
231
+ static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */
232
+ {
233
+ /* S[1] */
234
+ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
235
+ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
236
+ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
237
+ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
238
+ },
239
+ {
240
+ /* S[2] */
241
+ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
242
+ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
243
+ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
244
+ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
245
+ },
246
+ {
247
+ /* S[3] */
248
+ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
249
+ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
250
+ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
251
+ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
252
+ },
253
+ {
254
+ /* S[4] */
255
+ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
256
+ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
257
+ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
258
+ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
259
+ },
260
+ {
261
+ /* S[5] */
262
+ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
263
+ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
264
+ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
265
+ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
266
+ },
267
+ {
268
+ /* S[6] */
269
+ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
270
+ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
271
+ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
272
+ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
273
+ },
274
+ {
275
+ /* S[7] */
276
+ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
277
+ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
278
+ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
279
+ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
280
+ },
281
+ {
282
+ /* S[8] */
283
+ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
284
+ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
285
+ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
286
+ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
287
+ },
288
+ };
289
+
290
+ static const unsigned char P32Tr[] = { /* 32-bit permutation function */
291
+ 16, 7, 20, 21,
292
+ 29, 12, 28, 17,
293
+ 1, 15, 23, 26,
294
+ 5, 18, 31, 10,
295
+ 2, 8, 24, 14,
296
+ 32, 27, 3, 9,
297
+ 19, 13, 30, 6,
298
+ 22, 11, 4, 25,
299
+ };
300
+
301
+ static const unsigned char CIFP[] = { /* compressed/interleaved permutation */
302
+ 1, 2, 3, 4, 17, 18, 19, 20,
303
+ 5, 6, 7, 8, 21, 22, 23, 24,
304
+ 9, 10, 11, 12, 25, 26, 27, 28,
305
+ 13, 14, 15, 16, 29, 30, 31, 32,
306
+
307
+ 33, 34, 35, 36, 49, 50, 51, 52,
308
+ 37, 38, 39, 40, 53, 54, 55, 56,
309
+ 41, 42, 43, 44, 57, 58, 59, 60,
310
+ 45, 46, 47, 48, 61, 62, 63, 64,
311
+ };
312
+ #endif
313
+
314
+ static const unsigned char itoa64[] = /* 0..63 => ascii-64 */
315
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
316
+
317
+ /* table that converts chars "./0-9A-Za-z"to integers 0-63. */
318
+ static const unsigned char a64toi[256] = {
319
+ #define A64TOI1(c) \
320
+ ((c) == '.' ? 0 : \
321
+ (c) == '/' ? 1 : \
322
+ ('0' <= (c) && (c) <= '9') ? (c) - '0' + 2 : \
323
+ ('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 12 : \
324
+ ('a' <= (c) && (c) <= 'z') ? (c) - 'a' + 38 : \
325
+ 0)
326
+ #define A64TOI4(base) A64TOI1(base+0), A64TOI1(base+1), A64TOI1(base+2), A64TOI1(base+3)
327
+ #define A64TOI16(base) A64TOI4(base+0), A64TOI4(base+4), A64TOI4(base+8), A64TOI4(base+12)
328
+ #define A64TOI64(base) A64TOI16(base+0x00), A64TOI16(base+0x10), A64TOI16(base+0x20), A64TOI16(base+0x30)
329
+ A64TOI64(0x00), A64TOI64(0x40),
330
+ A64TOI64(0x00), A64TOI64(0x40),
331
+ };
332
+
333
+ #if INIT_DES
334
+ /* ===== Tables that are initialized at run time ==================== */
335
+
336
+ typedef struct {
337
+ /* Initial key schedule permutation */
338
+ C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
339
+
340
+ /* Subsequent key schedule rotation permutations */
341
+ C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
342
+
343
+ /* Initial permutation/expansion table */
344
+ C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS];
345
+
346
+ /* Table that combines the S, P, and E operations. */
347
+ unsigned long SPE[2][8][64];
348
+
349
+ /* compressed/interleaved => final permutation table */
350
+ C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS];
351
+
352
+ int ready;
353
+ } des_tables_t;
354
+ static des_tables_t des_tables[1];
355
+
356
+ #define des_tables ((const des_tables_t *)des_tables)
357
+ #define PC1ROT (des_tables->PC1ROT)
358
+ #define PC2ROT (des_tables->PC2ROT)
359
+ #define IE3264 (des_tables->IE3264)
360
+ #define SPE (des_tables->SPE)
361
+ #define CF6464 (des_tables->CF6464)
362
+
363
+ STATIC void init_des(void);
364
+ STATIC void init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS], unsigned char p[64], int chars_in, int chars_out);
365
+ #endif
366
+
367
+ static const C_block constdatablock = {{0}}; /* encryption constant */
368
+
369
+ #define KS (data->KS)
370
+ #define cryptresult (data->cryptresult)
371
+
372
+ static void des_setkey_r(const unsigned char *key, struct crypt_data *data);
373
+ static void des_cipher_r(const unsigned char *in, unsigned char *out, long salt, int num_iter, struct crypt_data *data);
374
+
375
+ /*
376
+ * Return a pointer to data consisting of the "setting" followed by an
377
+ * encryption produced by the "key" and "setting".
378
+ */
379
+ char *
380
+ crypt_r(const char *key, const char *setting, struct crypt_data *data)
381
+ {
382
+ register char *encp;
383
+ register long i;
384
+ register int t;
385
+ long salt;
386
+ int num_iter, salt_size;
387
+ C_block keyblock, rsltblock;
388
+
389
+ for (i = 0; i < 8; i++) {
390
+ if ((t = 2*(unsigned char)(*key)) != 0)
391
+ key++;
392
+ keyblock.b[i] = t;
393
+ }
394
+ des_setkey_r(keyblock.b, data); /* also initializes "a64toi" */
395
+
396
+ encp = &cryptresult[0];
397
+ switch (*setting) {
398
+ case _PASSWORD_EFMT1:
399
+ /*
400
+ * Involve the rest of the password 8 characters at a time.
401
+ */
402
+ while (*key) {
403
+ des_cipher_r(keyblock.b, keyblock.b, 0L, 1, data);
404
+ for (i = 0; i < 8; i++) {
405
+ if ((t = 2*(unsigned char)(*key)) != 0)
406
+ key++;
407
+ keyblock.b[i] ^= t;
408
+ }
409
+ des_setkey_r(keyblock.b, data);
410
+ }
411
+
412
+ *encp++ = *setting++;
413
+
414
+ /* get iteration count */
415
+ num_iter = 0;
416
+ for (i = 4; --i >= 0; ) {
417
+ if ((t = (unsigned char)setting[i]) == '\0')
418
+ t = '.';
419
+ encp[i] = t;
420
+ num_iter = (num_iter<<6) | a64toi[t];
421
+ }
422
+ setting += 4;
423
+ encp += 4;
424
+ salt_size = 4;
425
+ break;
426
+ default:
427
+ num_iter = 25;
428
+ salt_size = 2;
429
+ }
430
+
431
+ salt = 0;
432
+ for (i = salt_size; --i >= 0; ) {
433
+ if ((t = (unsigned char)setting[i]) == '\0')
434
+ t = '.';
435
+ encp[i] = t;
436
+ salt = (salt<<6) | a64toi[t];
437
+ }
438
+ encp += salt_size;
439
+ des_cipher_r(constdatablock.b, rsltblock.b, salt, num_iter, data);
440
+
441
+ /*
442
+ * Encode the 64 cipher bits as 11 ascii characters.
443
+ */
444
+ i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
445
+ encp[3] = itoa64[i&0x3f]; i >>= 6;
446
+ encp[2] = itoa64[i&0x3f]; i >>= 6;
447
+ encp[1] = itoa64[i&0x3f]; i >>= 6;
448
+ encp[0] = itoa64[i]; encp += 4;
449
+ i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
450
+ encp[3] = itoa64[i&0x3f]; i >>= 6;
451
+ encp[2] = itoa64[i&0x3f]; i >>= 6;
452
+ encp[1] = itoa64[i&0x3f]; i >>= 6;
453
+ encp[0] = itoa64[i]; encp += 4;
454
+ i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
455
+ encp[2] = itoa64[i&0x3f]; i >>= 6;
456
+ encp[1] = itoa64[i&0x3f]; i >>= 6;
457
+ encp[0] = itoa64[i];
458
+
459
+ encp[3] = 0;
460
+
461
+ return (cryptresult);
462
+ }
463
+
464
+ /*
465
+ * Set up the key schedule from the key.
466
+ */
467
+ static void
468
+ des_setkey_r(const unsigned char *key, struct crypt_data *data)
469
+ {
470
+ register DCL_BLOCK(K, K0, K1);
471
+ register const C_block *ptabp;
472
+ register int i;
473
+ C_block *ksp;
474
+
475
+ init_des();
476
+
477
+ PERM6464(K,K0,K1,key,PC1ROT[0]);
478
+ ksp = &KS[0];
479
+ STORE(K&~0x03030303L, K0&~0x03030303L, K1, *ksp);
480
+ for (i = 1; i < numberof(KS); i++) {
481
+ ksp++;
482
+ STORE(K,K0,K1,*ksp);
483
+ ptabp = PC2ROT[Rotates[i]-1][0];
484
+ PERM6464(K,K0,K1,ksp->b,ptabp);
485
+ STORE(K&~0x03030303L, K0&~0x03030303L, K1, *ksp);
486
+ }
487
+ }
488
+
489
+ /*
490
+ * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
491
+ * iterations of DES, using the given 24-bit salt and the pre-computed key
492
+ * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
493
+ *
494
+ * NOTE: the performance of this routine is critically dependent on your
495
+ * compiler and machine architecture.
496
+ */
497
+ void
498
+ des_cipher_r(const unsigned char *in, unsigned char *out, long salt, int num_iter, struct crypt_data *data)
499
+ {
500
+ /* variables that we want in registers, most important first */
501
+ #if defined(pdp11)
502
+ register int j;
503
+ #endif
504
+ register unsigned long L0, L1, R0, R1, k;
505
+ register const C_block *kp;
506
+ register int ks_inc, loop_count;
507
+ C_block B;
508
+
509
+ L0 = salt;
510
+ TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */
511
+
512
+ #if defined(vax) || defined(pdp11)
513
+ salt = ~salt; /* "x &~ y" is faster than "x & y". */
514
+ #define SALT (~salt)
515
+ #else
516
+ #define SALT salt
517
+ #endif
518
+
519
+ #if defined(MUST_ALIGN)
520
+ B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
521
+ B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
522
+ LOAD(L,L0,L1,B);
523
+ #else
524
+ LOAD(L,L0,L1,*(C_block *)in);
525
+ #endif
526
+ LOADREG(R,R0,R1,L,L0,L1);
527
+ L0 &= 0x55555555L;
528
+ L1 &= 0x55555555L;
529
+ L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */
530
+ R0 &= 0xaaaaaaaaL;
531
+ R1 = (R1 >> 1) & 0x55555555L;
532
+ L1 = R0 | R1; /* L1 is the odd-numbered input bits */
533
+ STORE(L,L0,L1,B);
534
+ PERM3264(L,L0,L1,B.b, IE3264[0]); /* even bits */
535
+ PERM3264(R,R0,R1,B.b+4,IE3264[0]); /* odd bits */
536
+
537
+ if (num_iter >= 0)
538
+ { /* encryption */
539
+ kp = &KS[0];
540
+ ks_inc = +1;
541
+ }
542
+ else
543
+ { /* decryption */
544
+ num_iter = -num_iter;
545
+ kp = &KS[KS_SIZE-1];
546
+ ks_inc = -1;
547
+ }
548
+
549
+ while (--num_iter >= 0) {
550
+ loop_count = 8;
551
+ do {
552
+
553
+ #define SPTAB(t, i) (*(const unsigned long *)((const unsigned char *)(t) + (i)*(sizeof(long)/4)))
554
+ #if defined(gould)
555
+ /* use this if B.b[i] is evaluated just once ... */
556
+ #define DOXOR(x,y,i) (x)^=SPTAB(SPE[0][(i)],B.b[(i)]); (y)^=SPTAB(SPE[1][(i)],B.b[(i)]);
557
+ #else
558
+ #if defined(pdp11)
559
+ /* use this if your "long" int indexing is slow */
560
+ #define DOXOR(x,y,i) j=B.b[(i)]; (x)^=SPTAB(SPE[0][(i)],j); (y)^=SPTAB(SPE[1][(i)],j);
561
+ #else
562
+ /* use this if "k" is allocated to a register ... */
563
+ #define DOXOR(x,y,i) k=B.b[(i)]; (x)^=SPTAB(SPE[0][(i)],k); (y)^=SPTAB(SPE[1][(i)],k);
564
+ #endif
565
+ #endif
566
+
567
+ #define CRUNCH(p0, p1, q0, q1) \
568
+ k = ((q0) ^ (q1)) & SALT; \
569
+ B.b32.i0 = k ^ (q0) ^ kp->b32.i0; \
570
+ B.b32.i1 = k ^ (q1) ^ kp->b32.i1; \
571
+ kp += ks_inc; \
572
+ \
573
+ DOXOR((p0), (p1), 0); \
574
+ DOXOR((p0), (p1), 1); \
575
+ DOXOR((p0), (p1), 2); \
576
+ DOXOR((p0), (p1), 3); \
577
+ DOXOR((p0), (p1), 4); \
578
+ DOXOR((p0), (p1), 5); \
579
+ DOXOR((p0), (p1), 6); \
580
+ DOXOR((p0), (p1), 7);
581
+
582
+ CRUNCH(L0, L1, R0, R1);
583
+ CRUNCH(R0, R1, L0, L1);
584
+ } while (--loop_count != 0);
585
+ kp -= (ks_inc*KS_SIZE);
586
+
587
+
588
+ /* swap L and R */
589
+ L0 ^= R0; L1 ^= R1;
590
+ R0 ^= L0; R1 ^= L1;
591
+ L0 ^= R0; L1 ^= R1;
592
+ }
593
+
594
+ /* store the encrypted (or decrypted) result */
595
+ L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
596
+ L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
597
+ STORE(L,L0,L1,B);
598
+ PERM6464(L,L0,L1,B.b, CF6464[0]);
599
+ #if defined(MUST_ALIGN)
600
+ STORE(L,L0,L1,B);
601
+ out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
602
+ out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
603
+ #else
604
+ STORE(L,L0,L1,*(C_block *)out);
605
+ #endif
606
+ }
607
+
608
+ #undef des_tables
609
+ #undef KS
610
+ #undef cryptresult
611
+
612
+ #if INIT_DES
613
+ /*
614
+ * Initialize various tables. This need only be done once. It could even be
615
+ * done at compile time, if the compiler were capable of that sort of thing.
616
+ */
617
+ STATIC void
618
+ init_des(void)
619
+ {
620
+ register int i, j;
621
+ register long k;
622
+ register int tableno;
623
+ unsigned char perm[64], tmp32[32];
624
+
625
+ if (des_tables->ready) return;
626
+
627
+ /*
628
+ * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
629
+ */
630
+ for (i = 0; i < 64; i++)
631
+ perm[i] = 0;
632
+ for (i = 0; i < 64; i++) {
633
+ if ((k = PC2[i]) == 0)
634
+ continue;
635
+ k += Rotates[0]-1;
636
+ if ((k%28) < Rotates[0]) k -= 28;
637
+ k = PC1[k];
638
+ if (k > 0) {
639
+ k--;
640
+ k = (k|07) - (k&07);
641
+ k++;
642
+ }
643
+ perm[i] = (unsigned char)k;
644
+ }
645
+ #ifdef DEBUG
646
+ prtab("pc1tab", perm, 8);
647
+ #endif
648
+ init_perm(PC1ROT, perm, 8, 8);
649
+
650
+ /*
651
+ * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
652
+ */
653
+ for (j = 0; j < 2; j++) {
654
+ unsigned char pc2inv[64];
655
+ for (i = 0; i < 64; i++)
656
+ perm[i] = pc2inv[i] = 0;
657
+ for (i = 0; i < 64; i++) {
658
+ if ((k = PC2[i]) == 0)
659
+ continue;
660
+ pc2inv[k-1] = i+1;
661
+ }
662
+ for (i = 0; i < 64; i++) {
663
+ if ((k = PC2[i]) == 0)
664
+ continue;
665
+ k += j;
666
+ if ((k%28) <= j) k -= 28;
667
+ perm[i] = pc2inv[k];
668
+ }
669
+ #ifdef DEBUG
670
+ prtab("pc2tab", perm, 8);
671
+ #endif
672
+ init_perm(PC2ROT[j], perm, 8, 8);
673
+ }
674
+
675
+ /*
676
+ * Bit reverse, then initial permutation, then expansion.
677
+ */
678
+ for (i = 0; i < 8; i++) {
679
+ for (j = 0; j < 8; j++) {
680
+ k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
681
+ if (k > 32)
682
+ k -= 32;
683
+ else if (k > 0)
684
+ k--;
685
+ if (k > 0) {
686
+ k--;
687
+ k = (k|07) - (k&07);
688
+ k++;
689
+ }
690
+ perm[i*8+j] = (unsigned char)k;
691
+ }
692
+ }
693
+ #ifdef DEBUG
694
+ prtab("ietab", perm, 8);
695
+ #endif
696
+ init_perm(IE3264, perm, 4, 8);
697
+
698
+ /*
699
+ * Compression, then final permutation, then bit reverse.
700
+ */
701
+ for (i = 0; i < 64; i++) {
702
+ k = IP[CIFP[i]-1];
703
+ if (k > 0) {
704
+ k--;
705
+ k = (k|07) - (k&07);
706
+ k++;
707
+ }
708
+ perm[k-1] = i+1;
709
+ }
710
+ #ifdef DEBUG
711
+ prtab("cftab", perm, 8);
712
+ #endif
713
+ init_perm(CF6464, perm, 8, 8);
714
+
715
+ /*
716
+ * SPE table
717
+ */
718
+ for (i = 0; i < 48; i++)
719
+ perm[i] = P32Tr[ExpandTr[i]-1];
720
+ for (tableno = 0; tableno < 8; tableno++) {
721
+ for (j = 0; j < 64; j++) {
722
+ k = (((j >> 0) &01) << 5)|
723
+ (((j >> 1) &01) << 3)|
724
+ (((j >> 2) &01) << 2)|
725
+ (((j >> 3) &01) << 1)|
726
+ (((j >> 4) &01) << 0)|
727
+ (((j >> 5) &01) << 4);
728
+ k = S[tableno][k];
729
+ k = (((k >> 3)&01) << 0)|
730
+ (((k >> 2)&01) << 1)|
731
+ (((k >> 1)&01) << 2)|
732
+ (((k >> 0)&01) << 3);
733
+ for (i = 0; i < 32; i++)
734
+ tmp32[i] = 0;
735
+ for (i = 0; i < 4; i++)
736
+ tmp32[4 * tableno + i] = (unsigned char)(k >> i) & 01;
737
+ k = 0;
738
+ for (i = 24; --i >= 0; )
739
+ k = (k<<1) | tmp32[perm[i]-1];
740
+ TO_SIX_BIT(SPE[0][tableno][j], k);
741
+ k = 0;
742
+ for (i = 24; --i >= 0; )
743
+ k = (k<<1) | tmp32[perm[i+24]-1];
744
+ TO_SIX_BIT(SPE[1][tableno][j], k);
745
+ }
746
+ }
747
+
748
+ des_tables->ready = 1;
749
+ }
750
+
751
+ /*
752
+ * Initialize "perm" to represent transformation "p", which rearranges
753
+ * (perhaps with expansion and/or contraction) one packed array of bits
754
+ * (of size "chars_in" characters) into another array (of size "chars_out"
755
+ * characters).
756
+ *
757
+ * "perm" must be all-zeroes on entry to this routine.
758
+ */
759
+ STATIC void
760
+ init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS],
761
+ unsigned char p[64], int chars_in, int chars_out)
762
+ {
763
+ register int i, j, k, l;
764
+
765
+ for (k = 0; k < chars_out*8; k++) { /* each output bit position */
766
+ l = p[k] - 1; /* where this bit comes from */
767
+ if (l < 0)
768
+ continue; /* output bit is always 0 */
769
+ i = l>>LGCHUNKBITS; /* which chunk this bit comes from */
770
+ l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */
771
+ for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */
772
+ if ((j & l) != 0)
773
+ perm[i][j].b[k>>3] |= 1<<(k&07);
774
+ }
775
+ }
776
+ }
777
+ #endif
778
+
779
+ #ifdef DEBUG
780
+ STATIC void
781
+ prtab(const char *s, const unsigned char *t, int num_rows)
782
+ {
783
+ register int i, j;
784
+
785
+ (void)printf("%s:\n", s);
786
+ for (i = 0; i < num_rows; i++) {
787
+ for (j = 0; j < 8; j++) {
788
+ (void)printf("%3d", t[i*8+j]);
789
+ }
790
+ (void)printf("\n");
791
+ }
792
+ (void)printf("\n");
793
+ }
794
+ #endif
795
+
796
+ #ifdef DUMP
797
+ void
798
+ dump_block(const C_block *block)
799
+ {
800
+ int i;
801
+ printf("{{");
802
+ for (i = 0; i < numberof(block->b); ++i) {
803
+ printf("%3d,", block->b[i]);
804
+ }
805
+ printf("}},\n");
806
+ }
807
+
808
+ int
809
+ main(void)
810
+ {
811
+ int i, j, k;
812
+ init_des();
813
+
814
+ printf("#ifndef HAVE_DES_TABLES\n\n");
815
+ printf("/* Initial key schedule permutation */\n");
816
+ printf("static const C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS] = {\n");
817
+ for (i = 0; i < numberof(PC1ROT); ++i) {
818
+ printf("\t{\n");
819
+ for (j = 0; j < numberof(PC1ROT[0]); ++j) {
820
+ printf("\t\t");
821
+ dump_block(&PC1ROT[i][j]);
822
+ }
823
+ printf("\t},\n");
824
+ }
825
+ printf("};\n\n");
826
+
827
+ printf("/* Subsequent key schedule rotation permutations */\n");
828
+ printf("static const C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS] = {\n");
829
+ for (i = 0; i < numberof(PC2ROT); ++i) {
830
+ printf("\t{\n");
831
+ for (j = 0; j < numberof(PC2ROT[0]); ++j) {
832
+ printf("\t\t{\n");
833
+ for (k = 0; k < numberof(PC2ROT[0][0]); ++k) {
834
+ printf("\t\t\t");
835
+ dump_block(&PC2ROT[i][j][k]);
836
+ }
837
+ printf("\t\t},\n");
838
+ }
839
+ printf("\t},\n");
840
+ }
841
+ printf("};\n\n");
842
+
843
+ printf("/* Initial permutation/expansion table */\n");
844
+ printf("static const C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS] = {\n");
845
+ for (i = 0; i < numberof(IE3264); ++i) {
846
+ printf("\t{\n");
847
+ for (j = 0; j < numberof(IE3264[0]); ++j) {
848
+ printf("\t\t");
849
+ dump_block(&IE3264[i][j]);
850
+ }
851
+ printf("\t},\n");
852
+ }
853
+ printf("};\n\n");
854
+
855
+ printf("/* Table that combines the S, P, and E operations. */\n");
856
+ printf("static const unsigned long SPE[2][8][64] = {\n");
857
+ for (i = 0; i < numberof(SPE); ++i) {
858
+ printf("\t{\n");
859
+ for (j = 0; j < numberof(SPE[0]); ++j) {
860
+ int r = 0;
861
+ printf("\t\t{");
862
+ for (k = 0; k < numberof(SPE[0][0]); ++k) {
863
+ if (r == 0) printf("\n\t\t\t");
864
+ printf("%#10lx,", SPE[i][j][k]);
865
+ if (++r == 4) r = 0;
866
+ }
867
+ printf("\n\t\t},\n");
868
+ }
869
+ printf("\t},\n");
870
+ }
871
+ printf("};\n\n");
872
+
873
+ printf("/* compressed/interleaved => final permutation table */\n");
874
+ printf("static const C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS] = {\n");
875
+ for (i = 0; i < numberof(CF6464); ++i) {
876
+ printf("\t{\n");
877
+ for (j = 0; j < numberof(CF6464[0]); ++j) {
878
+ printf("\t\t");
879
+ dump_block(&CF6464[i][j]);
880
+ }
881
+ printf("\t},\n");
882
+ }
883
+ printf("};\n\n");
884
+ printf("#define HAVE_DES_TABLES 1\n""#endif\n");
885
+
886
+ return 0;
887
+ }
888
+ #endif