Merge pull request #292 from ocheron/aes-gcm-siv

AES-GCM-SIV
This commit is contained in:
Olivier Chéron 2019-09-08 09:49:35 +02:00
commit 65643a3bea
11 changed files with 879 additions and 0 deletions

View File

@ -37,6 +37,9 @@ module Crypto.Cipher.AES.Primitive
, decryptCTR , decryptCTR
, decryptXTS , decryptXTS
-- * CTR with 32-bit wrapping
, combineC32
-- * Incremental GCM -- * Incremental GCM
, gcmMode , gcmMode
, gcmInit , gcmInit
@ -317,6 +320,21 @@ decryptXTS :: ByteArray ba
-> ba -- ^ output decrypted -> ba -- ^ output decrypted
decryptXTS = doXTS c_aes_decrypt_xts decryptXTS = doXTS c_aes_decrypt_xts
-- | encrypt/decrypt using Counter mode (32-bit wrapping used in AES-GCM-SIV)
{-# NOINLINE combineC32 #-}
combineC32 :: ByteArray ba
=> AES -- ^ AES Context
-> IV AES -- ^ initial vector of AES block size (usually representing a 128 bit integer)
-> ba -- ^ plaintext input
-> ba -- ^ ciphertext output
combineC32 ctx iv input
| len <= 0 = B.empty
| B.length iv /= 16 = error $ "AES error: IV length must be block size (16). Its length is: " ++ show (B.length iv)
| otherwise = B.allocAndFreeze len doEncrypt
where doEncrypt o = withKeyAndIV ctx iv $ \k v -> withByteArray input $ \i ->
c_aes_encrypt_c32 (castPtr o) k v i (fromIntegral len)
len = B.length input
{-# INLINE doECB #-} {-# INLINE doECB #-}
doECB :: ByteArray ba doECB :: ByteArray ba
=> (Ptr b -> Ptr AES -> CString -> CUInt -> IO ()) => (Ptr b -> Ptr AES -> CString -> CUInt -> IO ())
@ -578,6 +596,9 @@ foreign import ccall unsafe "cryptonite_aes.h cryptonite_aes_gen_ctr_cont"
foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_ctr" foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_ctr"
c_aes_encrypt_ctr :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO () c_aes_encrypt_ctr :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_c32"
c_aes_encrypt_c32 :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_init" foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_init"
c_aes_gcm_init :: Ptr AESGCM -> Ptr AES -> Ptr Word8 -> CUInt -> IO () c_aes_gcm_init :: Ptr AESGCM -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()

193
Crypto/Cipher/AESGCMSIV.hs Normal file
View File

@ -0,0 +1,193 @@
-- |
-- Module : Crypto.Cipher.AESGCMSIV
-- License : BSD-style
-- Maintainer : Olivier Chéron <olivier.cheron@gmail.com>
-- Stability : experimental
-- Portability : unknown
--
-- Implementation of AES-GCM-SIV, an AEAD scheme with nonce misuse resistance
-- defined in <https://tools.ietf.org/html/rfc8452 RFC 8452>.
--
-- To achieve the nonce misuse-resistance property, encryption requires two
-- passes on the plaintext, hence no streaming API is provided. This AEAD
-- operates on complete inputs held in memory. For simplicity, the
-- implementation of decryption uses a similar pattern, with performance
-- penalty compared to an implementation which is able to merge both passes.
--
-- The specification allows inputs up to 2^36 bytes but this implementation
-- requires AAD and plaintext/ciphertext to be both smaller than 2^32 bytes.
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Crypto.Cipher.AESGCMSIV
( Nonce
, nonce
, generateNonce
, encrypt
, decrypt
) where
import Data.Bits
import Data.Word
import Foreign.C.Types
import Foreign.C.String
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.Storable (peekElemOff, poke, pokeElemOff)
import Data.ByteArray
import qualified Data.ByteArray as B
import Data.Memory.Endian (toLE)
import Data.Memory.PtrMethods (memXor)
import Crypto.Cipher.AES.Primitive
import Crypto.Cipher.Types
import Crypto.Error
import Crypto.Internal.Compat (unsafeDoIO)
import Crypto.Random
-- 12-byte nonces
-- | Nonce value for AES-GCM-SIV, always 12 bytes.
newtype Nonce = Nonce Bytes deriving (Show, Eq, ByteArrayAccess)
-- | Nonce smart constructor. Accepts only 12-byte inputs.
nonce :: ByteArrayAccess iv => iv -> CryptoFailable Nonce
nonce iv
| B.length iv == 12 = CryptoPassed (Nonce $ B.convert iv)
| otherwise = CryptoFailed CryptoError_IvSizeInvalid
-- | Generate a random nonce for use with AES-GCM-SIV.
generateNonce :: MonadRandom m => m Nonce
generateNonce = Nonce <$> getRandomBytes 12
-- POLYVAL (mutable context)
newtype Polyval = Polyval Bytes
polyvalInit :: ScrubbedBytes -> IO Polyval
polyvalInit h = Polyval <$> doInit
where doInit = B.alloc 272 $ \pctx -> B.withByteArray h $ \ph ->
c_aes_polyval_init pctx ph
polyvalUpdate :: ByteArrayAccess ba => Polyval -> ba -> IO ()
polyvalUpdate (Polyval ctx) bs = B.withByteArray ctx $ \pctx ->
B.withByteArray bs $ \pbs -> c_aes_polyval_update pctx pbs sz
where sz = fromIntegral (B.length bs)
polyvalFinalize :: Polyval -> IO ScrubbedBytes
polyvalFinalize (Polyval ctx) = B.alloc 16 $ \dst ->
B.withByteArray ctx $ \pctx -> c_aes_polyval_finalize pctx dst
foreign import ccall unsafe "cryptonite_aes.h cryptonite_aes_polyval_init"
c_aes_polyval_init :: Ptr Polyval -> CString -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_polyval_update"
c_aes_polyval_update :: Ptr Polyval -> CString -> CUInt -> IO ()
foreign import ccall unsafe "cryptonite_aes.h cryptonite_aes_polyval_finalize"
c_aes_polyval_finalize :: Ptr Polyval -> CString -> IO ()
-- Key Generation
le32iv :: Word32 -> Nonce -> Bytes
le32iv n (Nonce iv) = B.allocAndFreeze 16 $ \ptr -> do
poke ptr (toLE n)
copyByteArrayToPtr iv (ptr `plusPtr` 4)
deriveKeys :: BlockCipher128 aes => aes -> Nonce -> (ScrubbedBytes, AES)
deriveKeys aes iv =
case cipherKeySize aes of
KeySizeFixed sz | sz `mod` 8 == 0 ->
let mak = buildKey [0 .. 1]
key = buildKey [2 .. fromIntegral (sz `div` 8) + 1]
mek = throwCryptoError (cipherInit key)
in (mak, mek)
_ -> error "AESGCMSIV: invalid cipher"
where
idx n = ecbEncrypt aes (le32iv n iv) `takeView` 8
buildKey = B.concat . map idx
-- Encryption and decryption
lengthInvalid :: ByteArrayAccess ba => ba -> Bool
lengthInvalid bs
| finiteBitSize len > 32 = len >= 1 `unsafeShiftL` 32
| otherwise = False
where len = B.length bs
-- | AEAD encryption with the specified key and nonce. The key must be given
-- as an initialized 'Crypto.Cipher.AES.AES128' or 'Crypto.Cipher.AES.AES256'
-- cipher.
--
-- Lengths of additional data and plaintext must be less than 2^32 bytes,
-- otherwise an exception is thrown.
encrypt :: (BlockCipher128 aes, ByteArrayAccess aad, ByteArray ba)
=> aes -> Nonce -> aad -> ba -> (AuthTag, ba)
encrypt aes iv aad plaintext
| lengthInvalid aad = error "AESGCMSIV: aad is too large"
| lengthInvalid plaintext = error "AESGCMSIV: plaintext is too large"
| otherwise = (AuthTag tag, ciphertext)
where
(mak, mek) = deriveKeys aes iv
ss = getSs mak aad plaintext
tag = buildTag mek ss iv
ciphertext = combineC32 mek (transformTag tag) plaintext
-- | AEAD decryption with the specified key and nonce. The key must be given
-- as an initialized 'Crypto.Cipher.AES.AES128' or 'Crypto.Cipher.AES.AES256'
-- cipher.
--
-- Lengths of additional data and ciphertext must be less than 2^32 bytes,
-- otherwise an exception is thrown.
decrypt :: (BlockCipher128 aes, ByteArrayAccess aad, ByteArray ba)
=> aes -> Nonce -> aad -> ba -> AuthTag -> Maybe ba
decrypt aes iv aad ciphertext (AuthTag tag)
| lengthInvalid aad = error "AESGCMSIV: aad is too large"
| lengthInvalid ciphertext = error "AESGCMSIV: ciphertext is too large"
| tag `constEq` buildTag mek ss iv = Just plaintext
| otherwise = Nothing
where
(mak, mek) = deriveKeys aes iv
ss = getSs mak aad plaintext
plaintext = combineC32 mek (transformTag tag) ciphertext
-- Calculate S_s = POLYVAL(mak, X_1, X_2, ...).
getSs :: (ByteArrayAccess aad, ByteArrayAccess ba)
=> ScrubbedBytes -> aad -> ba -> ScrubbedBytes
getSs mak aad plaintext = unsafeDoIO $ do
ctx <- polyvalInit mak
polyvalUpdate ctx aad
polyvalUpdate ctx plaintext
polyvalUpdate ctx (lb :: Bytes) -- the "length block"
polyvalFinalize ctx
where
lb = B.allocAndFreeze 16 $ \ptr -> do
pokeElemOff ptr 0 (toLE64 $ B.length aad)
pokeElemOff ptr 1 (toLE64 $ B.length plaintext)
toLE64 x = toLE (fromIntegral x * 8 :: Word64)
-- XOR the first 12 bytes of S_s with the nonce and clear the most significant
-- bit of the last byte.
tagInput :: ScrubbedBytes -> Nonce -> Bytes
tagInput ss (Nonce iv) =
B.copyAndFreeze ss $ \ptr ->
B.withByteArray iv $ \ivPtr -> do
memXor ptr ptr ivPtr 12
b <- peekElemOff ptr 15
pokeElemOff ptr 15 (b .&. (0x7f :: Word8))
-- Encrypt the result with AES using the message-encryption key to produce the
-- tag.
buildTag :: BlockCipher128 aes => aes -> ScrubbedBytes -> Nonce -> Bytes
buildTag mek ss iv = ecbEncrypt mek (tagInput ss iv)
-- The initial counter block is the tag with the most significant bit of the
-- last byte set to one.
transformTag :: Bytes -> IV AES
transformTag tag = toIV $ B.copyAndFreeze tag $ \ptr ->
peekElemOff ptr 15 >>= pokeElemOff ptr 15 . (.|. (0x80 :: Word8))
where toIV bs = let Just iv = makeIV (bs :: Bytes) in iv

View File

@ -6,6 +6,7 @@ module Main where
import Gauge.Main import Gauge.Main
import Crypto.Cipher.AES import Crypto.Cipher.AES
import qualified Crypto.Cipher.AESGCMSIV as AESGCMSIV
import Crypto.Cipher.Blowfish import Crypto.Cipher.Blowfish
import Crypto.Cipher.CAST5 import Crypto.Cipher.CAST5
import qualified Crypto.Cipher.ChaChaPoly1305 as CP import qualified Crypto.Cipher.ChaChaPoly1305 as CP
@ -167,6 +168,7 @@ benchAE =
[ bench "ChaChaPoly1305" $ nf (cp key32) (input64, input1024) [ bench "ChaChaPoly1305" $ nf (cp key32) (input64, input1024)
, bench "AES-GCM" $ nf (gcm key32) (input64, input1024) , bench "AES-GCM" $ nf (gcm key32) (input64, input1024)
, bench "AES-CCM" $ nf (ccm key32) (input64, input1024) , bench "AES-CCM" $ nf (ccm key32) (input64, input1024)
, bench "AES-GCM-SIV" $ nf (gcmsiv key32) (input64, input1024)
] ]
where cp k (ini, plain) = where cp k (ini, plain) =
let iniState = throwCryptoError $ CP.initialize k (throwCryptoError $ CP.nonce12 nonce12) let iniState = throwCryptoError $ CP.initialize k (throwCryptoError $ CP.nonce12 nonce12)
@ -186,6 +188,11 @@ benchAE =
state = throwCryptoError $ aeadInit mode ctx nonce12 state = throwCryptoError $ aeadInit mode ctx nonce12
in aeadSimpleEncrypt state ini plain 16 in aeadSimpleEncrypt state ini plain 16
gcmsiv k (ini, plain) =
let ctx = throwCryptoError (cipherInit k) :: AES256
iv = throwCryptoError (AESGCMSIV.nonce nonce12)
in AESGCMSIV.encrypt ctx iv ini plain
input64 = B.replicate 64 0 input64 = B.replicate 64 0
input1024 = B.replicate 1024 0 input1024 = B.replicate 1024 0

View File

@ -108,6 +108,13 @@ static inline void block128_vxor(block128 *d, const block128 *s1, const block128
} }
} }
static inline void block128_byte_reverse(block128 *a)
{
uint64_t s0 = a->q[0], s1 = a->q[1];
a->q[0] = bitfn_swap64(s1);
a->q[1] = bitfn_swap64(s0);
}
static inline void block128_inc_be(block128 *b) static inline void block128_inc_be(block128 *b)
{ {
uint64_t v = be64_to_cpu(b->q[1]); uint64_t v = be64_to_cpu(b->q[1]);
@ -123,6 +130,11 @@ static inline void block128_inc32_be(block128 *b)
b->d[3] = cpu_to_be32(be32_to_cpu(b->d[3]) + 1); b->d[3] = cpu_to_be32(be32_to_cpu(b->d[3]) + 1);
} }
static inline void block128_inc32_le(block128 *b)
{
b->d[0] = cpu_to_le32(le32_to_cpu(b->d[0]) + 1);
}
#ifdef IMPL_DEBUG #ifdef IMPL_DEBUG
#include <stdio.h> #include <stdio.h>
static inline void block128_print(block128 *b) static inline void block128_print(block128 *b)

