mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-17 13:50:06 +01:00
Add support for Adiantum cipher mode.
This commit is contained in:
@@ -26,53 +26,58 @@
|
|||||||
|
|
||||||
struct cipher_alg {
|
struct cipher_alg {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
const char *mode;
|
||||||
int blocksize;
|
int blocksize;
|
||||||
bool wrapped_key;
|
bool wrapped_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FIXME: Getting block size should be dynamic from cipher backend. */
|
/* FIXME: Getting block size should be dynamic from cipher backend. */
|
||||||
static const struct cipher_alg cipher_algs[] = {
|
static const struct cipher_alg cipher_algs[] = {
|
||||||
{ "cipher_null", 16, false },
|
{ "cipher_null", NULL, 16, false },
|
||||||
{ "aes", 16, false },
|
{ "aes", NULL, 16, false },
|
||||||
{ "serpent", 16, false },
|
{ "serpent", NULL, 16, false },
|
||||||
{ "twofish", 16, false },
|
{ "twofish", NULL, 16, false },
|
||||||
{ "anubis", 16, false },
|
{ "anubis", NULL, 16, false },
|
||||||
{ "blowfish", 8, false },
|
{ "blowfish", NULL, 8, false },
|
||||||
{ "camellia", 16, false },
|
{ "camellia", NULL, 16, false },
|
||||||
{ "cast5", 8, false },
|
{ "cast5", NULL, 8, false },
|
||||||
{ "cast6", 16, false },
|
{ "cast6", NULL, 16, false },
|
||||||
{ "des", 8, false },
|
{ "des", NULL, 8, false },
|
||||||
{ "des3_ede", 8, false },
|
{ "des3_ede", NULL, 8, false },
|
||||||
{ "khazad", 8, false },
|
{ "khazad", NULL, 8, false },
|
||||||
{ "seed", 16, false },
|
{ "seed", NULL, 16, false },
|
||||||
{ "tea", 8, false },
|
{ "tea", NULL, 8, false },
|
||||||
{ "xtea", 8, false },
|
{ "xtea", NULL, 8, false },
|
||||||
{ "paes", 16, true }, /* protected AES, s390 wrapped key scheme */
|
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||||
{ NULL, 0, false }
|
{ "xchacha12,aes", "adiantum", 32, false },
|
||||||
|
{ "xchacha20,aes", "adiantum", 32, false },
|
||||||
|
{ NULL, NULL, 0, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct cipher_alg *_get_alg(const char *name)
|
static const struct cipher_alg *_get_alg(const char *name, const char *mode)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (name && cipher_algs[i].name) {
|
while (name && cipher_algs[i].name) {
|
||||||
if (!strcasecmp(name, cipher_algs[i].name))
|
if (!strcasecmp(name, cipher_algs[i].name))
|
||||||
return &cipher_algs[i];
|
if (!mode || !cipher_algs[i].mode ||
|
||||||
|
!strncasecmp(mode, cipher_algs[i].mode, strlen(cipher_algs[i].mode)))
|
||||||
|
return &cipher_algs[i];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypt_cipher_blocksize(const char *name)
|
int crypt_cipher_ivsize(const char *name, const char *mode)
|
||||||
{
|
{
|
||||||
const struct cipher_alg *ca = _get_alg(name);
|
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||||
|
|
||||||
return ca ? ca->blocksize : -EINVAL;
|
return ca ? ca->blocksize : -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypt_cipher_wrapped_key(const char *name)
|
int crypt_cipher_wrapped_key(const char *name, const char *mode)
|
||||||
{
|
{
|
||||||
const struct cipher_alg *ca = _get_alg(name);
|
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||||
|
|
||||||
return ca ? (int)ca->wrapped_key : 0;
|
return ca ? (int)ca->wrapped_key : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ int argon2(const char *type, const char *password, size_t password_length,
|
|||||||
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
|
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
|
||||||
|
|
||||||
/* ciphers */
|
/* ciphers */
|
||||||
int crypt_cipher_blocksize(const char *name);
|
int crypt_cipher_ivsize(const char *name, const char *mode);
|
||||||
int crypt_cipher_wrapped_key(const char *name);
|
int crypt_cipher_wrapped_key(const char *name, const char *mode);
|
||||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||||
const char *mode, const void *key, size_t key_length);
|
const char *mode, const void *key, size_t key_length);
|
||||||
void crypt_cipher_destroy(struct crypt_cipher *ctx);
|
void crypt_cipher_destroy(struct crypt_cipher *ctx);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
|||||||
{
|
{
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
|
||||||
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
|
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
|
||||||
if (ctx->iv_size < 8)
|
if (ctx->iv_size < 8)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
|||||||
@@ -114,17 +114,18 @@ int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
|
|||||||
int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd)
|
int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd)
|
||||||
{
|
{
|
||||||
const char *cipher = crypt_get_cipher(cd);
|
const char *cipher = crypt_get_cipher(cd);
|
||||||
|
const char *cipher_mode = crypt_get_cipher_mode(cd);
|
||||||
|
|
||||||
/* Keyslot is already authenticated; we cannot use integrity tags here */
|
/* Keyslot is already authenticated; we cannot use integrity tags here */
|
||||||
if (crypt_get_integrity_tag_size(cd) || !cipher)
|
if (crypt_get_integrity_tag_size(cd) || !cipher)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Wrapped key schemes cannot be used for keyslot encryption */
|
/* Wrapped key schemes cannot be used for keyslot encryption */
|
||||||
if (crypt_cipher_wrapped_key(cipher))
|
if (crypt_cipher_wrapped_key(cipher, cipher_mode))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Check if crypto backend can use the cipher */
|
/* Check if crypto backend can use the cipher */
|
||||||
if (crypt_cipher_blocksize(cipher) < 0)
|
if (crypt_cipher_ivsize(cipher, cipher_mode) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -674,7 +674,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (crypt_cipher_wrapped_key(cipher)) {
|
if (crypt_cipher_wrapped_key(cipher, cipher_mode)) {
|
||||||
log_err(cd, _("Cannot convert to LUKS1 format - device uses wrapped key cipher %s."), cipher);
|
log_err(cd, _("Cannot convert to LUKS1 format - device uses wrapped key cipher %s."), cipher);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2368,7 +2368,7 @@ int crypt_suspend(struct crypt_device *cd,
|
|||||||
key_desc = crypt_get_device_key_description(name);
|
key_desc = crypt_get_device_key_description(name);
|
||||||
|
|
||||||
/* we can't simply wipe wrapped keys */
|
/* we can't simply wipe wrapped keys */
|
||||||
if (crypt_cipher_wrapped_key(crypt_get_cipher(cd)))
|
if (crypt_cipher_wrapped_key(crypt_get_cipher(cd), crypt_get_cipher_mode(cd)))
|
||||||
r = dm_suspend_device(cd, name);
|
r = dm_suspend_device(cd, name);
|
||||||
else
|
else
|
||||||
r = dm_suspend_and_wipe_key(cd, name);
|
r = dm_suspend_and_wipe_key(cd, name);
|
||||||
@@ -3420,7 +3420,8 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* wrapped keys or unbound keys may be exported */
|
/* wrapped keys or unbound keys may be exported */
|
||||||
if (crypt_fips_mode() && !crypt_cipher_wrapped_key(crypt_get_cipher(cd))) {
|
if (crypt_fips_mode() &&
|
||||||
|
!crypt_cipher_wrapped_key(crypt_get_cipher(cd), crypt_get_cipher_mode(cd))) {
|
||||||
if (!isLUKS2(cd->type) || keyslot == CRYPT_ANY_SLOT ||
|
if (!isLUKS2(cd->type) || keyslot == CRYPT_ANY_SLOT ||
|
||||||
!LUKS2_keyslot_for_segment(&cd->u.luks2.hdr, keyslot, CRYPT_DEFAULT_SEGMENT)) {
|
!LUKS2_keyslot_for_segment(&cd->u.luks2.hdr, keyslot, CRYPT_DEFAULT_SEGMENT)) {
|
||||||
log_err(cd, _("Function not available in FIPS mode."));
|
log_err(cd, _("Function not available in FIPS mode."));
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ dmcrypt_check() # device outstring
|
|||||||
dmremove $1
|
dmremove $1
|
||||||
}
|
}
|
||||||
|
|
||||||
dmcrypt_check_sum() # cipher device outstring
|
dmcrypt_check_sum() # cipher device
|
||||||
{
|
{
|
||||||
EXPSUM="c036cbb7553a909f8b8877d4461924307f27ecb66cff928eeeafd569c3887e29"
|
EXPSUM="c036cbb7553a909f8b8877d4461924307f27ecb66cff928eeeafd569c3887e29"
|
||||||
# Fill device with zeroes and reopen it
|
# Fill device with zeroes and reopen it
|
||||||
@@ -99,28 +99,35 @@ dmcrypt()
|
|||||||
{
|
{
|
||||||
OUT=$2
|
OUT=$2
|
||||||
[ -z "$OUT" ] && OUT=$1
|
[ -z "$OUT" ] && OUT=$1
|
||||||
printf "%-25s" "$1"
|
printf "%-31s" "$1"
|
||||||
|
|
||||||
echo $PASSWORD | $CRYPTSETUP create -h sha256 -c $1 -s 256 "$DEV_NAME"_"$1" /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
echo $PASSWORD | $CRYPTSETUP create -h sha256 -c $1 -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
||||||
if [ $? -eq 0 ] ; then
|
if [ $? -eq 0 ] ; then
|
||||||
echo -n -e "PLAIN:"
|
echo -n -e "PLAIN:"
|
||||||
dmcrypt_check "$DEV_NAME"_"$1" $OUT
|
dmcrypt_check "$DEV_NAME"_tstdev $OUT
|
||||||
else
|
else
|
||||||
echo -n "[n/a]"
|
echo -n "[n/a]"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $PASSWORD | $CRYPTSETUP luksFormat -i 1 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
echo $PASSWORD | $CRYPTSETUP luksFormat --type luks1 -i 1 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
||||||
if [ $? -eq 0 ] ; then
|
if [ $? -eq 0 ] ; then
|
||||||
echo -n -e " LUKS:"
|
echo -n -e " LUKS1:"
|
||||||
echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_"$1" >/dev/null 2>&1
|
echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1
|
||||||
dmcrypt_check "$DEV_NAME"_"$1" $OUT
|
dmcrypt_check "$DEV_NAME"_tstdev $OUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $PASSWORD | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 -i 1 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
echo -n -e " LUKS2:"
|
||||||
|
echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1
|
||||||
|
dmcrypt_check "$DEV_NAME"_tstdev $OUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# repeated device creation must return the same checksum
|
# repeated device creation must return the same checksum
|
||||||
echo $PASSWORD | $CRYPTSETUP create -h sha256 -c $1 -s 256 "$DEV_NAME"_"$1" /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
echo $PASSWORD | $CRYPTSETUP create -h sha256 -c $1 -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME >/dev/null 2>&1
|
||||||
if [ $? -eq 0 ] ; then
|
if [ $? -eq 0 ] ; then
|
||||||
echo -n -e " CHECKSUM:"
|
echo -n -e " CHECKSUM:"
|
||||||
dmcrypt_check_sum "$1" "$DEV_NAME"_"$1"
|
dmcrypt_check_sum "$1" "$DEV_NAME"_tstdev
|
||||||
fi
|
fi
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
@@ -154,4 +161,7 @@ for cipher in $CIPHERS ; do
|
|||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
dmcrypt xchacha12,aes-adiantum-plain64
|
||||||
|
dmcrypt xchacha20,aes-adiantum-plain64
|
||||||
|
|
||||||
cleanup
|
cleanup
|
||||||
|
|||||||
Reference in New Issue
Block a user