You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
6.0KB

  1. /*
  2. * A 32-bit implementation of the XTEA algorithm
  3. * Copyright (c) 2012 Samuel Pitoiset
  4. *
  5. * loosely based on the implementation of David Wheeler and Roger Needham
  6. *
  7. * This file is part of Libav.
  8. *
  9. * Libav is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * Libav is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with Libav; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. /**
  24. * @file
  25. * @brief XTEA 32-bit implementation
  26. * @author Samuel Pitoiset
  27. * @ingroup lavu_xtea
  28. */
  29. #include "avutil.h"
  30. #include "common.h"
  31. #include "intreadwrite.h"
  32. #include "mem.h"
  33. #include "xtea.h"
  34. #if !FF_API_CRYPTO_CONTEXT
  35. struct AVXTEA {
  36. uint32_t key[16];
  37. };
  38. #endif
  39. AVXTEA *av_xtea_alloc(void)
  40. {
  41. return av_mallocz(sizeof(struct AVXTEA));
  42. }
  43. void av_xtea_init(AVXTEA *ctx, const uint8_t key[16])
  44. {
  45. int i;
  46. for (i = 0; i < 4; i++)
  47. ctx->key[i] = AV_RB32(key + (i << 2));
  48. }
  49. static void xtea_crypt_ecb(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
  50. int decrypt, uint8_t *iv)
  51. {
  52. uint32_t v0, v1;
  53. int i;
  54. v0 = AV_RB32(src);
  55. v1 = AV_RB32(src + 4);
  56. if (decrypt) {
  57. uint32_t delta = 0x9E3779B9, sum = delta * 32;
  58. for (i = 0; i < 32; i++) {
  59. v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
  60. sum -= delta;
  61. v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
  62. }
  63. if (iv) {
  64. v0 ^= AV_RB32(iv);
  65. v1 ^= AV_RB32(iv + 4);
  66. memcpy(iv, src, 8);
  67. }
  68. } else {
  69. uint32_t sum = 0, delta = 0x9E3779B9;
  70. for (i = 0; i < 32; i++) {
  71. v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
  72. sum += delta;
  73. v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
  74. }
  75. }
  76. AV_WB32(dst, v0);
  77. AV_WB32(dst + 4, v1);
  78. }
  79. void av_xtea_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count,
  80. uint8_t *iv, int decrypt)
  81. {
  82. int i;
  83. if (decrypt) {
  84. while (count--) {
  85. xtea_crypt_ecb(ctx, dst, src, decrypt, iv);
  86. src += 8;
  87. dst += 8;
  88. }
  89. } else {
  90. while (count--) {
  91. if (iv) {
  92. for (i = 0; i < 8; i++)
  93. dst[i] = src[i] ^ iv[i];
  94. xtea_crypt_ecb(ctx, dst, dst, decrypt, NULL);
  95. memcpy(iv, dst, 8);
  96. } else {
  97. xtea_crypt_ecb(ctx, dst, src, decrypt, NULL);
  98. }
  99. src += 8;
  100. dst += 8;
  101. }
  102. }
  103. }
  104. #ifdef TEST
  105. #include <stdio.h>
  106. #define XTEA_NUM_TESTS 6
  107. static const uint8_t xtea_test_key[XTEA_NUM_TESTS][16] = {
  108. { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  109. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
  110. { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  111. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
  112. { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  113. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
  114. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  115. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  116. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  117. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
  118. { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  119. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
  120. };
  121. static const uint8_t xtea_test_pt[XTEA_NUM_TESTS][8] = {
  122. { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
  123. { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
  124. { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
  125. { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
  126. { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
  127. { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
  128. };
  129. static const uint8_t xtea_test_ct[XTEA_NUM_TESTS][8] = {
  130. { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
  131. { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
  132. { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
  133. { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
  134. { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
  135. { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
  136. };
  137. static void test_xtea(AVXTEA *ctx, uint8_t *dst, const uint8_t *src,
  138. const uint8_t *ref, int len, uint8_t *iv, int dir,
  139. const char *test)
  140. {
  141. av_xtea_crypt(ctx, dst, src, len, iv, dir);
  142. if (memcmp(dst, ref, 8*len)) {
  143. int i;
  144. printf("%s failed\ngot ", test);
  145. for (i = 0; i < 8*len; i++)
  146. printf("%02x ", dst[i]);
  147. printf("\nexpected ");
  148. for (i = 0; i < 8*len; i++)
  149. printf("%02x ", ref[i]);
  150. printf("\n");
  151. exit(1);
  152. }
  153. }
  154. int main(void)
  155. {
  156. AVXTEA ctx;
  157. uint8_t buf[8], iv[8];
  158. int i;
  159. const uint8_t src[32] = "HelloWorldHelloWorldHelloWorld";
  160. uint8_t ct[32];
  161. uint8_t pl[32];
  162. for (i = 0; i < XTEA_NUM_TESTS; i++) {
  163. av_xtea_init(&ctx, xtea_test_key[i]);
  164. test_xtea(&ctx, buf, xtea_test_pt[i], xtea_test_ct[i], 1, NULL, 0, "encryption");
  165. test_xtea(&ctx, buf, xtea_test_ct[i], xtea_test_pt[i], 1, NULL, 1, "decryption");
  166. /* encrypt */
  167. memcpy(iv, "HALLO123", 8);
  168. av_xtea_crypt(&ctx, ct, src, 4, iv, 0);
  169. /* decrypt into pl */
  170. memcpy(iv, "HALLO123", 8);
  171. test_xtea(&ctx, pl, ct, src, 4, iv, 1, "CBC decryption");
  172. memcpy(iv, "HALLO123", 8);
  173. test_xtea(&ctx, ct, ct, src, 4, iv, 1, "CBC inplace decryption");
  174. }
  175. printf("Test encryption/decryption success.\n");
  176. return 0;
  177. }
  178. #endif