Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nondeterministic AES decryption? #329

neongreen opened this issue Jul 27, 2020 · 3 comments

Nondeterministic AES decryption? #329

neongreen opened this issue Jul 27, 2020 · 3 comments


Copy link

I am debugging a production issue where something in the AES128 decryption chain (using cbcDecrypt) sometimes gives a wrong result — e.g. one time out of ten it would produce a completely different string than the expected one. There seems to be no randomness in the chain anywhere.

Unfortunately I can't reproduce it easily and can't give a minimal test case yet.

Until I produce a minimal test case — has anyone hit this before? Are there any clues as to why it might happen?

I am using cryptonite-0.26 — not the latest version. I see there are various AES changes in 0.27, but nothing concerning CBC (?). Switching to the next version is non-trivial — should I try anyway? Are there any AES-concerning changes there that I missed?

Copy link

This code is similar to the one that is failing, but, again, it's tricky to reproduce because it doesn't happen locally — so I don't know how useful this will be, if at all.

{-# LANGUAGE OverloadedStrings #-}
module Main where
import           Control.Monad       (when)
import           Crypto.Cipher.AES   (AES128)
import           Crypto.Cipher.Types (IV, cbcDecrypt, cipherInit, makeIV)
import           Crypto.Error        (CryptoFailable (..))
import           Data.ByteString     (ByteString)
import           Data.Foldable       (traverse_)
import           Data.Maybe          (fromMaybe)
iterations :: Int
iterations = 1000000
plaintext :: ByteString
plaintext = "random\n\n\n\n\n\n\n\n\n\n"
ciphertext :: ByteString
ciphertext = "\217\158i\238kt\244\139\227\147\244j\195\229\200%"
key :: ByteString
key = "abcdefghijklmnop"
iv :: IV AES128
iv = fromMaybe (error "bad IV") . makeIV $ ("@@@@&&&&####$$$$" :: ByteString)
decrypt :: ByteString -> ByteString
decrypt c = case cipherInit key of
  CryptoFailed _    -> error "bad key"
  CryptoPassed ciph -> cbcDecrypt ciph iv c
main :: IO ()
main = traverse_ go [1 .. iterations]
    go _ = do
      let result = decrypt ciphertext
      when (result /= plaintext) (err result)
    err res = error ("Decryption failed: expected " <>
                      show plaintext <>
                      " actual " <>
                      show res)

Copy link

The issue went away when I disabled AESNI.

Copy link

jjantura commented Mar 3, 2022

Same issue encountered, thanks @neongreen for a hint how to "fix".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

No branches or pull requests

2 participants