Copyright | (c) Piyush P Kurur 2016 |
---|---|
License | Apache-2.0 OR BSD-3-Clause |
Maintainer | Piyush P Kurur <ppk@iitpkd.ac.in> |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- lock :: Encodable plain => Key Cipher -> plain -> IO Locked
- unlock :: Encodable plain => Key Cipher -> Locked -> Maybe plain
- lockWith :: (Encodable plain, Encodable aad) => aad -> Key Cipher -> plain -> IO Locked
- unlockWith :: (Encodable plain, Encodable aad) => aad -> Key Cipher -> Locked -> Maybe plain
- type Locked = AEAD Cipher AuthTag
- type Cipher = Prim
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.
Key reuse.
Authenticated encryption needs, not just a key, but also a
nounce. Under the hood, both lock
and lockWith
uses randomly
generated nounce for each invocation (hence the result is an IO
type). This ensures that the key-nounce pair is never reused. The
nounce is packed together with the cipher text and tag so that at
the receiving end, the packet can be unlocked. It is therefore safe
to lock multiple messages with the same key.
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 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.
:: (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.
:: (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.
- The key/nounce used to encrypt the data is different
- The Authenticated additional data (
aad
) is incorrect - The cipher text is of the wrong type and hence the
fromByteString
failed - 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.