crypto::rsa+x86_64 +linux

This module provides RSA signature and encryption schemes defined in PKCS #1. The implementation only supports RSA keys with two prime factors. Most of the RSA operations in this module require buffers to perform. Buffer sizes are provided for keys of a default maximum size of 4096-bits. BITSZ may be changed with compiler flags to support bigger keys. MINBITSZ defines the minimum size accordingly.

Public and private keys are stored in byte slices. pubkey_init is used to initialize a public key. privkey_init or privkey_initd is used to initialize a private key, depending on which parameters are available.

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 pkcs1_hashalgo = enum {
	SHA1,
	SHA256, // SHA224, We don't have this one yet
	SHA384,
	SHA512,
	SHA512_224,
	SHA512_256,
};
type privparams = struct {
	// Bit length of the modulus n. If unknown, the modulus can be provided
	// to the init function, which derivces the length.
	nbitlen: size,
	// First prime factor.
	p: []u8,
	// Second prime factor
	q: []u8,
	// First exponent. dp = d mod (p - 1) where d is the private exponent.
	// May be omitted on [[privkey_initd]].
	dp: []u8,
	// Second exponent. dq = d mod (q - 1) where d is the private exponent.
	// May be omitted on [[privkey_initd]].
	dq: []u8,
	// Coefficient. iq = q^-1 mod p.
	iq: []u8,
};
type pubparams = struct {
	// Modulus in big-endian order
	n: []u8,
	// Public exponent in big-endian order
	e: []u8,
};

// Undocumented types:
type default = void;

Errors

type badsig = !void;
type error = !(badsig | errors::overflow | errors::invalid);

Constants

def BITSZ: size = 4096;
def MINBITSZ: size = 1024;
def PKCS1_SIGNBUFSZ: size = PRIVEXP_BUFSZ;
def PKCS1_VERIFYBUFSZ: size = PUBEXP_BUFSZ + BITSZ / 8;
def PRIVKEYSZ: size = 13 + (MAXFACTOR >> 3) * 5;
def PSS_SIGNBUFSZ = PRIVEXP_BUFSZ;
def PSS_VERIFYBUFSZ = PUBEXP_BUFSZ + (BITSZ + 7) / 8;
def PUBKEYSZ: size = 5 + 2 * (BITSZ >> 3);

Functions

fn pkcs1_sign(priv: []u8, msghash: []u8, sig: []u8, algo: pkcs1_hashalgo, buf: []u8) (void | error);
fn pkcs1_verify(pubkey: []u8, msghash: []u8, sig: []u8, algo: pkcs1_hashalgo, buf: []u8) (void | error);
fn privkey_init(privkey: []u8, x: privparams, n: []u8...) (size | error);
fn privkey_initd(privkey: []u8, x: privparams, d: []u8, n: []u8...) (size | error);
fn privkey_nbitlen(privkey: []u8) size;
fn privkey_nsize(privkey: []u8) size;
fn privkey_params(privkey: []u8) privparams;
fn pss_sign(privkey: []u8, msghash: []u8, sig: []u8, hf: *hash::hash, rand: io::handle, buf: []u8, saltsz: (size | default) = default) (void | error | io::error);
fn pss_verify(pubkey: []u8, msghash: []u8, sig: []u8, hf: *hash::hash, buf: []u8, saltsz: (size | default) = default) (void | error);
fn pubkey_init(pubkey: []u8, x: pubparams) (size | error);
fn pubkey_nbitlen(pubkey: []u8) size;
fn pubkey_params(pubkey: []u8) pubparams;
fn strerror(err: error) str;

Types

type pkcs1_hashalgo[link]

type pkcs1_hashalgo = enum {
	SHA1,
	SHA256, // SHA224, We don't have this one yet
	SHA384,
	SHA512,
	SHA512_224,
	SHA512_256,
};

Supported hash algorithms for pkcs1_sign and pkcs1_verify.

