commit
6c84a1605d
@ -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 \
|
||||
|
||||
@ -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 ()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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
155
tests/KAT_AES/KATCCM.hs
Normal 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)
|
||||
]
|
||||
@ -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)
|
||||
]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user