1CRYPTO_LOCK(3MONOCYPHER) LOCAL CRYPTO_LOCK(3MONOCYPHER)
2
4 crypto_lock_aead, crypto_unlock_aead, crypto_lock, crypto_unlock — au‐
5 thenticated encryption with additional data
6
8 #include <monocypher.h>
9
10 void
11 crypto_lock(uint8_t mac[16], uint8_t *cipher_text, const uint8_t key[32],
12 const uint8_t nonce[24], const uint8_t *plain_text,
13 size_t text_size);
14
15 int
16 crypto_unlock(uint8_t *plain_text, const uint8_t key[32],
17 const uint8_t nonce[24], const uint8_t mac[16],
18 const uint8_t *cipher_text, size_t text_size);
19
20 void
21 crypto_lock_aead(uint8_t mac[16], uint8_t *cipher_text,
22 const uint8_t key[32], const uint8_t nonce[24], const uint8_t *ad,
23 size_t ad_size, const uint8_t *plain_text, size_t text_size);
24
25 int
26 crypto_unlock_aead(uint8_t *plain_text, const uint8_t key[32],
27 const uint8_t nonce[24], const uint8_t mac[16], const uint8_t *ad,
28 size_t ad_size, const uint8_t *cipher_text, size_t text_size);
29
31 crypto_lock() encrypts and authenticates a plaintext. It can be de‐
32 crypted by crypto_unlock(). The arguments are:
33
34 key A 32-byte session key, shared between the sender and the recipi‐
35 ent. It must be secret and random. Different methods can be
36 used to produce and exchange this key, such as Diffie-Hellman key
37 exchange, password key derivation (the password must be communi‐
38 cated on a secure channel), or even meeting physically. See
39 crypto_key_exchange(3monocypher) for key exchange, and
40 crypto_argon2i(3monocypher) for password key derivation.
41
42 nonce A 24-byte number, used only once with any given session key. It
43 does not need to be secret or random, but it does have to be
44 unique. Never use the same nonce twice with the same key. This
45 would reveal the XOR of 2 different messages, which allows de‐
46 cryption and forgeries. The easiest (and recommended) way to
47 generate this nonce is to select it at random. See
48 intro(3monocypher) about random number generation (use your oper‐
49 ating system's random number generator).
50
51 mac A 16-byte message authentication code (MAC), that can only be
52 produced by someone who knows the session key. This guarantee
53 cannot be upheld if a nonce has been reused with the session key,
54 because doing so allows the attacker to learn the authentication
55 key associated with that nonce. The MAC is intended to be sent
56 along with the ciphertext.
57
58 plain_text
59 The secret message. Its contents will be kept hidden from at‐
60 tackers. Its length however, will not. Be careful when combin‐
61 ing encryption with compression. See intro(3monocypher) for de‐
62 tails.
63
64 cipher_text
65 The encrypted message.
66
67 text_size
68 Length of both plain_text and cipher_text, in bytes.
69
70 The cipher_text and plain_text arguments may point to the same buffer for
71 in-place encryption. Otherwise, the buffers they point to must not over‐
72 lap.
73
74 crypto_unlock() first checks the integrity of an encrypted message. If
75 it has been corrupted, crypto_unlock() returns -1 immediately. Other‐
76 wise, it decrypts the message, then returns zero. Always check the
77 return value.
78
79 crypto_lock_aead() and crypto_unlock_aead() are variants of crypto_lock()
80 and crypto_unlock(), permitting additional data. Additional data is au‐
81 thenticated, but not encrypted. This is used to authenticate relevant
82 data that cannot be encrypted. The arguments are:
83
84 ad Additional data to authenticate. It will not be encrypted. May
85 be NULL if ad_size is zero. Setting ad_size to zero yields the
86 same results as crypto_lock() and crypto_unlock().
87
88 ad_size
89 Length of the additional data, in bytes.
90
92 crypto_lock() and crypto_lock_aead() return nothing. crypto_unlock() and
93 crypto_unlock_aead() return 0 on success or -1 if the message was cor‐
94 rupted (i.e. mac mismatched the combination of key, nonce, ad and
95 cipher_text). Corruption can be caused by transmission errors, program‐
96 mer error, or an attacker's interference. plain_text does not need to be
97 wiped if the decryption fails.
98
100 The following examples assume the existence of arc4random_buf(), which
101 fills the given buffer with cryptographically secure random bytes. If
102 arc4random_buf() does not exist on your system, see intro(3monocypher)
103 for advice about how to generate cryptographically secure random bytes.
104
105 Encryption:
106
107 uint8_t key [32]; /* Random, secret session key */
108 uint8_t nonce [24]; /* Use only once per key */
109 uint8_t plain_text [12] = "Lorem ipsum"; /* Secret message */
110 uint8_t mac [16]; /* Message authentication code */
111 uint8_t cipher_text[12]; /* Encrypted message */
112 arc4random_buf(key, 32);
113 arc4random_buf(nonce, 24);
114 crypto_lock(mac, cipher_text, key, nonce, plain_text,
115 sizeof(plain_text));
116 /* Wipe secrets if they are no longer needed */
117 crypto_wipe(plain_text, 12);
118 crypto_wipe(key, 32);
119 /* Transmit cipher_text, nonce, and mac over the network,
120 * store them in a file, etc.
121 */
122
123 To decrypt the above:
124
125 uint8_t key [32]; /* Same as the above */
126 uint8_t nonce [24]; /* Same as the above */
127 const uint8_t cipher_text[12]; /* Encrypted message */
128 const uint8_t mac [16]; /* Received along with text */
129 uint8_t plain_text [12]; /* Secret message */
130 if (crypto_unlock(plain_text, key, nonce, mac, cipher_text, 12)) {
131 /* The message is corrupted.
132 * Wipe key if it is no longer needed,
133 * and abort the decryption.
134 */
135 crypto_wipe(key, 32);
136 } else {
137 /* ...do something with the decrypted text here... */
138 /* Finally, wipe secrets if they are no longer needed */
139 crypto_wipe(plain_text, 12);
140 crypto_wipe(key, 32);
141 }
142
143 In-place encryption:
144
145 uint8_t key [32]; /* Random, secret session key */
146 uint8_t nonce[24]; /* Use only once per key */
147 uint8_t text [12] = "Lorem ipsum"; /* Secret message */
148 uint8_t mac [16]; /* Message authentication code */
149 arc4random_buf(key, 32);
150 arc4random_buf(nonce, 24);
151 crypto_lock(mac, text, key, nonce, text, 12);
152 /* Wipe secrets if they are no longer needed */
153 crypto_wipe(key, 32);
154 /* Transmit cipher_text, nonce, and mac over the network,
155 * store them in a file, etc.
156 */
157
158 In-place decryption:
159
160 uint8_t key [32]; /* Same as the above */
161 const uint8_t nonce[24]; /* Same as the above */
162 const uint8_t mac [16]; /* Received from along with text */
163 uint8_t text [12]; /* Message to decrypt */
164 if (crypto_unlock(text, key, nonce, mac, text, 12)) {
165 /* The message is corrupted.
166 * Wipe key if it is no longer needed,
167 * and abort the decryption.
168 */
169 crypto_wipe(key, 32);
170 } else {
171 /* ...do something with the decrypted text here... */
172 /* Finally, wipe secrets if they are no longer needed */
173 crypto_wipe(text, 12);
174 crypto_wipe(key, 32);
175 }
176
178 crypto_key_exchange(3monocypher), crypto_wipe(3monocypher),
179 intro(3monocypher)
180
182 These functions implement RFC 8439, with XChacha20 instead of Chacha20.
183 XChacha20 derives from Chacha20 the same way XSalsa20 derives from
184 Salsa20, and benefits from the same security reduction (proven secure as
185 long as Chacha20 itself is secure).
186
188 The crypto_lock() and crypto_unlock() functions first appeared in Mono‐
189 cypher 0.1. crypto_lock_aead() and crypto_unlock_aead() were introduced
190 in Monocypher 1.1.0. In Monocypher 2.0.0, the underlying algorithms for
191 these functions were changed from a custom XChacha20/Poly1305 construc‐
192 tion to an implementation of RFC 7539 (now RFC 8439) with XChacha20 in‐
193 stead of Chacha20. The crypto_lock_encrypt() and crypto_lock_auth()
194 functions were removed in Monocypher 2.0.0.
195
196BSD February 29, 2020 BSD