1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 15:38:11 +00:00

embed/extmod/modtrezorcrypto: refactor AES API, use test from NIST SP 800-38A

This commit is contained in:
Pavol Rusnak 2018-08-13 21:47:57 +02:00
parent ebf912c8f1
commit 1a6e0f053a
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
7 changed files with 226 additions and 176 deletions

View File

@ -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);

View File

@ -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) },

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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()

@ -1 +1 @@
Subproject commit ff001a0f12565a0d7d51ad3ce5e11e98db6afc25 Subproject commit d454a48b5169fddacd169e6ca4124b69449501c9