type privparams[link]

type privparams = struct {
	// Bit length of the modulus n. If unknown, the modulus can be provided
	// to the init function, which derivces the length.
	nbitlen: size,
	// First prime factor.
	p: []u8,
	// Second prime factor
	q: []u8,
	// First exponent. dp = d mod (p - 1) where d is the private exponent.
	// May be omitted on [[privkey_initd]].
	dp: []u8,
	// Second exponent. dq = d mod (q - 1) where d is the private exponent.
	// May be omitted on [[privkey_initd]].
	dq: []u8,
	// Coefficient. iq = q^-1 mod p.
	iq: []u8,
};

RSA key parameters for initializing private keys with privkey_init. If the private exponent d is available, privkey_initd may be used, which derives 'dp' and 'dq'. All big integer values are in big-endian order.

type pubparams[link]

type pubparams = struct {
	// Modulus in big-endian order
	n: []u8,
	// Public exponent in big-endian order
	e: []u8,
};

RSA key parameters for initializing public keys with pubkey_init.

type default[link]

Show undocumented member
type default = void;

Errors

type badsig[link]

type badsig = !void;

Signature verification failed.

type error[link]

type error = !(badsig | errors::overflow | errors::invalid);

A tagged union of all RSA error types.

Constants

def BITSZ[link]

def BITSZ: size = 4096;

The default bit size of RSA keys is 4096-bit. Used as base for buffer sizes.

def MINBITSZ[link]

def MINBITSZ: size = 1024;

The minimum bit size of RSA keys used only for validation during key init. The default value is 1024-bit.

def PKCS1_SIGNBUFSZ[link]

def PKCS1_SIGNBUFSZ: size = PRIVEXP_BUFSZ;

Required buffer size for pkcs1_sign.

def PKCS1_VERIFYBUFSZ[link]

def PKCS1_VERIFYBUFSZ: size = PUBEXP_BUFSZ + BITSZ / 8;

Required buffer size for pkcs1_verify.

def PRIVKEYSZ[link]

def PRIVKEYSZ: size = 13 + (MAXFACTOR >> 3) * 5;

Size required to store a private key of BITSZ length.

def PSS_SIGNBUFSZ[link]

def PSS_SIGNBUFSZ = PRIVEXP_BUFSZ;

Required minimum buffer size for pss_sign

def PSS_VERIFYBUFSZ[link]

def PSS_VERIFYBUFSZ = PUBEXP_BUFSZ + (BITSZ + 7) / 8;

Required minimum buffer size for pss_verify

def PUBKEYSZ[link]

def PUBKEYSZ: size = 5 + 2 * (BITSZ >> 3);

Size required to store a public key of BITSZ length.

Functions

fn pkcs1_sign[link]

fn pkcs1_sign(priv: []u8, msghash: []u8, sig: []u8, algo: pkcs1_hashalgo, buf: []u8) (void | error);

Signs a message hash 'msghash' using the PKCS#1 V1.5 signature scheme. The signature will be written to 'sig' which must be in the the size of the modulus n (see privkey_nsize). 'algo' defines the hash algorithm 'msghash' was created with.

A temporary buffer 'buf' of size PKCS1_SIGNBUFSZ must be provided.

fn pkcs1_verify[link]

fn pkcs1_verify(pubkey: []u8, msghash: []u8, sig: []u8, algo: pkcs1_hashalgo, buf: []u8) (void | error);

Verifies a PKCS#1 v1.5 signature given a public key 'pubkey', the message hash 'msghash', the signature 'sig' and the hash algorithm 'algo'. 'algo' must reflect the hash algorithm 'sig' was created with.

A temporary buffer 'buf' of size PKCS1_VERIFYBUFSZ must be provided.

fn privkey_init[link]

fn privkey_init(privkey: []u8, x: privparams, n: []u8...) (size | error);

