diff options
Diffstat (limited to 'include/crypto')
-rw-r--r-- | include/crypto/afsplit.h | 8 | ||||
-rw-r--r-- | include/crypto/block.h | 2 | ||||
-rw-r--r-- | include/crypto/cipher.h | 18 | ||||
-rw-r--r-- | include/crypto/hash.h | 189 | ||||
-rw-r--r-- | include/crypto/hmac.h | 40 | ||||
-rw-r--r-- | include/crypto/ivgen.h | 30 | ||||
-rw-r--r-- | include/crypto/pbkdf.h | 14 | ||||
-rw-r--r-- | include/crypto/tlssession.h | 79 | ||||
-rw-r--r-- | include/crypto/x509-utils.h | 22 |
9 files changed, 308 insertions, 94 deletions
diff --git a/include/crypto/afsplit.h b/include/crypto/afsplit.h index 4894d64..06f28fe 100644 --- a/include/crypto/afsplit.h +++ b/include/crypto/afsplit.h @@ -46,7 +46,7 @@ * * splitkey = g_new0(uint8_t, nkey * stripes); * - * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALG_SHA256, + * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALGO_SHA256, * nkey, stripes, * masterkey, splitkey, errp) < 0) { * g_free(splitkey); @@ -71,7 +71,7 @@ * * masterkey = g_new0(uint8_t, nkey); * - * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALG_SHA256, + * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALGO_SHA256, * nkey, stripes, * splitkey, masterkey, errp) < 0) { * g_free(splitkey); @@ -102,7 +102,7 @@ * * Returns: 0 on success, -1 on error; */ -int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, +int qcrypto_afsplit_encode(QCryptoHashAlgo hash, size_t blocklen, uint32_t stripes, const uint8_t *in, @@ -124,7 +124,7 @@ int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, * * Returns: 0 on success, -1 on error; */ -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/include/crypto/block.h b/include/crypto/block.h index 5b5d039..b013d27 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -287,7 +287,7 @@ QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block); * * Returns: the hash algorithm */ -QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block); +QCryptoHashAlgo qcrypto_block_get_kdf_hash(QCryptoBlock *block); /** * qcrypto_block_get_payload_offset: diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h index 083e12a..9293931 100644 --- a/include/crypto/cipher.h +++ b/include/crypto/cipher.h @@ -26,7 +26,7 @@ typedef struct QCryptoCipher QCryptoCipher; typedef struct QCryptoCipherDriver QCryptoCipherDriver; -/* See also "QCryptoCipherAlgorithm" and "QCryptoCipherMode" +/* See also "QCryptoCipherAlgo" and "QCryptoCipherMode" * enums defined in qapi/crypto.json */ /** @@ -50,12 +50,12 @@ typedef struct QCryptoCipherDriver QCryptoCipherDriver; * size_t keylen = 16; * uint8_t iv = ....; * - * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128)) { + * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_128)) { * error_report(errp, "Feature <blah> requires AES cipher support"); * return -1; * } * - * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, + * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128, * QCRYPTO_CIPHER_MODE_CBC, * key, keylen, * errp); @@ -78,7 +78,7 @@ typedef struct QCryptoCipherDriver QCryptoCipherDriver; */ struct QCryptoCipher { - QCryptoCipherAlgorithm alg; + QCryptoCipherAlgo alg; QCryptoCipherMode mode; const QCryptoCipherDriver *driver; }; @@ -93,7 +93,7 @@ struct QCryptoCipher { * * Returns: true if the algorithm is supported, false otherwise */ -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, +bool qcrypto_cipher_supports(QCryptoCipherAlgo alg, QCryptoCipherMode mode); /** @@ -106,7 +106,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, * * Returns: the block size in bytes */ -size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg); +size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgo alg); /** @@ -117,7 +117,7 @@ size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg); * * Returns: the key size in bytes */ -size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg); +size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgo alg); /** @@ -130,7 +130,7 @@ size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg); * * Returns: the IV size in bytes, or 0 if no IV is permitted */ -size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg, +size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgo alg, QCryptoCipherMode mode); @@ -156,7 +156,7 @@ size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg, * * Returns: a new cipher object, or NULL on error */ -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/include/crypto/hash.h b/include/crypto/hash.h index 54d87aa..1868d4a 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -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 @@ -23,7 +24,23 @@ #include "qapi/qapi-types-crypto.h" -/* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */ +#define QCRYPTO_HASH_DIGEST_LEN_MD5 16 +#define QCRYPTO_HASH_DIGEST_LEN_SHA1 20 +#define QCRYPTO_HASH_DIGEST_LEN_SHA224 28 +#define QCRYPTO_HASH_DIGEST_LEN_SHA256 32 +#define QCRYPTO_HASH_DIGEST_LEN_SHA384 48 +#define QCRYPTO_HASH_DIGEST_LEN_SHA512 64 +#define QCRYPTO_HASH_DIGEST_LEN_RIPEMD160 20 +#define QCRYPTO_HASH_DIGEST_LEN_SM3 32 + +/* See also "QCryptoHashAlgo" defined in qapi/crypto.json */ + +typedef struct QCryptoHash QCryptoHash; +struct QCryptoHash { + QCryptoHashAlgo alg; + void *opaque; + void *driver; +}; /** * qcrypto_hash_supports: @@ -34,7 +51,7 @@ * * Returns: true if the algorithm is supported, false otherwise */ -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg); +gboolean qcrypto_hash_supports(QCryptoHashAlgo alg); /** @@ -45,7 +62,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg); * * Returns: the digest length in bytes */ -size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg); +size_t qcrypto_hash_digest_len(QCryptoHashAlgo alg); /** * qcrypto_hash_bytesv: @@ -57,15 +74,22 @@ size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg); * @errp: pointer to a NULL-initialized error object * * Computes the hash across all the memory regions - * present in @iov. The @result pointer will be - * filled with raw bytes representing the computed - * hash, which will have length @resultlen. The - * memory pointer in @result must be released - * with a call to g_free() when no longer required. + * present in @iov. + * + * If @result_len is set to a non-zero value by the caller, then + * @result must hold a pointer that is @result_len in size, and + * @result_len match the size of the hash output. The digest will + * be written into @result. + * + * If @result_len is set to zero, then this function will allocate + * a buffer to hold the hash output digest, storing a pointer to + * the buffer in @result, and setting @result_len to its size. + * The memory referenced in @result must be released with a call + * to g_free() when no longer required by the caller. * * Returns: 0 on success, -1 on error */ -int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg, +int qcrypto_hash_bytesv(QCryptoHashAlgo alg, const struct iovec *iov, size_t niov, uint8_t **result, @@ -82,15 +106,22 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg, * @errp: pointer to a NULL-initialized error object * * Computes the hash across all the memory region - * @buf of length @len. The @result pointer will be - * filled with raw bytes representing the computed - * hash, which will have length @resultlen. The - * memory pointer in @result must be released - * with a call to g_free() when no longer required. + * @buf of length @len. + * + * If @result_len is set to a non-zero value by the caller, then + * @result must hold a pointer that is @result_len in size, and + * @result_len match the size of the hash output. The digest will + * be written into @result. + * + * If @result_len is set to zero, then this function will allocate + * a buffer to hold the hash output digest, storing a pointer to + * the buffer in @result, and setting @result_len to its size. + * The memory referenced in @result must be released with a call + * to g_free() when no longer required by the caller. * * Returns: 0 on success, -1 on error */ -int qcrypto_hash_bytes(QCryptoHashAlgorithm alg, +int qcrypto_hash_bytes(QCryptoHashAlgo alg, const char *buf, size_t len, uint8_t **result, @@ -114,13 +145,133 @@ int qcrypto_hash_bytes(QCryptoHashAlgorithm alg, * * Returns: 0 on success, -1 on error */ -int qcrypto_hash_digestv(QCryptoHashAlgorithm alg, +int qcrypto_hash_digestv(QCryptoHashAlgo alg, const struct iovec *iov, size_t niov, char **digest, Error **errp); /** + * qcrypto_hash_updatev: + * @hash: hash object from qcrypto_hash_new + * @iov: the array of memory regions to hash + * @niov: the length of @iov + * @errp: pointer to a NULL-initialized error object + * + * Updates the given hash object with all the memory regions + * present in @iov. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_updatev(QCryptoHash *hash, + const struct iovec *iov, + size_t niov, + Error **errp); +/** + * qcrypto_hash_update: + * @hash: hash object from qcrypto_hash_new + * @buf: the memory region to hash + * @len: the length of @buf + * @errp: pointer to a NULL-initialized error object + * + * Updates the given hash object with the data from + * the given buffer. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_update(QCryptoHash *hash, + const char *buf, + size_t len, + Error **errp); + +/** + * qcrypto_hash_finalize_digest: + * @hash: the hash object to finalize + * @digest: pointer to hold output hash + * @errp: pointer to a NULL-initialized error object + * + * Computes the hash from the given hash object. Hash object + * is expected to have its data updated from the qcrypto_hash_update function. + * The @digest pointer will be filled with the printable hex digest of the + * computed hash, which will be terminated by '\0'. The memory pointer + * in @digest must be released with a call to g_free() when + * no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_finalize_digest(QCryptoHash *hash, + char **digest, + Error **errp); + +/** + * qcrypto_hash_finalize_base64: + * @hash_ctx: hash object to finalize + * @base64: pointer to store the hash result in + * @errp: pointer to a NULL-initialized error object + * + * Computes the hash from the given hash object. Hash object + * is expected to have it's data updated from the qcrypto_hash_update function. + * The @base64 pointer will be filled with the base64 encoding of the computed + * hash, which will be terminated by '\0'. The memory pointer in @base64 + * must be released with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_finalize_base64(QCryptoHash *hash, + char **base64, + Error **errp); + +/** + * qcrypto_hash_finalize_bytes: + * @hash_ctx: hash object to finalize + * @result: pointer to store the hash result in + * @result_len: Pointer to store the length of the result in + * @errp: pointer to a NULL-initialized error object + * + * Computes the hash from the given hash object. Hash object + * is expected to have it's data updated from the qcrypto_hash_update function. + * + * If @result_len is set to a non-zero value by the caller, then + * @result must hold a pointer that is @result_len in size, and + * @result_len match the size of the hash output. The digest will + * be written into @result. + * + * If @result_len is set to zero, then this function will allocate + * a buffer to hold the hash output digest, storing a pointer to + * the buffer in @result, and setting @result_len to its size. + * The memory referenced in @result must be released with a call + * to g_free() when no longer required by the caller. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hash_finalize_bytes(QCryptoHash *hash, + uint8_t **result, + size_t *result_len, + Error **errp); + +/** + * qcrypto_hash_new: + * @alg: the hash algorithm + * @errp: pointer to a NULL-initialized error object + * + * Creates a new hashing context for the chosen algorithm for + * usage with qcrypto_hash_update. + * + * Returns: New hash object with the given algorithm, or NULL on error. + */ +QCryptoHash *qcrypto_hash_new(QCryptoHashAlgo alg, Error **errp); + +/** + * qcrypto_hash_free: + * @hash: hash object to free + * + * Frees a hashing context for the chosen algorithm. + */ +void qcrypto_hash_free(QCryptoHash *hash); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHash, qcrypto_hash_free) + +/** * qcrypto_hash_digest: * @alg: the hash algorithm * @buf: the memory region to hash @@ -137,7 +288,7 @@ int qcrypto_hash_digestv(QCryptoHashAlgorithm alg, * * Returns: 0 on success, -1 on error */ -int qcrypto_hash_digest(QCryptoHashAlgorithm alg, +int qcrypto_hash_digest(QCryptoHashAlgo alg, const char *buf, size_t len, char **digest, @@ -160,7 +311,7 @@ int qcrypto_hash_digest(QCryptoHashAlgorithm alg, * * Returns: 0 on success, -1 on error */ -int qcrypto_hash_base64v(QCryptoHashAlgorithm alg, +int qcrypto_hash_base64v(QCryptoHashAlgo alg, const struct iovec *iov, size_t niov, char **base64, @@ -183,7 +334,7 @@ int qcrypto_hash_base64v(QCryptoHashAlgorithm alg, * * Returns: 0 on success, -1 on error */ -int qcrypto_hash_base64(QCryptoHashAlgorithm alg, +int qcrypto_hash_base64(QCryptoHashAlgo alg, const char *buf, size_t len, char **base64, diff --git a/include/crypto/hmac.h b/include/crypto/hmac.h index ad4d778..da8a1e3 100644 --- a/include/crypto/hmac.h +++ b/include/crypto/hmac.h @@ -16,7 +16,7 @@ typedef struct QCryptoHmac QCryptoHmac; struct QCryptoHmac { - QCryptoHashAlgorithm alg; + QCryptoHashAlgo alg; void *opaque; void *driver; }; @@ -31,7 +31,7 @@ struct QCryptoHmac { * Returns: * true if the algorithm is supported, false otherwise */ -bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg); +bool qcrypto_hmac_supports(QCryptoHashAlgo alg); /** * qcrypto_hmac_new: @@ -52,7 +52,7 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg); * Returns: * a new hmac object, or NULL on error */ -QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgo alg, const uint8_t *key, size_t nkey, Error **errp); @@ -77,11 +77,18 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHmac, qcrypto_hmac_free) * @errp: pointer to a NULL-initialized error object * * Computes the hmac across all the memory regions - * present in @iov. The @result pointer will be - * filled with raw bytes representing the computed - * hmac, which will have length @resultlen. The - * memory pointer in @result must be released - * with a call to g_free() when no longer required. + * present in @iov. + * + * If @result_len is set to a non-zero value by the caller, then + * @result must hold a pointer that is @result_len in size, and + * @result_len match the size of the hash output. The digest will + * be written into @result. + * + * If @result_len is set to zero, then this function will allocate + * a buffer to hold the hash output digest, storing a pointer to + * the buffer in @result, and setting @result_len to its size. + * The memory referenced in @result must be released with a call + * to g_free() when no longer required by the caller. * * Returns: * 0 on success, -1 on error @@ -103,11 +110,18 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac, * @errp: pointer to a NULL-initialized error object * * Computes the hmac across all the memory region - * @buf of length @len. The @result pointer will be - * filled with raw bytes representing the computed - * hmac, which will have length @resultlen. The - * memory pointer in @result must be released - * with a call to g_free() when no longer required. + * @buf of length @len. + * + * If @result_len is set to a non-zero value by the caller, then + * @result must hold a pointer that is @result_len in size, and + * @result_len match the size of the hash output. The digest will + * be written into @result. + * + * If @result_len is set to zero, then this function will allocate + * a buffer to hold the hash output digest, storing a pointer to + * the buffer in @result, and setting @result_len to its size. + * The memory referenced in @result must be released with a call + * to g_free() when no longer required by the caller. * * Returns: * 0 on success, -1 on error diff --git a/include/crypto/ivgen.h b/include/crypto/ivgen.h index a09d573..bfa5d28 100644 --- a/include/crypto/ivgen.h +++ b/include/crypto/ivgen.h @@ -44,22 +44,22 @@ * * g_assert((ndata % 512) == 0); * - * QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_ESSIV, - * QCRYPTO_CIPHER_ALG_AES_128, - * QCRYPTO_HASH_ALG_SHA256, + * QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IV_GEN_ALGO_ESSIV, + * QCRYPTO_CIPHER_ALGO_AES_128, + * QCRYPTO_HASH_ALGO_SHA256, * key, nkey, errp); * if (!ivgen) { * return -1; * } * - * QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, + * QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128, * QCRYPTO_CIPHER_MODE_CBC, * key, nkey, errp); * if (!cipher) { * goto error; * } * - * niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128, + * niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALGO_AES_128, * QCRYPTO_CIPHER_MODE_CBC); * iv = g_new0(uint8_t, niv); * @@ -97,7 +97,7 @@ typedef struct QCryptoIVGen QCryptoIVGen; -/* See also QCryptoIVGenAlgorithm enum in qapi/crypto.json */ +/* See also QCryptoIVGenAlgo enum in qapi/crypto.json */ /** @@ -113,19 +113,19 @@ typedef struct QCryptoIVGen QCryptoIVGen; * are required or not depends on the choice of @alg * requested. * - * - QCRYPTO_IVGEN_ALG_PLAIN + * - QCRYPTO_IV_GEN_ALGO_PLAIN * * The IVs are generated by the 32-bit truncated sector * number. This should never be used for block devices * that are larger than 2^32 sectors in size. * All the other parameters are unused. * - * - QCRYPTO_IVGEN_ALG_PLAIN64 + * - QCRYPTO_IV_GEN_ALGO_PLAIN64 * * The IVs are generated by the 64-bit sector number. * All the other parameters are unused. * - * - QCRYPTO_IVGEN_ALG_ESSIV: + * - QCRYPTO_IV_GEN_ALGO_ESSIV: * * The IVs are generated by encrypting the 64-bit sector * number with a hash of an encryption key. The @cipheralg, @@ -133,9 +133,9 @@ typedef struct QCryptoIVGen QCryptoIVGen; * * Returns: a new IV generator, or NULL on error */ -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); @@ -167,7 +167,7 @@ int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen, * * Returns: the IV generator algorithm */ -QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen); +QCryptoIVGenAlgo qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen); /** @@ -179,7 +179,7 @@ QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen); * * Returns: the cipher algorithm */ -QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen); +QCryptoCipherAlgo qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen); /** @@ -191,7 +191,7 @@ QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen); * * Returns: the hash algorithm */ -QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen); +QCryptoHashAlgo qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen); /** diff --git a/include/crypto/pbkdf.h b/include/crypto/pbkdf.h index 2c31a44..cf59fce 100644 --- a/include/crypto/pbkdf.h +++ b/include/crypto/pbkdf.h @@ -38,7 +38,7 @@ * .... * * char *password = "a-typical-awful-user-password"; - * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALG_AES_128); + * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALGO_AES_128); * uint8_t *salt = g_new0(uint8_t, nkey); * uint8_t *key = g_new0(uint8_t, nkey); * int iterations; @@ -50,7 +50,7 @@ * return -1; * } * - * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALG_SHA256, + * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALGO_SHA256, * (const uint8_t *)password, * strlen(password), * salt, nkey, errp); @@ -60,7 +60,7 @@ * return -1; * } * - * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALG_SHA256, + * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALGO_SHA256, * (const uint8_t *)password, strlen(password), * salt, nkey, iterations, key, nkey, errp) < 0) { * g_free(key); @@ -70,7 +70,7 @@ * * g_free(salt); * - * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, + * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128, * QCRYPTO_CIPHER_MODE_ECB, * key, nkey, errp); * g_free(key); @@ -92,7 +92,7 @@ * * Returns true if supported, false otherwise */ -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash); +bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash); /** @@ -119,7 +119,7 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash); * * Returns: 0 on success, -1 on error */ -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, @@ -147,7 +147,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, * * Returns: number of iterations in 1 second, -1 on error */ -uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, +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, diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h index 571049b..d77ae0d 100644 --- a/include/crypto/tlssession.h +++ b/include/crypto/tlssession.h @@ -75,12 +75,14 @@ * GINT_TO_POINTER(fd)); * * while (1) { - * if (qcrypto_tls_session_handshake(sess, errp) < 0) { + * int ret = qcrypto_tls_session_handshake(sess, errp); + * + * if (ret < 0) { * qcrypto_tls_session_free(sess); * return -1; * } * - * switch(qcrypto_tls_session_get_handshake_status(sess)) { + * switch(ret) { * case QCRYPTO_TLS_HANDSHAKE_COMPLETE: * if (qcrypto_tls_session_check_credentials(sess, errp) < )) { * qcrypto_tls_session_free(sess); @@ -107,6 +109,7 @@ typedef struct QCryptoTLSSession QCryptoTLSSession; +#define QCRYPTO_TLS_SESSION_ERR_BLOCK -2 /** * qcrypto_tls_session_new: @@ -169,7 +172,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free) * * Validate the peer's credentials after a successful * TLS handshake. It is an error to call this before - * qcrypto_tls_session_get_handshake_status() returns + * qcrypto_tls_session_handshake() returns * QCRYPTO_TLS_HANDSHAKE_COMPLETE * * Returns 0 if the credentials validated, -1 on error @@ -177,12 +180,18 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free) int qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess, Error **errp); +/* + * These must return QCRYPTO_TLS_SESSION_ERR_BLOCK if the I/O + * would block, but on other errors, must fill 'errp' + */ typedef ssize_t (*QCryptoTLSSessionWriteFunc)(const char *buf, size_t len, - void *opaque); + void *opaque, + Error **errp); typedef ssize_t (*QCryptoTLSSessionReadFunc)(char *buf, size_t len, - void *opaque); + void *opaque, + Error **errp); /** * qcrypto_tls_session_set_callbacks: @@ -212,41 +221,55 @@ void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess, * @sess: the TLS session object * @buf: the plain text to send * @len: the length of @buf + * @errp: pointer to hold returned error object * * Encrypt @len bytes of the data in @buf and send * it to the remote peer using the callback previously * registered with qcrypto_tls_session_set_callbacks() * * It is an error to call this before - * qcrypto_tls_session_get_handshake_status() returns + * qcrypto_tls_session_handshake() returns * QCRYPTO_TLS_HANDSHAKE_COMPLETE * - * Returns: the number of bytes sent, or -1 on error + * Returns: the number of bytes sent, + * or QCRYPTO_TLS_SESSION_ERR_BLOCK if the write would block, + * or -1 on error. */ ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess, const char *buf, - size_t len); + size_t len, + Error **errp); /** * qcrypto_tls_session_read: * @sess: the TLS session object * @buf: to fill with plain text received * @len: the length of @buf + * @gracefulTermination: treat premature termination as graceful EOF + * @errp: pointer to hold returned error object * * Receive up to @len bytes of data from the remote peer * using the callback previously registered with * qcrypto_tls_session_set_callbacks(), decrypt it and * store it in @buf. * + * If @gracefulTermination is true, then a premature termination + * of the TLS session will be treated as indicating EOF, as + * opposed to an error. + * * It is an error to call this before - * qcrypto_tls_session_get_handshake_status() returns + * qcrypto_tls_session_handshake() returns * QCRYPTO_TLS_HANDSHAKE_COMPLETE * - * Returns: the number of bytes received, or -1 on error + * Returns: the number of bytes received, + * or QCRYPTO_TLS_SESSION_ERR_BLOCK if the receive would block, + * or -1 on error. */ ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess, char *buf, - size_t len); + size_t len, + bool gracefulTermination, + Error **errp); /** * qcrypto_tls_session_check_pending: @@ -268,8 +291,7 @@ size_t qcrypto_tls_session_check_pending(QCryptoTLSSession *sess); * the underlying data channel is non-blocking, then * this method may return control before the handshake * is complete. On non-blocking channels the - * qcrypto_tls_session_get_handshake_status() method - * should be used to determine whether the handshake + * return value determines whether the handshake * has completed, or is waiting to send or receive * data. In the latter cases, the caller should setup * an event loop watch and call this method again @@ -285,22 +307,27 @@ typedef enum { QCRYPTO_TLS_HANDSHAKE_RECVING, } QCryptoTLSSessionHandshakeStatus; +typedef enum { + QCRYPTO_TLS_BYE_COMPLETE, + QCRYPTO_TLS_BYE_SENDING, + QCRYPTO_TLS_BYE_RECVING, +} QCryptoTLSSessionByeStatus; + /** - * qcrypto_tls_session_get_handshake_status: - * @sess: the TLS session object - * - * Check the status of the TLS handshake. This - * is used with non-blocking data channels to - * determine whether the handshake is waiting - * to send or receive further data to/from the - * remote peer. + * qcrypto_tls_session_bye: + * @session: the TLS session object + * @errp: pointer to a NULL-initialized error object * - * Once this returns QCRYPTO_TLS_HANDSHAKE_COMPLETE - * it is permitted to send/receive payload data on - * the channel + * Start, or continue, a TLS termination sequence. If the underlying + * data channel is non-blocking, then this method may return control + * before the termination is complete. The return value will indicate + * whether the termination has completed, or is waiting to send or + * receive data. In the latter cases, the caller should setup an event + * loop watch and call this method again once the underlying data + * channel is ready to read or write again. */ -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess); +int +qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp); /** * qcrypto_tls_session_get_key_size: diff --git a/include/crypto/x509-utils.h b/include/crypto/x509-utils.h new file mode 100644 index 0000000..1e99661 --- /dev/null +++ b/include/crypto/x509-utils.h @@ -0,0 +1,22 @@ +/* + * 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. + */ + +#ifndef QCRYPTO_X509_UTILS_H +#define QCRYPTO_X509_UTILS_H + +#include "crypto/hash.h" + +int qcrypto_get_x509_cert_fingerprint(uint8_t *cert, size_t size, + QCryptoHashAlgo hash, + uint8_t *result, + size_t *resultlen, + Error **errp); + +#endif |