AES Encryption

Port of Rijndael Block Cipher to Symbian OS

Introduction

The US National Institute of Standards and Technology selected the Rijndael block cipher as Advanced Encryption Standard (AES). Rijndael is free and a reference implementation is available.

This port to Symbian OS is based on the reference implementation v2.2 which is provided by the IAIK Krypto Group AES Lounge. My code is derived directly from the original C implementation and I documented every modification to maintain the reliability. I mostly replaced types or added const modifiers. Additionally I put everything into the namespace aes to avoid polluting the global namespace.

Rijndael Symbian OS Interface

#include "rijndael-alg-symbianos.h"


namespace aes {


/* Modes */
#define  DIR_ENCRYPT  0  // Encrypting?
#define  DIR_DECRYPT  1  // Decrypting?
#define  MODE_ECB     1  // Ciphering in ECB?
#define  MODE_CBC     2  // Ciphering in CBC?
#define  MODE_CFB1    3  // Ciphering in 1-bit CFB?


/* Block Size */
#define  BITSPERBLOCK 128  // Bits in a cipher block


/* Error Codes */
#define  BAD_KEY_DIR  -1  // Key direction is invalid
#define  BAD_KEY_MAT  -2  // Key not of correct length
#define  BAD_KEY_INSTANCE -3  // Key is not valid
#define  BAD_CIPHER_MODE  -4  // Cipher instance invalid
#define  BAD_CIPHER_STATE -5  // Cipher in wrong state
#define  BAD_CIPHER_INSTANCE -7


/* Keys */
#define  MAX_KEY_SIZE 64  // # of ASCII char's of a key
#define  MAX_IV_SIZE  BITSPERBLOCK/8  // # bytes of an IV


/* The structure for key information */
typedef struct {
  TUint8  direction;    // Encrypting or decrypting?
  TInt    keyLen;       // Length of the key
  TText8  keyMaterial[MAX_KEY_SIZE+1];  // Raw key
  TInt    blockLen;     // Block Length
  word8   keySched[MAXROUNDS+1][4][MAXBC];       
} keyInstance;


/* The structure for cipher information */
typedef struct {
  TUint8  mode;    // MODE_ECB, MODE_CBC, or MODE_CFB1
  TUint8  IV[MAX_IV_SIZE]; // Initialization vector
  TInt    blockLen;  
} cipherInstance;


/* ********* */
/* Functions */
/* ********* */

TInt makeKey(keyInstance *key,
             TUint8 direction,
             TInt keyLen,
             const TText8 *keyMaterial);

TInt cipherInit(cipherInstance *cipher,
                TUint8 mode,
                const TText8 *IV);

TInt blockEncrypt(const cipherInstance *cipher,
                  keyInstance *key,
                  TUint8 *input,
                  TInt inputLen,
                  TUint8 *outBuffer);

TInt blockDecrypt(const cipherInstance *cipher,
                  keyInstance *key,
                  TUint8 *input,
                  TInt inputLen,
                  TUint8 *outBuffer);
                       
TInt cipherUpdateRounds(const cipherInstance *cipher,
                        keyInstance *key,
                        TUint8 *input,
                        TInt inputLen,
                        TUint8 *outBuffer,
                        TInt Rounds);

} // namespace aes

Working with Rijndael

The following section shows the usage of the Rijndael interface. I omitted error handling for clarity.

// Secret message (which fits exactly in one block)
_LIT8(KMySecret, "Hello world!!!!!");  
TBuf8<128> secret(KMySecret);


//
// Init stuff
TUint8 block[4*MAXBC];
TPtr8 blockPtr(block, BITSPERBLOCK/8);
aes::keyInstance keyInst;
aes::cipherInstance cipherInst;


//
// Generate key instance for encryption.
// The secret key material is an hex string
// with a length of keyLen/4 bytes.
TInt keyLen = 128;
TText8* secretKeyMaterial =
         (TText8*) "E5E6E7E9EA292A2B2D256789012345E5";
keyInst.blockLen = BITSPERBLOCK;
aes::makeKey(&keyInst, DIR_ENCRYPT,
             keyLen, secretKeyMaterial);


