X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=crypto.c;h=0e18b36ff81aa6e4f535cea29c8bc6ba52df3db1;hb=e8a350841ca12302f2c32459a671dce7ff171f70;hp=f38a359da23431d03f4ef4efbf946acc4bcca26d;hpb=a17f7bcec7ed810a247c24e56229af8f43a9a6ae;p=bcachefs-tools-debian diff --git a/crypto.c b/crypto.c index f38a359..0e18b36 100644 --- a/crypto.c +++ b/crypto.c @@ -15,7 +15,7 @@ #include #include -#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)); }