]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - crypto.c
include/linux/bitmap.h: inline __bitmap_weight and __bitmap_and
[bcachefs-tools-debian] / crypto.c
index f38a359da23431d03f4ef4efbf946acc4bcca26d..0e18b36ff81aa6e4f535cea29c8bc6ba52df3db1 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -15,7 +15,7 @@
 #include <libscrypt.h>
 #include <uuid/uuid.h>
 
-#include "checksum.h"
+#include "libbcachefs/checksum.h"
 #include "crypto.h"
 
 char *read_passphrase(const char *prompt)
@@ -54,11 +54,32 @@ char *read_passphrase(const char *prompt)
        return buf;
 }
 
-void derive_passphrase(struct bch_sb_field_crypt *crypt,
-                      struct bch_key *key,
-                      const char *passphrase)
+char *read_passphrase_twice(const char *prompt)
+{
+       char *pass = read_passphrase(prompt);
+
+       if (!isatty(STDIN_FILENO))
+               return pass;
+
+       char *pass2 = read_passphrase("Enter same passphrase again: ");
+
+       if (strcmp(pass, pass2)) {
+               memzero_explicit(pass, strlen(pass));
+               memzero_explicit(pass2, strlen(pass2));
+               die("Passphrases do not match");
+       }
+
+       memzero_explicit(pass2, strlen(pass2));
+       free(pass2);
+
+       return pass;
+}
+
+struct bch_key derive_passphrase(struct bch_sb_field_crypt *crypt,
+                                const char *passphrase)
 {
        const unsigned char salt[] = "bcache";
+       struct bch_key key;
        int ret;
 
        switch (BCH_CRYPT_KDF_TYPE(crypt)) {
@@ -68,40 +89,54 @@ void derive_passphrase(struct bch_sb_field_crypt *crypt,
                                       1ULL << BCH_KDF_SCRYPT_N(crypt),
                                       1ULL << BCH_KDF_SCRYPT_R(crypt),
                                       1ULL << BCH_KDF_SCRYPT_P(crypt),
-                                      (void *) key, sizeof(*key));
+                                      (void *) &key, sizeof(key));
                if (ret)
                        die("scrypt error: %i", ret);
                break;
        default:
                die("unknown kdf type %llu", BCH_CRYPT_KDF_TYPE(crypt));
        }
+
+       return key;
 }
 
-void add_bcache_key(struct bch_sb *sb, const char *passphrase)
+void bch2_passphrase_check(struct bch_sb *sb, const char *passphrase,
+                          struct bch_key *passphrase_key,
+                          struct bch_encrypted_key *sb_key)
 {
-       struct bch_sb_field_crypt *crypt = bch_sb_get_crypt(sb);
+       struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(sb);
        if (!crypt)
                die("filesystem is not encrypted");
 
-       struct bch_encrypted_key sb_key = crypt->key;
-       if (!bch_key_is_encrypted(&sb_key))
+       *sb_key = crypt->key;
+
+       if (!bch2_key_is_encrypted(sb_key))
                die("filesystem does not have encryption key");
 
-       struct bch_key passphrase_key;
-       derive_passphrase(crypt, &passphrase_key, passphrase);
+       *passphrase_key = derive_passphrase(crypt, passphrase);
 
        /* Check if the user supplied the correct passphrase: */
-       if (bch_chacha_encrypt_key(&passphrase_key, __bch_sb_key_nonce(sb),
-                                  &sb_key, sizeof(sb_key)))
+       if (bch2_chacha_encrypt_key(passphrase_key, __bch2_sb_key_nonce(sb),
+                                   sb_key, sizeof(*sb_key)))
                die("error encrypting key");
 
-       if (bch_key_is_encrypted(&sb_key))
+       if (bch2_key_is_encrypted(sb_key))
                die("incorrect passphrase");
+}
+
+void bch2_add_key(struct bch_sb *sb, const char *passphrase)
+{
+       struct bch_key passphrase_key;
+       struct bch_encrypted_key sb_key;
+
+       bch2_passphrase_check(sb, passphrase,
+                             &passphrase_key,
+                             &sb_key);
 
        char uuid[40];
        uuid_unparse_lower(sb->user_uuid.b, uuid);
 
-       char *description = mprintf("bcache:%s", uuid);
+       char *description = mprintf("bcachefs:%s", uuid);
 
        if (add_key("logon", description,
                    &passphrase_key, sizeof(passphrase_key),
@@ -109,7 +144,7 @@ void add_bcache_key(struct bch_sb *sb, const char *passphrase)
            add_key("user", description,
                    &passphrase_key, sizeof(passphrase_key),
                    KEY_SPEC_USER_KEYRING) < 0)
-               die("add_key error: %s", strerror(errno));
+               die("add_key error: %m");
 
        memzero_explicit(description, strlen(description));
        free(description);
@@ -125,22 +160,21 @@ void bch_sb_crypt_init(struct bch_sb *sb,
        get_random_bytes(&crypt->key.key, sizeof(crypt->key.key));
 
        if (passphrase) {
-               struct bch_key passphrase_key;
 
                SET_BCH_CRYPT_KDF_TYPE(crypt, BCH_KDF_SCRYPT);
                SET_BCH_KDF_SCRYPT_N(crypt, ilog2(SCRYPT_N));
                SET_BCH_KDF_SCRYPT_R(crypt, ilog2(SCRYPT_r));
                SET_BCH_KDF_SCRYPT_P(crypt, ilog2(SCRYPT_p));
 
-               derive_passphrase(crypt, &passphrase_key, passphrase);
+               struct bch_key passphrase_key = derive_passphrase(crypt, passphrase);
 
-               assert(!bch_key_is_encrypted(&crypt->key));
+               assert(!bch2_key_is_encrypted(&crypt->key));
 
-               if (bch_chacha_encrypt_key(&passphrase_key, __bch_sb_key_nonce(sb),
+               if (bch2_chacha_encrypt_key(&passphrase_key, __bch2_sb_key_nonce(sb),
                                           &crypt->key, sizeof(crypt->key)))
                        die("error encrypting key");
 
-               assert(bch_key_is_encrypted(&crypt->key));
+               assert(bch2_key_is_encrypted(&crypt->key));
 
                memzero_explicit(&passphrase_key, sizeof(passphrase_key));
        }