Clean up the DES_key_schedule logic.

It's not clear why OpenSSL had a union. The comment says something about sizes
of long, since OpenSSL doesn't use stdint.h. But the variable is treated as a
bunch of uint32_t's, not DES_cblocks.

The key schedule is also always used by iterating or indexing into a uint32_t*,
treating the 16 2-word subkeys as a single uint32_t[32]. Instead, index into
them properly shush any picky tools. The compiler should be able to figure out
what's going on and optimize it appropriately.

BUG=517495

Change-Id: I83d0e63ac2c6fb76fac1dceda9f2fd6762074341
Reviewed-on: https://boringssl-review.googlesource.com/5627
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/des/des.c b/crypto/des/des.c
index 738793c..a5669a6 100644
--- a/crypto/des/des.c
+++ b/crypto/des/des.c
@@ -298,10 +298,8 @@
                                   0, 1, 1, 1, 1, 1, 1, 0};
   uint32_t c, d, t, s, t2;
   const uint8_t *in;
-  uint32_t *k;
   int i;
 
-  k = &schedule->ks->deslong[0];
   in = key->bytes;
 
   c2l(in, c);
@@ -344,10 +342,10 @@
 
     /* table contained 0213 4657 */
     t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
-    *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+    schedule->subkeys[i][0] = ROTATE(t2, 30) & 0xffffffffL;
 
     t2 = ((s >> 16L) | (t & 0xffff0000L));
-    *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+    schedule->subkeys[i][1] = ROTATE(t2, 26) & 0xffffffffL;
   }
 }
 
@@ -382,7 +380,6 @@
 
 static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
   uint32_t l, r, t, u;
-  const uint32_t *s;
 
   r = data[0];
   l = data[1];
@@ -398,43 +395,42 @@
   r = ROTATE(r, 29) & 0xffffffffL;
   l = ROTATE(l, 29) & 0xffffffffL;
 
-  s = ks->ks->deslong;
   /* I don't know if it is worth the effort of loop unrolling the
    * inner loop */
   if (enc) {
-    D_ENCRYPT(l, r, 0);  /*  1 */
-    D_ENCRYPT(r, l, 2);  /*  2 */
-    D_ENCRYPT(l, r, 4);  /*  3 */
-    D_ENCRYPT(r, l, 6);  /*  4 */
-    D_ENCRYPT(l, r, 8);  /*  5 */
-    D_ENCRYPT(r, l, 10); /*  6 */
-    D_ENCRYPT(l, r, 12); /*  7 */
-    D_ENCRYPT(r, l, 14); /*  8 */
-    D_ENCRYPT(l, r, 16); /*  9 */
-    D_ENCRYPT(r, l, 18); /*  10 */
-    D_ENCRYPT(l, r, 20); /*  11 */
-    D_ENCRYPT(r, l, 22); /*  12 */
-    D_ENCRYPT(l, r, 24); /*  13 */
-    D_ENCRYPT(r, l, 26); /*  14 */
-    D_ENCRYPT(l, r, 28); /*  15 */
-    D_ENCRYPT(r, l, 30); /*  16 */
+    D_ENCRYPT(ks, l, r, 0);
+    D_ENCRYPT(ks, r, l, 1);
+    D_ENCRYPT(ks, l, r, 2);
+    D_ENCRYPT(ks, r, l, 3);
+    D_ENCRYPT(ks, l, r, 4);
+    D_ENCRYPT(ks, r, l, 5);
+    D_ENCRYPT(ks, l, r, 6);
+    D_ENCRYPT(ks, r, l, 7);
+    D_ENCRYPT(ks, l, r, 8);
+    D_ENCRYPT(ks, r, l, 9);
+    D_ENCRYPT(ks, l, r, 10);
+    D_ENCRYPT(ks, r, l, 11);
+    D_ENCRYPT(ks, l, r, 12);
+    D_ENCRYPT(ks, r, l, 13);
+    D_ENCRYPT(ks, l, r, 14);
+    D_ENCRYPT(ks, r, l, 15);
   } else {
-    D_ENCRYPT(l, r, 30); /* 16 */
-    D_ENCRYPT(r, l, 28); /* 15 */
-    D_ENCRYPT(l, r, 26); /* 14 */
-    D_ENCRYPT(r, l, 24); /* 13 */
-    D_ENCRYPT(l, r, 22); /* 12 */
-    D_ENCRYPT(r, l, 20); /* 11 */
-    D_ENCRYPT(l, r, 18); /* 10 */
-    D_ENCRYPT(r, l, 16); /*  9 */
-    D_ENCRYPT(l, r, 14); /*  8 */
-    D_ENCRYPT(r, l, 12); /*  7 */
-    D_ENCRYPT(l, r, 10); /*  6 */
-    D_ENCRYPT(r, l, 8);  /*  5 */
-    D_ENCRYPT(l, r, 6);  /*  4 */
-    D_ENCRYPT(r, l, 4);  /*  3 */
-    D_ENCRYPT(l, r, 2);  /*  2 */
-    D_ENCRYPT(r, l, 0);  /*  1 */
+    D_ENCRYPT(ks, l, r, 15);
+    D_ENCRYPT(ks, r, l, 14);
+    D_ENCRYPT(ks, l, r, 13);
+    D_ENCRYPT(ks, r, l, 12);
+    D_ENCRYPT(ks, l, r, 11);
+    D_ENCRYPT(ks, r, l, 10);
+    D_ENCRYPT(ks, l, r, 9);
+    D_ENCRYPT(ks, r, l, 8);
+    D_ENCRYPT(ks, l, r, 7);
+    D_ENCRYPT(ks, r, l, 6);
+    D_ENCRYPT(ks, l, r, 5);
+    D_ENCRYPT(ks, r, l, 4);
+    D_ENCRYPT(ks, l, r, 3);
+    D_ENCRYPT(ks, r, l, 2);
+    D_ENCRYPT(ks, l, r, 1);
+    D_ENCRYPT(ks, r, l, 0);
   }
 
   /* rotate and clear the top bits on machines with 8byte longs */