//
// Init cipher instance
cipherInst.blockLen = BITSPERBLOCK;
aes::cipherInit(&cipherInst, MODE_ECB, NULL);

   
//
// Encrypt block
// Fill block with our secret message
blockPtr.Append(secret.Ptr(), BITSPERBLOCK/8);
aes::blockEncrypt(&cipherInst, &keyInst,
                  block, BITSPERBLOCK, block);
TBuf8<BITSPERBLOCK/8> cipherText;
cipherText.Append(blockPtr);
blockPtr.Zero();


//
// cipherText contains the encrypted secret


//
// Generate key instance for decryption
keyInst.blockLen = BITSPERBLOCK;
aes::makeKey(&keyInst, DIR_DECRYPT,
             keyLen, secretKeyMaterial);

 
//
// Init cipher instance
cipherInst.blockLen = BITSPERBLOCK;
aes::cipherInit(&cipherInst, MODE_ECB, NULL);


//
// Decrypt block
blockPtr.Append(cipherText.Ptr(), BITSPERBLOCK/8);
aes::blockDecrypt(&cipherInst, &keyInst,
                  block, BITSPERBLOCK, block);
TBuf8<BITSPERBLOCK/8> decryptedText;
decryptedText.Append(blockPtr);


//
// decryptedText contains "Hello world!!!!!"


Have fun,

Philipp

Software Engineer at bit-side [1]

Download

rijndael-api-symbianos-2005-05-17.zip
rijndael-api-symbianos-2005-05-17.zip

[1]  bit-side is a world wide operating creative engineering company providing mobile enterprise solutions, innovative mobile media applications and mobile games to clients from the Americas to Asia.


AES Encryption

Hello Philipp, I got a problem when I encrypt message less than blocklen: the decrypted message contains "extra" weird string.

// Secret message (which fits less than one block)

_LIT8(KMySecret, "Hello"); // 5 byte message

...

...

// decryptedText contains "Hello╠╠╠╠╠╠╠╠╠╠╠"

//(Hello+0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc)

AES Encryption

It looks like the internal block buffer is initialized with 0xCC. :-) That's a problem with block ciphers in principle. You have to append some padding bytes to your string to create exactly string which length is a multiple of the block size. In case you are encrypting a string a simple solution would be to append some spaces. Please note that a arbitrary padding may introduce some security issues...

AES Encryption

Can some one please post a example how to call these AES API's from symbian OS c++ code. I am new to symbian c++. I would grately appreciate your help.

AES Encryption

Hi. I use The AES version for Symbian. If I encrypt or decrypt a message by means of the proposed API, after I don't succeed to decrypt or encrypt the message by means of another implementation. Could someone help me? Thanks in advance.

AES Encryption

Could someone explain: Why in example keylen is given 128 bits = 16 bytes but key is constant of key material is 32 bytes?

AES Encryption

The Rijndael example works fine for me when used as a standard application on e.g. a Nokia 5500. However, when I try to access the code as a Python extension, I get the compiler error: 'declaration syntax error' near

typedef TUint8 BYTE;

in the rijndael-api-symbianos.h file. Do anyone know why?

Thanks in advance!

Re: AES Encryption

Is this a good AES implementation?

Or there is a better Symbian one?

Re: AES Encryption


i encrypted data following the example but failed to decrypt the encrypted data on the server side.

my server side works with bouncycastle's AES implementation

regards

Re: AES Encryption

Hi danielwang99

my problem is same as your problem.i m also trying to decrypt my data on server side but its not working for me;while i m decrypting it in same class, without any error i did it.can u help me if u have the solution for this problem.

Thanx in advance

Best Regards

Mobile_f

Re: AES Encryption

Hi everybody,
I'm trying to use this implementation, but I have some problems... I open a file and then I read the data from it in a TBuf8 buffer but I can't convert this butter in an TUint8*. My code:

                while(posizione != dimInput){
                        err = input.Read(posizione,letto);
                        letto2 = letto.Ptr();
                        out_be = aes::blockEncrypt(&pluto,&pippo, letto2, 1024, scritto2);
                        scritto.Copy(scritto2, 1024);
                        output.Write(scritto);
                        posizione = posizione + letto.Size();
                        console->Printf(_L("%d\n"),posizione);
                }

where input and output are RFile object, scritto and letto TBuf8
Someone can help me?

Thanks in advance
Giuseppe