crypto::rsa
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, SHA384,
SHA512,
SHA512_224,
SHA512_256,
};
type privparams = struct {
nbitlen: size,
p: []u8,
q: []u8,
dp: []u8,
dq: []u8,
iq: []u8,
};
type pubparams = struct {
n: []u8,
e: []u8,
};
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
type pkcs1_hashalgo = enum {
SHA1,
SHA256, SHA384,
SHA512,
SHA512_224,
SHA512_256,
};
Supported hash algorithms for pkcs1_sign and pkcs1_verify.
type privparams
type privparams = struct {
nbitlen: size,
p: []u8,
q: []u8,
dp: []u8,
dq: []u8,
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
type pubparams = struct {
n: []u8,
e: []u8,
};
RSA key parameters for initializing public keys with pubkey_init.
type default
Show undocumented member
type default = void;
Errors
type badsig
type badsig = !void;
Signature verification failed.
type error
type error = !(badsig | errors::overflow | errors::invalid);
A tagged union of all RSA error types.
Constants
def BITSZ
def BITSZ: size = 4096;
The default bit size of RSA keys is 4096-bit. Used as base for buffer sizes.
def MINBITSZ
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
def PKCS1_SIGNBUFSZ: size = PRIVEXP_BUFSZ;
Required buffer size for pkcs1_sign.
def PKCS1_VERIFYBUFSZ
def PKCS1_VERIFYBUFSZ: size = PUBEXP_BUFSZ + BITSZ / 8;
Required buffer size for pkcs1_verify.
def PRIVKEYSZ
def PRIVKEYSZ: size = 13 + (MAXFACTOR >> 3) * 5;
Size required to store a private key of BITSZ length.
def PSS_SIGNBUFSZ
def PSS_SIGNBUFSZ = PRIVEXP_BUFSZ;
Required minimum buffer size for pss_sign
def PSS_VERIFYBUFSZ
def PSS_VERIFYBUFSZ = PUBEXP_BUFSZ + (BITSZ + 7) / 8;
Required minimum buffer size for pss_verify
def PUBKEYSZ
def PUBKEYSZ: size = 5 + 2 * (BITSZ >> 3);
Size required to store a public key of BITSZ length.
Functions
fn pkcs1_sign
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
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
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
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
fn privkey_nbitlen(privkey: []u8) size;
Returns the length of the modulus 'n'.
fn privkey_nsize
fn privkey_nsize(privkey: []u8) size;
Returns the number of bytes that are required to store a value modulo 'n'.
fn privkey_params
fn privkey_params(privkey: []u8) privparams;
Returns the private key parameters borrowed from 'privkey'.
fn pss_sign
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
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
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
fn pubkey_nbitlen(pubkey: []u8) size;
Returns the length of the modulus 'n' of given public key.
fn pubkey_params
fn pubkey_params(pubkey: []u8) pubparams;
Returns the public key parameters, borrowed from given 'pubkey'.
fn strerror
fn strerror(err: error) str;
Converts an error into a human-friendly string representation.