diff --git a/lib/crypto_backend/Makemodule.am b/lib/crypto_backend/Makemodule.am index 894551ec..980eca5a 100644 --- a/lib/crypto_backend/Makemodule.am +++ b/lib/crypto_backend/Makemodule.am @@ -8,7 +8,8 @@ libcrypto_backend_la_SOURCES = \ lib/crypto_backend/crypto_storage.c \ lib/crypto_backend/pbkdf_check.c \ lib/crypto_backend/crc32.c \ - lib/crypto_backend/argon2_generic.c + lib/crypto_backend/argon2_generic.c \ + lib/crypto_backend/cipher_generic.c if CRYPTO_BACKEND_GCRYPT libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_gcrypt.c diff --git a/lib/crypto_backend/cipher_generic.c b/lib/crypto_backend/cipher_generic.c new file mode 100644 index 00000000..9b6acfd5 --- /dev/null +++ b/lib/crypto_backend/cipher_generic.c @@ -0,0 +1,78 @@ +/* + * Linux kernel cipher generic utilities + * + * Copyright (C) 2018, Red Hat, Inc. All rights reserved. + * Copyright (C) 2018, Milan Broz + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include "crypto_backend.h" + +struct cipher_alg { + const char *name; + 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 } +}; + +static const struct cipher_alg *_get_alg(const char *name) +{ + int i = 0; + + while (name && cipher_algs[i].name) { + if (!strcasecmp(name, cipher_algs[i].name)) + return &cipher_algs[i]; + i++; + } + return NULL; +} + +int crypt_cipher_blocksize(const char *name) +{ + const struct cipher_alg *ca = _get_alg(name); + + return ca ? ca->blocksize : -EINVAL; +} + +int crypt_cipher_wrapped_key(const char *name) +{ + const struct cipher_alg *ca = _get_alg(name); + + return ca ? (int)ca->wrapped_key : 0; +} diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h index 04c64e13..d99063af 100644 --- a/lib/crypto_backend/crypto_backend.h +++ b/lib/crypto_backend/crypto_backend.h @@ -100,6 +100,7 @@ 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_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); diff --git a/lib/crypto_backend/crypto_cipher_kernel.c b/lib/crypto_backend/crypto_cipher_kernel.c index 30ea3c1b..78a90919 100644 --- a/lib/crypto_backend/crypto_cipher_kernel.c +++ b/lib/crypto_backend/crypto_cipher_kernel.c @@ -44,50 +44,6 @@ struct crypt_cipher { int opfd; }; -struct cipher_alg { - const char *name; - int blocksize; -}; - -/* FIXME: Getting block size should be dynamic from cipher backend. */ -static struct cipher_alg cipher_algs[] = { - { "cipher_null", 16 }, - { "aes", 16 }, - { "serpent", 16 }, - { "twofish", 16 }, - { "anubis", 16 }, - { "blowfish", 8 }, - { "camellia", 16 }, - { "cast5", 8 }, - { "cast6", 16 }, - { "des", 8 }, - { "des3_ede", 8 }, - { "khazad", 8 }, - { "seed", 16 }, - { "tea", 8 }, - { "xtea", 8 }, - { NULL, 0 } -}; - -static struct cipher_alg *_get_alg(const char *name) -{ - int i = 0; - - while (name && cipher_algs[i].name) { - if (!strcasecmp(name, cipher_algs[i].name)) - return &cipher_algs[i]; - i++; - } - return NULL; -} - -int crypt_cipher_blocksize(const char *name) -{ - struct cipher_alg *ca = _get_alg(name); - - return ca ? ca->blocksize : -EINVAL; -} - /* * ciphers * @@ -236,12 +192,6 @@ void crypt_cipher_destroy(struct crypt_cipher *ctx) } #else /* ENABLE_AF_ALG */ - -int crypt_cipher_blocksize(const char *name) -{ - return -EINVAL; -} - int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, const char *mode, const void *buffer, size_t length) { diff --git a/lib/luks2/luks2_keyslot.c b/lib/luks2/luks2_keyslot.c index 8496ae94..e2dc9193 100644 --- a/lib/luks2/luks2_keyslot.c +++ b/lib/luks2/luks2_keyslot.c @@ -125,8 +125,8 @@ int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd) if (crypt_get_integrity_tag_size(cd) || !cipher) return 1; - /* protected AES (PAES) is a wrapped key scheme, not a block cipher */ - if (!strncmp("paes", cipher, 4)) + /* Wrapped key schemes cannot be used for keyslot encryption */ + if (crypt_cipher_wrapped_key(cipher)) return 1; return 0;