Commit 1167e6b8 authored by Milan Broz's avatar Milan Broz

Add support for Adiantum cipher mode.

parent 1684fa8c
......@@ -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
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