Merge pull request #216 from haskell-crypto/aesccm-rebase

AES CCM mode
This commit is contained in:
Vincent Hanquez 2018-02-04 21:38:16 +00:00 committed by GitHub
commit 6c84a1605d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 574 additions and 24 deletions

View File

@ -59,6 +59,7 @@ instance BlockCipher CSTR where \
; ctrCombine (CSTR aes) (IV iv) = encryptCTR aes (IV iv) \
; aeadInit AEAD_GCM (CSTR aes) iv = CryptoPassed $ AEAD (gcmMode aes) (gcmInit aes iv) \
; aeadInit AEAD_OCB (CSTR aes) iv = CryptoPassed $ AEAD (ocbMode aes) (ocbInit aes iv) \
; aeadInit (AEAD_CCM n m l) (CSTR aes) iv = AEAD (ccmMode aes) <$> ccmInit aes iv n m l \
; aeadInit _ _ _ = CryptoFailed CryptoError_AEADModeNotSupported \
}; \
instance BlockCipher128 CSTR where \

View File

@ -44,6 +44,10 @@ module Crypto.Cipher.AES.Primitive
-- * Incremental OCB
, ocbMode
, ocbInit
-- * CCM
, ccmMode
, ccmInit
) where
import Data.Word
@ -73,6 +77,7 @@ instance BlockCipher AES where
ctrCombine = encryptCTR
aeadInit AEAD_GCM aes iv = CryptoPassed $ AEAD (gcmMode aes) (gcmInit aes iv)
aeadInit AEAD_OCB aes iv = CryptoPassed $ AEAD (ocbMode aes) (ocbInit aes iv)
aeadInit (AEAD_CCM n m l) aes iv = AEAD (ccmMode aes) <$> ccmInit aes iv n m l
aeadInit _ _ _ = CryptoFailed CryptoError_AEADModeNotSupported
instance BlockCipher128 AES where
xtsEncrypt = encryptXTS
@ -96,6 +101,15 @@ ocbMode aes = AEADModeImpl
, aeadImplFinalize = ocbFinish aes
}
-- | Create an AES AEAD implementation for CCM
ccmMode :: AES -> AEADModeImpl AESCCM
ccmMode aes = AEADModeImpl
{ aeadImplAppendHeader = ccmAppendAAD aes
, aeadImplEncrypt = ccmEncrypt aes
, aeadImplDecrypt = ccmDecrypt aes
, aeadImplFinalize = ccmFinish aes
}
-- | AES Context (pre-processed key)
newtype AES = AES ScrubbedBytes
@ -109,12 +123,19 @@ newtype AESGCM = AESGCM ScrubbedBytes
newtype AESOCB = AESOCB ScrubbedBytes
deriving (NFData)
-- | AESCCM State
newtype AESCCM = AESCCM ScrubbedBytes
deriving (NFData)
sizeGCM :: Int
sizeGCM = 80
sizeOCB :: Int
sizeOCB = 160
sizeCCM :: Int
sizeCCM = 80
keyToPtr :: AES -> (Ptr AES -> IO a) -> IO a
keyToPtr (AES b) f = withByteArray b (f . castPtr)
@ -152,6 +173,13 @@ withOCBKeyAndCopySt aes (AESOCB gcmSt) f =
a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr
return (a, AESOCB newSt)
withCCMKeyAndCopySt :: AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM)
withCCMKeyAndCopySt aes (AESCCM ccmSt) f =
keyToPtr aes $ \aesPtr -> do
newSt <- B.copy ccmSt (\_ -> return ())
a <- withByteArray newSt $ \ccmStPtr -> f (castPtr ccmStPtr) aesPtr
return (a, AESCCM newSt)
-- | Initialize a new context with a key
--
-- Key needs to be of length 16, 24 or 32 bytes. Any other values will return failure
@ -447,6 +475,78 @@ ocbFinish ctx ocb taglen = AuthTag $ B.take taglen computeTag
where computeTag = B.allocAndFreeze 16 $ \t ->
withOCBKeyAndCopySt ctx ocb (c_aes_ocb_finish (castPtr t)) >> return ()
ccmGetM :: CCM_M -> Int
ccmGetL :: CCM_L -> Int
ccmGetM m = case m of
CCM_M4 -> 4
CCM_M6 -> 6
CCM_M8 -> 8
CCM_M10 -> 10
CCM_M12 -> 12
CCM_M14 -> 14
CCM_M16 -> 16
ccmGetL l = case l of
CCM_L2 -> 2
CCM_L3 -> 3
CCM_L4 -> 4
-- | initialize a ccm context
{-# NOINLINE ccmInit #-}
ccmInit :: ByteArrayAccess iv => AES -> iv -> Int -> CCM_M -> CCM_L -> CryptoFailable AESCCM
ccmInit ctx iv n m l
| 15 - li /= B.length iv = CryptoFailed CryptoError_IvSizeInvalid
| otherwise = unsafeDoIO $ do
sm <- B.alloc sizeCCM $ \ccmStPtr ->
withKeyAndIV ctx iv $ \k v ->
c_aes_ccm_init (castPtr ccmStPtr) k v (fromIntegral $ B.length iv) (fromIntegral n) (fromIntegral mi) (fromIntegral li)
return $ CryptoPassed (AESCCM sm)
where
mi = ccmGetM m
li = ccmGetL l
-- | append data which is only going to be authenticated to the CCM context.
--
-- needs to happen after initialization and before appending encryption/decryption data.
{-# NOINLINE ccmAppendAAD #-}
ccmAppendAAD :: ByteArrayAccess aad => AES -> AESCCM -> aad -> AESCCM
ccmAppendAAD ctx ccm input = unsafeDoIO $ snd <$> withCCMKeyAndCopySt ctx ccm doAppend
where doAppend ccmStPtr aesPtr =
withByteArray input $ \i -> c_aes_ccm_aad ccmStPtr aesPtr i (fromIntegral $ B.length input)
-- | append data to encrypt and append to the CCM context
--
-- the bytearray needs to be a multiple of AES block size, unless it's the last call to this function.
-- needs to happen after AAD appending, or after initialization if no AAD data.
{-# NOINLINE ccmEncrypt #-}
ccmEncrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmEncrypt ctx ccm input = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv
where len = B.length input
cbcmacAndIv ccmStPtr aesPtr =
B.alloc len $ \o ->
withByteArray input $ \i ->
c_aes_ccm_encrypt (castPtr o) ccmStPtr aesPtr i (fromIntegral len)
-- | append data to decrypt and append to the CCM context
--
-- the bytearray needs to be a multiple of AES block size, unless it's the last call to this function.
-- needs to happen after AAD appending, or after initialization if no AAD data.
{-# NOINLINE ccmDecrypt #-}
ccmDecrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM)
ccmDecrypt ctx ccm input = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv
where len = B.length input
cbcmacAndIv ccmStPtr aesPtr =
B.alloc len $ \o ->
withByteArray input $ \i ->
c_aes_ccm_decrypt (castPtr o) ccmStPtr aesPtr i (fromIntegral len)
-- | Generate the Tag from CCM context
{-# NOINLINE ccmFinish #-}
ccmFinish :: AES -> AESCCM -> Int -> AuthTag
ccmFinish ctx ccm taglen = AuthTag $ B.take taglen computeTag
where computeTag = B.allocAndFreeze 16 $ \t ->
withCCMKeyAndCopySt ctx ccm (c_aes_ccm_finish (castPtr t)) >> return ()
------------------------------------------------------------------------
foreign import ccall "cryptonite_aes.h cryptonite_aes_initkey"
c_aes_init :: Ptr AES -> CString -> CUInt -> IO ()
@ -508,3 +608,17 @@ foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_decrypt"
foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_finish"
c_aes_ocb_finish :: CString -> Ptr AESOCB -> Ptr AES -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_init"
c_aes_ccm_init :: Ptr AESCCM -> Ptr AES -> Ptr Word8 -> CUInt -> CUInt -> CInt -> CInt -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_aad"
c_aes_ccm_aad :: Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_encrypt"
c_aes_ccm_encrypt :: CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_decrypt"
c_aes_ccm_decrypt :: CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO ()
foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_finish"
c_aes_ccm_finish :: CString -> Ptr AESCCM -> Ptr AES -> IO ()

View File

@ -21,6 +21,8 @@ module Crypto.Cipher.Types
-- , cfb8Decrypt
-- * AEAD functions
, AEADMode(..)
, CCM_M(..)
, CCM_L(..)
, module Crypto.Cipher.Types.AEAD
-- * Initial Vector type and constructor
, IV

View File

@ -14,6 +14,8 @@ module Crypto.Cipher.Types.Base
, Cipher(..)
, AuthTag(..)
, AEADMode(..)
, CCM_M(..)
, CCM_L(..)
, DataUnitOffset
) where
@ -39,10 +41,13 @@ newtype AuthTag = AuthTag { unAuthTag :: Bytes }
instance Eq AuthTag where
(AuthTag a) == (AuthTag b) = B.constEq a b
data CCM_M = CCM_M4 | CCM_M6 | CCM_M8 | CCM_M10 | CCM_M12 | CCM_M14 | CCM_M16 deriving (Show, Eq)
data CCM_L = CCM_L2 | CCM_L3 | CCM_L4 deriving (Show, Eq)
-- | AEAD Mode
data AEADMode =
AEAD_OCB -- OCB3
| AEAD_CCM
| AEAD_CCM Int CCM_M CCM_L
| AEAD_EAX
| AEAD_CWC
| AEAD_GCM

View File

@ -52,6 +52,8 @@ void cryptonite_aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *
void cryptonite_aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_generic_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_generic_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_generic_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_generic_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length);
enum {
/* init */
@ -76,6 +78,9 @@ enum {
/* ocb */
ENCRYPT_OCB_128, ENCRYPT_OCB_192, ENCRYPT_OCB_256,
DECRYPT_OCB_128, DECRYPT_OCB_192, DECRYPT_OCB_256,
/* ccm */
ENCRYPT_CCM_128, ENCRYPT_CCM_192, ENCRYPT_CCM_256,
DECRYPT_CCM_128, DECRYPT_CCM_192, DECRYPT_CCM_256,
};
void *cryptonite_aes_branch_table[] = {
@ -129,6 +134,13 @@ void *cryptonite_aes_branch_table[] = {
[DECRYPT_OCB_128] = cryptonite_aes_generic_ocb_decrypt,
[DECRYPT_OCB_192] = cryptonite_aes_generic_ocb_decrypt,
[DECRYPT_OCB_256] = cryptonite_aes_generic_ocb_decrypt,
/* CCM */
[ENCRYPT_CCM_128] = cryptonite_aes_generic_ccm_encrypt,
[ENCRYPT_CCM_192] = cryptonite_aes_generic_ccm_encrypt,
[ENCRYPT_CCM_256] = cryptonite_aes_generic_ccm_encrypt,
[DECRYPT_CCM_128] = cryptonite_aes_generic_ccm_decrypt,
[DECRYPT_CCM_192] = cryptonite_aes_generic_ccm_decrypt,
[DECRYPT_CCM_256] = cryptonite_aes_generic_ccm_decrypt,
};
typedef void (*init_f)(aes_key *, uint8_t *, uint8_t);
@ -138,6 +150,7 @@ typedef void (*ctr_f)(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *inp
typedef void (*xts_f)(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks);
typedef void (*gcm_crypt_f)(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length);
typedef void (*ocb_crypt_f)(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
typedef void (*ccm_crypt_f)(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length);
typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input);
#ifdef WITH_AESNI
@ -165,6 +178,10 @@ typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input);
((ocb_crypt_f) (cryptonite_aes_branch_table[ENCRYPT_OCB_128 + strength]))
#define GET_OCB_DECRYPT(strength) \
((ocb_crypt_f) (cryptonite_aes_branch_table[DECRYPT_OCB_128 + strength]))
#define GET_CCM_ENCRYPT(strength) \
((ccm_crypt_f) (cryptonite_aes_branch_table[ENCRYPT_CCM_128 + strength]))
#define GET_CCM_DECRYPT(strength) \
((ccm_crypt_f) (cryptonite_aes_branch_table[DECRYPT_CCM_128 + strength]))
#define cryptonite_aes_encrypt_block(o,k,i) \
(((block_f) (cryptonite_aes_branch_table[ENCRYPT_BLOCK_128 + k->strength]))(o,k,i))
#define cryptonite_aes_decrypt_block(o,k,i) \
@ -182,6 +199,8 @@ typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input);
#define GET_GCM_DECRYPT(strength) cryptonite_aes_generic_gcm_decrypt
#define GET_OCB_ENCRYPT(strength) cryptonite_aes_generic_ocb_encrypt
#define GET_OCB_DECRYPT(strength) cryptonite_aes_generic_ocb_decrypt
#define GET_CCM_ENCRYPT(strength) cryptonite_aes_generic_ccm_encrypt
#define GET_CCM_DECRYPT(strength) cryptonite_aes_generic_ccm_decrypt
#define cryptonite_aes_encrypt_block(o,k,i) cryptonite_aes_generic_encrypt_block(o,k,i)
#define cryptonite_aes_decrypt_block(o,k,i) cryptonite_aes_generic_decrypt_block(o,k,i)
#endif
@ -321,6 +340,18 @@ void cryptonite_aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uin
d(output, gcm, key, input, length);
}
void cryptonite_aes_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length)
{
ccm_crypt_f e = GET_CCM_ENCRYPT(key->strength);
e(output, ccm, key, input, length);
}
void cryptonite_aes_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length)
{
ccm_crypt_f d = GET_CCM_DECRYPT(key->strength);
d(output, ccm, key, input, length);
}
void cryptonite_aes_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
{
ocb_crypt_f e = GET_OCB_ENCRYPT(key->strength);
@ -406,6 +437,140 @@ void cryptonite_aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key)
}
}
static inline uint8_t ccm_b0_flags(uint32_t has_adata, uint32_t m, uint32_t l)
{
return 8*m + l + (has_adata? 64: 0);
}
/* depends on input size */
static void ccm_encode_b0(block128* output, aes_ccm* ccm, uint32_t has_adata)
{
int last = 15;
uint32_t m = ccm->length_M;
uint32_t l = ccm->length_L;
uint32_t msg_len = ccm->length_input;
block128_zero(output);
block128_copy_aligned(output, &ccm->nonce);
output->b[0] = ccm_b0_flags(has_adata, (m-2)/2, l-1);
while (msg_len > 0) {
output->b[last--] = msg_len & 0xff;
msg_len >>= 8;
}
}
/* encode adata length */
static int ccm_encode_la(block128* output, uint32_t la)
{
if (la < ( (1 << 16) - (1 << 8)) ) {
output->b[0] = (la >> 8) & 0xff;
output->b[1] = la & 0xff;
return 2;
} else {
output->b[0] = 0xff;
output->b[1] = 0xfe;
output->b[2] = (la >> 24) & 0xff;
output->b[3] = (la >> 16) & 0xff;
output->b[4] = (la >> 8) & 0xff;
output->b[5] = la & 0xff;
return 6;
}
}
static void ccm_encode_ctr(block128* out, aes_ccm* ccm, unsigned int cnt)
{
int last = 15;
block128_copy_aligned(out, &ccm->nonce);
out->b[0] = ccm->length_L - 1;
while (cnt > 0) {
out->b[last--] = cnt & 0xff;
cnt >>= 8;
}
}
static void ccm_cbcmac_add(aes_ccm* ccm, aes_key* key, block128* bi)
{
block128_xor_aligned(&ccm->xi, bi);
cryptonite_aes_generic_encrypt_block(&ccm->xi, key, &ccm->xi);
}
/* even though it is possible to support message size as large as 2^64, we support up to 2^32 only */
void cryptonite_aes_ccm_init(aes_ccm *ccm, aes_key *key, uint8_t *nonce, uint32_t nonce_len, uint32_t input_size, int m, int l)
{
memset(ccm, 0, sizeof(aes_ccm));
if (l < 2 || l > 4) return;
if (m != 4 && m != 6 && m != 8 && m != 10
&& m != 12 && m != 14 && m != 16) return;
if (nonce_len > 15 - l) {
nonce_len = 15 - l;
}
if (l <= 4) {
if (input_size >= (1ull << (8*l))) return;
}
ccm->length_L = l;
ccm->length_M = m;
ccm->length_input = input_size;
memcpy(&ccm->nonce.b[1], nonce, nonce_len);
ccm_encode_b0(&ccm->b0, ccm, 1); /* assume aad is present */
cryptonite_aes_encrypt_block(&ccm->xi, key, &ccm->b0);
}
/* even though l(a) can be as large as 2^64, we only handle aad up to 2 ^ 32 for practical reasons.
Also we don't support incremental aad add, because the 1st encoded adata has length information
*/
void cryptonite_aes_ccm_aad(aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length)
{
block128 tmp;
if (ccm->length_aad != 0) return;
ccm->length_aad = length;
int len_len;
block128_zero(&tmp);
len_len = ccm_encode_la(&tmp, length);
if (length < 16 - len_len) {
memcpy(&tmp.b[len_len], input, length);
length = 0;
} else {
memcpy(&tmp.b[len_len], input, 16 - len_len);
input += 16 - len_len;
length -= 16 - len_len;
}
ccm_cbcmac_add(ccm, key, &tmp);
for (; length >= 16; input += 16, length -= 16) {
block128_copy(&tmp, (block128*)input);
ccm_cbcmac_add(ccm, key, &tmp);
}
if (length > 0) {
block128_zero(&tmp);
block128_copy_bytes(&tmp, input, length);
ccm_cbcmac_add(ccm, key, &tmp);
}
block128_copy_aligned(&ccm->header_cbcmac, &ccm->xi);
}
void cryptonite_aes_ccm_finish(uint8_t *tag, aes_ccm *ccm, aes_key *key)
{
block128 iv, s0;
block128_zero(&iv);
ccm_encode_ctr(&iv, ccm, 0);
cryptonite_aes_encrypt_block(&s0, key, &iv);
block128_vxor((block128*)tag, &ccm->xi, &s0);
}
static inline void ocb_block_double(block128 *d, block128 *s)
{
unsigned int i;
@ -739,6 +904,66 @@ static void ocb_generic_crypt(uint8_t *output, aes_ocb *ocb, aes_key *key,
}
}
void cryptonite_aes_generic_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length)
{
block128 tmp, ctr;
/* when aad is absent, reset b0 block */
if (ccm->length_aad == 0) {
ccm_encode_b0(&ccm->b0, ccm, 0); /* assume aad is present */
cryptonite_aes_encrypt_block(&ccm->xi, key, &ccm->b0);
block128_copy_aligned(&ccm->header_cbcmac, &ccm->xi);
}
if (length != ccm->length_input) {
return;
}
ccm_encode_ctr(&ctr, ccm, 1);
cryptonite_aes_encrypt_ctr(output, key, &ctr, input, length);
for (;length >= 16; input += 16, length -= 16) {
block128_copy(&tmp, (block128*)input);
ccm_cbcmac_add(ccm, key, &tmp);
}
if (length > 0) {
block128_zero(&tmp);
block128_copy_bytes(&tmp, input, length);
ccm_cbcmac_add(ccm, key, &tmp);
}
}
void cryptonite_aes_generic_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length)
{
block128 tmp, ctr;
if (length != ccm->length_input) {
return;
}
/* when aad is absent, reset b0 block */
if (ccm->length_aad == 0) {
ccm_encode_b0(&ccm->b0, ccm, 0); /* assume aad is present */
cryptonite_aes_encrypt_block(&ccm->xi, key, &ccm->b0);
block128_copy_aligned(&ccm->header_cbcmac, &ccm->xi);
}
ccm_encode_ctr(&ctr, ccm, 1);
cryptonite_aes_encrypt_ctr(output, key, &ctr, input, length);
block128_copy_aligned(&ccm->xi, &ccm->header_cbcmac);
input = output;
for (;length >= 16; input += 16, length -= 16) {
block128_copy(&tmp, (block128*)input);
ccm_cbcmac_add(ccm, key, &tmp);
}
if (length > 0) {
block128_zero(&tmp);
block128_copy_bytes(&tmp, input, length);
ccm_cbcmac_add(ccm, key, &tmp);
}
}
void cryptonite_aes_generic_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length)
{
ocb_generic_crypt(output, ocb, key, input, length, 1);

View File

@ -55,6 +55,18 @@ typedef struct {
uint64_t length_input;
} aes_gcm;
/* size = 4*16+4*4= 80 */
typedef struct {
aes_block xi;
aes_block header_cbcmac;
aes_block b0;
aes_block nonce;
uint32_t length_aad;
uint32_t length_input;
uint32_t length_M;
uint32_t length_L;
} aes_ccm;
typedef struct {
block128 offset_aad;
block128 offset_enc;
@ -97,4 +109,10 @@ void cryptonite_aes_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uin
void cryptonite_aes_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_ocb_finish(uint8_t *tag, aes_ocb *ocb, aes_key *key);
void cryptonite_aes_ccm_init(aes_ccm *ccm, aes_key *key, uint8_t *nonce, uint32_t len, uint32_t msg_size, int m, int l);
void cryptonite_aes_ccm_aad(aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length);
void cryptonite_aes_ccm_finish(uint8_t *tag, aes_ccm *ccm, aes_key *key);
#endif

View File

@ -377,6 +377,7 @@ Test-Suite test-cryptonite
KAT_AES.KATCBC
KAT_AES.KATECB
KAT_AES.KATGCM
KAT_AES.KATCCM
KAT_AES.KATOCB3
KAT_AES.KATXTS
KAT_AES

View File

@ -16,8 +16,8 @@ import Imports
import Data.Maybe
import Crypto.Error
import Crypto.Cipher.Types
import Data.ByteArray as B hiding (pack, null)
import qualified Data.ByteString as B hiding (all)
import Data.ByteArray as B hiding (pack, null, length)
import qualified Data.ByteString as B hiding (all, take, replicate)
------------------------------------------------------------------------
-- KAT
@ -161,7 +161,7 @@ testKATs kats cipher = testGroup "KAT"
++ maybeGroup makeCFBTest "CFB" (kat_CFB kats)
++ maybeGroup makeCTRTest "CTR" (kat_CTR kats)
-- ++ maybeGroup makeXTSTest "XTS" (kat_XTS kats)
-- ++ maybeGroup makeAEADTest "AEAD" (kat_AEAD kats)
++ maybeGroup makeAEADTest "AEAD" (kat_AEAD kats)
)
where makeECBTest i d =
[ testCase ("E" ++ i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d)
@ -191,25 +191,24 @@ testKATs kats cipher = testGroup "KAT"
[ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d)
, testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d)
]
where ctx1 = cipherInit (cipherMakeKey cipher $ xtsKey1 d)
ctx2 = cipherInit (cipherMakeKey cipher $ xtsKey2 d)
where ctx1 = cipherInitNoErr (cipherMakeKey cipher $ xtsKey1 d)
ctx2 = cipherInitNoErr (cipherMakeKey cipher $ xtsKey2 d)
ctx = (ctx1, ctx2)
iv = cipherMakeIV cipher $ xtsIV d
-}
makeAEADTest i d =
[ testCase ("AE" ++ i) (etag @?= aeadTag d)
, testCase ("AD" ++ i) (dtag @?= aeadTag d)
[ testCase ("AE" ++ i) (etag @?= AuthTag (B.convert (aeadTag d)))
, testCase ("AD" ++ i) (dtag @?= AuthTag (B.convert (aeadTag d)))
, testCase ("E" ++ i) (ebs @?= aeadCiphertext d)
, testCase ("D" ++ i) (dbs @?= aeadPlaintext d)
]
where ctx = cipherInit (cipherMakeKey cipher $ aeadKey d)
aead = maybe (error $ "cipher doesn't support aead mode: " ++ show (aeadMode d)) id
$ aeadInit (aeadMode d) ctx (aeadIV d)
where ctx = cipherInitNoErr (cipherMakeKey cipher $ aeadKey d)
aead = aeadInitNoErr (aeadMode d) ctx (aeadIV d)
aeadHeaded = aeadAppendHeader aead (aeadHeader d)
(ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d)
(dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d)
etag = aeadFinalize aeadEFinal (aeadTaglen d)
dtag = aeadFinalize aeadDFinal (aeadTaglen d)
-}
cipherInitNoErr :: BlockCipher c => Key c -> c
cipherInitNoErr (Key k) =
@ -217,6 +216,11 @@ testKATs kats cipher = testGroup "KAT"
CryptoPassed a -> a
CryptoFailed e -> error (show e)
aeadInitNoErr :: (ByteArrayAccess iv, BlockCipher cipher) => AEADMode -> cipher -> iv -> AEAD cipher
aeadInitNoErr mode ct iv =
case aeadInit mode ct iv of
CryptoPassed a -> a
CryptoFailed _ -> error $ "cipher doesn't support aead mode: " ++ show mode
------------------------------------------------------------------------
-- Properties
------------------------------------------------------------------------
@ -389,7 +393,7 @@ testBlockCipherModes cipher =
testBlockCipherAEAD :: BlockCipher a => a -> [TestTree]
testBlockCipherAEAD cipher =
[ testProperty "OCB" (aeadProp AEAD_OCB)
, testProperty "CCM" (aeadProp AEAD_CCM)
, testProperty "CCM" (aeadProp (AEAD_CCM 0 CCM_M16 CCM_L2))
, testProperty "EAX" (aeadProp AEAD_EAX)
, testProperty "CWC" (aeadProp AEAD_CWC)
, testProperty "GCM" (aeadProp AEAD_GCM)
@ -398,7 +402,7 @@ testBlockCipherAEAD cipher =
toTests :: BlockCipher a => a -> (AEADMode -> AEADUnit a -> Bool)
toTests _ = testProperty_AEAD
testProperty_AEAD mode (AEADUnit key testIV (unPlaintext -> aad) (unPlaintext -> plaintext)) = withCtx key $ \ctx ->
case aeadInit mode ctx testIV of
case aeadInit mode' ctx iv' of
CryptoPassed iniAead ->
let aead = aeadAppendHeader iniAead aad
(eText, aeadE) = aeadEncrypt aead plaintext
@ -409,6 +413,10 @@ testBlockCipherAEAD cipher =
CryptoFailed err
| err == CryptoError_AEADModeNotSupported -> True
| otherwise -> error ("testProperty_AEAD: " ++ show err)
where (mode', iv') = updateCcmInputSize mode (B.length plaintext) testIV
updateCcmInputSize aeadmode k iv = case aeadmode of
AEAD_CCM _ m l -> (AEAD_CCM k m l, B.take 13 (iv <> (B.replicate 15 0)))
aeadOther -> (aeadOther, iv)
withCtx :: Cipher c => Key c -> (c -> a) -> a
withCtx (Key key) f =

View File

@ -3,13 +3,16 @@ module KAT_AES (tests) where
import Imports
import BlockCipher
import Data.Maybe
import Crypto.Cipher.Types
import qualified Crypto.Cipher.AES as AES
import qualified Data.ByteString as B
import qualified KAT_AES.KATECB as KATECB
import qualified KAT_AES.KATCBC as KATCBC
import qualified KAT_AES.KATXTS as KATXTS
import qualified KAT_AES.KATGCM as KATGCM
import qualified KAT_AES.KATCCM as KATCCM
import qualified KAT_AES.KATOCB3 as KATOCB3
{-
@ -37,6 +40,23 @@ toKatAEAD mode (k,iv,h,p,c,taglen,tag) =
toKatGCM = toKatAEAD AEAD_GCM
toKatOCB = toKatAEAD AEAD_OCB
toKatCCM (k,iv,h,i,o,m) =
KAT_AEAD { aeadMode = AEAD_CCM (B.length i) (ccmMVal m) CCM_L2
, aeadKey = k
, aeadIV = iv
, aeadHeader = h
, aeadPlaintext = i
, aeadCiphertext = ct
, aeadTaglen = m
, aeadTag = at
}
where ccmMVal x = fromMaybe (error $ "unsupported CCM tag length: " ++ show x) $
lookup x [ (4, CCM_M4), (6, CCM_M6), (8, CCM_M8), (10, CCM_M10)
, (12, CCM_M12), (14, CCM_M14), (16, CCM_M16)
]
ctWithTag = B.drop (B.length h) o
(ct, at) = B.splitAt (B.length ctWithTag - m) ctWithTag
kats128 = defaultKATs
{ kat_ECB = map toKatECB KATECB.vectors_aes128_enc
, kat_CBC = map toKatCBC KATCBC.vectors_aes128_enc
@ -48,7 +68,8 @@ kats128 = defaultKATs
]
, kat_XTS = map toKatXTS KATXTS.vectors_aes128_enc
, kat_AEAD = map toKatGCM KATGCM.vectors_aes128_enc ++
map toKatOCB KATOCB3.vectors_aes128_enc
map toKatOCB KATOCB3.vectors_aes128_enc ++
map toKatCCM KATCCM.vectors_aes128_enc
}
kats192 = defaultKATs

155
tests/KAT_AES/KATCCM.hs Normal file
View File

@ -0,0 +1,155 @@
{-# LANGUAGE OverloadedStrings #-}
module KAT_AES.KATCCM where
import qualified Data.ByteString as B
-- (key, iv, header, in, out+atag, taglen)
type KATCCM = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, Int)
vectors_aes128_enc :: [KATCCM]
vectors_aes128_enc =
[ ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x03\x02\x01\x00\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07"
, {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x58\x8c\x97\x9a\x61\xc6\x63\xd2\xf0\x66\xd0\xc2\xc0\xf9\x89\x80\x6d\x5f\x6b\x61\xda\xc3\x84\x17\xe8\xd1\x2c\xfd\xf9\x26\xe0"
, {- M = -} 8)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x04\x03\x02\x01\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07"
, {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x72\xc9\x1a\x36\xe1\x35\xf8\xcf\x29\x1c\xa8\x94\x08\x5c\x87\xe3\xcc\x15\xc4\x39\xc9\xe4\x3a\x3b\xa0\x91\xd5\x6e\x10\x40\x09\x16"
, {- M = -} 8)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x05\x04\x03\x02\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07"
, {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x51\xb1\xe5\xf4\x4a\x19\x7d\x1d\xa4\x6b\x0f\x8e\x2d\x28\x2a\xe8\x71\xe8\x38\xbb\x64\xda\x85\x96\x57\x4a\xda\xa7\x6f\xbd\x9f\xb0\xc5"
, {- M = -} 8)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x06\x05\x04\x03\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"
, {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xa2\x8c\x68\x65\x93\x9a\x9a\x79\xfa\xaa\x5c\x4c\x2a\x9d\x4a\x91\xcd\xac\x8c\x96\xc8\x61\xb9\xc9\xe6\x1e\xf1"
, {- M = -} 8)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x07\x06\x05\x04\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"
, {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb\x9d\x4e\x13\x12\x53\x65\x8a\xd8\x6e\xbd\xca\x3e\x51\xe8\x3f\x07\x7d\x9c\x2d\x93"
, {- M = -} 8)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x08\x07\x06\x05\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"
, {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x6f\xc1\xb0\x11\xf0\x06\x56\x8b\x51\x71\xa4\x2d\x95\x3d\x46\x9b\x25\x70\xa4\xbd\x87\x40\x5a\x04\x43\xac\x91\xcb\x94"
, {- M = -} 8)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x09\x08\x07\x06\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07"
, {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x01\x35\xd1\xb2\xc9\x5f\x41\xd5\xd1\xd4\xfe\xc1\x85\xd1\x66\xb8\x09\x4e\x99\x9d\xfe\xd9\x6c\x04\x8c\x56\x60\x2c\x97\xac\xbb\x74\x90"
, {- M = -} 10)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x0a\x09\x08\x07\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07"
, {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x7b\x75\x39\x9a\xc0\x83\x1d\xd2\xf0\xbb\xd7\x58\x79\xa2\xfd\x8f\x6c\xae\x6b\x6c\xd9\xb7\xdb\x24\xc1\x7b\x44\x33\xf4\x34\x96\x3f\x34\xb4"
, {- M = -} 10)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x0b\x0a\x09\x08\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07"
, {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x82\x53\x1a\x60\xcc\x24\x94\x5a\x4b\x82\x79\x18\x1a\xb5\xc8\x4d\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1\x97\xea\x9c\x07\xe5\x6b\x5e\xb1\x7e\x5f\x4e"
, {- M = -} 10)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x0c\x0b\x0a\x09\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"
, {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x07\x34\x25\x94\x15\x77\x85\x15\x2b\x07\x40\x98\x33\x0a\xbb\x14\x1b\x94\x7b\x56\x6a\xa9\x40\x6b\x4d\x99\x99\x88\xdd"
, {- M = -} 10)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x0d\x0c\x0b\x0a\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"
, {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x67\x6b\xb2\x03\x80\xb0\xe3\x01\xe8\xab\x79\x59\x0a\x39\x6d\xa7\x8b\x83\x49\x34\xf5\x3a\xa2\xe9\x10\x7a\x8b\x6c\x02\x2c"
, {- M = -} 10)
, ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
, {- iv = -} "\x00\x00\x00\x0e\x0d\x0c\x0b\xa0\xa1\xa2\xa3\xa4\xa5"
, {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"
, {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
, {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xc0\xff\xa0\xd6\xf0\x5b\xdb\x67\xf2\x4d\x43\xa4\x33\x8d\x2a\xa4\xbe\xd7\xb2\x0e\x43\xcd\x1a\xa3\x16\x62\xe7\xad\x65\xd6\xdb"
, {- M = -} 10)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x41\x2b\x4e\xa9\xcd\xbe\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x0b\xe1\xa8\x8b\xac\xe0\x18\xb1"
, {- in = -} "\x08\xe8\xcf\x97\xd8\x20\xea\x25\x84\x60\xe9\x6a\xd9\xcf\x52\x89\x05\x4d\x89\x5c\xea\xc4\x7c"
, {- out = -} "\x0b\xe1\xa8\x8b\xac\xe0\x18\xb1\x4c\xb9\x7f\x86\xa2\xa4\x68\x9a\x87\x79\x47\xab\x80\x91\xef\x53\x86\xa6\xff\xbd\xd0\x80\xf8\xe7\x8c\xf7\xcb\x0c\xdd\xd7\xb3"
, {- M = -} 8)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x33\x56\x8e\xf7\xb2\x63\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb"
, {- in = -} "\x90\x20\xea\x6f\x91\xbd\xd8\x5a\xfa\x00\x39\xba\x4b\xaf\xf9\xbf\xb7\x9c\x70\x28\x94\x9c\xd0\xec"
, {- out = -} "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa\xa0\x72\x6c\x55\xd3\x78\x06\x12\x98\xc8\x5c\x92\x81\x4a\xbc\x33\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a"
, {- M = -} 8)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x10\x3f\xe4\x13\x36\x71\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\xaa\x6c\xfa\x36\xca\xe8\x6b\x40"
, {- in = -} "\xb9\x16\xe0\xea\xcc\x1c\x00\xd7\xdc\xec\x68\xec\x0b\x3b\xbb\x1a\x02\xde\x8a\x2d\x1a\xa3\x46\x13\x2e"
, {- out = -} "\xaa\x6c\xfa\x36\xca\xe8\x6b\x40\xb1\xd2\x3a\x22\x20\xdd\xc0\xac\x90\x0d\x9a\xa0\x3c\x61\xfc\xf4\xa5\x59\xa4\x41\x77\x67\x08\x97\x08\xa7\x76\x79\x6e\xdb\x72\x35\x06"
, {- M = -} 8)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x76\x4c\x63\xb8\x05\x8e\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\xd0\xd0\x73\x5c\x53\x1e\x1b\xec\xf0\x49\xc2\x44"
, {- in = -} "\x12\xda\xac\x56\x30\xef\xa5\x39\x6f\x77\x0c\xe1\xa6\x6b\x21\xf7\xb2\x10\x1c"
, {- out = -} "\xd0\xd0\x73\x5c\x53\x1e\x1b\xec\xf0\x49\xc2\x44\x14\xd2\x53\xc3\x96\x7b\x70\x60\x9b\x7c\xbb\x7c\x49\x91\x60\x28\x32\x45\x26\x9a\x6f\x49\x97\x5b\xca\xde\xaf"
, {- M = -} 8)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\xf8\xb6\x78\x09\x4e\x3b\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x77\xb6\x0f\x01\x1c\x03\xe1\x52\x58\x99\xbc\xae"
, {- in = -} "\xe8\x8b\x6a\x46\xc7\x8d\x63\xe5\x2e\xb8\xc5\x46\xef\xb5\xde\x6f\x75\xe9\xcc\x0d"
, {- out = -} "\x77\xb6\x0f\x01\x1c\x03\xe1\x52\x58\x99\xbc\xae\x55\x45\xff\x1a\x08\x5e\xe2\xef\xbf\x52\xb2\xe0\x4b\xee\x1e\x23\x36\xc7\x3e\x3f\x76\x2c\x0c\x77\x44\xfe\x7e\x3c"
, {- M = -} 8)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\xd5\x60\x91\x2d\x3f\x70\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81\x20\xea\x60\xc0"
, {- in = -} "\x64\x35\xac\xba\xfb\x11\xa8\x2e\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9\x3a\x80\x3b\xa8\x7f"
, {- out = -} "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81\x20\xea\x60\xc0\x00\x97\x69\xec\xab\xdf\x48\x62\x55\x94\xc5\x92\x51\xe6\x03\x57\x22\x67\x5e\x04\xc8\x47\x09\x9e\x5a\xe0\x70\x45\x51"
, {- M = -} 8)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x42\xff\xf8\xf1\x95\x1c\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8"
, {- in = -} "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01\x8e\x5e\x67\x01\xc9\x17\x87\x65\x98\x09\xd6\x7d\xbe\xdd\x18"
, {- out = -} "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8\xbc\x21\x8d\xaa\x94\x74\x27\xb6\xdb\x38\x6a\x99\xac\x1a\xef\x23\xad\xe0\xb5\x29\x39\xcb\x6a\x63\x7c\xf9\xbe\xc2\x40\x88\x97\xc6\xba"
, {- M = -} 10)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x92\x0f\x40\xe5\x6c\xdc\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x74\xa0\xeb\xc9\x06\x9f\x5b\x37"
, {- in = -} "\x17\x61\x43\x3c\x37\xc5\xa3\x5f\xc1\xf3\x9f\x40\x63\x02\xeb\x90\x7c\x61\x63\xbe\x38\xc9\x84\x37"
, {- out = -} "\x74\xa0\xeb\xc9\x06\x9f\x5b\x37\x58\x10\xe6\xfd\x25\x87\x40\x22\xe8\x03\x61\xa4\x78\xe3\xe9\xcf\x48\x4a\xb0\x4f\x44\x7e\xff\xf6\xf0\xa4\x77\xcc\x2f\xc9\xbf\x54\x89\x44"
, {- M = -} 10)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x27\xca\x0c\x71\x20\xbc\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x44\xa3\xaa\x3a\xae\x64\x75\xca"
, {- in = -} "\xa4\x34\xa8\xe5\x85\x00\xc6\xe4\x15\x30\x53\x88\x62\xd6\x86\xea\x9e\x81\x30\x1b\x5a\xe4\x22\x6b\xfa"
, {- out = -} "\x44\xa3\xaa\x3a\xae\x64\x75\xca\xf2\xbe\xed\x7b\xc5\x09\x8e\x83\xfe\xb5\xb3\x16\x08\xf8\xe2\x9c\x38\x81\x9a\x89\xc8\xe7\x76\xf1\x54\x4d\x41\x51\xa4\xed\x3a\x8b\x87\xb9\xce"
, {- M = -} 10)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x5b\x8c\xcb\xcd\x9a\xf8\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\xec\x46\xbb\x63\xb0\x25\x20\xc3\x3c\x49\xfd\x70"
, {- in = -} "\xb9\x6b\x49\xe2\x1d\x62\x17\x41\x63\x28\x75\xdb\x7f\x6c\x92\x43\xd2\xd7\xc2"
, {- out = -} "\xec\x46\xbb\x63\xb0\x25\x20\xc3\x3c\x49\xfd\x70\x31\xd7\x50\xa0\x9d\xa3\xed\x7f\xdd\xd4\x9a\x20\x32\xaa\xbf\x17\xec\x8e\xbf\x7d\x22\xc8\x08\x8c\x66\x6b\xe5\xc1\x97"
, {- M = -} 10)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x3e\xbe\x94\x04\x4b\x9a\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x47\xa6\x5a\xc7\x8b\x3d\x59\x42\x27\xe8\x5e\x71"
, {- in = -} "\xe2\xfc\xfb\xb8\x80\x44\x2c\x73\x1b\xf9\x51\x67\xc8\xff\xd7\x89\x5e\x33\x70\x76"
, {- out = -} "\x47\xa6\x5a\xc7\x8b\x3d\x59\x42\x27\xe8\x5e\x71\xe8\x82\xf1\xdb\xd3\x8c\xe3\xed\xa7\xc2\x3f\x04\xdd\x65\x07\x1e\xb4\x13\x42\xac\xdf\x7e\x00\xdc\xce\xc7\xae\x52\x98\x7d"
, {- M = -} 10)
, ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b"
, {- iv = -} "\x00\x8d\x49\x3b\x30\xae\x8b\x3c\x96\x96\x76\x6c\xfa"
, {- hdr = -} "\x6e\x37\xa6\xef\x54\x6d\x95\x5d\x34\xab\x60\x59"
, {- in = -} "\xab\xf2\x1c\x0b\x02\xfe\xb8\x8f\x85\x6d\xf4\xa3\x73\x81\xbc\xe3\xcc\x12\x85\x17\xd4"
, {- out = -} "\x6e\x37\xa6\xef\x54\x6d\x95\x5d\x34\xab\x60\x59\xf3\x29\x05\xb8\x8a\x64\x1b\x04\xb9\xc9\xff\xb5\x8c\xc3\x90\x90\x0f\x3d\xa1\x2a\xb1\x6d\xce\x9e\x82\xef\xa1\x6d\xa6\x20\x59"
, {- M = -} 10)
]

View File

@ -132,17 +132,17 @@ instance HashAlgorithm a => Arbitrary (MacIncrementalList a) where
macIncrementalTests :: [TestTree]
macIncrementalTests =
[ testProperties MD5
, testProperties SHA1
, testProperties SHA256
, testProperties SHA3_224
, testProperties SHA3_256
, testProperties SHA3_384
, testProperties SHA3_512
[ testIncrProperties MD5
, testIncrProperties SHA1
, testIncrProperties SHA256
, testIncrProperties SHA3_224
, testIncrProperties SHA3_256
, testIncrProperties SHA3_384
, testIncrProperties SHA3_512
]
where
--testProperties :: HashAlgorithm a => a -> [Property]
testProperties a = testGroup (show a)
--testIncrProperties :: HashAlgorithm a => a -> [Property]
testIncrProperties a = testGroup (show a)
[ testProperty "list-one" (prop_inc0 a)
, testProperty "list-multi" (prop_inc1 a)
]