]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/checksum.c
Merge pull request #26 from unquietwiki/master
[bcachefs-tools-debian] / libbcachefs / checksum.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include "bcachefs.h"
3 #include "checksum.h"
4 #include "super.h"
5 #include "super-io.h"
6
7 #include <linux/crc32c.h>
8 #include <linux/crypto.h>
9 #include <linux/key.h>
10 #include <linux/random.h>
11 #include <linux/scatterlist.h>
12 #include <crypto/algapi.h>
13 #include <crypto/chacha.h>
14 #include <crypto/hash.h>
15 #include <crypto/poly1305.h>
16 #include <keys/user-type.h>
17
18 static u64 bch2_checksum_init(unsigned type)
19 {
20         switch (type) {
21         case BCH_CSUM_NONE:
22                 return 0;
23         case BCH_CSUM_CRC32C_NONZERO:
24                 return U32_MAX;
25         case BCH_CSUM_CRC64_NONZERO:
26                 return U64_MAX;
27         case BCH_CSUM_CRC32C:
28                 return 0;
29         case BCH_CSUM_CRC64:
30                 return 0;
31         default:
32                 BUG();
33         }
34 }
35
36 static u64 bch2_checksum_final(unsigned type, u64 crc)
37 {
38         switch (type) {
39         case BCH_CSUM_NONE:
40                 return 0;
41         case BCH_CSUM_CRC32C_NONZERO:
42                 return crc ^ U32_MAX;
43         case BCH_CSUM_CRC64_NONZERO:
44                 return crc ^ U64_MAX;
45         case BCH_CSUM_CRC32C:
46                 return crc;
47         case BCH_CSUM_CRC64:
48                 return crc;
49         default:
50                 BUG();
51         }
52 }
53
54 static u64 bch2_checksum_update(unsigned type, u64 crc, const void *data, size_t len)
55 {
56         switch (type) {
57         case BCH_CSUM_NONE:
58                 return 0;
59         case BCH_CSUM_CRC32C_NONZERO:
60         case BCH_CSUM_CRC32C:
61                 return crc32c(crc, data, len);
62         case BCH_CSUM_CRC64_NONZERO:
63         case BCH_CSUM_CRC64:
64                 return crc64_be(crc, data, len);
65         default:
66                 BUG();
67         }
68 }
69
70 static inline void do_encrypt_sg(struct crypto_sync_skcipher *tfm,
71                                  struct nonce nonce,
72                                  struct scatterlist *sg, size_t len)
73 {
74         SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
75         int ret;
76
77         skcipher_request_set_sync_tfm(req, tfm);
78         skcipher_request_set_crypt(req, sg, sg, len, nonce.d);
79
80         ret = crypto_skcipher_encrypt(req);
81         BUG_ON(ret);
82 }
83
84 static inline void do_encrypt(struct crypto_sync_skcipher *tfm,
85                               struct nonce nonce,
86                               void *buf, size_t len)
87 {
88         struct scatterlist sg;
89
90         sg_init_one(&sg, buf, len);
91         do_encrypt_sg(tfm, nonce, &sg, len);
92 }
93
94 int bch2_chacha_encrypt_key(struct bch_key *key, struct nonce nonce,
95                             void *buf, size_t len)
96 {
97         struct crypto_sync_skcipher *chacha20 =
98                 crypto_alloc_sync_skcipher("chacha20", 0, 0);
99         int ret;
100
101         if (!chacha20) {
102                 pr_err("error requesting chacha20 module: %li", PTR_ERR(chacha20));
103                 return PTR_ERR(chacha20);
104         }
105
106         ret = crypto_skcipher_setkey(&chacha20->base,
107                                      (void *) key, sizeof(*key));
108         if (ret) {
109                 pr_err("crypto_skcipher_setkey() error: %i", ret);
110                 goto err;
111         }
112
113         do_encrypt(chacha20, nonce, buf, len);
114 err:
115         crypto_free_sync_skcipher(chacha20);
116         return ret;
117 }
118
119 static void gen_poly_key(struct bch_fs *c, struct shash_desc *desc,
120                          struct nonce nonce)
121 {
122         u8 key[POLY1305_KEY_SIZE];
123
124         nonce.d[3] ^= BCH_NONCE_POLY;
125
126         memset(key, 0, sizeof(key));
127         do_encrypt(c->chacha20, nonce, key, sizeof(key));
128
129         desc->tfm = c->poly1305;
130         crypto_shash_init(desc);
131         crypto_shash_update(desc, key, sizeof(key));
132 }
133
134 struct bch_csum bch2_checksum(struct bch_fs *c, unsigned type,
135                               struct nonce nonce, const void *data, size_t len)
136 {
137         switch (type) {
138         case BCH_CSUM_NONE:
139         case BCH_CSUM_CRC32C_NONZERO:
140         case BCH_CSUM_CRC64_NONZERO:
141         case BCH_CSUM_CRC32C:
142         case BCH_CSUM_CRC64: {
143                 u64 crc = bch2_checksum_init(type);
144
145                 crc = bch2_checksum_update(type, crc, data, len);
146                 crc = bch2_checksum_final(type, crc);
147
148                 return (struct bch_csum) { .lo = cpu_to_le64(crc) };
149         }
150
151         case BCH_CSUM_CHACHA20_POLY1305_80:
152         case BCH_CSUM_CHACHA20_POLY1305_128: {
153                 SHASH_DESC_ON_STACK(desc, c->poly1305);
154                 u8 digest[POLY1305_DIGEST_SIZE];
155                 struct bch_csum ret = { 0 };
156
157                 gen_poly_key(c, desc, nonce);
158
159                 crypto_shash_update(desc, data, len);
160                 crypto_shash_final(desc, digest);
161
162                 memcpy(&ret, digest, bch_crc_bytes[type]);
163                 return ret;
164         }
165         default:
166                 BUG();
167         }
168 }
169
170 void bch2_encrypt(struct bch_fs *c, unsigned type,
171                   struct nonce nonce, void *data, size_t len)
172 {
173         if (!bch2_csum_type_is_encryption(type))
174                 return;
175
176         do_encrypt(c->chacha20, nonce, data, len);
177 }
178
179 static struct bch_csum __bch2_checksum_bio(struct bch_fs *c, unsigned type,
180                                            struct nonce nonce, struct bio *bio,
181                                            struct bvec_iter *iter)
182 {
183         struct bio_vec bv;
184
185         switch (type) {
186         case BCH_CSUM_NONE:
187                 return (struct bch_csum) { 0 };
188         case BCH_CSUM_CRC32C_NONZERO:
189         case BCH_CSUM_CRC64_NONZERO:
190         case BCH_CSUM_CRC32C:
191         case BCH_CSUM_CRC64: {
192                 u64 crc = bch2_checksum_init(type);
193
194 #ifdef CONFIG_HIGHMEM
195                 __bio_for_each_segment(bv, bio, *iter, *iter) {
196                         void *p = kmap_atomic(bv.bv_page) + bv.bv_offset;
197                         crc = bch2_checksum_update(type,
198                                 crc, p, bv.bv_len);
199                         kunmap_atomic(p);
200                 }
201 #else
202                 __bio_for_each_bvec(bv, bio, *iter, *iter)
203                         crc = bch2_checksum_update(type, crc,
204                                 page_address(bv.bv_page) + bv.bv_offset,
205                                 bv.bv_len);
206 #endif
207                 crc = bch2_checksum_final(type, crc);
208                 return (struct bch_csum) { .lo = cpu_to_le64(crc) };
209         }
210
211         case BCH_CSUM_CHACHA20_POLY1305_80:
212         case BCH_CSUM_CHACHA20_POLY1305_128: {
213                 SHASH_DESC_ON_STACK(desc, c->poly1305);
214                 u8 digest[POLY1305_DIGEST_SIZE];
215                 struct bch_csum ret = { 0 };
216
217                 gen_poly_key(c, desc, nonce);
218
219 #ifdef CONFIG_HIGHMEM
220                 __bio_for_each_segment(bv, bio, *iter, *iter) {
221                         void *p = kmap_atomic(bv.bv_page) + bv.bv_offset;
222
223                         crypto_shash_update(desc, p, bv.bv_len);
224                         kunmap_atomic(p);
225                 }
226 #else
227                 __bio_for_each_bvec(bv, bio, *iter, *iter)
228                         crypto_shash_update(desc,
229                                 page_address(bv.bv_page) + bv.bv_offset,
230                                 bv.bv_len);
231 #endif
232                 crypto_shash_final(desc, digest);
233
234                 memcpy(&ret, digest, bch_crc_bytes[type]);
235                 return ret;
236         }
237         default:
238                 BUG();
239         }
240 }
241
242 struct bch_csum bch2_checksum_bio(struct bch_fs *c, unsigned type,
243                                   struct nonce nonce, struct bio *bio)
244 {
245         struct bvec_iter iter = bio->bi_iter;
246
247         return __bch2_checksum_bio(c, type, nonce, bio, &iter);
248 }
249
250 void bch2_encrypt_bio(struct bch_fs *c, unsigned type,
251                       struct nonce nonce, struct bio *bio)
252 {
253         struct bio_vec bv;
254         struct bvec_iter iter;
255         struct scatterlist sgl[16], *sg = sgl;
256         size_t bytes = 0;
257
258         if (!bch2_csum_type_is_encryption(type))
259                 return;
260
261         sg_init_table(sgl, ARRAY_SIZE(sgl));
262
263         bio_for_each_segment(bv, bio, iter) {
264                 if (sg == sgl + ARRAY_SIZE(sgl)) {
265                         sg_mark_end(sg - 1);
266                         do_encrypt_sg(c->chacha20, nonce, sgl, bytes);
267
268                         nonce = nonce_add(nonce, bytes);
269                         bytes = 0;
270
271                         sg_init_table(sgl, ARRAY_SIZE(sgl));
272                         sg = sgl;
273                 }
274
275                 sg_set_page(sg++, bv.bv_page, bv.bv_len, bv.bv_offset);
276                 bytes += bv.bv_len;
277         }
278
279         sg_mark_end(sg - 1);
280         do_encrypt_sg(c->chacha20, nonce, sgl, bytes);
281 }
282
283 struct bch_csum bch2_checksum_merge(unsigned type, struct bch_csum a,
284                                     struct bch_csum b, size_t b_len)
285 {
286         BUG_ON(!bch2_checksum_mergeable(type));
287
288         while (b_len) {
289                 unsigned b = min_t(unsigned, b_len, PAGE_SIZE);
290
291                 a.lo = bch2_checksum_update(type, a.lo,
292                                 page_address(ZERO_PAGE(0)), b);
293                 b_len -= b;
294         }
295
296         a.lo ^= b.lo;
297         a.hi ^= b.hi;
298         return a;
299 }
300
301 int bch2_rechecksum_bio(struct bch_fs *c, struct bio *bio,
302                         struct bversion version,
303                         struct bch_extent_crc_unpacked crc_old,
304                         struct bch_extent_crc_unpacked *crc_a,
305                         struct bch_extent_crc_unpacked *crc_b,
306                         unsigned len_a, unsigned len_b,
307                         unsigned new_csum_type)
308 {
309         struct bvec_iter iter = bio->bi_iter;
310         struct nonce nonce = extent_nonce(version, crc_old);
311         struct bch_csum merged = { 0 };
312         struct crc_split {
313                 struct bch_extent_crc_unpacked  *crc;
314                 unsigned                        len;
315                 unsigned                        csum_type;
316                 struct bch_csum                 csum;
317         } splits[3] = {
318                 { crc_a, len_a, new_csum_type },
319                 { crc_b, len_b, new_csum_type },
320                 { NULL,  bio_sectors(bio) - len_a - len_b, new_csum_type },
321         }, *i;
322         bool mergeable = crc_old.csum_type == new_csum_type &&
323                 bch2_checksum_mergeable(new_csum_type);
324         unsigned crc_nonce = crc_old.nonce;
325
326         BUG_ON(len_a + len_b > bio_sectors(bio));
327         BUG_ON(crc_old.uncompressed_size != bio_sectors(bio));
328         BUG_ON(crc_is_compressed(crc_old));
329         BUG_ON(bch2_csum_type_is_encryption(crc_old.csum_type) !=
330                bch2_csum_type_is_encryption(new_csum_type));
331
332         for (i = splits; i < splits + ARRAY_SIZE(splits); i++) {
333                 iter.bi_size = i->len << 9;
334                 if (mergeable || i->crc)
335                         i->csum = __bch2_checksum_bio(c, i->csum_type,
336                                                       nonce, bio, &iter);
337                 else
338                         bio_advance_iter(bio, &iter, i->len << 9);
339                 nonce = nonce_add(nonce, i->len << 9);
340         }
341
342         if (mergeable)
343                 for (i = splits; i < splits + ARRAY_SIZE(splits); i++)
344                         merged = bch2_checksum_merge(new_csum_type, merged,
345                                                      i->csum, i->len << 9);
346         else
347                 merged = bch2_checksum_bio(c, crc_old.csum_type,
348                                 extent_nonce(version, crc_old), bio);
349
350         if (bch2_crc_cmp(merged, crc_old.csum))
351                 return -EIO;
352
353         for (i = splits; i < splits + ARRAY_SIZE(splits); i++) {
354                 if (i->crc)
355                         *i->crc = (struct bch_extent_crc_unpacked) {
356                                 .csum_type              = i->csum_type,
357                                 .compression_type       = crc_old.compression_type,
358                                 .compressed_size        = i->len,
359                                 .uncompressed_size      = i->len,
360                                 .offset                 = 0,
361                                 .live_size              = i->len,
362                                 .nonce                  = crc_nonce,
363                                 .csum                   = i->csum,
364                         };
365
366                 if (bch2_csum_type_is_encryption(new_csum_type))
367                         crc_nonce += i->len;
368         }
369
370         return 0;
371 }
372
373 #ifdef __KERNEL__
374 int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
375 {
376         char key_description[60];
377         struct key *keyring_key;
378         const struct user_key_payload *ukp;
379         int ret;
380
381         snprintf(key_description, sizeof(key_description),
382                  "bcachefs:%pUb", &sb->user_uuid);
383
384         keyring_key = request_key(&key_type_logon, key_description, NULL);
385         if (IS_ERR(keyring_key))
386                 return PTR_ERR(keyring_key);
387
388         down_read(&keyring_key->sem);
389         ukp = dereference_key_locked(keyring_key);
390         if (ukp->datalen == sizeof(*key)) {
391                 memcpy(key, ukp->data, ukp->datalen);
392                 ret = 0;
393         } else {
394                 ret = -EINVAL;
395         }
396         up_read(&keyring_key->sem);
397         key_put(keyring_key);
398
399         return ret;
400 }
401 #else
402 #include <keyutils.h>
403 #include <uuid/uuid.h>
404
405 int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
406 {
407         key_serial_t key_id;
408         char key_description[60];
409         char uuid[40];
410
411         uuid_unparse_lower(sb->user_uuid.b, uuid);
412         sprintf(key_description, "bcachefs:%s", uuid);
413
414         key_id = request_key("user", key_description, NULL,
415                              KEY_SPEC_USER_KEYRING);
416         if (key_id < 0)
417                 return -errno;
418
419         if (keyctl_read(key_id, (void *) key, sizeof(*key)) != sizeof(*key))
420                 return -1;
421
422         return 0;
423 }
424 #endif
425
426 int bch2_decrypt_sb_key(struct bch_fs *c,
427                         struct bch_sb_field_crypt *crypt,
428                         struct bch_key *key)
429 {
430         struct bch_encrypted_key sb_key = crypt->key;
431         struct bch_key user_key;
432         int ret = 0;
433
434         /* is key encrypted? */
435         if (!bch2_key_is_encrypted(&sb_key))
436                 goto out;
437
438         ret = bch2_request_key(c->disk_sb.sb, &user_key);
439         if (ret) {
440                 bch_err(c, "error requesting encryption key: %i", ret);
441                 goto err;
442         }
443
444         /* decrypt real key: */
445         ret = bch2_chacha_encrypt_key(&user_key, bch2_sb_key_nonce(c),
446                              &sb_key, sizeof(sb_key));
447         if (ret)
448                 goto err;
449
450         if (bch2_key_is_encrypted(&sb_key)) {
451                 bch_err(c, "incorrect encryption key");
452                 ret = -EINVAL;
453                 goto err;
454         }
455 out:
456         *key = sb_key.key;
457 err:
458         memzero_explicit(&sb_key, sizeof(sb_key));
459         memzero_explicit(&user_key, sizeof(user_key));
460         return ret;
461 }
462
463 static int bch2_alloc_ciphers(struct bch_fs *c)
464 {
465         if (!c->chacha20)
466                 c->chacha20 = crypto_alloc_sync_skcipher("chacha20", 0, 0);
467         if (IS_ERR(c->chacha20)) {
468                 bch_err(c, "error requesting chacha20 module: %li",
469                         PTR_ERR(c->chacha20));
470                 return PTR_ERR(c->chacha20);
471         }
472
473         if (!c->poly1305)
474                 c->poly1305 = crypto_alloc_shash("poly1305", 0, 0);
475         if (IS_ERR(c->poly1305)) {
476                 bch_err(c, "error requesting poly1305 module: %li",
477                         PTR_ERR(c->poly1305));
478                 return PTR_ERR(c->poly1305);
479         }
480
481         return 0;
482 }
483
484 int bch2_disable_encryption(struct bch_fs *c)
485 {
486         struct bch_sb_field_crypt *crypt;
487         struct bch_key key;
488         int ret = -EINVAL;
489
490         mutex_lock(&c->sb_lock);
491
492         crypt = bch2_sb_get_crypt(c->disk_sb.sb);
493         if (!crypt)
494                 goto out;
495
496         /* is key encrypted? */
497         ret = 0;
498         if (bch2_key_is_encrypted(&crypt->key))
499                 goto out;
500
501         ret = bch2_decrypt_sb_key(c, crypt, &key);
502         if (ret)
503                 goto out;
504
505         crypt->key.magic        = BCH_KEY_MAGIC;
506         crypt->key.key          = key;
507
508         SET_BCH_SB_ENCRYPTION_TYPE(c->disk_sb.sb, 0);
509         bch2_write_super(c);
510 out:
511         mutex_unlock(&c->sb_lock);
512
513         return ret;
514 }
515
516 int bch2_enable_encryption(struct bch_fs *c, bool keyed)
517 {
518         struct bch_encrypted_key key;
519         struct bch_key user_key;
520         struct bch_sb_field_crypt *crypt;
521         int ret = -EINVAL;
522
523         mutex_lock(&c->sb_lock);
524
525         /* Do we already have an encryption key? */
526         if (bch2_sb_get_crypt(c->disk_sb.sb))
527                 goto err;
528
529         ret = bch2_alloc_ciphers(c);
530         if (ret)
531                 goto err;
532
533         key.magic = BCH_KEY_MAGIC;
534         get_random_bytes(&key.key, sizeof(key.key));
535
536         if (keyed) {
537                 ret = bch2_request_key(c->disk_sb.sb, &user_key);
538                 if (ret) {
539                         bch_err(c, "error requesting encryption key: %i", ret);
540                         goto err;
541                 }
542
543                 ret = bch2_chacha_encrypt_key(&user_key, bch2_sb_key_nonce(c),
544                                               &key, sizeof(key));
545                 if (ret)
546                         goto err;
547         }
548
549         ret = crypto_skcipher_setkey(&c->chacha20->base,
550                         (void *) &key.key, sizeof(key.key));
551         if (ret)
552                 goto err;
553
554         crypt = bch2_sb_resize_crypt(&c->disk_sb, sizeof(*crypt) / sizeof(u64));
555         if (!crypt) {
556                 ret = -ENOMEM; /* XXX this technically could be -ENOSPC */
557                 goto err;
558         }
559
560         crypt->key = key;
561
562         /* write superblock */
563         SET_BCH_SB_ENCRYPTION_TYPE(c->disk_sb.sb, 1);
564         bch2_write_super(c);
565 err:
566         mutex_unlock(&c->sb_lock);
567         memzero_explicit(&user_key, sizeof(user_key));
568         memzero_explicit(&key, sizeof(key));
569         return ret;
570 }
571
572 void bch2_fs_encryption_exit(struct bch_fs *c)
573 {
574         if (!IS_ERR_OR_NULL(c->poly1305))
575                 crypto_free_shash(c->poly1305);
576         if (!IS_ERR_OR_NULL(c->chacha20))
577                 crypto_free_sync_skcipher(c->chacha20);
578         if (!IS_ERR_OR_NULL(c->sha256))
579                 crypto_free_shash(c->sha256);
580 }
581
582 int bch2_fs_encryption_init(struct bch_fs *c)
583 {
584         struct bch_sb_field_crypt *crypt;
585         struct bch_key key;
586         int ret = 0;
587
588         pr_verbose_init(c->opts, "");
589
590         c->sha256 = crypto_alloc_shash("sha256", 0, 0);
591         if (IS_ERR(c->sha256)) {
592                 bch_err(c, "error requesting sha256 module");
593                 ret = PTR_ERR(c->sha256);
594                 goto out;
595         }
596
597         crypt = bch2_sb_get_crypt(c->disk_sb.sb);
598         if (!crypt)
599                 goto out;
600
601         ret = bch2_alloc_ciphers(c);
602         if (ret)
603                 goto out;
604
605         ret = bch2_decrypt_sb_key(c, crypt, &key);
606         if (ret)
607                 goto out;
608
609         ret = crypto_skcipher_setkey(&c->chacha20->base,
610                         (void *) &key.key, sizeof(key.key));
611         if (ret)
612                 goto out;
613 out:
614         memzero_explicit(&key, sizeof(key));
615         pr_verbose_init(c->opts, "ret %i", ret);
616         return ret;
617 }