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; } }