Microchip® Advanced Software Framework

Quick start guide for XMEGA DES driver

This is the quick start guide for the DES Driver, with step-by-step instructions on how to configure and use the driver for specific use cases.

The section described below can be compiled into e.g. the main application loop or any other function that might use the DES functionality.

Basic use case of the DES driver

In our basic use case, the DES driver is used to encrypt a 64 * 8 byte block of data with DES and 3DES encryption using a predefined key, and subsequently decrypt it. The DES driver does DES encryption and decryption on 64 bits of data at once, using a 64 bit key. 3DES encryption and decryption is done using three 64 bit keys. Therefore, the functions are called on 8 byte chunks of the code.

Prerequisites

There are no prerequisites for using this code.

Setup

There is no setup needed for this driver, all encryption/decryption functions can be used instantly.

Use case

Example code

#define DES_BLOCK_SIZE 8
#define DATA_BLOCKS 64
#define DATA_SIZE DATA_BLOCKS * DES_BLOCK_SIZE
uint8_t keys[DES_BLOCK_SIZE * 3] = {
0x94, 0x74, 0xB8, 0xE8, 0xC7, 0x3B, 0xCA, 0x7D,
0x28, 0x34, 0x76, 0xAB, 0x38, 0xCF, 0x37, 0xC2,
0xFE, 0x98, 0x6C, 0x38, 0x23, 0xFC, 0x2D, 0x23
};
uint16_t i;
uint8_t data[DATA_SIZE];
uint8_t encrypted_data_des[DATA_SIZE];
uint8_t encrypted_data_3des[DATA_SIZE];
uint8_t decrypted_data_des[DATA_SIZE];
uint8_t decrypted_data_3des[DATA_SIZE];
for (i = 0; i < DATA_SIZE; i++) {
data[i] = (uint8_t)i;
}
for (i = 0; i < DATA_BLOCKS; i++) {
uint8_t *current_data_block = (data + DES_BLOCK_SIZE * i);
uint8_t *current_des_enc_block =
(encrypted_data_des + DES_BLOCK_SIZE * i);
uint8_t *current_3des_enc_block =
(encrypted_data_3des + DES_BLOCK_SIZE * i);
des_encrypt(current_data_block, current_des_enc_block, keys);
des_3des_encrypt(current_data_block, current_3des_enc_block, keys);
}
for (i = 0; i < DATA_BLOCKS; i++) {
uint8_t *current_des_enc_block =
(encrypted_data_des + DES_BLOCK_SIZE * i);
uint8_t *current_3des_enc_block =
(encrypted_data_3des + DES_BLOCK_SIZE * i);
uint8_t *current_des_dec_block =
(decrypted_data_des + DES_BLOCK_SIZE * i);
uint8_t *current_3des_dec_block =
(decrypted_data_3des + DES_BLOCK_SIZE * i);
des_decrypt(current_des_enc_block, current_des_dec_block, keys);
des_3des_decrypt(current_3des_enc_block, current_3des_dec_block, keys);
}

Workflow

We first define the size of a DES block (8 bytes, 64 bits), the amount of data blocks we will use, and the total size of our data block:

#define DES_BLOCK_SIZE 8
#define DATA_BLOCKS 64
#define DATA_SIZE DATA_BLOCKS * DES_BLOCK_SIZE

The DES and 3DES functions require keys to be able to encrypt data, so we create three 64 bit (8 * 8 bit) keys for them to use:

uint8_t keys[DES_BLOCK_SIZE * 3] = {
0x94, 0x74, 0xB8, 0xE8, 0xC7, 0x3B, 0xCA, 0x7D,
0x28, 0x34, 0x76, 0xAB, 0x38, 0xCF, 0x37, 0xC2,
0xFE, 0x98, 0x6C, 0x38, 0x23, 0xFC, 0x2D, 0x23
};
Note
Only the first key is used for the DES routine.

We create a data block which we will encrypt, and destination blocks for the encrypted and decrypted data:

uint16_t i;
uint8_t data[DATA_SIZE];
uint8_t encrypted_data_des[DATA_SIZE];
uint8_t encrypted_data_3des[DATA_SIZE];
uint8_t decrypted_data_des[DATA_SIZE];
uint8_t decrypted_data_3des[DATA_SIZE];

We fill our data block with some data:

for (i = 0; i < DATA_SIZE; i++) {
data[i] = (uint8_t)i;
}

Now we will encrypt our data with both DES and 3DES encryption. The encrypted values will be stored in the variables encrypted_data_des and encrypted_data_3des. We loop through all the blocks:

for (i = 0; i < DATA_BLOCKS; i++) {

And create pointers to blocks currently being processed:

uint8_t *current_data_block = (data + DES_BLOCK_SIZE * i);
uint8_t *current_des_enc_block =
(encrypted_data_des + DES_BLOCK_SIZE * i);
uint8_t *current_3des_enc_block =
(encrypted_data_3des + DES_BLOCK_SIZE * i);

Finally we call des_encrypt() and des_3des_encrypt() on the data:

des_encrypt(current_data_block, current_des_enc_block, keys);
des_3des_encrypt(current_data_block, current_3des_enc_block, keys);
}
Note
Only the first key is used in the des_encrypt() function.

The encrypted data is now stored in the two variables. We will now decrypt the data in a similar fashion, storing the result in the variables decrypted_data_des and decrypted_data_3des.

Looping through the blocks:

for (i = 0; i < DATA_BLOCKS; i++) {

Pointing to the current blocks being processed:

uint8_t *current_des_enc_block =
(encrypted_data_des + DES_BLOCK_SIZE * i);
uint8_t *current_3des_enc_block =
(encrypted_data_3des + DES_BLOCK_SIZE * i);
uint8_t *current_des_dec_block =
(decrypted_data_des + DES_BLOCK_SIZE * i);
uint8_t *current_3des_dec_block =
(decrypted_data_3des + DES_BLOCK_SIZE * i);

And calling the decrypt functions:

des_decrypt(current_des_enc_block, current_des_dec_block, keys);
des_3des_decrypt(current_3des_enc_block, current_3des_dec_block, keys);
}