Initializes the private key 'privkey' using the values from 'x'. 'nbitlen' of 'x' may be omitted, if the modulus 'n' is passed. All other values of 'x' must be present. If 'x' is missing 'dp' and 'dq' use privkey_initd.

In case of invalid parameters or if the key is too small, errors::invalid is returned. If the key does not fit 'privkey', errors::overflow is returned. On success the number of bytes written to 'privkey' is returned.

fn privkey_initd[link]

fn privkey_initd(privkey: []u8, x: privparams, d: []u8, n: []u8...) (size | error);

Initializes the private key 'privkey' using the values from 'x' and the secret exponent 'd'. 'dp' and 'dq' will be derived from 'p' and 'q' of 'x'. 'nbitlen' of 'x' may be omitted, if the modulus 'n' is passed. 'x' must provide 'iq'.

In case of invalid parameters or if the key is too small, errors::invalid is returned. If the key does not fit 'privkey', errors::overflow is returned. On success the number of bytes written to 'privkey' is returend.

fn privkey_nbitlen[link]

fn privkey_nbitlen(privkey: []u8) size;

Returns the length of the modulus 'n'.

fn privkey_nsize[link]

fn privkey_nsize(privkey: []u8) size;

Returns the number of bytes that are required to store a value modulo 'n'.

fn privkey_params[link]

fn privkey_params(privkey: []u8) privparams;

Returns the private key parameters borrowed from 'privkey'.

fn pss_sign[link]

fn pss_sign(privkey: []u8, msghash: []u8, sig: []u8, hf: *hash::hash, rand: io::handle, buf: []u8, saltsz: (size | default) = default) (void | error | io::error);

Signs the hash 'msghash' using the private key 'privkey' by applying the PSS signature scheme as defined in RFC 8017. 'sig' must be in the the size of the modulus n (see privkey_nsize)

It is recommended that 'hf' is the same hash function that was used to generate 'msgmhash'. 'buf' needs to be at least the size of PSS_SIGNBUFSZ. 'rand' must be an io::reader that returns a cryptographiclly random data on read like crypto::random::stream. The expected size of the salt is provided with 'saltsz'. Default is the maximum possible salt size.

Returns errors::invalid, if one of the parameters are invalid. errors::overflow is returned, if 'buf' is to small. Errors that occur by reading from 'rand' are returned as io::error.

fn pss_verify[link]

fn pss_verify(pubkey: []u8, msghash: []u8, sig: []u8, hf: *hash::hash, buf: []u8, saltsz: (size | default) = default) (void | error);

Verifies a PSS signature 'sig' of the mesage hash 'msghash' using the public key 'pupkey' as defined in RFC 8017.

'hf' must be the hash that was used to create the signature. 'buf' needs to be at least the size of PSS_VERIFYBUFSZ. The expected size of the salt is provided with 'saltsz'. Default is the maximum possible salt size. The function will fail, if the signature's salt size does not match the expected.

Returns badsig, if the signature verification fails. errors::overflow is returned, if 'buf' is to small.

fn pubkey_init[link]

fn pubkey_init(pubkey: []u8, x: pubparams) (size | error);

Initializes a public key from given pubparams 'x'. The data format of 'pubkey' is subject to change and must not be used to serialize the key. PUBKEYSZ defines the required size to store a key of BITSZ.

If given key does not fit into 'pubkey' or is too small, errors::overflow is returned. Returns errors::invalid, if given key parameters are invalid. Returns the number of bytes written to 'pubkey' on success.

fn pubkey_nbitlen[link]

fn pubkey_nbitlen(pubkey: []u8) size;

Returns the length of the modulus 'n' of given public key.

fn pubkey_params[link]

fn pubkey_params(pubkey: []u8) pubparams;

Returns the public key parameters, borrowed from given 'pubkey'.

fn strerror[link]

fn strerror(err: error) str;

Converts an error into a human-friendly string representation.