TEA Cipher on ARM’s ISA

Tiny Encryption Algorithm (TEA) is a block cipher designed by R. Needham and D. Wheeler of the Cambridge Laboratory. TEA is notable for the simplicity of its structure and implementation, typically done with a few lines of code.

TEA uses a 128-bit key and operates on 64-bit data blocks. In its core operation, TEA follows a Feistel structure with suggested 32 loops. The key scheduling is very basic, mixing the key blocks exactly the same way in each round. Different multiplies with a standard contact (2654435769hex or 9E3779B9hex are preventing simple analysis attacks based on the symmetry of the rounds. In the figure at the right you can see two feistel rounds of the TEA algorithm in a block diagram.

TEA has a notably weakness that makes it inappropriate for high security applications. Each key is equivalent to three others, meaning that the effective key size is only 126 bits, making TEA a bad choice for cryptographic hash function (see hacking Microsoft’s 1st X-Box gaming console incident). Because of this weaknesses, XTEA has been designed to substitute TEA.

Despite the TEA’s weaknesses, it is a still a good choice for someone without deep cryptography knowledge that has low security needs for his/her implementation. I used the TEA cipher in home automation application that i implemented and i have wrote the code using ARM’s assembly instruction set. ARM’ has 32 bit ISA, so i implemented the data block by using two 32 memory blocks.

At the end of the post i also include the C code for the TEA cipher.

 

Download Assembly Source Code

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdint.h>;
 
void encrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                       /* basic cycle start */
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);  
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}
 
void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                         /* basic cycle start */
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;                                   
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}

 

 

A. Bechtsoudis