7 Miscellaneous Notes and Utilities
7.1 Input to Cryptographic Operations
bytes? —
no conversion needed string? —
converted to bytes via string->bytes/utf-8 input-port? —
read until eof is returned (but the port is not closed) bytes-range? —
represents a subsequence of a bytestring
struct
(struct bytes-range (bs start end))
bs : bytes? start : exact-nonnegative-integer? end : exact-nonnegative-integer?
Equivalent to (subbytes bs start end) if bs is not subsequently mutated, but avoids making a copy.
7.2 Random Bytes
procedure
(crypto-random-bytes n) → bytes?
n : exact-nonnegative-integer?
7.3 Notes on Cryptography Providers
7.3.1 CSPRNG Initialization
Some cryptographic operations require a source of cryptographically secure pseudo-random numbers. Some of these, such as generate-cipher-key, are handled at the Racket level and use crypto-random-bytes. Other operations, such as generate-private-key, RSA signing with PSS padding, and many more, use the crypto provider’s internal CSPRNG. This section contains notes on crypto providers’ CSPRNG initialization.
libcrypto The libcrypto foreign library automatically seeds its CSPRNG using entropy obtained from the operating system (as described here).
gcrypt The libgcrypt foreign library seems to perform some default CSPRNG initialization, but I don’t know the details.
nettle The crypto library creates a Yarrow-256 instance and seeds it with entropy obtained from crypto-random-bytes. The instance is reseeded when a certain number of entropy-consuming operations have been performed since the last reseed.
Changed in version 1.2 of package crypto-lib: The crypto module now also re-exports crypto-random-bytes from racket/random.
7.3.2 Libcrypto Quirks
PSS padding for RSA signatures is, in principle, parameterized by the salt length. A standard choice is the length of the digest to be signed. By default, libcrypto uses the maximum possible salt length when signing and infers the salt length when verifying, as documented for EVP_PKEY_CTX_set_rsa_pss_saltlen. See also this discussion. Unfortunately, other libraries do not directly support this behavior and it is nontrivial to work around it. Thus for greater compatibility, this library defines 'pss padding to use the digest length and 'pss* to be the libcrypto-specific behavior.
7.3.3 GCrypt Quirks
If ECDSA is used with a digest longer than the bit-length of the curve, gcrypt either fails to correctly truncate the digest or otherwise handles it by default in a way incompatible with libcrypto and nettle. Consequently, this library truncates the digest before passing it to gcrypt for signing.
GCrypt does not expose operations to compute EC and EdDSA public keys from the private keys, so reading a private key in PrivateKeyInfo or OneAsymmetricKey form may fail if the optional public key field is missing.
7.3.4 Sodium Quirks
Sodium provides only “all-at-once” encryption and decryption functions. Consequently, encryption and decryption contexts using sodium ciphers produce no output until cipher-final is called.