@@ -448,7 +444,6 @@
 
 static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
   uint32_t l, r, t, u;
-  const uint32_t *s;
 
   r = data[0];
   l = data[1];
@@ -462,43 +457,42 @@
   r = ROTATE(r, 29) & 0xffffffffL;
   l = ROTATE(l, 29) & 0xffffffffL;
 
-  s = ks->ks->deslong;
   /* I don't know if it is worth the effort of loop unrolling the
    * inner loop */
   if (enc) {
-    D_ENCRYPT(l, r, 0);  /*  1 */
-    D_ENCRYPT(r, l, 2);  /*  2 */
-    D_ENCRYPT(l, r, 4);  /*  3 */
-    D_ENCRYPT(r, l, 6);  /*  4 */
-    D_ENCRYPT(l, r, 8);  /*  5 */
-    D_ENCRYPT(r, l, 10); /*  6 */
-    D_ENCRYPT(l, r, 12); /*  7 */
-    D_ENCRYPT(r, l, 14); /*  8 */
-    D_ENCRYPT(l, r, 16); /*  9 */
-    D_ENCRYPT(r, l, 18); /*  10 */
-    D_ENCRYPT(l, r, 20); /*  11 */
-    D_ENCRYPT(r, l, 22); /*  12 */
-    D_ENCRYPT(l, r, 24); /*  13 */
-    D_ENCRYPT(r, l, 26); /*  14 */
-    D_ENCRYPT(l, r, 28); /*  15 */
-    D_ENCRYPT(r, l, 30); /*  16 */
+    D_ENCRYPT(ks, l, r, 0);
+    D_ENCRYPT(ks, r, l, 1);
+    D_ENCRYPT(ks, l, r, 2);
+    D_ENCRYPT(ks, r, l, 3);
+    D_ENCRYPT(ks, l, r, 4);
+    D_ENCRYPT(ks, r, l, 5);
+    D_ENCRYPT(ks, l, r, 6);
+    D_ENCRYPT(ks, r, l, 7);
+    D_ENCRYPT(ks, l, r, 8);
+    D_ENCRYPT(ks, r, l, 9);
+    D_ENCRYPT(ks, l, r, 10);
+    D_ENCRYPT(ks, r, l, 11);
+    D_ENCRYPT(ks, l, r, 12);
+    D_ENCRYPT(ks, r, l, 13);
+    D_ENCRYPT(ks, l, r, 14);
+    D_ENCRYPT(ks, r, l, 15);
   } else {
-    D_ENCRYPT(l, r, 30); /* 16 */
-    D_ENCRYPT(r, l, 28); /* 15 */
-    D_ENCRYPT(l, r, 26); /* 14 */
-    D_ENCRYPT(r, l, 24); /* 13 */
-    D_ENCRYPT(l, r, 22); /* 12 */
-    D_ENCRYPT(r, l, 20); /* 11 */
-    D_ENCRYPT(l, r, 18); /* 10 */
-    D_ENCRYPT(r, l, 16); /*  9 */
-    D_ENCRYPT(l, r, 14); /*  8 */
-    D_ENCRYPT(r, l, 12); /*  7 */
-    D_ENCRYPT(l, r, 10); /*  6 */
-    D_ENCRYPT(r, l, 8);  /*  5 */
-    D_ENCRYPT(l, r, 6);  /*  4 */
-    D_ENCRYPT(r, l, 4);  /*  3 */
-    D_ENCRYPT(l, r, 2);  /*  2 */
-    D_ENCRYPT(r, l, 0);  /*  1 */
+    D_ENCRYPT(ks, l, r, 15);
+    D_ENCRYPT(ks, r, l, 14);
+    D_ENCRYPT(ks, l, r, 13);
+    D_ENCRYPT(ks, r, l, 12);
+    D_ENCRYPT(ks, l, r, 11);
+    D_ENCRYPT(ks, r, l, 10);
+    D_ENCRYPT(ks, l, r, 9);
+    D_ENCRYPT(ks, r, l, 8);
+    D_ENCRYPT(ks, l, r, 7);
+    D_ENCRYPT(ks, r, l, 6);
+    D_ENCRYPT(ks, l, r, 5);
+    D_ENCRYPT(ks, r, l, 4);
+    D_ENCRYPT(ks, l, r, 3);
+    D_ENCRYPT(ks, r, l, 2);
+    D_ENCRYPT(ks, l, r, 1);
+    D_ENCRYPT(ks, r, l, 0);
   }
   /* rotate and clear the top bits on machines with 8byte longs */
   data[0] = ROTATE(l, 3) & 0xffffffffL;
