Skip to content

Commit

Permalink
Remove excessive byte-swapping in pytwofish.py (libkeepass#336)
Browse files Browse the repository at this point in the history
Since the explicitly little-endian struct format strings are already
handling byte-swapping, remove the WORD_BIGENDIAN flag and all of the
excessive byte-swapping it enables.

Fixes libkeepass#332.
  • Loading branch information
musicinmybrain authored May 12, 2023
1 parent d410a08 commit cb2636d
Showing 1 changed file with 20 additions and 57 deletions.
77 changes: 20 additions & 57 deletions pykeepass/kdbx_parsing/pytwofish.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,22 +137,13 @@ def get_key_size(self):
#

import struct
import sys

WORD_BIGENDIAN = 0
if sys.byteorder == 'big':
WORD_BIGENDIAN = 1

def rotr32(x, n):
return (x >> n) | ((x << (32 - n)) & 0xFFFFFFFF)

def rotl32(x, n):
return ((x << n) & 0xFFFFFFFF) | (x >> (32 - n))

def byteswap32(x):
return ((x & 0xff) << 24) | (((x >> 8) & 0xff) << 16) | \
(((x >> 16) & 0xff) << 8) | ((x >> 24) & 0xff)

class TWI:
def __init__(self):
self.k_len = 0 # word32
Expand Down Expand Up @@ -292,14 +283,9 @@ def set_key(pkey, in_key, key_len):
me_key = [0,0,0,0]
mo_key = [0,0,0,0]
for i in range(pkey.k_len):
if WORD_BIGENDIAN:
a = byteswap32(in_key[i + 1])
me_key[i] = a
b = byteswap32(in_key[i + i + 1])
else:
a = in_key[i + i]
me_key[i] = a
b = in_key[i + i + 1]
a = in_key[i + i]
me_key[i] = a
b = in_key[i + i + 1]
mo_key[i] = b
pkey.s_key[pkey.k_len - i - 1] = mds_rem(a, b);
for i in range(0, 40, 2):
Expand All @@ -314,16 +300,10 @@ def set_key(pkey, in_key, key_len):
def encrypt(pkey, in_blk):
blk = [0, 0, 0, 0]

if WORD_BIGENDIAN:
blk[0] = byteswap32(in_blk[0]) ^ pkey.l_key[0];
blk[1] = byteswap32(in_blk[1]) ^ pkey.l_key[1];
blk[2] = byteswap32(in_blk[2]) ^ pkey.l_key[2];
blk[3] = byteswap32(in_blk[3]) ^ pkey.l_key[3];
else:
blk[0] = in_blk[0] ^ pkey.l_key[0];
blk[1] = in_blk[1] ^ pkey.l_key[1];
blk[2] = in_blk[2] ^ pkey.l_key[2];
blk[3] = in_blk[3] ^ pkey.l_key[3];
blk[0] = in_blk[0] ^ pkey.l_key[0];
blk[1] = in_blk[1] ^ pkey.l_key[1];
blk[2] = in_blk[2] ^ pkey.l_key[2];
blk[3] = in_blk[3] ^ pkey.l_key[3];

for i in range(8):
t1 = ( pkey.mk_tab[0][byte(blk[1],3)] ^ pkey.mk_tab[1][byte(blk[1],0)] ^ pkey.mk_tab[2][byte(blk[1],1)] ^ pkey.mk_tab[3][byte(blk[1],2)] );
Expand All @@ -338,32 +318,20 @@ def encrypt(pkey, in_blk):
blk[0] = rotr32(blk[0] ^ ((t0 + t1 + pkey.l_key[4 * (i) + 10]) % 0x100000000), 1);
blk[1] = rotl32(blk[1], 1) ^ ((t0 + 2 * t1 + pkey.l_key[4 * (i) + 11]) % 0x100000000);

if WORD_BIGENDIAN:
in_blk[0] = byteswap32(blk[2] ^ pkey.l_key[4]);
in_blk[1] = byteswap32(blk[3] ^ pkey.l_key[5]);
in_blk[2] = byteswap32(blk[0] ^ pkey.l_key[6]);
in_blk[3] = byteswap32(blk[1] ^ pkey.l_key[7]);
else:
in_blk[0] = blk[2] ^ pkey.l_key[4];
in_blk[1] = blk[3] ^ pkey.l_key[5];
in_blk[2] = blk[0] ^ pkey.l_key[6];
in_blk[3] = blk[1] ^ pkey.l_key[7];
in_blk[0] = blk[2] ^ pkey.l_key[4];
in_blk[1] = blk[3] ^ pkey.l_key[5];
in_blk[2] = blk[0] ^ pkey.l_key[6];
in_blk[3] = blk[1] ^ pkey.l_key[7];

return

def decrypt(pkey, in_blk):
blk = [0, 0, 0, 0]

if WORD_BIGENDIAN:
blk[0] = byteswap32(in_blk[0]) ^ pkey.l_key[4];
blk[1] = byteswap32(in_blk[1]) ^ pkey.l_key[5];
blk[2] = byteswap32(in_blk[2]) ^ pkey.l_key[6];
blk[3] = byteswap32(in_blk[3]) ^ pkey.l_key[7];
else:
blk[0] = in_blk[0] ^ pkey.l_key[4];
blk[1] = in_blk[1] ^ pkey.l_key[5];
blk[2] = in_blk[2] ^ pkey.l_key[6];
blk[3] = in_blk[3] ^ pkey.l_key[7];
blk[0] = in_blk[0] ^ pkey.l_key[4];
blk[1] = in_blk[1] ^ pkey.l_key[5];
blk[2] = in_blk[2] ^ pkey.l_key[6];
blk[3] = in_blk[3] ^ pkey.l_key[7];

for i in range(7, -1, -1):
t1 = ( pkey.mk_tab[0][byte(blk[1],3)] ^ pkey.mk_tab[1][byte(blk[1],0)] ^ pkey.mk_tab[2][byte(blk[1],1)] ^ pkey.mk_tab[3][byte(blk[1],2)] )
Expand All @@ -378,16 +346,11 @@ def decrypt(pkey, in_blk):
blk[0] = rotl32(blk[0], 1) ^ ((t0 + t1 + pkey.l_key[4 * (i) + 8]) % 0x100000000)
blk[1] = rotr32(blk[1] ^ ((t0 + 2 * t1 + pkey.l_key[4 * (i) + 9]) % 0x100000000), 1)

if WORD_BIGENDIAN:
in_blk[0] = byteswap32(blk[2] ^ pkey.l_key[0]);
in_blk[1] = byteswap32(blk[3] ^ pkey.l_key[1]);
in_blk[2] = byteswap32(blk[0] ^ pkey.l_key[2]);
in_blk[3] = byteswap32(blk[1] ^ pkey.l_key[3]);
else:
in_blk[0] = blk[2] ^ pkey.l_key[0];
in_blk[1] = blk[3] ^ pkey.l_key[1];
in_blk[2] = blk[0] ^ pkey.l_key[2];
in_blk[3] = blk[1] ^ pkey.l_key[3];
in_blk[0] = blk[2] ^ pkey.l_key[0];
in_blk[1] = blk[3] ^ pkey.l_key[1];
in_blk[2] = blk[0] ^ pkey.l_key[2];
in_blk[3] = blk[1] ^ pkey.l_key[3];

return

__testkey = b'\xD4\x3B\xB7\x55\x6E\xA3\x2E\x46\xF2\xA2\x82\xB7\xD4\x5B\x4E\x0D\x57\xFF\x73\x9D\x4D\xC9\x2C\x1B\xD7\xFC\x01\x70\x0C\xC8\x21\x6F'
Expand Down

0 comments on commit cb2636d

Please sign in to comment.