commit
65643a3bea
@ -37,6 +37,9 @@ module Crypto.Cipher.AES.Primitive
|
||||
, decryptCTR
|
||||
, decryptXTS
|
||||
|
||||
-- * CTR with 32-bit wrapping
|
||||
, combineC32
|
||||
|
||||
-- * Incremental GCM
|
||||
, gcmMode
|
||||
, gcmInit
|
||||
@ -317,6 +320,21 @@ decryptXTS :: ByteArray ba
|
||||
-> ba -- ^ output decrypted
|
||||
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 #-}
|
||||
doECB :: ByteArray ba
|
||||
=> (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"
|
||||
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"
|
||||
c_aes_gcm_init :: Ptr AESGCM -> Ptr AES -> Ptr Word8 -> CUInt -> IO ()
|
||||
|
||||
|
||||
193
Crypto/Cipher/AESGCMSIV.hs
Normal file
193
Crypto/Cipher/AESGCMSIV.hs
Normal 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
|
||||
@ -6,6 +6,7 @@ module Main where
|
||||
import Gauge.Main
|
||||
|
||||
import Crypto.Cipher.AES
|
||||
import qualified Crypto.Cipher.AESGCMSIV as AESGCMSIV
|
||||
import Crypto.Cipher.Blowfish
|
||||
import Crypto.Cipher.CAST5
|
||||
import qualified Crypto.Cipher.ChaChaPoly1305 as CP
|
||||
@ -167,6 +168,7 @@ benchAE =
|
||||
[ bench "ChaChaPoly1305" $ nf (cp key32) (input64, input1024)
|
||||
, bench "AES-GCM" $ nf (gcm 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) =
|
||||
let iniState = throwCryptoError $ CP.initialize k (throwCryptoError $ CP.nonce12 nonce12)
|
||||
@ -186,6 +188,11 @@ benchAE =
|
||||
state = throwCryptoError $ aeadInit mode ctx nonce12
|
||||
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
|
||||
input1024 = B.replicate 1024 0
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static inline void block128_inc32_le(block128 *b)
|
||||
{
|
||||
b->d[0] = cpu_to_le32(le32_to_cpu(b->d[0]) + 1);
|
||||
}
|
||||
|
||||
#ifdef IMPL_DEBUG
|
||||
#include <stdio.h>
|
||||
static inline void block128_print(block128 *b)
|
||||
|
||||
@ -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_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_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,
|
||||
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,
|
||||
|
||||
@ -151,6 +151,47 @@ void SIZED(cryptonite_aesni_encrypt_ctr)(uint8_t *output, aes_key *key, aes_bloc
|
||||
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,
|
||||
aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks)
|
||||
{
|
||||
|
||||
@ -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_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_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,
|
||||
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,
|
||||
@ -69,6 +70,8 @@ enum {
|
||||
DECRYPT_CBC_128, DECRYPT_CBC_192, DECRYPT_CBC_256,
|
||||
/* ctr */
|
||||
ENCRYPT_CTR_128, ENCRYPT_CTR_192, ENCRYPT_CTR_256,
|
||||
/* ctr with 32-bit wrapping */
|
||||
ENCRYPT_C32_128, ENCRYPT_C32_192, ENCRYPT_C32_256,
|
||||
/* xts */
|
||||
ENCRYPT_XTS_128, ENCRYPT_XTS_192, ENCRYPT_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_192] = 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 */
|
||||
[ENCRYPT_XTS_128] = 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]))
|
||||
#define GET_CTR_ENCRYPT(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) \
|
||||
((xts_f) (cryptonite_aes_branch_table[ENCRYPT_XTS_128 + 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_DECRYPT(strength) cryptonite_aes_generic_decrypt_cbc
|
||||
#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_DECRYPT(strength) cryptonite_aes_generic_decrypt_xts
|
||||
#define GET_GCM_ENCRYPT(strength) cryptonite_aes_generic_gcm_encrypt
|
||||
@ -251,6 +261,9 @@ static void initialize_table_ni(int aesni, int pclmul)
|
||||
/* CTR */
|
||||
cryptonite_aes_branch_table[ENCRYPT_CTR_128] = cryptonite_aesni_encrypt_ctr128;
|
||||
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 */
|
||||
cryptonite_aes_branch_table[ENCRYPT_XTS_128] = cryptonite_aesni_encrypt_xts128;
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -77,6 +77,12 @@ typedef struct {
|
||||
block128 li[4];
|
||||
} aes_ocb;
|
||||
|
||||
/* size = 17*16= 272 */
|
||||
typedef struct {
|
||||
aes_block htable[16];
|
||||
aes_block s;
|
||||
} aes_polyval;
|
||||
|
||||
/* in bytes: either 16,24,32 */
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
@ -104,6 +104,7 @@ Flag check_alignment
|
||||
|
||||
Library
|
||||
Exposed-modules: Crypto.Cipher.AES
|
||||
Crypto.Cipher.AESGCMSIV
|
||||
Crypto.Cipher.Blowfish
|
||||
Crypto.Cipher.CAST5
|
||||
Crypto.Cipher.Camellia
|
||||
@ -395,6 +396,7 @@ Test-Suite test-cryptonite
|
||||
KAT_AES.KATOCB3
|
||||
KAT_AES.KATXTS
|
||||
KAT_AES
|
||||
KAT_AESGCMSIV
|
||||
KAT_AFIS
|
||||
KAT_Argon2
|
||||
KAT_Blowfish
|
||||
|
||||
494
tests/KAT_AESGCMSIV.hs
Normal file
494
tests/KAT_AESGCMSIV.hs
Normal 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)
|
||||
]
|
||||
]
|
||||
@ -33,6 +33,7 @@ import qualified KAT_PubKey
|
||||
import qualified KAT_Scrypt
|
||||
-- symmetric cipher --------------------
|
||||
import qualified KAT_AES
|
||||
import qualified KAT_AESGCMSIV
|
||||
import qualified KAT_Blowfish
|
||||
import qualified KAT_CAST5
|
||||
import qualified KAT_Camellia
|
||||
@ -77,6 +78,7 @@ tests = testGroup "cryptonite"
|
||||
]
|
||||
, testGroup "block-cipher"
|
||||
[ KAT_AES.tests
|
||||
, KAT_AESGCMSIV.tests
|
||||
, KAT_Blowfish.tests
|
||||
, KAT_CAST5.tests
|
||||
, KAT_Camellia.tests
|
||||
|
||||
Loading…
Reference in New Issue
Block a user