crypto::cipher
The crypto::cipher module provides block cipher encryption modes. The block
type provides an abstraction over a block cipher algorithm, and functions like
cbc_decryptor create encryptors or decryptors for specific block encryption
modes.
Block ciphers in Hare rely upon caller-provided buffer allocations, and do not
allocate memory at runtime. Consult the documentation for the underlying
algorithm, e.g. crypto::aes, for the appropriate buffer sizes to use.
This is a low-level module which implements cryptographic primitives. Direct use
of cryptographic primitives is not recommended for non-experts, as incorrect use
of these primitives can easily lead to the introduction of security
vulnerabilities. Non-experts are advised to use the high-level operations
available in the top-level crypto module.
Be advised that Hare's cryptography implementations have not been audited.
Index
Types
type blockvtable;
type ctr_stream;
type xorstream;
type block;
type cbc_mode;
type gcmstream;
Constants
const GCMTAGSIZE: size;
Globals
let xorstream_vtable: io::vtable;
Functions
fn blocksz(*block) size;
fn cbc_decrypt(*cbc_mode, []u8, []u8) void;
fn cbc_decryptor(*block, []u8, []u8) cbc_mode;
fn cbc_encrypt(*cbc_mode, []u8, []u8) void;
fn cbc_encryptor(*block, []u8, []u8) cbc_mode;
fn ctr(io::handle, *block, []u8, []u8) ctr_stream;
fn decrypt(*block, []u8, []u8) void;
fn encrypt(*block, []u8, []u8) void;
fn finish(*block) void;
fn gcm() gcmstream;
fn gcm_init(*gcmstream, io::handle, *block, const []u8, const []u8) void;
fn gcm_seal(*gcmstream, []u8) void;
fn gcm_verify(*gcmstream, []u8) (void | errors::invalid);
fn nparallel(*block) size;
Types
type blockvtable
type blockvtable = struct {
blocksz: size,
nparallel: size,
encrypt: *fn(b: *block, dest: []u8, src: []u8) void,
decrypt: *fn(b: *block, dest: []u8, src: []u8) void,
finish: *fn(b: *block) void,
};
An abstract interface for implementing block ciphers.
type ctr_stream
type ctr_stream = struct {
xorstream,
b: *block,
counter: []u8,
xorbuf: []u8,
xorused: size,
};
A counter mode (CTR) stream.
type xorstream
type xorstream = struct {
stream: io::stream,
h: io::handle,
keybuf: *fn(s: *xorstream) []u8,
advance: *fn(s: *xorstream, n: size) void,
finish: *fn(s: *xorstream) void,
};
An abstract interface for implementing streams that encrypt or decrypt by
producing a key stream that is xored with the data. The stream field should
be set to &xorstream_vtable.
After initializing the xorstream can be written to with io::write to
encrypt data and write it to the handle 'h'. For decrpytion 'h' will provide
the ciphertext and the plaintext can be read from the xorstream with
io::read.
type block
Show undocumented member
type block = *blockvtable;
type cbc_mode
Show undocumented member
type cbc_mode = struct {
b: *block,
encrypt: bool,
carry: []u8,
carrybuf: []u8,
};
type gcmstream
Show undocumented member
type gcmstream = struct {
stream: io::stream,
block: nullable *block,
handle: io::handle,
tagbuf: [GCMBLOCKSIZE]u8,
xorbuf: [GCMBLOCKSIZE]u8,
cipherbuf: [GCMBLOCKSIZE]u8,
y0: [GCMBLOCKSIZE]u8,
h: [GCMBLOCKSIZE]u8,
y: u32,
xorbufpos: size,
adlen: u64,
clen: u64,
};
Constants
Show undocumented member
def GCMTAGSIZE: size;
Globals
let xorstream_vtable
Show undocumented member
const xorstream_vtable: io::vtable;
Functions
fn blocksz
fn blocksz(b: *block) size;
Returns the block size in bytes for a block cipher.
fn cbc_decrypt
fn cbc_decrypt(c: *cbc_mode, dest: []u8, src: []u8) void;
Decrypts given blocks with a length that is a multiple of the block size.
In place decryption only works if dest and src point exactly at the
same range.
fn cbc_decryptor
fn cbc_decryptor(b: *block, iv: []u8, buf: []u8) cbc_mode;
Creates a cipher block chaining (CBC) mode decryptor.
The user must supply an initialization vector (IV) equal in length to the
block size of the underlying block cipher, and a temporary state buffer
whose size is equal to the block size times two. The module providing the
underlying block cipher usually provides constants which define the lengths
of these buffers for static allocation.
fn cbc_encrypt
fn cbc_encrypt(c: *cbc_mode, dest: []u8, src: []u8) void;
Encrypts given blocks with a length that is a multiple of the block size.
In place encryption only works if dest and src point exactly at the
same range.
fn cbc_encryptor
fn cbc_encryptor(b: *block, iv: []u8, buf: []u8) cbc_mode;
Creates a cipher block chaining (CBC) mode encryptor.
The user must supply an initialization vector (IV) equal in length to the
block size of the underlying block cipher, and a temporary state buffer
whose size is equal to the block size times two. The module providing the
underlying block cipher usually provides constants which define the lengths
of these buffers for static allocation.
fn ctr
fn ctr(h: io::handle, b: *block, iv: []u8, buf: []u8) ctr_stream;
Creates a counter mode (CTR) cipher stream which can be used for encryption
(by encrypting writes to the underlying handle) or decryption (or by
decrypting reads from the underlying handle), but not both.
The user must supply an initialization vector (IV) equal in length to the
block size of the underlying block cipher, and a temporary state buffer
whose size is equal to the block size times two. The module providing the
underlying block cipher usually provides constants which define the lengths
of these buffers for static allocation.
The user must call io::close when they are done using the stream to
securely erase secret information stored in the stream state. This will also
finish the underlying block cipher.
fn decrypt
fn decrypt(b: *block, dest: []u8, src: []u8) void;
Decrypt up to nparallel blocks from 'src' and writes to 'dest'.
fn encrypt
fn encrypt(b: *block, dest: []u8, src: []u8) void;
Encrypt up to nparallel blocks from 'src' and writes to 'dest'.
fn finish
fn finish(a: *block) void;
Discards any state associated with a block or a stream cipher algorithm,
securely erasing secret data from memory.
fn gcm
fn gcm() gcmstream;
Creates a Galois Counter Mode (GCM) io::stream which can be used for
encryption (by encrypting writes to the underlying handle) or decryption (or
by decrypting reads from the underlying handle), but not both. gcm_init
must be called to initialize the stream, before reading or writing. To
authenticate the encrypted data an authentication tag must be created using
gcm_seal after the encryption step. The authentication tag must be passed
to gcm_verify after decryption to make sure that the encrypted and
additional data were not modified. In case of a verification fail the
decrypted data must not be trusted and hence discarded.
A maximum of 2**36-32 bytes may be encrypted.
The user must call io::close when they are done using the stream to
securely erase secret information stored in the stream state. Close will
also finish the 'block' provided by gcm_init.
fn gcm_init
fn gcm_init(
s: *gcmstream,
handle: io::handle,
b: *block,
iv: const []u8,
ad: const []u8,
) void;
Initialises the gcmstream. The data will be encrypted to or encrypted from
the given 'handle' The implementation only supports a block cipher 'b' with a
block size of 16 bytes. The initialization vector (nonce) 'iv' may have any
size up to 2**61 bytes. 12 bytes is the recommended size, if efficiency is
critical. The additional data 'ad' will be authenticated but not encrypted
and may have a maximum length of 2**61 - 1 bytes. 'ad' will not be written to
the underlying handle.
fn gcm_seal
fn gcm_seal(s: *gcmstream, tag: []u8) void;
Finishes encryption and returns the authentication tag. After calling seal,
the user must not write any more data to the stream.
fn gcm_verify
fn gcm_verify(s: *gcmstream, tag: []u8) (void | errors::invalid);
Verifies the authentication tag against the decrypted data. Must be called
after reading all data from the stream to ensure that the data was not
modified. If the data was modified, errors::invalid will be returned and
the data must not be trusted.
fn nparallel
fn nparallel(b: *block) size;
Returns the number of blocks that can be processed at once for a block
cipher.