mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
embed/extmod/modtrezorcrypto: refactor AES API, use test from NIST SP 800-38A
This commit is contained in:
parent
ebf912c8f1
commit
1a6e0f053a
@ -22,34 +22,26 @@
|
|||||||
#include "aes/aes.h"
|
#include "aes/aes.h"
|
||||||
#include "memzero.h"
|
#include "memzero.h"
|
||||||
|
|
||||||
|
enum AESMode {
|
||||||
|
ECB = 0x00,
|
||||||
|
CBC = 0x01,
|
||||||
|
CFB = 0x02,
|
||||||
|
OFB = 0x03,
|
||||||
|
CTR = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
/// class AES:
|
/// class AES:
|
||||||
/// '''
|
/// '''
|
||||||
/// AES context.
|
/// AES context.
|
||||||
/// '''
|
/// '''
|
||||||
typedef struct _mp_obj_AES_t {
|
typedef struct _mp_obj_AES_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
union {
|
aes_encrypt_ctx encrypt_ctx;
|
||||||
aes_encrypt_ctx encrypt_ctx;
|
aes_decrypt_ctx decrypt_ctx;
|
||||||
aes_decrypt_ctx decrypt_ctx;
|
|
||||||
} ctx;
|
|
||||||
mp_int_t mode;
|
mp_int_t mode;
|
||||||
uint8_t iv[AES_BLOCK_SIZE];
|
uint8_t iv[AES_BLOCK_SIZE];
|
||||||
uint8_t ctr[AES_BLOCK_SIZE];
|
|
||||||
} mp_obj_AES_t;
|
} mp_obj_AES_t;
|
||||||
|
|
||||||
enum {
|
|
||||||
ECB = 0x00,
|
|
||||||
CBC = 0x01,
|
|
||||||
CFB = 0x02,
|
|
||||||
OFB = 0x03,
|
|
||||||
CTR = 0x04,
|
|
||||||
Encrypt = 0x40,
|
|
||||||
Decrypt = 0x80,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define AESModeMask 0x3F
|
|
||||||
#define AESDirMask 0xC0
|
|
||||||
|
|
||||||
/// def __init__(self, mode: int, key: bytes, iv: bytes = None) -> None:
|
/// def __init__(self, mode: int, key: bytes, iv: bytes = None) -> None:
|
||||||
/// '''
|
/// '''
|
||||||
/// Initialize AES context.
|
/// Initialize AES context.
|
||||||
@ -59,7 +51,7 @@ STATIC mp_obj_t mod_trezorcrypto_AES_make_new(const mp_obj_type_t *type, size_t
|
|||||||
mp_obj_AES_t *o = m_new_obj(mp_obj_AES_t);
|
mp_obj_AES_t *o = m_new_obj(mp_obj_AES_t);
|
||||||
o->base.type = type;
|
o->base.type = type;
|
||||||
o->mode = mp_obj_get_int(args[0]);
|
o->mode = mp_obj_get_int(args[0]);
|
||||||
if ((o->mode & AESModeMask) > 0x04) {
|
if (o->mode < ECB || o->mode > CTR) {
|
||||||
mp_raise_ValueError("Invalid AES mode");
|
mp_raise_ValueError("Invalid AES mode");
|
||||||
}
|
}
|
||||||
mp_buffer_info_t key;
|
mp_buffer_info_t key;
|
||||||
@ -77,38 +69,24 @@ STATIC mp_obj_t mod_trezorcrypto_AES_make_new(const mp_obj_type_t *type, size_t
|
|||||||
} else {
|
} else {
|
||||||
memset(o->iv, 0, AES_BLOCK_SIZE);
|
memset(o->iv, 0, AES_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
memset(o->ctr, 0, AES_BLOCK_SIZE);
|
|
||||||
switch (key.len) {
|
switch (key.len) {
|
||||||
case 16:
|
case 16:
|
||||||
if (o->mode == (ECB | Decrypt) || o->mode == (CBC | Decrypt)) {
|
aes_decrypt_key128(key.buf, &(o->decrypt_ctx));
|
||||||
aes_decrypt_key128(key.buf, &(o->ctx.decrypt_ctx));
|
aes_encrypt_key128(key.buf, &(o->encrypt_ctx));
|
||||||
} else {
|
|
||||||
aes_encrypt_key128(key.buf, &(o->ctx.encrypt_ctx));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
if (o->mode == (ECB | Decrypt) || o->mode == (CBC | Decrypt)) {
|
aes_decrypt_key192(key.buf, &(o->decrypt_ctx));
|
||||||
aes_decrypt_key192(key.buf, &(o->ctx.decrypt_ctx));
|
aes_encrypt_key192(key.buf, &(o->encrypt_ctx));
|
||||||
} else {
|
|
||||||
aes_encrypt_key192(key.buf, &(o->ctx.encrypt_ctx));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
if (o->mode == (ECB | Decrypt) || o->mode == (CBC |Decrypt)) {
|
aes_decrypt_key256(key.buf, &(o->decrypt_ctx));
|
||||||
aes_decrypt_key256(key.buf, &(o->ctx.decrypt_ctx));
|
aes_encrypt_key256(key.buf, &(o->encrypt_ctx));
|
||||||
} else {
|
|
||||||
aes_encrypt_key256(key.buf, &(o->ctx.encrypt_ctx));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return MP_OBJ_FROM_PTR(o);
|
return MP_OBJ_FROM_PTR(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// def update(self, data: bytes) -> bytes:
|
static mp_obj_t aes_update(mp_obj_t self, mp_obj_t data, bool encrypt) {
|
||||||
/// '''
|
|
||||||
/// Update AES context with data.
|
|
||||||
/// '''
|
|
||||||
STATIC mp_obj_t mod_trezorcrypto_AES_update(mp_obj_t self, mp_obj_t data) {
|
|
||||||
mp_buffer_info_t buf;
|
mp_buffer_info_t buf;
|
||||||
mp_get_buffer_raise(data, &buf, MP_BUFFER_READ);
|
mp_get_buffer_raise(data, &buf, MP_BUFFER_READ);
|
||||||
if (buf.len == 0) {
|
if (buf.len == 0) {
|
||||||
@ -117,63 +95,80 @@ STATIC mp_obj_t mod_trezorcrypto_AES_update(mp_obj_t self, mp_obj_t data) {
|
|||||||
vstr_t vstr;
|
vstr_t vstr;
|
||||||
vstr_init_len(&vstr, buf.len);
|
vstr_init_len(&vstr, buf.len);
|
||||||
mp_obj_AES_t *o = MP_OBJ_TO_PTR(self);
|
mp_obj_AES_t *o = MP_OBJ_TO_PTR(self);
|
||||||
switch (o->mode & AESModeMask) {
|
switch (o->mode) {
|
||||||
case ECB:
|
case ECB:
|
||||||
if (buf.len & (AES_BLOCK_SIZE - 1)) {
|
if (buf.len & (AES_BLOCK_SIZE - 1)) {
|
||||||
mp_raise_ValueError("Invalid data length");
|
mp_raise_ValueError("Invalid data length");
|
||||||
}
|
}
|
||||||
if ((o->mode & AESDirMask) == Encrypt) {
|
if (encrypt) {
|
||||||
aes_ecb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, &(o->ctx.encrypt_ctx));
|
aes_ecb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, &(o->encrypt_ctx));
|
||||||
} else {
|
} else {
|
||||||
aes_ecb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, &(o->ctx.decrypt_ctx));
|
aes_ecb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, &(o->decrypt_ctx));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CBC:
|
case CBC:
|
||||||
if (buf.len & (AES_BLOCK_SIZE - 1)) {
|
if (buf.len & (AES_BLOCK_SIZE - 1)) {
|
||||||
mp_raise_ValueError("Invalid data length");
|
mp_raise_ValueError("Invalid data length");
|
||||||
}
|
}
|
||||||
if ((o->mode & AESDirMask) == Encrypt) {
|
if (encrypt) {
|
||||||
aes_cbc_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->ctx.encrypt_ctx));
|
aes_cbc_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx));
|
||||||
} else {
|
} else {
|
||||||
aes_cbc_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->ctx.decrypt_ctx));
|
aes_cbc_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->decrypt_ctx));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CFB:
|
case CFB:
|
||||||
if ((o->mode & AESDirMask) == Encrypt) {
|
if (encrypt) {
|
||||||
aes_cfb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->ctx.encrypt_ctx));
|
aes_cfb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx));
|
||||||
} else {
|
} else {
|
||||||
aes_cfb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->ctx.encrypt_ctx));
|
aes_cfb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx)); // decrypt uses encrypt_ctx
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OFB: // (encrypt == decrypt)
|
case OFB: // (encrypt == decrypt)
|
||||||
aes_ofb_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->ctx.encrypt_ctx));
|
aes_ofb_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx));
|
||||||
break;
|
break;
|
||||||
case CTR: // (encrypt == decrypt)
|
case CTR: // (encrypt == decrypt)
|
||||||
aes_ctr_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->ctr, aes_ctr_cbuf_inc, &(o->ctx.encrypt_ctx));
|
aes_ctr_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, aes_ctr_cbuf_inc, &(o->encrypt_ctx));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_update_obj, mod_trezorcrypto_AES_update);
|
|
||||||
|
/// def encrypt(self, data: bytes) -> bytes:
|
||||||
|
/// '''
|
||||||
|
/// Encrypt data and update AES context.
|
||||||
|
/// '''
|
||||||
|
STATIC mp_obj_t mod_trezorcrypto_AES_encrypt(mp_obj_t self, mp_obj_t data) {
|
||||||
|
return aes_update(self, data, true);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_encrypt_obj, mod_trezorcrypto_AES_encrypt);
|
||||||
|
|
||||||
|
/// def decrypt(self, data: bytes) -> bytes:
|
||||||
|
/// '''
|
||||||
|
/// Decrypt data and update AES context.
|
||||||
|
/// '''
|
||||||
|
STATIC mp_obj_t mod_trezorcrypto_AES_decrypt(mp_obj_t self, mp_obj_t data) {
|
||||||
|
return aes_update(self, data, false);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_decrypt_obj, mod_trezorcrypto_AES_decrypt);
|
||||||
|
|
||||||
STATIC mp_obj_t mod_trezorcrypto_AES___del__(mp_obj_t self) {
|
STATIC mp_obj_t mod_trezorcrypto_AES___del__(mp_obj_t self) {
|
||||||
mp_obj_AES_t *o = MP_OBJ_TO_PTR(self);
|
mp_obj_AES_t *o = MP_OBJ_TO_PTR(self);
|
||||||
memzero(&(o->ctx), sizeof(aes_encrypt_ctx));
|
memzero(&(o->encrypt_ctx), sizeof(aes_encrypt_ctx));
|
||||||
|
memzero(&(o->decrypt_ctx), sizeof(aes_decrypt_ctx));
|
||||||
memzero(o->iv, AES_BLOCK_SIZE);
|
memzero(o->iv, AES_BLOCK_SIZE);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_AES___del___obj, mod_trezorcrypto_AES___del__);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_AES___del___obj, mod_trezorcrypto_AES___del__);
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mod_trezorcrypto_AES_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t mod_trezorcrypto_AES_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_AES_update_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_encrypt), MP_ROM_PTR(&mod_trezorcrypto_AES_encrypt_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_decrypt), MP_ROM_PTR(&mod_trezorcrypto_AES_decrypt_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_AES___del___obj) },
|
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_AES___del___obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ECB), MP_OBJ_NEW_SMALL_INT(ECB) },
|
{ MP_ROM_QSTR(MP_QSTR_ECB), MP_OBJ_NEW_SMALL_INT(ECB) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CBC), MP_OBJ_NEW_SMALL_INT(CBC) },
|
{ MP_ROM_QSTR(MP_QSTR_CBC), MP_OBJ_NEW_SMALL_INT(CBC) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CFB), MP_OBJ_NEW_SMALL_INT(CFB) },
|
{ MP_ROM_QSTR(MP_QSTR_CFB), MP_OBJ_NEW_SMALL_INT(CFB) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_OFB), MP_OBJ_NEW_SMALL_INT(OFB) },
|
{ MP_ROM_QSTR(MP_QSTR_OFB), MP_OBJ_NEW_SMALL_INT(OFB) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_CTR), MP_OBJ_NEW_SMALL_INT(CTR) },
|
{ MP_ROM_QSTR(MP_QSTR_CTR), MP_OBJ_NEW_SMALL_INT(CTR) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Encrypt), MP_OBJ_NEW_SMALL_INT(Encrypt) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Decrypt), MP_OBJ_NEW_SMALL_INT(Decrypt) },
|
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_AES_locals_dict, mod_trezorcrypto_AES_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_AES_locals_dict, mod_trezorcrypto_AES_locals_dict_table);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mp_module_trezorcrypto_globals_table[] = {
|
STATIC const mp_rom_map_elem_t mp_module_trezorcrypto_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorcrypto) },
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorcrypto) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_AES), MP_ROM_PTR(&mod_trezorcrypto_AES_type) },
|
{ MP_ROM_QSTR(MP_QSTR_aes), MP_ROM_PTR(&mod_trezorcrypto_AES_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_bip32), MP_ROM_PTR(&mod_trezorcrypto_bip32_module) },
|
{ MP_ROM_QSTR(MP_QSTR_bip32), MP_ROM_PTR(&mod_trezorcrypto_bip32_module) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_bip39), MP_ROM_PTR(&mod_trezorcrypto_bip39_module) },
|
{ MP_ROM_QSTR(MP_QSTR_bip39), MP_ROM_PTR(&mod_trezorcrypto_bip39_module) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_blake256), MP_ROM_PTR(&mod_trezorcrypto_Blake256_type) },
|
{ MP_ROM_QSTR(MP_QSTR_blake256), MP_ROM_PTR(&mod_trezorcrypto_Blake256_type) },
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.crypto import hmac
|
from trezor.crypto import aes, hmac
|
||||||
from trezor.crypto.aes import AES_CBC_Decrypt, AES_CBC_Encrypt
|
|
||||||
from trezor.crypto.hashlib import sha512
|
from trezor.crypto.hashlib import sha512
|
||||||
from trezor.messages.CipheredKeyValue import CipheredKeyValue
|
from trezor.messages.CipheredKeyValue import CipheredKeyValue
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
@ -40,9 +39,8 @@ def compute_cipher_key_value(msg, seckey: bytes) -> bytes:
|
|||||||
else:
|
else:
|
||||||
iv = data[32:48]
|
iv = data[32:48]
|
||||||
|
|
||||||
|
ctx = aes(aes.CBC, key, iv)
|
||||||
if msg.encrypt:
|
if msg.encrypt:
|
||||||
aes = AES_CBC_Encrypt(key=key, iv=iv)
|
return ctx.encrypt(msg.value)
|
||||||
else:
|
else:
|
||||||
aes = AES_CBC_Decrypt(key=key, iv=iv)
|
return ctx.decrypt(msg.value)
|
||||||
|
|
||||||
return aes.update(msg.value)
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from gc import collect
|
from gc import collect
|
||||||
|
|
||||||
from trezorcrypto import ( # noqa: F401
|
from trezorcrypto import ( # noqa: F401
|
||||||
|
aes,
|
||||||
bip32,
|
bip32,
|
||||||
bip39,
|
bip39,
|
||||||
chacha20poly1305,
|
chacha20poly1305,
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
from trezorcrypto import AES
|
|
||||||
|
|
||||||
|
|
||||||
def AES_ECB_Encrypt(key: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES encryption context in ECB mode
|
|
||||||
"""
|
|
||||||
return AES(AES.ECB | AES.Encrypt, key)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_ECB_Decrypt(key: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES decryption context in ECB mode
|
|
||||||
"""
|
|
||||||
return AES(AES.ECB | AES.Decrypt, key)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_CBC_Encrypt(key: bytes, iv: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES encryption context in CBC mode
|
|
||||||
"""
|
|
||||||
return AES(AES.CBC | AES.Encrypt, key, iv)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_CBC_Decrypt(key: bytes, iv: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES decryption context in CBC mode
|
|
||||||
"""
|
|
||||||
return AES(AES.CBC | AES.Decrypt, key, iv)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_CFB_Encrypt(key: bytes, iv: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES encryption context in CFB mode
|
|
||||||
"""
|
|
||||||
return AES(AES.CFB | AES.Encrypt, key, iv)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_CFB_Decrypt(key: bytes, iv: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES decryption context in CFB mode
|
|
||||||
"""
|
|
||||||
return AES(AES.CFB | AES.Decrypt, key, iv)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_OFB_Encrypt(key: bytes, iv: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES encryption context in OFB mode
|
|
||||||
"""
|
|
||||||
return AES(AES.OFB | AES.Encrypt, key, iv)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_OFB_Decrypt(key: bytes, iv: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES decryption context in OFB mode
|
|
||||||
"""
|
|
||||||
return AES(AES.OFB | AES.Decrypt, key, iv)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_CTR_Encrypt(key: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES encryption context in CTR mode
|
|
||||||
"""
|
|
||||||
return AES(AES.CTR | AES.Encrypt, key)
|
|
||||||
|
|
||||||
|
|
||||||
def AES_CTR_Decrypt(key: bytes) -> AES:
|
|
||||||
"""
|
|
||||||
Create AES decryption context in CTR mode
|
|
||||||
"""
|
|
||||||
return AES(AES.CTR | AES.Decrypt, key)
|
|
@ -1,59 +1,186 @@
|
|||||||
from common import *
|
from common import *
|
||||||
|
|
||||||
from trezor.crypto.aes import *
|
from trezor.crypto import aes
|
||||||
|
|
||||||
|
|
||||||
class TestCryptoAes(unittest.TestCase):
|
class TestCryptoAes(unittest.TestCase):
|
||||||
|
|
||||||
# vectors from https://github.com/ricmoo/pyaes
|
# test vectors from NIST Special Publication 800-38A (Appendix F)
|
||||||
key = b'This_key_for_demo_purposes_only!'
|
# https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38a.pdf
|
||||||
iv = b'InitializationVe'
|
|
||||||
|
iv = unhexlify("000102030405060708090a0b0c0d0e0f")
|
||||||
|
ctr = unhexlify("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
|
||||||
|
key128 = unhexlify("2b7e151628aed2a6abf7158809cf4f3c")
|
||||||
|
key192 = unhexlify("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b")
|
||||||
|
key256 = unhexlify(
|
||||||
|
"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"
|
||||||
|
)
|
||||||
|
|
||||||
def test_ecb(self):
|
def test_ecb(self):
|
||||||
a = AES_ECB_Encrypt(key=self.key)
|
vectors128 = [
|
||||||
plain = b'TextMustBe16Byte'
|
("6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"),
|
||||||
e = a.update(plain)
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"),
|
||||||
self.assertEqual(e, b'L6\x95\x85\xe4\xd9\xf1\x8a\xfb\xe5\x94X\x80|\x19\xc3')
|
("30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688"),
|
||||||
a = AES_ECB_Decrypt(key=self.key)
|
("f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4"),
|
||||||
d = a.update(e)
|
]
|
||||||
self.assertEqual(d, plain)
|
vectors192 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "bd334f1d6e45f25ff712a214571fa5cc"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "974104846d0ad3ad7734ecb3ecee4eef"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "ef7afd2270e2e60adce0ba2face6444e"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "9a4b41ba738d6c72fb16691603c18e0e"),
|
||||||
|
]
|
||||||
|
vectors256 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"),
|
||||||
|
]
|
||||||
|
for key, vec in [
|
||||||
|
(self.key128, vectors128),
|
||||||
|
(self.key192, vectors192),
|
||||||
|
(self.key256, vectors256),
|
||||||
|
]:
|
||||||
|
ctx1 = aes(aes.ECB, key)
|
||||||
|
ctx2 = aes(aes.ECB, key)
|
||||||
|
for plain, cipher in vec:
|
||||||
|
plain, cipher = unhexlify(plain), unhexlify(cipher)
|
||||||
|
e = ctx1.encrypt(plain)
|
||||||
|
self.assertEqual(e, cipher)
|
||||||
|
d = ctx2.decrypt(cipher)
|
||||||
|
self.assertEqual(d, plain)
|
||||||
|
|
||||||
def test_cbc(self):
|
def test_cbc(self):
|
||||||
a = AES_CBC_Encrypt(key=self.key, iv=self.iv)
|
vectors128 = [
|
||||||
plain = b'TextMustBe16Byte'
|
("6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d"),
|
||||||
e = a.update(plain)
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b2"),
|
||||||
self.assertEqual(e, b'\xd6:\x18\xe6\xb1\xb3\xc3\xdc\x87\xdf\xa7|\x08{k\xb6')
|
("30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516"),
|
||||||
a = AES_CBC_Decrypt(key=self.key, iv=self.iv)
|
("f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a7"),
|
||||||
d = a.update(e)
|
]
|
||||||
self.assertEqual(d, plain)
|
vectors192 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "4f021db243bc633d7178183a9fa071e8"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "b4d9ada9ad7dedf4e5e738763f69145a"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "571b242012fb7ae07fa9baac3df102e0"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "08b0e27988598881d920a9e64f5615cd"),
|
||||||
|
]
|
||||||
|
vectors256 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "f58c4c04d6e5f1ba779eabfb5f7bfbd6"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "9cfc4e967edb808d679f777bc6702c7d"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "39f23369a9d9bacfa530e26304231461"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "b2eb05e2c39be9fcda6c19078c6a9d1b"),
|
||||||
|
]
|
||||||
|
for key, vec in [
|
||||||
|
(self.key128, vectors128),
|
||||||
|
(self.key192, vectors192),
|
||||||
|
(self.key256, vectors256),
|
||||||
|
]:
|
||||||
|
ctx1 = aes(aes.CBC, key, self.iv)
|
||||||
|
ctx2 = aes(aes.CBC, key, self.iv)
|
||||||
|
for plain, cipher in vec:
|
||||||
|
plain, cipher = unhexlify(plain), unhexlify(cipher)
|
||||||
|
e = ctx1.encrypt(plain)
|
||||||
|
self.assertEqual(e, cipher)
|
||||||
|
d = ctx2.decrypt(cipher)
|
||||||
|
self.assertEqual(d, plain)
|
||||||
|
|
||||||
def test_cfb(self):
|
def test_cfb(self):
|
||||||
a = AES_CFB_Encrypt(key=self.key, iv=self.iv)
|
vectors128 = [
|
||||||
plain = b'TextMustBeAMultipleOfSegmentSize'
|
("6bc1bee22e409f96e93d7e117393172a", "3b3fd92eb72dad20333449f8e83cfb4a"),
|
||||||
e = a.update(plain)
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "c8a64537a0b3a93fcde3cdad9f1ce58b"),
|
||||||
self.assertEqual(e, b'v\xa9\xc1w"\x8aL\x93oU:\x9a\xa5\xa0\x90k\x1a/\xb4\\U\xc3>\xffh\x08\xe5\xac\'\xc4\xcfv')
|
("30c81c46a35ce411e5fbc1191a0a52ef", "26751f67a3cbb140b1808cf187a4f4df"),
|
||||||
a = AES_CFB_Decrypt(key=self.key, iv=self.iv)
|
("f69f2445df4f9b17ad2b417be66c3710", "c04b05357c5d1c0eeac4c66f9ff7f2e6"),
|
||||||
d = a.update(e)
|
]
|
||||||
self.assertEqual(d, plain)
|
vectors192 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "cdc80d6fddf18cab34c25909c99a4174"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "67ce7f7f81173621961a2b70171d3d7a"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "2e1e8a1dd59b88b1c8e60fed1efac4c9"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "c05f9f9ca9834fa042ae8fba584b09ff"),
|
||||||
|
]
|
||||||
|
vectors256 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "dc7e84bfda79164b7ecd8486985d3860"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "39ffed143b28b1c832113c6331e5407b"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "df10132415e54b92a13ed0a8267ae2f9"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "75a385741ab9cef82031623d55b1e471"),
|
||||||
|
]
|
||||||
|
for key, vec in [
|
||||||
|
(self.key128, vectors128),
|
||||||
|
(self.key192, vectors192),
|
||||||
|
(self.key256, vectors256),
|
||||||
|
]:
|
||||||
|
ctx1 = aes(aes.CFB, key, self.iv)
|
||||||
|
ctx2 = aes(aes.CFB, key, self.iv)
|
||||||
|
for plain, cipher in vec:
|
||||||
|
plain, cipher = unhexlify(plain), unhexlify(cipher)
|
||||||
|
e = ctx1.encrypt(plain)
|
||||||
|
self.assertEqual(e, cipher)
|
||||||
|
d = ctx2.decrypt(cipher)
|
||||||
|
self.assertEqual(d, plain)
|
||||||
|
|
||||||
def test_ofb(self):
|
def test_ofb(self):
|
||||||
a = AES_OFB_Encrypt(key=self.key, iv=self.iv)
|
vectors128 = [
|
||||||
plain = b'Text may be any length you wish, no padding is required'
|
("6bc1bee22e409f96e93d7e117393172a", "3b3fd92eb72dad20333449f8e83cfb4a"),
|
||||||
e = a.update(plain)
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "7789508d16918f03f53c52dac54ed825"),
|
||||||
self.assertEqual(e, b'v\xa9\xc1wO\x92^\x9e\rR\x1e\xf7\xb1\xa2\x9d"l1\xc7\xe7\x9d\x87(\xc26s\xdd8\xc8@\xb6\xd9!\xf5\x0cM\xaa\x9b\xc4\xedLD\xe4\xb9\xd8\xdf\x9e\xac\xa1\xb8\xea\x0f\x8ev\xb5')
|
("30c81c46a35ce411e5fbc1191a0a52ef", "9740051e9c5fecf64344f7a82260edcc"),
|
||||||
a = AES_OFB_Decrypt(key=self.key, iv=self.iv)
|
("f69f2445df4f9b17ad2b417be66c3710", "304c6528f659c77866a510d9c1d6ae5e"),
|
||||||
d = a.update(e)
|
]
|
||||||
self.assertEqual(d, plain)
|
vectors192 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "cdc80d6fddf18cab34c25909c99a4174"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "fcc28b8d4c63837c09e81700c1100401"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "8d9a9aeac0f6596f559c6d4daf59a5f2"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "6d9f200857ca6c3e9cac524bd9acc92a"),
|
||||||
|
]
|
||||||
|
vectors256 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "dc7e84bfda79164b7ecd8486985d3860"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "4febdc6740d20b3ac88f6ad82a4fb08d"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "71ab47a086e86eedf39d1c5bba97c408"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "0126141d67f37be8538f5a8be740e484"),
|
||||||
|
]
|
||||||
|
for key, vec in [
|
||||||
|
(self.key128, vectors128),
|
||||||
|
(self.key192, vectors192),
|
||||||
|
(self.key256, vectors256),
|
||||||
|
]:
|
||||||
|
ctx1 = aes(aes.OFB, key, self.iv)
|
||||||
|
ctx2 = aes(aes.OFB, key, self.iv)
|
||||||
|
for plain, cipher in vec:
|
||||||
|
plain, cipher = unhexlify(plain), unhexlify(cipher)
|
||||||
|
e = ctx1.encrypt(plain)
|
||||||
|
self.assertEqual(e, cipher)
|
||||||
|
d = ctx2.decrypt(cipher)
|
||||||
|
self.assertEqual(d, plain)
|
||||||
|
|
||||||
def test_ctr(self):
|
def test_ctr(self):
|
||||||
a = AES_CTR_Encrypt(key=self.key)
|
vectors128 = [
|
||||||
plain = b'Text may be any length you wish, no padding is required'
|
("6bc1bee22e409f96e93d7e117393172a", "874d6191b620e3261bef6864990db6ce"),
|
||||||
e = a.update(plain)
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "9806f66b7970fdff8617187bb9fffdff"),
|
||||||
self.assertEqual(e, b'1\xac\xd9d\xbaM\x8b\xf3I\xac\xce]\x8e\xac\xd8B\x8e\x99\x06.\xf0\x93\xc9\xd1\xc6\x0b*\xb1\x15\xf2*\x1dO\xe8\xef\xeeR63D\xb9~\x8a\x18\xe3\xdf\xd5\x08\\\xfa\x97"\x9dl\xb8')
|
("30c81c46a35ce411e5fbc1191a0a52ef", "5ae4df3edbd5d35e5b4f09020db03eab"),
|
||||||
a = AES_CTR_Decrypt(key=self.key)
|
("f69f2445df4f9b17ad2b417be66c3710", "1e031dda2fbe03d1792170a0f3009cee"),
|
||||||
d = a.update(e)
|
]
|
||||||
self.assertEqual(d, plain)
|
vectors192 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "1abc932417521ca24f2b0459fe7e6e0b"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "090339ec0aa6faefd5ccc2c6f4ce8e94"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "1e36b26bd1ebc670d1bd1d665620abf7"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "4f78a7f6d29809585a97daec58c6b050"),
|
||||||
|
]
|
||||||
|
vectors256 = [
|
||||||
|
("6bc1bee22e409f96e93d7e117393172a", "601ec313775789a5b7a7f504bbf3d228"),
|
||||||
|
("ae2d8a571e03ac9c9eb76fac45af8e51", "f443e3ca4d62b59aca84e990cacaf5c5"),
|
||||||
|
("30c81c46a35ce411e5fbc1191a0a52ef", "2b0930daa23de94ce87017ba2d84988d"),
|
||||||
|
("f69f2445df4f9b17ad2b417be66c3710", "dfc9c58db67aada613c2dd08457941a6"),
|
||||||
|
]
|
||||||
|
for key, vec in [
|
||||||
|
(self.key128, vectors128),
|
||||||
|
(self.key192, vectors192),
|
||||||
|
(self.key256, vectors256),
|
||||||
|
]:
|
||||||
|
ctx1 = aes(aes.CTR, key, self.ctr)
|
||||||
|
ctx2 = aes(aes.CTR, key, self.ctr)
|
||||||
|
for plain, cipher in vec:
|
||||||
|
plain, cipher = unhexlify(plain), unhexlify(cipher)
|
||||||
|
e = ctx1.encrypt(plain)
|
||||||
|
self.assertEqual(e, cipher)
|
||||||
|
d = ctx2.decrypt(cipher)
|
||||||
|
self.assertEqual(d, plain)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
2
vendor/trezor-crypto
vendored
2
vendor/trezor-crypto
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ff001a0f12565a0d7d51ad3ce5e11e98db6afc25
|
Subproject commit d454a48b5169fddacd169e6ca4124b69449501c9
|
Loading…
Reference in New Issue
Block a user