]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/wrap.py
KExp15/KImp15
[pygost.git] / pygost / wrap.py
index a3c206ca4c52a02c61e35fb55806fed0d5a36ae3..301023eda18228d35ca1b00d2916afc30495e30a 100644 (file)
@@ -18,6 +18,7 @@
 :rfc:`4357` key wrapping (28147-89 and CryptoPro).
 """
 
+from hmac import compare_digest
 from struct import pack
 from struct import unpack
 
@@ -26,6 +27,8 @@ from pygost.gost28147 import DEFAULT_SBOX
 from pygost.gost28147 import ecb_decrypt
 from pygost.gost28147 import ecb_encrypt
 from pygost.gost28147_mac import MAC
+from pygost.gost3413 import ctr
+from pygost.gost3413 import mac
 
 
 def wrap_gost(ukm, kek, cek, sbox=DEFAULT_SBOX):
@@ -111,3 +114,34 @@ def diversify(kek, ukm, sbox=DEFAULT_SBOX):
         iv = pack("<I", s1 % 2 ** 32) + pack("<I", s2 % 2 ** 32)
         out = cfb_encrypt(out, out, iv=iv, sbox=sbox)
     return out
+
+
+def kexp15(encrypter_key, encrypter_mac, bs, key, iv):
+    """KExp15 key exporting
+
+    :param encrypter_key: encrypting function for key encryption,
+                          that takes block as an input
+    :param encrypter_mac: encrypting function for key authentication
+    :param int bs: cipher's blocksize, bytes
+    :param bytes key: key to export
+    :param bytes iv: half blocksize-sized initialization vector
+    """
+    key_mac = mac(encrypter_mac, bs, iv + key)
+    return ctr(encrypter_key, bs, key + key_mac, iv)
+
+
+def kimp15(encrypter_key, encrypter_mac, bs, kexp, iv):
+    """KImp15 key importing
+
+    :param encrypter_key: encrypting function for key decryption,
+                          that takes block as an input
+    :param encrypter_mac: encrypting function for key authentication
+    :param int bs: cipher's blocksize, bytes
+    :param bytes kexp: key to import
+    :param bytes iv: half blocksize-sized initialization vector
+    """
+    key_and_key_mac = ctr(encrypter_key, bs, kexp, iv)
+    key, key_mac = key_and_key_mac[:-bs], key_and_key_mac[-bs:]
+    if not compare_digest(mac(encrypter_mac, bs, iv + key), key_mac):
+        raise ValueError("invalid authentication tag")
+    return key