Added support for AES-CTR

pull/33/head
Daniele Lacamera 2022-01-29 00:50:18 +01:00
parent c7125b04b1
commit 8a514e0f8e
4 changed files with 42 additions and 11 deletions

View File

@ -51,14 +51,15 @@ if _lib.ED448_ENABLED:
from wolfcrypt.ciphers import (Ed448Private, Ed448Public)
from wolfcrypt.ciphers import (
MODE_ECB, MODE_CBC, WolfCryptError
MODE_CTR, MODE_ECB, MODE_CBC, WolfCryptError
)
@pytest.fixture
def vectors():
TestVector = namedtuple("TestVector", """key iv plaintext ciphertext raw_key
pkcs8_key pem""")
TestVector = namedtuple("TestVector", """key iv plaintext ciphertext
ciphertext_ctr raw_key
pkcs8_key pem""")
TestVector.__new__.__defaults__ = (None,) * len(TestVector._fields)
# test vector dictionary
@ -69,7 +70,9 @@ def vectors():
key="0123456789abcdef",
iv="1234567890abcdef",
plaintext=t2b("now is the time "),
ciphertext=h2b("959492575f4281532ccc9d4677a233cb")
ciphertext=h2b("959492575f4281532ccc9d4677a233cb"),
#ciphertext_ctr = b'(u(\xdd\xf4\x84\xb1\x05]\xeb\xbeu\x1e\xb5+\x8a'
ciphertext_ctr = h2b('287528ddf484b1055debbe751eb52b8a')
)
if _lib.CHACHA_ENABLED:
vectorArray[ChaCha]=TestVector(
@ -235,12 +238,12 @@ def cipher_new(cipher_cls, vectors):
MODE_CBC,
vectors[cipher_cls].iv)
def test_block_cipher(cipher_cls, vectors):
key = vectors[cipher_cls].key
iv = vectors[cipher_cls].iv
plaintext = vectors[cipher_cls].plaintext
ciphertext = vectors[cipher_cls].ciphertext
ciphertext_ctr = vectors[cipher_cls].ciphertext_ctr
with pytest.raises(ValueError):
cipher_cls.new(key[:-1], MODE_CBC, iv) # invalid key length
@ -257,11 +260,21 @@ def test_block_cipher(cipher_cls, vectors):
with pytest.raises(ValueError):
cipher_cls.new(key, MODE_CBC, iv[:-1]) # invalid iv length
# Test AES in counter mode
if ciphertext_ctr is not None:
cipher_obj = cipher_cls.new(key, MODE_CTR, iv)
res = cipher_obj.encrypt(plaintext)
assert res == ciphertext_ctr
cipher_obj = cipher_cls.new(key, MODE_CTR, iv)
assert plaintext == cipher_obj.decrypt(res)
# single encryption
cipher_obj = cipher_new(cipher_cls, vectors)
assert cipher_obj.encrypt(plaintext) == ciphertext
# many encryptions
cipher_obj = cipher_new(cipher_cls, vectors)
result = t2b("")

View File

@ -320,6 +320,7 @@ if AES_ENABLED:
int wc_AesSetKey(Aes*, const byte*, word32, const byte*, int);
int wc_AesCbcEncrypt(Aes*, byte*, const byte*, word32);
int wc_AesCbcDecrypt(Aes*, byte*, const byte*, word32);
int wc_AesCtrEncrypt(Aes*, byte*, const byte*, word32);
"""
if CHACHA_ENABLED:

View File

@ -184,6 +184,7 @@ def make_flags(prefix):
# symmetric ciphers
flags.append("--enable-aes")
flags.append("--enable-aesctr")
flags.append("--enable-des3")
flags.append("--enable-chacha")

View File

@ -92,12 +92,14 @@ class _Cipher(object):
if mode not in _FEEDBACK_MODES:
raise ValueError("this mode is not supported")
if mode == MODE_CBC:
if mode == MODE_CBC or mode == MODE_CTR:
if IV is None:
raise ValueError("this mode requires an 'IV' string")
else:
raise ValueError("this mode is not supported by this cipher")
self.mode = mode
if self.key_size:
if self.key_size != len(key):
raise ValueError("key must be %d in length, not %d" %
@ -218,17 +220,31 @@ if _lib.AES_ENABLED:
if direction == _ENCRYPTION:
return _lib.wc_AesSetKey(
self._enc, self._key, len(self._key), self._IV, _ENCRYPTION)
if self.mode == MODE_CTR:
return _lib.wc_AesSetKey(
self._dec, self._key, len(self._key), self._IV, _ENCRYPTION)
return _lib.wc_AesSetKey(
self._dec, self._key, len(self._key), self._IV, _DECRYPTION)
def _encrypt(self, destination, source):
return _lib.wc_AesCbcEncrypt(self._enc, destination,
source, len(source))
if self.mode == MODE_CBC:
return _lib.wc_AesCbcEncrypt(self._enc, destination,
source, len(source))
elif self.mode == MODE_CTR:
return _lib.wc_AesCtrEncrypt(self._enc, destination,
source, len(source))
else:
raise ValueError("Invalid mode associated to cipher")
def _decrypt(self, destination, source):
return _lib.wc_AesCbcDecrypt(self._dec, destination,
source, len(source))
if self.mode == MODE_CBC:
return _lib.wc_AesCbcDecrypt(self._dec, destination,
source, len(source))
elif self.mode == MODE_CTR:
return _lib.wc_AesCtrEncrypt(self._dec, destination,
source, len(source))
else:
raise ValueError("Invalid mode associated to cipher")
if _lib.CHACHA_ENABLED:
class ChaCha(_Cipher):