cbc128.c: fix strict aliasing warning.
[openssl.git] / crypto / modes / cbc128.c
index af844b6ac48a6ef8d4c76221a75dbe04447a93dc..34b2a2ef211fd09d85361c1e7bbf07e72f8b3d85 100644 (file)
@@ -48,7 +48,8 @@
  *
  */
 
-#include <stddef.h>
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
 #include <string.h>
 
 #ifndef MODES_DEBUG
 #endif
 #include <assert.h>
 
-#include "modes.h"
-
-#define STRICT_ALIGNMENT 1
-#if defined(__i386) || defined(__i386__) || \
-    defined(__x86_64) || defined(__x86_64__) || \
-    defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
-    defined(__s390__) || defined(__s390x__)
-#  undef STRICT_ALIGNMENT
+#ifndef STRICT_ALIGNMENT
 #  define STRICT_ALIGNMENT 0
 #endif
 
 void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
                        size_t len, const void *key,
-                       unsigned char ivec[16], block_f block)
+                       unsigned char ivec[16], block128_f block)
 {
        size_t n;
        const unsigned char *iv = ivec;
@@ -120,10 +114,10 @@ void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
 
 void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
                        size_t len, const void *key,
-                       unsigned char ivec[16], block_f block)
+                       unsigned char ivec[16], block128_f block)
 {
        size_t n;
-       union { size_t align; unsigned char c[16]; } tmp;
+       union { size_t t[16/sizeof(size_t)]; unsigned char c[16]; } tmp;
 
        assert(in && out && key && ivec);
 
@@ -171,19 +165,19 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
                                out += 16;
                        }
                }
-               else {
-                       size_t c;
+               else if (16%sizeof(size_t) == 0) { /* always true */
+                       size_t c, *out_t=(size_t *)out, *ivec_t=(size_t *)ivec;
+                       const size_t *in_t=(const size_t *)in;
                        while (len>=16) {
-                               (*block)(in, tmp.c, key);
-                               for(n=0; n<16; n+=sizeof(size_t)) {
-                                       c = *(size_t *)(in+n);
-                                       *(size_t *)(out+n) =
-                                       *(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
-                                       *(size_t *)(ivec+n) = c;
+                               (*block)((const unsigned char *)in_t, tmp.c, key);
+                               for(n=0; n<16/sizeof(size_t); n++) {
+                                       c = in_t[n];
+                                       out_t[n] = tmp.t[n] ^ ivec_t[n];
+                                       ivec_t[n] = c;
                                }
                                len -= 16;
-                               in  += 16;
-                               out += 16;
+                               in_t  += 16/sizeof(size_t);
+                               out_t += 16/sizeof(size_t);
                        }
                }
        }