raaz-0.3.7: Fast and type safe cryptography.
Copyright(c) Piyush P Kurur 2016
LicenseApache-2.0 OR BSD-3-Clause
MaintainerPiyush P Kurur <ppk@iitpkd.ac.in>
Stabilityexperimental
Safe HaskellSafe-Inferred
LanguageHaskell2010

Raaz.AuthEncrypt

Description

 
Synopsis

Authenticated encryption

Suppose that Alice wants to send a private message to Bob that should not be seen by anyone else. Alice can use their shared secret key K to encrypt the message, which Bob decrypts when he receives it. The secrecy of the key K ensures that a third party Eve will not be able to read what Alice sends. However, it is possible for Eve to forge message and pretend that it has originated from Alice. Consider a string R that Bob receives purportedly from Alice. Since stream ciphers encrypt message M by xoring it with the keystream KS generated using the key K, from Bob's point of view it is impossible to know whether it was some nonsense that Eve sent or whether it was from Alice who wanted to actually send the message R ⊕ KS. In many situations, Eve can exploit this ability to fake communication and breach the security of the protocol. Authenticated encryption is to solve this issue.

Authenticated encryption via message locking

To send a message m using a key k, Alice computes the locked variant using the function lock. At Bobs end, he can unlock this locked message using the function unlock. If there has been any tampering of message on the way from A to B, the unlocking will fail. It is computationally infeasible to decrypt or fake the authentication without knowing the key. Sometimes the protocol requires additional authenticated data. The lockWith and the unlockWith variants are used for this purpose.

Safety against key reuse

The interface exposed here is safe even with key reuse. Under the hood, both lock and lockWith uses randomly generated nounce for each invocation (hence the result is an IO type). The nounce is large (192-bits) and is generated using cryptographically secure pseudo-random generator (csprg). Thus even when a particular key is used multiple times, each such invocation is paired with a distinct nounce thereby preventing the reuse of the (key, nounce)-pair.

Serialisation

Unfortunately, there does not seem to be an agreed upon format for serialising AEAD tokens. As a result the Locked type does not have an instance of Encodable unlike the message digest and message authentication type. However, for particular wire protocol, one can take apart the AEAD token using the Raaz.AuthEncrypt.Unsafe interface and individually serialise the constituents.

Security assumption

The security of the interface is compromised if and only if the key gets exposed. Otherwise an adversary should not be able to read, tamper or forge Locked data.

lock Source #

Arguments

:: Encodable plain 
=> Key Cipher

The key

-> plain

The object to be locked.

-> IO Locked 

Generate a locked version of an unencrypted object. You will need the exact same key to unlock the object. Unlike unsafelock, this function does not require a nounce as internally a random nounce is generated and used each time. Because of this, it is safe to use the same key multiple times.

unlock Source #

Arguments

:: Encodable plain 
=> Key Cipher

The key

-> Locked

Locked object that needs unlocking

-> Maybe plain 

Unlock the locked version of an object. You will need the exact same key that was used to lock the object.

Locking with additional data

Some protocols have additional data that needs to be factored in when sending the locked packet. In such situations one can use the lockWith and unlockWith variants.

lockWith Source #

Arguments

:: (Encodable plain, Encodable aad) 
=> aad

the authenticated additional data.

-> Key Cipher

The key

-> plain

the unencrypted object

-> IO Locked 

This function locks a plain text message together with and additional authenticated data to produce an AEAD token. A peer who has the right key and the additional authenticated data can recover the unencrypted object using the unlockWith function.

Unlike unsafeLockWith, this function does not require a nounce as internally a random nounce is generated and used each time. As a result we do not put any restriction on the key used; it is safe to use the same key multiple times.

unlockWith Source #

Arguments

:: (Encodable plain, Encodable aad) 
=> aad

the authenticated additional data.

-> Key Cipher

The key for the stream cipher

-> Locked

The message to unlock

-> Maybe plain 

Unlock an encrypted authenticated version of the data given the additional data, key, and nounce. An attempt to unlock the element can result in Nothing if either of the following is true.

  1. The key/nounce used to encrypt the data is different
  2. The Authenticated additional data (aad) is incorrect
  3. The cipher text is of the wrong type and hence the fromByteString failed
  4. The Locked message has been tampered with by the adversary

The interface provided does not indicate which of the above failures had happened. This is a deliberate design as revealing the nature of the failure can leak information to a potential attacker.

type Locked = AEAD Cipher AuthTag #

type Cipher = Prim #