View File

@ -64,6 +64,8 @@ void cryptonite_aesni_decrypt_cbc128(aes_block *out, aes_key *key, aes_block *_i
void cryptonite_aesni_decrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks); void cryptonite_aesni_decrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks);
void cryptonite_aesni_encrypt_ctr128(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length); void cryptonite_aesni_encrypt_ctr128(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length);
void cryptonite_aesni_encrypt_ctr256(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length); void cryptonite_aesni_encrypt_ctr256(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length);
void cryptonite_aesni_encrypt_c32_128(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length);
void cryptonite_aesni_encrypt_c32_256(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length);
void cryptonite_aesni_encrypt_xts128(aes_block *out, aes_key *key1, aes_key *key2, void cryptonite_aesni_encrypt_xts128(aes_block *out, aes_key *key1, aes_key *key2,
aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks); aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks);
void cryptonite_aesni_encrypt_xts256(aes_block *out, aes_key *key1, aes_key *key2, void cryptonite_aesni_encrypt_xts256(aes_block *out, aes_key *key1, aes_key *key2,

View File

@ -151,6 +151,47 @@ void SIZED(cryptonite_aesni_encrypt_ctr)(uint8_t *output, aes_key *key, aes_bloc
return ; return ;
} }
void SIZED(cryptonite_aesni_encrypt_c32_)(uint8_t *output, aes_key *key, aes_block *_iv, uint8_t *input, uint32_t len)
{
__m128i *k = (__m128i *) key->data;
__m128i one = _mm_set_epi32(0,0,0,1);
uint32_t nb_blocks = len / 16;
uint32_t part_block_len = len % 16;
/* get the IV */
__m128i iv = _mm_loadu_si128((__m128i *) _iv);
PRELOAD_ENC(k);
for (; nb_blocks-- > 0; output += 16, input += 16) {
/* encrypt the iv and and xor it the input block */
__m128i tmp = iv;
DO_ENC_BLOCK(tmp);
__m128i m = _mm_loadu_si128((__m128i *) input);
m = _mm_xor_si128(m, tmp);
_mm_storeu_si128((__m128i *) output, m);
/* iv += 1 */
iv = _mm_add_epi32(iv, one);
}
if (part_block_len != 0) {
aes_block block;
memset(&block.b, 0, 16);
memcpy(&block.b, input, part_block_len);
__m128i m = _mm_loadu_si128((__m128i *) &block);
__m128i tmp = iv;
DO_ENC_BLOCK(tmp);
m = _mm_xor_si128(m, tmp);
_mm_storeu_si128((__m128i *) &block.b, m);
memcpy(output, &block.b, part_block_len);
}
return ;
}
void SIZED(cryptonite_aesni_encrypt_xts)(aes_block *out, aes_key *key1, aes_key *key2, void SIZED(cryptonite_aesni_encrypt_xts)(aes_block *out, aes_key *key1, aes_key *key2,
aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks) aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks)
{ {

View File

@ -44,6 +44,7 @@ void cryptonite_aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_blo
void cryptonite_aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
void cryptonite_aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks);
void cryptonite_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length); void cryptonite_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length);
void cryptonite_aes_generic_encrypt_c32(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length);
void cryptonite_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, void cryptonite_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
uint32_t spoint, aes_block *input, uint32_t nb_blocks); uint32_t spoint, aes_block *input, uint32_t nb_blocks);
void cryptonite_aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, void cryptonite_aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
@ -69,6 +70,8 @@ enum {
DECRYPT_CBC_128, DECRYPT_CBC_192, DECRYPT_CBC_256, DECRYPT_CBC_128, DECRYPT_CBC_192, DECRYPT_CBC_256,
/* ctr */ /* ctr */
ENCRYPT_CTR_128, ENCRYPT_CTR_192, ENCRYPT_CTR_256, ENCRYPT_CTR_128, ENCRYPT_CTR_192, ENCRYPT_CTR_256,
/* ctr with 32-bit wrapping */
ENCRYPT_C32_128, ENCRYPT_C32_192, ENCRYPT_C32_256,
/* xts */ /* xts */
ENCRYPT_XTS_128, ENCRYPT_XTS_192, ENCRYPT_XTS_256, ENCRYPT_XTS_128, ENCRYPT_XTS_192, ENCRYPT_XTS_256,
DECRYPT_XTS_128, DECRYPT_XTS_192, DECRYPT_XTS_256, DECRYPT_XTS_128, DECRYPT_XTS_192, DECRYPT_XTS_256,
@ -115,6 +118,10 @@ void *cryptonite_aes_branch_table[] = {
[ENCRYPT_CTR_128] = cryptonite_aes_generic_encrypt_ctr, [ENCRYPT_CTR_128] = cryptonite_aes_generic_encrypt_ctr,
[ENCRYPT_CTR_192] = cryptonite_aes_generic_encrypt_ctr, [ENCRYPT_CTR_192] = cryptonite_aes_generic_encrypt_ctr,
[ENCRYPT_CTR_256] = cryptonite_aes_generic_encrypt_ctr, [ENCRYPT_CTR_256] = cryptonite_aes_generic_encrypt_ctr,
/* CTR with 32-bit wrapping */
[ENCRYPT_C32_128] = cryptonite_aes_generic_encrypt_c32,
[ENCRYPT_C32_192] = cryptonite_aes_generic_encrypt_c32,
[ENCRYPT_C32_256] = cryptonite_aes_generic_encrypt_c32,
/* XTS */ /* XTS */
[ENCRYPT_XTS_128] = cryptonite_aes_generic_encrypt_xts, [ENCRYPT_XTS_128] = cryptonite_aes_generic_encrypt_xts,
[ENCRYPT_XTS_192] = cryptonite_aes_generic_encrypt_xts, [ENCRYPT_XTS_192] = cryptonite_aes_generic_encrypt_xts,
@ -173,6 +180,8 @@ typedef void (*gf_mul_f)(block128 *a, const table_4bit htable);
((cbc_f) (cryptonite_aes_branch_table[DECRYPT_CBC_128 + strength])) ((cbc_f) (cryptonite_aes_branch_table[DECRYPT_CBC_128 + strength]))
#define GET_CTR_ENCRYPT(strength) \ #define GET_CTR_ENCRYPT(strength) \
((ctr_f) (cryptonite_aes_branch_table[ENCRYPT_CTR_128 + strength])) ((ctr_f) (cryptonite_aes_branch_table[ENCRYPT_CTR_128 + strength]))
#define GET_C32_ENCRYPT(strength) \
((ctr_f) (cryptonite_aes_branch_table[ENCRYPT_C32_128 + strength]))
#define GET_XTS_ENCRYPT(strength) \ #define GET_XTS_ENCRYPT(strength) \
((xts_f) (cryptonite_aes_branch_table[ENCRYPT_XTS_128 + strength])) ((xts_f) (cryptonite_aes_branch_table[ENCRYPT_XTS_128 + strength]))
#define GET_XTS_DECRYPT(strength) \ #define GET_XTS_DECRYPT(strength) \
@ -204,6 +213,7 @@ typedef void (*gf_mul_f)(block128 *a, const table_4bit htable);
#define GET_CBC_ENCRYPT(strength) cryptonite_aes_generic_encrypt_cbc #define GET_CBC_ENCRYPT(strength) cryptonite_aes_generic_encrypt_cbc
#define GET_CBC_DECRYPT(strength) cryptonite_aes_generic_decrypt_cbc #define GET_CBC_DECRYPT(strength) cryptonite_aes_generic_decrypt_cbc
#define GET_CTR_ENCRYPT(strength) cryptonite_aes_generic_encrypt_ctr #define GET_CTR_ENCRYPT(strength) cryptonite_aes_generic_encrypt_ctr
#define GET_C32_ENCRYPT(strength) cryptonite_aes_generic_encrypt_c32
#define GET_XTS_ENCRYPT(strength) cryptonite_aes_generic_encrypt_xts #define GET_XTS_ENCRYPT(strength) cryptonite_aes_generic_encrypt_xts
#define GET_XTS_DECRYPT(strength) cryptonite_aes_generic_decrypt_xts #define GET_XTS_DECRYPT(strength) cryptonite_aes_generic_decrypt_xts
#define GET_GCM_ENCRYPT(strength) cryptonite_aes_generic_gcm_encrypt #define GET_GCM_ENCRYPT(strength) cryptonite_aes_generic_gcm_encrypt
@ -251,6 +261,9 @@ static void initialize_table_ni(int aesni, int pclmul)
/* CTR */ /* CTR */
cryptonite_aes_branch_table[ENCRYPT_CTR_128] = cryptonite_aesni_encrypt_ctr128; cryptonite_aes_branch_table[ENCRYPT_CTR_128] = cryptonite_aesni_encrypt_ctr128;
cryptonite_aes_branch_table[ENCRYPT_CTR_256] = cryptonite_aesni_encrypt_ctr256; cryptonite_aes_branch_table[ENCRYPT_CTR_256] = cryptonite_aesni_encrypt_ctr256;
/* CTR with 32-bit wrapping */
cryptonite_aes_branch_table[ENCRYPT_C32_128] = cryptonite_aesni_encrypt_c32_128;
cryptonite_aes_branch_table[ENCRYPT_C32_256] = cryptonite_aesni_encrypt_c32_256;
/* XTS */ /* XTS */
cryptonite_aes_branch_table[ENCRYPT_XTS_128] = cryptonite_aesni_encrypt_xts128; cryptonite_aes_branch_table[ENCRYPT_XTS_128] = cryptonite_aesni_encrypt_xts128;
cryptonite_aes_branch_table[ENCRYPT_XTS_256] = cryptonite_aesni_encrypt_xts256; cryptonite_aes_branch_table[ENCRYPT_XTS_256] = cryptonite_aesni_encrypt_xts256;
@ -352,6 +365,12 @@ void cryptonite_aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, ui
e(output, key, iv, input, len); e(output, key, iv, input, len);
} }
void cryptonite_aes_encrypt_c32(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len)
{
ctr_f e = GET_C32_ENCRYPT(key->strength);
e(output, key, iv, input, len);
}
void cryptonite_aes_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, void cryptonite_aes_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
uint32_t spoint, aes_block *input, uint32_t nb_blocks) uint32_t spoint, aes_block *input, uint32_t nb_blocks)
{ {
@ -789,6 +808,30 @@ void cryptonite_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block
} }
} }
void cryptonite_aes_generic_encrypt_c32(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len)
{
aes_block block, o;
uint32_t nb_blocks = len / 16;
int i;
/* preload IV in block */
block128_copy(&block, iv);
for ( ; nb_blocks-- > 0; block128_inc32_le(&block), output += 16, input += 16) {
cryptonite_aes_encrypt_block(&o, key, &block);
block128_vxor((block128 *) output, &o, (block128 *) input);
}
if ((len % 16) != 0) {
cryptonite_aes_encrypt_block(&o, key, &block);
for (i = 0; i < (len % 16); i++) {
*output = ((uint8_t *) &o)[i] ^ *input;
output++;
input++;
}
}
}
void cryptonite_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, void cryptonite_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit,
uint32_t spoint, aes_block *input, uint32_t nb_blocks) uint32_t spoint, aes_block *input, uint32_t nb_blocks)
{ {
@ -1012,3 +1055,55 @@ void cryptonite_aes_generic_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *
{ {
ocb_generic_crypt(output, ocb, key, input, length, 0); ocb_generic_crypt(output, ocb, key, input, length, 0);
} }
static inline void gf_mulx_rev(block128 *a, const block128 *h)
{
uint64_t v1 = cpu_to_le64(h->q[0]);
uint64_t v0 = cpu_to_le64(h->q[1]);
a->q[1] = cpu_to_be64(v1 >> 1 | v0 << 63);
a->q[0] = cpu_to_be64(v0 >> 1 ^ ((0-(v1 & 1)) & 0xe100000000000000ULL));
}
void cryptonite_aes_polyval_init(aes_polyval *ctx, const aes_block *h)
{
aes_block r;
/* ByteReverse(S_0) = 0 */
block128_zero(&ctx->s);
/* ByteReverse(H) * x */
gf_mulx_rev(&r, h);
cryptonite_hinit(ctx->htable, &r);
}
void cryptonite_aes_polyval_update(aes_polyval *ctx, const uint8_t *input, uint32_t length)
{
aes_block r;
const uint8_t *p;
uint32_t sz;
/* This automatically pads with zeros if input is not a multiple of the
block size. */
for (p = input; length > 0; p += 16, length -= sz)
{
sz = length < 16 ? length : 16;
/* ByteReverse(X_j) */
block128_zero(&r);
memcpy(&r, p, sz);
block128_byte_reverse(&r);
/* ByteReverse(S_{j-1}) + ByteReverse(X_j) */
block128_xor_aligned(&ctx->s, &r);
/* ByteReverse(S_j) */
cryptonite_gf_mul(&ctx->s, ctx->htable);
}
}
void cryptonite_aes_polyval_finalize(aes_polyval *ctx, aes_block *dst)
{
/* S_s */
block128_copy_aligned(dst, &ctx->s);
block128_byte_reverse(dst);
}

View File

@ -77,6 +77,12 @@ typedef struct {
block128 li[4]; block128 li[4];
} aes_ocb; } aes_ocb;
/* size = 17*16= 272 */
typedef struct {
aes_block htable[16];
aes_block s;
} aes_polyval;
/* in bytes: either 16,24,32 */ /* in bytes: either 16,24,32 */
void cryptonite_aes_initkey(aes_key *ctx, uint8_t *key, uint8_t size); void cryptonite_aes_initkey(aes_key *ctx, uint8_t *key, uint8_t size);
@ -117,4 +123,8 @@ void cryptonite_aes_ccm_finish(uint8_t *tag, aes_ccm *ccm, aes_key *key);
uint8_t *cryptonite_aes_cpu_init(void); uint8_t *cryptonite_aes_cpu_init(void);
void cryptonite_aes_polyval_init(aes_polyval *ctx, const aes_block *h);
void cryptonite_aes_polyval_update(aes_polyval *ctx, const uint8_t *input, uint32_t length);
void cryptonite_aes_polyval_finalize(aes_polyval *ctx, aes_block *dst);
#endif #endif

View File

@ -104,6 +104,7 @@ Flag check_alignment
Library Library
Exposed-modules: Crypto.Cipher.AES Exposed-modules: Crypto.Cipher.AES
Crypto.Cipher.AESGCMSIV
Crypto.Cipher.Blowfish Crypto.Cipher.Blowfish
Crypto.Cipher.CAST5 Crypto.Cipher.CAST5
Crypto.Cipher.Camellia Crypto.Cipher.Camellia
@ -395,6 +396,7 @@ Test-Suite test-cryptonite
KAT_AES.KATOCB3 KAT_AES.KATOCB3
KAT_AES.KATXTS KAT_AES.KATXTS
KAT_AES KAT_AES
KAT_AESGCMSIV
KAT_AFIS KAT_AFIS
KAT_Argon2 KAT_Argon2
KAT_Blowfish KAT_Blowfish

494
tests/KAT_AESGCMSIV.hs Normal file
View File

@ -0,0 +1,494 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE RecordWildCards #-}
module KAT_AESGCMSIV (tests) where
import Imports
import Data.Proxy
import qualified Data.ByteArray as B
import Crypto.Cipher.AES
import Crypto.Cipher.AESGCMSIV
import Crypto.Cipher.Types
import Crypto.Error
data Vector c = Vector
{ vecPlaintext :: ByteString
, vecAAD :: ByteString
, vecKey :: ByteString
, vecNonce :: ByteString
, vecTag :: ByteString
, vecCiphertext :: ByteString
}
vecCipher :: Cipher c => Vector c -> c
vecCipher = throwCryptoError . cipherInit . vecKey
vectors128 :: [Vector AES128]
vectors128 =
[ Vector
{ vecPlaintext = ""
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xdc\x20\xe2\xd8\x3f\x25\x70\x5b\xb4\x9e\x43\x9e\xca\x56\xde\x25"
, vecCiphertext = ""
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x57\x87\x82\xff\xf6\x01\x3b\x81\x5b\x28\x7c\x22\x49\x3a\x36\x4c"
, vecCiphertext = "\xb5\xd8\x39\x33\x0a\xc7\xb7\x86"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xa4\x97\x8d\xb3\x57\x39\x1a\x0b\xc4\xfd\xec\x8b\x0d\x10\x66\x39"
, vecCiphertext = "\x73\x23\xea\x61\xd0\x59\x32\x26\x00\x47\xd9\x42"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x30\x3a\xaf\x90\xf6\xfe\x21\x19\x9c\x60\x68\x57\x74\x37\xa0\xc4"
, vecCiphertext = "\x74\x3f\x7c\x80\x77\xab\x25\xf8\x62\x4e\x2e\x94\x85\x79\xcf\x77"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x1a\x8e\x45\xdc\xd4\x57\x8c\x66\x7c\xd8\x68\x47\xbf\x61\x55\xff"
, vecCiphertext = "\x84\xe0\x7e\x62\xba\x83\xa6\x58\x54\x17\x24\x5d\x7e\xc4\x13\xa9\xfe\x42\x7d\x63\x15\xc0\x9b\x57\xce\x45\xf2\xe3\x93\x6a\x94\x45"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x5e\x6e\x31\x1d\xbf\x39\x5d\x35\xb0\xfe\x39\xc2\x71\x43\x88\xf8"
, vecCiphertext = "\x3f\xd2\x4c\xe1\xf5\xa6\x7b\x75\xbf\x23\x51\xf1\x81\xa4\x75\xc7\xb8\x00\xa5\xb4\xd3\xdc\xf7\x01\x06\xb1\xee\xa8\x2f\xa1\xd6\x4d\xf4\x2b\xf7\x22\x61\x22\xfa\x92\xe1\x7a\x40\xee\xaa\xc1\x20\x1b"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x8a\x26\x3d\xd3\x17\xaa\x88\xd5\x6b\xdf\x39\x36\xdb\xa7\x5b\xb8"
, vecCiphertext = "\x24\x33\x66\x8f\x10\x58\x19\x0f\x6d\x43\xe3\x60\xf4\xf3\x5c\xd8\xe4\x75\x12\x7c\xfc\xa7\x02\x8e\xa8\xab\x5c\x20\xf7\xab\x2a\xf0\x25\x16\xa2\xbd\xcb\xc0\x8d\x52\x1b\xe3\x7f\xf2\x8c\x15\x2b\xba\x36\x69\x7f\x25\xb4\xcd\x16\x9c\x65\x90\xd1\xdd\x39\x56\x6d\x3f"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x3b\x0a\x1a\x25\x60\x96\x9c\xdf\x79\x0d\x99\x75\x9a\xbd\x15\x08"
, vecCiphertext = "\x1e\x6d\xab\xa3\x56\x69\xf4\x27"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x08\x29\x9c\x51\x02\x74\x5a\xaa\x3a\x0c\x46\x9f\xad\x9e\x07\x5a"
, vecCiphertext = "\x29\x6c\x78\x89\xfd\x99\xf4\x19\x17\xf4\x46\x20"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x8f\x89\x36\xec\x03\x9e\x4e\x4b\xb9\x7e\xbd\x8c\x44\x57\x44\x1f"
, vecCiphertext = "\xe2\xb0\xc5\xda\x79\xa9\x01\xc1\x74\x5f\x70\x05\x25\xcb\x33\x5b"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xe6\xaf\x6a\x7f\x87\x28\x7d\xa0\x59\xa7\x16\x84\xed\x34\x98\xe1"
, vecCiphertext = "\x62\x00\x48\xef\x3c\x1e\x73\xe5\x7e\x02\xbb\x85\x62\xc4\x16\xa3\x19\xe7\x3e\x4c\xaa\xc8\xe9\x6a\x1e\xcb\x29\x33\x14\x5a\x1d\x71"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x6a\x8c\xc3\x86\x5f\x76\x89\x7c\x2e\x4b\x24\x5c\xf3\x1c\x51\xf2"
, vecCiphertext = "\x50\xc8\x30\x3e\xa9\x39\x25\xd6\x40\x90\xd0\x7b\xd1\x09\xdf\xd9\x51\x5a\x5a\x33\x43\x10\x19\xc1\x7d\x93\x46\x59\x99\xa8\xb0\x05\x32\x01\xd7\x23\x12\x0a\x85\x62\xb8\x38\xcd\xff\x25\xbf\x9d\x1e"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xcd\xc4\x6a\xe4\x75\x56\x3d\xe0\x37\x00\x1e\xf8\x4a\xe2\x17\x44"
, vecCiphertext = "\x2f\x5c\x64\x05\x9d\xb5\x5e\xe0\xfb\x84\x7e\xd5\x13\x00\x37\x46\xac\xa4\xe6\x1c\x71\x1b\x5d\xe2\xe7\xa7\x7f\xfd\x02\xda\x42\xfe\xec\x60\x19\x10\xd3\x46\x7b\xb8\xb3\x6e\xbb\xae\xbc\xe5\xfb\xa3\x0d\x36\xc9\x5f\x48\xa3\xe7\x98\x0f\x0e\x7a\xc2\x99\x33\x2a\x80"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00"
, vecAAD = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x07\xeb\x1f\x84\xfb\x28\xf8\xcb\x73\xde\x8e\x99\xe2\xf4\x8a\x14"
, vecCiphertext = "\xa8\xfe\x3e\x87"
}
, Vector
{ vecPlaintext = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00"
, vecAAD = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x24\xaf\xc9\x80\x5e\x97\x6f\x45\x1e\x6d\x87\xf6\xfe\x10\x65\x14"
, vecCiphertext = "\x6b\xb0\xfe\xcf\x5d\xed\x9b\x77\xf9\x02\xc7\xd5\xda\x23\x6a\x43\x91\xdd\x02\x97"
}
, Vector
{ vecPlaintext = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
, vecAAD = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xbf\xf9\xb2\xef\x00\xfb\x47\x92\x0c\xc7\x2a\x0c\x0f\x13\xb9\xfd"
, vecCiphertext = "\x44\xd0\xaa\xf6\xfb\x2f\x1f\x34\xad\xd5\xe8\x06\x4e\x83\xe1\x2a\x2a\xda"
}
, Vector
{ vecPlaintext = ""
, vecAAD = ""
, vecKey = "\xe6\x60\x21\xd5\xeb\x8e\x4f\x40\x66\xd4\xad\xb9\xc3\x35\x60\xe4"
, vecNonce = "\xf4\x6e\x44\xbb\x3d\xa0\x01\x5c\x94\xf7\x08\x87"
, vecTag = "\xa4\x19\x4b\x79\x07\x1b\x01\xa8\x7d\x65\xf7\x06\xe3\x94\x95\x78"
, vecCiphertext = ""
}
, Vector
{ vecPlaintext = "\x7a\x80\x6c"
, vecAAD = "\x46\xbb\x91\xc3\xc5"
, vecKey = "\x36\x86\x42\x00\xe0\xea\xf5\x28\x4d\x88\x4a\x0e\x77\xd3\x16\x46"
, vecNonce = "\xba\xe8\xe3\x7f\xc8\x34\x41\xb1\x60\x34\x56\x6b"
, vecTag = "\x71\x1b\xd8\x5b\xc1\xe4\xd3\xe0\xa4\x62\xe0\x74\xee\xa4\x28\xa8"
, vecCiphertext = "\xaf\x60\xeb"
}
, Vector
{ vecPlaintext = "\xbd\xc6\x6f\x14\x65\x45"
, vecAAD = "\xfc\x88\x0c\x94\xa9\x51\x98\x87\x42\x96"
, vecKey = "\xae\xdb\x64\xa6\xc5\x90\xbc\x84\xd1\xa5\xe2\x69\xe4\xb4\x78\x01"
, vecNonce = "\xaf\xc0\x57\x7e\x34\x69\x9b\x9e\x67\x1f\xdd\x4f"
, vecTag = "\xd6\xa9\xc4\x55\x45\xcf\xc1\x1f\x03\xad\x74\x3d\xba\x20\xf9\x66"
, vecCiphertext = "\xbb\x93\xa3\xe3\x4d\x3c"
}
, Vector
{ vecPlaintext = "\x11\x77\x44\x1f\x19\x54\x95\x86\x0f"
, vecAAD = "\x04\x67\x87\xf3\xea\x22\xc1\x27\xaa\xf1\x95\xd1\x89\x47\x28"
, vecKey = "\xd5\xcc\x1f\xd1\x61\x32\x0b\x69\x20\xce\x07\x78\x7f\x86\x74\x3b"
, vecNonce = "\x27\x5d\x1a\xb3\x2f\x6d\x1f\x04\x34\xd8\x84\x8c"
, vecTag = "\x1d\x02\xfd\x0c\xd1\x74\xc8\x4f\xc5\xda\xe2\xf6\x0f\x52\xfd\x2b"
, vecCiphertext = "\x4f\x37\x28\x1f\x7a\xd1\x29\x49\xd0"
}
, Vector
{ vecPlaintext = "\x9f\x57\x2c\x61\x4b\x47\x45\x91\x44\x74\xe7\xc7"
, vecAAD = "\xc9\x88\x2e\x53\x86\xfd\x9f\x92\xec\x48\x9c\x8f\xde\x2b\xe2\xcf\x97\xe7\x4e\x93"
, vecKey = "\xb3\xfe\xd1\x47\x3c\x52\x8b\x84\x26\xa5\x82\x99\x59\x29\xa1\x49"
, vecNonce = "\x9e\x9a\xd8\x78\x0c\x8d\x63\xd0\xab\x41\x49\xc0"
, vecTag = "\xc1\xdc\x2f\x87\x1f\xb7\x56\x1d\xa1\x28\x6e\x65\x5e\x24\xb7\xb0"
, vecCiphertext = "\xf5\x46\x73\xc5\xdd\xf7\x10\xc7\x45\x64\x1c\x8b"
}
, Vector
{ vecPlaintext = "\x0d\x8c\x84\x51\x17\x80\x82\x35\x5c\x9e\x94\x0f\xea\x2f\x58"
, vecAAD = "\x29\x50\xa7\x0d\x5a\x1d\xb2\x31\x6f\xd5\x68\x37\x8d\xa1\x07\xb5\x2b\x0d\xa5\x52\x10\xcc\x1c\x1b\x0a"
, vecKey = "\x2d\x4e\xd8\x7d\xa4\x41\x02\x95\x2e\xf9\x4b\x02\xb8\x05\x24\x9b"
, vecNonce = "\xac\x80\xe6\xf6\x14\x55\xbf\xac\x83\x08\xa2\xd4"
, vecTag = "\x83\xb3\x44\x9b\x9f\x39\x55\x2d\xe9\x9d\xc2\x14\xa1\x19\x0b\x0b"
, vecCiphertext = "\xc9\xff\x54\x5e\x07\xb8\x8a\x01\x5f\x05\xb2\x74\x54\x0a\xa1"
}
, Vector
{ vecPlaintext = "\x6b\x3d\xb4\xda\x3d\x57\xaa\x94\x84\x2b\x98\x03\xa9\x6e\x07\xfb\x6d\xe7"
, vecAAD = "\x18\x60\xf7\x62\xeb\xfb\xd0\x82\x84\xe4\x21\x70\x2d\xe0\xde\x18\xba\xa9\xc9\x59\x62\x91\xb0\x84\x66\xf3\x7d\xe2\x1c\x7f"
, vecKey = "\xbd\xe3\xb2\xf2\x04\xd1\xe9\xf8\xb0\x6b\xc4\x7f\x97\x45\xb3\xd1"
, vecNonce = "\xae\x06\x55\x6f\xb6\xaa\x78\x90\xbe\xbc\x18\xfe"
, vecTag = "\x3e\x37\x70\x94\xf0\x47\x09\xf6\x4d\x7b\x98\x53\x10\xa4\xdb\x84"
, vecCiphertext = "\x62\x98\xb2\x96\xe2\x4e\x8c\xc3\x5d\xce\x0b\xed\x48\x4b\x7f\x30\xd5\x80"
}
, Vector
{ vecPlaintext = "\xe4\x2a\x3c\x02\xc2\x5b\x64\x86\x9e\x14\x6d\x7b\x23\x39\x87\xbd\xdf\xc2\x40\x87\x1d"
, vecAAD = "\x75\x76\xf7\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4\xb2\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96\xfa\x85\x9c\x21"
, vecKey = "\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a\x98\xca\xd4\x81\x79"
, vecNonce = "\x62\x45\x70\x9f\xb1\x88\x53\xf6\x8d\x83\x36\x40"
, vecTag = "\x2d\x15\x50\x6c\x84\xa9\xed\xd6\x5e\x13\xe9\xd2\x4a\x2a\x6e\x70"
, vecCiphertext = "\x39\x1c\xc3\x28\xd4\x84\xa4\xf4\x64\x06\x18\x1b\xcd\x62\xef\xd9\xb3\xee\x19\x7d\x05"
}
]
vectors256 :: [Vector AES256]
vectors256 =
[ Vector
{ vecPlaintext = ""
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x07\xf5\xf4\x16\x9b\xbf\x55\xa8\x40\x0c\xd4\x7e\xa6\xfd\x40\x0f"
, vecCiphertext = ""
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x84\x31\x22\x13\x0f\x73\x64\xb7\x61\xe0\xb9\x74\x27\xe3\xdf\x28"
, vecCiphertext = "\xc2\xef\x32\x8e\x5c\x71\xc8\x3b"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x8c\xa5\x0d\xa9\xae\x65\x59\xe4\x8f\xd1\x0f\x6e\x5c\x9c\xa1\x7e"
, vecCiphertext = "\x9a\xab\x2a\xeb\x3f\xaa\x0a\x34\xae\xa8\xe2\xb1"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xc9\xea\xc6\xfa\x70\x09\x42\x70\x2e\x90\x86\x23\x83\xc6\xc3\x66"
, vecCiphertext = "\x85\xa0\x1b\x63\x02\x5b\xa1\x9b\x7f\xd3\xdd\xfc\x03\x3b\x3e\x76"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xe8\x19\xe6\x3a\xbc\xd0\x20\xb0\x06\xa9\x76\x39\x76\x32\xeb\x5d"
, vecCiphertext = "\x4a\x6a\x9d\xb4\xc8\xc6\x54\x92\x01\xb9\xed\xb5\x30\x06\xcb\xa8\x21\xec\x9c\xf8\x50\x94\x8a\x7c\x86\xc6\x8a\xc7\x53\x9d\x02\x7f"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x79\x0b\xc9\x68\x80\xa9\x9b\xa8\x04\xbd\x12\xc0\xe6\xa2\x2c\xc4"
, vecCiphertext = "\xc0\x0d\x12\x18\x93\xa9\xfa\x60\x3f\x48\xcc\xc1\xca\x3c\x57\xce\x74\x99\x24\x5e\xa0\x04\x6d\xb1\x6c\x53\xc7\xc6\x6f\xe7\x17\xe3\x9c\xf6\xc7\x48\x83\x7b\x61\xf6\xee\x3a\xdc\xee\x17\x53\x4e\xd5"
}
, Vector
{ vecPlaintext = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x11\x28\x64\xc2\x69\xfc\x0d\x9d\x88\xc6\x1f\xa4\x7e\x39\xaa\x08"
, vecCiphertext = "\xc2\xd5\x16\x0a\x1f\x86\x83\x83\x49\x10\xac\xda\xfc\x41\xfb\xb1\x63\x2d\x4a\x35\x3e\x8b\x90\x5e\xc9\xa5\x49\x9a\xc3\x4f\x96\xc7\xe1\x04\x9e\xb0\x80\x88\x38\x91\xa4\xdb\x8c\xaa\xa1\xf9\x9d\xd0\x04\xd8\x04\x87\x54\x07\x35\x23\x4e\x37\x44\x51\x2c\x6f\x90\xce"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x91\x21\x3f\x26\x7e\x3b\x45\x2f\x02\xd0\x1a\xe3\x3e\x4e\xc8\x54"
, vecCiphertext = "\x1d\xe2\x29\x67\x23\x7a\x81\x32"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xc1\xa4\xa1\x9a\xe8\x00\x94\x1c\xcd\xc5\x7c\xc8\x41\x3c\x27\x7f"
, vecCiphertext = "\x16\x3d\x6f\x9c\xc1\xb3\x46\xcd\x45\x3a\x2e\x4c"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xb2\x92\xd2\x8f\xf6\x11\x89\xe8\xe4\x9f\x38\x75\xef\x91\xaf\xf7"
, vecCiphertext = "\xc9\x15\x45\x82\x3c\xc2\x4f\x17\xdb\xb0\xe9\xe8\x07\xd5\xec\x17"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xae\xa1\xba\xd1\x27\x02\xe1\x96\x56\x04\x37\x4a\xab\x96\xdb\xbc"
, vecCiphertext = "\x07\xda\xd3\x64\xbf\xc2\xb9\xda\x89\x11\x6d\x7b\xef\x6d\xaa\xaf\x6f\x25\x55\x10\xaa\x65\x4f\x92\x0a\xc8\x1b\x94\xe8\xba\xd3\x65"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x03\x33\x27\x42\xb2\x28\xc6\x47\x17\x36\x16\xcf\xd4\x4c\x54\xeb"
, vecCiphertext = "\xc6\x7a\x1f\x0f\x56\x7a\x51\x98\xaa\x1f\xcc\x8e\x3f\x21\x31\x43\x36\xf7\xf5\x1c\xa8\xb1\xaf\x61\xfe\xac\x35\xa8\x64\x16\xfa\x47\xfb\xca\x3b\x5f\x74\x9c\xdf\x56\x45\x27\xf2\x31\x4f\x42\xfe\x25"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = "\x01"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x5b\xde\x02\x85\x03\x7c\x5d\xe8\x1e\x5b\x57\x0a\x04\x9b\x62\xa0"
, vecCiphertext = "\x67\xfd\x45\xe1\x26\xbf\xb9\xa7\x99\x30\xc4\x3a\xad\x2d\x36\x96\x7d\x3f\x0e\x4d\x21\x7c\x1e\x55\x1f\x59\x72\x78\x70\xbe\xef\xc9\x8c\xb9\x33\xa8\xfc\xe9\xde\x88\x7b\x1e\x40\x79\x99\x88\xdb\x1f\xc3\xf9\x18\x80\xed\x40\x5b\x2d\xd2\x98\x31\x88\x58\x46\x7c\x89"
}
, Vector
{ vecPlaintext = "\x02\x00\x00\x00"
, vecAAD = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\x18\x35\xe5\x17\x74\x1d\xfd\xdc\xcf\xa0\x7f\xa4\x66\x1b\x74\xcf"
, vecCiphertext = "\x22\xb3\xf4\xcd"
}
, Vector
{ vecPlaintext = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00"
, vecAAD = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xb8\x79\xad\x97\x6d\x82\x42\xac\xc1\x88\xab\x59\xca\xbf\xe3\x07"
, vecCiphertext = "\x43\xdd\x01\x63\xcd\xb4\x8f\x9f\xe3\x21\x2b\xf6\x1b\x20\x19\x76\x06\x7f\x34\x2b"
}
, Vector
{ vecPlaintext = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
, vecAAD = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00"
, vecKey = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xcf\xcd\xf5\x04\x21\x12\xaa\x29\x68\x5c\x91\x2f\xc2\x05\x65\x43"
, vecCiphertext = "\x46\x24\x01\x72\x4b\x5c\xe6\x58\x8d\x5a\x54\xaa\xe5\x37\x55\x13\xa0\x75"
}
, Vector
{ vecPlaintext = ""
, vecAAD = ""
, vecKey = "\xe6\x60\x21\xd5\xeb\x8e\x4f\x40\x66\xd4\xad\xb9\xc3\x35\x60\xe4\xf4\x6e\x44\xbb\x3d\xa0\x01\x5c\x94\xf7\x08\x87\x36\x86\x42\x00"
, vecNonce = "\xe0\xea\xf5\x28\x4d\x88\x4a\x0e\x77\xd3\x16\x46"
, vecTag = "\x16\x9f\xbb\x2f\xbf\x38\x9a\x99\x5f\x63\x90\xaf\x22\x22\x8a\x62"
, vecCiphertext = ""
}
, Vector
{ vecPlaintext = "\x67\x1f\xdd"
, vecAAD = "\x4f\xbd\xc6\x6f\x14"
, vecKey = "\xba\xe8\xe3\x7f\xc8\x34\x41\xb1\x60\x34\x56\x6b\x7a\x80\x6c\x46\xbb\x91\xc3\xc5\xae\xdb\x64\xa6\xc5\x90\xbc\x84\xd1\xa5\xe2\x69"
, vecNonce = "\xe4\xb4\x78\x01\xaf\xc0\x57\x7e\x34\x69\x9b\x9e"
, vecTag = "\x93\xda\x9b\xb8\x13\x33\xae\xe0\xc7\x85\xb2\x40\xd3\x19\x71\x9d"
, vecCiphertext = "\x0e\xac\xcb"
}
, Vector
{ vecPlaintext = "\x19\x54\x95\x86\x0f\x04"
, vecAAD = "\x67\x87\xf3\xea\x22\xc1\x27\xaa\xf1\x95"
, vecKey = "\x65\x45\xfc\x88\x0c\x94\xa9\x51\x98\x87\x42\x96\xd5\xcc\x1f\xd1\x61\x32\x0b\x69\x20\xce\x07\x78\x7f\x86\x74\x3b\x27\x5d\x1a\xb3"
, vecNonce = "\x2f\x6d\x1f\x04\x34\xd8\x84\x8c\x11\x77\x44\x1f"
, vecTag = "\x6b\x62\xb8\x4d\xc4\x0c\x84\x63\x6a\x5e\xc1\x20\x20\xec\x8c\x2c"
, vecCiphertext = "\xa2\x54\xda\xd4\xf3\xf9"
}
, Vector
{ vecPlaintext = "\xc9\x88\x2e\x53\x86\xfd\x9f\x92\xec"
, vecAAD = "\x48\x9c\x8f\xde\x2b\xe2\xcf\x97\xe7\x4e\x93\x2d\x4e\xd8\x7d"
, vecKey = "\xd1\x89\x47\x28\xb3\xfe\xd1\x47\x3c\x52\x8b\x84\x26\xa5\x82\x99\x59\x29\xa1\x49\x9e\x9a\xd8\x78\x0c\x8d\x63\xd0\xab\x41\x49\xc0"
, vecNonce = "\x9f\x57\x2c\x61\x4b\x47\x45\x91\x44\x74\xe7\xc7"
, vecTag = "\xc0\xfd\x3d\xc6\x62\x8d\xfe\x55\xeb\xb0\xb9\xfb\x22\x95\xc8\xc2"
, vecCiphertext = "\x0d\xf9\xe3\x08\x67\x82\x44\xc4\x4b"
}
, Vector
{ vecPlaintext = "\x1d\xb2\x31\x6f\xd5\x68\x37\x8d\xa1\x07\xb5\x2b"
, vecAAD = "\x0d\xa5\x52\x10\xcc\x1c\x1b\x0a\xbd\xe3\xb2\xf2\x04\xd1\xe9\xf8\xb0\x6b\xc4\x7f"
, vecKey = "\xa4\x41\x02\x95\x2e\xf9\x4b\x02\xb8\x05\x24\x9b\xac\x80\xe6\xf6\x14\x55\xbf\xac\x83\x08\xa2\xd4\x0d\x8c\x84\x51\x17\x80\x82\x35"
, vecNonce = "\x5c\x9e\x94\x0f\xea\x2f\x58\x29\x50\xa7\x0d\x5a"
, vecTag = "\x40\x40\x99\xc2\x58\x7f\x64\x97\x9f\x21\x82\x67\x06\xd4\x97\xd5"
, vecCiphertext = "\x8d\xbe\xb9\xf7\x25\x5b\xf5\x76\x9d\xd5\x66\x92"
}
, Vector
{ vecPlaintext = "\x21\x70\x2d\xe0\xde\x18\xba\xa9\xc9\x59\x62\x91\xb0\x84\x66"
, vecAAD = "\xf3\x7d\xe2\x1c\x7f\xf9\x01\xcf\xe8\xa6\x96\x15\xa9\x3f\xdf\x7a\x98\xca\xd4\x81\x79\x62\x45\x70\x9f"
, vecKey = "\x97\x45\xb3\xd1\xae\x06\x55\x6f\xb6\xaa\x78\x90\xbe\xbc\x18\xfe\x6b\x3d\xb4\xda\x3d\x57\xaa\x94\x84\x2b\x98\x03\xa9\x6e\x07\xfb"
, vecNonce = "\x6d\xe7\x18\x60\xf7\x62\xeb\xfb\xd0\x82\x84\xe4"
, vecTag = "\xb3\x08\x0d\x28\xf6\xeb\xb5\xd3\x64\x8c\xe9\x7b\xd5\xba\x67\xfd"
, vecCiphertext = "\x79\x35\x76\xdf\xa5\xc0\xf8\x87\x29\xa7\xed\x3c\x2f\x1b\xff"
}
, Vector
{ vecPlaintext = "\xb2\x02\xb3\x70\xef\x97\x68\xec\x65\x61\xc4\xfe\x6b\x7e\x72\x96\xfa\x85"
, vecAAD = "\x9c\x21\x59\x05\x8b\x1f\x0f\xe9\x14\x33\xa5\xbd\xc2\x0e\x21\x4e\xab\x7f\xec\xef\x44\x54\xa1\x0e\xf0\x65\x7d\xf2\x1a\xc7"
, vecKey = "\xb1\x88\x53\xf6\x8d\x83\x36\x40\xe4\x2a\x3c\x02\xc2\x5b\x64\x86\x9e\x14\x6d\x7b\x23\x39\x87\xbd\xdf\xc2\x40\x87\x1d\x75\x76\xf7"
, vecNonce = "\x02\x8e\xc6\xeb\x5e\xa7\xe2\x98\x34\x2a\x94\xd4"
, vecTag = "\x45\x4f\xc2\xa1\x54\xfe\xa9\x1f\x83\x63\xa3\x9f\xec\x7d\x0a\x49"
, vecCiphertext = "\x85\x7e\x16\xa6\x49\x15\xa7\x87\x63\x76\x87\xdb\x4a\x95\x19\x63\x5c\xdd"
}
, Vector
{ vecPlaintext = "\xce\xd5\x32\xce\x41\x59\xb0\x35\x27\x7d\x4d\xfb\xb7\xdb\x62\x96\x8b\x13\xcd\x4e\xec"
, vecAAD = "\x73\x43\x20\xcc\xc9\xd9\xbb\xbb\x19\xcb\x81\xb2\xaf\x4e\xcb\xc3\xe7\x28\x34\x32\x1f\x7a\xa0\xf7\x0b\x72\x82\xb4\xf3\x3d\xf2\x3f\x16\x75\x41"
, vecKey = "\x3c\x53\x5d\xe1\x92\xea\xed\x38\x22\xa2\xfb\xbe\x2c\xa9\xdf\xc8\x82\x55\xe1\x4a\x66\x1b\x8a\xa8\x2c\xc5\x42\x36\x09\x3b\xbc\x23"
, vecNonce = "\x68\x80\x89\xe5\x55\x40\xdb\x18\x72\x50\x4e\x1c"
, vecTag = "\x9d\x6c\x70\x29\x67\x5b\x89\xea\xf4\xba\x1d\xed\x1a\x28\x65\x94"
, vecCiphertext = "\x62\x66\x60\xc2\x6e\xa6\x61\x2f\xb1\x7a\xd9\x1e\x8e\x76\x76\x39\xed\xd6\xc9\xfa\xee"
}
]
vectorsWrap256 :: [Vector AES256]
vectorsWrap256 =
[ Vector
{ vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\xb9\x23\xdc\x79\x3e\xe6\x49\x7c\x76\xdc\xc0\x3a\x98\xe1\x08"
, vecAAD = ""
, vecKey = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\xf3\xf8\x0f\x2c\xf0\xcb\x2d\xd9\xc5\x98\x4f\xcd\xa9\x08\x45\x6c\xc5\x37\x70\x3b\x5b\xa7\x03\x24\xa6\x79\x3a\x7b\xf2\x18\xd3\xea"
}
, Vector
{ vecPlaintext = "\xeb\x36\x40\x27\x7c\x7f\xfd\x13\x03\xc7\xa5\x42\xd0\x2d\x3e\x4c\x00\x00\x00\x00\x00\x00\x00\x00"
, vecAAD = ""
, vecKey = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecNonce = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecTag = "\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\x18\xce\x4f\x0b\x8c\xb4\xd0\xca\xc6\x5f\xea\x8f\x79\x25\x7b\x20\x88\x8e\x53\xe7\x22\x99\xe5\x6d"
}
]
makeEncryptionTest :: BlockCipher128 aes => Int -> Vector aes -> TestTree
makeEncryptionTest i vec@Vector{..} =
testCase (show i) $
(t, vecCiphertext) @=? encrypt (vecCipher vec) n vecAAD vecPlaintext
where t = AuthTag (B.convert vecTag)
n = throwCryptoError (nonce vecNonce)
makeDecryptionTest :: BlockCipher128 aes => Int -> Vector aes -> TestTree
makeDecryptionTest i vec@Vector{..} =
testCase (show i) $
Just vecPlaintext @=? decrypt (vecCipher vec) n vecAAD vecCiphertext t
where t = AuthTag (B.convert vecTag)
n = throwCryptoError (nonce vecNonce)
katTests :: TestName
-> (forall c . BlockCipher128 c => Int -> Vector c -> TestTree)
-> TestTree
katTests name makeTest = testGroup name
[ testGroup "AES128" $ zipWith makeTest [1..] vectors128
, testGroup "AES256" $ zipWith makeTest [1..] vectors256
, testGroup "CounterWrap" $ zipWith makeTest [1..] vectorsWrap256
]
newtype Key c = Key ByteString
deriving (Show,Eq)
instance Arbitrary (Key AES128) where
arbitrary = Key <$> arbitraryBS 16
instance Arbitrary (Key AES256) where
arbitrary = Key <$> arbitraryBS 32
instance Arbitrary Nonce where
arbitrary = throwCryptoError . nonce <$> arbitraryBS 12
encDecTest :: BlockCipher128 c
=> Proxy c -> Key c -> Nonce
-> ArbitraryBS0_2901 -> ArbitraryBS0_2901 -> Property
encDecTest prx (Key key) iv (ArbitraryBS0_2901 aad) (ArbitraryBS0_2901 input) =
let c = throwCryptoError (cipherInit key) `asProxyTypeOf` prx
(tag, ciphertext) = encrypt c iv aad input
in decrypt c iv aad ciphertext tag === Just input
tests :: TestTree
tests = testGroup "AES-GCM-SIV"
[ testGroup "KATs"
[ katTests "encrypt" makeEncryptionTest
, katTests "decrypt" makeDecryptionTest
]
, testGroup "properties"
[ testProperty "AES128" $ encDecTest (Proxy :: Proxy AES128)
, testProperty "AES256" $ encDecTest (Proxy :: Proxy AES256)
]
]

View File

@ -33,6 +33,7 @@ import qualified KAT_PubKey
import qualified KAT_Scrypt import qualified KAT_Scrypt
-- symmetric cipher -------------------- -- symmetric cipher --------------------
import qualified KAT_AES import qualified KAT_AES
import qualified KAT_AESGCMSIV
import qualified KAT_Blowfish import qualified KAT_Blowfish
import qualified KAT_CAST5 import qualified KAT_CAST5
import qualified KAT_Camellia import qualified KAT_Camellia
@ -77,6 +78,7 @@ tests = testGroup "cryptonite"
] ]
, testGroup "block-cipher" , testGroup "block-cipher"
[ KAT_AES.tests [ KAT_AES.tests
, KAT_AESGCMSIV.tests
, KAT_Blowfish.tests , KAT_Blowfish.tests
, KAT_CAST5.tests , KAT_CAST5.tests
, KAT_Camellia.tests , KAT_Camellia.tests