crypto optimization
Great to see the crypto.py in action!  If I may, can I suggest a modification:

In crypto.py the key is padded and the keygen function is called every time encrypt() or decrypt() is called. The keygen function is cpu time intensive, so I would like to suggest that the padding process and keygen function be moved out of encrypt() or decrypt()  keygen would then only be called twice at start up: once with the user password and once with the panel supplied password. The precalculated saved padded/expanded key would then be passed to encrypt() or decrypt() from then on.

Very minor issue: the array 'shifts' is nested one too many times deep, so in the function shift_row() we see shifts[0][i][d]) % 4] with the fixed [0] index, which is not required.