diff --git a/crypto/des/internal.h b/crypto/des/internal.h
index d3a5cec..91559ff 100644
--- a/crypto/des/internal.h
+++ b/crypto/des/internal.h
@@ -183,13 +183,13 @@
     PERM_OP(l, r, tt, 4, 0x0f0f0f0fL);  \
   }
 
-#define LOAD_DATA(R, S, u, t, E0, E1) \
-  u = R ^ s[S];                            \
-  t = R ^ s[S + 1]
+#define LOAD_DATA(ks, R, S, u, t, E0, E1) \
+  u = R ^ ks->subkeys[S][0];              \
+  t = R ^ ks->subkeys[S][1]
 
-#define D_ENCRYPT(LL, R, S)                                                    \
+#define D_ENCRYPT(ks, LL, R, S)                                                \
   {                                                                            \
-    LOAD_DATA(R, S, u, t, E0, E1);                                             \
+    LOAD_DATA(ks, R, S, u, t, E0, E1);                                         \
     t = ROTATE(t, 4);                                                          \
     LL ^=                                                                      \
         DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
diff --git a/include/openssl/des.h b/include/openssl/des.h
index 25a7468..f9db62d 100644
--- a/include/openssl/des.h
+++ b/include/openssl/des.h
@@ -72,12 +72,7 @@
 } DES_cblock;
 
 typedef struct DES_ks {
-  union {
-    DES_cblock cblock;
-    /* make sure things are correct size on machines with
-     * 8 byte longs */
-    uint32_t deslong[2];
-  } ks[16];
+  uint32_t subkeys[16][2];
 } DES_key_schedule;