]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/checksum.c
Update bcachefs sources to 5a3a4087af bcachefs: Convert a BUG_ON() to a warning
[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_old.compression_type);
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                                 .compressed_size        = i->len,
358                                 .uncompressed_size      = i->len,
359                                 .offset                 = 0,
360                                 .live_size              = i->len,
361                                 .nonce                  = crc_nonce,
362                                 .csum                   = i->csum,
363                         };
364
365                 if (bch2_csum_type_is_encryption(new_csum_type))
366                         crc_nonce += i->len;
367         }
368
369         return 0;
370 }
371
372 #ifdef __KERNEL__
373 int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
374 {
375         char key_description[60];
376         struct key *keyring_key;
377         const struct user_key_payload *ukp;
378         int ret;
379
380         snprintf(key_description, sizeof(key_description),
381                  "bcachefs:%pUb", &sb->user_uuid);
382
383         keyring_key = request_key(&key_type_logon, key_description, NULL);
384         if (IS_ERR(keyring_key))
385                 return PTR_ERR(keyring_key);
386
387         down_read(&keyring_key->sem);
388         ukp = dereference_key_locked(keyring_key);
389         if (ukp->datalen == sizeof(*key)) {
390                 memcpy(key, ukp->data, ukp->datalen);
391                 ret = 0;
392         } else {
393                 ret = -EINVAL;
394         }
395         up_read(&keyring_key->sem);
396         key_put(keyring_key);
397
398         return ret;
399 }
400 #else
401 #include <keyutils.h>
402 #include <uuid/uuid.h>
403
404 int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
405 {
406         key_serial_t key_id;
407         char key_description[60];
408         char uuid[40];
409
410         uuid_unparse_lower(sb->user_uuid.b, uuid);
411         sprintf(key_description, "bcachefs:%s", uuid);
412
413         key_id = request_key("user", key_description, NULL,
414                              KEY_SPEC_USER_KEYRING);
415         if (key_id < 0)
416                 return -errno;
417
418         if (keyctl_read(key_id, (void *) key, sizeof(*key)) != sizeof(*key))
419                 return -1;
420
421         return 0;
422 }
423 #endif
424
425 int bch2_decrypt_sb_key(struct bch_fs *c,
426                         struct bch_sb_field_crypt *crypt,
427                         struct bch_key *key)
428 {
429         struct bch_encrypted_key sb_key = crypt->key;
430         struct bch_key user_key;
431         int ret = 0;
432
433         /* is key encrypted? */
434         if (!bch2_key_is_encrypted(&sb_key))
435                 goto out;
436
437         ret = bch2_request_key(c->disk_sb.sb, &user_key);
438         if (ret) {
439                 bch_err(c, "error requesting encryption key: %i", ret);
440                 goto err;
441         }
442
443         /* decrypt real key: */
444         ret = bch2_chacha_encrypt_key(&user_key, bch2_sb_key_nonce(c),
445                              &sb_key, sizeof(sb_key));
446         if (ret)
447                 goto err;
448
449         if (bch2_key_is_encrypted(&sb_key)) {
450                 bch_err(c, "incorrect encryption key");
451                 ret = -EINVAL;
452                 goto err;
453         }
454 out:
455         *key = sb_key.key;
456 err:
457         memzero_explicit(&sb_key, sizeof(sb_key));
458         memzero_explicit(&user_key, sizeof(user_key));
459         return ret;
460 }
461
462 static int bch2_alloc_ciphers(struct bch_fs *c)
463 {
464         if (!c->chacha20)
465                 c->chacha20 = crypto_alloc_sync_skcipher("chacha20", 0, 0);
466         if (IS_ERR(c->chacha20)) {
467                 bch_err(c, "error requesting chacha20 module: %li",
468                         PTR_ERR(c->chacha20));
469                 return PTR_ERR(c->chacha20);
470         }
471
472         if (!c->poly1305)
473                 c->poly1305 = crypto_alloc_shash("poly1305", 0, 0);
474         if (IS_ERR(c->poly1305)) {
475                 bch_err(c, "error requesting poly1305 module: %li",
476                         PTR_ERR(c->poly1305));
477                 return PTR_ERR(c->poly1305);
478         }
479
480         return 0;
481 }
482
483 int bch2_disable_encryption(struct bch_fs *c)
484 {
485         struct bch_sb_field_crypt *crypt;
486         struct bch_key key;
487         int ret = -EINVAL;
488
489         mutex_lock(&c->sb_lock);
490
491         crypt = bch2_sb_get_crypt(c->disk_sb.sb);
492         if (!crypt)
493                 goto out;
494
495         /* is key encrypted? */
496         ret = 0;
497         if (bch2_key_is_encrypted(&crypt->key))
498                 goto out;
499
500         ret = bch2_decrypt_sb_key(c, crypt, &key);
501         if (ret)
502                 goto out;
503
504         crypt->key.magic        = BCH_KEY_MAGIC;
505         crypt->key.key          = key;
506
507         SET_BCH_SB_ENCRYPTION_TYPE(c->disk_sb.sb, 0);
508         bch2_write_super(c);
509 out:
510         mutex_unlock(&c->sb_lock);
511
512         return ret;
513 }
514
515 int bch2_enable_encryption(struct bch_fs *c, bool keyed)
516 {
517         struct bch_encrypted_key key;
518         struct bch_key user_key;
519         struct bch_sb_field_crypt *crypt;
520         int ret = -EINVAL;
521
522         mutex_lock(&c->sb_lock);
523
524         /* Do we already have an encryption key? */
525         if (bch2_sb_get_crypt(c->disk_sb.sb))
526                 goto err;
527
528         ret = bch2_alloc_ciphers(c);
529         if (ret)
530                 goto err;
531
532         key.magic = BCH_KEY_MAGIC;
533         get_random_bytes(&key.key, sizeof(key.key));
534
535         if (keyed) {
536                 ret = bch2_request_key(c->disk_sb.sb, &user_key);
537                 if (ret) {
538                         bch_err(c, "error requesting encryption key: %i", ret);
539                         goto err;
540                 }
541
542                 ret = bch2_chacha_encrypt_key(&user_key, bch2_sb_key_nonce(c),
543                                               &key, sizeof(key));
544                 if (ret)
545                         goto err;
546         }
547
548         ret = crypto_skcipher_setkey(&c->chacha20->base,
549                         (void *) &key.key, sizeof(key.key));
550         if (ret)
551                 goto err;
552
553         crypt = bch2_sb_resize_crypt(&c->disk_sb, sizeof(*crypt) / sizeof(u64));
554         if (!crypt) {
555                 ret = -ENOMEM; /* XXX this technically could be -ENOSPC */
556                 goto err;
557         }
558
559         crypt->key = key;
560
561         /* write superblock */
562         SET_BCH_SB_ENCRYPTION_TYPE(c->disk_sb.sb, 1);
563         bch2_write_super(c);
564 err:
565         mutex_unlock(&c->sb_lock);
566         memzero_explicit(&user_key, sizeof(user_key));
567         memzero_explicit(&key, sizeof(key));
568         return ret;
569 }
570
571 void bch2_fs_encryption_exit(struct bch_fs *c)
572 {
573         if (!IS_ERR_OR_NULL(c->poly1305))
574                 crypto_free_shash(c->poly1305);
575         if (!IS_ERR_OR_NULL(c->chacha20))
576                 crypto_free_sync_skcipher(c->chacha20);
577         if (!IS_ERR_OR_NULL(c->sha256))
578                 crypto_free_shash(c->sha256);
579 }
580
581 int bch2_fs_encryption_init(struct bch_fs *c)
582 {
583         struct bch_sb_field_crypt *crypt;
584         struct bch_key key;
585         int ret = 0;
586
587         pr_verbose_init(c->opts, "");
588
589         c->sha256 = crypto_alloc_shash("sha256", 0, 0);
590         if (IS_ERR(c->sha256)) {
591                 bch_err(c, "error requesting sha256 module");
592                 ret = PTR_ERR(c->sha256);
593                 goto out;
594         }
595
596         crypt = bch2_sb_get_crypt(c->disk_sb.sb);
597         if (!crypt)
598                 goto out;
599
600         ret = bch2_alloc_ciphers(c);
601         if (ret)
602                 goto out;
603
604         ret = bch2_decrypt_sb_key(c, crypt, &key);
605         if (ret)
606                 goto out;
607
608         ret = crypto_skcipher_setkey(&c->chacha20->base,
609                         (void *) &key.key, sizeof(key.key));
610         if (ret)
611                 goto out;
612 out:
613         memzero_explicit(&key, sizeof(key));
614         pr_verbose_init(c->opts, "ret %i", ret);
615         return ret;
616 }