You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

207 lines
7.4 KiB

#include <stdint.h>
#include <string.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "shared-bindings/crypto/__init__.h"
// Defined at the end of this file
extern const mp_obj_type_t aescipher_type;
STATIC mp_obj_t aescipher_make_new(size_t n_args, const mp_obj_t *pos_args,
mp_map_t *kw_args) {
enum { ARG_key, ARG_mode, ARG_IV, ARG_counter, ARG_segment_size };
static const mp_arg_t allowed_args[] = {
{MP_QSTR_key, MP_ARG_OBJ | MP_ARG_REQUIRED},
{MP_QSTR_mode, MP_ARG_INT},
{MP_QSTR_IV, MP_ARG_OBJ},
{MP_QSTR_counter, MP_ARG_OBJ},
{MP_QSTR_segment_size, MP_ARG_INT},
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
// Set defaults. These will be overridden in mp_arg_parse_all() if an
// argument is provided.
args[ARG_mode].u_int = AES_MODE_ECB;
args[ARG_IV].u_obj = NULL;
args[ARG_counter].u_int = 0;
args[ARG_segment_size].u_int =
8; // Only useful in CFB mode, which we don't support
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args),
allowed_args, args);
aes_obj_t *self = m_new_obj(aes_obj_t);
self->base.type = &aescipher_type;
mp_buffer_info_t bufinfo;
const uint8_t *key = NULL;
uint32_t key_length = 0;
if (mp_get_buffer(args[ARG_key].u_obj, &bufinfo, MP_BUFFER_READ)) {
if ((bufinfo.len != 16) && (bufinfo.len != 24) && (bufinfo.len != 32)) {
mp_raise_TypeError(translate("key must be 16, 24, or 32 bytes long"));
}
key = bufinfo.buf;
key_length = bufinfo.len;
} else {
mp_raise_TypeError(translate("no key was specified"));
}
int mode = args[ARG_mode].u_int;
switch (args[ARG_mode].u_int) {
case AES_MODE_CBC: /* CBC */
break;
case AES_MODE_ECB: /* ECB */
break;
case AES_MODE_CTR: /* CTR */
break;
default:
mp_raise_TypeError(translate("requested AES mode is unsupported"));
}
// IV is required for CBC mode and is ignored for other modes.
const uint8_t *iv = NULL;
if (args[ARG_IV].u_obj != NULL &&
mp_get_buffer(args[ARG_IV].u_obj, &bufinfo, MP_BUFFER_READ)) {
if (bufinfo.len != AES_BLOCKLEN) {
mp_raise_TypeError_varg(translate("iv must be %d bytes long"),
AES_BLOCKLEN);
}
iv = bufinfo.buf;
}
common_hal_aes_construct(self, key, key_length, iv, mode, args[ARG_counter].u_int);
return MP_OBJ_FROM_PTR(self);
}
// Used when constructing with `new AESCipher`
STATIC mp_obj_t aescipher_make_new_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t *pos_args,
mp_map_t *kw_args) {
return aescipher_make_new(n_args, pos_args, kw_args);
}
STATIC byte *duplicate_data(const byte *src_buf, size_t len) {
byte *dest_buf = m_new(byte, len);
memcpy(dest_buf, src_buf, len);
return dest_buf;
}
STATIC mp_obj_t aescipher_encrypt_in_place(mp_obj_t aes_obj, mp_obj_t buf) {
if (!MP_OBJ_IS_TYPE(aes_obj, &aescipher_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aescipher_type.name);
}
// Convert parameters into expected types.
aes_obj_t *aes = MP_OBJ_TO_PTR(aes_obj);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
if ((bufinfo.len & (AES_BLOCKLEN - 1)) != 0) {
mp_raise_ValueError(translate("Buffer must be a multiple of 16 bytes"));
}
common_hal_aes_encrypt(aes, (uint8_t *)bufinfo.buf, bufinfo.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(aescipher_encrypt_in_place_obj,
aescipher_encrypt_in_place);
STATIC mp_obj_t aescipher_encrypt(mp_obj_t aes_obj, mp_obj_t buf) {
if (!MP_OBJ_IS_TYPE(aes_obj, &aescipher_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aescipher_type.name);
}
// Convert parameters into expected types.
aes_obj_t *aes = MP_OBJ_TO_PTR(aes_obj);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
if ((bufinfo.len & (AES_BLOCKLEN - 1)) != 0) {
mp_raise_ValueError(translate("Buffer must be a multiple of 16 bytes"));
}
byte *dest_buf = duplicate_data((const byte *)bufinfo.buf, bufinfo.len);
common_hal_aes_encrypt(aes, (uint8_t *)dest_buf, bufinfo.len);
return mp_obj_new_bytearray_by_ref(bufinfo.len, dest_buf);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(aescipher_encrypt_obj, aescipher_encrypt);
STATIC mp_obj_t aescipher_decrypt_in_place(mp_obj_t aes_obj, mp_obj_t buf) {
if (!MP_OBJ_IS_TYPE(aes_obj, &aescipher_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aescipher_type.name);
}
// Convert parameters into expected types.
aes_obj_t *aes = MP_OBJ_TO_PTR(aes_obj);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
if ((bufinfo.len & (AES_BLOCKLEN - 1)) != 0) {
mp_raise_ValueError(translate("Buffer must be a multiple of 16 bytes"));
}
common_hal_aes_decrypt(aes, (uint8_t *)bufinfo.buf, bufinfo.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(aescipher_decrypt_in_place_obj,
aescipher_decrypt_in_place);
STATIC mp_obj_t aescipher_decrypt(mp_obj_t aes_obj, mp_obj_t buf) {
if (!MP_OBJ_IS_TYPE(aes_obj, &aescipher_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), aescipher_type.name);
}
// Convert parameters into expected types.
aes_obj_t *aes = MP_OBJ_TO_PTR(aes_obj);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
if ((bufinfo.len & (AES_BLOCKLEN - 1)) != 0) {
mp_raise_ValueError(translate("Buffer must be a multiple of 16 bytes"));
}
byte *dest_buf = duplicate_data((const byte *)bufinfo.buf, bufinfo.len);
common_hal_aes_decrypt(aes, (uint8_t *)dest_buf, bufinfo.len);
return mp_obj_new_bytearray_by_ref(bufinfo.len, dest_buf);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(aescipher_decrypt_obj, aescipher_decrypt);
STATIC const mp_obj_tuple_t mp_crypto_aes_key_size_obj = {
{&mp_type_tuple},
3,
{
MP_OBJ_NEW_SMALL_INT(16),
MP_OBJ_NEW_SMALL_INT(24),
MP_OBJ_NEW_SMALL_INT(32),
}};
STATIC const mp_rom_map_elem_t aescipher_locals_dict_table[] = {
// Methods
{MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_AES)},
{MP_ROM_QSTR(MP_QSTR_encrypt), (mp_obj_t)&aescipher_encrypt_obj},
{MP_ROM_QSTR(MP_QSTR_decrypt), (mp_obj_t)&aescipher_decrypt_obj},
{MP_ROM_QSTR(MP_QSTR_encrypt_in_place),
(mp_obj_t)&aescipher_encrypt_in_place_obj},
{MP_ROM_QSTR(MP_QSTR_decrypt_in_place),
(mp_obj_t)&aescipher_decrypt_in_place_obj},
};
STATIC MP_DEFINE_CONST_DICT(aescipher_locals_dict, aescipher_locals_dict_table);
const mp_obj_type_t aescipher_type = {
{&mp_type_type},
.name = MP_QSTR_AESCipher,
.make_new = aescipher_make_new_new,
.locals_dict = (mp_obj_dict_t *)&aescipher_locals_dict,
};
MP_DEFINE_CONST_FUN_OBJ_KW(aescipher_make_new_obj, 1, aescipher_make_new);
STATIC const mp_rom_map_elem_t aes_module_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_MODE_ECB), MP_ROM_INT(AES_MODE_ECB)},
{MP_ROM_QSTR(MP_QSTR_MODE_CBC), MP_ROM_INT(AES_MODE_CBC)},
{MP_ROM_QSTR(MP_QSTR_MODE_CTR), MP_ROM_INT(AES_MODE_CTR)},
{MP_ROM_QSTR(MP_QSTR_block_size), MP_ROM_INT(AES_BLOCKLEN)},
{MP_ROM_QSTR(MP_QSTR_key_size), (mp_obj_t)&mp_crypto_aes_key_size_obj},
{MP_ROM_QSTR(MP_QSTR_new), MP_ROM_PTR(&aescipher_make_new_obj)},
};
STATIC MP_DEFINE_CONST_DICT(aes_module_globals, aes_module_globals_table);
const mp_obj_module_t aes_module = {
{&mp_type_module},
.globals = (mp_obj_dict_t *)&aes_module_globals,
};