diff --git a/examples/aes/test_aes.py b/examples/aes/test_aes.py new file mode 100644 index 000000000..18c0c40e2 --- /dev/null +++ b/examples/aes/test_aes.py @@ -0,0 +1,77 @@ +import aes + + +raw = b"0102030405060708" + +print("== aes 128 ecb test begin ==") +a = aes.new(b"0102030405060708", aes.MODE_ECB) +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 128 ecb test end ==") + +print("== aes 192 ecb test begin ==") +a = aes.new(b"010203040506070811121314", aes.MODE_ECB) +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 192 ecb test end ==") + + +print("== aes 256 ecb test begin ==") +a = aes.new(b"01020304050607081112131415161718", aes.MODE_ECB) +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 256 ecb test end ==") + + +raw = b"0102030405060708111213141516171821222324252627283132333435363738" + + +print("== aes 128 cbc test begin ==") +a = aes.new(b"0102030405060708", aes.MODE_CBC, iv=b"0102030405060708") +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 128 cbc test end ==") + +print("== aes 192 cbc test begin ==") +a = aes.new(b"010203040506070811121314", aes.MODE_CBC, iv=b"0102030405060708") +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 192 cbc test end ==") + + +print("== aes 256 cbc test begin ==") +a = aes.new(b"01020304050607081112131415161718", + aes.MODE_CBC, iv=b"0102030405060708") +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 256 cbc test end ==") diff --git a/package/aes/_aes.pyi b/package/aes/_aes.pyi new file mode 100644 index 000000000..fe1db93e4 --- /dev/null +++ b/package/aes/_aes.pyi @@ -0,0 +1,7 @@ +class AES: + MODE_ECB: int + MODE_CBC: int + def __init__(self): ... + def new(self, password:any, mode:int, iv:any): ... + def encrypt(self, msg:any) -> any: ... + def decrypt(self, msg:any) -> any: ... diff --git a/package/aes/_aes_AES.c b/package/aes/_aes_AES.c new file mode 100644 index 000000000..f15d731d5 --- /dev/null +++ b/package/aes/_aes_AES.c @@ -0,0 +1,149 @@ +#include "_aes_AES.h" + +#include "mbedtls/aes.h" + +enum { + MODE_ECB, + MODE_CBC, +} pika_aes_t; + +void _aes_AES___init__(PikaObj* self) { + obj_setInt(self, "MODE_ECB", MODE_ECB); + obj_setInt(self, "MODE_CBC", MODE_CBC); +} + +void _aes_AES_new(PikaObj* self, Arg* password, int mode, Arg* iv) { + ArgType t; + mbedtls_aes_context context; + + t = arg_getType(password); + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } + + t = arg_getType(iv); + if (ARG_TYPE_NONE != t) { + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } else { + size_t len = arg_getBytesSize(iv); + if (len != 16) { + obj_setErrorCode(self, -2); // io error + } else { + obj_setBytes(self, "_iv", arg_getBytes(iv), len); + } + } + } + + obj_setBytes(self, "_password", arg_getBytes(password), + arg_getBytesSize(password)); + obj_setInt(self, "_mode", mode); + mbedtls_aes_init(&context); + obj_setStruct(self, "context", context); +} + +Arg* _aes_AES_encrypt(PikaObj* self, Arg* msg) { + ArgType t; + + t = arg_getType(msg); + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } + + uint8_t* data = arg_getBytes(msg); + uint8_t data_len = arg_getBytesSize(msg); + uint8_t mode = obj_getInt(self, "_mode"); + void* context = obj_getStruct(self, "context"); + uint8_t* password = obj_getBytes(self, "_password"); + uint8_t password_len = obj_getBytesSize(self, "_password"); + uint8_t* iv = obj_getBytes(self, "_iv"); + uint8_t iv_in[16]; + + if (obj_getBytes(self, "_buff") != NULL) { + obj_removeArg(self, "_buff"); + } + + obj_setBytes(self, "_buff", NULL, data_len * sizeof(uint8_t)); + uint8_t* buff = obj_getBytes(self, "_buff"); + + if (mode == MODE_CBC) { + if (iv != NULL) { + __platform_memcpy(iv_in, iv, 16); + } else { + obj_setErrorCode(self, -2); // io error + } + } + + mbedtls_aes_setkey_enc((mbedtls_aes_context*)context, password, + password_len * 8); + + switch (mode) { + case MODE_ECB: + mbedtls_aes_crypt_ecb((mbedtls_aes_context*)context, + MBEDTLS_AES_ENCRYPT, data, buff); + break; + case MODE_CBC: + mbedtls_aes_crypt_cbc((mbedtls_aes_context*)context, + MBEDTLS_AES_ENCRYPT, data_len, iv_in, data, + buff); + break; + default: + __platform_printf("[%s]not support mode\r\n", __FUNCTION__); + obj_setErrorCode(self, -3); // not support now + break; + } + return arg_newBytes(buff, data_len); +} + +Arg* _aes_AES_decrypt(PikaObj* self, Arg* msg) { + ArgType t; + + t = arg_getType(msg); + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } + + uint8_t* data = arg_getBytes(msg); + uint8_t data_len = arg_getBytesSize(msg); + void* context = obj_getStruct(self, "context"); + uint8_t mode = obj_getInt(self, "_mode"); + uint8_t* password = obj_getBytes(self, "_password"); + uint8_t password_len = obj_getBytesSize(self, "_password"); + uint8_t* iv = obj_getBytes(self, "_iv"); + uint8_t iv_in[16]; + + if (obj_getBytes(self, "_buff") != NULL) { + obj_removeArg(self, "_buff"); + } + + obj_setBytes(self, "_buff", NULL, data_len * sizeof(uint8_t)); + uint8_t* buff = obj_getBytes(self, "_buff"); + + if (mode == MODE_CBC) { + if (iv != NULL) { + __platform_memcpy(iv_in, iv, 16); + } else { + obj_setErrorCode(self, -2); // io error + } + } + + mbedtls_aes_setkey_dec((mbedtls_aes_context*)context, password, + password_len * 8); + + switch (mode) { + case MODE_ECB: + mbedtls_aes_crypt_ecb((mbedtls_aes_context*)context, + MBEDTLS_AES_DECRYPT, data, buff); + break; + case MODE_CBC: + mbedtls_aes_crypt_cbc((mbedtls_aes_context*)context, + MBEDTLS_AES_DECRYPT, data_len, iv_in, data, + buff); + break; + default: + __platform_printf("[%s]not support mode\r\n", __FUNCTION__); + obj_setErrorCode(self, -3); // not support now + break; + } + return arg_newBytes(buff, data_len); +} \ No newline at end of file diff --git a/package/aes/aes.py b/package/aes/aes.py new file mode 100644 index 000000000..b94ba2d94 --- /dev/null +++ b/package/aes/aes.py @@ -0,0 +1,9 @@ +import _aes + +MODE_ECB = _aes.AES.MODE_ECB +MODE_CBC = _aes.AES.MODE_CBC + +def new(password:any, mode:int, iv=None) -> _aes.AES: + aes = _aes.AES() + aes.new(password, mode, iv) + return aes diff --git a/port/linux/package/pikascript/_aes.pyi b/port/linux/package/pikascript/_aes.pyi new file mode 100644 index 000000000..fe1db93e4 --- /dev/null +++ b/port/linux/package/pikascript/_aes.pyi @@ -0,0 +1,7 @@ +class AES: + MODE_ECB: int + MODE_CBC: int + def __init__(self): ... + def new(self, password:any, mode:int, iv:any): ... + def encrypt(self, msg:any) -> any: ... + def decrypt(self, msg:any) -> any: ... diff --git a/port/linux/package/pikascript/aes.py b/port/linux/package/pikascript/aes.py new file mode 100644 index 000000000..b94ba2d94 --- /dev/null +++ b/port/linux/package/pikascript/aes.py @@ -0,0 +1,9 @@ +import _aes + +MODE_ECB = _aes.AES.MODE_ECB +MODE_CBC = _aes.AES.MODE_CBC + +def new(password:any, mode:int, iv=None) -> _aes.AES: + aes = _aes.AES() + aes.new(password, mode, iv) + return aes diff --git a/port/linux/package/pikascript/pikascript-lib/aes/_aes_AES.c b/port/linux/package/pikascript/pikascript-lib/aes/_aes_AES.c new file mode 100644 index 000000000..f15d731d5 --- /dev/null +++ b/port/linux/package/pikascript/pikascript-lib/aes/_aes_AES.c @@ -0,0 +1,149 @@ +#include "_aes_AES.h" + +#include "mbedtls/aes.h" + +enum { + MODE_ECB, + MODE_CBC, +} pika_aes_t; + +void _aes_AES___init__(PikaObj* self) { + obj_setInt(self, "MODE_ECB", MODE_ECB); + obj_setInt(self, "MODE_CBC", MODE_CBC); +} + +void _aes_AES_new(PikaObj* self, Arg* password, int mode, Arg* iv) { + ArgType t; + mbedtls_aes_context context; + + t = arg_getType(password); + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } + + t = arg_getType(iv); + if (ARG_TYPE_NONE != t) { + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } else { + size_t len = arg_getBytesSize(iv); + if (len != 16) { + obj_setErrorCode(self, -2); // io error + } else { + obj_setBytes(self, "_iv", arg_getBytes(iv), len); + } + } + } + + obj_setBytes(self, "_password", arg_getBytes(password), + arg_getBytesSize(password)); + obj_setInt(self, "_mode", mode); + mbedtls_aes_init(&context); + obj_setStruct(self, "context", context); +} + +Arg* _aes_AES_encrypt(PikaObj* self, Arg* msg) { + ArgType t; + + t = arg_getType(msg); + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } + + uint8_t* data = arg_getBytes(msg); + uint8_t data_len = arg_getBytesSize(msg); + uint8_t mode = obj_getInt(self, "_mode"); + void* context = obj_getStruct(self, "context"); + uint8_t* password = obj_getBytes(self, "_password"); + uint8_t password_len = obj_getBytesSize(self, "_password"); + uint8_t* iv = obj_getBytes(self, "_iv"); + uint8_t iv_in[16]; + + if (obj_getBytes(self, "_buff") != NULL) { + obj_removeArg(self, "_buff"); + } + + obj_setBytes(self, "_buff", NULL, data_len * sizeof(uint8_t)); + uint8_t* buff = obj_getBytes(self, "_buff"); + + if (mode == MODE_CBC) { + if (iv != NULL) { + __platform_memcpy(iv_in, iv, 16); + } else { + obj_setErrorCode(self, -2); // io error + } + } + + mbedtls_aes_setkey_enc((mbedtls_aes_context*)context, password, + password_len * 8); + + switch (mode) { + case MODE_ECB: + mbedtls_aes_crypt_ecb((mbedtls_aes_context*)context, + MBEDTLS_AES_ENCRYPT, data, buff); + break; + case MODE_CBC: + mbedtls_aes_crypt_cbc((mbedtls_aes_context*)context, + MBEDTLS_AES_ENCRYPT, data_len, iv_in, data, + buff); + break; + default: + __platform_printf("[%s]not support mode\r\n", __FUNCTION__); + obj_setErrorCode(self, -3); // not support now + break; + } + return arg_newBytes(buff, data_len); +} + +Arg* _aes_AES_decrypt(PikaObj* self, Arg* msg) { + ArgType t; + + t = arg_getType(msg); + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + } + + uint8_t* data = arg_getBytes(msg); + uint8_t data_len = arg_getBytesSize(msg); + void* context = obj_getStruct(self, "context"); + uint8_t mode = obj_getInt(self, "_mode"); + uint8_t* password = obj_getBytes(self, "_password"); + uint8_t password_len = obj_getBytesSize(self, "_password"); + uint8_t* iv = obj_getBytes(self, "_iv"); + uint8_t iv_in[16]; + + if (obj_getBytes(self, "_buff") != NULL) { + obj_removeArg(self, "_buff"); + } + + obj_setBytes(self, "_buff", NULL, data_len * sizeof(uint8_t)); + uint8_t* buff = obj_getBytes(self, "_buff"); + + if (mode == MODE_CBC) { + if (iv != NULL) { + __platform_memcpy(iv_in, iv, 16); + } else { + obj_setErrorCode(self, -2); // io error + } + } + + mbedtls_aes_setkey_dec((mbedtls_aes_context*)context, password, + password_len * 8); + + switch (mode) { + case MODE_ECB: + mbedtls_aes_crypt_ecb((mbedtls_aes_context*)context, + MBEDTLS_AES_DECRYPT, data, buff); + break; + case MODE_CBC: + mbedtls_aes_crypt_cbc((mbedtls_aes_context*)context, + MBEDTLS_AES_DECRYPT, data_len, iv_in, data, + buff); + break; + default: + __platform_printf("[%s]not support mode\r\n", __FUNCTION__); + obj_setErrorCode(self, -3); // not support now + break; + } + return arg_newBytes(buff, data_len); +} \ No newline at end of file diff --git a/test/python/aes/test_aes.py b/test/python/aes/test_aes.py new file mode 100644 index 000000000..18c0c40e2 --- /dev/null +++ b/test/python/aes/test_aes.py @@ -0,0 +1,77 @@ +import aes + + +raw = b"0102030405060708" + +print("== aes 128 ecb test begin ==") +a = aes.new(b"0102030405060708", aes.MODE_ECB) +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 128 ecb test end ==") + +print("== aes 192 ecb test begin ==") +a = aes.new(b"010203040506070811121314", aes.MODE_ECB) +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 192 ecb test end ==") + + +print("== aes 256 ecb test begin ==") +a = aes.new(b"01020304050607081112131415161718", aes.MODE_ECB) +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 256 ecb test end ==") + + +raw = b"0102030405060708111213141516171821222324252627283132333435363738" + + +print("== aes 128 cbc test begin ==") +a = aes.new(b"0102030405060708", aes.MODE_CBC, iv=b"0102030405060708") +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 128 cbc test end ==") + +print("== aes 192 cbc test begin ==") +a = aes.new(b"010203040506070811121314", aes.MODE_CBC, iv=b"0102030405060708") +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 192 cbc test end ==") + + +print("== aes 256 cbc test begin ==") +a = aes.new(b"01020304050607081112131415161718", + aes.MODE_CBC, iv=b"0102030405060708") +b = a.encrypt(raw) +c = a.decrypt(b) +print("encrypt:", b) +print("decrypt:", c) +del a +del b +del c +print("== aes 256 cbc test end ==")