Skip to content

Instantly share code, notes, and snippets.

@erev0s

erev0s/README.md

Last active Oct 16, 2020
Embed
What would you like to do?

Example of AES in CBC mode with PKCS7 padding using the tiny-AES implementation of kokke.

Files needed besides the test.c found below

Once you have all the files simply run make

This gist is part of an article about tiny AES written here https://erev0s.com/blog/tiny-aes-cbc-mode-pkcs7-padding-written-c/

Update 16/10/2020
  • As noted by Sarah there is a small bug in the code of pkcs7_padding.c. I have attached to this gist a corrected version of it. The line 41 is the only thing that was changed.
#include "pkcs7_padding.h"
int pkcs7_padding_pad_buffer( uint8_t *buffer, size_t data_length, size_t buffer_size, uint8_t modulus ){
uint8_t pad_byte = modulus - ( data_length % modulus ) ;
if( data_length + pad_byte > buffer_size ){
return -pad_byte;
}
int i = 0;
while( i < pad_byte){
buffer[data_length+i] = pad_byte;
i++;
}
return pad_byte;
}
int pkcs7_padding_valid( uint8_t *buffer, size_t data_length, size_t buffer_size, uint8_t modulus ){
uint8_t expected_pad_byte = modulus - ( data_length % modulus ) ;
if( data_length + expected_pad_byte > buffer_size ){
return 0;
}
int i = 0;
while( i < expected_pad_byte ){
if( buffer[data_length + i] != expected_pad_byte){
return 0;
}
i++;
}
return 1;
}
size_t pkcs7_padding_data_length( uint8_t * buffer, size_t buffer_size, uint8_t modulus ){
/* test for valid buffer size */
if( buffer_size % modulus != 0 ||
buffer_size < modulus ){
return 0;
}
uint8_t padding_value;
padding_value = buffer[buffer_size-1];
/* test for valid padding value */
if( padding_value < 1 || padding_value > modulus ){
return buffer_size;
}
/* buffer must be at least padding_value + 1 in size */
if( buffer_size < padding_value + 1 ){
return 0;
}
uint8_t count = 1;
buffer_size --;
for( ; count < padding_value ; count++){
buffer_size --;
if( buffer[buffer_size] != padding_value ){
return 0;
}
}
return buffer_size;
}
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define CBC 1
#include "aes.h"
#include "pkcs7_padding.c"
static void test_encrypt_cbc(void);
int main(void)
{
int exit=0;
#if defined(AES256)
printf("\nTesting AES256\n\n");
#elif defined(AES192)
printf("\nTesting AES192\n\n");
#elif defined(AES128)
printf("\nTesting AES128\n\n");
#else
printf("You need to specify a symbol between AES128, AES192 or AES256. Exiting");
return 0;
#endif
test_encrypt_cbc();
return exit;
}
static void test_encrypt_cbc(void)
{
//Initialization Vector
uint8_t iv[] = { 0x75, 0x52, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x21, 0x21 };
uint8_t i;
char* report = "my super secret thing that needs to remain that way!";
char* key = "thisIstheKey";
int dlen = strlen(report);
int klen = strlen(key);
printf("THE PLAIN TEXT STRING = ");
for (i=0; i<dlen;i++){
printf("%c", report[i]);
}
printf("\n");
//Proper Length of report
int dlenu = dlen;
if (dlen % 16) {
dlenu += 16 - (dlen % 16);
printf("The original length of the STRING = %d and the length of the padded STRING = %d\n", dlen, dlenu);
}
//Proper length of key
int klenu = klen;
if (klen % 16) {
klenu += 16 - (klen % 16);
printf("The original length of the KEY = %d and the length of the padded KEY = %d\n", klen, klenu);
}
// Make the uint8_t arrays
uint8_t hexarray[dlenu];
uint8_t kexarray[klenu];
// Initialize them with zeros
memset( hexarray, 0, dlenu );
memset( kexarray, 0, klenu );
// Fill the uint8_t arrays
for (int i=0;i<dlen;i++) {
hexarray[i] = (uint8_t)report[i];
}
for (int i=0;i<klen;i++) {
kexarray[i] = (uint8_t)key[i];
}
int reportPad = pkcs7_padding_pad_buffer( hexarray, dlen, sizeof(hexarray), 16 );
int keyPad = pkcs7_padding_pad_buffer( kexarray, klen, sizeof(kexarray), 16 );
printf("The padded STRING in hex is = ");
for (i=0; i<dlenu;i++){
printf("%02x",hexarray[i]);
}
printf("\n");
printf("The padded key in hex is = ");
for (i=0; i<klenu;i++){
printf("%02x",kexarray[i]);
}
printf("\n");
// In case you want to check if the padding is valid
int valid = pkcs7_padding_valid( hexarray, dlen, sizeof(hexarray), 16 );
int valid2 = pkcs7_padding_valid( kexarray, klen, sizeof(kexarray), 16 );
printf("Is the pkcs7 padding valid report = %d | key = %d\n", valid, valid2);
//start the encryption
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, kexarray, iv);
// encrypt
AES_CBC_encrypt_buffer(&ctx, hexarray, dlenu);
printf("the encrypted STRING = ");
for (i=0; i<dlenu;i++){
printf("%02x",hexarray[i]);
}
printf("\n");
// reset the iv !! important to work!
AES_ctx_set_iv(&ctx,iv);
// start decryption
AES_CBC_decrypt_buffer(&ctx, hexarray, dlenu);
size_t actualDataLength = pkcs7_padding_data_length( hexarray, dlenu, 16);
printf("The actual data length (without the padding) = %ld\n", actualDataLength);
printf("the decrypted STRING in hex = ");
for (i=0; i<actualDataLength;i++){
printf("%02x",hexarray[i]);
}
printf("\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.