Click here to Skip to main content
15,867,594 members
Articles / Desktop Programming / MFC
Article

TEA Encryption/Decryption Made Simple

Rate me:
Please Sign up or sign in to vote.
4.60/5 (10 votes)
20 Dec 2008CPOL5 min read 105.9K   5.4K   50   28
Easy to use crypto class that uses TEA, XTEA and XXTEA standards
tea.jpg

Introduction

When we want to hide data for our user based on simple data types we could sometimes ask for a simple and straight forward approach - like a class, a lib or a DLL or something - not necessarily going into all kinds of details and crypto-theory for experts only. This is what this small project is all about. Using the one-and-only class in it CEncryptDecrypt, one will be able to encrypt and decrypt simple data types, say to- and from the registry in C.

Background

The basic ideas are held simple: I wanted to hide a PIN code in the registry to begin with in a safe manner. Just wanted to write the PIN down and reading it up again to a (another) program needing it. To do so, I first had to encrypt the value like "2416", then deliver it and then later do the opposite thing reading it back. I had no idea how to do so even "pretty" safe - so to begin with, I simply Googled the problem instead of going into drowning myself in an overwhelming crypto API that I did not understand and perhaps it turned out a little overkill. Soon I was lead to a series of articles, more or less linked, in Wikipedia (Wiki). Hence this code is based on Wiki knowledge and not a crypto API.

Also, downloading and reading this article, please keep in mind that I'm not in any way a crypto expert - not at all and just at the beginning - again; I just want to be able to do crypto things the simple way... and then ok perhaps some day go more into the theory and mathematics behind. For a discussion on these subjects, please follow the links I've added to the core methods in the class - this is: TEA, XTEA and XXTEA.

Using the Code

The class is based on three algorithms: The Tiny Encryption Algorithm (called TEA) and two extended and more safe versions of it called XTEA and XXTEA to think of as derivatives of the first.

Given below is a brief description of how to use the project and the code. From the outside, this is really simple - as I wanted it.

Build the project and run the dialog now. You are now enabled to encrypt/decrypt: int, TCHAR and CString - this is sufficient in its first version and for most enterprises. To encrypt an int, press "Encrypt int" and to have it back press "Decrypt int". Likewise for the other types. I'm well aware that there are people out there that can perhaps attack this encryption with their super computer and super brains but to obscure information for the average user, this should be enough - I hope. :-) Also the articles and the Internet are flooded with information about attack principles - interesting stuff but outside the scope of my article and a fast 95% and 'pretty safe' solution. Anyway nothing is good enough and 100%.

C++
//
// To create a CEncryptDecrypt instance.
//
m_pEncryptDecrypt = new CEncryptDecrypt();

This makes you access the simplest standard - TEA - by default.

C++
//
// To use another standard.
//
new CEncryptDecrypt(CEncryptDecrypt::eXTEA)
// or
new CEncryptDecrypt(CEncryptDecrypt::eXXTEA)

Or call m_pEncryptDecrypt->SetEncryptionStandard(CEncryptDecrypt::eXTEA) on the fly. To encrypt a value, you go:

C++
//
// To encrypt.
//
m_pEncryptDecrypt->Encrypt(456)
// or
m_pEncryptDecrypt->Encrypt('F')
// or
m_pEncryptDecrypt->Encrypt(CString(_T("Hey you."))).

While the objects are in its encrypted state, the values are held in a vector inside the class. The class then exposes methods to build a comma separated list from or to the vector. In that way, the vector can be wiped and later reconstructed and meanwhile stored in a file or in the registry. Going the other way and decrypting is - big surprise - likewise simple:

C++
//
// To decrypt.
//
int iVal = 0;
m_pEncryptDecrypt->Decrypt(iVal)
// or
TCHAR chVal = 0;
m_pEncryptDecrypt->Decrypt(chVal)
// or
CString cstrVal(_T(""));
m_pEncryptDecrypt->Decrypt(cstrVal)

That's it folks - crypto for dummies.

TEA in C

Keysize is 128 bits in TEA and XTEA and bigger in XXTEA (>= 4 WORDS of 32 bits). To make it work, you have to decide on a magic and arbitrary number as well - to understand how it works find: #define MAGIC_KEY 3594 in the implementation. This is more or less how Wiki defines the TEA routine:

C++
inline const void TEAEncrypt(const int iOffset)
// Core encryption method (TEA) inspired from
// http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm.
{
	ULONG ulSum = 0;
	ULONG ulVec[SIZE_OF_VEC_TEA] = { GetVec(iOffset + 0), GetVec(iOffset + 1) };
	for(register int iBit = 0; iBit < 32; iBit++)
	{
		ulSum += m_ulDelta;
		ulVec[0] += ((ulVec[1] << 4) + m_uKey[0]) ^
			(ulVec[1] + ulSum) ^ ((ulVec[1] >> 5) + m_uKey[1]);
		ulVec[1] += ((ulVec[0] << 4) + m_uKey[2]) ^
			(ulVec[0] + ulSum) ^ ((ulVec[0] >> 5) + m_uKey[3]);
	}
	SetVec(iOffset + 0, ulVec[0]);
	SetVec(iOffset + 1, ulVec[1]);
}
inline const void TEADecrypt(const int iOffset)
// Core decryption method (TEA) inspired from
// http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm.
{
	ULONG ulSum = 0xc6ef3720;
	ULONG ulVec[SIZE_OF_VEC_TEA] = { GetVec(iOffset + 0), GetVec(iOffset + 1) };
	for(register int iBit = 0; iBit < 32; iBit++)
	{
		ulVec[1] -= ((ulVec[0] << 4) + m_uKey[2]) ^
			(ulVec[0] + ulSum) ^ ((ulVec[0] >> 5) + m_uKey[3]);
		ulVec[0] -= ((ulVec[1] << 4) + m_uKey[0]) ^
			(ulVec[1] + ulSum) ^ ((ulVec[1] >> 5) + m_uKey[1]);
		ulSum -= m_ulDelta;
	}
	SetVec(iOffset + 0, ulVec[0]);
	SetVec(iOffset + 1, ulVec[1]);
}

