00001
00028
00029 #include "xtea.h"
00030
00031
00032 #define STORE32L(x, y) \
00033 do { \
00034 (y)[3] = (uint8_t)(((x)>>24)&255); \
00035 (y)[2] = (uint8_t)(((x)>>16)&255); \
00036 (y)[1] = (uint8_t)(((x)>>8)&255); \
00037 (y)[0] = (uint8_t)((x)&255); \
00038 } while (0)
00039
00040 #define LOAD32L(x, y) \
00041 do { \
00042 (x) = ((uint32_t)((y)[3] & 255)<<24) | \
00043 ((uint32_t)((y)[2] & 255)<<16) | \
00044 ((uint32_t)((y)[1] & 255)<<8) | \
00045 ((uint32_t)((y)[0] & 255)); \
00046 } while (0)
00047
00048
00049
00050 static void xtea_encrypt(const uint8_t *pt, uint8_t *ct, XteaStateKey_T *skey);
00051
00052
00053
00054
00055 void XteaSetup(const uint8_t *key, const uint8_t *iv, XteaStateKey_T *skey)
00056 {
00057 uint32_t x;
00058 uint32_t sum;
00059 uint32_t K[4];
00060
00061
00062
00063
00064 for(x = 0; x < XTEA_BLOCKLEN; x++)
00065 {
00066 if (iv)
00067 {
00068 skey->IV[x] = iv[x];
00069 }
00070 else
00071 {
00072 skey->IV[x] = x;
00073 }
00074 }
00075
00076
00077 LOAD32L(K[0], key+0);
00078 LOAD32L(K[1], key+4);
00079 LOAD32L(K[2], key+8);
00080 LOAD32L(K[3], key+12);
00081
00082 sum = 0;
00083 for (x = 0; x < 32; x++)
00084 {
00085 skey->A[x] = sum + K[sum & 3U];
00086 sum = sum + 0x9E3779B9UL;
00087 skey->B[x] = sum + K[(sum>>11) & 3U];
00088 }
00089
00090 XteaRestart(skey);
00091 }
00092
00093
00094
00095
00096 void XteaRestart(XteaStateKey_T *skey)
00097 {
00098 uint32_t x;
00099
00100
00101
00102 for(x = 0; x < XTEA_BLOCKLEN; x++)
00103 {
00104 skey->pad[x] = skey->IV[x];
00105 }
00106
00107 skey->padlen = XTEA_BLOCKLEN;
00108 }
00109
00110
00111
00112
00113 void XteaEncrypt(const uint8_t *pt, uint8_t *ct, uint32_t len, XteaStateKey_T *skey)
00114 {
00115 while (len)
00116 {
00117
00118
00119
00120
00121 if (XTEA_BLOCKLEN == skey->padlen)
00122 {
00123 xtea_encrypt(skey->pad, skey->pad, skey);
00124 skey->padlen = 0;
00125 }
00126 *ct++ = *pt++ ^ skey->pad[skey->padlen++];
00127 len--;
00128 }
00129 }
00130
00131
00132
00133 void XteaDecrypt(const uint8_t *ct, uint8_t *pt, uint32_t len, XteaStateKey_T *skey)
00134 {
00135 XteaEncrypt(ct, pt, len, skey);
00136 }
00137
00138
00139
00140
00141 static void xtea_encrypt(const uint8_t *pt, uint8_t *ct, XteaStateKey_T *skey)
00142 {
00143 uint32_t y;
00144 uint32_t z;
00145 uint32_t r;
00146
00147 LOAD32L(y, &pt[0]);
00148 LOAD32L(z, &pt[4]);
00149
00150 for (r = 0; r < 32; r += 4)
00151 {
00152 y = y + ((((z<<4)^(z>>5)) + z) ^ skey->A[r]);
00153 z = z + ((((y<<4)^(y>>5)) + y) ^ skey->B[r]);
00154
00155 y = y + ((((z<<4)^(z>>5)) + z) ^ skey->A[r+1]);
00156 z = z + ((((y<<4)^(y>>5)) + y) ^ skey->B[r+1]);
00157
00158 y = y + ((((z<<4)^(z>>5)) + z) ^ skey->A[r+2]);
00159 z = z + ((((y<<4)^(y>>5)) + y) ^ skey->B[r+2]);
00160
00161 y = y + ((((z<<4)^(z>>5)) + z) ^ skey->A[r+3]);
00162 z = z + ((((y<<4)^(y>>5)) + y) ^ skey->B[r+3]);
00163 }
00164
00165 STORE32L(y, &ct[0]);
00166 STORE32L(z, &ct[4]);
00167 }