From: Sergey Matveev Date: Sun, 2 Dec 2018 17:17:39 +0000 (+0300) Subject: 28147-89 CBC key meshing ability X-Git-Tag: 3.15~12 X-Git-Url: http://www.git.cypherpunks.ru/?p=pygost.git;a=commitdiff_plain;h=dd0805888217ef624c159baad44c2488101d5750 28147-89 CBC key meshing ability --- diff --git a/NEWS b/NEWS index e2e8679..2655265 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ 3.13: * Ability to explicitly specify used 28147-89 Sbox in pygost.wrap.* functions + * Ability to use key meshing in 28147-89 CBC mode 3.12: * Added mode argument to pygost.gost3410_vko.kek_34102012256, diff --git a/news.texi b/news.texi index 7841bef..e87f637 100644 --- a/news.texi +++ b/news.texi @@ -8,6 +8,7 @@ @itemize @item Ability to explicitly specify used 28147-89 Sbox in @code{pygost.wrap.*} functions + @item Ability to use key meshing in 28147-89 CBC mode @end itemize @anchor{Release 3.12} diff --git a/pygost/gost28147.py b/pygost/gost28147.py index 585d0e7..78a0e37 100644 --- a/pygost/gost28147.py +++ b/pygost/gost28147.py @@ -281,7 +281,7 @@ ecb_encrypt = partial(ecb, action=encrypt) ecb_decrypt = partial(ecb, action=decrypt) -def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX): +def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX, mesh=False): """ CBC encryption mode of operation :param bytes key: encryption key @@ -291,6 +291,7 @@ def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX): :type bool pad: perform ISO/IEC 7816-4 padding :param sbox: S-box parameters to use :type sbox: str, SBOXES'es key + :param bool mesh: enable key meshing :returns: ciphertext :rtype: bytes @@ -307,13 +308,15 @@ def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX): raise ValueError("Data is not blocksize aligned") ciphertext = [iv] for i in xrange(0, len(data), BLOCKSIZE): + if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0: + key, _ = meshing(key, iv, sbox=sbox) ciphertext.append(ns2block(encrypt(sbox, key, block2ns( strxor(ciphertext[-1], data[i:i + BLOCKSIZE]) )))) return b"".join(ciphertext) -def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX): +def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX, mesh=False): """ CBC decryption mode of operation :param bytes key: encryption key @@ -321,6 +324,7 @@ def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX): :type bool pad: perform ISO/IEC 7816-4 unpadding after decryption :param sbox: S-box parameters to use :type sbox: str, SBOXES'es key + :param bool mesh: enable key meshing :returns: plaintext :rtype: bytes """ @@ -330,8 +334,15 @@ def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX): raise ValueError("Data is not blocksize aligned") if len(data) < 2 * BLOCKSIZE: raise ValueError("There is no either data, or IV in ciphertext") + iv = data[:BLOCKSIZE] plaintext = [] for i in xrange(BLOCKSIZE, len(data), BLOCKSIZE): + if ( + mesh and + (i - BLOCKSIZE) >= MESH_MAX_DATA and + (i - BLOCKSIZE) % MESH_MAX_DATA == 0 + ): + key, _ = meshing(key, iv, sbox=sbox) plaintext.append(strxor( ns2block(decrypt(sbox, key, block2ns(data[i:i + BLOCKSIZE]))), data[i - BLOCKSIZE:i], diff --git a/pygost/test_gost28147.py b/pygost/test_gost28147.py index f28618d..037b7b8 100644 --- a/pygost/test_gost28147.py +++ b/pygost/test_gost28147.py @@ -338,6 +338,13 @@ class CBCTest(TestCase): iv = urandom(8) cbc_decrypt(key, cbc_encrypt(key, 8 * b"x", iv)) + def test_meshing(self): + pt = urandom(MESH_MAX_DATA * 3) + key = urandom(32) + ct = cbc_encrypt(key, pt) + dt = cbc_decrypt(key, ct) + self.assertEqual(pt, dt) + class CFBMeshingTest(TestCase): def setUp(self):