dennis@GW.CCIE.UTORONTO.CA (Dennis Ferguson) (06/08/89)
I am using gcc 1.35 on a Sun 3/180 running SunOS 3.5. The compiler
was configured using `config.gcc sun3'. I am using the Sun assembler
and loader.
The following program, when compiled with `gcc -O ...', produces correct
results, as it does when compiled with the Sun compiler. When compiled
with `gcc -O -fstrength-reduce ...' it does not. I tried to find a smaller
fragment which would exhibit the problem but found the trouble kept
disappearing on me.
Dennis Ferguson
------
#include <stdio.h>
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
u_char ekeys[128];
u_char dkeys[128];
u_long keys[10][2] = {
0x00000000, 0x00000000,
0xffffffff, 0xffffffff,
0x30000000, 0x00000000,
0x11111111, 0x11111111,
0x01234567, 0x89abcdef,
0xfedcba98, 0x76543210,
0x7ca11045, 0x4a1a6e57,
0x0131d961, 0x9dc1376e,
0x07a1133e, 0x4a0b2686,
0x3849674c, 0x2602319e
};
main()
{
int i, j;
for (i = 0; i < 10; i++) {
auth_subkeys(&keys[i][0], ekeys, dkeys);
(void) printf("0x%08x 0x%08x\n", keys[i][0], keys[i][1]);
for (j = 0; j < 128; j++) {
printf(" 0x%03x", ekeys[j]);
if (j % 8 == 7)
printf("\n");
}
}
}
static u_char PC1_C[28] = {
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35
};
static u_char PC1_D[28] = {
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3
};
static u_char two_bit_shift[16] = {
0, 0, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 0
};
static u_char PC2_C[24] = {
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1
};
static u_char PC2_D[24] = {
12, 23, 2, 8, 18, 26,
1, 11, 22, 16, 4, 19,
15, 20, 10, 27, 5, 24,
17, 13, 21, 7, 0, 3
};
auth_subkeys(key, encryptkeys, decryptkeys)
u_long *key;
u_char *encryptkeys;
u_char *decryptkeys;
{
register u_char *ek, *dk;
register int i;
register u_char tempc;
register u_long templ;
register int iteration;
u_char bits[64];
u_char c[28], d[28];
templ = *key;
for (i = 0; i < 32; i++) {
bits[i] = ((templ & 0x80000000) != 0);
templ <<= 1;
}
templ = *(key+1);
for ( ; i < 64; i++) {
bits[i] = ((templ & 0x80000000) != 0);
templ <<= 1;
}
for (i = 0; i < 28; i++) {
c[i] = bits[PC1_C[i]];
d[i] = bits[PC1_D[i]];
}
ek = encryptkeys;
dk = decryptkeys + (8 * 15);
for (iteration = 0; iteration < 16; iteration++) {
if (two_bit_shift[iteration]) {
tempc = c[0];
templ = c[1];
for (i = 0; i < 26; i++)
c[i] = c[i+2];
c[26] = tempc;
c[27] = (u_char)templ;
tempc = d[0];
templ = d[1];
for (i = 0; i < 26; i++)
d[i] = d[i+2];
d[26] = tempc;
d[27] = (u_char)templ;
} else {
tempc = c[0];
for (i = 0; i < 27; i++)
c[i] = c[i+1];
c[27] = tempc;
tempc = d[0];
for (i = 0; i < 27; i++)
d[i] = d[i+1];
d[27] = tempc;
}
for (i = 0; i < 24; i += 6) {
tempc = (c[PC2_C[i]] << 5)
| (c[PC2_C[i+1]] << 4)
| (c[PC2_C[i+2]] << 3)
| (c[PC2_C[i+3]] << 2)
| (c[PC2_C[i+4]] << 1)
| c[PC2_C[i+5]];
*ek++ = *dk++ = tempc;
}
for (i = 0; i < 24; i += 6) {
tempc = (d[PC2_D[i]] << 5)
| (d[PC2_D[i+1]] << 4)
| (d[PC2_D[i+2]] << 3)
| (d[PC2_D[i+3]] << 2)
| (d[PC2_D[i+4]] << 1)
| d[PC2_D[i+5]];
*ek++ = *dk++ = tempc;
}
dk -= 16;
}
}