14 #include <linux/random.h>
15 #include <sodium/crypto_pwhash_scryptsalsa208sha256.h>
16 #include <uuid/uuid.h>
18 #include "libbcachefs/checksum.h"
21 char *read_passphrase(const char *prompt)
27 if (isatty(STDIN_FILENO)) {
28 struct termios old, new;
30 fprintf(stderr, "%s", prompt);
33 if (tcgetattr(STDIN_FILENO, &old))
34 die("error getting terminal attrs");
38 if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new))
39 die("error setting terminal attrs");
41 len = getline(&buf, &buflen, stdin);
43 tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);
44 fprintf(stderr, "\n");
46 len = getline(&buf, &buflen, stdin);
50 die("error reading passphrase");
51 if (len && buf[len - 1] == '\n')
57 char *read_passphrase_twice(const char *prompt)
59 char *pass = read_passphrase(prompt);
61 if (!isatty(STDIN_FILENO))
64 char *pass2 = read_passphrase("Enter same passphrase again: ");
66 if (strcmp(pass, pass2)) {
67 memzero_explicit(pass, strlen(pass));
68 memzero_explicit(pass2, strlen(pass2));
69 die("Passphrases do not match");
72 memzero_explicit(pass2, strlen(pass2));
78 struct bch_key derive_passphrase(struct bch_sb_field_crypt *crypt,
79 const char *passphrase)
81 const unsigned char salt[] = "bcache";
85 switch (BCH_CRYPT_KDF_TYPE(crypt)) {
87 ret = crypto_pwhash_scryptsalsa208sha256_ll(
88 (void *) passphrase, strlen(passphrase),
90 1ULL << BCH_KDF_SCRYPT_N(crypt),
91 1ULL << BCH_KDF_SCRYPT_R(crypt),
92 1ULL << BCH_KDF_SCRYPT_P(crypt),
93 (void *) &key, sizeof(key));
95 die("scrypt error: %i", ret);
98 die("unknown kdf type %llu", BCH_CRYPT_KDF_TYPE(crypt));
104 bool bch2_sb_is_encrypted(struct bch_sb *sb)
106 struct bch_sb_field_crypt *crypt;
108 return (crypt = bch2_sb_get_crypt(sb)) &&
109 bch2_key_is_encrypted(&crypt->key);
112 void bch2_passphrase_check(struct bch_sb *sb, const char *passphrase,
113 struct bch_key *passphrase_key,
114 struct bch_encrypted_key *sb_key)
116 struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(sb);
118 die("filesystem is not encrypted");
120 *sb_key = crypt->key;
122 if (!bch2_key_is_encrypted(sb_key))
123 die("filesystem does not have encryption key");
125 *passphrase_key = derive_passphrase(crypt, passphrase);
127 /* Check if the user supplied the correct passphrase: */
128 if (bch2_chacha_encrypt_key(passphrase_key, __bch2_sb_key_nonce(sb),
129 sb_key, sizeof(*sb_key)))
130 die("error encrypting key");
132 if (bch2_key_is_encrypted(sb_key))
133 die("incorrect passphrase");
136 void bch2_add_key(struct bch_sb *sb,
138 const char *keyring_str,
139 const char *passphrase)
141 struct bch_key passphrase_key;
142 struct bch_encrypted_key sb_key;
145 if (!strcmp(keyring_str, "session"))
146 keyring = KEY_SPEC_SESSION_KEYRING;
147 else if (!strcmp(keyring_str, "user"))
148 keyring = KEY_SPEC_USER_KEYRING;
149 else if (!strcmp(keyring_str, "user_session"))
150 keyring = KEY_SPEC_USER_SESSION_KEYRING;
152 die("unknown keyring %s", keyring_str);
154 bch2_passphrase_check(sb, passphrase,
159 uuid_unparse_lower(sb->user_uuid.b, uuid);
161 char *description = mprintf("bcachefs:%s", uuid);
165 &passphrase_key, sizeof(passphrase_key),
167 die("add_key error: %m");
169 memzero_explicit(description, strlen(description));
171 memzero_explicit(&passphrase_key, sizeof(passphrase_key));
172 memzero_explicit(&sb_key, sizeof(sb_key));
175 void bch_sb_crypt_init(struct bch_sb *sb,
176 struct bch_sb_field_crypt *crypt,
177 const char *passphrase)
179 crypt->key.magic = BCH_KEY_MAGIC;
180 get_random_bytes(&crypt->key.key, sizeof(crypt->key.key));
184 SET_BCH_CRYPT_KDF_TYPE(crypt, BCH_KDF_SCRYPT);
185 SET_BCH_KDF_SCRYPT_N(crypt, ilog2(16384));
186 SET_BCH_KDF_SCRYPT_R(crypt, ilog2(8));
187 SET_BCH_KDF_SCRYPT_P(crypt, ilog2(16));
189 struct bch_key passphrase_key = derive_passphrase(crypt, passphrase);
191 assert(!bch2_key_is_encrypted(&crypt->key));
193 if (bch2_chacha_encrypt_key(&passphrase_key, __bch2_sb_key_nonce(sb),
194 &crypt->key, sizeof(crypt->key)))
195 die("error encrypting key");
197 assert(bch2_key_is_encrypted(&crypt->key));
199 memzero_explicit(&passphrase_key, sizeof(passphrase_key));