X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Fgost3413.py;h=27f0c30dc79a75de4e66f8e284455221474fa215;hb=a9f7e3dfc59a987c3d6cce4108f18d9f6b72867b;hp=5aeaec63ef415091ae3de81b64facb57e0af62bd;hpb=7e5fe8586c0f17834a8df558b7ca86c5d7accd3e;p=pygost.git diff --git a/pygost/gost3413.py b/pygost/gost3413.py index 5aeaec6..27f0c30 100644 --- a/pygost/gost3413.py +++ b/pygost/gost3413.py @@ -1,6 +1,6 @@ # coding: utf-8 # PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2020 Sergey Matveev +# Copyright (C) 2015-2022 Sergey Matveev # # 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 @@ -13,11 +13,13 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -""" 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]