mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add constant time crypt_bytes_to_hex helper and use it in libdevmapper.
Fixes: #736
This commit is contained in:
@@ -465,14 +465,6 @@ char *dm_device_name(const char *path)
|
||||
return dm_device_path(NULL, major(st.st_rdev), minor(st.st_rdev));
|
||||
}
|
||||
|
||||
static void hex_key(char *hexkey, size_t key_size, const char *key)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for(i = 0; i < key_size; i++)
|
||||
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
|
||||
}
|
||||
|
||||
static size_t int_log10(uint64_t x)
|
||||
{
|
||||
uint64_t r = 0;
|
||||
@@ -676,24 +668,20 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
|
||||
null_cipher = 1;
|
||||
|
||||
if (null_cipher)
|
||||
hexkey = crypt_safe_alloc(2);
|
||||
hexkey = crypt_bytes_to_hex(0, NULL);
|
||||
else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
|
||||
keystr_len = strlen(tgt->u.crypt.vk->key_description) + int_log10(tgt->u.crypt.vk->keylength) + 10;
|
||||
hexkey = crypt_safe_alloc(keystr_len);
|
||||
} else
|
||||
hexkey = crypt_safe_alloc(tgt->u.crypt.vk->keylength * 2 + 1);
|
||||
|
||||
if (!hexkey)
|
||||
goto out;
|
||||
|
||||
if (null_cipher)
|
||||
strncpy(hexkey, "-", 2);
|
||||
else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
|
||||
if (!hexkey)
|
||||
goto out;
|
||||
r = snprintf(hexkey, keystr_len, ":%zu:logon:%s", tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key_description);
|
||||
if (r < 0 || r >= keystr_len)
|
||||
goto out;
|
||||
} else
|
||||
hex_key(hexkey, tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key);
|
||||
hexkey = crypt_bytes_to_hex(tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key);
|
||||
|
||||
if (!hexkey)
|
||||
goto out;
|
||||
|
||||
max_size = strlen(hexkey) + strlen(cipher_dm) +
|
||||
strlen(device_block_path(tgt->data_device)) +
|
||||
@@ -788,18 +776,13 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
} else
|
||||
*features = '\0';
|
||||
|
||||
hexroot = crypt_safe_alloc(tgt->u.verity.root_hash_size * 2 + 1);
|
||||
hexroot = crypt_bytes_to_hex(tgt->u.verity.root_hash_size, tgt->u.verity.root_hash);
|
||||
if (!hexroot)
|
||||
goto out;
|
||||
hex_key(hexroot, tgt->u.verity.root_hash_size, tgt->u.verity.root_hash);
|
||||
|
||||
hexsalt = crypt_safe_alloc(vp->salt_size ? vp->salt_size * 2 + 1 : 2);
|
||||
hexsalt = crypt_bytes_to_hex(vp->salt_size, vp->salt);
|
||||
if (!hexsalt)
|
||||
goto out;
|
||||
if (vp->salt_size)
|
||||
hex_key(hexsalt, vp->salt_size, vp->salt);
|
||||
else
|
||||
strncpy(hexsalt, "-", 2);
|
||||
|
||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||
strlen(device_block_path(tgt->data_device)) +
|
||||
@@ -864,10 +847,9 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
num_options++;
|
||||
|
||||
if (tgt->u.integrity.vk) {
|
||||
hexkey = crypt_safe_alloc(tgt->u.integrity.vk->keylength * 2 + 1);
|
||||
hexkey = crypt_bytes_to_hex(tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key);
|
||||
if (!hexkey)
|
||||
goto out;
|
||||
hex_key(hexkey, tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key);
|
||||
} else
|
||||
hexkey = NULL;
|
||||
|
||||
@@ -882,11 +864,10 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
num_options++;
|
||||
|
||||
if (tgt->u.integrity.journal_integrity_key) {
|
||||
hexkey = crypt_safe_alloc(tgt->u.integrity.journal_integrity_key->keylength * 2 + 1);
|
||||
hexkey = crypt_bytes_to_hex( tgt->u.integrity.journal_integrity_key->keylength,
|
||||
tgt->u.integrity.journal_integrity_key->key);
|
||||
if (!hexkey)
|
||||
goto out;
|
||||
hex_key(hexkey, tgt->u.integrity.journal_integrity_key->keylength,
|
||||
tgt->u.integrity.journal_integrity_key->key);
|
||||
} else
|
||||
hexkey = NULL;
|
||||
|
||||
@@ -901,11 +882,10 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
num_options++;
|
||||
|
||||
if (tgt->u.integrity.journal_crypt_key) {
|
||||
hexkey = crypt_safe_alloc(tgt->u.integrity.journal_crypt_key->keylength * 2 + 1);
|
||||
hexkey = crypt_bytes_to_hex(tgt->u.integrity.journal_crypt_key->keylength,
|
||||
tgt->u.integrity.journal_crypt_key->key);
|
||||
if (!hexkey)
|
||||
goto out;
|
||||
hex_key(hexkey, tgt->u.integrity.journal_crypt_key->keylength,
|
||||
tgt->u.integrity.journal_crypt_key->key);
|
||||
} else
|
||||
hexkey = NULL;
|
||||
|
||||
@@ -3024,7 +3004,7 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
{
|
||||
uint32_t dmt_flags;
|
||||
int msg_size;
|
||||
char *msg = NULL;
|
||||
char *msg = NULL, *key = NULL;
|
||||
int r = -ENOTSUP;
|
||||
|
||||
if (dm_init_context(cd, DM_CRYPT) || dm_flags(cd, DM_CRYPT, &dmt_flags))
|
||||
@@ -3046,20 +3026,21 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
strcpy(msg, "key set ");
|
||||
if (!vk->keylength) {
|
||||
if (snprintf(msg + 8, msg_size - 8, "-") < 0) {
|
||||
r = -EINVAL;
|
||||
if (vk->key_description) {
|
||||
r = snprintf(msg, msg_size, "key set :%zu:logon:%s", vk->keylength, vk->key_description);
|
||||
} else {
|
||||
key = crypt_bytes_to_hex(vk->keylength, vk->key);
|
||||
if (!key) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
} else if (vk->key_description) {
|
||||
if (snprintf(msg + 8, msg_size - 8, ":%zu:logon:%s", vk->keylength, vk->key_description) < 0) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
hex_key(&msg[8], vk->keylength, vk->key);
|
||||
|
||||
r = snprintf(msg, msg_size, "key set %s", key);
|
||||
}
|
||||
if (r < 0 || r >= msg_size) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!_dm_message(name, msg) ||
|
||||
_dm_resume_device(name, 0)) {
|
||||
r = -EINVAL;
|
||||
@@ -3068,6 +3049,7 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
r = 0;
|
||||
out:
|
||||
crypt_safe_free(msg);
|
||||
crypt_safe_free(key);
|
||||
dm_exit_context();
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -183,6 +183,11 @@ static int hex_to_bin(unsigned char ch)
|
||||
((cu - 'A' + 11) & (unsigned)((cu - 'F' - 1) & ('A' - 1 - cu)) >> 8);
|
||||
}
|
||||
|
||||
static char hex2asc(unsigned char c)
|
||||
{
|
||||
return c + '0' + ((unsigned)(9 - c) >> 4 & 0x27);
|
||||
}
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
{
|
||||
char *bytes;
|
||||
@@ -214,6 +219,32 @@ ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
return i;
|
||||
}
|
||||
|
||||
char *crypt_bytes_to_hex(size_t size, const char *bytes)
|
||||
{
|
||||
unsigned i;
|
||||
char *hex;
|
||||
|
||||
if (size && !bytes)
|
||||
return NULL;
|
||||
|
||||
/* Alloc adds trailing \0 */
|
||||
if (size == 0)
|
||||
hex = crypt_safe_alloc(2);
|
||||
else
|
||||
hex = crypt_safe_alloc(size * 2 + 1);
|
||||
if (!hex)
|
||||
return NULL;
|
||||
|
||||
if (size == 0)
|
||||
hex[0] = '-';
|
||||
else for (i = 0; i < size; i++) {
|
||||
hex[i * 2] = hex2asc((const unsigned char)bytes[i] >> 4);
|
||||
hex[i * 2 + 1] = hex2asc((const unsigned char)bytes[i] & 0xf);
|
||||
}
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
bool crypt_is_cipher_null(const char *cipher_spec)
|
||||
{
|
||||
if (!cipher_spec)
|
||||
|
||||
@@ -37,6 +37,7 @@ int crypt_parse_integrity_mode(const char *s, char *integrity,
|
||||
int crypt_parse_pbkdf(const char *s, const char **pbkdf);
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
|
||||
char *crypt_bytes_to_hex(size_t size, const char *bytes);
|
||||
|
||||
bool crypt_is_cipher_null(const char *cipher_spec);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user