Copyright | (C) Hécate Moonlight 2022 |
---|---|
License | BSD-3-Clause |
Maintainer | The Haskell Cryptography Group |
Stability | Stable |
Portability | GHC only |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- data CryptoSecretStreamXChaCha20Poly1305State
- withCryptoSecretStreamXChaCha20Poly1305State :: (Ptr CryptoSecretStreamXChaCha20Poly1305State -> IO a) -> IO a
- cryptoSecretStreamXChaCha20Poly1305KeyGen :: Ptr CUChar -> IO ()
- cryptoSecretStreamXChaCha20Poly1305InitPush :: Ptr CryptoSecretStreamXChaCha20Poly1305State -> Ptr CUChar -> Ptr CUChar -> IO CInt
- cryptoSecretStreamXChaCha20Poly1305Push :: Ptr CryptoSecretStreamXChaCha20Poly1305State -> Ptr CUChar -> Ptr CULLong -> Ptr CUChar -> CULLong -> Ptr CUChar -> CULLong -> CUChar -> IO CInt
- cryptoSecretStreamXChaCha20Poly1305InitPull :: Ptr CryptoSecretStreamXChaCha20Poly1305State -> Ptr CUChar -> Ptr CUChar -> IO CInt
- cryptoSecretStreamXChaCha20Poly1305Pull :: Ptr CryptoSecretStreamXChaCha20Poly1305State -> Ptr CUChar -> Ptr CULLong -> Ptr CUChar -> Ptr CUChar -> CULLong -> Ptr CUChar -> CULLong -> IO CInt
- cryptoSecretStreamXChaCha20Poly1305Rekey :: Ptr CryptoSecretStreamXChaCha20Poly1305State -> IO ()
- cryptoSecretStreamXChaCha20Poly1305KeyBytes :: CSize
- cryptoSecretStreamXChaCha20Poly1305HeaderBytes :: CSize
- cryptoSecretStreamXChaCha20Poly1305StateBytes :: CSize
- cryptoSecretStreamXChaCha20Poly1305ABytes :: CSize
- cryptoSecretStreamXChaCha20Poly1305MessageBytesMax :: CSize
- cryptoSecretStreamXChaCha20Poly1305TagMessage :: CSize
- cryptoSecretStreamXChaCha20Poly1305TagPush :: CSize
- cryptoSecretStreamXChaCha20Poly1305TagRekey :: CSize
- cryptoSecretStreamXChaCha20Poly1305TagFinal :: CSize
Introduction
This high-level API encrypts a sequence of messages, or a single message split into an arbitrary number of chunks, using a secret key, with the following properties:
- Messages cannot be truncated, removed, reordered, duplicated or modified without this being detected by the decryption functions.
- The same sequence encrypted twice will produce different ciphertexts.
- An authentication tag is added to each encrypted message: stream corruption will be detected early, without having to read the stream until the end.
- Each message can include additional data (ex: timestamp, protocol version) in the computation of the authentication tag.
- Messages can have different sizes.
- There are no practical limits to the total length of the stream, or to the total number of individual messages.
- Ratcheting: at any point in the stream, it is possible to "forget" the secret key used to encrypt the previous messages, and switch to a new key.
Usage
An encrypted stream starts with a short header, whose size is cryptoSecretStreamXChaCha20Poly1305HeaderBytes
bytes.
That header must be sent/stored before the sequence of encrypted messages, as it is required to decrypt the stream.
The header content doesn't have to be secret and decryption with a different header would fail.
A tag is attached to each message. That tag can be any of:
- 0, or
cryptoSecretStreamXChaCha20Poly1305TagMessage
: the most common tag, that doesn't add any information about the nature of the message. cryptoSecretStreamXChaCha20Poly1305TagFinal
: indicates that the message marks the end of the stream, and erases the secret key used to encrypt the previous sequence.cryptoSecretStreamXChaCha20Poly1305TagPush
: indicates that the message marks the end of a set of messages, but not the end of the stream. For example, a huge JSON string sent as multiple chunks can use this tag to indicate to the application that the string is complete and that it can be decoded. But the stream itself is not closed, and more data may follow.cryptoSecretStreamXChaCha20Poly1305TagRekey
: "forget" the secret key used to encrypt this message and the previous ones, and derive a new secret key.
A typical encrypted stream simply attaches 0 as a tag to all messages, except the last one which is tagged as cryptoSecretStreamXChaCha20Poly1305TagFinal
.
Note that tags are encrypted; encrypted streams do not reveal any information about sequence boundaries
(cryptoSecretStreamXChaCha20Poly1305TagPush
and cryptoSecretStreamXChaCha20Poly1305TagRekey
tags).
For each message, additional data can be included in the computation of the authentication tag.
With this API, additional data is rarely required, and most applications can just use nullPtr
and a length of 0 instead.
data CryptoSecretStreamXChaCha20Poly1305State Source #
Opaque tag representing the hash state struct crypto_secretstream_xchacha20poly1305_state
used by the C API.
To use a CryptoSecretStreamXChaCha20Poly1305State
, use withCryptoSecretStreamXChaCha20Poly1305State
.
Since: 0.0.1.0
withCryptoSecretStreamXChaCha20Poly1305State :: (Ptr CryptoSecretStreamXChaCha20Poly1305State -> IO a) -> IO a Source #
Allocate an opaque CryptoSecretStreamXChaCha20Poly1305State
of size cryptoSecretStreamXChaCha20Poly1305StateBytes
.
⚠️ Do not leak the CryptoSecretStreamXChaCha20Poly1305State
outside of the lambda,
otherwise you will point at deallocated memory!
Since: 0.0.1.0
Encryption
cryptoSecretStreamXChaCha20Poly1305KeyGen Source #
Create a random secret key to encrypt a stream, and store it into the parameter
Note that using this function is not required to obtain a suitable key:
the secretstream API can use any secret key whose size is
cryptoSecretStreamXChaCha20Poly1305KeyBytes
bytes.
See: crypto_secretstream_xchacha20poly1305_keygen()
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305InitPush Source #
:: Ptr CryptoSecretStreamXChaCha20Poly1305State | Cryptographic state |
-> Ptr CUChar | Header buffer, must be of size |
-> Ptr CUChar | Buffer holding the secret key. Must be of size |
-> IO CInt | Returns 0 on success, -1 on error. |
Initialise the cryptographic state using the secret key, then stores the stream header into the header buffer
See: crypto_secretstream_xchacha20poly1305_init_push()
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305Push Source #
:: Ptr CryptoSecretStreamXChaCha20Poly1305State | Cryptographic state |
-> Ptr CUChar | Buffer that receives the cipher text. |
-> Ptr CULLong | If this pointer is not |
-> Ptr CUChar | Pointer to the message to encrypt |
-> CULLong | Length of the message ( |
-> Ptr CUChar | Additional, optional data that can be included in the computation. Can be |
-> CULLong | Length of the additional, optional data. Can be 0 if you have nothing to add. |
-> CUChar | Tag for the cipher text. |
-> IO CInt | Returns 0 on success, -1 on error. |
Encrypt a message using a cryptographic state and a tag.
Additional data can be optionally provided.
The maximum length of an individual message is cryptoSecretStreamXChaCha20Poly1305MessageBytesMax
bytes (~ 256 GB).
See: crypto_secretstream_xchacha20poly1305_push()
Since: 0.0.1.0
Decryption
cryptoSecretStreamXChaCha20Poly1305InitPull Source #
:: Ptr CryptoSecretStreamXChaCha20Poly1305State | Cryptographic state |
-> Ptr CUChar | Header buffer, must be of size |
-> Ptr CUChar | Buffer holding the secret key. Must be of size |
-> IO CInt | Returns 0 on success, -1 if the header is invalid. |
Initialise the cryptographic state using the secret key and a header. The secret key will not be required any more for subsequent operations
See: crypto_secretstream_xchacha20poly1305_init_pull()
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305Pull Source #
:: Ptr CryptoSecretStreamXChaCha20Poly1305State | Cryptographic state. |
-> Ptr CUChar | Buffer that will hold the decrypted message. |
-> Ptr CULLong | If this pointer is not |
-> Ptr CUChar | If this pointer is not |
-> Ptr CUChar | Cipher text to be decrypted. |
-> CULLong | Length in bytes of the cipher text. |
-> Ptr CUChar | Additional, optional data that was bundled with the cipher text will be put there. Can be |
-> CULLong | Length of the additional, optional data. Can be 0 if you have nothing to add. |
-> IO CInt | Return 0 on success, -1 if the ciphertext appears to be invalid. |
Decrypt a message chunk.
Applications will typically call this function in a loop, until a message with the
cryptoSecretStreamXChaCha20Poly1305TagFinal
tag is found.
See: crypto_secretstream_xchacha20poly1305_pull()
Since: 0.0.1.0
Rekeying
cryptoSecretStreamXChaCha20Poly1305Rekey Source #
:: Ptr CryptoSecretStreamXChaCha20Poly1305State | Cryptographic state. |
-> IO () |
Rekeying happens automatically and transparently, before the internal counter of the underlying cipher wraps. Therefore, streams can be arbitrary large.
Optionally, applications for which forward secrecy is critical can attach the cryptoSecretStreamXChaCha20Poly1305TagRekey
tag to a message in order to trigger an explicit rekeying.
The decryption API will automatically update the secret key if this tag is found attached to a message. Explicit rekeying can also be performed without adding a tag, by calling this function.
This updates the state, but doesn't add any information about the secret key change to the stream. If this function is used to create an encrypted stream, the decryption process must call that function at the exact same stream location.
See: crypto_secretstream_xchacha20poly1305_rekey()
Since: 0.0.1.0
Constants
Key, Header and State size constants
cryptoSecretStreamXChaCha20Poly1305StateBytes :: CSize Source #
Size of an opaque CryptoSecretStreamXChaCha20Poly1305State
See: crypto_secretstream_xchacha20poly1305_statebytes
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305ABytes :: CSize Source #
Size of an authentication tag in bytes
See: crypto_secretstream_xchacha20poly1305_ABYTES
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305MessageBytesMax :: CSize Source #
Maximum length of an invidual message in bytes (~ 256 GB)
See: crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX
Since: 0.0.1.0
Tag constants
cryptoSecretStreamXChaCha20Poly1305TagMessage :: CSize Source #
Most common tag, add no information about the nature of the message
See: crypto_secretstream_xchacha20poly1305_TAG_MESSAGE
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305TagPush :: CSize Source #
Indicates that the message marks the end of a set of messages, but not the end of the stream
See: crypto_secretstream_xchacha20poly1305_TAG_PUSH
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305TagRekey :: CSize Source #
"forget" the secret key used to encrypt this message and the previous ones, and derive a new secret key.
See: crypto_secretstream_xchacha20poly1305_TAG_REKEY
Since: 0.0.1.0
cryptoSecretStreamXChaCha20Poly1305TagFinal :: CSize Source #
Marks the end of the stream, and erases the secret key used to encrypt the previous sequence.
See: crypto_secretstream_xchacha20poly1305_TAG_FINAL
Since: 0.0.1.0