mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add support for Adiantum cipher mode.
This commit is contained in:
@@ -26,53 +26,58 @@
|
||||
|
||||
struct cipher_alg {
|
||||
const char *name;
|
||||
const char *mode;
|
||||
int blocksize;
|
||||
bool wrapped_key;
|
||||
};
|
||||
|
||||
/* FIXME: Getting block size should be dynamic from cipher backend. */
|
||||
static const struct cipher_alg cipher_algs[] = {
|
||||
{ "cipher_null", 16, false },
|
||||
{ "aes", 16, false },
|
||||
{ "serpent", 16, false },
|
||||
{ "twofish", 16, false },
|
||||
{ "anubis", 16, false },
|
||||
{ "blowfish", 8, false },
|
||||
{ "camellia", 16, false },
|
||||
{ "cast5", 8, false },
|
||||
{ "cast6", 16, false },
|
||||
{ "des", 8, false },
|
||||
{ "des3_ede", 8, false },
|
||||
{ "khazad", 8, false },
|
||||
{ "seed", 16, false },
|
||||
{ "tea", 8, false },
|
||||
{ "xtea", 8, false },
|
||||
{ "paes", 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||
{ NULL, 0, false }
|
||||
{ "cipher_null", NULL, 16, false },
|
||||
{ "aes", NULL, 16, false },
|
||||
{ "serpent", NULL, 16, false },
|
||||
{ "twofish", NULL, 16, false },
|
||||
{ "anubis", NULL, 16, false },
|
||||
{ "blowfish", NULL, 8, false },
|
||||
{ "camellia", NULL, 16, false },
|
||||
{ "cast5", NULL, 8, false },
|
||||
{ "cast6", NULL, 16, false },
|
||||
{ "des", NULL, 8, false },
|
||||
{ "des3_ede", NULL, 8, false },
|
||||
{ "khazad", NULL, 8, false },
|
||||
{ "seed", NULL, 16, false },
|
||||
{ "tea", NULL, 8, false },
|
||||
{ "xtea", NULL, 8, false },
|
||||
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||
{ "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;
|
||||
|
||||
while (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++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
/* ciphers */
|
||||
int crypt_cipher_blocksize(const char *name);
|
||||
int crypt_cipher_wrapped_key(const char *name);
|
||||
int crypt_cipher_ivsize(const char *name, const char *mode);
|
||||
int crypt_cipher_wrapped_key(const char *name, const char *mode);
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length);
|
||||
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));
|
||||
|
||||
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
|
||||
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
|
||||
if (ctx->iv_size < 8)
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
if (crypt_get_integrity_tag_size(cd) || !cipher)
|
||||
return 1;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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 0;
|
||||
|
||||
@@ -674,7 +674,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
if (r < 0)
|
||||
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);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1560,7 +1560,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
||||
}
|
||||
}
|
||||
|
||||
if ((!integrity || integrity_key_size) && !crypt_cipher_wrapped_key(cipher) &&
|
||||
if ((!integrity || integrity_key_size) && !crypt_cipher_wrapped_key(cipher, cipher_mode) &&
|
||||
!INTEGRITY_tag_size(cd, NULL, cipher, cipher_mode)) {
|
||||
r = LUKS_check_cipher(cd, volume_key_size - integrity_key_size,
|
||||
cipher, cipher_mode);
|
||||
@@ -2329,7 +2329,7 @@ int crypt_suspend(struct crypt_device *cd,
|
||||
key_desc = crypt_get_device_key_description(name);
|
||||
|
||||
/* 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);
|
||||
else
|
||||
r = dm_suspend_and_wipe_key(cd, name);
|
||||
@@ -3381,7 +3381,8 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
|
||||
/* 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 ||
|
||||
!LUKS2_keyslot_for_segment(&cd->u.luks2.hdr, keyslot, CRYPT_DEFAULT_SEGMENT)) {
|
||||
log_err(cd, _("Function not available in FIPS mode."));
|
||||
|
||||
@@ -73,7 +73,7 @@ dmcrypt_check() # device outstring
|
||||
dmremove $1
|
||||
}
|
||||
|
||||
dmcrypt_check_sum() # cipher device outstring
|
||||
dmcrypt_check_sum() # cipher device
|
||||
{
|
||||
EXPSUM="c036cbb7553a909f8b8877d4461924307f27ecb66cff928eeeafd569c3887e29"
|
||||
# Fill device with zeroes and reopen it
|
||||
@@ -99,28 +99,35 @@ dmcrypt()
|
||||
{
|
||||
OUT=$2
|
||||
[ -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
|
||||
echo -n -e "PLAIN:"
|
||||
dmcrypt_check "$DEV_NAME"_"$1" $OUT
|
||||
dmcrypt_check "$DEV_NAME"_tstdev $OUT
|
||||
else
|
||||
echo -n "[n/a]"
|
||||
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
|
||||
echo -n -e " LUKS:"
|
||||
echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_"$1" >/dev/null 2>&1
|
||||
dmcrypt_check "$DEV_NAME"_"$1" $OUT
|
||||
echo -n -e " LUKS1:"
|
||||
echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1
|
||||
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
|
||||
|
||||
# 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
|
||||
echo -n -e " CHECKSUM:"
|
||||
dmcrypt_check_sum "$1" "$DEV_NAME"_"$1"
|
||||
dmcrypt_check_sum "$1" "$DEV_NAME"_tstdev
|
||||
fi
|
||||
echo
|
||||
}
|
||||
@@ -154,4 +161,7 @@ for cipher in $CIPHERS ; do
|
||||
done
|
||||
done
|
||||
|
||||
dmcrypt xchacha12,aes-adiantum-plain64
|
||||
dmcrypt xchacha20,aes-adiantum-plain64
|
||||
|
||||
cleanup
|
||||
|
||||
Reference in New Issue
Block a user