Commit aa76c4e0 authored by Hanspeter Portner's avatar Hanspeter Portner

add AES128 encryption/decryption.

parent 474b5620
Pipeline #4161729 failed with stages
in 4 minutes and 8 seconds
......@@ -10,6 +10,7 @@ include_directories(${PROJECT_SOURCE_DIR}/timely.lv2)
include_directories(${PROJECT_SOURCE_DIR}/xpress.lv2)
include_directories(${PROJECT_SOURCE_DIR}/lua-5.3.3)
include_directories(${PROJECT_SOURCE_DIR}/cJSON)
include_directories(${PROJECT_SOURCE_DIR}/tiny-AES128-C)
include_directories(${PROJECT_SOURCE_DIR}/api)
include_directories(${PROJECT_SOURCE_DIR}/ui)
include_directories(${PROJECT_SOURCE_DIR}/include)
......@@ -164,7 +165,8 @@ add_library(api OBJECT
api/api_time.c
api/api_state.c
api/api_vm.c
tlsf-3.0/tlsf.c)
tlsf-3.0/tlsf.c
tiny-AES128-C/aes.c)
set_target_properties(api PROPERTIES POSITION_INDEPENDENT_CODE true) # -fPIC
add_library(moony MODULE
......
......@@ -20,6 +20,10 @@
#include <inttypes.h>
#include <stdatomic.h>
#define ECB 1
#define CBC 0
#include <aes.h>
#include <api_atom.h>
#include <api_forge.h>
#include <api_stash.h>
......@@ -341,6 +345,122 @@ _log(lua_State *L)
return 0;
}
static bool
_parse_key(lua_State *L, int idx, uint8_t key [16])
{
size_t key_len;
const char *pass = luaL_checklstring(L, idx, &key_len);
switch(key_len)
{
case 16: // raw key
memcpy(key, pass, 16);
break;
case 32: // hex-encoded key
for(unsigned i=0; i<16; i++)
{
if(sscanf(&pass[i*2], "%02"SCNx8, &key[i]) != 1)
return false; // sscanf failed
}
break;
default: // invalid key
return false;
}
return true; // success
}
static int
_lencrypt(lua_State *L)
{
size_t input_len;
const uint8_t *input = (const uint8_t *)luaL_checklstring(L, 1, &input_len);
uint8_t key [16];
if(!_parse_key(L, 2, key))
{
lua_pushnil(L);
return 1;
}
const size_t offset_len = sizeof(uint32_t); // length of size prefix
const uint32_t output_len = ((input_len + 15) & (~15)) + offset_len; // round to next 16 byte boundary
luaL_Buffer buf;
uint8_t *dst = (uint8_t *)luaL_buffinitsize(L, &buf, output_len);
*(uint32_t *)dst = htobe32(input_len); // write chunk size
aes_t aes;
for(unsigned i=0; i<input_len; i+=16)
{
uint8_t temp [16];
const unsigned rem = input_len - i;
const unsigned len = rem < 16 ? rem : 16;
if(len < 16)
memset(temp, 0x0, 16); // pad remainder
memcpy(temp, &input[i], 16);
AES128_ECB_encrypt(&aes, temp, key, &dst[offset_len + i]);
}
luaL_addsize(&buf, output_len);
luaL_pushresult(&buf);
return 1;
}
static int
_ldecrypt(lua_State *L)
{
size_t input_len;
const uint8_t *input = (const uint8_t *)luaL_checklstring(L, 1, &input_len);
uint8_t key [16];
if(!_parse_key(L, 2, key))
{
lua_pushnil(L);
return 1;
}
const uint32_t output_len = be32toh(*(uint32_t *)input); // read chunk size
const size_t offset_len = sizeof(uint32_t); // length of size prefix
luaL_Buffer buf;
uint8_t *dst = (uint8_t *)luaL_buffinitsize(L, &buf, output_len);
aes_t aes;
for(unsigned i=0; i<output_len; i+=16)
{
uint8_t temp [16];
memcpy(temp, &input[offset_len + i], 16);
AES128_ECB_decrypt(&aes, temp, key, &dst[i]);
}
luaL_addsize(&buf, output_len);
luaL_pushresult(&buf);
// discriminate between code and string
if(lua_isstring(L, -1))
{
size_t str_len;
const char *str = lua_tolstring(L, -1, &str_len);
if(luaL_loadbuffer(L, str, str_len, "decrypt") == LUA_OK)
{
return 1; // return code parsed from decrypted string
}
else
{
lua_pop(L, 1); // pop error code;
return 1; // return decrypted string
}
}
lua_pushnil(L);
return 1;
}
LV2_Atom_Forge_Ref
_sink(LV2_Atom_Forge_Sink_Handle handle, const void *buf, uint32_t size)
{
......@@ -1444,6 +1564,12 @@ moony_open(moony_t *moony, lua_State *L, bool use_assert)
lua_newtable(L);
lua_rawseti(L, LUA_REGISTRYINDEX, UDATA_OFFSET + MOONY_UDATA_COUNT + MOONY_CCLOSURE_COUNT + MOONY_UPCLOSURE_SEQUENCE_MULTIPLEX);
lua_pushcclosure(L, _lencrypt, 0);
lua_setglobal(L, "encrypt");
lua_pushcclosure(L, _ldecrypt, 0);
lua_setglobal(L, "decrypt");
#undef SET_MAP
}
......
......@@ -1621,3 +1621,57 @@ do
i = i + 1
end
end
print('[test] encrypt')
do
local key = string.char(
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c)
local inp = string.char(
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a)
local out = string.char(
0x00, 0x00, 0x00, 0x10, -- size = 16
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97)
local sec = encrypt(inp, key)
assert(#sec - 4 == #inp)
assert(#sec == #out)
assert(sec == out)
end
print('[test] decrypt')
do
local key = '2b7e151628aed2a6abf7158809cf4f3c'
local inp = string.char(
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a)
local out = string.char(
0x00, 0x00, 0x00, 0x10, -- size = 16
0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97)
local dec = decrypt(out, key)
assert(dec == inp)
end
print('[test] obfuscate')
do
local key = string.char(
0x43, 0x4e, 0x5e, 0x42, 0x1a, 0x9e, 0x4f, 0xda,
0xb0, 0x83, 0xa2, 0xeb, 0xf2, 0xd9, 0x78, 0x07)
local chunk_1 = 'return "hello world"'
local chunk_2 = 'hello world'
local sec = encrypt(chunk_1, key)
local dec = decrypt(sec, key)
assert(type(dec) == 'function')
assert(dec() == 'hello world')
sec = encrypt(chunk_2, key)
dec = decrypt(sec, key)
assert(type(dec) == 'string')
assert(#dec == #chunk_2)
assert(dec == chunk_2)
end
#CC = avr-gcc
#CFLAGS = -Wall -mmcu=atmega16 -Os -Wl,-Map,test.map
#OBJCOPY = avr-objcopy
CC = gcc
CFLAGS = -Wall -Os -Wl,-Map,test.map
OBJCOPY = objcopy
# include path to AVR library
INCLUDE_PATH = /usr/lib/avr/include
# splint static check
SPLINT = splint test.c aes.c -I$(INCLUDE_PATH) +charindex -unrecog
.SILENT:
.PHONY: lint clean
rom.hex : test.out
# copy object-code to new image and format in hex
$(OBJCOPY) -j .text -O ihex test.out rom.hex
test.o : test.c
# compiling test.c
$(CC) $(CFLAGS) -c test.c -o test.o
aes.o : aes.h aes.c
# compiling aes.c
$(CC) $(CFLAGS) -c aes.c -o aes.o
test.out : aes.o test.o
# linking object code to binary
$(CC) $(CFLAGS) aes.o test.o -o test.out
small: test.out
$(OBJCOPY) -j .text -O ihex test.out rom.hex
clean:
rm -f *.OBJ *.LST *.o *.gch *.out *.hex *.map
lint:
$(call SPLINT)
### Tiny AES128 in C
This is a small and portable implementation of the AES128 ECB and CBC encryption algorithms written in C.
The API is very simple and looks like this (I am using C99 `<stdint.h>`-style annotated types):
```C
void AES128_ECB_encrypt(aes_t *aes, uint8_t* input, const uint8_t* key, uint8_t* output);
void AES128_ECB_decrypt(aes_t *aes, uint8_t* input, const uint8_t* key, uint8_t* output);
void AES128_CBC_encrypt_buffer(aes_t *aes, uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES128_CBC_decrypt_buffer(aes_t *aes, uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
```
You can choose to use one or both of the modes-of-operation, by defining the symbols CBC and ECB. See the header file for clarification.
There is no built-in error checking or protection from out-of-bounds memory access errors as a result of malicious input. The two functions AES128_ECB_xxcrypt() do most of the work, and they expect inputs of 128 bit length.
The module uses around 200 bytes of RAM and 2.5K ROM when compiled for ARM (~2K for Thumb but YMMV).
It is one of the smallest implementation in C I've seen yet, but do contact me if you know of something smaller (or have improvements to the code here).
I've successfully used the code on 64bit x86, 32bit ARM and 8 bit AVR platforms.
GCC size output when ECB mode is compiled for ARM:
$ arm-none-eabi-gcc -Os -c aes.c -DCBC=0
$ size aes.o
text data bss dec hex filename
2323 0 184 2507 9cb aes.o
.. and when compiling for the THUMB instruction set, we end up around 2K in code size.
$ arm-none-eabi-gcc -mthumb -Os -c aes.c -DCBC=0
$ size aes.o
text data bss dec hex filename
1775 0 184 1959 7a7 aes.o
I am using Mentor Graphics free ARM toolchain:
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.4 20140526 (release) [ARM/embedded-4_8-branch revision 211358]
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This implementation is verified against the data in:
[National Institute of Standards and Technology Special Publication 800-38A 2001 ED](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf) Appendix F: Example Vectors for Modes of Operation of the AES.
All material in this repository is in the public domain.
I am a bit slow to react to pull requests and issues, but I have an ambition to go through all issues sometime in the future and release a stable version.
This diff is collapsed.
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES128 encryption in CBC-mode of operation and handles 0-padding.
// ECB enables the basic ECB 16-byte block algorithm. Both can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
typedef uint8_t aes_state_t[4][4];
typedef struct _aes_t aes_t;
struct _aes_t {
// state - array holding the intermediate results during decryption.
aes_state_t* state;
// The array that stores the round keys.
uint8_t RoundKey[176];
// The Key input to the AES Program
const uint8_t* Key;
#if defined(CBC) && CBC
// Initial Vector used only for CBC mode
uint8_t* Iv;
#endif
};
#if defined(ECB) && ECB
void AES128_ECB_encrypt(aes_t *aes, uint8_t* input, const uint8_t* key, uint8_t *output);
void AES128_ECB_decrypt(aes_t *aes, uint8_t* input, const uint8_t* key, uint8_t *output);
#endif // #if defined(ECB) && ECB
#if defined(CBC) && CBC
void AES128_CBC_encrypt_buffer(aes_t *aes, uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES128_CBC_decrypt_buffer(aes_t *aes, uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
#endif // #if defined(CBC) && CBC
#endif //_AES_H_
#include <stdio.h>
#include <string.h>
#include <stdint.h>
// Enable both ECB and CBC mode. Note this can be done before including aes.h or at compile-time.
// E.g. with GCC by using the -D flag: gcc -c aes.c -DCBC=0 -DECB=1
#define CBC 1
#define ECB 1
#include "aes.h"
static void phex(uint8_t* str);
static void test_encrypt_ecb(void);
static void test_decrypt_ecb(void);
static void test_encrypt_ecb_verbose(void);
static void test_encrypt_cbc(void);
static void test_decrypt_cbc(void);
int main(void)
{
test_encrypt_cbc();
test_decrypt_cbc();
test_decrypt_ecb();
test_encrypt_ecb();
test_encrypt_ecb_verbose();
return 0;
}
// prints string as hex
static void phex(uint8_t* str)
{
unsigned char i;
for(i = 0; i < 16; ++i)
printf("%.2x", str[i]);
printf("\n");
}
static void test_encrypt_ecb_verbose(void)
{
// Example of more verbose verification
uint8_t i, buf[64], buf2[64];
// 128bit key
uint8_t key[16] = { (uint8_t) 0x2b, (uint8_t) 0x7e, (uint8_t) 0x15, (uint8_t) 0x16, (uint8_t) 0x28, (uint8_t) 0xae, (uint8_t) 0xd2, (uint8_t) 0xa6, (uint8_t) 0xab, (uint8_t) 0xf7, (uint8_t) 0x15, (uint8_t) 0x88, (uint8_t) 0x09, (uint8_t) 0xcf, (uint8_t) 0x4f, (uint8_t) 0x3c };
// 512bit text
uint8_t plain_text[64] = { (uint8_t) 0x6b, (uint8_t) 0xc1, (uint8_t) 0xbe, (uint8_t) 0xe2, (uint8_t) 0x2e, (uint8_t) 0x40, (uint8_t) 0x9f, (uint8_t) 0x96, (uint8_t) 0xe9, (uint8_t) 0x3d, (uint8_t) 0x7e, (uint8_t) 0x11, (uint8_t) 0x73, (uint8_t) 0x93, (uint8_t) 0x17, (uint8_t) 0x2a,
(uint8_t) 0xae, (uint8_t) 0x2d, (uint8_t) 0x8a, (uint8_t) 0x57, (uint8_t) 0x1e, (uint8_t) 0x03, (uint8_t) 0xac, (uint8_t) 0x9c, (uint8_t) 0x9e, (uint8_t) 0xb7, (uint8_t) 0x6f, (uint8_t) 0xac, (uint8_t) 0x45, (uint8_t) 0xaf, (uint8_t) 0x8e, (uint8_t) 0x51,
(uint8_t) 0x30, (uint8_t) 0xc8, (uint8_t) 0x1c, (uint8_t) 0x46, (uint8_t) 0xa3, (uint8_t) 0x5c, (uint8_t) 0xe4, (uint8_t) 0x11, (uint8_t) 0xe5, (uint8_t) 0xfb, (uint8_t) 0xc1, (uint8_t) 0x19, (uint8_t) 0x1a, (uint8_t) 0x0a, (uint8_t) 0x52, (uint8_t) 0xef,
(uint8_t) 0xf6, (uint8_t) 0x9f, (uint8_t) 0x24, (uint8_t) 0x45, (uint8_t) 0xdf, (uint8_t) 0x4f, (uint8_t) 0x9b, (uint8_t) 0x17, (uint8_t) 0xad, (uint8_t) 0x2b, (uint8_t) 0x41, (uint8_t) 0x7b, (uint8_t) 0xe6, (uint8_t) 0x6c, (uint8_t) 0x37, (uint8_t) 0x10 };
memset(buf, 0, 64);
memset(buf2, 0, 64);
// print text to encrypt, key and IV
printf("ECB encrypt verbose:\n\n");
printf("plain text:\n");
for(i = (uint8_t) 0; i < (uint8_t) 4; ++i)
{
phex(plain_text + i * (uint8_t) 16);
}
printf("\n");
printf("key:\n");
phex(key);
printf("\n");
// print the resulting cipher as 4 x 16 byte strings
printf("ciphertext:\n");
for(i = 0; i < 4; ++i)
{
aes_t aes;
AES128_ECB_encrypt(&aes, plain_text + (i*16), key, buf+(i*16));
phex(buf + (i*16));
}
printf("\n");
}
static void test_encrypt_ecb(void)
{
uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
uint8_t in[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
uint8_t out[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
uint8_t buffer[16];
aes_t aes;
AES128_ECB_encrypt(&aes, in, key, buffer);
printf("ECB decrypt: ");
if(0 == memcmp((char*) out, (char*) buffer, 16))
{
printf("SUCCESS!\n");
}
else
{
printf("FAILURE!\n");
}
}
static void test_decrypt_cbc(void)
{
// Example "simulating" a smaller buffer...
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
uint8_t in[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 };
uint8_t out[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
uint8_t buffer[64];
aes_t aes;
AES128_CBC_decrypt_buffer(&aes, buffer+0, in+0, 16, key, iv);
AES128_CBC_decrypt_buffer(&aes, buffer+16, in+16, 16, 0, 0);
AES128_CBC_decrypt_buffer(&aes, buffer+32, in+32, 16, 0, 0);
AES128_CBC_decrypt_buffer(&aes, buffer+48, in+48, 16, 0, 0);
printf("CBC decrypt: ");
if(0 == memcmp((char*) out, (char*) buffer, 64))
{
printf("SUCCESS!\n");
}
else
{
printf("FAILURE!\n");
}
}
static void test_encrypt_cbc(void)
{
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
uint8_t in[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
uint8_t out[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 };
uint8_t buffer[64];
aes_t aes;
AES128_CBC_encrypt_buffer(&aes, buffer, in, 64, key, iv);
printf("CBC encrypt: ");
if(0 == memcmp((char*) out, (char*) buffer, 64))
{
printf("SUCCESS!\n");
}
else
{
printf("FAILURE!\n");
}
}
static void test_decrypt_ecb(void)
{
uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
uint8_t in[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
uint8_t out[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
uint8_t buffer[16];
aes_t aes;
AES128_ECB_decrypt(&aes, in, key, buffer);
printf("ECB decrypt: ");
if(0 == memcmp((char*) out, (char*) buffer, 16))
{
printf("SUCCESS!\n");
}
else
{
printf("FAILURE!\n");
}
}
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
......@@ -24,7 +24,7 @@ var LuaHighlightRules = function() {
"__concat|__len|__eq|__lt|__le|__index|__newindex|__call|"+
"__gc|__mode|__name|__tostring|__metatable|__pairs|"+
// moony basic
"run|once|save|restore|stash|apply|register|midi2cps|cps2midi");
"run|once|save|restore|stash|apply|register|midi2cps|cps2midi|encrypt|decrypt");
var field_functions = (
// Lua coroutine
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment