]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/gost3413.py
(un)pad_iso10126
[pygost.git] / pygost / gost3413.py
index 5aeaec63ef415091ae3de81b64facb57e0af62bd..27f0c30dc79a75de4e66f8e284455221474fa215 100644 (file)
@@ -1,6 +1,6 @@
 # coding: utf-8
 # PyGOST -- Pure Python GOST cryptographic functions library
-# Copyright (C) 2015-2020 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2015-2022 Sergey Matveev <stargrave@stargrave.org>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-""" GOST R 34.13-2015: Modes of operation for block ciphers
+"""GOST R 34.13-2015: Modes of operation for block ciphers
 
 This module currently includes only padding methods.
 """
 
+from os import urandom
+
 from pygost.utils import bytes2long
 from pygost.utils import long2bytes
 from pygost.utils import strxor
@@ -274,7 +276,7 @@ Rb128 = 0b10000111
 
 def _mac_ks(encrypter, bs):
     Rb = Rb128 if bs == 16 else Rb64
-    _l = encrypter(bs * b'\x00')
+    _l = encrypter(bs * b"\x00")
     k1 = _mac_shift(bs, _l, Rb) if bytearray(_l)[0] & 0x80 > 0 else _mac_shift(bs, _l)
     k2 = _mac_shift(bs, k1, Rb) if bytearray(k1)[0] & 0x80 > 0 else _mac_shift(bs, k1)
     return k1, k2
@@ -294,7 +296,7 @@ def mac(encrypter, bs, data):
         tail_offset = len(data) - bs
     else:
         tail_offset = len(data) - (len(data) % bs)
-    prev = bs * b'\x00'
+    prev = bs * b"\x00"
     for i in xrange(0, tail_offset, bs):
         prev = encrypter(strxor(data[i:i + bs], prev))
     tail = data[tail_offset:]
@@ -337,7 +339,7 @@ def mac_acpkm_master(algo_class, encrypter, key_section_size, section_size, bs,
         tail_offset = len(data) - bs
     else:
         tail_offset = len(data) - (len(data) % bs)
-    prev = bs * b'\x00'
+    prev = bs * b"\x00"
     sections = len(data) // section_size
     if len(data) % section_size != 0:
         sections += 1
@@ -365,3 +367,26 @@ def mac_acpkm_master(algo_class, encrypter, key_section_size, section_size, bs,
         strxor(pad3(tail, bs), prev),
         k1 if len(tail) == bs else k2,
     ))
+
+
+def pad_iso10126(data, blocksize):
+    """ISO 10126 padding
+
+    Does not exist in 34.13, but added for convenience.
+    It uses urandom call for getting the randomness.
+    """
+    pad_len = blocksize - len(data) % blocksize
+    if pad_len == 0:
+        pad_len = blocksize
+    return b"".join((data, urandom(pad_len - 1), bytes((pad_len,))))
+
+
+def unpad_iso10126(data, blocksize):
+    """Unpad :py:func:`pygost.gost3413.pad_iso10126`
+    """
+    if len(data) % blocksize != 0:
+        raise ValueError("Data length is not multiple of blocksize")
+    pad_len = bytearray(data)[-1]
+    if pad_len > blocksize:
+        raise ValueError("Padding length is bigger than blocksize")
+    return data[:-pad_len]