crypto::cipher+x86_64 +linux

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 = 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,
};
type ctr_stream = struct {
	xorstream,
	b: *block,
	counter: []u8,
	xorbuf: []u8,
	xorused: size,
};
type xorstream = struct {
	stream: io::stream,
	h: io::handle,
	// Returns usable part of the current key buffer. The buffer must be
	// modifiable by the callee.
	keybuf: *fn(s: *xorstream) []u8,
	// Advances the start index of the keybuffer by 'n' bytes.
	advance: *fn(s: *xorstream, n: size) void,
	// Erases all sensitive data from memory.
	finish: *fn(s: *xorstream) void,
};

// Undocumented types:
type block = *blockvtable;
type cbc_mode = struct {
	b: *block,
	encrypt: bool,
	carry: []u8,
	carrybuf: []u8,
};
type gcmstream = struct {
	stream: io::stream,
	block: nullable *block,
	handle: io::handle,
	tagbuf: [GCMBLOCKSZ]u8,
	xorbuf: [GCMBLOCKSZ]u8,
	cipherbuf: [GCMBLOCKSZ]u8,
	y0: [GCMBLOCKSZ]u8,
	h: [GCMBLOCKSZ]u8,
	y: u32,
	xorbufpos: size,
	adlen: u64,
	clen: u64,
};

Constants

// Undocumented constants:
def GCMTAGSZ: size = 16;

Globals

// Undocumented globals:
const xorstream_vtable: io::vtable;

Functions

fn blocksz(b: *block) size;
fn cbc_decrypt(c: *cbc_mode, dest: []u8, src: []u8) void;
fn cbc_decryptor(b: *block, iv: []u8, buf: []u8) cbc_mode;
fn cbc_encrypt(c: *cbc_mode, dest: []u8, src: []u8) void;
fn cbc_encryptor(b: *block, iv: []u8, buf: []u8) cbc_mode;
fn ctr(h: io::handle, b: *block, iv: []u8, buf: []u8) ctr_stream;
fn decrypt(b: *block, dest: []u8, src: []u8) void;
fn encrypt(b: *block, dest: []u8, src: []u8) void;
fn finish(a: *block) void;
fn gcm() gcmstream;
fn gcm_init(s: *gcmstream, handle: io::handle, b: *block, iv: const []u8, ad: const []u8) void;
fn gcm_seal(s: *gcmstream, tag: []u8) void;
fn gcm_verify(s: *gcmstream, tag: []u8) (void | errors::invalid);
fn nparallel(b: *block) size;

Types

type blockvtable[link]

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[link]

type ctr_stream = struct {
	xorstream,
	b: *block,
	counter: []u8,
	xorbuf: []u8,
	xorused: size,
};

A counter mode (CTR) stream.

type xorstream[link]

type xorstream = struct {
	stream: io::stream,
	h: io::handle,
	// Returns usable part of the current key buffer. The buffer must be
	// modifiable by the callee.
	keybuf: *fn(s: *xorstream) []u8,
	// Advances the start index of the keybuffer by 'n' bytes.
	advance: *fn(s: *xorstream, n: size) void,
	// Erases all sensitive data from memory.
	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[link]

Show undocumented member
type block = *blockvtable;

type cbc_mode[link]

Show undocumented member
type cbc_mode = struct {
	b: *block,
	encrypt: bool,
	carry: []u8,
	carrybuf: []u8,
};

type gcmstream[link]

Show undocumented member
type gcmstream = struct {
	stream: io::stream,
	block: nullable *block,
	handle: io::handle,
	tagbuf: [GCMBLOCKSZ]u8,
	xorbuf: [GCMBLOCKSZ]u8,
	cipherbuf: [GCMBLOCKSZ]u8,
	y0: [GCMBLOCKSZ]u8,
	h: [GCMBLOCKSZ]u8,
	y: u32,
	xorbufpos: size,
	adlen: u64,
	clen: u64,
};

Constants

def GCMTAGSZ[link]

Show undocumented member
def GCMTAGSZ: size = 16;

Globals

let xorstream_vtable[link]

Show undocumented member
const xorstream_vtable: io::vtable;

Functions

fn blocksz[link]

fn blocksz(b: *block) size;

Returns the block size in bytes for a block cipher.

fn cbc_decrypt[link]

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[link]

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[link]

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[link]

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[link]

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[link]

fn decrypt(b: *block, dest: []u8, src: []u8) void;

Decrypt up to nparallel blocks from 'src' and writes to 'dest'.

fn encrypt[link]

fn encrypt(b: *block, dest: []u8, src: []u8) void;

Encrypt up to nparallel blocks from 'src' and writes to 'dest'.

fn finish[link]

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[link]

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[link]

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[link]

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[link]

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[link]

fn nparallel(b: *block) size;

Returns the number of blocks that can be processed at once for a block cipher.