botan icon indicating copy to clipboard operation
botan copied to clipboard

AES sample ?

Open Ogromny opened this issue 8 years ago • 5 comments

Would it be possible for you to show a tiny AES sample ?

Thanks in advance ;)

Ogromny avatar Apr 13 '16 20:04 Ogromny

Not sure if it is almost corect code, but I used it for my pet project.

import botan.block.aes;
import botan.libstate.lookup;

const int AES256_KEY_LEN = 32;
const int AES256_BLOCK_LEN = 16;

ubyte[] encrypt_aes256_cbc_pkcs7(const ubyte[] key, const ubyte[] iv, const ubyte[] input)
{
    assert(key.length == AES256_KEY_LEN);
    assert(iv.length == AES256_BLOCK_LEN);

    Unique!BlockCipher aes256 = retrieveBlockCipher("AES-256").clone();
    aes256.setKey(key.ptr, AES256_KEY_LEN);

    size_t blocks = (input.length / AES256_BLOCK_LEN) + 1;
    size_t padding = ((blocks * AES256_BLOCK_LEN) - input.length);

    ubyte[] padd = new ubyte[padding];
    padd[] = cast(ubyte)padding;
    ubyte[] buffer = input ~ padd;

    ubyte[AES256_BLOCK_LEN] _iv;
    _iv[] = iv[];

    for (size_t i = 0; i < blocks * AES256_BLOCK_LEN; i += AES256_BLOCK_LEN)
    {
        ubyte[] b = buffer[i .. i + AES256_BLOCK_LEN];
        b[] ^= _iv[];
        aes256.encrypt(b.ptr);
        _iv[] = b[];
    }

    return buffer;
}

ubyte[] decrypt_aes256_cbc_pkcs7(const ubyte[] key, const ubyte[] iv, const ubyte[] input)
{
    assert(key.length == AES256_KEY_LEN);
    assert(iv.length == AES256_BLOCK_LEN);
    assert(input.length > 0);
    assert((input.length % AES256_BLOCK_LEN) == 0);

    Unique!BlockCipher aes256 = retrieveBlockCipher("AES-256").clone();
    aes256.setKey(key.ptr, AES256_KEY_LEN);

    ubyte[] buffer = new ubyte[input.length];
    buffer[] = input[];

    ubyte[AES256_BLOCK_LEN] nextIv;
    ubyte[AES256_BLOCK_LEN] _iv;
    _iv[] = iv[];

    for (size_t i = 0; i < buffer.length; i += AES256_BLOCK_LEN)
    {
        ubyte[] b = buffer[i .. i + AES256_BLOCK_LEN];
        nextIv[] = b[];
        aes256.decrypt(b.ptr);
        b[] ^= _iv[];
        _iv[] = nextIv[];
    }

    size_t padding = buffer[$ - 1];
    assert(padding > 0);
    assert(padding <= buffer.length);

    return buffer[0..$ - padding];
}

vladimirgamalyan avatar Jul 03 '16 03:07 vladimirgamalyan

You should also make sure you call .destroy on your AES object to zeroise your key from memory as its destructor intends. You can also place it in a Unique!AES256. I would even create it with findBlockCipher to make sure it uses the available hardware optimizations like AES-NI or SSSE3.

Also, there's a (considerably more complex) example in source/botan/constructs/cryptobox_psk.d

etcimon avatar Jul 03 '16 03:07 etcimon

Sorry, that's retrieveBlockCipher from import botan.libstate.lookup

etcimon avatar Jul 03 '16 03:07 etcimon

Update the code with your suggestions, thanks a lot!

vladimirgamalyan avatar Jul 03 '16 03:07 vladimirgamalyan

The example given seems way too complicated. Here is ECB:

import botan.all;
import botan.filters.b64_filt;
import std.stdio;

void main() {
   auto cipher = getCipher("AES-128/ECB", ENCRYPTION);
   cipher.setKey(SymmetricKey("4B444B444B444B444B444B444B444B44"));
   auto pipe = Pipe(cipher, new Base64Encoder);
   pipe.processMsg("January February");
   writeln(pipe.toString == "hr0e+xH2oi0mYHMmdGQCnQ==");
}

and CBC:

import botan.all;
import botan.filters.b64_filt;
import std.stdio;

void main() {
   auto cipher = getCipher("AES-128/CBC", ENCRYPTION);
   cipher.setKey(SymmetricKey("4B444B444B444B444B444B444B444B44"));
   cipher.setIv(InitializationVector("49564956495649564956495649564956"));
   auto pipe = Pipe(cipher, new Base64Encoder);
   pipe.processMsg("January February");
   writeln(pipe.toString == "BvfnZp4jmCaveE6kefhumpZ0raWX9GDojfPasgSwLTM=");
}

89z avatar Mar 20 '21 06:03 89z