Legrandin / pycryptodome

A self-contained cryptographic library for Python
https://www.pycryptodome.org
Other
2.81k stars 502 forks source link

aes-gcm got wrong tag on arm #728

Closed fthmko closed 1 year ago

fthmko commented 1 year ago

Hi, I'm using aes-gcm on windows arm, with python 3.8.10-x64 and pycryptodome 3.17.0, got error 'MAC check failed' when decryption.

I've found that when using the same input and nonce, the tag part changed in different python.exe process, and keep the same in same process (but all of these are wrong tag).

Tested with this code, use fixed nonce to got same result as expected.

from Crypto.Cipher import AES
content = 'The quick brown fox jumps over the lazy dog'
key = '1234567890123456'.encode('utf-8')
nonce = '123456789012'.encode('utf-8')
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
enc, tag = cipher.encrypt_and_digest(content.encode('utf-8'))
print('body:', enc.hex(), '\ntag:', tag.hex())

on win11-arm64 fist process: body: e5190b88a9e43d6bccd179c7394634649011002415b6c1f81a8afabb5d4cafa97e51532b3f6454128765af tag: 931873920f4a94caed6155aa4b132f8a

on win11-arm64 second process: body: e5190b88a9e43d6bccd179c7394634649011002415b6c1f81a8afabb5d4cafa97e51532b3f6454128765af tag: 119fa21da4ad44de1b7837c2b73816bc

on x64 pc(keep same every time): body: e5190b88a9e43d6bccd179c7394634649011002415b6c1f81a8afabb5d4cafa97e51532b3f6454128765af tag: 8e655a2ffd2cf34ba5e3b5796b82bc7e

I'm not sure this is an issue of pycryptodome, or the windows emmulator.

oestej commented 1 year ago

I'm also looking at an issue in our application where decryption of a file encrypted with AES-GCM appears to be producing incorrect plaintext outputs using python 3.10.10 and pycryptodome 3.17.0 specifically on Windows 10 - ARM in Parallels on a M1 Mac, when the same code produces a different output on all other platforms using the same source data.

Possibly related to some sort of core cipher issue on Windows 10 - ARM?

fthmko commented 1 year ago

More test with 3.17.0:

Legrandin commented 1 year ago

@fthmko Can you share how you installed Python 3.8 x64 on Windows - ARM? And I assume that :o: means "works" and :x: means "doesn't work", in your last message, right?

fthmko commented 1 year ago

@Legrandin Yes, you are right. I'm using the official windows installer with -amd64 sufix. Also trid 3.10.11-amd64 got the same issue.

From 3.11 the python-arm64 is available for windows, but pycryptodome need to be compiled when installing. I will try this way later after my visual studio get ready.

Legrandin commented 1 year ago

I looked into it, managed to reproduce it using Python 3.11 (-amd64, official installer) in Win11 for ARM running on an M1 under UTM, and narrow it down to an issue with the Intel AESNI instruction (which clearly must get emulated).

However, it appears that a simple refactoring (done to enable more unit testing) makes the problem disappear:

https://github.com/Legrandin/pycryptodome/commit/6f942d13e857617351a7a75b3d4e4eeb9a5b1772#diff-e44e95969b5406bb4933af88c0cf804e732e8aa7573bb928201eae5d891294f4

This indicates some problem in the x86 emulator in Windows. I can release this version to see it it helps, but getting to the root cause requires following the disassembly, which is very time consuming.

PS: in this configuration, pycryptodome does not need to be compiled. It installs with the x86 wheel from pypi.

fthmko commented 1 year ago

Wow, this is good news indeed. I have spent several days dealing with various errors encountered during compilation and given up now. I don't know much about C, so I think perhaps the source is writen for x86 and won't be compiled directly to arm .

Look forward to your new release :)

Legrandin commented 1 year ago

The workaround is now in v3.18.0 - could you please check again?

fthmko commented 1 year ago

Yes! It works fine now!

I've run tests with v3.18.0 on these cases, and all of them got correct result.

Thank u for your effort on this!