packages feed

nettle 0.1.1 → 0.2.0

raw patch · 9 files changed

+602/−119 lines, 9 files

Files

README.md view
@@ -1,8 +1,8 @@ # haskell-nettle -This is the source repository for the "nettle" cabal package, which is a safe binding to the [nettle](http://www.lysator.liu.se/~nisse/nettle/nettle.html) library (tested with 2.7.1, might work with 2.5, does NOT WORK with 3.0).+This is the source repository for the "nettle" cabal package, which is a safe binding to the [nettle](http://www.lysator.liu.se/~nisse/nettle/nettle.html) library (tested with 3.1.1, might work with 3.0, does NOT WORK with 2.x). -The binding supports all hash functions, cipher functions, cipher modes and keyed hash functions included in nettle (additionally the AEAD-CCM cipher mode is implemented in pure haskell).+The binding supports all hash functions, cipher functions, cipher modes and keyed hash functions (apart from Poly1305-AES) included in nettle (additionally the AEAD-CCM cipher mode is implemented in pure haskell).  Not included are the PBKDF2 key derivation functions, the public-key algorithms (RSA, DSA, elliptic curves, ECDSA), the pseudo-random generators (lagged Fibonacci and Yarrow), and the base64/base16 encoding/decoding functions. 
nettle.cabal view
@@ -1,9 +1,9 @@ Name:                nettle-Version:             0.1.1+Version:             0.2.0 Synopsis:            safe nettle binding Description:   safe binding for the nettle (<http://www.lysator.liu.se/~nisse/nettle/nettle.html>) library.-  Tested with nettle-2.7.1, might work with 2.5, does NOT WORK with 3.0.+  Tested with 3.1.1, might work with 3.0, does NOT WORK with 2.x. License:             MIT License-file:        COPYING Copyright:           Stefan Bühler <stbuehler@web.de>@@ -32,7 +32,8 @@                    , tagged                    , securemem >= 0.1.2                    , crypto-cipher-types >= 0.0.3 && < 0.1-  Exposed-modules:   Crypto.Nettle.Ciphers+  Exposed-modules:   Crypto.Nettle.ChaChaPoly1305+                     Crypto.Nettle.Ciphers                      Crypto.Nettle.CCM                      Crypto.Nettle.Hash                      Crypto.Nettle.KeyedHash@@ -43,7 +44,7 @@                      Crypto.Nettle.Hash.ForeignImports                      Crypto.Nettle.Hash.Types                      Nettle.Utils-  ghc-options:       -Wall -optc-O3 -fno-cse+  ghc-options:       -Wall -optc-O3 -fno-cse -fno-warn-tabs   include-dirs:      src   C-sources:         src/nettle-ciphers.c   if flag(UsePkgConfig)@@ -64,6 +65,7 @@                    , crypto-cipher-types                    , crypto-cipher-tests                    , nettle+  ghc-options: -fno-warn-tabs  Test-Suite test-hashes   type:              exitcode-stdio-1.0@@ -77,6 +79,7 @@                    , HUnit                    , test-framework-hunit                    , nettle+  ghc-options: -fno-warn-tabs  Test-Suite test-hmac   type:              exitcode-stdio-1.0@@ -90,6 +93,7 @@                    , HUnit                    , test-framework-hunit                    , nettle+  ghc-options: -fno-warn-tabs  Test-Suite test-umac   type:              exitcode-stdio-1.0@@ -103,6 +107,7 @@                    , HUnit                    , test-framework-hunit                    , nettle+  ghc-options: -fno-warn-tabs  source-repository head   type:     git
+ src/Crypto/Nettle/ChaChaPoly1305.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Crypto.Nettle.ChaChaPoly1305+-- Copyright   :  (c) 2013 Stefan Bühler+-- License     :  MIT-style (see the file COPYING)+-- +-- Maintainer  :  stbuehler@web.de+-- Stability   :  experimental+-- Portability :  portable+--+-- This module exports the ChaCha-Poly1305 AEAD cipher supported by nettle:+--   <http://www.lysator.liu.se/~nisse/nettle/>+--+-- Both ChaCha (the underlying cipher) and Poly1305 (the keyed hash) were+-- designed by D. J. Bernstein.+--+-----------------------------------------------------------------------------++module Crypto.Nettle.ChaChaPoly1305 (+	-- * ChaCha-Poly1305+	--+	-- No streaming interface is provided, as this basically violates the+	-- spirit of the "AEAD-should-be-simple-to-use" concept - you only can+	-- use the decrypted data after it got successfully verified.++	  chaChaPoly1305Encrypt+	, chaChaPoly1305Decrypt+	) where++import qualified Data.ByteString as B+import qualified Data.ByteString.Internal as B+import Data.SecureMem++import Crypto.Nettle.Ciphers.ForeignImports+import Nettle.Utils++{-|+Encrypt plain text and create a verification tag for the encrypted text and some additional data.+@key@ and @nonce@ must not be reused together.+The returned tag is 16 bytes long, but may be shortened for verification (loosing security).+-}+chaChaPoly1305Encrypt+	:: B.ByteString                 -- ^ @key@ (must be 32 bytes)+	-> B.ByteString                 -- ^ @nonce@ (must be 12 bytes)+	-> B.ByteString                 -- ^ @aad@ additional data to be verified+	-> B.ByteString                 -- ^ @plain@ data to encrypt+	-> (B.ByteString, B.ByteString) -- ^ returns (@cipher@, @tag@) ciphertext and verification tag+chaChaPoly1305Encrypt key nonce aad plain = unsafeDupablePerformIO $ do+	ctx <- allocateSecureMem c_chacha_poly1305_ctx_size+	tag <- B.create 16 (\_ -> return ())+	cipher <- B.create (B.length plain) (\_ -> return ())+	withByteStringPtr plain $ \psize pptr ->+		withByteStringPtr aad $ \aadsize aadptr ->+		withByteStringPtr cipher $ \_ cipherptr ->+		withByteStringPtr tag $ \_ tagptr ->+		withSecureMemPtr ctx $ \ctxptr ->+		withSecureMemPtrSz (toSecureMem key) $ \ksize kptr -> if ksize /= 32 then error "Invalid key length" else+		withSecureMemPtrSz (toSecureMem nonce) $ \nsize nptr -> if nsize /= 12 then error "Invalid nonce length" else do+		c_chacha_poly1305_set_key ctxptr kptr+		c_chacha_poly1305_set_nonce ctxptr nptr+		c_chacha_poly1305_update ctxptr aadsize aadptr+		c_chacha_poly1305_encrypt ctxptr psize cipherptr pptr+		c_chacha_poly1305_digest ctxptr 16 tagptr+	return (cipher, tag)++{-|+Decrypt cipher text and verify a (possible shortened) tag for the encrypted text and some additional data.+@key@ and @nonce@ must not be reused together.+-}+chaChaPoly1305Decrypt :: B.ByteString -> B.ByteString -> B.ByteString -> B.ByteString -> B.ByteString -> Maybe B.ByteString+chaChaPoly1305Decrypt key nonce aad cipher verifytag = unsafeDupablePerformIO $ do+	ctx <- allocateSecureMem c_chacha_poly1305_ctx_size+	tag <- B.create 16 (\_ -> return ())+	plain <- B.create (B.length cipher) (\_ -> return ())+	withByteStringPtr cipher $ \psize pptr ->+		withByteStringPtr aad $ \aadsize aadptr ->+		withByteStringPtr plain $ \_ plainptr ->+		withByteStringPtr tag $ \_ tagptr ->+		withSecureMemPtr ctx $ \ctxptr ->+		withSecureMemPtrSz (toSecureMem key) $ \ksize kptr -> if ksize /= 32 then error "Invalid key length" else+		withSecureMemPtrSz (toSecureMem nonce) $ \nsize nptr -> if nsize /= 12 then error "Invalid nonce length" else do+		c_chacha_poly1305_set_key ctxptr kptr+		c_chacha_poly1305_set_nonce ctxptr nptr+		c_chacha_poly1305_update ctxptr aadsize aadptr+		c_chacha_poly1305_decrypt ctxptr psize plainptr pptr+		c_chacha_poly1305_digest ctxptr 16 tagptr+	if B.take (B.length verifytag) tag == verifytag then return $ Just plain else return Nothing
src/Crypto/Nettle/Ciphers.hs view
@@ -54,6 +54,8 @@ 	, streamSetNonceWord64 	-- ** ARCFOUR 	, ARCFOUR+	-- ** ChaCha+	, CHACHA 	-- ** Salsa20 	, SALSA20 	, ESTREAM_SALSA20@@ -125,7 +127,6 @@ 	; streamNonceSize = witness nbsc_nonceSize \ 	} - {-| 'AES' is the generic cipher context for the AES cipher, supporting key sizes of 128, 196 and 256 bits (16, 24 and 32 bytes). The 'blockSize' is always 128 bits (16 bytes).@@ -142,35 +143,32 @@ 	nc_Ctx           = AES instance NettleBlockCipher AES where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_aes_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_aes_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_aes_encrypt-	nbc_ecb_decrypt        = Tagged c_aes_decrypt-	nbc_fun_encrypt        = Tagged p_aes_encrypt-	nbc_fun_decrypt        = Tagged p_aes_decrypt+	nbc_ecb_encrypt        = Tagged c_hs_aes_encrypt+	nbc_ecb_decrypt        = Tagged c_hs_aes_decrypt+	nbc_fun_encrypt        = Tagged p_hs_aes_encrypt+	nbc_fun_decrypt        = Tagged p_hs_aes_decrypt  INSTANCE_BLOCKCIPHER(AES) - {-| 'AES128' provides the same interface as 'AES', but is restricted to 128-bit keys. -} newtype AES128 = AES128 SecureMem instance NettleCipher AES128 where-	nc_cipherInit    = Tagged c_hs_aes_init+	nc_cipherInit    = Tagged (\ctx _ key -> c_hs_aes128_init ctx key) 	nc_cipherName    = Tagged "AES-128" 	nc_cipherKeySize = Tagged $ KeySizeFixed 16-	nc_ctx_size      = Tagged c_hs_aes_ctx_size+	nc_ctx_size      = Tagged c_hs_aes128_ctx_size 	nc_ctx (AES128 c) = c 	nc_Ctx            = AES128 instance NettleBlockCipher AES128 where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_aes_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_aes_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_aes_encrypt-	nbc_ecb_decrypt        = Tagged c_aes_decrypt-	nbc_fun_encrypt        = Tagged p_aes_encrypt-	nbc_fun_decrypt        = Tagged p_aes_decrypt+	nbc_encrypt_ctx_offset = Tagged c_hs_aes128_ctx_encrypt+	nbc_decrypt_ctx_offset = Tagged c_hs_aes128_ctx_decrypt+	nbc_ecb_encrypt        = Tagged c_aes128_encrypt+	nbc_ecb_decrypt        = Tagged c_aes128_decrypt+	nbc_fun_encrypt        = Tagged p_aes128_encrypt+	nbc_fun_decrypt        = Tagged p_aes128_decrypt  INSTANCE_BLOCKCIPHER(AES128) @@ -180,20 +178,20 @@ -} newtype AES192 = AES192 SecureMem instance NettleCipher AES192 where-	nc_cipherInit    = Tagged c_hs_aes_init+	nc_cipherInit    = Tagged (\ctx _ key -> c_hs_aes192_init ctx key) 	nc_cipherName    = Tagged "AES-192" 	nc_cipherKeySize = Tagged $ KeySizeFixed 24-	nc_ctx_size      = Tagged c_hs_aes_ctx_size+	nc_ctx_size      = Tagged c_hs_aes192_ctx_size 	nc_ctx  (AES192 c) = c 	nc_Ctx             = AES192 instance NettleBlockCipher AES192 where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_aes_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_aes_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_aes_encrypt-	nbc_ecb_decrypt        = Tagged c_aes_decrypt-	nbc_fun_encrypt        = Tagged p_aes_encrypt-	nbc_fun_decrypt        = Tagged p_aes_decrypt+	nbc_encrypt_ctx_offset = Tagged c_hs_aes192_ctx_encrypt+	nbc_decrypt_ctx_offset = Tagged c_hs_aes192_ctx_decrypt+	nbc_ecb_encrypt        = Tagged c_aes192_encrypt+	nbc_ecb_decrypt        = Tagged c_aes192_decrypt+	nbc_fun_encrypt        = Tagged p_aes192_encrypt+	nbc_fun_decrypt        = Tagged p_aes192_decrypt  INSTANCE_BLOCKCIPHER(AES192) @@ -203,20 +201,20 @@ -} newtype AES256 = AES256 SecureMem instance NettleCipher AES256 where-	nc_cipherInit    = Tagged c_hs_aes_init+	nc_cipherInit    = Tagged (\ctx _ key -> c_hs_aes256_init ctx key) 	nc_cipherName    = Tagged "AES-256" 	nc_cipherKeySize = Tagged $ KeySizeFixed 32-	nc_ctx_size      = Tagged c_hs_aes_ctx_size+	nc_ctx_size      = Tagged c_hs_aes256_ctx_size 	nc_ctx  (AES256 c) = c 	nc_Ctx             = AES256 instance NettleBlockCipher AES256 where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_aes_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_aes_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_aes_encrypt-	nbc_ecb_decrypt        = Tagged c_aes_decrypt-	nbc_fun_encrypt        = Tagged p_aes_encrypt-	nbc_fun_decrypt        = Tagged p_aes_decrypt+	nbc_encrypt_ctx_offset = Tagged c_hs_aes256_ctx_encrypt+	nbc_decrypt_ctx_offset = Tagged c_hs_aes256_ctx_decrypt+	nbc_ecb_encrypt        = Tagged c_aes256_encrypt+	nbc_ecb_decrypt        = Tagged c_aes256_decrypt+	nbc_fun_encrypt        = Tagged p_aes256_encrypt+	nbc_fun_decrypt        = Tagged p_aes256_decrypt  INSTANCE_BLOCKCIPHER(AES256) @@ -297,12 +295,10 @@ 	nc_Ctx             = Camellia instance NettleBlockCipher Camellia where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_camellia_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_camellia_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_camellia_crypt-	nbc_ecb_decrypt        = Tagged c_camellia_crypt-	nbc_fun_encrypt        = Tagged p_camellia_crypt-	nbc_fun_decrypt        = Tagged p_camellia_crypt+	nbc_ecb_encrypt        = Tagged c_hs_camellia_encrypt+	nbc_ecb_decrypt        = Tagged c_hs_camellia_decrypt+	nbc_fun_encrypt        = Tagged p_hs_camellia_encrypt+	nbc_fun_decrypt        = Tagged p_hs_camellia_decrypt  INSTANCE_BLOCKCIPHER(Camellia) @@ -311,20 +307,20 @@ -} newtype Camellia128 = Camellia128 SecureMem instance NettleCipher Camellia128 where-	nc_cipherInit    = Tagged c_hs_camellia_init+	nc_cipherInit    = Tagged (\ctx _ key -> c_hs_camellia128_init ctx key) 	nc_cipherName    = Tagged "Camellia-128" 	nc_cipherKeySize = Tagged $ KeySizeFixed 16-	nc_ctx_size      = Tagged c_hs_camellia_ctx_size+	nc_ctx_size      = Tagged c_hs_camellia128_ctx_size 	nc_ctx  (Camellia128 c) = c 	nc_Ctx             = Camellia128 instance NettleBlockCipher Camellia128 where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_camellia_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_camellia_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_camellia_crypt-	nbc_ecb_decrypt        = Tagged c_camellia_crypt-	nbc_fun_encrypt        = Tagged p_camellia_crypt-	nbc_fun_decrypt        = Tagged p_camellia_crypt+	nbc_encrypt_ctx_offset = Tagged c_hs_camellia128_ctx_encrypt+	nbc_decrypt_ctx_offset = Tagged c_hs_camellia128_ctx_decrypt+	nbc_ecb_encrypt        = Tagged c_camellia128_crypt+	nbc_ecb_decrypt        = Tagged c_camellia128_crypt+	nbc_fun_encrypt        = Tagged p_camellia128_crypt+	nbc_fun_decrypt        = Tagged p_camellia128_crypt  INSTANCE_BLOCKCIPHER(Camellia128) @@ -333,20 +329,20 @@ -} newtype Camellia192 = Camellia192 SecureMem instance NettleCipher Camellia192 where-	nc_cipherInit    = Tagged c_hs_camellia_init+	nc_cipherInit    = Tagged (\ctx _ key -> c_hs_camellia192_init ctx key) 	nc_cipherName    = Tagged "Camellia-192" 	nc_cipherKeySize = Tagged $ KeySizeFixed 24-	nc_ctx_size      = Tagged c_hs_camellia_ctx_size+	nc_ctx_size      = Tagged c_hs_camellia192_ctx_size 	nc_ctx  (Camellia192 c) = c 	nc_Ctx             = Camellia192 instance NettleBlockCipher Camellia192 where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_camellia_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_camellia_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_camellia_crypt-	nbc_ecb_decrypt        = Tagged c_camellia_crypt-	nbc_fun_encrypt        = Tagged p_camellia_crypt-	nbc_fun_decrypt        = Tagged p_camellia_crypt+	nbc_encrypt_ctx_offset = Tagged c_hs_camellia192_ctx_encrypt+	nbc_decrypt_ctx_offset = Tagged c_hs_camellia192_ctx_decrypt+	nbc_ecb_encrypt        = Tagged c_camellia192_crypt+	nbc_ecb_decrypt        = Tagged c_camellia192_crypt+	nbc_fun_encrypt        = Tagged p_camellia192_crypt+	nbc_fun_decrypt        = Tagged p_camellia192_crypt  INSTANCE_BLOCKCIPHER(Camellia192) @@ -355,20 +351,20 @@ -} newtype Camellia256 = Camellia256 SecureMem instance NettleCipher Camellia256 where-	nc_cipherInit    = Tagged c_hs_camellia_init+	nc_cipherInit    = Tagged (\ctx _ key -> c_hs_camellia256_init ctx key) 	nc_cipherName    = Tagged "Camellia-256" 	nc_cipherKeySize = Tagged $ KeySizeFixed 32-	nc_ctx_size      = Tagged c_hs_camellia_ctx_size+	nc_ctx_size      = Tagged c_hs_camellia256_ctx_size 	nc_ctx  (Camellia256 c) = c 	nc_Ctx             = Camellia256 instance NettleBlockCipher Camellia256 where 	nbc_blockSize          = Tagged 16-	nbc_encrypt_ctx_offset = Tagged c_hs_camellia_ctx_encrypt-	nbc_decrypt_ctx_offset = Tagged c_hs_camellia_ctx_decrypt-	nbc_ecb_encrypt        = Tagged c_camellia_crypt-	nbc_ecb_decrypt        = Tagged c_camellia_crypt-	nbc_fun_encrypt        = Tagged p_camellia_crypt-	nbc_fun_decrypt        = Tagged p_camellia_crypt+	nbc_encrypt_ctx_offset = Tagged c_hs_camellia256_ctx_encrypt+	nbc_decrypt_ctx_offset = Tagged c_hs_camellia256_ctx_decrypt+	nbc_ecb_encrypt        = Tagged c_camellia256_crypt+	nbc_ecb_decrypt        = Tagged c_camellia256_crypt+	nbc_fun_encrypt        = Tagged p_camellia256_crypt+	nbc_fun_decrypt        = Tagged p_camellia256_crypt  INSTANCE_BLOCKCIPHER(Camellia256) @@ -378,7 +374,7 @@ -} newtype CAST128 = CAST128 SecureMem instance NettleCipher CAST128 where-	nc_cipherInit    = Tagged c_cast128_set_key+	nc_cipherInit    = Tagged c_cast5_set_key 	nc_cipherName    = Tagged "CAST-128" 	nc_cipherKeySize = Tagged $ KeySizeRange 5 16 	nc_ctx_size      = Tagged c_cast128_ctx_size@@ -529,15 +525,58 @@ streamSetNonceWord64 c nonce = streamSetNonce c $ word64BE nonce  -- set nonce to 0 on init+wrap_chacha_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()+wrap_chacha_set_key ctxptr _ keyptr = do+	c_chacha_set_key ctxptr keyptr+	withByteStringPtr (B.replicate 8 0) $ \_ nonceptr ->+		c_chacha_set_nonce ctxptr nonceptr++-- check nonce length+wrap_chacha_set_nonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()+wrap_chacha_set_nonce ctxptr ivlen ivptr = if ivlen == 8 then c_chacha_set_nonce ctxptr ivptr else fail "Invalid nonce length"++{-|+'CHACHA' is a variant of the 'SALSA20' stream cipher, both designed by D. J. Bernstein.++Key size is 256 bits (32 bytes).++'CHACHA' works similar to 'SALSA20'; it could theoretically also support 128-bit keys, but there is no need for it as they share the same performance.++ChaCha uses a blocksize of 64 bytes internally; if crpyted input isn't aligned to 64 bytes it will+pad it with 0 and store the encrypted padding to xor with future input data.++Each message also requires a 8-byte ('Word64') nonce (which is initialized to 0; you can use a message sequence number).+Don't reuse a nonce with the same key.++Setting a nonce also resets the remaining padding data.+-}+newtype CHACHA = CHACHA (SecureMem, B.ByteString)+instance NettleCipher CHACHA where+	nc_cipherInit    = Tagged wrap_chacha_set_key+	nc_cipherName    = Tagged "ChaCha"+	nc_cipherKeySize = Tagged $ KeySizeFixed 32+	nc_ctx_size      = Tagged c_chacha_ctx_size+	nc_ctx (CHACHA (c, _)) = c+	nc_Ctx c           = CHACHA (c, B.empty)+instance NettleBlockedStreamCipher CHACHA where+	nbsc_blockSize     = Tagged 64+	nbsc_IncompleteState (CHACHA (c, _)) inc = CHACHA (c, inc)+	nbsc_incompleteState (CHACHA (_, inc)) = inc+	nbsc_streamCombine = Tagged c_chacha_crypt+	nbsc_nonceSize     = Tagged $ KeySizeFixed 8+	nbsc_setNonce      = Tagged $ Just wrap_chacha_set_nonce+INSTANCE_BLOCKEDSTREAMNONCECIPHER(CHACHA)++-- set nonce to 0 on init wrap_salsa20_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO () wrap_salsa20_set_key ctxptr keylen keyptr = do 	c_salsa20_set_key ctxptr keylen keyptr 	withByteStringPtr (B.replicate 8 0) $ \_ nonceptr ->-		c_salsa20_set_iv ctxptr nonceptr+		c_salsa20_set_nonce ctxptr nonceptr  -- check nonce length-wrap_salsa20_set_iv :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()-wrap_salsa20_set_iv ctxptr ivlen ivptr = if ivlen == 8 then c_salsa20_set_iv ctxptr ivptr else fail "Invalid nonce length"+wrap_salsa20_set_nonce :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()+wrap_salsa20_set_nonce ctxptr ivlen ivptr = if ivlen == 8 then c_salsa20_set_nonce ctxptr ivptr else fail "Invalid nonce length"  {-| 'SALSA20' is a fairly recent stream cipher designed by D. J. Bernstein.@@ -566,7 +605,7 @@ 	nbsc_incompleteState (SALSA20 (_, inc)) = inc 	nbsc_streamCombine = Tagged c_salsa20_crypt 	nbsc_nonceSize     = Tagged $ KeySizeFixed 8-	nbsc_setNonce      = Tagged $ Just wrap_salsa20_set_iv+	nbsc_setNonce      = Tagged $ Just wrap_salsa20_set_nonce INSTANCE_BLOCKEDSTREAMNONCECIPHER(SALSA20)  @@ -587,5 +626,5 @@ 	nbsc_incompleteState (ESTREAM_SALSA20 (_, inc)) = inc 	nbsc_streamCombine = Tagged c_salsa20r12_crypt 	nbsc_nonceSize     = Tagged $ KeySizeFixed 8-	nbsc_setNonce      = Tagged $ Just wrap_salsa20_set_iv+	nbsc_setNonce      = Tagged $ Just wrap_salsa20_set_nonce INSTANCE_BLOCKEDSTREAMNONCECIPHER(ESTREAM_SALSA20)
src/Crypto/Nettle/Ciphers/ForeignImports.hsc view
@@ -23,14 +23,39 @@ 	, c_gcm_digest  	, c_hs_aes_ctx_size-	, c_hs_aes_ctx_encrypt-	, c_hs_aes_ctx_decrypt 	, c_hs_aes_init-	, c_aes_encrypt-	, p_aes_encrypt-	, c_aes_decrypt-	, p_aes_decrypt+	, c_hs_aes_encrypt+	, p_hs_aes_encrypt+	, c_hs_aes_decrypt+	, p_hs_aes_decrypt +	, c_hs_aes128_ctx_size+	, c_hs_aes128_ctx_encrypt+	, c_hs_aes128_ctx_decrypt+	, c_hs_aes128_init+	, c_aes128_encrypt+	, p_aes128_encrypt+	, c_aes128_decrypt+	, p_aes128_decrypt++	, c_hs_aes192_ctx_size+	, c_hs_aes192_ctx_encrypt+	, c_hs_aes192_ctx_decrypt+	, c_hs_aes192_init+	, c_aes192_encrypt+	, p_aes192_encrypt+	, c_aes192_decrypt+	, p_aes192_decrypt++	, c_hs_aes256_ctx_size+	, c_hs_aes256_ctx_encrypt+	, c_hs_aes256_ctx_decrypt+	, c_hs_aes256_init+	, c_aes256_encrypt+	, p_aes256_encrypt+	, c_aes256_decrypt+	, p_aes256_decrypt+ 	, c_arctwo_ctx_size 	, c_arctwo_set_key 	, c_arctwo_set_key_ekb@@ -48,14 +73,35 @@ 	, p_blowfish_decrypt  	, c_hs_camellia_ctx_size-	, c_hs_camellia_ctx_encrypt-	, c_hs_camellia_ctx_decrypt 	, c_hs_camellia_init-	, c_camellia_crypt-	, p_camellia_crypt+	, c_hs_camellia_encrypt+	, p_hs_camellia_encrypt+	, c_hs_camellia_decrypt+	, p_hs_camellia_decrypt +	, c_hs_camellia128_ctx_size+	, c_hs_camellia128_ctx_encrypt+	, c_hs_camellia128_ctx_decrypt+	, c_hs_camellia128_init+	, c_camellia128_crypt+	, p_camellia128_crypt++	, c_hs_camellia192_ctx_size+	, c_hs_camellia192_ctx_encrypt+	, c_hs_camellia192_ctx_decrypt+	, c_hs_camellia192_init+	, c_camellia192_crypt+	, p_camellia192_crypt++	, c_hs_camellia256_ctx_size+	, c_hs_camellia256_ctx_encrypt+	, c_hs_camellia256_ctx_decrypt+	, c_hs_camellia256_init+	, c_camellia256_crypt+	, p_camellia256_crypt+ 	, c_cast128_ctx_size-	, c_cast128_set_key+	, c_cast5_set_key 	, c_cast128_encrypt 	, p_cast128_encrypt 	, c_cast128_decrypt@@ -93,11 +139,24 @@ 	, c_arcfour_set_key 	, c_arcfour_crypt +	, c_chacha_ctx_size+	, c_chacha_set_key+	, c_chacha_set_nonce+	, c_chacha_crypt+ 	, c_salsa20_ctx_size 	, c_salsa20_set_key-	, c_salsa20_set_iv+	, c_salsa20_set_nonce 	, c_salsa20_crypt 	, c_salsa20r12_crypt++	, c_chacha_poly1305_ctx_size+	, c_chacha_poly1305_set_key+	, c_chacha_poly1305_set_nonce+	, c_chacha_poly1305_update+	, c_chacha_poly1305_encrypt+	, c_chacha_poly1305_decrypt+	, c_chacha_poly1305_digest 	) where  import Nettle.Utils@@ -145,22 +204,68 @@  c_hs_aes_ctx_size :: Int c_hs_aes_ctx_size = #{size struct hs_aes_ctx}-c_hs_aes_ctx_encrypt :: Ptr Word8 -> Ptr Word8-c_hs_aes_ctx_encrypt = #ptr struct hs_aes_ctx, encrypt-c_hs_aes_ctx_decrypt :: Ptr Word8 -> Ptr Word8-c_hs_aes_ctx_decrypt = #ptr struct hs_aes_ctx, decrypt foreign import ccall unsafe "hs_nettle_aes_init" 	c_hs_aes_init :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()-foreign import ccall unsafe "nettle_aes_encrypt"-	c_aes_encrypt :: NettleCryptFunc-foreign import ccall unsafe "&nettle_aes_encrypt"-	p_aes_encrypt :: FunPtr NettleCryptFunc-foreign import ccall unsafe "nettle_aes_decrypt"-	c_aes_decrypt :: NettleCryptFunc-foreign import ccall unsafe "&nettle_aes_decrypt"-	p_aes_decrypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "hs_nettle_aes_encrypt"+	c_hs_aes_encrypt :: NettleCryptFunc+foreign import ccall unsafe "&hs_nettle_aes_encrypt"+	p_hs_aes_encrypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "hs_nettle_aes_decrypt"+	c_hs_aes_decrypt :: NettleCryptFunc+foreign import ccall unsafe "&hs_nettle_aes_decrypt"+	p_hs_aes_decrypt :: FunPtr NettleCryptFunc +c_hs_aes128_ctx_size :: Int+c_hs_aes128_ctx_size = #{size struct hs_aes128_ctx}+c_hs_aes128_ctx_encrypt :: Ptr Word8 -> Ptr Word8+c_hs_aes128_ctx_encrypt = #ptr struct hs_aes128_ctx, encrypt+c_hs_aes128_ctx_decrypt :: Ptr Word8 -> Ptr Word8+c_hs_aes128_ctx_decrypt = #ptr struct hs_aes128_ctx, decrypt+foreign import ccall unsafe "hs_nettle_aes128_init"+	c_hs_aes128_init :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_aes128_encrypt"+	c_aes128_encrypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_aes128_encrypt"+	p_aes128_encrypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "nettle_aes128_decrypt"+	c_aes128_decrypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_aes128_decrypt"+	p_aes128_decrypt :: FunPtr NettleCryptFunc +c_hs_aes192_ctx_size :: Int+c_hs_aes192_ctx_size = #{size struct hs_aes192_ctx}+c_hs_aes192_ctx_encrypt :: Ptr Word8 -> Ptr Word8+c_hs_aes192_ctx_encrypt = #ptr struct hs_aes192_ctx, encrypt+c_hs_aes192_ctx_decrypt :: Ptr Word8 -> Ptr Word8+c_hs_aes192_ctx_decrypt = #ptr struct hs_aes192_ctx, decrypt+foreign import ccall unsafe "hs_nettle_aes192_init"+	c_hs_aes192_init :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_aes192_encrypt"+	c_aes192_encrypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_aes192_encrypt"+	p_aes192_encrypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "nettle_aes192_decrypt"+	c_aes192_decrypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_aes192_decrypt"+	p_aes192_decrypt :: FunPtr NettleCryptFunc++c_hs_aes256_ctx_size :: Int+c_hs_aes256_ctx_size = #{size struct hs_aes256_ctx}+c_hs_aes256_ctx_encrypt :: Ptr Word8 -> Ptr Word8+c_hs_aes256_ctx_encrypt = #ptr struct hs_aes256_ctx, encrypt+c_hs_aes256_ctx_decrypt :: Ptr Word8 -> Ptr Word8+c_hs_aes256_ctx_decrypt = #ptr struct hs_aes256_ctx, decrypt+foreign import ccall unsafe "hs_nettle_aes256_init"+	c_hs_aes256_init :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_aes256_encrypt"+	c_aes256_encrypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_aes256_encrypt"+	p_aes256_encrypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "nettle_aes256_decrypt"+	c_aes256_decrypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_aes256_decrypt"+	p_aes256_decrypt :: FunPtr NettleCryptFunc+ c_arctwo_ctx_size :: Int c_arctwo_ctx_size = #{size struct arctwo_ctx} foreign import ccall unsafe "nettle_arctwo_set_key"@@ -193,21 +298,62 @@  c_hs_camellia_ctx_size :: Int c_hs_camellia_ctx_size = #{size struct hs_camellia_ctx}-c_hs_camellia_ctx_encrypt :: Ptr Word8 -> Ptr Word8-c_hs_camellia_ctx_encrypt = #ptr struct hs_camellia_ctx, encrypt-c_hs_camellia_ctx_decrypt :: Ptr Word8 -> Ptr Word8-c_hs_camellia_ctx_decrypt = #ptr struct hs_camellia_ctx, decrypt foreign import ccall unsafe "hs_nettle_camellia_init" 	c_hs_camellia_init :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()-foreign import ccall unsafe "nettle_camellia_crypt"-	c_camellia_crypt :: NettleCryptFunc-foreign import ccall unsafe "&nettle_camellia_crypt"-	p_camellia_crypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "hs_nettle_camellia_encrypt"+	c_hs_camellia_encrypt :: NettleCryptFunc+foreign import ccall unsafe "&hs_nettle_camellia_encrypt"+	p_hs_camellia_encrypt :: FunPtr NettleCryptFunc+foreign import ccall unsafe "hs_nettle_camellia_decrypt"+	c_hs_camellia_decrypt :: NettleCryptFunc+foreign import ccall unsafe "&hs_nettle_camellia_decrypt"+	p_hs_camellia_decrypt :: FunPtr NettleCryptFunc +c_hs_camellia128_ctx_size :: Int+c_hs_camellia128_ctx_size = #{size struct hs_camellia128_ctx}+c_hs_camellia128_ctx_encrypt :: Ptr Word8 -> Ptr Word8+c_hs_camellia128_ctx_encrypt = #ptr struct hs_camellia128_ctx, encrypt+c_hs_camellia128_ctx_decrypt :: Ptr Word8 -> Ptr Word8+c_hs_camellia128_ctx_decrypt = #ptr struct hs_camellia128_ctx, decrypt+foreign import ccall unsafe "hs_nettle_camellia128_init"+	c_hs_camellia128_init :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_camellia128_crypt"+	c_camellia128_crypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_camellia128_crypt"+	p_camellia128_crypt :: FunPtr NettleCryptFunc++c_hs_camellia192_ctx_size :: Int+c_hs_camellia192_ctx_size = #{size struct hs_camellia192_ctx}+c_hs_camellia192_ctx_encrypt :: Ptr Word8 -> Ptr Word8+c_hs_camellia192_ctx_encrypt = #ptr struct hs_camellia192_ctx, encrypt+c_hs_camellia192_ctx_decrypt :: Ptr Word8 -> Ptr Word8+c_hs_camellia192_ctx_decrypt = #ptr struct hs_camellia192_ctx, decrypt+foreign import ccall unsafe "hs_nettle_camellia192_init"+	c_hs_camellia192_init :: Ptr Word8 -> Ptr Word8 -> IO ()+-- 192 and 256 bit variants use same crypt function+foreign import ccall unsafe "nettle_camellia256_crypt"+	c_camellia192_crypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_camellia256_crypt"+	p_camellia192_crypt :: FunPtr NettleCryptFunc++c_hs_camellia256_ctx_size :: Int+c_hs_camellia256_ctx_size = #{size struct hs_camellia256_ctx}+c_hs_camellia256_ctx_encrypt :: Ptr Word8 -> Ptr Word8+c_hs_camellia256_ctx_encrypt = #ptr struct hs_camellia256_ctx, encrypt+c_hs_camellia256_ctx_decrypt :: Ptr Word8 -> Ptr Word8+c_hs_camellia256_ctx_decrypt = #ptr struct hs_camellia256_ctx, decrypt+foreign import ccall unsafe "hs_nettle_camellia256_init"+	c_hs_camellia256_init :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_camellia256_crypt"+	c_camellia256_crypt :: NettleCryptFunc+foreign import ccall unsafe "&nettle_camellia256_crypt"+	p_camellia256_crypt :: FunPtr NettleCryptFunc+ c_cast128_ctx_size :: Int c_cast128_ctx_size = #{size struct cast128_ctx}-foreign import ccall unsafe "nettle_cast128_set_key"-	c_cast128_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()+-- cast128_set_key uses a 128-bit fixed size key, cast-5 supports the variable length+foreign import ccall unsafe "nettle_cast5_set_key"+	c_cast5_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO () foreign import ccall unsafe "nettle_cast128_encrypt" 	c_cast128_encrypt :: NettleCryptFunc foreign import ccall unsafe "&nettle_cast128_encrypt"@@ -278,17 +424,37 @@ foreign import ccall unsafe "nettle_arcfour_crypt" 	c_arcfour_crypt :: NettleCryptFunc +c_chacha_ctx_size :: Int+c_chacha_ctx_size = #{size struct chacha_ctx}+foreign import ccall unsafe "nettle_chacha_set_key"+	c_chacha_set_key :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_chacha_set_nonce"+	c_chacha_set_nonce :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_chacha_crypt"+	c_chacha_crypt :: NettleCryptFunc+ c_salsa20_ctx_size :: Int c_salsa20_ctx_size = #{size struct salsa20_ctx} foreign import ccall unsafe "nettle_salsa20_set_key" 	c_salsa20_set_key :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()-foreign import ccall unsafe "nettle_salsa20_set_iv"-	c_salsa20_set_iv :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_salsa20_set_nonce"+	c_salsa20_set_nonce :: Ptr Word8 -> Ptr Word8 -> IO () foreign import ccall unsafe "nettle_salsa20_crypt" 	c_salsa20_crypt :: NettleCryptFunc foreign import ccall unsafe "nettle_salsa20r12_crypt" 	c_salsa20r12_crypt :: NettleCryptFunc ---+c_chacha_poly1305_ctx_size :: Int+c_chacha_poly1305_ctx_size = #{size struct chacha_poly1305_ctx}+foreign import ccall unsafe "nettle_chacha_poly1305_set_key"+	c_chacha_poly1305_set_key :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_chacha_poly1305_set_nonce"+	c_chacha_poly1305_set_nonce :: Ptr Word8 -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_chacha_poly1305_update"+	c_chacha_poly1305_update :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()+foreign import ccall unsafe "nettle_chacha_poly1305_encrypt"+	c_chacha_poly1305_encrypt :: NettleCryptFunc+foreign import ccall unsafe "nettle_chacha_poly1305_decrypt"+	c_chacha_poly1305_decrypt :: NettleCryptFunc+foreign import ccall unsafe "nettle_chacha_poly1305_digest"+	c_chacha_poly1305_digest :: Ptr Word8 -> Word -> Ptr Word8 -> IO ()
src/Tests/Ciphers.hs view
@@ -148,6 +148,7 @@ 	, testBlockCipher defaultKATs (undefined :: TWOFISH) 	, testBlockCipher defaultKATs (undefined :: SERPENT) 	, testStreamCipher defaultStreamKATs (undefined :: ARCFOUR)+	, testStreamCipher defaultStreamKATs (undefined :: CHACHA) 	, testStreamCipher defaultStreamKATs (undefined :: SALSA20) 	, testStreamCipher defaultStreamKATs (undefined :: ESTREAM_SALSA20) @@ -170,10 +171,13 @@ 	, genBlockTest (undefined :: TWOFISH) 	, genBlockTest (undefined :: SERPENT) 	, genStreamTest (undefined :: ARCFOUR)+	, genStreamTest (undefined :: CHACHA) 	, genStreamTest (undefined :: SALSA20) 	, genStreamTest (undefined :: ESTREAM_SALSA20)+	, genStreamNonceTest (undefined :: CHACHA) 	, genStreamNonceTest (undefined :: SALSA20) 	, genStreamNonceTest (undefined :: ESTREAM_SALSA20)+	, genStreamNonceWord64Test (undefined :: CHACHA) 	, genStreamNonceWord64Test (undefined :: SALSA20) 	, genStreamNonceWord64Test (undefined :: ESTREAM_SALSA20) 	]
src/nettle-ciphers.c view
@@ -38,16 +38,132 @@ 	} } +void hs_nettle_aes128_init(struct hs_aes128_ctx *ctx, const char *key) {+	aes128_set_encrypt_key(&ctx->encrypt, key);+	aes128_invert_key(&ctx->decrypt, &ctx->encrypt);+}++void hs_nettle_aes192_init(struct hs_aes192_ctx *ctx, const char *key) {+	aes192_set_encrypt_key(&ctx->encrypt, key);+	aes192_invert_key(&ctx->decrypt, &ctx->encrypt);+}++void hs_nettle_aes256_init(struct hs_aes256_ctx *ctx, const char *key) {+	aes256_set_encrypt_key(&ctx->encrypt, key);+	aes256_invert_key(&ctx->decrypt, &ctx->encrypt);+}+ void hs_nettle_aes_init(struct hs_aes_ctx *ctx, unsigned int key_size, const char *key) { 	assert(16 == key_size || 24 == key_size || 32 == key_size); -	aes_set_encrypt_key(&ctx->encrypt, key_size, key);-	aes_invert_key(&ctx->decrypt, &ctx->encrypt);+	switch (key_size) {+	case 16:+		ctx->selector = AES128;+		aes128_set_encrypt_key(&ctx->encrypt.inner128, key);+		aes128_invert_key(&ctx->decrypt.inner128, &ctx->encrypt.inner128);+		break;+	case 24:+		ctx->selector = AES192;+		aes192_set_encrypt_key(&ctx->encrypt.inner192, key);+		aes192_invert_key(&ctx->decrypt.inner192, &ctx->encrypt.inner192);+		break;+	case 32:+		ctx->selector = AES256;+		aes256_set_encrypt_key(&ctx->encrypt.inner256, key);+		aes256_invert_key(&ctx->decrypt.inner256, &ctx->encrypt.inner256);+		break;+	} } +void hs_nettle_aes_encrypt(const struct hs_aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src) {+	switch (ctx->selector) {+	case AES128:+		aes128_encrypt(&ctx->encrypt.inner128, length, dst, src);+		break;+	case AES192:+		aes192_encrypt(&ctx->encrypt.inner192, length, dst, src);+		break;+	case AES256:+		aes256_encrypt(&ctx->encrypt.inner256, length, dst, src);+		break;+	}+}++void hs_nettle_aes_decrypt(const struct hs_aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src) {+	switch (ctx->selector) {+	case AES128:+		aes128_decrypt(&ctx->decrypt.inner128, length, dst, src);+		break;+	case AES192:+		aes192_decrypt(&ctx->decrypt.inner192, length, dst, src);+		break;+	case AES256:+		aes256_decrypt(&ctx->decrypt.inner256, length, dst, src);+		break;+	}+}++void hs_nettle_camellia128_init(struct hs_camellia128_ctx *ctx, const char *key) {+	camellia128_set_encrypt_key(&ctx->encrypt, key);+	camellia128_invert_key(&ctx->decrypt, &ctx->encrypt);+}++void hs_nettle_camellia192_init(struct hs_camellia192_ctx *ctx, const char *key) {+	camellia192_set_encrypt_key(&ctx->encrypt, key);+	camellia192_invert_key(&ctx->decrypt, &ctx->encrypt);+}++void hs_nettle_camellia256_init(struct hs_camellia256_ctx *ctx, const char *key) {+	camellia256_set_encrypt_key(&ctx->encrypt, key);+	camellia256_invert_key(&ctx->decrypt, &ctx->encrypt);+}+ void hs_nettle_camellia_init(struct hs_camellia_ctx *ctx, unsigned int key_size, const char *key) { 	assert(16 == key_size || 24 == key_size || 32 == key_size); -	camellia_set_encrypt_key(&ctx->encrypt, key_size, key);-	camellia_invert_key(&ctx->decrypt, &ctx->encrypt);+	switch (key_size) {+	case 16:+		ctx->selector = CAMELLIA128;+		camellia128_set_encrypt_key(&ctx->encrypt.inner128, key);+		camellia128_invert_key(&ctx->decrypt.inner128, &ctx->encrypt.inner128);+		break;+	case 24:+		ctx->selector = CAMELLIA192;+		camellia192_set_encrypt_key(&ctx->encrypt.inner192, key);+		camellia192_invert_key(&ctx->decrypt.inner192, &ctx->encrypt.inner192);+		break;+	case 32:+		ctx->selector = CAMELLIA256;+		camellia256_set_encrypt_key(&ctx->encrypt.inner256, key);+		camellia256_invert_key(&ctx->decrypt.inner256, &ctx->encrypt.inner256);+		break;+	}+}++void hs_nettle_camellia_encrypt(const struct hs_camellia_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src) {+	switch (ctx->selector) {+	case CAMELLIA128:+		camellia128_crypt(&ctx->encrypt.inner128, length, dst, src);+		break;+	case CAMELLIA192:+		camellia192_crypt(&ctx->encrypt.inner192, length, dst, src);+		break;+	case CAMELLIA256:+		camellia256_crypt(&ctx->encrypt.inner256, length, dst, src);+		break;+	}+}++void hs_nettle_camellia_decrypt(const struct hs_camellia_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src) {+	switch (ctx->selector) {+	case CAMELLIA128:+		camellia128_crypt(&ctx->decrypt.inner128, length, dst, src);+		break;+	case CAMELLIA192:+		camellia192_crypt(&ctx->decrypt.inner192, length, dst, src);+		break;+	case CAMELLIA256:+		camellia256_crypt(&ctx->decrypt.inner256, length, dst, src);+		break;+	} }
src/nettle-ciphers.h view
@@ -2,6 +2,12 @@ #ifndef _HS_NETTLE_CIPHERS_H #define _HS_NETTLE_CIPHERS_H _HS_NETTLE_CIPHERS_H +#include <nettle/version.h>++#if (NETTLE_VERSION_MAJOR != 3)+#error unsupported nettle version+#endif+ #include <sys/types.h> #include <nettle/cbc.h> #include <nettle/gcm.h>@@ -19,8 +25,16 @@  /* stream ciphers */ #include <nettle/arcfour.h>+#include <nettle/chacha.h> #include <nettle/salsa20.h> +/* AEAD ciphers */+#include <nettle/chacha-poly1305.h>++#if (CHACHA_POLY1305_NONCE_SIZE != CHACHA_NONCE96_SIZE)+#error unsupported nettle version, require 96-bit nonce chacha-poly1305 variant+#endif+ void hs_nettle_cfb_encrypt(void *ctx, nettle_crypt_func *f, 	unsigned block_size, uint8_t *iv, 	unsigned length, uint8_t *dst,@@ -33,15 +47,60 @@ 	const uint8_t *src);  +struct hs_aes128_ctx {+	struct aes128_ctx encrypt, decrypt;+};+void hs_nettle_aes128_init(struct hs_aes128_ctx *ctx, const char *key);++struct hs_aes192_ctx {+	struct aes192_ctx encrypt, decrypt;+};+void hs_nettle_aes192_init(struct hs_aes192_ctx *ctx, const char *key);++struct hs_aes256_ctx {+	struct aes256_ctx encrypt, decrypt;+};+void hs_nettle_aes256_init(struct hs_aes256_ctx *ctx, const char *key);++union hs_aes_ctx_inner {+	struct aes128_ctx inner128;+	struct aes192_ctx inner192;+	struct aes256_ctx inner256;+}; struct hs_aes_ctx {-	struct aes_ctx encrypt, decrypt;+	enum { AES128, AES192, AES256 } selector;+	union hs_aes_ctx_inner encrypt, decrypt; }; void hs_nettle_aes_init(struct hs_aes_ctx *ctx, unsigned int key_size, const char *key);+void hs_nettle_aes_encrypt(const struct hs_aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);+void hs_nettle_aes_decrypt(const struct hs_aes_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src); +struct hs_camellia128_ctx {+	struct camellia128_ctx encrypt, decrypt;+};+void hs_nettle_camellia128_init(struct hs_camellia128_ctx *ctx, const char *key); +struct hs_camellia192_ctx {+	struct camellia192_ctx encrypt, decrypt;+};+void hs_nettle_camellia192_init(struct hs_camellia192_ctx *ctx, const char *key);++struct hs_camellia256_ctx {+	struct camellia256_ctx encrypt, decrypt;+};+void hs_nettle_camellia256_init(struct hs_camellia256_ctx *ctx, const char *key);++union hs_camellia_ctx_inner {+	struct camellia128_ctx inner128;+	struct camellia192_ctx inner192;+	struct camellia256_ctx inner256;+}; struct hs_camellia_ctx {-	struct camellia_ctx encrypt, decrypt;+	enum { CAMELLIA128, CAMELLIA192, CAMELLIA256 } selector;+	union hs_camellia_ctx_inner encrypt, decrypt; }; void hs_nettle_camellia_init(struct hs_camellia_ctx *ctx, unsigned int key_size, const char *key);+void hs_nettle_camellia_encrypt(const struct hs_camellia_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);+void hs_nettle_camellia_decrypt(const struct hs_camellia_ctx *ctx, size_t length, uint8_t *dst, const uint8_t *src);  #endif
src/nettle-hash.h view
@@ -2,6 +2,12 @@ #ifndef _HS_NETTLE_HASH_H #define _HS_NETTLE_HASH_H _HS_NETTLE_HASH_H +#include <nettle/version.h>++#if (NETTLE_VERSION_MAJOR != 3)+#error unsupported nettle version+#endif+ #include <sys/types.h> #include <nettle/cbc.h> #include <nettle/gcm.h>