# coding: utf-8
# PyGOST -- Pure Python GOST cryptographic functions library
-# Copyright (C) 2015-2018 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2015-2020 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
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
from struct import unpack
from pygost.gost28147 import cfb_encrypt
+from pygost.gost28147 import DEFAULT_SBOX
from pygost.gost28147 import ecb_decrypt
from pygost.gost28147 import ecb_encrypt
from pygost.gost28147_mac import MAC
-def wrap_gost(ukm, kek, cek):
+def wrap_gost(ukm, kek, cek, sbox=DEFAULT_SBOX):
"""28147-89 key wrapping
:param ukm: UKM
:returns: wrapped key
:rtype: bytes, 44 bytes
"""
- cek_mac = MAC(kek, data=cek, iv=ukm).digest()[:4]
- cek_enc = ecb_encrypt(kek, cek)
+ cek_mac = MAC(kek, data=cek, iv=ukm, sbox=sbox).digest()[:4]
+ cek_enc = ecb_encrypt(kek, cek, sbox=sbox)
return ukm + cek_enc + cek_mac
-def unwrap_gost(kek, data):
+def unwrap_gost(kek, data, sbox=DEFAULT_SBOX):
"""28147-89 key unwrapping
:param kek: key encryption key
if len(data) != 44:
raise ValueError("Invalid data length")
ukm, cek_enc, cek_mac = data[:8], data[8:8 + 32], data[-4:]
- cek = ecb_decrypt(kek, cek_enc)
- if MAC(kek, data=cek, iv=ukm).digest()[:4] != cek_mac:
+ cek = ecb_decrypt(kek, cek_enc, sbox=sbox)
+ if MAC(kek, data=cek, iv=ukm, sbox=sbox).digest()[:4] != cek_mac:
raise ValueError("Invalid MAC")
return cek
-def wrap_cryptopro(ukm, kek, cek):
+def wrap_cryptopro(ukm, kek, cek, sbox=DEFAULT_SBOX):
"""CryptoPro key wrapping
:param ukm: UKM
:returns: wrapped key
:rtype: bytes, 44 bytes
"""
- return wrap_gost(ukm, diversify(kek, bytearray(ukm)), cek)
+ return wrap_gost(ukm, diversify(kek, bytearray(ukm)), cek, sbox=sbox)
-def unwrap_cryptopro(kek, data):
+def unwrap_cryptopro(kek, data, sbox=DEFAULT_SBOX):
"""CryptoPro key unwrapping
:param kek: key encryption key
"""
if len(data) < 8:
raise ValueError("Invalid data length")
- return unwrap_gost(diversify(kek, bytearray(data[:8])), data)
+ return unwrap_gost(
+ diversify(kek, bytearray(data[:8]), sbox=sbox),
+ data,
+ sbox=sbox,
+ )
-def diversify(kek, ukm):
+def diversify(kek, ukm, sbox=DEFAULT_SBOX):
out = kek
for i in range(8):
s1, s2 = 0, 0
else:
s2 += k
iv = pack("<I", s1 % 2 ** 32) + pack("<I", s2 % 2 ** 32)
- out = cfb_encrypt(out, out, iv=iv)
+ out = cfb_encrypt(out, out, iv=iv, sbox=sbox)
return out