x86inc: Enable AVX emulation for floating-point pseudo-instructions
[ffmpeg.git] / libavutil / xtea.c
index 1c2bd04..f7892af 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/intreadwrite.h"
+/**
+ * @file
+ * @brief XTEA 32-bit implementation
+ * @author Samuel Pitoiset
+ * @ingroup lavu_xtea
+ */
 
 #include "avutil.h"
 #include "common.h"
+#include "intreadwrite.h"
+#include "mem.h"
 #include "xtea.h"
 
+AVXTEA *av_xtea_alloc(void)
+{
+    return av_mallocz(sizeof(struct AVXTEA));
+}
+
 void av_xtea_init(AVXTEA *ctx, const uint8_t key[16])
 {
     int i;
@@ -35,14 +47,24 @@ void av_xtea_init(AVXTEA *ctx, const uint8_t key[16])
         ctx->key[i] = AV_RB32(key + (i << 2));
 }
 
+void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16])
+{
+    int i;
+
+    for (i = 0; i < 4; i++)
+        ctx->key[i] = AV_RL32(key + (i << 2));
+}
+
 static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
                            int decrypt, uint8_t *iv)
 {
     uint32_t v0, v1;
+#if !CONFIG_SMALL
     uint32_t k0 = ctx->key[0];
     uint32_t k1 = ctx->key[1];
     uint32_t k2 = ctx->key[2];
     uint32_t k3 = ctx->key[3];
+#endif
 
     v0 = AV_RB32(src);
     v1 = AV_RB32(src + 4);
@@ -50,7 +72,7 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
     if (decrypt) {
 #if CONFIG_SMALL
         int i;
-        uint32_t delta = 0x9E3779B9, sum = delta * 32;
+        uint32_t delta = 0x9E3779B9U, sum = delta * 32;
 
         for (i = 0; i < 32; i++) {
             v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
@@ -60,7 +82,7 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
 #else
 #define DSTEP(SUM, K0, K1) \
             v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + K0); \
-            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM - 0x9E3779B9 + K1)
+            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM - 0x9E3779B9U + K1)
 
         DSTEP(0xC6EF3720U, k2, k3);
         DSTEP(0x28B7BD67U, k3, k2);
@@ -96,14 +118,14 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
         DSTEP(0x9E3779B9U, k3, k0);
 #endif
         if (iv) {
-            v0 ^= AV_RB32(iv  );
-            v1 ^= AV_RB32(iv+4);
+            v0 ^= AV_RB32(iv);
+            v1 ^= AV_RB32(iv + 4);
             memcpy(iv, src, 8);
         }
     } else {
 #if CONFIG_SMALL
         int i;
-        uint32_t sum = 0, delta = 0x9E3779B9;
+        uint32_t sum = 0, delta = 0x9E3779B9U;
 
         for (i = 0; i < 32; i++) {
             v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
@@ -113,7 +135,7 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
 #else
 #define ESTEP(SUM, K0, K1) \
             v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM + K0);\
-            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + 0x9E3779B9 + K1)
+            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + 0x9E3779B9U + K1)
         ESTEP(0x00000000U, k0, k3);
         ESTEP(0x9E3779B9U, k1, k2);
         ESTEP(0x3C6EF372U, k2, k1);
@@ -153,14 +175,51 @@ static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
     AV_WB32(dst + 4, v1);
 }
 
-void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
-                   uint8_t *iv, int decrypt)
+static void xtea_le_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
+                              int decrypt, uint8_t *iv)
+{
+    uint32_t v0, v1;
+    int i;
+
+    v0 = AV_RL32(src);
+    v1 = AV_RL32(src + 4);
+
+    if (decrypt) {
+        uint32_t delta = 0x9E3779B9, sum = delta * 32;
+
+        for (i = 0; i < 32; i++) {
+            v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
+            sum -= delta;
+            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
+        }
+        if (iv) {
+            v0 ^= AV_RL32(iv);
+            v1 ^= AV_RL32(iv + 4);
+            memcpy(iv, src, 8);
+        }
+    } else {
+        uint32_t sum = 0, delta = 0x9E3779B9;
+
+        for (i = 0; i < 32; i++) {
+            v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
+            sum += delta;
+            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
+        }
+    }
+
+    AV_WL32(dst, v0);
+    AV_WL32(dst + 4, v1);
+}
+
+static void xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
+                       uint8_t *iv, int decrypt,
+                       void (*crypt)(AVXTEA *, uint8_t *, const uint8_t *, int, uint8_t *))
 {
     int i;
 
     if (decrypt) {
         while (count--) {
-            xtea_crypt_ecb(ctx, dst, src, decrypt, iv);
+            crypt(ctx, dst, src, decrypt, iv);
 
             src   += 8;
             dst   += 8;
@@ -170,10 +229,10 @@ void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
             if (iv) {
                 for (i = 0; i < 8; i++)
                     dst[i] = src[i] ^ iv[i];
-                xtea_crypt_ecb(ctx, dst, dst, decrypt, NULL);
+                crypt(ctx, dst, dst, decrypt, NULL);
                 memcpy(iv, dst, 8);
             } else {
-                xtea_crypt_ecb(ctx, dst, src, decrypt, NULL);
+                crypt(ctx, dst, src, decrypt, NULL);
             }
             src   += 8;
             dst   += 8;
@@ -181,82 +240,14 @@ void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
     }
 }
 
-#ifdef TEST
-#include <stdio.h>
-#undef printf
-
-#define XTEA_NUM_TESTS 6
-
-static const uint8_t xtea_test_key[XTEA_NUM_TESTS][16] = {
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-};
-
-static const uint8_t xtea_test_pt[XTEA_NUM_TESTS][8] = {
-    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
-    { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
-    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
-    { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
-};
-
-static const uint8_t xtea_test_ct[XTEA_NUM_TESTS][8] = {
-    { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
-    { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
-    { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
-    { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
-    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
-};
-
-int main(void)
+void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
+                   uint8_t *iv, int decrypt)
 {
-    AVXTEA ctx;
-    uint8_t buf[8], iv[8];
-    int i;
-    const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld";
-    uint8_t  ct[32];
-    uint8_t  pl[32];
-
-#define CHECK(dst, src, ref, len, iv, dir, error) \
-        av_xtea_crypt(&ctx, dst, src, len, iv, dir);\
-        if (memcmp(dst, ref, 8*len)) {\
-            printf(error);\
-            return 1;\
-        }
-
-    for (i = 0; i < XTEA_NUM_TESTS; i++) {
-        av_xtea_init(&ctx, xtea_test_key[i]);
-
-        CHECK(buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "Test encryption failed.\n");
-        CHECK(buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "Test decryption failed.\n");
-
-        /* encrypt */
-        memcpy(iv, "HALLO123", 8);
-        av_xtea_crypt(&ctx, ct, src, 4, iv, 0);
-
-        /* decrypt into pl */
-        memcpy(iv, "HALLO123", 8);
-        CHECK(pl, ct, src, 4, iv, 1, "Test IV decryption failed.\n");
-
-        memcpy(iv, "HALLO123", 8);
-        CHECK(ct, ct, src, 4, iv, 1, "Test IV inplace decryption failed.\n");
-    }
-
-    printf("Test encryption/decryption success.\n");
-
-    return 0;
+    xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_crypt_ecb);
 }
 
-#endif
+void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
+                      uint8_t *iv, int decrypt)
+{
+    xtea_crypt(ctx, dst, src, count, iv, decrypt, xtea_le_crypt_ecb);
+}