lnsocket

A minimal C library for connecting to the lightning network
git clone git://jb55.com/lnsocket
Log | Files | Refs | Submodules | README | LICENSE

crypto.c (7060B)


      1 /* Copyright Rusty Russell (Blockstream) 2015.
      2 	     William Casarin 2022
      3 
      4 Permission is hereby granted, free of charge, to any person obtaining a copy
      5 of this software and associated documentation files (the "Software"), to deal
      6 in the Software without restriction, including without limitation the rights
      7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 copies of the Software, and to permit persons to whom the Software is
      9 furnished to do so, subject to the following conditions:
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 THE SOFTWARE.
     21 */
     22 
     23 
     24 #include "config.h"
     25 #include "crypto.h"
     26 #include "endian.h"
     27 #include "typedefs.h"
     28 #include "compiler.h"
     29 #include "hkdf.h"
     30 
     31 #include <assert.h>
     32 #include <sodium/crypto_aead_chacha20poly1305.h>
     33 
     34 void le64_nonce(unsigned char *npub, u64 nonce)
     35 {
     36 	/* BOLT #8:
     37 	 *
     38 	 * ...with nonce `n` encoded as 32 zero bits, followed by a
     39 	 * *little-endian* 64-bit value.  Note: this follows the Noise Protocol
     40 	 * convention, rather than our normal endian
     41 	 */
     42 	le64 le_nonce = cpu_to_le64(nonce);
     43 	const size_t zerolen = crypto_aead_chacha20poly1305_ietf_NPUBBYTES - sizeof(le_nonce);
     44 
     45 	BUILD_ASSERT(crypto_aead_chacha20poly1305_ietf_NPUBBYTES >= sizeof(le_nonce));
     46 	/* First part is 0, followed by nonce. */
     47 	memset(npub, 0, zerolen);
     48 	memcpy(npub + zerolen, &le_nonce, sizeof(le_nonce));
     49 }
     50 
     51 /* out1, out2 = HKDF(in1, in2)` */
     52 void hkdf_two_keys(struct secret *out1, struct secret *out2,
     53 			  const struct secret *in1,
     54 			  const struct secret *in2)
     55 {
     56 	/* BOLT #8:
     57 	 *
     58 	 *   * `HKDF(salt,ikm)`: a function defined in `RFC 5869`<sup>[3](#reference-3)</sup>,
     59 	 *      evaluated with a zero-length `info` field
     60 	 *      * All invocations of `HKDF` implicitly return 64 bytes
     61 	 *        of cryptographic randomness using the extract-and-expand
     62 	 *        component of the `HKDF`.
     63 	 */
     64 	struct secret okm[2];
     65 	size_t in2_size = in2 == NULL ? 0 : sizeof(*in2);
     66 
     67 	hkdf_sha256(okm, sizeof(okm), in1, sizeof(*in1), in2, in2_size,
     68 		    NULL, 0);
     69 	*out1 = okm[0];
     70 	*out2 = okm[1];
     71 }
     72 
     73 
     74 static void maybe_rotate_key(u64 *n, struct secret *k, struct secret *ck)
     75 {
     76 	struct secret new_k, new_ck;
     77 
     78 	/* BOLT #8:
     79 	 *
     80 	 * A key is to be rotated after a party encrypts or decrypts 1000 times
     81 	 * with it (i.e. every 500 messages). This can be properly accounted
     82 	 * for by rotating the key once the nonce dedicated to it
     83 	 * exceeds 1000.
     84 	 */
     85 	if (*n != 1000)
     86 		return;
     87 
     88 	/* BOLT #8:
     89 	 *
     90 	 * Key rotation for a key `k` is performed according to the following
     91 	 * steps:
     92 	 *
     93 	 * 1. Let `ck` be the chaining key obtained at the end of Act Three.
     94 	 * 2. `ck', k' = HKDF(ck, k)`
     95 	 * 3. Reset the nonce for the key to `n = 0`.
     96 	 * 4. `k = k'`
     97 	 * 5. `ck = ck'`
     98 	 */
     99 	hkdf_two_keys(&new_ck, &new_k, ck, k);
    100 
    101 	*ck = new_ck;
    102 	*k = new_k;
    103 	*n = 0;
    104 }
    105 
    106 int cryptomsg_decrypt_body(struct crypto_state *cs, const u8 *in, size_t inlen, u8 *out, size_t outcap)
    107 {
    108 	unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
    109 	unsigned long long mlen;
    110 
    111 	if (inlen < 16 || outcap < cryptomsg_decrypt_size(inlen))
    112 		return 0;
    113 
    114 	le64_nonce(npub, cs->rn++);
    115 
    116 	/* BOLT #8:
    117 	 *
    118 	 * 5. Decrypt `c` (using `ChaCha20-Poly1305`, `rn`, and `rk`), to
    119 	 *    obtain decrypted plaintext packet `p`.
    120 	 *    * The nonce `rn` MUST be incremented after this step.
    121 	 */
    122 	if (crypto_aead_chacha20poly1305_ietf_decrypt(out,
    123 						      &mlen, NULL,
    124 						      memcheck(in, inlen),
    125 						      inlen,
    126 						      NULL, 0,
    127 						      npub, cs->rk.data) != 0) {
    128 		/* FIXME: Report error! */
    129 		return 0;
    130 	}
    131 
    132 	assert(mlen == cryptomsg_decrypt_size(inlen));
    133 
    134 	maybe_rotate_key(&cs->rn, &cs->rk, &cs->r_ck);
    135 
    136 	return 1;
    137 }
    138 
    139 int cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp)
    140 {
    141 	unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
    142 	unsigned long long mlen;
    143 	be16 len;
    144 
    145 	le64_nonce(npub, cs->rn++);
    146 
    147 	/* BOLT #8:
    148 	 *
    149 	 *  2. Let the encrypted length prefix be known as `lc`.
    150 	 *  3. Decrypt `lc` (using `ChaCha20-Poly1305`, `rn`, and `rk`), to
    151 	 *     obtain the size of the encrypted packet `l`.
    152 	 *    * A zero-length byte slice is to be passed as the AD
    153 	 *	(associated data).
    154 	 *    * The nonce `rn` MUST be incremented after this step.
    155 	 */
    156 	if (crypto_aead_chacha20poly1305_ietf_decrypt((unsigned char *)&len,
    157 						      &mlen, NULL,
    158 						      memcheck(hdr, 18), 18,
    159 						      NULL, 0,
    160 						      npub, cs->rk.data) != 0) {
    161 		return 0;
    162 	}
    163 	assert(mlen == sizeof(len));
    164 	*lenp = be16_to_cpu(len);
    165 	return 1;
    166 }
    167 
    168 u8 *cryptomsg_encrypt_msg(struct crypto_state *cs, const u8 *msg, unsigned long long mlen, u8 *out, size_t *outlen, size_t outcap)
    169 {
    170 	unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
    171 	unsigned long long clen;
    172 	be16 l;
    173 	int ret;
    174 
    175 	*outlen = sizeof(l) + 16 + mlen + 16; 
    176 
    177 	if (outcap < mlen) {
    178 		*outlen = 0;
    179 		return NULL;
    180 	}
    181 
    182 	/* BOLT #8:
    183 	 *
    184 	 * In order to encrypt and send a Lightning message (`m`) to the
    185 	 * network stream, given a sending key (`sk`) and a nonce (`sn`), the
    186 	 * following steps are completed:
    187 	 *
    188 	 *   1. Let `l = len(m)`.
    189 	 *      * where `len` obtains the length in bytes of the Lightning
    190 	 *        message
    191 	 *
    192 	 *   2. Serialize `l` into 2 bytes encoded as a big-endian integer.
    193 	 */
    194 	l = cpu_to_be16(mlen);
    195 
    196 	/* BOLT #8:
    197 	 *
    198 	 * 3. Encrypt `l` (using `ChaChaPoly-1305`, `sn`, and `sk`), to obtain
    199 	 *    `lc` (18 bytes)
    200 	 *    * The nonce `sn` is encoded as a 96-bit little-endian number. As
    201 	 *      the decoded nonce is 64 bits, the 96-bit nonce is encoded as:
    202 	 *      32 bits of leading 0s followed by a 64-bit value.
    203 	 *        * The nonce `sn` MUST be incremented after this step.
    204 	 *    * A zero-length byte slice is to be passed as the AD (associated
    205                 data).
    206 	 */
    207 	le64_nonce(npub, cs->sn++);
    208 	ret = crypto_aead_chacha20poly1305_ietf_encrypt(out, &clen,
    209 							(unsigned char *)
    210 							memcheck(&l, sizeof(l)),
    211 							sizeof(l),
    212 							NULL, 0,
    213 							NULL, npub,
    214 							cs->sk.data);
    215 	assert(ret == 0);
    216 	assert(clen == sizeof(l) + 16);
    217 
    218 	/* BOLT #8:
    219 	 *
    220 	 *   4. Finally, encrypt the message itself (`m`) using the same
    221 	 *      procedure used to encrypt the length prefix. Let
    222 	 *      encrypted ciphertext be known as `c`.
    223 	 *
    224 	 *     * The nonce `sn` MUST be incremented after this step.
    225 	 */
    226 	le64_nonce(npub, cs->sn++);
    227 	ret = crypto_aead_chacha20poly1305_ietf_encrypt(out + clen, &clen,
    228 							memcheck(msg, mlen),
    229 							mlen,
    230 							NULL, 0,
    231 							NULL, npub,
    232 							cs->sk.data);
    233 	assert(ret == 0);
    234 	assert(clen == mlen + 16);
    235 
    236 	maybe_rotate_key(&cs->sn, &cs->sk, &cs->s_ck);
    237 
    238 	return out;
    239 }