Skip to content

Commit

Permalink
cipher: Increase test coverage and fix minor bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Synss committed Sep 21, 2019
1 parent ffd0628 commit 9bb0b17
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 36 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[next]

* cipher: Increase test coverage and fix minor bugs.
* tests: Do not assume that havege is missing as it could be included
in some configurations.
* tests: Make error reporting with memoryviews closer to pytest
Expand Down
1 change: 0 additions & 1 deletion src/mbedtls/cipher/ARIA.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def new(key, mode, iv=None):
# _cipher.Mode.CFB128,
_cipher.Mode.CTR,
_cipher.Mode.GCM,
_cipher.Mode.CCM,
}:
if len(key) * 8 not in {128, 192, 256}:
raise TLSError(
Expand Down
7 changes: 3 additions & 4 deletions src/mbedtls/cipher/Blowfish.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ def new(key, mode, iv=None):
"""
mode = _cipher.Mode(mode)
if len(key) not in range(4, 57):
raise TLSError(
msg="key size must be 4 to 57 bytes, got %i" % (key_size, len(key))
)
key_len = len(key)
if key_len not in range(4, 57):
raise TLSError(msg="key size must be 4 to 56 bytes, got %i" % key_len)
if mode not in {
_cipher.Mode.ECB,
_cipher.Mode.CBC,
Expand Down
1 change: 0 additions & 1 deletion src/mbedtls/cipher/Camellia.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ def new(key, mode, iv=None):
_cipher.Mode.CFB,
_cipher.Mode.CTR,
_cipher.Mode.GCM,
_cipher.Mode.CCM,
}:
raise TLSError(msg="unsupported mode %r" % mode)
name = (
Expand Down
182 changes: 152 additions & 30 deletions tests/test_cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ class _TestCipher:
def mode(self, request):
return request.param

@pytest.fixture(params=[])
def unsupported_mode(self, request):
return request.param

@pytest.fixture
def iv(self, mode, randbytes):
return randbytes(16)
Expand All @@ -87,6 +91,10 @@ def iv(self, mode, randbytes):
def key_size(self):
raise NotImplementedError

@pytest.fixture(params=[])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
raise NotImplementedError
Expand All @@ -99,6 +107,10 @@ def cipher(self):
def key(self, key_size, randbytes):
return randbytes(key_size)

@pytest.fixture
def invalid_key(self, invalid_key_size, randbytes):
return randbytes(invalid_key_size)

@pytest.fixture
def cipher(self, module, key, mode, iv):
return module.new(key, mode, iv)
Expand All @@ -108,6 +120,14 @@ def data(self, cipher, mode, randbytes):
# `block_size` is limited for ECB because it is a block cipher.
return randbytes(cipher.block_size if mode is mb.Mode.ECB else 20000)

def test_unsupported_mode(self, module, key, unsupported_mode, iv):
with pytest.raises(TLSError):
module.new(key, unsupported_mode, iv)

def test_invalid_key_size(self, module, invalid_key, mode, iv):
with pytest.raises(TLSError):
module.new(invalid_key, mode, iv)

def test_encrypt_decrypt(self, cipher, data):
assert cipher.decrypt(cipher.encrypt(data)) == data

Expand Down Expand Up @@ -135,7 +155,21 @@ def test_encrypt_decrypt(self, cipher, data):
@pytest.mark.skipif(
not mbedtls.has_feature("aes"), reason="requires AES support in libmbedtls"
)
class TestAES(_TestCipher):
class _TestAESBase(_TestCipher):
@pytest.fixture(params=[mb.Mode.STREAM, mb.Mode.CHACHAPOLY])
def unsupported_mode(self, request):
return request.param

@pytest.fixture(params=[8, 15, 128])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.AES


class TestAES(_TestAESBase):
@pytest.fixture(
params=[
mb.Mode.ECB,
Expand All @@ -152,15 +186,8 @@ def mode(self, request):
def key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.AES


@pytest.mark.skipif(
not mbedtls.has_feature("aes"), reason="requires AES support in libmbedtls"
)
class TestAES_XTS(TestAES):
class TestAES_XTS(_TestAESBase):
@pytest.fixture(params=[_mode(mb.Mode.XTS)])
def mode(self, request):
return request.param
Expand All @@ -170,14 +197,15 @@ def key_size(self, request):
return request.param


@pytest.mark.skipif(
not mbedtls.has_feature("aes"), reason="requires AES support in libmbedtls"
)
class TestAES_AEAD(_TestAEADCipher):
@pytest.fixture(params=[mb.Mode.GCM, mb.Mode.CCM])
def mode(self, request):
return request.param

@pytest.fixture(params=[8, 15, 128])
def invalid_key_size(self, request):
return request.param

@pytest.fixture(params=[16, 24, 32])
def key_size(self, request):
return request.param
Expand All @@ -200,6 +228,10 @@ class TestARC4(_TestCipher):
def key_size(self, request):
return request.param

@pytest.fixture(params=[8, 15, 32])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.ARC4
Expand All @@ -221,10 +253,27 @@ class TestARIA(_TestCipher):
def mode(self, request):
return request.param

@pytest.fixture(
params=[
mb.Mode.CFB,
mb.Mode.OFB,
mb.Mode.STREAM,
mb.Mode.CCM,
mb.Mode.XTS,
mb.Mode.CHACHAPOLY,
]
)
def unsupported_mode(self, request):
return request.param

@pytest.fixture(params=[16, 24, 32])
def key_size(self, request):
return request.param

@pytest.fixture(params=[8, 15, 64])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.ARIA
Expand All @@ -246,10 +295,27 @@ class TestBlowfish(_TestCipher):
def mode(self, request):
return request.param

@pytest.fixture(
params=[
mb.Mode.OFB,
mb.Mode.GCM,
mb.Mode.STREAM,
mb.Mode.CCM,
mb.Mode.XTS,
mb.Mode.CHACHAPOLY,
]
)
def unsupported_mode(self, request):
return request.param

@pytest.fixture(params=range(4, 57))
def key_size(self, request):
return request.param

@pytest.fixture(params=[3, 57])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.Blowfish
Expand All @@ -262,7 +328,6 @@ def module(self):
class TestCamellia(_TestCipher):
@pytest.fixture(
params=[
# CCM is not available.
mb.Mode.ECB,
_mode(mb.Mode.CBC),
_mode(mb.Mode.CFB),
Expand All @@ -273,10 +338,26 @@ class TestCamellia(_TestCipher):
def mode(self, request):
return request.param

@pytest.fixture(
params=[
mb.Mode.OFB,
mb.Mode.STREAM,
mb.Mode.CCM,
mb.Mode.XTS,
mb.Mode.CHACHAPOLY,
]
)
def unsupported_mode(self, request):
return request.param

@pytest.fixture(params=[16, 24, 32])
def key_size(self, request):
return request.param

@pytest.fixture(params=[8, 15, 64])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.Camellia
Expand All @@ -285,11 +366,28 @@ def module(self):
@pytest.mark.skipif(
not mbedtls.has_feature("des"), reason="requires DES support in libmbedtls"
)
class TestDES(_TestCipher):
class _TestDESBase(_TestCipher):
@pytest.fixture(params=[mb.Mode.ECB, _mode(mb.Mode.CBC)])
def mode(self, request):
return request.param

@pytest.fixture(
params=[
mb.Mode.CFB,
mb.Mode.OFB,
mb.Mode.CTR,
mb.Mode.GCM,
mb.Mode.STREAM,
mb.Mode.CCM,
mb.Mode.XTS,
mb.Mode.CHACHAPOLY,
]
)
def unsupported_mode(self, request):
return request.param


class TestDES(_TestDESBase):
@pytest.fixture(params=[8])
def key_size(self, request):
return request.param
Expand All @@ -299,14 +397,7 @@ def module(self):
return mb.DES


@pytest.mark.skipif(
not mbedtls.has_feature("des"), reason="requires DES support in libmbedtls"
)
class TestDES3(_TestCipher):
@pytest.fixture(params=[mb.Mode.ECB, _mode(mb.Mode.CBC)])
def mode(self, request):
return request.param

class TestDES3(_TestDESBase):
@pytest.fixture(params=[24])
def key_size(self, request):
return request.param
Expand All @@ -316,14 +407,7 @@ def module(self):
return mb.DES3


@pytest.mark.skipif(
not mbedtls.has_feature("des"), reason="requires DES support in libmbedtls"
)
class TestDES3dbl(_TestCipher):
@pytest.fixture(params=[mb.Mode.ECB, _mode(mb.Mode.CBC)])
def mode(self, request):
return request.param

class TestDES3dbl(_TestDESBase):
@pytest.fixture(params=[16])
def key_size(self, request):
return request.param
Expand All @@ -342,10 +426,29 @@ class TestCHACHA20(_TestCipher):
def mode(self, request):
return request.param

@pytest.fixture(
params=[
mb.Mode.ECB,
mb.Mode.CBC,
mb.Mode.CFB,
mb.Mode.OFB,
mb.Mode.CTR,
mb.Mode.GCM,
mb.Mode.CCM,
mb.Mode.XTS,
]
)
def unsupported_mode(self, request):
return request.param

@pytest.fixture(params=[32])
def key_size(self, request):
return request.param

@pytest.fixture(params=[8, 16, 64])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.CHACHA20
Expand All @@ -366,10 +469,29 @@ def iv(self, mode, randbytes):
def mode(self, request):
return request.param

@pytest.fixture(
params=[
mb.Mode.ECB,
mb.Mode.CBC,
mb.Mode.CFB,
mb.Mode.OFB,
mb.Mode.CTR,
mb.Mode.GCM,
mb.Mode.CCM,
mb.Mode.XTS,
]
)
def unsupported_mode(self, request):
return request.param

@pytest.fixture(params=[32])
def key_size(self, request):
return request.param

@pytest.fixture(params=[8, 16, 64])
def invalid_key_size(self, request):
return request.param

@pytest.fixture
def module(self):
return mb.CHACHA20

0 comments on commit 9bb0b17

Please sign in to comment.