Commit 25512d89 authored by Milan Broz's avatar Milan Broz

Clean up plain password hashing, do not ignore error in crypto backend.

(New backend can fail there).

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@451 36d66b0a-2a48-0410-832c-cd162a569da5
parent e1cc40df
......@@ -2,7 +2,7 @@
* cryptsetup plain device helper functions
*
* Copyright (C) 2004 Christophe Saout <christophe@saout.de>
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -25,70 +25,80 @@
#include "internal.h"
#include "crypto_backend.h"
static int hash(const char *hash_name, int size, char *key,
int sizep, const char *passphrase)
static int hash(const char *hash_name, size_t key_size, char *key,
size_t passphrase_size, const char *passphrase)
{
struct crypt_hash *md = NULL;
size_t slen;
int len = crypt_hash_size(hash_name);
int round, i;
size_t len;
int round, i, r = 0;
if (crypt_hash_init(&md, hash_name))
return -ENOENT;
for(round = 0; size; round++) {
len = crypt_hash_size(hash_name);
for(round = 0; key_size && !r; round++) {
/* hack from hashalot to avoid null bytes in key */
for(i = 0; i < round; i++)
crypt_hash_write(md, "A", 1);
if (crypt_hash_write(md, "A", 1))
r = 1;
if (crypt_hash_write(md, passphrase, passphrase_size))
r = 1;
crypt_hash_write(md, passphrase, sizep);
if (len > key_size)
len = key_size;
if (len > size)
len = size;
slen = len;
crypt_hash_final(md, key, slen);
// FIXME: if slen != len
if (crypt_hash_final(md, key, len))
r = 1;
key += len;
size -= len;
if (size)
crypt_hash_restart(md);
key_size -= len;
if (key_size && crypt_hash_restart(md))
r = 1;
}
crypt_hash_destroy(md);
return 0;
return r;
}
int crypt_plain_hash(struct crypt_device *ctx, const char *hash_name,
char *result, size_t size,
const char *passphrase, size_t sizep)
#define PLAIN_HASH_LEN_MAX 256
int crypt_plain_hash(struct crypt_device *ctx,
const char *hash_name,
char *key, size_t key_size,
const char *passphrase, size_t passphrase_size)
{
char hash_name_buf[256], *s;
size_t hlen, pad = 0;
char hash_name_buf[PLAIN_HASH_LEN_MAX], *s;
size_t hash_size, pad_size;
int r;
if (strlen(hash_name) >= sizeof(hash_name_buf))
log_dbg("Plain: hashing passphrase using %s.", hash_name);
if (strlen(hash_name) >= PLAIN_HASH_LEN_MAX)
return -EINVAL;
strncpy(hash_name_buf, hash_name, PLAIN_HASH_LEN_MAX);
hash_name_buf[PLAIN_HASH_LEN_MAX - 1] = '\0';
if ((s = strchr(hash_name, ':'))) {
strcpy(hash_name_buf, hash_name);
hash_name_buf[s-hash_name] = '\0';
hash_name = hash_name_buf;
hlen = atoi(++s);
if (hlen > size) {
log_err(ctx, "Requested hash length (%zd) > key length (%zd)\n", hlen, size);
/* hash[:hash_length] */
if ((s = strchr(hash_name_buf, ':'))) {
*s = '\0';
hash_size = atoi(++s);
if (hash_size > key_size) {
log_dbg("Hash length %zd > key length %zd",
hash_size, key_size);
return -EINVAL;
}
pad = size-hlen;
size = hlen;
pad_size = key_size - hash_size;
} else {
hash_size = key_size;
pad_size = 0;
}
r = hash(hash_name, size, result, sizep, passphrase);
if (r < 0)
log_err(ctx, "Hash algorithm %s not supported.\n", hash_name);
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
if (r == 0 && pad)
memset(result+size, 0, pad);
if (r == 0 && pad_size)
memset(key + hash_size, 0, pad_size);
return r;
}
......@@ -132,8 +132,9 @@ int crypt_random_get(struct crypt_device *ctx, char *buf, size_t len, int qualit
void crypt_random_exit(void);
int crypt_random_default_key_rng(void);
int crypt_plain_hash(struct crypt_device *ctx, const char *hash_name,
char *result, size_t size,
const char *passphrase, size_t sizep);
int crypt_plain_hash(struct crypt_device *ctx,
const char *hash_name,
char *key, size_t key_size,
const char *passphrase, size_t passphrase_size);
#endif /* INTERNAL_H */
......@@ -124,6 +124,7 @@ static char *process_key(struct crypt_device *cd, const char *hash_name,
const char *pass, size_t passLen)
{
char *key;
int r;
if (!key_size)
return NULL;
......@@ -145,9 +146,14 @@ static char *process_key(struct crypt_device *cd, const char *hash_name,
/* key is coming from tty, fd or binary stdin */
if (hash_name) {
if (crypt_plain_hash(cd, hash_name, key, key_size, pass, passLen) < 0) {
log_err(cd, _("Key processing error (using hash algorithm %s).\n"),
hash_name);
r = crypt_plain_hash(cd, hash_name, key, key_size, pass, passLen);
if (r < 0) {
if (r == -ENOENT)
log_err(cd, _("Hash algorithm %s not supported.\n"),
hash_name);
else
log_err(cd, _("Key processing error (using hash %s).\n"),
hash_name);
crypt_safe_free(key);
return NULL;
}
......
......@@ -85,6 +85,10 @@ crypt_key ripemd160 256 stdin "xxx\n" 625ce2a8dbdf08f1de400dba7ab9fab246f2a55ad6
crypt_key ripemd160 256 file /dev/zero 0000000000000000000000000000000000000000000000000000000000000000
crypt_key sha256 256 file /dev/zero 0000000000000000000000000000000000000000000000000000000000000000
# limiting key
crypt_key sha256:20 256 pwd "xxx" cd2eb0837c9b4c962c22d2ff8b5441b7b4580588000000000000000000000000
crypt_key sha256:32 256 pwd "xxx" cd2eb0837c9b4c962c22d2ff8b5441b7b45805887f051d39bf133b583baf6860
# key file, 80 chars
echo -n -e "0123456789abcdef\n\x01\x00\x03\xff\xff\r\xff\xff\n\r" \
"2352j3rkjhadcfasc823rqaw7e1 3dq sdq3d 2dkjqw3h2=====" >$KEY_FILE
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment