Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Nondeterministic AES decryption? #329

Closed
neongreen opened this issue Jul 27, 2020 · 3 comments
Closed

Nondeterministic AES decryption? #329

neongreen opened this issue Jul 27, 2020 · 3 comments

Comments

@neongreen
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?

@neongreen
Copy link
Author

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]
  where
    go _ = do
      let result = decrypt ciphertext
      when (result /= plaintext) (err result)
    err res = error ("Decryption failed: expected " <>
                      show plaintext <>
                      " actual " <>
                      show res)

@neongreen
Copy link
Author

The issue went away when I disabled AESNI.

@ghost
Copy link

ghost commented Mar 3, 2022

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

@vincenthz vincenthz closed this as not planned Won't fix, can't repro, duplicate, stale Sep 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants