Inline AES 256 / CBC Implementation

published: April 14, 2019 — last modified: October 23, 2025

Today I like to share some encryption code, which can be used in various situations - and is also useful for embedded systems.

It is a unique implementation of the AES 256 / CBC crypto algorithm. The goal of this implementation was neither speed nor size. It was written to inline it into existing code.

The compiler will create a new instance of the algorithm on the fly, at the place where you insert it into the code. Depending of used optimization flags, this inlined code can get very compact.

Goals

I had numerous goals and constraints while I created this implementation:

  • Completely inline.
  • Generated by the compiler on the fly.
  • Easy to read and understand.
  • Suitable for embedded processors.
  • No static tables (S-Box) in memory or the binary.
  • Minimal dependencies (just stdint and cstddef headers).).
  • Compatible with other AES 256 / CBC implementation.

The following things were not relevant to me:

  • Speed
  • Size
  • Multiple algorithms
  • Error checking of inputs

Requirements and Usage

The requirements are very minimal, all what you need is a C++17 compatible compiler which provides the stdint and cstddef headers for the uint32_t types and the size_t type.

Using the code is very simple because you just add an include to it:

#include "../InlineAES256/CBC.hpp"

#include <iostream>
#include <iomanip>
#include <string>


using namespace lrcrypto;


void hexBlock(const uint8_t *data, size_t size) {
    for (size_t i = 0; i < size; ++i) {
        std::cout << std::internal << std::setw(2) << std::setfill('0')
            << std::hex << static_cast<int>(data[i]);
        std::cout << " ";
    }
    std::cout << std::endl;
}


int main(int argc, const char * argv[]) {
	// Do _not_ store your key in a real application!
    const uint8_t key[aes256::cKeySizeBytes] = {
        0x4e, 0x89, 0x5a, 0xb7, 0xaf, 0x3d, 0xf6, 0xcf,
        0x6d, 0x22, 0x86, 0x01, 0x32, 0x0a, 0x8a, 0xa7,
        0x7b, 0x61, 0x2d, 0xdc, 0x92, 0xe0, 0xc9, 0x8a,
        0xd2, 0x43, 0x43, 0xb9, 0x35, 0x57, 0xad, 0x80
    };
    // Do _not_ use a static IV in a real application!
    const uint8_t iv[aes256::cBlockSizeBytes] = {
        0x44, 0xa9, 0x48, 0x66, 0x3d, 0xb9, 0x92, 0xb8,
        0x2b, 0xe7, 0xd5, 0xed, 0xf0, 0x6d, 0x71, 0x4d
    };
    // The buffer size has to be a multiple of the block size
    // which is 16 bytes.
    const int bufferSize = (aes256::cBlockSizeBytes * 4);
    uint8_t buffer[bufferSize];
    std::memset(buffer, 0, bufferSize);
    std::strcpy(reinterpret_cast<char*>(buffer), "Hello World!");
    std::cout << "Original: " << buffer << std::endl;
    hexBlock(buffer, bufferSize);
    aes256::SubstitutionBox box;
    box.initialize();
    aes256::encryptDataCBC(box, buffer, bufferSize, key, iv);
    std::cout << "Encrypted..." << std::endl;
    hexBlock(buffer, bufferSize);
    aes256::decryptDataCBC(box, buffer, bufferSize, key, iv);
    std::cout << "Decrypted: " << buffer << std::endl;
    hexBlock(buffer, bufferSize);
    return 0;
}

Source and License

I license the source using a very permissive MIT license. You can find it on GitHub:

https://github.com/LuckyResistor/InlineAES256CBC

If you have questions, miss some information or just have any feedback, feel free to add a comment below.

Have fun!

More Posts

New Additions to the Storage Box System

Posted on 2023-10-17— 3D Printing

I've added a batch of new divider layouts across my storage box system — regular, flat, tall, triple and extended series — based on your feedback. I've updated documentation and uploads; downloads are available on the new platform. Please take a look and read the full post for details and download links.

Read this post

Rail Grid Alternatives and More Interesting Updates

Posted on 2022-12-08— 3D Printing, Projects

I published a detailed update to my stackable storage boxes project that adds new rail grid series, larger sizes up to 9×9, and improved catalogues. I outline design reasoning, alternative part-number placement, image and archive changes. If this sounds useful, please read the full post for downloads and printing notes.

Read this post

Using the TDA 7052 as Amplifier

Posted on 2014-11-08— Projects

I swapped my LM386 for an NXP TDA7052 to reduce distortion and gain more volume. The TDA7052 needs only power, an input and connects to an 8Ω speaker; I added a volume trimmer (I used 47k, 10k also works). Read the full post for the schematic and wiring details.

Read this post

Event-Based Firmware (Part 2/2)

Posted on 2019-07-08— C++, Improve your Code, Learn

I guide you through evolving a simple Arduino blink example into a reusable event system. In Part 2 I cover function-pointer events, an EventLoop module, and practical multi-event examples. If you want cleaner, non-blocking firmware structure, read the full post for code and explanations.

Read this post

Boldport "The Cuttle" Arrived

Posted on 2016-08-17— Fun

My new Boldport Club project, "The Cuttle," arrived today — a minimal ATMega328-PU board shaped like a cuttlefish. Soldering was straightforward; I photographed each stage and made a short video of a simple LED effect. Read on if you'd like photos, the code, and a closer look.

Read this post

Perfect Prototype Boards from Eurocircuits

Posted on 2017-10-02— Projects

I received prototype boards from Eurocircuits and was impressed by their outstanding build quality—sharp solder-mask edges, precise alignment, and a subtle shine on the traces. I share close-up photos and brief thoughts about vias and finishes; read on if you appreciate careful PCB craftsmanship.

Read this post