As for the others, please see the implementation for details. The implementation of XXTEA are split in two and not one like Wiki suggested it. Exposed public methods for calling encrypt/decrypt logic are directing the call to the right method one level below based on an enum EEncryptDecryptStandard for what standard you want to deal with. Don't change the standard while encrypted! Always encrypt/decrypt using the same - like XTEA! To better understand the mechanism, please see TEA for a graphic display on what's going on at the operator level, etc. To speed up things a little, I'm working on a local counterpart of the part of the original class-owned vector in the core methods. So that's why I copy to an array before I do anything and afterwards from the array to the vector using the SetVec(...)/GetVec(...).

Points of Interest

This class can without any problems be converted into a C# class - all code is inlined. The project is in VC8.0 and should have been 9.0 - but my environment is not right now keen to let me build an MFC dialog from the wizard. But this is really not important. Please come up with ideas to improve the class. I don't say these algorithms are the best, but they are small and easy to implement. I think it would be easy to extend the class with more and even safer crypto-routines in the future. Wiki has a lot, it seems.

Problems and Ideas

I don't find the comma separated list exactly an elegant solution. Perhaps it's better to stream the vector to a file or some bit-stream? Hope you like it anyway.

History

  • 1.00: 08.12.08: Initial version
  • 1.10: 18.12.08: Replaced MFC CArray<T, T> with SLT vector<T> to loosen MFC dependence. New Encrypt(...)/Decrypt(...) methods work with char[].

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Denmark Denmark
c/c++/c# -developer.

Comments and Discussions

 
Questionfatal error C1859 Pin
mrhydn23-Sep-12 20:26
mrhydn23-Sep-12 20:26 
AnswerRe: fatal error C1859 Pin
Michael Pauli23-Sep-12 21:59
Michael Pauli23-Sep-12 21:59 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey29-Mar-12 20:17
professionalManoj Kumar Choubey29-Mar-12 20:17 
QuestionXXTea Pin
Jose A Pascoa11-Oct-11 6:06
Jose A Pascoa11-Oct-11 6:06 
QuestionFor VC 2003 ? Pin
MroMarcosKim15-Oct-10 10:29
MroMarcosKim15-Oct-10 10:29 
AnswerRe: For VC 2003 ? Pin
Michael Pauli23-Oct-10 3:18
Michael Pauli23-Oct-10 3:18 
Questionsrc Pin
BMW74025-Aug-10 0:42
BMW74025-Aug-10 0:42 
AnswerRe: src Pin
Michael Pauli25-Aug-10 2:11
Michael Pauli25-Aug-10 2:11 
GeneralRe: src Pin
BMW74025-Aug-10 2:14
BMW74025-Aug-10 2:14 
GeneralRe: src Pin
Michael Pauli25-Aug-10 3:17
Michael Pauli25-Aug-10 3:17 
GeneralGood information Pin
Dr.Luiji16-Dec-08 11:39
professionalDr.Luiji16-Dec-08 11:39 
GeneralRe: Good information Pin
Michael Pauli18-Dec-08 15:02
Michael Pauli18-Dec-08 15:02 
GeneralRe: Good information Pin
Dr.Luiji18-Dec-08 21:44
professionalDr.Luiji18-Dec-08 21:44 
GeneralGreat, the simplified approach is good enough for manu occasions Pin
Tage Lejon10-Dec-08 23:48
Tage Lejon10-Dec-08 23:48 
GeneralTwo improvements desired Pin
Tage Lejon11-Dec-08 2:27
Tage Lejon11-Dec-08 2:27 
GeneralGood ideas Pin
Michael Pauli11-Dec-08 3:24
Michael Pauli11-Dec-08 3:24 
GeneralRe: Good ideas Pin
Tage Lejon11-Dec-08 5:03
Tage Lejon11-Dec-08 5:03 
GeneralRe: Good ideas Pin
Michael Pauli12-Dec-08 3:06
Michael Pauli12-Dec-08 3:06 
QuestionWhen is simple good? Pin
supercat99-Dec-08 9:12
supercat99-Dec-08 9:12 
AnswerGood point Pin
Michael Pauli11-Dec-08 3:38
Michael Pauli11-Dec-08 3:38 
GeneralNice but.. Pin
Axel Rietschin8-Dec-08 13:45
professionalAxel Rietschin8-Dec-08 13:45 
GeneralRe: Nice but.. Pin
Michael Pauli8-Dec-08 14:24
Michael Pauli8-Dec-08 14:24 
GeneralRe: Nice but.. Pin
Axel Rietschin9-Dec-08 17:53
professionalAxel Rietschin9-Dec-08 17:53 
GeneralThe key is secret Pin
Michael Pauli11-Dec-08 3:43
Michael Pauli11-Dec-08 3:43 
GeneralRe: The key is secret Pin
Nnamdi Onyeyiri11-Dec-08 6:26
Nnamdi Onyeyiri11-Dec-08 6:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.