* Remove po/cryptsetup-luks.pot, it's autogenerated.
* Return ENOENT for empty keyslots, EINVAL will be used later for other type of error.
* Switch PBKDF2 from internal SHA1 to libgcrypt, make hash algorithm not hardcoded to SHA1 here.
+ * Add required parameters for changing hash used in LUKS key setup scheme.
2009-07-28 Milan Broz <mbroz@redhat.com>
* Pad luks header to 512 sector size.
char cipherName[LUKS_CIPHERNAME_L];
char cipherMode[LUKS_CIPHERMODE_L];
unsigned int passwordLen;
- int PBKDF2perSecond;
+ unsigned int PBKDF2perSecond = 0;
int keyIndex;
if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL))
r = parse_into_name_and_mode(options->cipher, cipherName, cipherMode);
if(r < 0) return r;
- r = LUKS_generate_phdr(&header,mk,cipherName, cipherMode,LUKS_STRIPES, options->align_payload);
- if(r < 0) {
- set_error("Can't generate phdr");
- return r;
+ r = LUKS_generate_phdr(&header, mk, cipherName, cipherMode, options->hash, LUKS_STRIPES, options->align_payload);
+ if(r < 0) return r;
+
+ keyIndex = keyslot_from_option(options->key_slot, &header, options);
+ if(keyIndex == -EINVAL) {
+ r = -EINVAL; goto out;
}
- keyIndex = keyslot_from_option(options->key_slot, &header, options);
- if(keyIndex == -EINVAL) {
- r = -EINVAL; goto out;
- }
+ r = LUKS_benchmarkt_iterations(options->hash, &PBKDF2perSecond);
+ if (r < 0) goto out;
- PBKDF2perSecond = LUKS_benchmarkt_iterations();
header.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000.0));
#ifdef LUKS_DEBUG
logger(options, CRYPT_LOG_ERROR, "pitr %d\n", header.keyblock[0].passwordIterations);
struct luks_masterkey *mk=NULL;
struct luks_phdr hdr;
char *password=NULL; unsigned int passwordLen;
- unsigned int keyIndex;
+ unsigned int keyIndex;
+ unsigned int PBKDF2perSecond = 0;
const char *device = options->device;
int r;
r = -EINVAL; goto out;
}
- hdr.keyblock[keyIndex].passwordIterations = at_least_one(LUKS_benchmarkt_iterations() * ((float)options->iteration_time / 1000));
+ r = LUKS_benchmarkt_iterations(hdr.hashSpec, &PBKDF2perSecond);
+ if (r < 0) goto out;
+ hdr.keyblock[keyIndex].passwordIterations = at_least_one(PBKDF2perSecond * ((float)options->iteration_time / 1000));
- r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend);
+ r = LUKS_set_key(device, keyIndex, password, passwordLen, &hdr, mk, backend);
if(r < 0) goto out;
r = 0;
int LUKS_read_phdr(const char *device, struct luks_phdr *hdr)
{
- int devfd = 0, r = 0;
- unsigned int i;
+ int devfd = 0, r = 0;
+ unsigned int i;
uint64_t size;
char luksMagic[] = LUKS_MAGIC;
} else if(memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */
set_error(_("%s is not a LUKS partition\n"), device);
r = -EINVAL;
- } else if(memcmp(hdr->hashSpec, "sha1", 4)) { /* Check for SHA1 - other hashspecs are not implemented ATM */
- set_error(_("unknown hash spec in phdr\n"), stderr);
- r = -EINVAL;
} else if((hdr->version = ntohs(hdr->version)) != 1) { /* Convert every uint16/32_t item from network byte order */
set_error(_("unknown LUKS version %d\n"), hdr->version);
r = -EINVAL;
+ } else if (PBKDF2_HMAC_ready(hdr->hashSpec) < 0) {
+ set_error(_("Requested LUKS hash %s is not supported.\n"), hdr->hashSpec);
+ r = -EINVAL;
} else {
hdr->payloadOffset = ntohl(hdr->payloadOffset);
hdr->keyBytes = ntohl(hdr->keyBytes);
return r;
}
-int LUKS_generate_phdr(struct luks_phdr *header,
- const struct luks_masterkey *mk, const char *cipherName,
- const char *cipherMode, unsigned int stripes,
+int LUKS_generate_phdr(struct luks_phdr *header,
+ const struct luks_masterkey *mk,
+ const char *cipherName, const char *cipherMode, const char *hashSpec,
+ unsigned int stripes,
unsigned int alignPayload)
{
unsigned int i=0;
header->version=1;
strncpy(header->cipherName,cipherName,LUKS_CIPHERNAME_L);
strncpy(header->cipherMode,cipherMode,LUKS_CIPHERMODE_L);
-
- /* This is hard coded ATM */
- strncpy(header->hashSpec,"sha1",LUKS_HASHSPEC_L);
+ strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L);
header->keyBytes=mk->keyLength;
return 0;
}
-int LUKS_set_key(const char *device, unsigned int keyIndex,
- const char *password, size_t passwordLen,
+int LUKS_set_key(const char *device, unsigned int keyIndex,
+ const char *password, size_t passwordLen,
struct luks_phdr *hdr, struct luks_masterkey *mk,
struct setup_backend *backend)
{
}
/* Try to open a particular key slot */
-int LUKS_open_key(const char *device,
- unsigned int keyIndex,
- const char *password,
- size_t passwordLen,
- struct luks_phdr *hdr,
+int LUKS_open_key(const char *device,
+ unsigned int keyIndex,
+ const char *password,
+ size_t passwordLen,
+ struct luks_phdr *hdr,
struct luks_masterkey *mk,
struct setup_backend *backend)
{
return 1;
}
-
-int LUKS_benchmarkt_iterations()
+int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count)
{
- unsigned int count;
- char *hash = "sha1";
-
- if (PBKDF2_performance_check(hash, &count) < 0) {
+ if (PBKDF2_performance_check(hash, count) < 0) {
set_error(_("Not compatible options (using hash algorithm %s)."), hash);
return -EINVAL;
}
- return count/2;
+ *count /= 2;
+ return 0;
}
int LUKS_device_ready(const char *device, int mode)
struct luks_masterkey *LUKS_generate_masterkey(int keylength);
int LUKS_generate_phdr(struct luks_phdr *header,
- const struct luks_masterkey *mk, const char *cipherName,
- const char *cipherMode, unsigned int stripes,
+ const struct luks_masterkey *mk,
+ const char *cipherName, const char *cipherMode, const char *hashSpec,
+ unsigned int stripes,
unsigned int alignPayload);
int LUKS_read_phdr(const char *device, struct luks_phdr *hdr);
int LUKS_del_key(const char *device, unsigned int keyIndex);
int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex);
-int LUKS_benchmarkt_iterations();
+int LUKS_benchmarkt_iterations(const char *hash, unsigned int *count);
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
const char *device,
unsigned int sector, struct setup_backend *backend);
-
+
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
struct luks_phdr *hdr,
char *key, size_t keyLength,
static int opt_verbose = 1;
static char *opt_cipher = NULL;
-static char *opt_hash = DEFAULT_HASH;
+static char *opt_hash = NULL;
static int opt_verify_passphrase = 0;
static char *opt_key_file = NULL;
static unsigned int opt_key_size = 0;
.name = action_argv[0],
.device = action_argv[1],
.cipher = opt_cipher?opt_cipher:DEFAULT_CIPHER,
- .hash = opt_hash,
+ .hash = opt_hash ?: DEFAULT_HASH,
.key_file = opt_key_file,
.key_size = ((opt_key_size)?opt_key_size:DEFAULT_KEY_SIZE)/8,
.key_slot = opt_key_slot,
.key_slot = opt_key_slot,
.device = action_argv[0],
.cipher = opt_cipher?opt_cipher:DEFAULT_LUKS_CIPHER,
+ .hash = DEFAULT_LUKS_HASH,
+ // FIXME: enable other hash use here
+ //.hash = opt_hash ?: DEFAULT_LUKS_HASH,
.new_key_file = action_argc > 1 ? action_argv[1] : NULL,
.flags = opt_verify_passphrase ? CRYPT_FLAG_VERIFY : (!opt_batch_mode?CRYPT_FLAG_VERIFY_IF_POSSIBLE : 0),
.iteration_time = opt_iteration_time,
#define DEFAULT_CIPHER "aes"
#define DEFAULT_LUKS_CIPHER "aes-cbc-essiv:sha256"
#define DEFAULT_HASH "ripemd160"
+#define DEFAULT_LUKS_HASH "sha1"
#define DEFAULT_KEY_SIZE 256
#define DEFAULT_LUKS_KEY_SIZE 128