string-crypt 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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