diff options
Diffstat (limited to 'crypto')
55 files changed, 1373 insertions, 1242 deletions
diff --git a/crypto/afalg.c b/crypto/afalg.c index 52a491d..246d067 100644 --- a/crypto/afalg.c +++ b/crypto/afalg.c @@ -66,13 +66,13 @@ qcrypto_afalg_socket_bind(const char *type, const char *name, return sbind; } -QCryptoAFAlg * +QCryptoAFAlgo * qcrypto_afalg_comm_alloc(const char *type, const char *name, Error **errp) { - QCryptoAFAlg *afalg; + QCryptoAFAlgo *afalg; - afalg = g_new0(QCryptoAFAlg, 1); + afalg = g_new0(QCryptoAFAlgo, 1); /* initialize crypto API socket */ afalg->opfd = -1; afalg->tfmfd = qcrypto_afalg_socket_bind(type, name, errp); @@ -93,7 +93,7 @@ error: return NULL; } -void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg) +void qcrypto_afalg_comm_free(QCryptoAFAlgo *afalg) { if (!afalg) { return; diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h index 5a2393f..3fdcc0f 100644 --- a/crypto/afalgpriv.h +++ b/crypto/afalgpriv.h @@ -30,9 +30,9 @@ #define ALG_OPTYPE_LEN 4 #define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len)) -typedef struct QCryptoAFAlg QCryptoAFAlg; +typedef struct QCryptoAFAlgo QCryptoAFAlgo; -struct QCryptoAFAlg { +struct QCryptoAFAlgo { QCryptoCipher base; int tfmfd; @@ -46,22 +46,22 @@ struct QCryptoAFAlg { * @type: the type of crypto operation * @name: the name of crypto operation * - * Allocate a QCryptoAFAlg object and bind itself to + * Allocate a QCryptoAFAlgo object and bind itself to * a AF_ALG socket. * * Returns: - * a new QCryptoAFAlg object, or NULL in error. + * a new QCryptoAFAlgo object, or NULL in error. */ -QCryptoAFAlg * +QCryptoAFAlgo * qcrypto_afalg_comm_alloc(const char *type, const char *name, Error **errp); /** * afalg_comm_free: - * @afalg: the QCryptoAFAlg object + * @afalg: the QCryptoAFAlgo object * * Free the @afalg. */ -void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg); +void qcrypto_afalg_comm_free(QCryptoAFAlgo *afalg); #endif diff --git a/crypto/afsplit.c b/crypto/afsplit.c index b1a5a20..b2e383a 100644 --- a/crypto/afsplit.c +++ b/crypto/afsplit.c @@ -40,7 +40,7 @@ static void qcrypto_afsplit_xor(size_t blocklen, } -static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash, +static int qcrypto_afsplit_hash(QCryptoHashAlgo hash, size_t blocklen, uint8_t *block, Error **errp) @@ -85,7 +85,7 @@ static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash, } -int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, +int qcrypto_afsplit_encode(QCryptoHashAlgo hash, size_t blocklen, uint32_t stripes, const uint8_t *in, @@ -117,7 +117,7 @@ int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, } -int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash, +int qcrypto_afsplit_decode(QCryptoHashAlgo hash, size_t blocklen, uint32_t stripes, const uint8_t *in, diff --git a/crypto/akcipher-gcrypt.c.inc b/crypto/akcipher-gcrypt.c.inc index abb1fb2..bcf030f 100644 --- a/crypto/akcipher-gcrypt.c.inc +++ b/crypto/akcipher-gcrypt.c.inc @@ -26,14 +26,14 @@ #include "crypto/akcipher.h" #include "crypto/random.h" #include "qapi/error.h" -#include "sysemu/cryptodev.h" +#include "system/cryptodev.h" #include "rsakey.h" typedef struct QCryptoGcryptRSA { QCryptoAkCipher akcipher; gcry_sexp_t key; - QCryptoRSAPaddingAlgorithm padding_alg; - QCryptoHashAlgorithm hash_alg; + QCryptoRSAPaddingAlgo padding_alg; + QCryptoHashAlgo hash_alg; } QCryptoGcryptRSA; static void qcrypto_gcrypt_rsa_free(QCryptoAkCipher *akcipher) @@ -59,7 +59,7 @@ QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts, Error **errp) { switch (opts->alg) { - case QCRYPTO_AKCIPHER_ALG_RSA: + case QCRYPTO_AK_CIPHER_ALGO_RSA: return (QCryptoAkCipher *)qcrypto_gcrypt_rsa_new( &opts->u.rsa, type, key, keylen, errp); @@ -85,7 +85,7 @@ static int qcrypto_gcrypt_parse_rsa_private_key( const uint8_t *key, size_t keylen, Error **errp) { g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse( - QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE, key, keylen, errp); + QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE, key, keylen, errp); gcry_mpi_t n = NULL, e = NULL, d = NULL, p = NULL, q = NULL, u = NULL; bool compute_mul_inv = false; int ret = -1; @@ -178,7 +178,7 @@ static int qcrypto_gcrypt_parse_rsa_public_key(QCryptoGcryptRSA *rsa, { g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse( - QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC, key, keylen, errp); + QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC, key, keylen, errp); gcry_mpi_t n = NULL, e = NULL; int ret = -1; gcry_error_t err; @@ -241,7 +241,7 @@ static int qcrypto_gcrypt_rsa_encrypt(QCryptoAkCipher *akcipher, err = gcry_sexp_build(&data_sexp, NULL, "(data (flags %s) (value %b))", - QCryptoRSAPaddingAlgorithm_str(rsa->padding_alg), + QCryptoRSAPaddingAlgo_str(rsa->padding_alg), in_len, in); if (gcry_err_code(err) != 0) { error_setg(errp, "Failed to build plaintext: %s/%s", @@ -263,7 +263,7 @@ static int qcrypto_gcrypt_rsa_encrypt(QCryptoAkCipher *akcipher, goto cleanup; } - if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) { + if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALGO_RAW) { cipher_mpi = gcry_sexp_nth_mpi(cipher_sexp_item, 1, GCRYMPI_FMT_USG); if (!cipher_mpi) { error_setg(errp, "Invalid ciphertext result"); @@ -332,7 +332,7 @@ static int qcrypto_gcrypt_rsa_decrypt(QCryptoAkCipher *akcipher, err = gcry_sexp_build(&cipher_sexp, NULL, "(enc-val (flags %s) (rsa (a %b) ))", - QCryptoRSAPaddingAlgorithm_str(rsa->padding_alg), + QCryptoRSAPaddingAlgo_str(rsa->padding_alg), in_len, in); if (gcry_err_code(err) != 0) { error_setg(errp, "Failed to build ciphertext: %s/%s", @@ -348,7 +348,7 @@ static int qcrypto_gcrypt_rsa_decrypt(QCryptoAkCipher *akcipher, } /* S-expression of plaintext: (value plaintext) */ - if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) { + if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALGO_RAW) { data_mpi = gcry_sexp_nth_mpi(data_sexp, 1, GCRYMPI_FMT_USG); if (!data_mpi) { error_setg(errp, "Invalid plaintext result"); @@ -410,14 +410,14 @@ static int qcrypto_gcrypt_rsa_sign(QCryptoAkCipher *akcipher, return ret; } - if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALG_PKCS1) { + if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALGO_PKCS1) { error_setg(errp, "Invalid padding %u", rsa->padding_alg); return ret; } err = gcry_sexp_build(&dgst_sexp, NULL, "(data (flags pkcs1) (hash %s %b))", - QCryptoHashAlgorithm_str(rsa->hash_alg), + QCryptoHashAlgo_str(rsa->hash_alg), in_len, in); if (gcry_err_code(err) != 0) { error_setg(errp, "Failed to build dgst: %s/%s", @@ -482,7 +482,7 @@ static int qcrypto_gcrypt_rsa_verify(QCryptoAkCipher *akcipher, return ret; } - if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALG_PKCS1) { + if (rsa->padding_alg != QCRYPTO_RSA_PADDING_ALGO_PKCS1) { error_setg(errp, "Invalid padding %u", rsa->padding_alg); return ret; } @@ -497,7 +497,7 @@ static int qcrypto_gcrypt_rsa_verify(QCryptoAkCipher *akcipher, err = gcry_sexp_build(&dgst_sexp, NULL, "(data (flags pkcs1) (hash %s %b))", - QCryptoHashAlgorithm_str(rsa->hash_alg), + QCryptoHashAlgo_str(rsa->hash_alg), in2_len, in2); if (gcry_err_code(err) != 0) { error_setg(errp, "Failed to build dgst: %s/%s", @@ -540,13 +540,13 @@ static QCryptoGcryptRSA *qcrypto_gcrypt_rsa_new( rsa->akcipher.driver = &gcrypt_rsa; switch (type) { - case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE: if (qcrypto_gcrypt_parse_rsa_private_key(rsa, key, keylen, errp) != 0) { goto error; } break; - case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC: if (qcrypto_gcrypt_parse_rsa_public_key(rsa, key, keylen, errp) != 0) { goto error; } @@ -568,17 +568,17 @@ error: bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts) { switch (opts->alg) { - case QCRYPTO_AKCIPHER_ALG_RSA: + case QCRYPTO_AK_CIPHER_ALGO_RSA: switch (opts->u.rsa.padding_alg) { - case QCRYPTO_RSA_PADDING_ALG_RAW: + case QCRYPTO_RSA_PADDING_ALGO_RAW: return true; - case QCRYPTO_RSA_PADDING_ALG_PKCS1: + case QCRYPTO_RSA_PADDING_ALGO_PKCS1: switch (opts->u.rsa.hash_alg) { - case QCRYPTO_HASH_ALG_MD5: - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA256: - case QCRYPTO_HASH_ALG_SHA512: + case QCRYPTO_HASH_ALGO_MD5: + case QCRYPTO_HASH_ALGO_SHA1: + case QCRYPTO_HASH_ALGO_SHA256: + case QCRYPTO_HASH_ALGO_SHA512: return true; default: diff --git a/crypto/akcipher-nettle.c.inc b/crypto/akcipher-nettle.c.inc index 02699e6..1d4bd69 100644 --- a/crypto/akcipher-nettle.c.inc +++ b/crypto/akcipher-nettle.c.inc @@ -26,15 +26,15 @@ #include "crypto/akcipher.h" #include "crypto/random.h" #include "qapi/error.h" -#include "sysemu/cryptodev.h" +#include "system/cryptodev.h" #include "rsakey.h" typedef struct QCryptoNettleRSA { QCryptoAkCipher akcipher; struct rsa_public_key pub; struct rsa_private_key priv; - QCryptoRSAPaddingAlgorithm padding_alg; - QCryptoHashAlgorithm hash_alg; + QCryptoRSAPaddingAlgo padding_alg; + QCryptoHashAlgo hash_alg; } QCryptoNettleRSA; static void qcrypto_nettle_rsa_free(QCryptoAkCipher *akcipher) @@ -61,7 +61,7 @@ QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts, Error **errp) { switch (opts->alg) { - case QCRYPTO_AKCIPHER_ALG_RSA: + case QCRYPTO_AK_CIPHER_ALGO_RSA: return qcrypto_nettle_rsa_new(&opts->u.rsa, type, key, keylen, errp); default: @@ -87,7 +87,7 @@ static int qcrypt_nettle_parse_rsa_private_key(QCryptoNettleRSA *rsa, Error **errp) { g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse( - QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE, key, keylen, errp); + QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE, key, keylen, errp); if (!rsa_key) { return -1; @@ -137,7 +137,7 @@ static int qcrypt_nettle_parse_rsa_public_key(QCryptoNettleRSA *rsa, Error **errp) { g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse( - QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC, key, keylen, errp); + QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC, key, keylen, errp); if (!rsa_key) { return -1; @@ -184,11 +184,11 @@ static int qcrypto_nettle_rsa_encrypt(QCryptoAkCipher *akcipher, /* Nettle do not support RSA encryption without any padding */ switch (rsa->padding_alg) { - case QCRYPTO_RSA_PADDING_ALG_RAW: + case QCRYPTO_RSA_PADDING_ALGO_RAW: error_setg(errp, "RSA with raw padding is not supported"); break; - case QCRYPTO_RSA_PADDING_ALG_PKCS1: + case QCRYPTO_RSA_PADDING_ALGO_PKCS1: mpz_init(c); if (rsa_encrypt(&rsa->pub, NULL, wrap_nettle_random_func, data_len, (uint8_t *)data, c) != 1) { @@ -223,11 +223,11 @@ static int qcrypto_nettle_rsa_decrypt(QCryptoAkCipher *akcipher, } switch (rsa->padding_alg) { - case QCRYPTO_RSA_PADDING_ALG_RAW: + case QCRYPTO_RSA_PADDING_ALGO_RAW: error_setg(errp, "RSA with raw padding is not supported"); break; - case QCRYPTO_RSA_PADDING_ALG_PKCS1: + case QCRYPTO_RSA_PADDING_ALGO_PKCS1: nettle_mpz_init_set_str_256_u(c, enc_len, enc); if (!rsa_decrypt(&rsa->priv, &data_len, (uint8_t *)data, c)) { error_setg(errp, "Failed to decrypt"); @@ -257,7 +257,7 @@ static int qcrypto_nettle_rsa_sign(QCryptoAkCipher *akcipher, * The RSA algorithm cannot be used for signature/verification * without padding. */ - if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) { + if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALGO_RAW) { error_setg(errp, "Try to make signature without padding"); return ret; } @@ -276,19 +276,19 @@ static int qcrypto_nettle_rsa_sign(QCryptoAkCipher *akcipher, mpz_init(s); switch (rsa->hash_alg) { - case QCRYPTO_HASH_ALG_MD5: + case QCRYPTO_HASH_ALGO_MD5: rv = rsa_md5_sign_digest(&rsa->priv, data, s); break; - case QCRYPTO_HASH_ALG_SHA1: + case QCRYPTO_HASH_ALGO_SHA1: rv = rsa_sha1_sign_digest(&rsa->priv, data, s); break; - case QCRYPTO_HASH_ALG_SHA256: + case QCRYPTO_HASH_ALGO_SHA256: rv = rsa_sha256_sign_digest(&rsa->priv, data, s); break; - case QCRYPTO_HASH_ALG_SHA512: + case QCRYPTO_HASH_ALGO_SHA512: rv = rsa_sha512_sign_digest(&rsa->priv, data, s); break; @@ -324,7 +324,7 @@ static int qcrypto_nettle_rsa_verify(QCryptoAkCipher *akcipher, * The RSA algorithm cannot be used for signature/verification * without padding. */ - if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) { + if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALGO_RAW) { error_setg(errp, "Try to verify signature without padding"); return ret; } @@ -341,19 +341,19 @@ static int qcrypto_nettle_rsa_verify(QCryptoAkCipher *akcipher, nettle_mpz_init_set_str_256_u(s, sig_len, sig); switch (rsa->hash_alg) { - case QCRYPTO_HASH_ALG_MD5: + case QCRYPTO_HASH_ALGO_MD5: rv = rsa_md5_verify_digest(&rsa->pub, data, s); break; - case QCRYPTO_HASH_ALG_SHA1: + case QCRYPTO_HASH_ALGO_SHA1: rv = rsa_sha1_verify_digest(&rsa->pub, data, s); break; - case QCRYPTO_HASH_ALG_SHA256: + case QCRYPTO_HASH_ALGO_SHA256: rv = rsa_sha256_verify_digest(&rsa->pub, data, s); break; - case QCRYPTO_HASH_ALG_SHA512: + case QCRYPTO_HASH_ALGO_SHA512: rv = rsa_sha512_verify_digest(&rsa->pub, data, s); break; @@ -397,13 +397,13 @@ static QCryptoAkCipher *qcrypto_nettle_rsa_new( rsa_private_key_init(&rsa->priv); switch (type) { - case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE: if (qcrypt_nettle_parse_rsa_private_key(rsa, key, keylen, errp) != 0) { goto error; } break; - case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC: if (qcrypt_nettle_parse_rsa_public_key(rsa, key, keylen, errp) != 0) { goto error; } @@ -425,21 +425,21 @@ error: bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts) { switch (opts->alg) { - case QCRYPTO_AKCIPHER_ALG_RSA: + case QCRYPTO_AK_CIPHER_ALGO_RSA: switch (opts->u.rsa.padding_alg) { - case QCRYPTO_RSA_PADDING_ALG_PKCS1: + case QCRYPTO_RSA_PADDING_ALGO_PKCS1: switch (opts->u.rsa.hash_alg) { - case QCRYPTO_HASH_ALG_MD5: - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA256: - case QCRYPTO_HASH_ALG_SHA512: + case QCRYPTO_HASH_ALGO_MD5: + case QCRYPTO_HASH_ALGO_SHA1: + case QCRYPTO_HASH_ALGO_SHA256: + case QCRYPTO_HASH_ALGO_SHA512: return true; default: return false; } - case QCRYPTO_RSA_PADDING_ALG_RAW: + case QCRYPTO_RSA_PADDING_ALGO_RAW: default: return false; } diff --git a/crypto/akcipher.c b/crypto/akcipher.c index e4bbc6e..0a0576b 100644 --- a/crypto/akcipher.c +++ b/crypto/akcipher.c @@ -115,7 +115,7 @@ int qcrypto_akcipher_export_p8info(const QCryptoAkCipherOptions *opts, Error **errp) { switch (opts->alg) { - case QCRYPTO_AKCIPHER_ALG_RSA: + case QCRYPTO_AK_CIPHER_ALGO_RSA: qcrypto_akcipher_rsakey_export_p8info(key, keylen, dst, dst_len); return 0; diff --git a/crypto/akcipherpriv.h b/crypto/akcipherpriv.h index 739f639..3b33e54 100644 --- a/crypto/akcipherpriv.h +++ b/crypto/akcipherpriv.h @@ -27,7 +27,7 @@ typedef struct QCryptoAkCipherDriver QCryptoAkCipherDriver; struct QCryptoAkCipher { - QCryptoAkCipherAlgorithm alg; + QCryptoAkCipherAlgo alg; QCryptoAkCipherKeyType type; int max_plaintext_len; int max_ciphertext_len; diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 5b777c1..0926ad2 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -33,6 +33,7 @@ #include "qemu/uuid.h" #include "qemu/bitmap.h" +#include "qemu/range.h" /* * Reference for the LUKS format implemented here is @@ -67,38 +68,38 @@ struct QCryptoBlockLUKSCipherNameMap { static const QCryptoBlockLUKSCipherSizeMap qcrypto_block_luks_cipher_size_map_aes[] = { - { 16, QCRYPTO_CIPHER_ALG_AES_128 }, - { 24, QCRYPTO_CIPHER_ALG_AES_192 }, - { 32, QCRYPTO_CIPHER_ALG_AES_256 }, + { 16, QCRYPTO_CIPHER_ALGO_AES_128 }, + { 24, QCRYPTO_CIPHER_ALGO_AES_192 }, + { 32, QCRYPTO_CIPHER_ALGO_AES_256 }, { 0, 0 }, }; static const QCryptoBlockLUKSCipherSizeMap qcrypto_block_luks_cipher_size_map_cast5[] = { - { 16, QCRYPTO_CIPHER_ALG_CAST5_128 }, + { 16, QCRYPTO_CIPHER_ALGO_CAST5_128 }, { 0, 0 }, }; static const QCryptoBlockLUKSCipherSizeMap qcrypto_block_luks_cipher_size_map_serpent[] = { - { 16, QCRYPTO_CIPHER_ALG_SERPENT_128 }, - { 24, QCRYPTO_CIPHER_ALG_SERPENT_192 }, - { 32, QCRYPTO_CIPHER_ALG_SERPENT_256 }, + { 16, QCRYPTO_CIPHER_ALGO_SERPENT_128 }, + { 24, QCRYPTO_CIPHER_ALGO_SERPENT_192 }, + { 32, QCRYPTO_CIPHER_ALGO_SERPENT_256 }, { 0, 0 }, }; static const QCryptoBlockLUKSCipherSizeMap qcrypto_block_luks_cipher_size_map_twofish[] = { - { 16, QCRYPTO_CIPHER_ALG_TWOFISH_128 }, - { 24, QCRYPTO_CIPHER_ALG_TWOFISH_192 }, - { 32, QCRYPTO_CIPHER_ALG_TWOFISH_256 }, + { 16, QCRYPTO_CIPHER_ALGO_TWOFISH_128 }, + { 24, QCRYPTO_CIPHER_ALGO_TWOFISH_192 }, + { 32, QCRYPTO_CIPHER_ALGO_TWOFISH_256 }, { 0, 0 }, }; #ifdef CONFIG_CRYPTO_SM4 static const QCryptoBlockLUKSCipherSizeMap qcrypto_block_luks_cipher_size_map_sm4[] = { - { 16, QCRYPTO_CIPHER_ALG_SM4}, + { 16, QCRYPTO_CIPHER_ALGO_SM4}, { 0, 0 }, }; #endif @@ -122,25 +123,25 @@ struct QCryptoBlockLUKS { QCryptoBlockLUKSHeader header; /* Main encryption algorithm used for encryption*/ - QCryptoCipherAlgorithm cipher_alg; + QCryptoCipherAlgo cipher_alg; /* Mode of encryption for the selected encryption algorithm */ QCryptoCipherMode cipher_mode; /* Initialization vector generation algorithm */ - QCryptoIVGenAlgorithm ivgen_alg; + QCryptoIVGenAlgo ivgen_alg; /* Hash algorithm used for IV generation*/ - QCryptoHashAlgorithm ivgen_hash_alg; + QCryptoHashAlgo ivgen_hash_alg; /* * Encryption algorithm used for IV generation. * Usually the same as main encryption algorithm */ - QCryptoCipherAlgorithm ivgen_cipher_alg; + QCryptoCipherAlgo ivgen_cipher_alg; /* Hash algorithm used in pbkdf2 function */ - QCryptoHashAlgorithm hash_alg; + QCryptoHashAlgo hash_alg; /* Name of the secret that was used to open the image */ char *secret; @@ -178,7 +179,7 @@ static int qcrypto_block_luks_cipher_name_lookup(const char *name, } static const char * -qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg, +qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgo alg, Error **errp) { const QCryptoBlockLUKSCipherNameMap *map = @@ -194,7 +195,7 @@ qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg, } error_setg(errp, "Algorithm '%s' not supported", - QCryptoCipherAlgorithm_str(alg)); + QCryptoCipherAlgo_str(alg)); return NULL; } @@ -222,13 +223,13 @@ static int qcrypto_block_luks_name_lookup(const char *name, #define qcrypto_block_luks_hash_name_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - &QCryptoHashAlgorithm_lookup, \ + &QCryptoHashAlgo_lookup, \ "Hash algorithm", \ errp) #define qcrypto_block_luks_ivgen_name_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - &QCryptoIVGenAlgorithm_lookup, \ + &QCryptoIVGenAlgo_lookup, \ "IV generator", \ errp) @@ -261,9 +262,9 @@ qcrypto_block_luks_has_format(const uint8_t *buf, * the cipher since that gets a key length matching the digest * size, not AES 128 with truncated digest as might be imagined */ -static QCryptoCipherAlgorithm -qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher, - QCryptoHashAlgorithm hash, +static QCryptoCipherAlgo +qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgo cipher, + QCryptoHashAlgo hash, Error **errp) { size_t digestlen = qcrypto_hash_digest_len(hash); @@ -273,54 +274,54 @@ qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher, } switch (cipher) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_256: if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_AES_128)) { - return QCRYPTO_CIPHER_ALG_AES_128; + QCRYPTO_CIPHER_ALGO_AES_128)) { + return QCRYPTO_CIPHER_ALGO_AES_128; } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_AES_192)) { - return QCRYPTO_CIPHER_ALG_AES_192; + QCRYPTO_CIPHER_ALGO_AES_192)) { + return QCRYPTO_CIPHER_ALGO_AES_192; } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_AES_256)) { - return QCRYPTO_CIPHER_ALG_AES_256; + QCRYPTO_CIPHER_ALGO_AES_256)) { + return QCRYPTO_CIPHER_ALGO_AES_256; } else { error_setg(errp, "No AES cipher with key size %zu available", digestlen); return 0; } break; - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: + case QCRYPTO_CIPHER_ALGO_SERPENT_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_192: + case QCRYPTO_CIPHER_ALGO_SERPENT_256: if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_SERPENT_128)) { - return QCRYPTO_CIPHER_ALG_SERPENT_128; + QCRYPTO_CIPHER_ALGO_SERPENT_128)) { + return QCRYPTO_CIPHER_ALGO_SERPENT_128; } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_SERPENT_192)) { - return QCRYPTO_CIPHER_ALG_SERPENT_192; + QCRYPTO_CIPHER_ALGO_SERPENT_192)) { + return QCRYPTO_CIPHER_ALGO_SERPENT_192; } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_SERPENT_256)) { - return QCRYPTO_CIPHER_ALG_SERPENT_256; + QCRYPTO_CIPHER_ALGO_SERPENT_256)) { + return QCRYPTO_CIPHER_ALGO_SERPENT_256; } else { error_setg(errp, "No Serpent cipher with key size %zu available", digestlen); return 0; } break; - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: + case QCRYPTO_CIPHER_ALGO_TWOFISH_128: + case QCRYPTO_CIPHER_ALGO_TWOFISH_192: + case QCRYPTO_CIPHER_ALGO_TWOFISH_256: if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_TWOFISH_128)) { - return QCRYPTO_CIPHER_ALG_TWOFISH_128; + QCRYPTO_CIPHER_ALGO_TWOFISH_128)) { + return QCRYPTO_CIPHER_ALGO_TWOFISH_128; } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_TWOFISH_192)) { - return QCRYPTO_CIPHER_ALG_TWOFISH_192; + QCRYPTO_CIPHER_ALGO_TWOFISH_192)) { + return QCRYPTO_CIPHER_ALGO_TWOFISH_192; } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_TWOFISH_256)) { - return QCRYPTO_CIPHER_ALG_TWOFISH_256; + QCRYPTO_CIPHER_ALGO_TWOFISH_256)) { + return QCRYPTO_CIPHER_ALGO_TWOFISH_256; } else { error_setg(errp, "No Twofish cipher with key size %zu available", digestlen); @@ -329,7 +330,7 @@ qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher, break; default: error_setg(errp, "Cipher %s not supported with essiv", - QCryptoCipherAlgorithm_str(cipher)); + QCryptoCipherAlgo_str(cipher)); return 0; } } @@ -572,7 +573,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, header_sectors, slot2->stripes); - if (start1 + len1 > start2 && start2 + len2 > start1) { + if (ranges_overlap(start1, len1, start2, len2)) { error_setg(errp, "Keyslots %zu and %zu are overlapping in the header", i, j); @@ -659,7 +660,7 @@ qcrypto_block_luks_parse_header(QCryptoBlockLUKS *luks, Error **errp) return -1; } - if (luks->ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { + if (luks->ivgen_alg == QCRYPTO_IV_GEN_ALGO_ESSIV) { if (!ivhash_name) { error_setg(errp, "Missing IV generator hash specification"); return -1; @@ -1321,20 +1322,20 @@ qcrypto_block_luks_create(QCryptoBlock *block, luks_opts.iter_time = QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS; } if (!luks_opts.has_cipher_alg) { - luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256; + luks_opts.cipher_alg = QCRYPTO_CIPHER_ALGO_AES_256; } if (!luks_opts.has_cipher_mode) { luks_opts.cipher_mode = QCRYPTO_CIPHER_MODE_XTS; } if (!luks_opts.has_ivgen_alg) { - luks_opts.ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64; + luks_opts.ivgen_alg = QCRYPTO_IV_GEN_ALGO_PLAIN64; } if (!luks_opts.has_hash_alg) { - luks_opts.hash_alg = QCRYPTO_HASH_ALG_SHA256; + luks_opts.hash_alg = QCRYPTO_HASH_ALGO_SHA256; } - if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { + if (luks_opts.ivgen_alg == QCRYPTO_IV_GEN_ALGO_ESSIV) { if (!luks_opts.has_ivgen_hash_alg) { - luks_opts.ivgen_hash_alg = QCRYPTO_HASH_ALG_SHA256; + luks_opts.ivgen_hash_alg = QCRYPTO_HASH_ALGO_SHA256; luks_opts.has_ivgen_hash_alg = true; } } @@ -1383,15 +1384,15 @@ qcrypto_block_luks_create(QCryptoBlock *block, } cipher_mode = QCryptoCipherMode_str(luks_opts.cipher_mode); - ivgen_alg = QCryptoIVGenAlgorithm_str(luks_opts.ivgen_alg); + ivgen_alg = QCryptoIVGenAlgo_str(luks_opts.ivgen_alg); if (luks_opts.has_ivgen_hash_alg) { - ivgen_hash_alg = QCryptoHashAlgorithm_str(luks_opts.ivgen_hash_alg); + ivgen_hash_alg = QCryptoHashAlgo_str(luks_opts.ivgen_hash_alg); cipher_mode_spec = g_strdup_printf("%s-%s:%s", cipher_mode, ivgen_alg, ivgen_hash_alg); } else { cipher_mode_spec = g_strdup_printf("%s-%s", cipher_mode, ivgen_alg); } - hash_alg = QCryptoHashAlgorithm_str(luks_opts.hash_alg); + hash_alg = QCryptoHashAlgo_str(luks_opts.hash_alg); if (strlen(cipher_alg) >= QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN) { @@ -1410,7 +1411,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, goto error; } - if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { + if (luks_opts.ivgen_alg == QCRYPTO_IV_GEN_ALGO_ESSIV) { luks->ivgen_cipher_alg = qcrypto_block_luks_essiv_cipher(luks_opts.cipher_alg, luks_opts.ivgen_hash_alg, @@ -1860,11 +1861,11 @@ qcrypto_block_luks_amend_options(QCryptoBlock *block, QCryptoBlockAmendOptionsLUKS *opts_luks = &options->u.luks; switch (opts_luks->state) { - case Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE_ACTIVE: + case QCRYPTO_BLOCK_LUKS_KEYSLOT_STATE_ACTIVE: return qcrypto_block_luks_amend_add_keyslot(block, readfunc, writefunc, opaque, opts_luks, force, errp); - case Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE_INACTIVE: + case QCRYPTO_BLOCK_LUKS_KEYSLOT_STATE_INACTIVE: return qcrypto_block_luks_amend_erase_keyslots(block, readfunc, writefunc, opaque, opts_luks, force, errp); @@ -1885,7 +1886,7 @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block, info->u.luks.cipher_alg = luks->cipher_alg; info->u.luks.cipher_mode = luks->cipher_mode; info->u.luks.ivgen_alg = luks->ivgen_alg; - if (info->u.luks.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { + if (info->u.luks.ivgen_alg == QCRYPTO_IV_GEN_ALGO_ESSIV) { info->u.luks.has_ivgen_hash_alg = true; info->u.luks.ivgen_hash_alg = luks->ivgen_hash_alg; } diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 42e9556..054078b 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -62,16 +62,16 @@ qcrypto_block_qcow_init(QCryptoBlock *block, memcpy(keybuf, password, MIN(len, sizeof(keybuf))); g_free(password); - block->niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128, + block->niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALGO_AES_128, QCRYPTO_CIPHER_MODE_CBC); - block->ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_PLAIN64, + block->ivgen = qcrypto_ivgen_new(QCRYPTO_IV_GEN_ALGO_PLAIN64, 0, 0, NULL, 0, errp); if (!block->ivgen) { ret = -ENOTSUP; goto fail; } - ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128, + ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALGO_AES_128, QCRYPTO_CIPHER_MODE_CBC, keybuf, G_N_ELEMENTS(keybuf), errp); diff --git a/crypto/block.c b/crypto/block.c index 3bcc427..96c83e6 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -26,8 +26,8 @@ #include "block-luks.h" static const QCryptoBlockDriver *qcrypto_block_drivers[] = { - [Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow, - [Q_CRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks, + [QCRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow, + [QCRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks, }; @@ -267,7 +267,7 @@ static void qcrypto_block_push_cipher(QCryptoBlock *block, int qcrypto_block_init_cipher(QCryptoBlock *block, - QCryptoCipherAlgorithm alg, + QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp) @@ -332,7 +332,7 @@ QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) } -QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block) +QCryptoHashAlgo qcrypto_block_get_kdf_hash(QCryptoBlock *block) { return block->kdfhash; } diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index b8f77cb..edf0b3a 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -33,7 +33,7 @@ struct QCryptoBlock { void *opaque; /* Cipher parameters */ - QCryptoCipherAlgorithm alg; + QCryptoCipherAlgo alg; QCryptoCipherMode mode; uint8_t *key; size_t nkey; @@ -44,7 +44,7 @@ struct QCryptoBlock { QCryptoIVGen *ivgen; QemuMutex mutex; - QCryptoHashAlgorithm kdfhash; + QCryptoHashAlgo kdfhash; size_t niv; uint64_t payload_offset; /* In bytes */ uint64_t sector_size; /* In bytes */ @@ -132,7 +132,7 @@ int qcrypto_block_encrypt_helper(QCryptoBlock *block, Error **errp); int qcrypto_block_init_cipher(QCryptoBlock *block, - QCryptoCipherAlgorithm alg, + QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp); diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c index 3df8fc5..4980d41 100644 --- a/crypto/cipher-afalg.c +++ b/crypto/cipher-afalg.c @@ -18,7 +18,7 @@ static char * -qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg, +qcrypto_afalg_cipher_format_name(QCryptoCipherAlgo alg, QCryptoCipherMode mode, Error **errp) { @@ -27,22 +27,22 @@ qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg, const char *mode_name; switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_256: alg_name = "aes"; break; - case QCRYPTO_CIPHER_ALG_CAST5_128: + case QCRYPTO_CIPHER_ALGO_CAST5_128: alg_name = "cast5"; break; - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: + case QCRYPTO_CIPHER_ALGO_SERPENT_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_192: + case QCRYPTO_CIPHER_ALGO_SERPENT_256: alg_name = "serpent"; break; - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: + case QCRYPTO_CIPHER_ALGO_TWOFISH_128: + case QCRYPTO_CIPHER_ALGO_TWOFISH_192: + case QCRYPTO_CIPHER_ALGO_TWOFISH_256: alg_name = "twofish"; break; @@ -60,12 +60,12 @@ qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg, static const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver; QCryptoCipher * -qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg, +qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp) { - QCryptoAFAlg *afalg; + QCryptoAFAlgo *afalg; size_t expect_niv; char *name; @@ -119,7 +119,7 @@ qcrypto_afalg_cipher_setiv(QCryptoCipher *cipher, const uint8_t *iv, size_t niv, Error **errp) { - QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base); + QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base); struct af_alg_iv *alg_iv; size_t expect_niv; @@ -143,7 +143,7 @@ qcrypto_afalg_cipher_setiv(QCryptoCipher *cipher, } static int -qcrypto_afalg_cipher_op(QCryptoAFAlg *afalg, +qcrypto_afalg_cipher_op(QCryptoAFAlgo *afalg, const void *in, void *out, size_t len, bool do_encrypt, Error **errp) @@ -202,7 +202,7 @@ qcrypto_afalg_cipher_encrypt(QCryptoCipher *cipher, const void *in, void *out, size_t len, Error **errp) { - QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base); + QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base); return qcrypto_afalg_cipher_op(afalg, in, out, len, true, errp); } @@ -212,14 +212,14 @@ qcrypto_afalg_cipher_decrypt(QCryptoCipher *cipher, const void *in, void *out, size_t len, Error **errp) { - QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base); + QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base); return qcrypto_afalg_cipher_op(afalg, in, out, len, false, errp); } static void qcrypto_afalg_comm_ctx_free(QCryptoCipher *cipher) { - QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base); + QCryptoAFAlgo *afalg = container_of(cipher, QCryptoAFAlgo, base); qcrypto_afalg_comm_free(afalg); } diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc deleted file mode 100644 index b409089..0000000 --- a/crypto/cipher-builtin.c.inc +++ /dev/null @@ -1,303 +0,0 @@ -/* - * QEMU Crypto cipher built-in algorithms - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library 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 library 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 library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "crypto/aes.h" - -typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext; -struct QCryptoCipherBuiltinAESContext { - AES_KEY enc; - AES_KEY dec; -}; - -typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES; -struct QCryptoCipherBuiltinAES { - QCryptoCipher base; - QCryptoCipherBuiltinAESContext key; - uint8_t iv[AES_BLOCK_SIZE]; -}; - - -static inline bool qcrypto_length_check(size_t len, size_t blocksize, - Error **errp) -{ - if (unlikely(len & (blocksize - 1))) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, blocksize); - return false; - } - return true; -} - -static void qcrypto_cipher_ctx_free(QCryptoCipher *cipher) -{ - g_free(cipher); -} - -static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - error_setg(errp, "Setting IV is not supported"); - return -1; -} - -static void do_aes_encrypt_ecb(const void *vctx, - size_t len, - uint8_t *out, - const uint8_t *in) -{ - const QCryptoCipherBuiltinAESContext *ctx = vctx; - - /* We have already verified that len % AES_BLOCK_SIZE == 0. */ - while (len) { - AES_encrypt(in, out, &ctx->enc); - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - len -= AES_BLOCK_SIZE; - } -} - -static void do_aes_decrypt_ecb(const void *vctx, - size_t len, - uint8_t *out, - const uint8_t *in) -{ - const QCryptoCipherBuiltinAESContext *ctx = vctx; - - /* We have already verified that len % AES_BLOCK_SIZE == 0. */ - while (len) { - AES_decrypt(in, out, &ctx->dec); - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - len -= AES_BLOCK_SIZE; - } -} - -static void do_aes_encrypt_cbc(const AES_KEY *key, - size_t len, - uint8_t *out, - const uint8_t *in, - uint8_t *ivec) -{ - uint8_t tmp[AES_BLOCK_SIZE]; - size_t n; - - /* We have already verified that len % AES_BLOCK_SIZE == 0. */ - while (len) { - for (n = 0; n < AES_BLOCK_SIZE; ++n) { - tmp[n] = in[n] ^ ivec[n]; - } - AES_encrypt(tmp, out, key); - memcpy(ivec, out, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } -} - -static void do_aes_decrypt_cbc(const AES_KEY *key, - size_t len, - uint8_t *out, - const uint8_t *in, - uint8_t *ivec) -{ - uint8_t tmp[AES_BLOCK_SIZE]; - size_t n; - - /* We have already verified that len % AES_BLOCK_SIZE == 0. */ - while (len) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(in, out, key); - for (n = 0; n < AES_BLOCK_SIZE; ++n) { - out[n] ^= ivec[n]; - } - memcpy(ivec, tmp, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } -} - -static int qcrypto_cipher_aes_encrypt_ecb(QCryptoCipher *cipher, - const void *in, void *out, - size_t len, Error **errp) -{ - QCryptoCipherBuiltinAES *ctx - = container_of(cipher, QCryptoCipherBuiltinAES, base); - - if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { - return -1; - } - do_aes_encrypt_ecb(&ctx->key, len, out, in); - return 0; -} - -static int qcrypto_cipher_aes_decrypt_ecb(QCryptoCipher *cipher, - const void *in, void *out, - size_t len, Error **errp) -{ - QCryptoCipherBuiltinAES *ctx - = container_of(cipher, QCryptoCipherBuiltinAES, base); - - if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { - return -1; - } - do_aes_decrypt_ecb(&ctx->key, len, out, in); - return 0; -} - -static int qcrypto_cipher_aes_encrypt_cbc(QCryptoCipher *cipher, - const void *in, void *out, - size_t len, Error **errp) -{ - QCryptoCipherBuiltinAES *ctx - = container_of(cipher, QCryptoCipherBuiltinAES, base); - - if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { - return -1; - } - do_aes_encrypt_cbc(&ctx->key.enc, len, out, in, ctx->iv); - return 0; -} - -static int qcrypto_cipher_aes_decrypt_cbc(QCryptoCipher *cipher, - const void *in, void *out, - size_t len, Error **errp) -{ - QCryptoCipherBuiltinAES *ctx - = container_of(cipher, QCryptoCipherBuiltinAES, base); - - if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { - return -1; - } - do_aes_decrypt_cbc(&ctx->key.dec, len, out, in, ctx->iv); - return 0; -} - -static int qcrypto_cipher_aes_setiv(QCryptoCipher *cipher, const uint8_t *iv, - size_t niv, Error **errp) -{ - QCryptoCipherBuiltinAES *ctx - = container_of(cipher, QCryptoCipherBuiltinAES, base); - - if (niv != AES_BLOCK_SIZE) { - error_setg(errp, "IV must be %d bytes not %zu", - AES_BLOCK_SIZE, niv); - return -1; - } - - memcpy(ctx->iv, iv, AES_BLOCK_SIZE); - return 0; -} - -static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_ecb = { - .cipher_encrypt = qcrypto_cipher_aes_encrypt_ecb, - .cipher_decrypt = qcrypto_cipher_aes_decrypt_ecb, - .cipher_setiv = qcrypto_cipher_no_setiv, - .cipher_free = qcrypto_cipher_ctx_free, -}; - -static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_cbc = { - .cipher_encrypt = qcrypto_cipher_aes_encrypt_cbc, - .cipher_decrypt = qcrypto_cipher_aes_decrypt_cbc, - .cipher_setiv = qcrypto_cipher_aes_setiv, - .cipher_free = qcrypto_cipher_ctx_free, -}; - -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode) -{ - switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - switch (mode) { - case QCRYPTO_CIPHER_MODE_ECB: - case QCRYPTO_CIPHER_MODE_CBC: - return true; - default: - return false; - } - break; - default: - return false; - } -} - -static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - const uint8_t *key, - size_t nkey, - Error **errp) -{ - if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { - return NULL; - } - - switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - { - QCryptoCipherBuiltinAES *ctx; - const QCryptoCipherDriver *drv; - - switch (mode) { - case QCRYPTO_CIPHER_MODE_ECB: - drv = &qcrypto_cipher_aes_driver_ecb; - break; - case QCRYPTO_CIPHER_MODE_CBC: - drv = &qcrypto_cipher_aes_driver_cbc; - break; - default: - goto bad_mode; - } - - ctx = g_new0(QCryptoCipherBuiltinAES, 1); - ctx->base.driver = drv; - - if (AES_set_encrypt_key(key, nkey * 8, &ctx->key.enc)) { - error_setg(errp, "Failed to set encryption key"); - goto error; - } - if (AES_set_decrypt_key(key, nkey * 8, &ctx->key.dec)) { - error_setg(errp, "Failed to set decryption key"); - goto error; - } - - return &ctx->base; - - error: - g_free(ctx); - return NULL; - } - - default: - error_setg(errp, - "Unsupported cipher algorithm %s", - QCryptoCipherAlgorithm_str(alg)); - return NULL; - } - - bad_mode: - error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_str(mode)); - return NULL; -} diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc index 4a83147..12eb9dd 100644 --- a/crypto/cipher-gcrypt.c.inc +++ b/crypto/cipher-gcrypt.c.inc @@ -20,33 +20,33 @@ #include <gcrypt.h> -static int qcrypto_cipher_alg_to_gcry_alg(QCryptoCipherAlgorithm alg) +static int qcrypto_cipher_alg_to_gcry_alg(QCryptoCipherAlgo alg) { switch (alg) { - case QCRYPTO_CIPHER_ALG_DES: + case QCRYPTO_CIPHER_ALGO_DES: return GCRY_CIPHER_DES; - case QCRYPTO_CIPHER_ALG_3DES: + case QCRYPTO_CIPHER_ALGO_3DES: return GCRY_CIPHER_3DES; - case QCRYPTO_CIPHER_ALG_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_128: return GCRY_CIPHER_AES128; - case QCRYPTO_CIPHER_ALG_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_192: return GCRY_CIPHER_AES192; - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_256: return GCRY_CIPHER_AES256; - case QCRYPTO_CIPHER_ALG_CAST5_128: + case QCRYPTO_CIPHER_ALGO_CAST5_128: return GCRY_CIPHER_CAST5; - case QCRYPTO_CIPHER_ALG_SERPENT_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_128: return GCRY_CIPHER_SERPENT128; - case QCRYPTO_CIPHER_ALG_SERPENT_192: + case QCRYPTO_CIPHER_ALGO_SERPENT_192: return GCRY_CIPHER_SERPENT192; - case QCRYPTO_CIPHER_ALG_SERPENT_256: + case QCRYPTO_CIPHER_ALGO_SERPENT_256: return GCRY_CIPHER_SERPENT256; - case QCRYPTO_CIPHER_ALG_TWOFISH_128: + case QCRYPTO_CIPHER_ALGO_TWOFISH_128: return GCRY_CIPHER_TWOFISH128; - case QCRYPTO_CIPHER_ALG_TWOFISH_256: + case QCRYPTO_CIPHER_ALGO_TWOFISH_256: return GCRY_CIPHER_TWOFISH; #ifdef CONFIG_CRYPTO_SM4 - case QCRYPTO_CIPHER_ALG_SM4: + case QCRYPTO_CIPHER_ALGO_SM4: return GCRY_CIPHER_SM4; #endif default: @@ -70,23 +70,23 @@ static int qcrypto_cipher_mode_to_gcry_mode(QCryptoCipherMode mode) } } -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, +bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, QCryptoCipherMode mode) { switch (alg) { - case QCRYPTO_CIPHER_ALG_DES: - case QCRYPTO_CIPHER_ALG_3DES: - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - case QCRYPTO_CIPHER_ALG_CAST5_128: - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: + case QCRYPTO_CIPHER_ALGO_DES: + case QCRYPTO_CIPHER_ALGO_3DES: + case QCRYPTO_CIPHER_ALGO_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_256: + case QCRYPTO_CIPHER_ALGO_CAST5_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_192: + case QCRYPTO_CIPHER_ALGO_SERPENT_256: + case QCRYPTO_CIPHER_ALGO_TWOFISH_128: + case QCRYPTO_CIPHER_ALGO_TWOFISH_256: #ifdef CONFIG_CRYPTO_SM4 - case QCRYPTO_CIPHER_ALG_SM4: + case QCRYPTO_CIPHER_ALGO_SM4: #endif break; default: @@ -228,7 +228,7 @@ static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = { .cipher_free = qcrypto_gcrypt_ctx_free, }; -static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, +static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, @@ -246,7 +246,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, gcryalg = qcrypto_cipher_alg_to_gcry_alg(alg); if (gcryalg == GCRY_CIPHER_NONE) { error_setg(errp, "Unsupported cipher algorithm %s", - QCryptoCipherAlgorithm_str(alg)); + QCryptoCipherAlgo_str(alg)); return NULL; } diff --git a/crypto/cipher-gnutls.c.inc b/crypto/cipher-gnutls.c.inc index d3e231c..b9450d4 100644 --- a/crypto/cipher-gnutls.c.inc +++ b/crypto/cipher-gnutls.c.inc @@ -27,7 +27,7 @@ #define QEMU_GNUTLS_XTS #endif -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, +bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, QCryptoCipherMode mode) { @@ -35,11 +35,11 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, case QCRYPTO_CIPHER_MODE_ECB: case QCRYPTO_CIPHER_MODE_CBC: switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - case QCRYPTO_CIPHER_ALG_DES: - case QCRYPTO_CIPHER_ALG_3DES: + case QCRYPTO_CIPHER_ALGO_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_256: + case QCRYPTO_CIPHER_ALGO_DES: + case QCRYPTO_CIPHER_ALGO_3DES: return true; default: return false; @@ -47,8 +47,8 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, #ifdef QEMU_GNUTLS_XTS case QCRYPTO_CIPHER_MODE_XTS: switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_256: return true; default: return false; @@ -229,7 +229,7 @@ static struct QCryptoCipherDriver gnutls_driver = { .cipher_free = qcrypto_gnutls_cipher_free, }; -static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, +static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, @@ -244,10 +244,10 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, #ifdef QEMU_GNUTLS_XTS case QCRYPTO_CIPHER_MODE_XTS: switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_128: galg = GNUTLS_CIPHER_AES_128_XTS; break; - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_256: galg = GNUTLS_CIPHER_AES_256_XTS; break; default: @@ -259,19 +259,19 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, case QCRYPTO_CIPHER_MODE_ECB: case QCRYPTO_CIPHER_MODE_CBC: switch (alg) { - case QCRYPTO_CIPHER_ALG_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_128: galg = GNUTLS_CIPHER_AES_128_CBC; break; - case QCRYPTO_CIPHER_ALG_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_192: galg = GNUTLS_CIPHER_AES_192_CBC; break; - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_256: galg = GNUTLS_CIPHER_AES_256_CBC; break; - case QCRYPTO_CIPHER_ALG_DES: + case QCRYPTO_CIPHER_ALGO_DES: galg = GNUTLS_CIPHER_DES_CBC; break; - case QCRYPTO_CIPHER_ALG_3DES: + case QCRYPTO_CIPHER_ALGO_3DES: galg = GNUTLS_CIPHER_3DES_CBC; break; default: @@ -284,7 +284,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, if (galg == GNUTLS_CIPHER_UNKNOWN) { error_setg(errp, "Unsupported cipher algorithm %s with %s mode", - QCryptoCipherAlgorithm_str(alg), + QCryptoCipherAlgo_str(alg), QCryptoCipherMode_str(mode)); return NULL; } @@ -310,8 +310,8 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, } } - if (alg == QCRYPTO_CIPHER_ALG_DES || - alg == QCRYPTO_CIPHER_ALG_3DES) + if (alg == QCRYPTO_CIPHER_ALGO_DES || + alg == QCRYPTO_CIPHER_ALGO_3DES) ctx->blocksize = 8; else ctx->blocksize = 16; diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc index 42b39e1..ae91363 100644 --- a/crypto/cipher-nettle.c.inc +++ b/crypto/cipher-nettle.c.inc @@ -454,24 +454,24 @@ DEFINE_ECB(qcrypto_nettle_sm4, sm4_encrypt_native, sm4_decrypt_native) #endif -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, +bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, QCryptoCipherMode mode) { switch (alg) { - case QCRYPTO_CIPHER_ALG_DES: - case QCRYPTO_CIPHER_ALG_3DES: - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - case QCRYPTO_CIPHER_ALG_CAST5_128: - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: + case QCRYPTO_CIPHER_ALGO_DES: + case QCRYPTO_CIPHER_ALGO_3DES: + case QCRYPTO_CIPHER_ALGO_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_256: + case QCRYPTO_CIPHER_ALGO_CAST5_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_192: + case QCRYPTO_CIPHER_ALGO_SERPENT_256: + case QCRYPTO_CIPHER_ALGO_TWOFISH_128: + case QCRYPTO_CIPHER_ALGO_TWOFISH_192: + case QCRYPTO_CIPHER_ALGO_TWOFISH_256: #ifdef CONFIG_CRYPTO_SM4 - case QCRYPTO_CIPHER_ALG_SM4: + case QCRYPTO_CIPHER_ALGO_SM4: #endif break; default: @@ -489,7 +489,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, } } -static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, +static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, @@ -510,7 +510,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, } switch (alg) { - case QCRYPTO_CIPHER_ALG_DES: + case QCRYPTO_CIPHER_ALGO_DES: { QCryptoNettleDES *ctx; const QCryptoCipherDriver *drv; @@ -525,8 +525,10 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, case QCRYPTO_CIPHER_MODE_CTR: drv = &qcrypto_nettle_des_driver_ctr; break; - default: + case QCRYPTO_CIPHER_MODE_XTS: goto bad_cipher_mode; + default: + g_assert_not_reached(); } ctx = g_new0(QCryptoNettleDES, 1); @@ -536,7 +538,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_3DES: + case QCRYPTO_CIPHER_ALGO_3DES: { QCryptoNettleDES3 *ctx; const QCryptoCipherDriver *drv; @@ -551,8 +553,10 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, case QCRYPTO_CIPHER_MODE_CTR: drv = &qcrypto_nettle_des3_driver_ctr; break; - default: + case QCRYPTO_CIPHER_MODE_XTS: goto bad_cipher_mode; + default: + g_assert_not_reached(); } ctx = g_new0(QCryptoNettleDES3, 1); @@ -561,7 +565,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_AES_128: + case QCRYPTO_CIPHER_ALGO_AES_128: { QCryptoNettleAES128 *ctx = g_new0(QCryptoNettleAES128, 1); @@ -590,7 +594,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_AES_192: + case QCRYPTO_CIPHER_ALGO_AES_192: { QCryptoNettleAES192 *ctx = g_new0(QCryptoNettleAES192, 1); @@ -619,7 +623,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_AES_256: + case QCRYPTO_CIPHER_ALGO_AES_256: { QCryptoNettleAES256 *ctx = g_new0(QCryptoNettleAES256, 1); @@ -648,7 +652,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_CAST5_128: + case QCRYPTO_CIPHER_ALGO_CAST5_128: { QCryptoNettleCAST128 *ctx; const QCryptoCipherDriver *drv; @@ -663,8 +667,10 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, case QCRYPTO_CIPHER_MODE_CTR: drv = &qcrypto_nettle_cast128_driver_ctr; break; - default: + case QCRYPTO_CIPHER_MODE_XTS: goto bad_cipher_mode; + default: + g_assert_not_reached(); } ctx = g_new0(QCryptoNettleCAST128, 1); @@ -674,9 +680,9 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: + case QCRYPTO_CIPHER_ALGO_SERPENT_128: + case QCRYPTO_CIPHER_ALGO_SERPENT_192: + case QCRYPTO_CIPHER_ALGO_SERPENT_256: { QCryptoNettleSerpent *ctx = g_new0(QCryptoNettleSerpent, 1); @@ -703,9 +709,9 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: + case QCRYPTO_CIPHER_ALGO_TWOFISH_128: + case QCRYPTO_CIPHER_ALGO_TWOFISH_192: + case QCRYPTO_CIPHER_ALGO_TWOFISH_256: { QCryptoNettleTwofish *ctx = g_new0(QCryptoNettleTwofish, 1); @@ -732,18 +738,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, return &ctx->base; } #ifdef CONFIG_CRYPTO_SM4 - case QCRYPTO_CIPHER_ALG_SM4: + case QCRYPTO_CIPHER_ALGO_SM4: { - QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1); + QCryptoNettleSm4 *ctx; + const QCryptoCipherDriver *drv; switch (mode) { case QCRYPTO_CIPHER_MODE_ECB: - ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb; + drv = &qcrypto_nettle_sm4_driver_ecb; break; - default: + case QCRYPTO_CIPHER_MODE_CBC: + case QCRYPTO_CIPHER_MODE_CTR: + case QCRYPTO_CIPHER_MODE_XTS: goto bad_cipher_mode; + default: + g_assert_not_reached(); } + ctx = g_new0(QCryptoNettleSm4, 1); + ctx->base.driver = drv; sm4_set_encrypt_key(&ctx->key[0], key); sm4_set_decrypt_key(&ctx->key[1], key); @@ -753,7 +766,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, default: error_setg(errp, "Unsupported cipher algorithm %s", - QCryptoCipherAlgorithm_str(alg)); + QCryptoCipherAlgo_str(alg)); return NULL; } diff --git a/crypto/cipher-stub.c.inc b/crypto/cipher-stub.c.inc new file mode 100644 index 0000000..1b7ea81 --- /dev/null +++ b/crypto/cipher-stub.c.inc @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * QEMU Crypto cipher impl stub + * + * Copyright (c) 2025 Red Hat, Inc. + * + */ + +bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, + QCryptoCipherMode mode) +{ + return false; +} + +static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgo alg, + QCryptoCipherMode mode, + const uint8_t *key, + size_t nkey, + Error **errp) +{ + if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { + return NULL; + } + + error_setg(errp, + "Unsupported cipher algorithm %s, no crypto library enabled in build", + QCryptoCipherAlgo_str(alg)); + return NULL; +} diff --git a/crypto/cipher.c b/crypto/cipher.c index 5f51276..229710f 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -25,39 +25,39 @@ #include "cipherpriv.h" -static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = { - [QCRYPTO_CIPHER_ALG_AES_128] = 16, - [QCRYPTO_CIPHER_ALG_AES_192] = 24, - [QCRYPTO_CIPHER_ALG_AES_256] = 32, - [QCRYPTO_CIPHER_ALG_DES] = 8, - [QCRYPTO_CIPHER_ALG_3DES] = 24, - [QCRYPTO_CIPHER_ALG_CAST5_128] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_192] = 24, - [QCRYPTO_CIPHER_ALG_SERPENT_256] = 32, - [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24, - [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32, +static const size_t alg_key_len[QCRYPTO_CIPHER_ALGO__MAX] = { + [QCRYPTO_CIPHER_ALGO_AES_128] = 16, + [QCRYPTO_CIPHER_ALGO_AES_192] = 24, + [QCRYPTO_CIPHER_ALGO_AES_256] = 32, + [QCRYPTO_CIPHER_ALGO_DES] = 8, + [QCRYPTO_CIPHER_ALGO_3DES] = 24, + [QCRYPTO_CIPHER_ALGO_CAST5_128] = 16, + [QCRYPTO_CIPHER_ALGO_SERPENT_128] = 16, + [QCRYPTO_CIPHER_ALGO_SERPENT_192] = 24, + [QCRYPTO_CIPHER_ALGO_SERPENT_256] = 32, + [QCRYPTO_CIPHER_ALGO_TWOFISH_128] = 16, + [QCRYPTO_CIPHER_ALGO_TWOFISH_192] = 24, + [QCRYPTO_CIPHER_ALGO_TWOFISH_256] = 32, #ifdef CONFIG_CRYPTO_SM4 - [QCRYPTO_CIPHER_ALG_SM4] = 16, + [QCRYPTO_CIPHER_ALGO_SM4] = 16, #endif }; -static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = { - [QCRYPTO_CIPHER_ALG_AES_128] = 16, - [QCRYPTO_CIPHER_ALG_AES_192] = 16, - [QCRYPTO_CIPHER_ALG_AES_256] = 16, - [QCRYPTO_CIPHER_ALG_DES] = 8, - [QCRYPTO_CIPHER_ALG_3DES] = 8, - [QCRYPTO_CIPHER_ALG_CAST5_128] = 8, - [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_192] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_256] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16, +static const size_t alg_block_len[QCRYPTO_CIPHER_ALGO__MAX] = { + [QCRYPTO_CIPHER_ALGO_AES_128] = 16, + [QCRYPTO_CIPHER_ALGO_AES_192] = 16, + [QCRYPTO_CIPHER_ALGO_AES_256] = 16, + [QCRYPTO_CIPHER_ALGO_DES] = 8, + [QCRYPTO_CIPHER_ALGO_3DES] = 8, + [QCRYPTO_CIPHER_ALGO_CAST5_128] = 8, + [QCRYPTO_CIPHER_ALGO_SERPENT_128] = 16, + [QCRYPTO_CIPHER_ALGO_SERPENT_192] = 16, + [QCRYPTO_CIPHER_ALGO_SERPENT_256] = 16, + [QCRYPTO_CIPHER_ALGO_TWOFISH_128] = 16, + [QCRYPTO_CIPHER_ALGO_TWOFISH_192] = 16, + [QCRYPTO_CIPHER_ALGO_TWOFISH_256] = 16, #ifdef CONFIG_CRYPTO_SM4 - [QCRYPTO_CIPHER_ALG_SM4] = 16, + [QCRYPTO_CIPHER_ALGO_SM4] = 16, #endif }; @@ -69,21 +69,21 @@ static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = { }; -size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg) +size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgo alg) { assert(alg < G_N_ELEMENTS(alg_key_len)); return alg_block_len[alg]; } -size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg) +size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgo alg) { assert(alg < G_N_ELEMENTS(alg_key_len)); return alg_key_len[alg]; } -size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg, +size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgo alg, QCryptoCipherMode mode) { if (alg >= G_N_ELEMENTS(alg_block_len)) { @@ -101,20 +101,20 @@ size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg, static bool -qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg, +qcrypto_cipher_validate_key_length(QCryptoCipherAlgo alg, QCryptoCipherMode mode, size_t nkey, Error **errp) { - if ((unsigned)alg >= QCRYPTO_CIPHER_ALG__MAX) { + if ((unsigned)alg >= QCRYPTO_CIPHER_ALGO__MAX) { error_setg(errp, "Cipher algorithm %d out of range", alg); return false; } if (mode == QCRYPTO_CIPHER_MODE_XTS) { - if (alg == QCRYPTO_CIPHER_ALG_DES || - alg == QCRYPTO_CIPHER_ALG_3DES) { + if (alg == QCRYPTO_CIPHER_ALGO_DES || + alg == QCRYPTO_CIPHER_ALGO_3DES) { error_setg(errp, "XTS mode not compatible with DES/3DES"); return false; } @@ -145,10 +145,10 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg, #elif defined CONFIG_GNUTLS_CRYPTO #include "cipher-gnutls.c.inc" #else -#include "cipher-builtin.c.inc" +#include "cipher-stub.c.inc" #endif -QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, +QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp) diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h index 3965278..64737ce 100644 --- a/crypto/cipherpriv.h +++ b/crypto/cipherpriv.h @@ -42,7 +42,7 @@ struct QCryptoCipherDriver { #include "afalgpriv.h" extern QCryptoCipher * -qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg, +qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgo alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp); diff --git a/crypto/der.c b/crypto/der.c index ebbecfc..8136752 100644 --- a/crypto/der.c +++ b/crypto/der.c @@ -408,19 +408,6 @@ void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, qcrypto_der_encode_prim(ctx, tag, src, src_len); } -void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx) -{ - uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, - QCRYPTO_DER_TAG_ENC_PRIM, - QCRYPTO_DER_TYPE_TAG_OCT_STR); - qcrypto_der_encode_cons_begin(ctx, tag); -} - -void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx) -{ - qcrypto_der_encode_cons_end(ctx); -} - size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx) { return ctx->root.dlen; diff --git a/crypto/der.h b/crypto/der.h index f4ba6da..bcfa4a2 100644 --- a/crypto/der.h +++ b/crypto/der.h @@ -243,28 +243,6 @@ void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, const uint8_t *src, size_t src_len); /** - * qcrypto_der_encode_octet_str_begin: - * @ctx: the encode context. - * - * Start encoding a octet string, All fields between - * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end - * are encoded as an octet string. This is useful when we need to encode a - * encoded SEQUENCE as OCTET STRING. - */ -void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx); - -/** - * qcrypto_der_encode_octet_str_end: - * @ctx: the encode context. - * - * Finish encoding a octet string, All fields between - * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end - * are encoded as an octet string. This is useful when we need to encode a - * encoded SEQUENCE as OCTET STRING. - */ -void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx); - -/** * qcrypto_der_encode_ctx_buffer_len: * @ctx: the encode context. * diff --git a/crypto/hash-afalg.c b/crypto/hash-afalg.c index 3ebea39..bd3fe3b 100644 --- a/crypto/hash-afalg.c +++ b/crypto/hash-afalg.c @@ -1,6 +1,7 @@ /* * QEMU Crypto af_alg-backend hash/hmac support * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD. * * Authors: @@ -20,7 +21,7 @@ #include "hmacpriv.h" static char * -qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg, +qcrypto_afalg_hash_format_name(QCryptoHashAlgo alg, bool is_hmac, Error **errp) { @@ -28,25 +29,25 @@ qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg, const char *alg_name; switch (alg) { - case QCRYPTO_HASH_ALG_MD5: + case QCRYPTO_HASH_ALGO_MD5: alg_name = "md5"; break; - case QCRYPTO_HASH_ALG_SHA1: + case QCRYPTO_HASH_ALGO_SHA1: alg_name = "sha1"; break; - case QCRYPTO_HASH_ALG_SHA224: + case QCRYPTO_HASH_ALGO_SHA224: alg_name = "sha224"; break; - case QCRYPTO_HASH_ALG_SHA256: + case QCRYPTO_HASH_ALGO_SHA256: alg_name = "sha256"; break; - case QCRYPTO_HASH_ALG_SHA384: + case QCRYPTO_HASH_ALGO_SHA384: alg_name = "sha384"; break; - case QCRYPTO_HASH_ALG_SHA512: + case QCRYPTO_HASH_ALGO_SHA512: alg_name = "sha512"; break; - case QCRYPTO_HASH_ALG_RIPEMD160: + case QCRYPTO_HASH_ALGO_RIPEMD160: alg_name = "rmd160"; break; @@ -58,18 +59,18 @@ qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg, if (is_hmac) { name = g_strdup_printf("hmac(%s)", alg_name); } else { - name = g_strdup_printf("%s", alg_name); + name = g_strdup(alg_name); } return name; } -static QCryptoAFAlg * -qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgorithm alg, +static QCryptoAFAlgo * +qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, bool is_hmac, Error **errp) { - QCryptoAFAlg *afalg; + QCryptoAFAlgo *afalg; char *name; name = qcrypto_afalg_hash_format_name(alg, is_hmac, errp); @@ -98,89 +99,160 @@ qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgorithm alg, return afalg; } -static QCryptoAFAlg * -qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, +static QCryptoAFAlgo * +qcrypto_afalg_hash_ctx_new(QCryptoHashAlgo alg, Error **errp) { return qcrypto_afalg_hash_hmac_ctx_new(alg, NULL, 0, false, errp); } -QCryptoAFAlg * -qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg, +QCryptoAFAlgo * +qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp) { return qcrypto_afalg_hash_hmac_ctx_new(alg, key, nkey, true, errp); } -static int -qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlg *hmac, - QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, uint8_t **result, - size_t *resultlen, - Error **errp) +static +QCryptoHash *qcrypto_afalg_hash_new(QCryptoHashAlgo alg, Error **errp) { - QCryptoAFAlg *afalg; - struct iovec outv; - int ret = 0; - bool is_hmac = (hmac != NULL) ? true : false; - const int expect_len = qcrypto_hash_digest_len(alg); + /* Check if hash algorithm is supported */ + char *alg_name = qcrypto_afalg_hash_format_name(alg, false, NULL); + QCryptoHash *hash; - if (*resultlen == 0) { - *resultlen = expect_len; - *result = g_new0(uint8_t, *resultlen); - } else if (*resultlen != expect_len) { - error_setg(errp, - "Result buffer size %zu is not match hash %d", - *resultlen, expect_len); - return -1; + if (alg_name == NULL) { + error_setg(errp, "Unknown hash algorithm %d", alg); + return NULL; } - if (is_hmac) { - afalg = hmac; - } else { - afalg = qcrypto_afalg_hash_ctx_new(alg, errp); - if (!afalg) { - return -1; - } + g_free(alg_name); + + hash = g_new(QCryptoHash, 1); + hash->alg = alg; + hash->opaque = qcrypto_afalg_hash_ctx_new(alg, errp); + if (!hash->opaque) { + free(hash); + return NULL; } + return hash; +} + +static +void qcrypto_afalg_hash_free(QCryptoHash *hash) +{ + QCryptoAFAlgo *ctx = hash->opaque; + + if (ctx) { + qcrypto_afalg_comm_free(ctx); + } + + g_free(hash); +} + +/** + * Send data to the kernel's crypto core. + * + * The more_data parameter is used to notify the crypto engine + * that this is an "update" operation, and that more data will + * be provided to calculate the final hash. + */ +static +int qcrypto_afalg_send_to_kernel(QCryptoAFAlgo *afalg, + const struct iovec *iov, + size_t niov, + bool more_data, + Error **errp) +{ + int ret = 0; + int flags = (more_data ? MSG_MORE : 0); + /* send data to kernel's crypto core */ - ret = iov_send_recv(afalg->opfd, iov, niov, - 0, iov_size(iov, niov), true); + ret = iov_send_recv_with_flags(afalg->opfd, flags, iov, niov, + 0, iov_size(iov, niov), true); if (ret < 0) { error_setg_errno(errp, errno, "Send data to afalg-core failed"); - goto out; + ret = -1; + } else { + /* No error, so return 0 */ + ret = 0; + } + + return ret; +} + +static +int qcrypto_afalg_recv_from_kernel(QCryptoAFAlgo *afalg, + QCryptoHashAlgo alg, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + struct iovec outv; + int ret; + const int expected_len = qcrypto_hash_digest_len(alg); + + if (*result_len == 0) { + *result_len = expected_len; + *result = g_new0(uint8_t, *result_len); + } else if (*result_len != expected_len) { + error_setg(errp, + "Result buffer size %zu is not match hash %d", + *result_len, expected_len); + return -1; } /* hash && get result */ outv.iov_base = *result; - outv.iov_len = *resultlen; + outv.iov_len = *result_len; ret = iov_send_recv(afalg->opfd, &outv, 1, 0, iov_size(&outv, 1), false); if (ret < 0) { error_setg_errno(errp, errno, "Recv result from afalg-core failed"); - } else { - ret = 0; + return -1; } -out: - if (!is_hmac) { - qcrypto_afalg_comm_free(afalg); - } - return ret; + return 0; +} + +static +int qcrypto_afalg_hash_update(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + return qcrypto_afalg_send_to_kernel((QCryptoAFAlgo *) hash->opaque, + iov, niov, true, errp); +} + +static +int qcrypto_afalg_hash_finalize(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + return qcrypto_afalg_recv_from_kernel((QCryptoAFAlgo *) hash->opaque, + hash->alg, result, result_len, errp); } static int -qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, uint8_t **result, - size_t *resultlen, - Error **errp) +qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlgo *hmac, + QCryptoHashAlgo alg, + const struct iovec *iov, + size_t niov, uint8_t **result, + size_t *resultlen, + Error **errp) { - return qcrypto_afalg_hash_hmac_bytesv(NULL, alg, iov, niov, result, - resultlen, errp); + int ret = 0; + + ret = qcrypto_afalg_send_to_kernel(hmac, iov, niov, false, errp); + if (ret == 0) { + ret = qcrypto_afalg_recv_from_kernel(hmac, alg, result, + resultlen, errp); + } + + return ret; } static int @@ -197,14 +269,17 @@ qcrypto_afalg_hmac_bytesv(QCryptoHmac *hmac, static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac *hmac) { - QCryptoAFAlg *afalg; + QCryptoAFAlgo *afalg; afalg = hmac->opaque; qcrypto_afalg_comm_free(afalg); } QCryptoHashDriver qcrypto_hash_afalg_driver = { - .hash_bytesv = qcrypto_afalg_hash_bytesv, + .hash_new = qcrypto_afalg_hash_new, + .hash_free = qcrypto_afalg_hash_free, + .hash_update = qcrypto_afalg_hash_update, + .hash_finalize = qcrypto_afalg_hash_finalize }; QCryptoHmacDriver qcrypto_hmac_afalg_driver = { diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c index 829e482..af61c4e 100644 --- a/crypto/hash-gcrypt.c +++ b/crypto/hash-gcrypt.c @@ -1,6 +1,7 @@ /* * QEMU Crypto hash algorithms * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -25,92 +26,115 @@ #include "hashpriv.h" -static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GCRY_MD_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GCRY_MD_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = GCRY_MD_SHA224, - [QCRYPTO_HASH_ALG_SHA256] = GCRY_MD_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = GCRY_MD_SHA384, - [QCRYPTO_HASH_ALG_SHA512] = GCRY_MD_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MD_RMD160, +static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GCRY_MD_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GCRY_MD_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GCRY_MD_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GCRY_MD_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GCRY_MD_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GCRY_MD_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GCRY_MD_RMD160, +#ifdef CONFIG_CRYPTO_SM3 + [QCRYPTO_HASH_ALGO_SM3] = GCRY_MD_SM3, +#endif }; -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) +gboolean qcrypto_hash_supports(QCryptoHashAlgo alg) { if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) && qcrypto_hash_alg_map[alg] != GCRY_MD_NONE) { - return true; + return gcry_md_test_algo(qcrypto_hash_alg_map[alg]) == 0; } return false; } - -static int -qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - uint8_t **result, - size_t *resultlen, - Error **errp) +static +QCryptoHash *qcrypto_gcrypt_hash_new(QCryptoHashAlgo alg, Error **errp) { - int i, ret; - gcry_md_hd_t md; - unsigned char *digest; - - if (!qcrypto_hash_supports(alg)) { - error_setg(errp, - "Unknown hash algorithm %d", - alg); - return -1; - } + QCryptoHash *hash; + gcry_error_t ret; - ret = gcry_md_open(&md, qcrypto_hash_alg_map[alg], 0); + hash = g_new(QCryptoHash, 1); + hash->alg = alg; + hash->opaque = g_new(gcry_md_hd_t, 1); - if (ret < 0) { + ret = gcry_md_open((gcry_md_hd_t *) hash->opaque, + qcrypto_hash_alg_map[alg], 0); + if (ret != 0) { error_setg(errp, "Unable to initialize hash algorithm: %s", gcry_strerror(ret)); - return -1; + g_free(hash->opaque); + g_free(hash); + return NULL; } + return hash; +} - for (i = 0; i < niov; i++) { - gcry_md_write(md, iov[i].iov_base, iov[i].iov_len); +static +void qcrypto_gcrypt_hash_free(QCryptoHash *hash) +{ + gcry_md_hd_t *ctx = hash->opaque; + + if (ctx) { + gcry_md_close(*ctx); + g_free(ctx); } - ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[alg]); - if (ret <= 0) { - error_setg(errp, - "Unable to get hash length: %s", - gcry_strerror(ret)); - goto error; + g_free(hash); +} + + +static +int qcrypto_gcrypt_hash_update(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + gcry_md_hd_t *ctx = hash->opaque; + + for (int i = 0; i < niov; i++) { + gcry_md_write(*ctx, iov[i].iov_base, iov[i].iov_len); } - if (*resultlen == 0) { - *resultlen = ret; - *result = g_new0(uint8_t, *resultlen); - } else if (*resultlen != ret) { - error_setg(errp, - "Result buffer size %zu is smaller than hash %d", - *resultlen, ret); - goto error; + + return 0; +} + +static +int qcrypto_gcrypt_hash_finalize(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + int ret; + unsigned char *digest; + gcry_md_hd_t *ctx = hash->opaque; + + ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]); + if (ret == 0) { + error_setg(errp, "Unable to get hash length"); + return -1; } - digest = gcry_md_read(md, 0); - if (!digest) { + if (*result_len == 0) { + *result_len = ret; + *result = g_new(uint8_t, *result_len); + } else if (*result_len != ret) { error_setg(errp, - "No digest produced"); - goto error; + "Result buffer size %zu is smaller than hash %d", + *result_len, ret); + return -1; } - memcpy(*result, digest, *resultlen); - gcry_md_close(md); + /* Digest is freed by gcry_md_close(), copy it */ + digest = gcry_md_read(*ctx, 0); + memcpy(*result, digest, *result_len); return 0; - - error: - gcry_md_close(md); - return -1; } - QCryptoHashDriver qcrypto_hash_lib_driver = { - .hash_bytesv = qcrypto_gcrypt_hash_bytesv, + .hash_new = qcrypto_gcrypt_hash_new, + .hash_update = qcrypto_gcrypt_hash_update, + .hash_finalize = qcrypto_gcrypt_hash_finalize, + .hash_free = qcrypto_gcrypt_hash_free, }; diff --git a/crypto/hash-glib.c b/crypto/hash-glib.c index 82de9db..809cef9 100644 --- a/crypto/hash-glib.c +++ b/crypto/hash-glib.c @@ -1,6 +1,7 @@ /* * QEMU Crypto hash algorithms * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -24,17 +25,17 @@ #include "hashpriv.h" -static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5, - [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = -1, - [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = -1, - [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = -1, +static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = G_CHECKSUM_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = G_CHECKSUM_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = -1, + [QCRYPTO_HASH_ALGO_SHA256] = G_CHECKSUM_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = G_CHECKSUM_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = G_CHECKSUM_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = -1, }; -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) +gboolean qcrypto_hash_supports(QCryptoHashAlgo alg) { if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) && qcrypto_hash_alg_map[alg] != -1) { @@ -43,58 +44,78 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) return false; } - -static int -qcrypto_glib_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - uint8_t **result, - size_t *resultlen, - Error **errp) +static +QCryptoHash *qcrypto_glib_hash_new(QCryptoHashAlgo alg, + Error **errp) { - int i, ret; - GChecksum *cs; + QCryptoHash *hash; - if (!qcrypto_hash_supports(alg)) { - error_setg(errp, - "Unknown hash algorithm %d", - alg); - return -1; + hash = g_new(QCryptoHash, 1); + hash->alg = alg; + hash->opaque = g_checksum_new(qcrypto_hash_alg_map[alg]); + + return hash; +} + +static +void qcrypto_glib_hash_free(QCryptoHash *hash) +{ + if (hash->opaque) { + g_checksum_free(hash->opaque); } - cs = g_checksum_new(qcrypto_hash_alg_map[alg]); + g_free(hash); +} + + +static +int qcrypto_glib_hash_update(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + GChecksum *ctx = hash->opaque; - for (i = 0; i < niov; i++) { - g_checksum_update(cs, iov[i].iov_base, iov[i].iov_len); + for (int i = 0; i < niov; i++) { + g_checksum_update(ctx, iov[i].iov_base, iov[i].iov_len); } - ret = g_checksum_type_get_length(qcrypto_hash_alg_map[alg]); + return 0; +} + +static +int qcrypto_glib_hash_finalize(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + int ret; + GChecksum *ctx = hash->opaque; + + ret = g_checksum_type_get_length(qcrypto_hash_alg_map[hash->alg]); if (ret < 0) { - error_setg(errp, "%s", - "Unable to get hash length"); - goto error; + error_setg(errp, "Unable to get hash length"); + *result_len = 0; + return -1; } - if (*resultlen == 0) { - *resultlen = ret; - *result = g_new0(uint8_t, *resultlen); - } else if (*resultlen != ret) { + + if (*result_len == 0) { + *result_len = ret; + *result = g_new(uint8_t, *result_len); + } else if (*result_len != ret) { error_setg(errp, "Result buffer size %zu is smaller than hash %d", - *resultlen, ret); - goto error; + *result_len, ret); + return -1; } - g_checksum_get_digest(cs, *result, resultlen); - - g_checksum_free(cs); + g_checksum_get_digest(ctx, *result, result_len); return 0; - - error: - g_checksum_free(cs); - return -1; } - QCryptoHashDriver qcrypto_hash_lib_driver = { - .hash_bytesv = qcrypto_glib_hash_bytesv, + .hash_new = qcrypto_glib_hash_new, + .hash_update = qcrypto_glib_hash_update, + .hash_finalize = qcrypto_glib_hash_finalize, + .hash_free = qcrypto_glib_hash_free, }; diff --git a/crypto/hash-gnutls.c b/crypto/hash-gnutls.c index 17911ac..99fbe82 100644 --- a/crypto/hash-gnutls.c +++ b/crypto/hash-gnutls.c @@ -1,6 +1,7 @@ /* * QEMU Crypto hash algorithms * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2021 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -25,17 +26,17 @@ #include "hashpriv.h" -static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = GNUTLS_DIG_SHA224, - [QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = GNUTLS_DIG_SHA384, - [QCRYPTO_HASH_ALG_SHA512] = GNUTLS_DIG_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = GNUTLS_DIG_RMD160, +static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GNUTLS_DIG_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GNUTLS_DIG_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GNUTLS_DIG_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GNUTLS_DIG_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GNUTLS_DIG_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GNUTLS_DIG_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GNUTLS_DIG_RMD160, }; -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) +gboolean qcrypto_hash_supports(QCryptoHashAlgo alg) { size_t i; const gnutls_digest_algorithm_t *algs; @@ -52,53 +53,93 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) return false; } - -static int -qcrypto_gnutls_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - uint8_t **result, - size_t *resultlen, - Error **errp) +static +QCryptoHash *qcrypto_gnutls_hash_new(QCryptoHashAlgo alg, Error **errp) { - int i, ret; - gnutls_hash_hd_t hash; - - if (!qcrypto_hash_supports(alg)) { - error_setg(errp, - "Unknown hash algorithm %d", - alg); - return -1; - } + QCryptoHash *hash; + int ret; - ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]); - if (*resultlen == 0) { - *resultlen = ret; - *result = g_new0(uint8_t, *resultlen); - } else if (*resultlen != ret) { - error_setg(errp, - "Result buffer size %zu is smaller than hash %d", - *resultlen, ret); - return -1; - } + hash = g_new(QCryptoHash, 1); + hash->alg = alg; + hash->opaque = g_new(gnutls_hash_hd_t, 1); - ret = gnutls_hash_init(&hash, qcrypto_hash_alg_map[alg]); + ret = gnutls_hash_init(hash->opaque, qcrypto_hash_alg_map[alg]); if (ret < 0) { error_setg(errp, "Unable to initialize hash algorithm: %s", gnutls_strerror(ret)); - return -1; + g_free(hash->opaque); + g_free(hash); + return NULL; } - for (i = 0; i < niov; i++) { - gnutls_hash(hash, iov[i].iov_base, iov[i].iov_len); + return hash; +} + +static +void qcrypto_gnutls_hash_free(QCryptoHash *hash) +{ + gnutls_hash_hd_t *ctx = hash->opaque; + + gnutls_hash_deinit(*ctx, NULL); + g_free(ctx); + g_free(hash); +} + + +static +int qcrypto_gnutls_hash_update(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + int ret = 0; + gnutls_hash_hd_t *ctx = hash->opaque; + + for (int i = 0; i < niov; i++) { + ret = gnutls_hash(*ctx, iov[i].iov_base, iov[i].iov_len); + if (ret != 0) { + error_setg(errp, "Failed to hash data: %s", + gnutls_strerror(ret)); + return -1; + } } - gnutls_hash_deinit(hash, *result); return 0; } +static +int qcrypto_gnutls_hash_finalize(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + gnutls_hash_hd_t *ctx = hash->opaque; + int ret; + + ret = gnutls_hash_get_len(qcrypto_hash_alg_map[hash->alg]); + if (ret == 0) { + error_setg(errp, "Unable to get hash length"); + return -1; + } + + if (*result_len == 0) { + *result_len = ret; + *result = g_new(uint8_t, *result_len); + } else if (*result_len != ret) { + error_setg(errp, + "Result buffer size %zu is smaller than hash %d", + *result_len, ret); + return -1; + } + + gnutls_hash_output(*ctx, *result); + return 0; +} QCryptoHashDriver qcrypto_hash_lib_driver = { - .hash_bytesv = qcrypto_gnutls_hash_bytesv, + .hash_new = qcrypto_gnutls_hash_new, + .hash_update = qcrypto_gnutls_hash_update, + .hash_finalize = qcrypto_gnutls_hash_finalize, + .hash_free = qcrypto_gnutls_hash_free, }; diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c index 1ca1a41..53f6830 100644 --- a/crypto/hash-nettle.c +++ b/crypto/hash-nettle.c @@ -1,6 +1,7 @@ /* * QEMU Crypto hash algorithms * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -25,6 +26,9 @@ #include <nettle/md5.h> #include <nettle/sha.h> #include <nettle/ripemd160.h> +#ifdef CONFIG_CRYPTO_SM3 +#include <nettle/sm3.h> +#endif typedef void (*qcrypto_nettle_init)(void *ctx); typedef void (*qcrypto_nettle_write)(void *ctx, @@ -42,6 +46,9 @@ union qcrypto_hash_ctx { struct sha384_ctx sha384; struct sha512_ctx sha512; struct ripemd160_ctx ripemd160; +#ifdef CONFIG_CRYPTO_SM3 + struct sm3_ctx sm3; +#endif }; struct qcrypto_hash_alg { @@ -50,51 +57,59 @@ struct qcrypto_hash_alg { qcrypto_nettle_result result; size_t len; } qcrypto_hash_alg_map[] = { - [QCRYPTO_HASH_ALG_MD5] = { + [QCRYPTO_HASH_ALGO_MD5] = { .init = (qcrypto_nettle_init)md5_init, .write = (qcrypto_nettle_write)md5_update, .result = (qcrypto_nettle_result)md5_digest, .len = MD5_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA1] = { + [QCRYPTO_HASH_ALGO_SHA1] = { .init = (qcrypto_nettle_init)sha1_init, .write = (qcrypto_nettle_write)sha1_update, .result = (qcrypto_nettle_result)sha1_digest, .len = SHA1_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA224] = { + [QCRYPTO_HASH_ALGO_SHA224] = { .init = (qcrypto_nettle_init)sha224_init, .write = (qcrypto_nettle_write)sha224_update, .result = (qcrypto_nettle_result)sha224_digest, .len = SHA224_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA256] = { + [QCRYPTO_HASH_ALGO_SHA256] = { .init = (qcrypto_nettle_init)sha256_init, .write = (qcrypto_nettle_write)sha256_update, .result = (qcrypto_nettle_result)sha256_digest, .len = SHA256_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA384] = { + [QCRYPTO_HASH_ALGO_SHA384] = { .init = (qcrypto_nettle_init)sha384_init, .write = (qcrypto_nettle_write)sha384_update, .result = (qcrypto_nettle_result)sha384_digest, .len = SHA384_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA512] = { + [QCRYPTO_HASH_ALGO_SHA512] = { .init = (qcrypto_nettle_init)sha512_init, .write = (qcrypto_nettle_write)sha512_update, .result = (qcrypto_nettle_result)sha512_digest, .len = SHA512_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_RIPEMD160] = { + [QCRYPTO_HASH_ALGO_RIPEMD160] = { .init = (qcrypto_nettle_init)ripemd160_init, .write = (qcrypto_nettle_write)ripemd160_update, .result = (qcrypto_nettle_result)ripemd160_digest, .len = RIPEMD160_DIGEST_SIZE, }, +#ifdef CONFIG_CRYPTO_SM3 + [QCRYPTO_HASH_ALGO_SM3] = { + .init = (qcrypto_nettle_init)sm3_init, + .write = (qcrypto_nettle_write)sm3_update, + .result = (qcrypto_nettle_result)sm3_digest, + .len = SM3_DIGEST_SIZE, + }, +#endif }; -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) +gboolean qcrypto_hash_supports(QCryptoHashAlgo alg) { if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) && qcrypto_hash_alg_map[alg].init != NULL) { @@ -103,59 +118,72 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) return false; } +static +QCryptoHash *qcrypto_nettle_hash_new(QCryptoHashAlgo alg, Error **errp) +{ + QCryptoHash *hash; + + hash = g_new(QCryptoHash, 1); + hash->alg = alg; + hash->opaque = g_new(union qcrypto_hash_ctx, 1); + + qcrypto_hash_alg_map[alg].init(hash->opaque); + return hash; +} -static int -qcrypto_nettle_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - uint8_t **result, - size_t *resultlen, - Error **errp) +static +void qcrypto_nettle_hash_free(QCryptoHash *hash) { - size_t i; - union qcrypto_hash_ctx ctx; + union qcrypto_hash_ctx *ctx = hash->opaque; - if (!qcrypto_hash_supports(alg)) { - error_setg(errp, - "Unknown hash algorithm %d", - alg); - return -1; - } + g_free(ctx); + g_free(hash); +} - qcrypto_hash_alg_map[alg].init(&ctx); - - for (i = 0; i < niov; i++) { - /* Some versions of nettle have functions - * declared with 'int' instead of 'size_t' - * so to be safe avoid writing more than - * UINT_MAX bytes at a time - */ - size_t len = iov[i].iov_len; - uint8_t *base = iov[i].iov_base; - while (len) { - size_t shortlen = MIN(len, UINT_MAX); - qcrypto_hash_alg_map[alg].write(&ctx, len, base); - len -= shortlen; - base += len; - } +static +int qcrypto_nettle_hash_update(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + union qcrypto_hash_ctx *ctx = hash->opaque; + + for (int i = 0; i < niov; i++) { + qcrypto_hash_alg_map[hash->alg].write(ctx, + iov[i].iov_len, + iov[i].iov_base); } - if (*resultlen == 0) { - *resultlen = qcrypto_hash_alg_map[alg].len; - *result = g_new0(uint8_t, *resultlen); - } else if (*resultlen != qcrypto_hash_alg_map[alg].len) { + return 0; +} + +static +int qcrypto_nettle_hash_finalize(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + union qcrypto_hash_ctx *ctx = hash->opaque; + int ret = qcrypto_hash_alg_map[hash->alg].len; + + if (*result_len == 0) { + *result_len = ret; + *result = g_new(uint8_t, *result_len); + } else if (*result_len != ret) { error_setg(errp, - "Result buffer size %zu is smaller than hash %zu", - *resultlen, qcrypto_hash_alg_map[alg].len); + "Result buffer size %zu is smaller than hash %d", + *result_len, ret); return -1; } - qcrypto_hash_alg_map[alg].result(&ctx, *resultlen, *result); + qcrypto_hash_alg_map[hash->alg].result(ctx, *result_len, *result); return 0; } - QCryptoHashDriver qcrypto_hash_lib_driver = { - .hash_bytesv = qcrypto_nettle_hash_bytesv, + .hash_new = qcrypto_nettle_hash_new, + .hash_update = qcrypto_nettle_hash_update, + .hash_finalize = qcrypto_nettle_hash_finalize, + .hash_free = qcrypto_nettle_hash_free, }; diff --git a/crypto/hash.c b/crypto/hash.c index b0f8228..7513769 100644 --- a/crypto/hash.c +++ b/crypto/hash.c @@ -1,6 +1,7 @@ /* * QEMU Crypto hash algorithms * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2015 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -19,53 +20,53 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" +#include "qapi-types-crypto.h" #include "crypto/hash.h" #include "hashpriv.h" -static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = 16, - [QCRYPTO_HASH_ALG_SHA1] = 20, - [QCRYPTO_HASH_ALG_SHA224] = 28, - [QCRYPTO_HASH_ALG_SHA256] = 32, - [QCRYPTO_HASH_ALG_SHA384] = 48, - [QCRYPTO_HASH_ALG_SHA512] = 64, - [QCRYPTO_HASH_ALG_RIPEMD160] = 20, +static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = QCRYPTO_HASH_DIGEST_LEN_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = QCRYPTO_HASH_DIGEST_LEN_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = QCRYPTO_HASH_DIGEST_LEN_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = QCRYPTO_HASH_DIGEST_LEN_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = QCRYPTO_HASH_DIGEST_LEN_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = QCRYPTO_HASH_DIGEST_LEN_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = QCRYPTO_HASH_DIGEST_LEN_RIPEMD160, +#ifdef CONFIG_CRYPTO_SM3 + [QCRYPTO_HASH_ALGO_SM3] = QCRYPTO_HASH_DIGEST_LEN_SM3, +#endif }; -size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg) +size_t qcrypto_hash_digest_len(QCryptoHashAlgo alg) { assert(alg < G_N_ELEMENTS(qcrypto_hash_alg_size)); return qcrypto_hash_alg_size[alg]; } -int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg, +int qcrypto_hash_bytesv(QCryptoHashAlgo alg, const struct iovec *iov, size_t niov, uint8_t **result, size_t *resultlen, Error **errp) { -#ifdef CONFIG_AF_ALG - int ret; - /* - * TODO: - * Maybe we should treat some afalg errors as fatal - */ - ret = qcrypto_hash_afalg_driver.hash_bytesv(alg, iov, niov, - result, resultlen, - NULL); - if (ret == 0) { - return ret; + g_autoptr(QCryptoHash) ctx = qcrypto_hash_new(alg, errp); + + if (!ctx) { + return -1; + } + + if (qcrypto_hash_updatev(ctx, iov, niov, errp) < 0 || + qcrypto_hash_finalize_bytes(ctx, result, resultlen, errp) < 0) { + return -1; } -#endif - return qcrypto_hash_lib_driver.hash_bytesv(alg, iov, niov, - result, resultlen, - errp); + return 0; } -int qcrypto_hash_bytes(QCryptoHashAlgorithm alg, +int qcrypto_hash_bytes(QCryptoHashAlgo alg, const char *buf, size_t len, uint8_t **result, @@ -77,33 +78,134 @@ int qcrypto_hash_bytes(QCryptoHashAlgorithm alg, return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp); } +int qcrypto_hash_updatev(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp) +{ + QCryptoHashDriver *drv = hash->driver; + + return drv->hash_update(hash, iov, niov, errp); +} + +int qcrypto_hash_update(QCryptoHash *hash, + const char *buf, + size_t len, + Error **errp) +{ + struct iovec iov = { .iov_base = (char *)buf, .iov_len = len }; + + return qcrypto_hash_updatev(hash, &iov, 1, errp); +} + +QCryptoHash *qcrypto_hash_new(QCryptoHashAlgo alg, Error **errp) +{ + QCryptoHash *hash = NULL; + + if (!qcrypto_hash_supports(alg)) { + error_setg(errp, "Unsupported hash algorithm %s", + QCryptoHashAlgo_str(alg)); + return NULL; + } + +#ifdef CONFIG_AF_ALG + hash = qcrypto_hash_afalg_driver.hash_new(alg, NULL); + if (hash) { + hash->driver = &qcrypto_hash_afalg_driver; + return hash; + } +#endif + + hash = qcrypto_hash_lib_driver.hash_new(alg, errp); + if (!hash) { + return NULL; + } + + hash->driver = &qcrypto_hash_lib_driver; + return hash; +} + +void qcrypto_hash_free(QCryptoHash *hash) +{ + QCryptoHashDriver *drv; + + if (hash) { + drv = hash->driver; + drv->hash_free(hash); + } +} + +int qcrypto_hash_finalize_bytes(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp) +{ + QCryptoHashDriver *drv = hash->driver; + + return drv->hash_finalize(hash, result, result_len, errp); +} + static const char hex[] = "0123456789abcdef"; -int qcrypto_hash_digestv(QCryptoHashAlgorithm alg, +int qcrypto_hash_finalize_digest(QCryptoHash *hash, + char **digest, + Error **errp) +{ + int ret; + g_autofree uint8_t *result = NULL; + size_t resultlen = 0; + size_t i; + + ret = qcrypto_hash_finalize_bytes(hash, &result, &resultlen, errp); + if (ret == 0) { + *digest = g_new0(char, (resultlen * 2) + 1); + for (i = 0 ; i < resultlen ; i++) { + (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf]; + (*digest)[(i * 2) + 1] = hex[result[i] & 0xf]; + } + (*digest)[resultlen * 2] = '\0'; + } + + return ret; +} + +int qcrypto_hash_finalize_base64(QCryptoHash *hash, + char **base64, + Error **errp) +{ + int ret; + g_autofree uint8_t *result = NULL; + size_t resultlen = 0; + + ret = qcrypto_hash_finalize_bytes(hash, &result, &resultlen, errp); + if (ret == 0) { + *base64 = g_base64_encode(result, resultlen); + } + + return ret; +} + +int qcrypto_hash_digestv(QCryptoHashAlgo alg, const struct iovec *iov, size_t niov, char **digest, Error **errp) { - uint8_t *result = NULL; - size_t resultlen = 0; - size_t i; + g_autoptr(QCryptoHash) ctx = qcrypto_hash_new(alg, errp); - if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) { + if (!ctx) { return -1; } - *digest = g_new0(char, (resultlen * 2) + 1); - for (i = 0 ; i < resultlen ; i++) { - (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf]; - (*digest)[(i * 2) + 1] = hex[result[i] & 0xf]; + if (qcrypto_hash_updatev(ctx, iov, niov, errp) < 0 || + qcrypto_hash_finalize_digest(ctx, digest, errp) < 0) { + return -1; } - (*digest)[resultlen * 2] = '\0'; - g_free(result); + return 0; } -int qcrypto_hash_digest(QCryptoHashAlgorithm alg, +int qcrypto_hash_digest(QCryptoHashAlgo alg, const char *buf, size_t len, char **digest, @@ -114,25 +216,27 @@ int qcrypto_hash_digest(QCryptoHashAlgorithm alg, return qcrypto_hash_digestv(alg, &iov, 1, digest, errp); } -int qcrypto_hash_base64v(QCryptoHashAlgorithm alg, +int qcrypto_hash_base64v(QCryptoHashAlgo alg, const struct iovec *iov, size_t niov, char **base64, Error **errp) { - uint8_t *result = NULL; - size_t resultlen = 0; + g_autoptr(QCryptoHash) ctx = qcrypto_hash_new(alg, errp); + + if (!ctx) { + return -1; + } - if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) { + if (qcrypto_hash_updatev(ctx, iov, niov, errp) < 0 || + qcrypto_hash_finalize_base64(ctx, base64, errp) < 0) { return -1; } - *base64 = g_base64_encode(result, resultlen); - g_free(result); return 0; } -int qcrypto_hash_base64(QCryptoHashAlgorithm alg, +int qcrypto_hash_base64(QCryptoHashAlgo alg, const char *buf, size_t len, char **base64, diff --git a/crypto/hashpriv.h b/crypto/hashpriv.h index cee26cc..83b9256 100644 --- a/crypto/hashpriv.h +++ b/crypto/hashpriv.h @@ -1,6 +1,7 @@ /* * QEMU Crypto hash driver supports * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD. * * Authors: @@ -15,15 +16,21 @@ #ifndef QCRYPTO_HASHPRIV_H #define QCRYPTO_HASHPRIV_H +#include "crypto/hash.h" + typedef struct QCryptoHashDriver QCryptoHashDriver; struct QCryptoHashDriver { - int (*hash_bytesv)(QCryptoHashAlgorithm alg, + QCryptoHash *(*hash_new)(QCryptoHashAlgo alg, Error **errp); + int (*hash_update)(QCryptoHash *hash, const struct iovec *iov, size_t niov, - uint8_t **result, - size_t *resultlen, Error **errp); + int (*hash_finalize)(QCryptoHash *hash, + uint8_t **result, + size_t *resultlen, + Error **errp); + void (*hash_free)(QCryptoHash *hash); }; extern QCryptoHashDriver qcrypto_hash_lib_driver; diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c index 0c6f979..5273086 100644 --- a/crypto/hmac-gcrypt.c +++ b/crypto/hmac-gcrypt.c @@ -18,14 +18,17 @@ #include "hmacpriv.h" #include <gcrypt.h> -static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GCRY_MAC_HMAC_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GCRY_MAC_HMAC_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = GCRY_MAC_HMAC_SHA224, - [QCRYPTO_HASH_ALG_SHA256] = GCRY_MAC_HMAC_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = GCRY_MAC_HMAC_SHA384, - [QCRYPTO_HASH_ALG_SHA512] = GCRY_MAC_HMAC_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MAC_HMAC_RMD160, +static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GCRY_MAC_HMAC_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GCRY_MAC_HMAC_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GCRY_MAC_HMAC_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GCRY_MAC_HMAC_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GCRY_MAC_HMAC_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GCRY_MAC_HMAC_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GCRY_MAC_HMAC_RMD160, +#ifdef CONFIG_CRYPTO_SM3 + [QCRYPTO_HASH_ALGO_SM3] = GCRY_MAC_HMAC_SM3, +#endif }; typedef struct QCryptoHmacGcrypt QCryptoHmacGcrypt; @@ -33,17 +36,17 @@ struct QCryptoHmacGcrypt { gcry_mac_hd_t handle; }; -bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +bool qcrypto_hmac_supports(QCryptoHashAlgo alg) { if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && qcrypto_hmac_alg_map[alg] != GCRY_MAC_NONE) { - return true; + return gcry_mac_test_algo(qcrypto_hmac_alg_map[alg]) == 0; } return false; } -void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, +void *qcrypto_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp) { @@ -52,7 +55,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_str(alg)); + QCryptoHashAlgo_str(alg)); return NULL; } diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c index 509bbc7..ea80c8d 100644 --- a/crypto/hmac-glib.c +++ b/crypto/hmac-glib.c @@ -17,14 +17,14 @@ #include "crypto/hmac.h" #include "hmacpriv.h" -static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5, - [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1, - [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256, - [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512, - [QCRYPTO_HASH_ALG_SHA224] = -1, - [QCRYPTO_HASH_ALG_SHA384] = -1, - [QCRYPTO_HASH_ALG_RIPEMD160] = -1, +static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = G_CHECKSUM_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = G_CHECKSUM_SHA1, + [QCRYPTO_HASH_ALGO_SHA256] = G_CHECKSUM_SHA256, + [QCRYPTO_HASH_ALGO_SHA512] = G_CHECKSUM_SHA512, + [QCRYPTO_HASH_ALGO_SHA224] = -1, + [QCRYPTO_HASH_ALGO_SHA384] = -1, + [QCRYPTO_HASH_ALGO_RIPEMD160] = -1, }; typedef struct QCryptoHmacGlib QCryptoHmacGlib; @@ -32,7 +32,7 @@ struct QCryptoHmacGlib { GHmac *ghmac; }; -bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +bool qcrypto_hmac_supports(QCryptoHashAlgo alg) { if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && qcrypto_hmac_alg_map[alg] != -1) { @@ -42,7 +42,7 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) return false; } -void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, +void *qcrypto_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp) { @@ -50,7 +50,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_str(alg)); + QCryptoHashAlgo_str(alg)); return NULL; } diff --git a/crypto/hmac-gnutls.c b/crypto/hmac-gnutls.c index 24db383..8229955 100644 --- a/crypto/hmac-gnutls.c +++ b/crypto/hmac-gnutls.c @@ -20,14 +20,14 @@ #include "crypto/hmac.h" #include "hmacpriv.h" -static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GNUTLS_MAC_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GNUTLS_MAC_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = GNUTLS_MAC_SHA224, - [QCRYPTO_HASH_ALG_SHA256] = GNUTLS_MAC_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = GNUTLS_MAC_SHA384, - [QCRYPTO_HASH_ALG_SHA512] = GNUTLS_MAC_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = GNUTLS_MAC_RMD160, +static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GNUTLS_MAC_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GNUTLS_MAC_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GNUTLS_MAC_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GNUTLS_MAC_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GNUTLS_MAC_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GNUTLS_MAC_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GNUTLS_MAC_RMD160, }; typedef struct QCryptoHmacGnutls QCryptoHmacGnutls; @@ -35,7 +35,7 @@ struct QCryptoHmacGnutls { gnutls_hmac_hd_t handle; }; -bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +bool qcrypto_hmac_supports(QCryptoHashAlgo alg) { size_t i; const gnutls_digest_algorithm_t *algs; @@ -52,7 +52,7 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) return false; } -void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, +void *qcrypto_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp) { @@ -61,7 +61,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_str(alg)); + QCryptoHashAlgo_str(alg)); return NULL; } diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c index 1ad6c4f..dd5b2ab 100644 --- a/crypto/hmac-nettle.c +++ b/crypto/hmac-nettle.c @@ -38,6 +38,9 @@ struct QCryptoHmacNettle { struct hmac_sha256_ctx sha256_ctx; /* equals hmac_sha224_ctx */ struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */ struct hmac_ripemd160_ctx ripemd160_ctx; +#ifdef CONFIG_CRYPTO_SM3 + struct hmac_sm3_ctx ctx; +#endif } u; }; @@ -46,52 +49,60 @@ struct qcrypto_nettle_hmac_alg { qcrypto_nettle_hmac_update update; qcrypto_nettle_hmac_digest digest; size_t len; -} qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = { +} qcrypto_hmac_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key, .update = (qcrypto_nettle_hmac_update)hmac_md5_update, .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest, .len = MD5_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA1] = { + [QCRYPTO_HASH_ALGO_SHA1] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key, .update = (qcrypto_nettle_hmac_update)hmac_sha1_update, .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest, .len = SHA1_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA224] = { + [QCRYPTO_HASH_ALGO_SHA224] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha224_set_key, .update = (qcrypto_nettle_hmac_update)hmac_sha224_update, .digest = (qcrypto_nettle_hmac_digest)hmac_sha224_digest, .len = SHA224_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA256] = { + [QCRYPTO_HASH_ALGO_SHA256] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key, .update = (qcrypto_nettle_hmac_update)hmac_sha256_update, .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest, .len = SHA256_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA384] = { + [QCRYPTO_HASH_ALGO_SHA384] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha384_set_key, .update = (qcrypto_nettle_hmac_update)hmac_sha384_update, .digest = (qcrypto_nettle_hmac_digest)hmac_sha384_digest, .len = SHA384_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_SHA512] = { + [QCRYPTO_HASH_ALGO_SHA512] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key, .update = (qcrypto_nettle_hmac_update)hmac_sha512_update, .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest, .len = SHA512_DIGEST_SIZE, }, - [QCRYPTO_HASH_ALG_RIPEMD160] = { + [QCRYPTO_HASH_ALGO_RIPEMD160] = { .setkey = (qcrypto_nettle_hmac_setkey)hmac_ripemd160_set_key, .update = (qcrypto_nettle_hmac_update)hmac_ripemd160_update, .digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest, .len = RIPEMD160_DIGEST_SIZE, }, +#ifdef CONFIG_CRYPTO_SM3 + [QCRYPTO_HASH_ALGO_SM3] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sm3_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_sm3_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_sm3_digest, + .len = SM3_DIGEST_SIZE, + }, +#endif }; -bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +bool qcrypto_hmac_supports(QCryptoHashAlgo alg) { if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && qcrypto_hmac_alg_map[alg].setkey != NULL) { @@ -101,7 +112,7 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) return false; } -void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, +void *qcrypto_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp) { @@ -109,7 +120,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_str(alg)); + QCryptoHashAlgo_str(alg)); return NULL; } diff --git a/crypto/hmac.c b/crypto/hmac.c index 4de7e8c..422e005 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -83,7 +83,7 @@ int qcrypto_hmac_digest(QCryptoHmac *hmac, return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp); } -QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp) { diff --git a/crypto/hmacpriv.h b/crypto/hmacpriv.h index 62dfe82..f339596 100644 --- a/crypto/hmacpriv.h +++ b/crypto/hmacpriv.h @@ -28,7 +28,7 @@ struct QCryptoHmacDriver { void (*hmac_free)(QCryptoHmac *hmac); }; -void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, +void *qcrypto_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp); extern QCryptoHmacDriver qcrypto_hmac_lib_driver; @@ -37,7 +37,7 @@ extern QCryptoHmacDriver qcrypto_hmac_lib_driver; #include "afalgpriv.h" -QCryptoAFAlg *qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg, +QCryptoAFAlgo *qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp); extern QCryptoHmacDriver qcrypto_hmac_afalg_driver; diff --git a/crypto/init.c b/crypto/init.c index fb7f1bf..674d237 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -34,14 +34,11 @@ #include "crypto/random.h" -/* #define DEBUG_GNUTLS */ -#ifdef DEBUG_GNUTLS -static void qcrypto_gnutls_log(int level, const char *str) -{ - fprintf(stderr, "%d: %s", level, str); -} -#endif +/* + * To debug GNUTLS see env vars listed in + * https://gnutls.org/manual/html_node/Debugging-and-auditing.html + */ int qcrypto_init(Error **errp) { #ifdef CONFIG_GNUTLS @@ -53,10 +50,6 @@ int qcrypto_init(Error **errp) gnutls_strerror(ret)); return -1; } -#ifdef DEBUG_GNUTLS - gnutls_global_set_log_level(10); - gnutls_global_set_log_function(qcrypto_gnutls_log); -#endif #endif #ifdef CONFIG_GCRYPT diff --git a/crypto/ivgen.c b/crypto/ivgen.c index 12822f8..6b7d24d 100644 --- a/crypto/ivgen.c +++ b/crypto/ivgen.c @@ -27,9 +27,9 @@ #include "ivgen-essiv.h" -QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg, - QCryptoCipherAlgorithm cipheralg, - QCryptoHashAlgorithm hash, +QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgo alg, + QCryptoCipherAlgo cipheralg, + QCryptoHashAlgo hash, const uint8_t *key, size_t nkey, Error **errp) { @@ -40,13 +40,13 @@ QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg, ivgen->hash = hash; switch (alg) { - case QCRYPTO_IVGEN_ALG_PLAIN: + case QCRYPTO_IV_GEN_ALGO_PLAIN: ivgen->driver = &qcrypto_ivgen_plain; break; - case QCRYPTO_IVGEN_ALG_PLAIN64: + case QCRYPTO_IV_GEN_ALGO_PLAIN64: ivgen->driver = &qcrypto_ivgen_plain64; break; - case QCRYPTO_IVGEN_ALG_ESSIV: + case QCRYPTO_IV_GEN_ALGO_ESSIV: ivgen->driver = &qcrypto_ivgen_essiv; break; default: @@ -73,19 +73,19 @@ int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen, } -QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen) +QCryptoIVGenAlgo qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen) { return ivgen->algorithm; } -QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen) +QCryptoCipherAlgo qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen) { return ivgen->cipher; } -QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen) +QCryptoHashAlgo qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen) { return ivgen->hash; } diff --git a/crypto/ivgenpriv.h b/crypto/ivgenpriv.h index cecdbed..e3388d3 100644 --- a/crypto/ivgenpriv.h +++ b/crypto/ivgenpriv.h @@ -40,9 +40,9 @@ struct QCryptoIVGen { QCryptoIVGenDriver *driver; void *private; - QCryptoIVGenAlgorithm algorithm; - QCryptoCipherAlgorithm cipher; - QCryptoHashAlgorithm hash; + QCryptoIVGenAlgo algorithm; + QCryptoCipherAlgo cipher; + QCryptoHashAlgo hash; }; diff --git a/crypto/meson.build b/crypto/meson.build index c46f9c2..735635d 100644 --- a/crypto/meson.build +++ b/crypto/meson.build @@ -24,6 +24,10 @@ crypto_ss.add(files( 'rsakey.c', )) +if gnutls.found() + crypto_ss.add(files('x509-utils.c')) +endif + if nettle.found() crypto_ss.add(nettle, files('hash-nettle.c', 'hmac-nettle.c', 'pbkdf-nettle.c')) if hogweed.found() diff --git a/crypto/pbkdf-gcrypt.c b/crypto/pbkdf-gcrypt.c index a8d8e64..e89b8b1 100644 --- a/crypto/pbkdf-gcrypt.c +++ b/crypto/pbkdf-gcrypt.c @@ -23,37 +23,43 @@ #include "qapi/error.h" #include "crypto/pbkdf.h" -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash) +bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash) { switch (hash) { - case QCRYPTO_HASH_ALG_MD5: - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA224: - case QCRYPTO_HASH_ALG_SHA256: - case QCRYPTO_HASH_ALG_SHA384: - case QCRYPTO_HASH_ALG_SHA512: - case QCRYPTO_HASH_ALG_RIPEMD160: - return true; + case QCRYPTO_HASH_ALGO_MD5: + case QCRYPTO_HASH_ALGO_SHA1: + case QCRYPTO_HASH_ALGO_SHA224: + case QCRYPTO_HASH_ALGO_SHA256: + case QCRYPTO_HASH_ALGO_SHA384: + case QCRYPTO_HASH_ALGO_SHA512: + case QCRYPTO_HASH_ALGO_RIPEMD160: +#ifdef CONFIG_CRYPTO_SM3 + case QCRYPTO_HASH_ALGO_SM3: +#endif + return qcrypto_hash_supports(hash); default: return false; } } -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, +int qcrypto_pbkdf2(QCryptoHashAlgo hash, const uint8_t *key, size_t nkey, const uint8_t *salt, size_t nsalt, uint64_t iterations, uint8_t *out, size_t nout, Error **errp) { - static const int hash_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GCRY_MD_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GCRY_MD_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = GCRY_MD_SHA224, - [QCRYPTO_HASH_ALG_SHA256] = GCRY_MD_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = GCRY_MD_SHA384, - [QCRYPTO_HASH_ALG_SHA512] = GCRY_MD_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MD_RMD160, + static const int hash_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GCRY_MD_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GCRY_MD_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GCRY_MD_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GCRY_MD_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GCRY_MD_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GCRY_MD_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GCRY_MD_RMD160, +#ifdef CONFIG_CRYPTO_SM3 + [QCRYPTO_HASH_ALGO_SM3] = GCRY_MD_SM3, +#endif }; int ret; @@ -68,7 +74,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, hash_map[hash] == GCRY_MD_NONE) { error_setg_errno(errp, ENOSYS, "PBKDF does not support hash algorithm %s", - QCryptoHashAlgorithm_str(hash)); + QCryptoHashAlgo_str(hash)); return -1; } diff --git a/crypto/pbkdf-gnutls.c b/crypto/pbkdf-gnutls.c index 2dfbbd3..f34423f 100644 --- a/crypto/pbkdf-gnutls.c +++ b/crypto/pbkdf-gnutls.c @@ -23,37 +23,37 @@ #include "qapi/error.h" #include "crypto/pbkdf.h" -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash) +bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash) { switch (hash) { - case QCRYPTO_HASH_ALG_MD5: - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA224: - case QCRYPTO_HASH_ALG_SHA256: - case QCRYPTO_HASH_ALG_SHA384: - case QCRYPTO_HASH_ALG_SHA512: - case QCRYPTO_HASH_ALG_RIPEMD160: - return true; + case QCRYPTO_HASH_ALGO_MD5: + case QCRYPTO_HASH_ALGO_SHA1: + case QCRYPTO_HASH_ALGO_SHA224: + case QCRYPTO_HASH_ALGO_SHA256: + case QCRYPTO_HASH_ALGO_SHA384: + case QCRYPTO_HASH_ALGO_SHA512: + case QCRYPTO_HASH_ALGO_RIPEMD160: + return qcrypto_hash_supports(hash); default: return false; } } -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, +int qcrypto_pbkdf2(QCryptoHashAlgo hash, const uint8_t *key, size_t nkey, const uint8_t *salt, size_t nsalt, uint64_t iterations, uint8_t *out, size_t nout, Error **errp) { - static const int hash_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1, - [QCRYPTO_HASH_ALG_SHA224] = GNUTLS_DIG_SHA224, - [QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256, - [QCRYPTO_HASH_ALG_SHA384] = GNUTLS_DIG_SHA384, - [QCRYPTO_HASH_ALG_SHA512] = GNUTLS_DIG_SHA512, - [QCRYPTO_HASH_ALG_RIPEMD160] = GNUTLS_DIG_RMD160, + static const int hash_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GNUTLS_DIG_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GNUTLS_DIG_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GNUTLS_DIG_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GNUTLS_DIG_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GNUTLS_DIG_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GNUTLS_DIG_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GNUTLS_DIG_RMD160, }; int ret; const gnutls_datum_t gkey = { (unsigned char *)key, nkey }; @@ -70,7 +70,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, hash_map[hash] == GNUTLS_DIG_UNKNOWN) { error_setg_errno(errp, ENOSYS, "PBKDF does not support hash algorithm %s", - QCryptoHashAlgorithm_str(hash)); + QCryptoHashAlgo_str(hash)); return -1; } diff --git a/crypto/pbkdf-nettle.c b/crypto/pbkdf-nettle.c index d6293c2..3ef9c1b 100644 --- a/crypto/pbkdf-nettle.c +++ b/crypto/pbkdf-nettle.c @@ -25,22 +25,25 @@ #include "crypto/pbkdf.h" -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash) +bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash) { switch (hash) { - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA224: - case QCRYPTO_HASH_ALG_SHA256: - case QCRYPTO_HASH_ALG_SHA384: - case QCRYPTO_HASH_ALG_SHA512: - case QCRYPTO_HASH_ALG_RIPEMD160: + case QCRYPTO_HASH_ALGO_SHA1: + case QCRYPTO_HASH_ALGO_SHA224: + case QCRYPTO_HASH_ALGO_SHA256: + case QCRYPTO_HASH_ALGO_SHA384: + case QCRYPTO_HASH_ALGO_SHA512: + case QCRYPTO_HASH_ALGO_RIPEMD160: +#ifdef CONFIG_CRYPTO_SM3 + case QCRYPTO_HASH_ALGO_SM3: +#endif return true; default: return false; } } -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, +int qcrypto_pbkdf2(QCryptoHashAlgo hash, const uint8_t *key, size_t nkey, const uint8_t *salt, size_t nsalt, uint64_t iterations, @@ -55,6 +58,9 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, struct hmac_sha384_ctx sha384; struct hmac_sha512_ctx sha512; struct hmac_ripemd160_ctx ripemd160; +#ifdef CONFIG_CRYPTO_SM3 + struct hmac_sm3_ctx sm3; +#endif } ctx; if (iterations > UINT_MAX) { @@ -65,52 +71,59 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, } switch (hash) { - case QCRYPTO_HASH_ALG_MD5: + case QCRYPTO_HASH_ALGO_MD5: hmac_md5_set_key(&ctx.md5, nkey, key); PBKDF2(&ctx.md5, hmac_md5_update, hmac_md5_digest, MD5_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; - case QCRYPTO_HASH_ALG_SHA1: + case QCRYPTO_HASH_ALGO_SHA1: hmac_sha1_set_key(&ctx.sha1, nkey, key); PBKDF2(&ctx.sha1, hmac_sha1_update, hmac_sha1_digest, SHA1_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; - case QCRYPTO_HASH_ALG_SHA224: + case QCRYPTO_HASH_ALGO_SHA224: hmac_sha224_set_key(&ctx.sha224, nkey, key); PBKDF2(&ctx.sha224, hmac_sha224_update, hmac_sha224_digest, SHA224_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; - case QCRYPTO_HASH_ALG_SHA256: + case QCRYPTO_HASH_ALGO_SHA256: hmac_sha256_set_key(&ctx.sha256, nkey, key); PBKDF2(&ctx.sha256, hmac_sha256_update, hmac_sha256_digest, SHA256_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; - case QCRYPTO_HASH_ALG_SHA384: + case QCRYPTO_HASH_ALGO_SHA384: hmac_sha384_set_key(&ctx.sha384, nkey, key); PBKDF2(&ctx.sha384, hmac_sha384_update, hmac_sha384_digest, SHA384_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; - case QCRYPTO_HASH_ALG_SHA512: + case QCRYPTO_HASH_ALGO_SHA512: hmac_sha512_set_key(&ctx.sha512, nkey, key); PBKDF2(&ctx.sha512, hmac_sha512_update, hmac_sha512_digest, SHA512_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; - case QCRYPTO_HASH_ALG_RIPEMD160: + case QCRYPTO_HASH_ALGO_RIPEMD160: hmac_ripemd160_set_key(&ctx.ripemd160, nkey, key); PBKDF2(&ctx.ripemd160, hmac_ripemd160_update, hmac_ripemd160_digest, RIPEMD160_DIGEST_SIZE, iterations, nsalt, salt, nout, out); break; +#ifdef CONFIG_CRYPTO_SM3 + case QCRYPTO_HASH_ALGO_SM3: + hmac_sm3_set_key(&ctx.sm3, nkey, key); + PBKDF2(&ctx.sm3, hmac_sm3_update, hmac_sm3_digest, + SM3_DIGEST_SIZE, iterations, nsalt, salt, nout, out); + break; +#endif default: error_setg_errno(errp, ENOSYS, "PBKDF does not support hash algorithm %s", - QCryptoHashAlgorithm_str(hash)); + QCryptoHashAlgo_str(hash)); return -1; } return 0; diff --git a/crypto/pbkdf-stub.c b/crypto/pbkdf-stub.c index 9c4622e..9f29d0e 100644 --- a/crypto/pbkdf-stub.c +++ b/crypto/pbkdf-stub.c @@ -22,12 +22,12 @@ #include "qapi/error.h" #include "crypto/pbkdf.h" -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash G_GNUC_UNUSED) +bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash G_GNUC_UNUSED) { return false; } -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash G_GNUC_UNUSED, +int qcrypto_pbkdf2(QCryptoHashAlgo hash G_GNUC_UNUSED, const uint8_t *key G_GNUC_UNUSED, size_t nkey G_GNUC_UNUSED, const uint8_t *salt G_GNUC_UNUSED, diff --git a/crypto/pbkdf.c b/crypto/pbkdf.c index 8d198c1..2989fc0 100644 --- a/crypto/pbkdf.c +++ b/crypto/pbkdf.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qemu/thread.h" #include "qapi/error.h" #include "crypto/pbkdf.h" #ifndef _WIN32 @@ -85,12 +86,28 @@ static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms, #endif } -uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, - const uint8_t *key, size_t nkey, - const uint8_t *salt, size_t nsalt, - size_t nout, - Error **errp) +typedef struct CountItersData { + QCryptoHashAlgo hash; + const uint8_t *key; + size_t nkey; + const uint8_t *salt; + size_t nsalt; + size_t nout; + uint64_t iterations; + Error **errp; +} CountItersData; + +static void *threaded_qcrypto_pbkdf2_count_iters(void *data) { + CountItersData *iters_data = (CountItersData *) data; + QCryptoHashAlgo hash = iters_data->hash; + const uint8_t *key = iters_data->key; + size_t nkey = iters_data->nkey; + const uint8_t *salt = iters_data->salt; + size_t nsalt = iters_data->nsalt; + size_t nout = iters_data->nout; + Error **errp = iters_data->errp; + size_t scaled = 0; uint64_t ret = -1; g_autofree uint8_t *out = g_new(uint8_t, nout); uint64_t iterations = (1 << 15); @@ -114,13 +131,27 @@ uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, delta_ms = end_ms - start_ms; - if (delta_ms > 500) { + /* + * For very small 'iterations' values, CPU (or crypto + * accelerator) might be fast enough that the scheduler + * hasn't incremented getrusage() data, or incremented + * it by a very small amount, resulting in delta_ms == 0. + * Once we've scaled 'iterations' x10, 5 times, we really + * should be seeing delta_ms != 0, so sanity check at + * that point. + */ + if (scaled > 5 && + delta_ms == 0) { /* sanity check */ + error_setg(errp, "Unable to get accurate CPU usage"); + goto cleanup; + } else if (delta_ms > 500) { break; } else if (delta_ms < 100) { iterations = iterations * 10; } else { iterations = (iterations * 1000 / delta_ms); } + scaled++; } iterations = iterations * 1000 / delta_ms; @@ -129,5 +160,24 @@ uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, cleanup: memset(out, 0, nout); - return ret; + iters_data->iterations = ret; + return NULL; +} + +uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgo hash, + const uint8_t *key, size_t nkey, + const uint8_t *salt, size_t nsalt, + size_t nout, + Error **errp) +{ + CountItersData data = { + hash, key, nkey, salt, nsalt, nout, 0, errp + }; + QemuThread thread; + + qemu_thread_create(&thread, "pbkdf2", threaded_qcrypto_pbkdf2_count_iters, + &data, QEMU_THREAD_JOINABLE); + qemu_thread_join(&thread); + + return data.iterations; } diff --git a/crypto/rsakey-builtin.c.inc b/crypto/rsakey-builtin.c.inc index 46cc7af..6337b84 100644 --- a/crypto/rsakey-builtin.c.inc +++ b/crypto/rsakey-builtin.c.inc @@ -183,10 +183,10 @@ QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse( size_t keylen, Error **errp) { switch (type) { - case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE: return qcrypto_builtin_rsa_private_key_parse(key, keylen, errp); - case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC: return qcrypto_builtin_rsa_public_key_parse(key, keylen, errp); default: diff --git a/crypto/rsakey-nettle.c.inc b/crypto/rsakey-nettle.c.inc index cc49872..b7f34b0 100644 --- a/crypto/rsakey-nettle.c.inc +++ b/crypto/rsakey-nettle.c.inc @@ -145,10 +145,10 @@ QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse( size_t keylen, Error **errp) { switch (type) { - case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE: return qcrypto_nettle_rsa_private_key_parse(key, keylen, errp); - case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC: + case QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC: return qcrypto_nettle_rsa_public_key_parse(key, keylen, errp); default: diff --git a/crypto/secret.c b/crypto/secret.c index 44eaff1..61a4584 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -117,7 +117,7 @@ qcrypto_secret_finalize(Object *obj) } static void -qcrypto_secret_class_init(ObjectClass *oc, void *data) +qcrypto_secret_class_init(ObjectClass *oc, const void *data) { QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc); sic->load_data = qcrypto_secret_load_data; diff --git a/crypto/secret_common.c b/crypto/secret_common.c index 3441c44..a5ecb87 100644 --- a/crypto/secret_common.c +++ b/crypto/secret_common.c @@ -71,7 +71,7 @@ static void qcrypto_secret_decrypt(QCryptoSecretCommon *secret, return; } - aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256, + aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_256, QCRYPTO_CIPHER_MODE_CBC, key, keylen, errp); @@ -191,15 +191,6 @@ qcrypto_secret_complete(UserCreatable *uc, Error **errp) } -static bool -qcrypto_secret_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj); - return secret->rawdata != NULL; -} - - static void qcrypto_secret_prop_set_format(Object *obj, int value, @@ -272,15 +263,12 @@ qcrypto_secret_finalize(Object *obj) } static void -qcrypto_secret_class_init(ObjectClass *oc, void *data) +qcrypto_secret_class_init(ObjectClass *oc, const void *data) { UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); ucc->complete = qcrypto_secret_complete; - object_class_property_add_bool(oc, "loaded", - qcrypto_secret_prop_get_loaded, - NULL); object_class_property_add_enum(oc, "format", "QCryptoSecretFormat", &QCryptoSecretFormat_lookup, @@ -387,7 +375,7 @@ static const TypeInfo qcrypto_secret_info = { .class_size = sizeof(QCryptoSecretCommonClass), .class_init = qcrypto_secret_class_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } } diff --git a/crypto/secret_keyring.c b/crypto/secret_keyring.c index 1b7edec..78d7f09 100644 --- a/crypto/secret_keyring.c +++ b/crypto/secret_keyring.c @@ -103,7 +103,7 @@ qcrypto_secret_prop_get_key(Object *obj, Visitor *v, static void -qcrypto_secret_keyring_class_init(ObjectClass *oc, void *data) +qcrypto_secret_keyring_class_init(ObjectClass *oc, const void *data) { QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc); sic->load_data = qcrypto_secret_keyring_load_data; diff --git a/crypto/tls-cipher-suites.c b/crypto/tls-cipher-suites.c index d0df4ba..d9b61d0 100644 --- a/crypto/tls-cipher-suites.c +++ b/crypto/tls-cipher-suites.c @@ -102,7 +102,8 @@ static GByteArray *qcrypto_tls_cipher_suites_fw_cfg_gen_data(Object *obj, errp); } -static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, void *data) +static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, + const void *data) { UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(oc); @@ -117,7 +118,7 @@ static const TypeInfo qcrypto_tls_cipher_suites_info = { .instance_size = sizeof(QCryptoTLSCipherSuites), .class_size = sizeof(QCryptoTLSCredsClass), .class_init = qcrypto_tls_cipher_suites_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE }, { } diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c index 084ce0d..9e59594 100644 --- a/crypto/tlscreds.c +++ b/crypto/tlscreds.c @@ -223,7 +223,7 @@ qcrypto_tls_creds_prop_get_endpoint(Object *obj, static void -qcrypto_tls_creds_class_init(ObjectClass *oc, void *data) +qcrypto_tls_creds_class_init(ObjectClass *oc, const void *data) { object_class_property_add_bool(oc, "verify-peer", qcrypto_tls_creds_prop_get_verify, diff --git a/crypto/tlscredsanon.c b/crypto/tlscredsanon.c index c0d23a0..44af9e6 100644 --- a/crypto/tlscredsanon.c +++ b/crypto/tlscredsanon.c @@ -127,37 +127,6 @@ qcrypto_tls_creds_anon_complete(UserCreatable *uc, Error **errp) } -#ifdef CONFIG_GNUTLS - - -static bool -qcrypto_tls_creds_anon_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsAnon *creds = QCRYPTO_TLS_CREDS_ANON(obj); - - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - return creds->data.server != NULL; - } else { - return creds->data.client != NULL; - } -} - - -#else /* ! CONFIG_GNUTLS */ - - -static bool -qcrypto_tls_creds_anon_prop_get_loaded(Object *obj G_GNUC_UNUSED, - Error **errp G_GNUC_UNUSED) -{ - return false; -} - - -#endif /* ! CONFIG_GNUTLS */ - - static void qcrypto_tls_creds_anon_finalize(Object *obj) { @@ -168,15 +137,11 @@ qcrypto_tls_creds_anon_finalize(Object *obj) static void -qcrypto_tls_creds_anon_class_init(ObjectClass *oc, void *data) +qcrypto_tls_creds_anon_class_init(ObjectClass *oc, const void *data) { UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); ucc->complete = qcrypto_tls_creds_anon_complete; - - object_class_property_add_bool(oc, "loaded", - qcrypto_tls_creds_anon_prop_get_loaded, - NULL); } @@ -187,7 +152,7 @@ static const TypeInfo qcrypto_tls_creds_anon_info = { .instance_finalize = qcrypto_tls_creds_anon_finalize, .class_size = sizeof(QCryptoTLSCredsAnonClass), .class_init = qcrypto_tls_creds_anon_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } } diff --git a/crypto/tlscredspsk.c b/crypto/tlscredspsk.c index 546cad1..5b68a6b 100644 --- a/crypto/tlscredspsk.c +++ b/crypto/tlscredspsk.c @@ -206,43 +206,13 @@ qcrypto_tls_creds_psk_complete(UserCreatable *uc, Error **errp) } -#ifdef CONFIG_GNUTLS - - -static bool -qcrypto_tls_creds_psk_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsPSK *creds = QCRYPTO_TLS_CREDS_PSK(obj); - - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - return creds->data.server != NULL; - } else { - return creds->data.client != NULL; - } -} - - -#else /* ! CONFIG_GNUTLS */ - - -static bool -qcrypto_tls_creds_psk_prop_get_loaded(Object *obj G_GNUC_UNUSED, - Error **errp G_GNUC_UNUSED) -{ - return false; -} - - -#endif /* ! CONFIG_GNUTLS */ - - static void qcrypto_tls_creds_psk_finalize(Object *obj) { QCryptoTLSCredsPSK *creds = QCRYPTO_TLS_CREDS_PSK(obj); qcrypto_tls_creds_psk_unload(creds); + g_free(creds->username); } static void @@ -266,15 +236,12 @@ qcrypto_tls_creds_psk_prop_get_username(Object *obj, } static void -qcrypto_tls_creds_psk_class_init(ObjectClass *oc, void *data) +qcrypto_tls_creds_psk_class_init(ObjectClass *oc, const void *data) { UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); ucc->complete = qcrypto_tls_creds_psk_complete; - object_class_property_add_bool(oc, "loaded", - qcrypto_tls_creds_psk_prop_get_loaded, - NULL); object_class_property_add_str(oc, "username", qcrypto_tls_creds_psk_prop_get_username, qcrypto_tls_creds_psk_prop_set_username); @@ -288,7 +255,7 @@ static const TypeInfo qcrypto_tls_creds_psk_info = { .instance_finalize = qcrypto_tls_creds_psk_finalize, .class_size = sizeof(QCryptoTLSCredsPSKClass), .class_init = qcrypto_tls_creds_psk_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } } diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index d143139..63a72fe 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -695,33 +695,6 @@ qcrypto_tls_creds_x509_complete(UserCreatable *uc, Error **errp) } -#ifdef CONFIG_GNUTLS - - -static bool -qcrypto_tls_creds_x509_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - return creds->data != NULL; -} - - -#else /* ! CONFIG_GNUTLS */ - - -static bool -qcrypto_tls_creds_x509_prop_get_loaded(Object *obj G_GNUC_UNUSED, - Error **errp G_GNUC_UNUSED) -{ - return false; -} - - -#endif /* ! CONFIG_GNUTLS */ - - static void qcrypto_tls_creds_x509_prop_set_sanity(Object *obj, bool value, @@ -829,7 +802,7 @@ qcrypto_tls_creds_x509_finalize(Object *obj) static void -qcrypto_tls_creds_x509_class_init(ObjectClass *oc, void *data) +qcrypto_tls_creds_x509_class_init(ObjectClass *oc, const void *data) { UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); QCryptoTLSCredsClass *ctcc = QCRYPTO_TLS_CREDS_CLASS(oc); @@ -838,9 +811,6 @@ qcrypto_tls_creds_x509_class_init(ObjectClass *oc, void *data) ucc->complete = qcrypto_tls_creds_x509_complete; - object_class_property_add_bool(oc, "loaded", - qcrypto_tls_creds_x509_prop_get_loaded, - NULL); object_class_property_add_bool(oc, "sanity-check", qcrypto_tls_creds_x509_prop_get_sanity, qcrypto_tls_creds_x509_prop_set_sanity); @@ -858,7 +828,7 @@ static const TypeInfo qcrypto_tls_creds_x509_info = { .instance_finalize = qcrypto_tls_creds_x509_finalize, .class_size = sizeof(QCryptoTLSCredsX509Class), .class_init = qcrypto_tls_creds_x509_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } } diff --git a/crypto/tlssession.c b/crypto/tlssession.c index 1e98f44..6d8f8df 100644 --- a/crypto/tlssession.c +++ b/crypto/tlssession.c @@ -44,6 +44,13 @@ struct QCryptoTLSSession { QCryptoTLSSessionReadFunc readFunc; void *opaque; char *peername; + + /* + * Allow concurrent reads and writes, so track + * errors separately + */ + Error *rerr; + Error *werr; }; @@ -54,6 +61,9 @@ qcrypto_tls_session_free(QCryptoTLSSession *session) return; } + error_free(session->rerr); + error_free(session->werr); + gnutls_deinit(session->handle); g_free(session->hostname); g_free(session->peername); @@ -67,13 +77,26 @@ static ssize_t qcrypto_tls_session_push(void *opaque, const void *buf, size_t len) { QCryptoTLSSession *session = opaque; + ssize_t ret; if (!session->writeFunc) { errno = EIO; return -1; }; - return session->writeFunc(buf, len, session->opaque); + error_free(session->werr); + session->werr = NULL; + + ret = session->writeFunc(buf, len, session->opaque, &session->werr); + if (ret == QCRYPTO_TLS_SESSION_ERR_BLOCK) { + errno = EAGAIN; + return -1; + } else if (ret < 0) { + errno = EIO; + return -1; + } else { + return ret; + } } @@ -81,13 +104,26 @@ static ssize_t qcrypto_tls_session_pull(void *opaque, void *buf, size_t len) { QCryptoTLSSession *session = opaque; + ssize_t ret; if (!session->readFunc) { errno = EIO; return -1; }; - return session->readFunc(buf, len, session->opaque); + error_free(session->rerr); + session->rerr = NULL; + + ret = session->readFunc(buf, len, session->opaque, &session->rerr); + if (ret == QCRYPTO_TLS_SESSION_ERR_BLOCK) { + errno = EAGAIN; + return -1; + } else if (ret < 0) { + errno = EIO; + return -1; + } else { + return ret; + } } #define TLS_PRIORITY_ADDITIONAL_ANON "+ANON-DH" @@ -441,23 +477,25 @@ qcrypto_tls_session_set_callbacks(QCryptoTLSSession *session, ssize_t qcrypto_tls_session_write(QCryptoTLSSession *session, const char *buf, - size_t len) + size_t len, + Error **errp) { ssize_t ret = gnutls_record_send(session->handle, buf, len); if (ret < 0) { - switch (ret) { - case GNUTLS_E_AGAIN: - errno = EAGAIN; - break; - case GNUTLS_E_INTERRUPTED: - errno = EINTR; - break; - default: - errno = EIO; - break; + if (ret == GNUTLS_E_AGAIN) { + return QCRYPTO_TLS_SESSION_ERR_BLOCK; + } else { + if (session->werr) { + error_propagate(errp, session->werr); + session->werr = NULL; + } else { + error_setg(errp, + "Cannot write to TLS channel: %s", + gnutls_strerror(ret)); + } + return -1; } - ret = -1; } return ret; @@ -467,26 +505,29 @@ qcrypto_tls_session_write(QCryptoTLSSession *session, ssize_t qcrypto_tls_session_read(QCryptoTLSSession *session, char *buf, - size_t len) + size_t len, + bool gracefulTermination, + Error **errp) { ssize_t ret = gnutls_record_recv(session->handle, buf, len); if (ret < 0) { - switch (ret) { - case GNUTLS_E_AGAIN: - errno = EAGAIN; - break; - case GNUTLS_E_INTERRUPTED: - errno = EINTR; - break; - case GNUTLS_E_PREMATURE_TERMINATION: - errno = ECONNABORTED; - break; - default: - errno = EIO; - break; + if (ret == GNUTLS_E_AGAIN) { + return QCRYPTO_TLS_SESSION_ERR_BLOCK; + } else if ((ret == GNUTLS_E_PREMATURE_TERMINATION) && + gracefulTermination){ + return 0; + } else { + if (session->rerr) { + error_propagate(errp, session->rerr); + session->rerr = NULL; + } else { + error_setg(errp, + "Cannot read from TLS channel: %s", + gnutls_strerror(ret)); + } + return -1; } - ret = -1; } return ret; @@ -505,35 +546,69 @@ qcrypto_tls_session_handshake(QCryptoTLSSession *session, Error **errp) { int ret = gnutls_handshake(session->handle); - if (ret == 0) { + if (!ret) { session->handshakeComplete = true; + return QCRYPTO_TLS_HANDSHAKE_COMPLETE; + } + + if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { + int direction = gnutls_record_get_direction(session->handle); + return direction ? QCRYPTO_TLS_HANDSHAKE_SENDING : + QCRYPTO_TLS_HANDSHAKE_RECVING; + } + + if (session->rerr || session->werr) { + error_setg(errp, "TLS handshake failed: %s: %s", + gnutls_strerror(ret), + error_get_pretty(session->rerr ? + session->rerr : session->werr)); } else { - if (ret == GNUTLS_E_INTERRUPTED || - ret == GNUTLS_E_AGAIN) { - ret = 1; - } else { - error_setg(errp, "TLS handshake failed: %s", - gnutls_strerror(ret)); - ret = -1; - } + error_setg(errp, "TLS handshake failed: %s", + gnutls_strerror(ret)); } - return ret; + error_free(session->rerr); + error_free(session->werr); + session->rerr = session->werr = NULL; + + return -1; } -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session) +int +qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp) { - if (session->handshakeComplete) { - return QCRYPTO_TLS_HANDSHAKE_COMPLETE; - } else if (gnutls_record_get_direction(session->handle) == 0) { - return QCRYPTO_TLS_HANDSHAKE_RECVING; + int ret; + + if (!session->handshakeComplete) { + return 0; + } + + ret = gnutls_bye(session->handle, GNUTLS_SHUT_WR); + + if (!ret) { + return QCRYPTO_TLS_BYE_COMPLETE; + } + + if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { + int direction = gnutls_record_get_direction(session->handle); + return direction ? QCRYPTO_TLS_BYE_SENDING : QCRYPTO_TLS_BYE_RECVING; + } + + if (session->rerr || session->werr) { + error_setg(errp, "TLS termination failed: %s: %s", gnutls_strerror(ret), + error_get_pretty(session->rerr ? + session->rerr : session->werr)); } else { - return QCRYPTO_TLS_HANDSHAKE_SENDING; + error_setg(errp, "TLS termination failed: %s", gnutls_strerror(ret)); } -} + error_free(session->rerr); + error_free(session->werr); + session->rerr = session->werr = NULL; + + return -1; +} int qcrypto_tls_session_get_key_size(QCryptoTLSSession *session, @@ -605,9 +680,10 @@ qcrypto_tls_session_set_callbacks( ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess, const char *buf, - size_t len) + size_t len, + Error **errp) { - errno = -EIO; + error_setg(errp, "TLS requires GNUTLS support"); return -1; } @@ -615,9 +691,11 @@ qcrypto_tls_session_write(QCryptoTLSSession *sess, ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess, char *buf, - size_t len) + size_t len, + bool gracefulTermination, + Error **errp) { - errno = -EIO; + error_setg(errp, "TLS requires GNUTLS support"); return -1; } @@ -638,10 +716,10 @@ qcrypto_tls_session_handshake(QCryptoTLSSession *sess, } -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess) +int +qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp) { - return QCRYPTO_TLS_HANDSHAKE_COMPLETE; + return QCRYPTO_TLS_BYE_COMPLETE; } diff --git a/crypto/x509-utils.c b/crypto/x509-utils.c new file mode 100644 index 0000000..8bad00a --- /dev/null +++ b/crypto/x509-utils.c @@ -0,0 +1,76 @@ +/* + * X.509 certificate related helpers + * + * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "crypto/x509-utils.h" +#include <gnutls/gnutls.h> +#include <gnutls/crypto.h> +#include <gnutls/x509.h> + +static const int qcrypto_to_gnutls_hash_alg_map[QCRYPTO_HASH_ALGO__MAX] = { + [QCRYPTO_HASH_ALGO_MD5] = GNUTLS_DIG_MD5, + [QCRYPTO_HASH_ALGO_SHA1] = GNUTLS_DIG_SHA1, + [QCRYPTO_HASH_ALGO_SHA224] = GNUTLS_DIG_SHA224, + [QCRYPTO_HASH_ALGO_SHA256] = GNUTLS_DIG_SHA256, + [QCRYPTO_HASH_ALGO_SHA384] = GNUTLS_DIG_SHA384, + [QCRYPTO_HASH_ALGO_SHA512] = GNUTLS_DIG_SHA512, + [QCRYPTO_HASH_ALGO_RIPEMD160] = GNUTLS_DIG_RMD160, +}; + +int qcrypto_get_x509_cert_fingerprint(uint8_t *cert, size_t size, + QCryptoHashAlgo alg, + uint8_t *result, + size_t *resultlen, + Error **errp) +{ + int ret = -1; + int hlen; + gnutls_x509_crt_t crt; + gnutls_datum_t datum = {.data = cert, .size = size}; + + if (alg >= G_N_ELEMENTS(qcrypto_to_gnutls_hash_alg_map)) { + error_setg(errp, "Unknown hash algorithm"); + return -1; + } + + if (result == NULL) { + error_setg(errp, "No valid buffer given"); + return -1; + } + + gnutls_x509_crt_init(&crt); + + if (gnutls_x509_crt_import(crt, &datum, GNUTLS_X509_FMT_PEM) != 0) { + error_setg(errp, "Failed to import certificate"); + goto cleanup; + } + + hlen = gnutls_hash_get_len(qcrypto_to_gnutls_hash_alg_map[alg]); + if (*resultlen < hlen) { + error_setg(errp, + "Result buffer size %zu is smaller than hash %d", + *resultlen, hlen); + goto cleanup; + } + + if (gnutls_x509_crt_get_fingerprint(crt, + qcrypto_to_gnutls_hash_alg_map[alg], + result, resultlen) != 0) { + error_setg(errp, "Failed to get fingerprint from certificate"); + goto cleanup; + } + + ret = 0; + + cleanup: + gnutls_x509_crt_deinit(crt); + return ret; +} |