From b58560a8b31e236306cbc3575e862fc5bd17c3bc Mon Sep 17 00:00:00 2001 From: CuleX Date: Fri, 20 Oct 2017 13:52:11 +0200 Subject: [PATCH] Add man page for crypto_wipe This includes adjustments in other manual pages and examples, telling the user to use crypto_wipe. --- doc/man/man3/crypto_argon2i.3monocypher | 5 ++ doc/man/man3/crypto_blake2b.3monocypher | 4 ++ .../man3/crypto_chacha20_encrypt.3monocypher | 23 +++++++++ doc/man/man3/crypto_key_exchange.3monocypher | 5 ++ doc/man/man3/crypto_lock.3monocypher | 6 +++ doc/man/man3/crypto_lock_init.3monocypher | 9 +++- .../crypto_sign_init_first_pass.3monocypher | 9 ++++ doc/man/man3/crypto_wipe.3monocypher | 48 +++++++++++++++++++ doc/man/man3/intro.3monocypher | 9 ++++ 9 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 doc/man/man3/crypto_wipe.3monocypher diff --git a/doc/man/man3/crypto_argon2i.3monocypher b/doc/man/man3/crypto_argon2i.3monocypher index 4689bca..22e1b7d 100644 --- a/doc/man/man3/crypto_argon2i.3monocypher +++ b/doc/man/man3/crypto_argon2i.3monocypher @@ -80,6 +80,9 @@ It must be at least 1. A value of 3 is recommended. .It Fa password the password to hash. +You will likely want to wipe this using +.Xr crypto_wipe 3monocypher +after hashing it. .It Fa password_size the length of .Fa password . @@ -180,10 +183,12 @@ crypto_argon2i(hash, sizeof(hash), salt, sizeof(salt), NULL, 0, NULL, 0); +crypto_wipe(password, strlen(password)); .Ed .Sh SEE ALSO .Xr crypto_lock 3monocypher , .Xr crypto_verify16 3monocypher , +.Xr crypto_wipe 3monocypher , .Xr intro 3monocypher .Sh CAVEATS Any deviation from the specified input and output length ranges results diff --git a/doc/man/man3/crypto_blake2b.3monocypher b/doc/man/man3/crypto_blake2b.3monocypher index 98dec04..65cc808 100644 --- a/doc/man/man3/crypto_blake2b.3monocypher +++ b/doc/man/man3/crypto_blake2b.3monocypher @@ -116,6 +116,10 @@ If you use the function, you can specify the size of the hash, and use a secret key to make the hash unpredictable \(en useful for message authentication codes. +Even when using a +.Fa key , +you do not have to wipe the context struct with +.Xr crypto_wipe 3monocypher . .Ss Incremental interface Incremental interfaces are useful to handle streams of data or large files without using too much memory. diff --git a/doc/man/man3/crypto_chacha20_encrypt.3monocypher b/doc/man/man3/crypto_chacha20_encrypt.3monocypher index 1a0cdca..cdb315c 100644 --- a/doc/man/man3/crypto_chacha20_encrypt.3monocypher +++ b/doc/man/man3/crypto_chacha20_encrypt.3monocypher @@ -121,6 +121,11 @@ encrypt it again with the same .Fa key and .Fa nonce . +You will likely want to wipe the key and context when you are done with +encryption or decryption. +Use +.Xr crypto_wipe 3monocypher +to wipe them. .Pp .Fn crypto_chacha20_stream is the same as @@ -176,6 +181,12 @@ uint8_t plain_text [500]; /* Will be the decrypted message */ crypto_chacha_ctx ctx; crypto_chacha20_x_init(&ctx, key, nonce); crypto_chacha20_encrypt(&ctx, plain_text, cipher_text, 500); +/* If you're done with encryption, you will want to wipe the key and + * context, possibly the plaintext, too. + */ +crypto_wipe(key, sizeof(key)); +crypto_wipe(&ctx, sizeof(ctx)); +crypto_wipe(plain_text, sizeof(plain_text)); .Ed .Pp Encryption chunk by chunk (same as simple encryption): @@ -189,6 +200,11 @@ crypto_chacha20_x_init(&ctx, key, nonce); for(int i = 0; i < 500; i += 100) { crypto_chacha20_encrypt(&ctx, cipher_text+i, plain_text+i, 100); } +/* If you're done with decryption, you will want to wipe the key and + * context. + */ +crypto_wipe(key, sizeof(key)); +crypto_wipe(&ctx, sizeof(ctx)); .Ed .Pp In place encryption (same results as simple encryption): @@ -199,6 +215,8 @@ uint8_t message [500]; /* Buffer to be encrypted in place */ crypto_chacha_ctx ctx; crypto_chacha20_x_init(&ctx, key, nonce); crypto_chacha20_encrypt(&ctx, message, message, 500); +crypto_wipe(key, sizeof(key)); +crypto_wipe(&ctx, sizeof(ctx)); .Ed .Pp Simple encryption with a small, @@ -211,6 +229,8 @@ const uint8_t plain_text [500]; /* Message to be encrypted */ crypto_chacha_ctx ctx; crypto_chacha20_init(&ctx, key, nonce); crypto_chacha20_encrypt(&ctx, cipher_text, plain_text, 500); +crypto_wipe(key, sizeof(key)); +crypto_wipe(&ctx, sizeof(ctx)); .Ed .Pp Encryption by jumping around (don't do that): @@ -230,9 +250,12 @@ crypto_chacha20_encrypt(&ctx, /* ...then encrypt the first part */ crypto_chacha20_set_ctr(&ctx, 0); crypto_chacha20_encrypt(&ctx, cipher_text, plain_text, 3 * 64); +crypto_wipe(key, sizeof(key)); +crypto_wipe(&ctx, sizeof(ctx)); .Ed .Sh SEE ALSO .Xr crypto_lock 3monocypher , +.Xr crypto_wipe 3monocypher , .Xr intro 3monocypher .Sh STANDARDS These functions implement Chacha20 and XChacha20. diff --git a/doc/man/man3/crypto_key_exchange.3monocypher b/doc/man/man3/crypto_key_exchange.3monocypher index f050ebf..97a3151 100644 --- a/doc/man/man3/crypto_key_exchange.3monocypher +++ b/doc/man/man3/crypto_key_exchange.3monocypher @@ -134,6 +134,11 @@ if (crypto_key_exchange(shared_key, sk, theirpk) != 0) { */ } +/* You will want to wipe the secret key unless you specifically need + * it for another key exchange. + */ +crypto_wipe(sk, sizeof(sk)); + /* shared_key can now be used as key, for example in * crypto_lock/crypto_unlock. */ diff --git a/doc/man/man3/crypto_lock.3monocypher b/doc/man/man3/crypto_lock.3monocypher index 0c931e4..d6136a3 100644 --- a/doc/man/man3/crypto_lock.3monocypher +++ b/doc/man/man3/crypto_lock.3monocypher @@ -257,6 +257,9 @@ uint8_t cipher_text[51]; /* strlen(plain_text) + terminating NUL */ crypto_lock(mac, cipher_text, key, nonce, plain_text, sizeof(plain_text)); +/* Once you're done with encryption, wipe the key from memory */ +crypto_wipe(key, sizeof(key)); + /* You can now transmit over the network: * - cipher_text * - nonce @@ -281,6 +284,8 @@ int ret; ret = crypto_unlock(plain_text, key, nonce, mac, cipher_text, sizeof(cipher_text)); +/* Once you're done with decryption, wipe the key from memory */ +crypto_wipe(key, sizeof(key)); if (ret != 0) { /* Message corrupted; possibly an attacker is interfering * with the connection. @@ -290,6 +295,7 @@ if (ret != 0) { .Sh SEE ALSO .Xr crypto_key_exchange 3monocypher , .Xr crypto_lock_init 3monocypher , +.Xr crypto_wipe 3monocypher , .Xr intro 3monocypher .Sh IMPLEMENTATION DETAILS These functions implement the XChacha20 (encryption) and Poly1305 (MAC) diff --git a/doc/man/man3/crypto_lock_init.3monocypher b/doc/man/man3/crypto_lock_init.3monocypher index d23a194..ad545d3 100644 --- a/doc/man/man3/crypto_lock_init.3monocypher +++ b/doc/man/man3/crypto_lock_init.3monocypher @@ -110,7 +110,7 @@ and .Fn crypto_lock_update authenticates and encrypts the data; .Fn crypto_lock_final -generates the MAC. +generates the MAC and wipes the context. .Sy For decryption , .Fn crypto_unlock_update authenticates and decrypts the data; @@ -169,6 +169,8 @@ Encryption: /* First, initialise the context */ crypto_lock_ctx ctx; crypto_lock_init(&ctx, key, nonce); +/* Wipe the key unless you need it for another operation. */ +crypto_wipe(key, sizeof(key)); /* Second, authenticate the additional data, if any. */ crypto_lock_auth(&ctx, ad1, ad_size1); @@ -194,6 +196,8 @@ To decrypt the above: */ crypto_lock_ctx ctx; crypto_lock_init(&ctx, key, nonce); +/* Wipe the key unless you need it for another operation. */ +crypto_wipe(key, sizeof(key)); /* Second, authenticate the additional data, if any. */ crypto_lock_auth(&ctx, ad1, ad_size1); @@ -220,6 +224,8 @@ To authenticate without decrypting at all: */ crypto_lock_ctx ctx; crypto_lock_init(&ctx, key, nonce); +/* Wipe the key unless you need it for another operation. */ +crypto_wipe(key, sizeof(key)); /* Second, authenticate the additional data, if any. */ crypto_lock_auth(&ctx, ad1, ad_size1); @@ -244,6 +250,7 @@ if (crypto_unlock_final(&ctx, mac2)) { .Xr crypto_key_exchange 3monocypher , .Xr crypto_lock 3monocypher , .Xr crypto_unlock 3monocypher , +.Xr crypto_wipe 3monocypher , .Xr intro 3monocypher .Sh IMPLEMENTATION DETAILS These functions implement the XChacha20 (encryption) and Poly1305 (MAC) diff --git a/doc/man/man3/crypto_sign_init_first_pass.3monocypher b/doc/man/man3/crypto_sign_init_first_pass.3monocypher index 62fcb1a..0d9ce67 100644 --- a/doc/man/man3/crypto_sign_init_first_pass.3monocypher +++ b/doc/man/man3/crypto_sign_init_first_pass.3monocypher @@ -89,6 +89,9 @@ update, where the message is processed; final, where the signature is actually verified. .El .Pp +You do not have to wipe the context structs with +.Xr crypto_wipe 3monocypher . +.Pp Signatures made with this interface are compatible with the direct interface and vice-versa. .Sh RETURN VALUES @@ -118,6 +121,11 @@ crypto_sign_public_key(pk, sk); uint8_t sig[64]; crypto_sign_ctx sctx; crypto_sign_init_first_pass (&sctx, sk, pk); +/* You can wipe the key from memory as early as this. + * Obviously, if you still need to sign more messages, do not wipe + * the secret key yet. + */ +crypto_wipe(sk, sizeof(sk)); crypto_sign_update (&sctx, msg, sizeof(msg)); crypto_sign_init_second_pass(&sctx); crypto_sign_update (&sctx, msg, sizeof(msg)); @@ -134,6 +142,7 @@ int is_valid_sig = (crypto_check_final(&cctx) == 0); .Xr crypto_key_exchange 3monocypher , .Xr crypto_lock 3monocypher , .Xr crypto_sign 3monocypher , +.Xr crypto_wipe 3monocypher , .Xr intro 3monocypher .Sh CAVEATS The same caveats as documented on diff --git a/doc/man/man3/crypto_wipe.3monocypher b/doc/man/man3/crypto_wipe.3monocypher new file mode 100644 index 0000000..f118d0c --- /dev/null +++ b/doc/man/man3/crypto_wipe.3monocypher @@ -0,0 +1,48 @@ +.Dd October 20, 2017 +.Dt CRYPTO_WIPE 3MONOCYPHER +.Os +.Sh NAME +.Nm crypto_wipe +.Nd wipe data from memory +.Sh SYNOPSIS +.In monocypher.h +.Ft int +.Fn crypto_wipe "void *secret" "size_t size" +.Sh DESCRIPTION +Secrets and values derived from them should stay in memory for the +shortest possible amount of time. +.Fn crypto_wipe +allows zeroing out contents that contain secrets. +A secret may be a cryptographic key or a decrypted message. +The arguments are: +.Bl -tag -width Ds +.It Fa secret +the buffer to erase. +.It Fa size +the number of bytes to erase from the buffer. +This will normally be the entire buffer. +.El +.Pp +Monocypher will wipe its context structs when finalizing an operation +such as signing or decrypting. +When using direct interfaces like +.Xr crypto_lock 3monocypher , +these context structs are invisible to you. +They are exposed in incremental interfaces like +.Xr crypto_lock_init 3monocypher . +The original key buffer does not get automatically wiped. +When using incremental interfaces, you may want to wipe the original key +buffer(s) immediately after calling the respective init function. +.Pp +Using +.Fn crypto_wipe +alone may not suffice for security. +It is recommended to lock down relevant memory regions as well. +Refer to +.Xr intro 3monocypher +for instructions on how to lock down memory on common operating systems. +.Sh RETURN VALUES +This function returns nothing. +It cannot fail. +.Sh SEE ALSO +.Xr intro 3monocypher diff --git a/doc/man/man3/intro.3monocypher b/doc/man/man3/intro.3monocypher index 5849b0d..e4d3af4 100644 --- a/doc/man/man3/intro.3monocypher +++ b/doc/man/man3/intro.3monocypher @@ -80,6 +80,10 @@ Note: core dumps cause similar problems. Disable them. Also beware of suspend to disk (deep sleep mode), which writes all RAM to disk regardless of swap policy, as well as virtual machine snapshots. +It is recommended to also use +.Xr crypto_wipe 3monocypher +to clear secrets from memory as soon as possible to mitigate these +dangers. .Ss Index Monocypher provides functions the following: .Bl -ohang -offset indent @@ -157,6 +161,10 @@ Monocypher provides functions the following: .It Xr crypto_verify32 3monocypher .It Xr crypto_verify64 3monocypher .El +.It Utility functions +.Bl -tag -offset indent-two -width Ds +.It Xr crypto_wipe 3monocypher +.El .El .Sh SEE ALSO .Xr crypto_aead_lock 3monocypher , @@ -201,5 +209,6 @@ Monocypher provides functions the following: .Xr crypto_verify16 3monocypher , .Xr crypto_verify32 3monocypher , .Xr crypto_verify64 3monocypher , +.Xr crypto_wipe 3monocypher , .Xr crypto_x25519 3monocypher , .Xr crypto_x25519_public_key 3monocypher -- 2.47.3