summaryrefslogtreecommitdiff
path: root/extmod/moducryptolib.c
diff options
context:
space:
mode:
authorYonatan Goldschmidt <yon.goldschmidt@gmail.com>2019-04-23 12:39:05 +0300
committerDamien George <damien.p.george@gmail.com>2019-05-06 18:09:48 +1000
commitef9843653b795b650e1fe77e22f87e3523bd0a08 (patch)
tree03e184551ea430f8e5d95cc40748f7af5c8773df /extmod/moducryptolib.c
parent906fb89fd778cb695ba81c871086fe1ce340e681 (diff)
extmod/moducryptolib: Add AES-CTR support.
Selectable at compile time via MICROPY_PY_UCRYPTOLIB_CTR. Disabled by default.
Diffstat (limited to 'extmod/moducryptolib.c')
-rw-r--r--extmod/moducryptolib.c99
1 files changed, 79 insertions, 20 deletions
diff --git a/extmod/moducryptolib.c b/extmod/moducryptolib.c
index af9eec624..6c45c2fde 100644
--- a/extmod/moducryptolib.c
+++ b/extmod/moducryptolib.c
@@ -41,10 +41,17 @@
// values follow PEP 272
enum {
- UCRYPTOLIB_MODE_MIN = 0,
- UCRYPTOLIB_MODE_ECB,
- UCRYPTOLIB_MODE_CBC,
- UCRYPTOLIB_MODE_MAX,
+ UCRYPTOLIB_MODE_ECB = 1,
+ UCRYPTOLIB_MODE_CBC = 2,
+ UCRYPTOLIB_MODE_CTR = 6,
+};
+
+struct ctr_params {
+ // counter is the IV of the AES context.
+
+ size_t offset; // in encrypted_counter
+ // encrypted counter
+ uint8_t encrypted_counter[16];
};
#if MICROPY_SSL_AXTLS
@@ -82,6 +89,19 @@ typedef struct _mp_obj_aes_t {
uint8_t key_type: 2;
} mp_obj_aes_t;
+STATIC inline bool is_ctr_mode(int block_mode) {
+ #if MICROPY_PY_UCRYPTOLIB_CTR
+ return block_mode == UCRYPTOLIB_MODE_CTR;
+ #else
+ return false;
+ #endif
+}
+
+STATIC inline struct ctr_params *ctr_params_from_aes(mp_obj_aes_t *o) {
+ // ctr_params follows aes object struct
+ return (struct ctr_params*)&o[1];
+}
+
#if MICROPY_SSL_AXTLS
STATIC void aes_initial_set_key_impl(AES_CTX_IMPL *ctx, const uint8_t *key, size_t keysize, const uint8_t iv[16]) {
assert(16 == keysize || 32 == keysize);
@@ -155,20 +175,38 @@ STATIC void aes_process_ecb_impl(AES_CTX_IMPL *ctx, const uint8_t in[16], uint8_
STATIC void aes_process_cbc_impl(AES_CTX_IMPL *ctx, const uint8_t *in, uint8_t *out, size_t in_len, bool encrypt) {
mbedtls_aes_crypt_cbc(&ctx->u.mbedtls_ctx, encrypt ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT, in_len, ctx->iv, in, out);
}
+
+#if MICROPY_PY_UCRYPTOLIB_CTR
+STATIC void aes_process_ctr_impl(AES_CTX_IMPL *ctx, const uint8_t *in, uint8_t *out, size_t in_len, struct ctr_params *ctr_params) {
+ mbedtls_aes_crypt_ctr(&ctx->u.mbedtls_ctx, in_len, &ctr_params->offset, ctx->iv, ctr_params->encrypted_counter, in, out);
+}
+#endif
+
#endif
STATIC mp_obj_t ucryptolib_aes_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 2, 3, false);
- mp_obj_aes_t *o = m_new_obj(mp_obj_aes_t);
- o->base.type = type;
- o->block_mode = mp_obj_get_int(args[1]);
- o->key_type = AES_KEYTYPE_NONE;
+ const mp_int_t block_mode = mp_obj_get_int(args[1]);
+
+ switch (block_mode) {
+ case UCRYPTOLIB_MODE_ECB:
+ case UCRYPTOLIB_MODE_CBC:
+ #if MICROPY_PY_UCRYPTOLIB_CTR
+ case UCRYPTOLIB_MODE_CTR:
+ #endif
+ break;
- if (o->block_mode <= UCRYPTOLIB_MODE_MIN || o->block_mode >= UCRYPTOLIB_MODE_MAX) {
- mp_raise_ValueError("mode");
+ default:
+ mp_raise_ValueError("mode");
}
+ mp_obj_aes_t *o = m_new_obj_var(mp_obj_aes_t, struct ctr_params, !!is_ctr_mode(block_mode));
+ o->base.type = type;
+
+ o->block_mode = block_mode;
+ o->key_type = AES_KEYTYPE_NONE;
+
mp_buffer_info_t keyinfo;
mp_get_buffer_raise(args[0], &keyinfo, MP_BUFFER_READ);
if (32 != keyinfo.len && 16 != keyinfo.len) {
@@ -183,10 +221,14 @@ STATIC mp_obj_t ucryptolib_aes_make_new(const mp_obj_type_t *type, size_t n_args
if (16 != ivinfo.len) {
mp_raise_ValueError("IV");
}
- } else if (o->block_mode == UCRYPTOLIB_MODE_CBC) {
+ } else if (o->block_mode == UCRYPTOLIB_MODE_CBC || is_ctr_mode(o->block_mode)) {
mp_raise_ValueError("IV");
}
+ if (is_ctr_mode(block_mode)) {
+ ctr_params_from_aes(o)->offset = 0;
+ }
+
aes_initial_set_key_impl(&o->ctx, keyinfo.buf, keyinfo.len, ivinfo.buf);
return MP_OBJ_FROM_PTR(o);
@@ -204,7 +246,7 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) {
mp_buffer_info_t in_bufinfo;
mp_get_buffer_raise(in_buf, &in_bufinfo, MP_BUFFER_READ);
- if (in_bufinfo.len % 16 != 0) {
+ if (!is_ctr_mode(self->block_mode) && in_bufinfo.len % 16 != 0) {
mp_raise_ValueError("blksize % 16");
}
@@ -224,7 +266,9 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) {
}
if (AES_KEYTYPE_NONE == self->key_type) {
- aes_final_set_key_impl(&self->ctx, encrypt);
+ // always set key for encryption if CTR mode.
+ const bool encrypt_mode = encrypt || is_ctr_mode(self->block_mode);
+ aes_final_set_key_impl(&self->ctx, encrypt_mode);
self->key_type = encrypt ? AES_KEYTYPE_ENC : AES_KEYTYPE_DEC;
} else {
if ((encrypt && self->key_type == AES_KEYTYPE_DEC) ||
@@ -234,14 +278,26 @@ STATIC mp_obj_t aes_process(size_t n_args, const mp_obj_t *args, bool encrypt) {
}
}
- if (self->block_mode == UCRYPTOLIB_MODE_ECB) {
- uint8_t *in = in_bufinfo.buf, *out = out_buf_ptr;
- uint8_t *top = in + in_bufinfo.len;
- for (; in < top; in += 16, out += 16) {
- aes_process_ecb_impl(&self->ctx, in, out, encrypt);
+ switch (self->block_mode) {
+ case UCRYPTOLIB_MODE_ECB: {
+ uint8_t *in = in_bufinfo.buf, *out = out_buf_ptr;
+ uint8_t *top = in + in_bufinfo.len;
+ for (; in < top; in += 16, out += 16) {
+ aes_process_ecb_impl(&self->ctx, in, out, encrypt);
+ }
+ break;
}
- } else {
- aes_process_cbc_impl(&self->ctx, in_bufinfo.buf, out_buf_ptr, in_bufinfo.len, encrypt);
+
+ case UCRYPTOLIB_MODE_CBC:
+ aes_process_cbc_impl(&self->ctx, in_bufinfo.buf, out_buf_ptr, in_bufinfo.len, encrypt);
+ break;
+
+ #if MICROPY_PY_UCRYPTOLIB_CTR
+ case UCRYPTOLIB_MODE_CTR:
+ aes_process_ctr_impl(&self->ctx, in_bufinfo.buf, out_buf_ptr, in_bufinfo.len,
+ ctr_params_from_aes(self));
+ break;
+ #endif
}
if (out_buf != MP_OBJ_NULL) {
@@ -279,6 +335,9 @@ STATIC const mp_rom_map_elem_t mp_module_ucryptolib_globals_table[] = {
#if MICROPY_PY_UCRYPTOLIB_CONSTS
{ MP_ROM_QSTR(MP_QSTR_MODE_ECB), MP_ROM_INT(UCRYPTOLIB_MODE_ECB) },
{ MP_ROM_QSTR(MP_QSTR_MODE_CBC), MP_ROM_INT(UCRYPTOLIB_MODE_CBC) },
+ #if MICROPY_PY_UCRYPTOLIB_CTR
+ { MP_ROM_QSTR(MP_QSTR_MODE_CTR), MP_ROM_INT(UCRYPTOLIB_MODE_CTR) },
+ #endif
#endif
};