-- CryptoAES.hs: OpenPGP (RFC9580) AES helper utilities
-- Copyright © 2012-2026  Clint Adams
-- This software is released under the terms of the Expat license.
-- (See the LICENSE file).
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE RankNTypes #-}

module Codec.Encryption.OpenPGP.Internal.CryptoAES
    ( withAESCipher
    ) where

import qualified Crypto.Error as CE
import Data.Bifunctor (first)
import qualified Data.ByteString as B
import qualified "crypton" Crypto.Cipher.AES as AES
import qualified "crypton" Crypto.Cipher.Types as CCT

import Codec.Encryption.OpenPGP.Types

withAESCipher
    :: (CE.CryptoError -> e)
    -> e
    -> SymmetricAlgorithm
    -> B.ByteString
    -> (forall cipher. CCT.BlockCipher cipher => cipher -> Either e a)
    -> Either e a
withAESCipher mkCryptoError unsupportedSymmetricError symalgo keyBytes f =
    case symalgo of
        AES128 ->
            first
                mkCryptoError
                ( CE.eitherCryptoError
                    (CCT.cipherInit keyBytes :: CE.CryptoFailable AES.AES128)
                )
                >>= f
        AES192 ->
            first
                mkCryptoError
                ( CE.eitherCryptoError
                    (CCT.cipherInit keyBytes :: CE.CryptoFailable AES.AES192)
                )
                >>= f
        AES256 ->
            first
                mkCryptoError
                ( CE.eitherCryptoError
                    (CCT.cipherInit keyBytes :: CE.CryptoFailable AES.AES256)
                )
                >>= f
        _ -> Left unsupportedSymmetricError
