Import QEMU upstream snapshot d2e570c
Upstream: https://gitlab.com/qemu-project/qemu.git Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
This commit is contained in:
commit
cf256aa081
11315 files changed
+3598369
No files matched your search
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* AES round fragments, generic version
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* Copyright (C) 2023 Linaro, Ltd.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_AES_ROUND_H
|
||||
#define CRYPTO_AES_ROUND_H
|
||||
|
||||
/* Hosts with acceleration will usually need a 16-byte vector type. */
|
||||
typedef uint8_t AESStateVec __attribute__((vector_size(16)));
|
||||
|
||||
typedef union {
|
||||
uint8_t b[16];
|
||||
uint32_t w[4];
|
||||
uint64_t d[2];
|
||||
AESStateVec v;
|
||||
} AESState;
|
||||
|
||||
#include "host/crypto/aes-round.h"
|
||||
|
||||
/*
|
||||
* Perform MixColumns.
|
||||
*/
|
||||
|
||||
void aesenc_MC_gen(AESState *ret, const AESState *st);
|
||||
void aesenc_MC_genrev(AESState *ret, const AESState *st);
|
||||
|
||||
static inline void aesenc_MC(AESState *r, const AESState *st, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesenc_MC_accel(r, st, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesenc_MC_gen(r, st);
|
||||
} else {
|
||||
aesenc_MC_genrev(r, st);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform SubBytes + ShiftRows + AddRoundKey.
|
||||
*/
|
||||
|
||||
void aesenc_SB_SR_AK_gen(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
void aesenc_SB_SR_AK_genrev(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
|
||||
static inline void aesenc_SB_SR_AK(AESState *r, const AESState *st,
|
||||
const AESState *rk, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesenc_SB_SR_AK_accel(r, st, rk, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesenc_SB_SR_AK_gen(r, st, rk);
|
||||
} else {
|
||||
aesenc_SB_SR_AK_genrev(r, st, rk);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform SubBytes + ShiftRows + MixColumns + AddRoundKey.
|
||||
*/
|
||||
|
||||
void aesenc_SB_SR_MC_AK_gen(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
void aesenc_SB_SR_MC_AK_genrev(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
|
||||
static inline void aesenc_SB_SR_MC_AK(AESState *r, const AESState *st,
|
||||
const AESState *rk, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesenc_SB_SR_MC_AK_accel(r, st, rk, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesenc_SB_SR_MC_AK_gen(r, st, rk);
|
||||
} else {
|
||||
aesenc_SB_SR_MC_AK_genrev(r, st, rk);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform InvMixColumns.
|
||||
*/
|
||||
|
||||
void aesdec_IMC_gen(AESState *ret, const AESState *st);
|
||||
void aesdec_IMC_genrev(AESState *ret, const AESState *st);
|
||||
|
||||
static inline void aesdec_IMC(AESState *r, const AESState *st, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesdec_IMC_accel(r, st, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesdec_IMC_gen(r, st);
|
||||
} else {
|
||||
aesdec_IMC_genrev(r, st);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform InvSubBytes + InvShiftRows + AddRoundKey.
|
||||
*/
|
||||
|
||||
void aesdec_ISB_ISR_AK_gen(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
void aesdec_ISB_ISR_AK_genrev(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
|
||||
static inline void aesdec_ISB_ISR_AK(AESState *r, const AESState *st,
|
||||
const AESState *rk, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesdec_ISB_ISR_AK_accel(r, st, rk, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesdec_ISB_ISR_AK_gen(r, st, rk);
|
||||
} else {
|
||||
aesdec_ISB_ISR_AK_genrev(r, st, rk);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform InvSubBytes + InvShiftRows + AddRoundKey + InvMixColumns.
|
||||
*/
|
||||
|
||||
void aesdec_ISB_ISR_AK_IMC_gen(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
void aesdec_ISB_ISR_AK_IMC_genrev(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
|
||||
static inline void aesdec_ISB_ISR_AK_IMC(AESState *r, const AESState *st,
|
||||
const AESState *rk, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesdec_ISB_ISR_AK_IMC_accel(r, st, rk, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesdec_ISB_ISR_AK_IMC_gen(r, st, rk);
|
||||
} else {
|
||||
aesdec_ISB_ISR_AK_IMC_genrev(r, st, rk);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform InvSubBytes + InvShiftRows + InvMixColumns + AddRoundKey.
|
||||
*/
|
||||
|
||||
void aesdec_ISB_ISR_IMC_AK_gen(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
void aesdec_ISB_ISR_IMC_AK_genrev(AESState *ret, const AESState *st,
|
||||
const AESState *rk);
|
||||
|
||||
static inline void aesdec_ISB_ISR_IMC_AK(AESState *r, const AESState *st,
|
||||
const AESState *rk, bool be)
|
||||
{
|
||||
if (HAVE_AES_ACCEL) {
|
||||
aesdec_ISB_ISR_IMC_AK_accel(r, st, rk, be);
|
||||
} else if (HOST_BIG_ENDIAN == be) {
|
||||
aesdec_ISB_ISR_IMC_AK_gen(r, st, rk);
|
||||
} else {
|
||||
aesdec_ISB_ISR_IMC_AK_genrev(r, st, rk);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CRYPTO_AES_ROUND_H */
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef QEMU_AES_H
|
||||
#define QEMU_AES_H
|
||||
|
||||
#define AES_MAXNR 14
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
struct aes_key_st {
|
||||
uint32_t rd_key[4 *(AES_MAXNR + 1)];
|
||||
int rounds;
|
||||
};
|
||||
typedef struct aes_key_st AES_KEY;
|
||||
|
||||
/* FreeBSD/OpenSSL have their own AES functions with the same names in -lcrypto
|
||||
* (which might be pulled in via curl), so redefine to avoid conflicts. */
|
||||
#define AES_set_encrypt_key QEMU_AES_set_encrypt_key
|
||||
#define AES_set_decrypt_key QEMU_AES_set_decrypt_key
|
||||
#define AES_encrypt QEMU_AES_encrypt
|
||||
#define AES_decrypt QEMU_AES_decrypt
|
||||
|
||||
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
|
||||
void AES_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void AES_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
|
||||
extern const uint8_t AES_sbox[256];
|
||||
extern const uint8_t AES_isbox[256];
|
||||
|
||||
/*
|
||||
AES_Te0[x] = S [x].[02, 01, 01, 03];
|
||||
AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
|
||||
*/
|
||||
|
||||
extern const uint32_t AES_Te0[256], AES_Td0[256];
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* QEMU Crypto anti forensic information splitter
|
||||
*
|
||||
* Copyright (c) 2015-2016 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_AFSPLIT_H
|
||||
#define QCRYPTO_AFSPLIT_H
|
||||
|
||||
#include "crypto/hash.h"
|
||||
|
||||
/**
|
||||
* This module implements the anti-forensic splitter that is specified
|
||||
* as part of the LUKS format:
|
||||
*
|
||||
* http://clemens.endorphin.org/cryptography
|
||||
* http://clemens.endorphin.org/TKS1-draft.pdf
|
||||
*
|
||||
* The core idea is to take a short piece of data (key material)
|
||||
* and process it to expand it to a much larger piece of data.
|
||||
* The expansion process is reversible, to obtain the original
|
||||
* short data. The key property of the expansion is that if any
|
||||
* byte in the larger data set is changed / missing, it should be
|
||||
* impossible to recreate the original short data.
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating a large split key for storage</title>
|
||||
* <programlisting>
|
||||
* size_t nkey = 32;
|
||||
* uint32_t stripes = 32768; // To produce a 1 MB split key
|
||||
* uint8_t *masterkey = ....a 32-byte AES key...
|
||||
* uint8_t *splitkey;
|
||||
*
|
||||
* splitkey = g_new0(uint8_t, nkey * stripes);
|
||||
*
|
||||
* if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALGO_SHA256,
|
||||
* nkey, stripes,
|
||||
* masterkey, splitkey, errp) < 0) {
|
||||
* g_free(splitkey);
|
||||
* g_free(masterkey);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* ...store splitkey somewhere...
|
||||
*
|
||||
* g_free(splitkey);
|
||||
* g_free(masterkey);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* <example>
|
||||
* <title>Retrieving a master key from storage</title>
|
||||
* <programlisting>
|
||||
* size_t nkey = 32;
|
||||
* uint32_t stripes = 32768; // To produce a 1 MB split key
|
||||
* uint8_t *masterkey;
|
||||
* uint8_t *splitkey = .... read in 1 MB of data...
|
||||
*
|
||||
* masterkey = g_new0(uint8_t, nkey);
|
||||
*
|
||||
* if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALGO_SHA256,
|
||||
* nkey, stripes,
|
||||
* splitkey, masterkey, errp) < 0) {
|
||||
* g_free(splitkey);
|
||||
* g_free(masterkey);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* ..decrypt data with masterkey...
|
||||
*
|
||||
* g_free(splitkey);
|
||||
* g_free(masterkey);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*/
|
||||
|
||||
/**
|
||||
* qcrypto_afsplit_encode:
|
||||
* @hash: the hash algorithm to use for data expansion
|
||||
* @blocklen: the size of @in in bytes
|
||||
* @stripes: the number of times to expand @in in size
|
||||
* @in: the master key to be expanded in size
|
||||
* @out: preallocated buffer to hold the split key
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Split the data in @in, which is @blocklen bytes in
|
||||
* size, to form a larger piece of data @out, which is
|
||||
* @blocklen * @stripes bytes in size.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error;
|
||||
*/
|
||||
int qcrypto_afsplit_encode(QCryptoHashAlgo hash,
|
||||
size_t blocklen,
|
||||
uint32_t stripes,
|
||||
const uint8_t *in,
|
||||
uint8_t *out,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_afsplit_decode:
|
||||
* @hash: the hash algorithm to use for data compression
|
||||
* @blocklen: the size of @out in bytes
|
||||
* @stripes: the number of times to decrease @in in size
|
||||
* @in: the split key to be recombined
|
||||
* @out: preallocated buffer to hold the master key
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Join the data in @in, which is @blocklen * @stripes
|
||||
* bytes in size, to form the original small piece of
|
||||
* data @out, which is @blocklen bytes in size.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error;
|
||||
*/
|
||||
int qcrypto_afsplit_decode(QCryptoHashAlgo hash,
|
||||
size_t blocklen,
|
||||
uint32_t stripes,
|
||||
const uint8_t *in,
|
||||
uint8_t *out,
|
||||
Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_AFSPLIT_H */
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* QEMU Crypto asymmetric algorithms
|
||||
*
|
||||
* Copyright (c) 2022 Bytedance
|
||||
* Author: zhenwei pi <[email protected]>
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_AKCIPHER_H
|
||||
#define QCRYPTO_AKCIPHER_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
|
||||
typedef struct QCryptoAkCipher QCryptoAkCipher;
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_supports:
|
||||
* @opts: the asymmetric key algorithm and related options
|
||||
*
|
||||
* Determine if asymmetric key cipher described with @opts is
|
||||
* supported by the current configured build
|
||||
*
|
||||
* Returns: true if it is supported, false otherwise.
|
||||
*/
|
||||
bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_new:
|
||||
* @opts: specify the algorithm and the related arguments
|
||||
* @type: private or public key type
|
||||
* @key: buffer to store the key
|
||||
* @key_len: the length of key buffer
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Create akcipher context
|
||||
*
|
||||
* Returns: On success, a new QCryptoAkCipher initialized with @opt
|
||||
* is created and returned, otherwise NULL is returned.
|
||||
*/
|
||||
|
||||
QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts,
|
||||
QCryptoAkCipherKeyType type,
|
||||
const uint8_t *key, size_t key_len,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_encrypt:
|
||||
* @akcipher: akcipher context
|
||||
* @in: plaintext pending to be encrypted
|
||||
* @in_len: length of plaintext, less or equal to the size reported
|
||||
* by a call to qcrypto_akcipher_max_plaintext_len()
|
||||
* @out: buffer to store the ciphertext
|
||||
* @out_len: length of ciphertext, less or equal to the size reported
|
||||
* by a call to qcrypto_akcipher_max_ciphertext_len()
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Encrypt @in and write ciphertext into @out
|
||||
*
|
||||
* Returns: length of ciphertext if encrypt succeed,
|
||||
* otherwise -1 is returned
|
||||
*/
|
||||
int qcrypto_akcipher_encrypt(QCryptoAkCipher *akcipher,
|
||||
const void *in, size_t in_len,
|
||||
void *out, size_t out_len, Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_decrypt:
|
||||
* @akcipher: akcipher context
|
||||
* @in: ciphertext to be decrypted
|
||||
* @in_len: the length of ciphertext, less or equal to the size reported
|
||||
* by a call to qcrypto_akcipher_max_ciphertext_len()
|
||||
* @out: buffer to store the plaintext
|
||||
* @out_len: length of the plaintext buffer, less or equal to the size
|
||||
* reported by a call to qcrypto_akcipher_max_plaintext_len()
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Decrypt @in and write plaintext into @out
|
||||
*
|
||||
* Returns: length of plaintext if decrypt succeed,
|
||||
* otherwise -1 is returned
|
||||
*/
|
||||
int qcrypto_akcipher_decrypt(QCryptoAkCipher *akcipher,
|
||||
const void *in, size_t in_len,
|
||||
void *out, size_t out_len, Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_sign:
|
||||
* @akcipher: akcipher context
|
||||
* @in: data to be signed
|
||||
* @in_len: the length of data, less or equal to the size reported
|
||||
* by a call to qcrypto_akcipher_max_dgst_len()
|
||||
* @out: buffer to store the signature
|
||||
* @out_len: length of the signature buffer, less or equal to the size
|
||||
* by a call to qcrypto_akcipher_max_signature_len()
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Generate signature for @in, write into @out
|
||||
*
|
||||
* Returns: length of signature if succeed,
|
||||
* otherwise -1 is returned
|
||||
*/
|
||||
int qcrypto_akcipher_sign(QCryptoAkCipher *akcipher,
|
||||
const void *in, size_t in_len,
|
||||
void *out, size_t out_len, Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_verify:
|
||||
* @akcipher: akcipher context
|
||||
* @in: pointer to the signature
|
||||
* @in_len: length of signature, ess or equal to the size reported
|
||||
* by a call to qcrypto_akcipher_max_signature_len()
|
||||
* @in2: pointer to original data
|
||||
* @in2_len: the length of original data, less or equal to the size
|
||||
* by a call to qcrypto_akcipher_max_dgst_len()
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Verify @in and @in2 match or not
|
||||
*
|
||||
* Returns: 0 for succeed,
|
||||
* otherwise -1 is returned
|
||||
*/
|
||||
int qcrypto_akcipher_verify(QCryptoAkCipher *akcipher,
|
||||
const void *in, size_t in_len,
|
||||
const void *in2, size_t in2_len, Error **errp);
|
||||
|
||||
int qcrypto_akcipher_max_plaintext_len(QCryptoAkCipher *akcipher);
|
||||
|
||||
int qcrypto_akcipher_max_ciphertext_len(QCryptoAkCipher *akcipher);
|
||||
|
||||
int qcrypto_akcipher_max_signature_len(QCryptoAkCipher *akcipher);
|
||||
|
||||
int qcrypto_akcipher_max_dgst_len(QCryptoAkCipher *akcipher);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_free:
|
||||
* @akcipher: akcipher context
|
||||
*
|
||||
* Free the akcipher context
|
||||
*
|
||||
*/
|
||||
void qcrypto_akcipher_free(QCryptoAkCipher *akcipher);
|
||||
|
||||
/**
|
||||
* qcrypto_akcipher_export_p8info:
|
||||
* @opts: the options of the akcipher to be exported.
|
||||
* @key: the original key of the akcipher to be exported.
|
||||
* @keylen: length of the 'key'
|
||||
* @dst: output parameter, if export succeed, *dst is set to the
|
||||
* PKCS#8 encoded private key, caller MUST free this key with
|
||||
* g_free after use.
|
||||
* @dst_len: output parameter, indicates the length of PKCS#8 encoded
|
||||
* key.
|
||||
*
|
||||
* Export the akcipher into DER encoded pkcs#8 private key info, expects
|
||||
* |key| stores a valid asymmetric PRIVATE key.
|
||||
*
|
||||
* Returns: 0 for succeed, otherwise -1 is returned.
|
||||
*/
|
||||
int qcrypto_akcipher_export_p8info(const QCryptoAkCipherOptions *opts,
|
||||
uint8_t *key, size_t keylen,
|
||||
uint8_t **dst, size_t *dst_len,
|
||||
Error **errp);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoAkCipher, qcrypto_akcipher_free)
|
||||
|
||||
#endif /* QCRYPTO_AKCIPHER_H */
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* QEMU Crypto block device encryption
|
||||
*
|
||||
* Copyright (c) 2015-2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_BLOCK_H
|
||||
#define QCRYPTO_BLOCK_H
|
||||
|
||||
#include "crypto/cipher.h"
|
||||
#include "crypto/ivgen.h"
|
||||
|
||||
typedef struct QCryptoBlock QCryptoBlock;
|
||||
|
||||
/* See also QCryptoBlockFormat, QCryptoBlockCreateOptions
|
||||
* and QCryptoBlockOpenOptions in qapi/crypto.json */
|
||||
|
||||
typedef int (*QCryptoBlockReadFunc)(QCryptoBlock *block,
|
||||
size_t offset,
|
||||
uint8_t *buf,
|
||||
size_t buflen,
|
||||
void *opaque,
|
||||
Error **errp);
|
||||
|
||||
typedef int (*QCryptoBlockInitFunc)(QCryptoBlock *block,
|
||||
size_t headerlen,
|
||||
void *opaque,
|
||||
Error **errp);
|
||||
|
||||
typedef int (*QCryptoBlockWriteFunc)(QCryptoBlock *block,
|
||||
size_t offset,
|
||||
const uint8_t *buf,
|
||||
size_t buflen,
|
||||
void *opaque,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_block_has_format:
|
||||
* @format: the encryption format
|
||||
* @buf: the data from head of the volume
|
||||
* @len: the length of @buf in bytes
|
||||
*
|
||||
* Given @len bytes of data from the head of a storage volume
|
||||
* in @buf, probe to determine if the volume has the encryption
|
||||
* format specified in @format.
|
||||
*
|
||||
* Returns: true if the data in @buf matches @format
|
||||
*/
|
||||
bool qcrypto_block_has_format(QCryptoBlockFormat format,
|
||||
const uint8_t *buf,
|
||||
size_t buflen);
|
||||
|
||||
typedef enum {
|
||||
QCRYPTO_BLOCK_OPEN_NO_IO = (1 << 0),
|
||||
QCRYPTO_BLOCK_OPEN_DETACHED = (1 << 1),
|
||||
} QCryptoBlockOpenFlags;
|
||||
|
||||
/**
|
||||
* qcrypto_block_open:
|
||||
* @options: the encryption options
|
||||
* @optprefix: name prefix for options
|
||||
* @readfunc: callback for reading data from the volume
|
||||
* @opaque: data to pass to @readfunc
|
||||
* @flags: bitmask of QCryptoBlockOpenFlags values
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a new block encryption object for an existing
|
||||
* storage volume encrypted with format identified by
|
||||
* the parameters in @options.
|
||||
*
|
||||
* This will use @readfunc to initialize the encryption
|
||||
* context based on the volume header(s), extracting the
|
||||
* master key(s) as required.
|
||||
*
|
||||
* If @flags contains QCRYPTO_BLOCK_OPEN_NO_IO then
|
||||
* the open process will be optimized to skip any parts
|
||||
* that are only required to perform I/O. In particular
|
||||
* this would usually avoid the need to decrypt any
|
||||
* master keys. The only thing that can be done with
|
||||
* the resulting QCryptoBlock object would be to query
|
||||
* metadata such as the payload offset. There will be
|
||||
* no cipher or ivgen objects available.
|
||||
*
|
||||
* If @flags contains QCRYPTO_BLOCK_OPEN_DETACHED then
|
||||
* the open process will be optimized to skip the LUKS
|
||||
* payload overlap check.
|
||||
*
|
||||
* If any part of initializing the encryption context
|
||||
* fails an error will be returned. This could be due
|
||||
* to the volume being in the wrong format, a cipher
|
||||
* or IV generator algorithm that is not supported,
|
||||
* or incorrect passphrases.
|
||||
*
|
||||
* Returns: a block encryption format, or NULL on error
|
||||
*/
|
||||
QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
|
||||
const char *optprefix,
|
||||
QCryptoBlockReadFunc readfunc,
|
||||
void *opaque,
|
||||
unsigned int flags,
|
||||
Error **errp);
|
||||
|
||||
typedef enum {
|
||||
QCRYPTO_BLOCK_CREATE_DETACHED = (1 << 0),
|
||||
} QCryptoBlockCreateFlags;
|
||||
|
||||
/**
|
||||
* qcrypto_block_create:
|
||||
* @options: the encryption options
|
||||
* @optprefix: name prefix for options
|
||||
* @initfunc: callback for initializing volume header
|
||||
* @writefunc: callback for writing data to the volume header
|
||||
* @opaque: data to pass to @initfunc and @writefunc
|
||||
* @flags: bitmask of QCryptoBlockCreateFlags values
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a new block encryption object for initializing
|
||||
* a storage volume to be encrypted with format identified
|
||||
* by the parameters in @options.
|
||||
*
|
||||
* This method will allocate space for a new volume header
|
||||
* using @initfunc and then write header data using @writefunc,
|
||||
* generating new master keys, etc as required. Any existing
|
||||
* data present on the volume will be irrevocably destroyed.
|
||||
*
|
||||
* If @flags contains QCRYPTO_BLOCK_CREATE_DETACHED then
|
||||
* the open process will set the payload_offset_sector to 0
|
||||
* to specify the starting point for the read/write of a
|
||||
* detached LUKS header image.
|
||||
*
|
||||
* If any part of initializing the encryption context
|
||||
* fails an error will be returned. This could be due
|
||||
* to the volume being in the wrong format, a cipher
|
||||
* or IV generator algorithm that is not supported,
|
||||
* or incorrect passphrases.
|
||||
*
|
||||
* Returns: a block encryption format, or NULL on error
|
||||
*/
|
||||
QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
|
||||
const char *optprefix,
|
||||
QCryptoBlockInitFunc initfunc,
|
||||
QCryptoBlockWriteFunc writefunc,
|
||||
void *opaque,
|
||||
unsigned int flags,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_block_amend_options:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* @readfunc: callback for reading data from the volume header
|
||||
* @writefunc: callback for writing data to the volume header
|
||||
* @opaque: data to pass to @readfunc and @writefunc
|
||||
* @options: the new/amended encryption options
|
||||
* @force: hint for the driver to allow unsafe operation
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Changes the crypto options of the encryption format
|
||||
*
|
||||
*/
|
||||
int qcrypto_block_amend_options(QCryptoBlock *block,
|
||||
QCryptoBlockReadFunc readfunc,
|
||||
QCryptoBlockWriteFunc writefunc,
|
||||
void *opaque,
|
||||
QCryptoBlockAmendOptions *options,
|
||||
bool force,
|
||||
Error **errp);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_block_calculate_payload_offset:
|
||||
* @create_opts: the encryption options
|
||||
* @optprefix: name prefix for options
|
||||
* @len: output for number of header bytes before payload
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Calculate the number of header bytes before the payload in an encrypted
|
||||
* storage volume. The header is an area before the payload that is reserved
|
||||
* for encryption metadata.
|
||||
*
|
||||
* Returns: true on success, false on error
|
||||
*/
|
||||
bool
|
||||
qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
|
||||
const char *optprefix,
|
||||
size_t *len,
|
||||
Error **errp);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_block_get_info:
|
||||
* @block: the block encryption object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Get information about the configuration options for the
|
||||
* block encryption object. This includes details such as
|
||||
* the cipher algorithms, modes, and initialization vector
|
||||
* generators.
|
||||
*
|
||||
* Returns: a block encryption info object, or NULL on error
|
||||
*/
|
||||
QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* @qcrypto_block_decrypt:
|
||||
* @block: the block encryption object
|
||||
* @offset: the position at which @iov was read
|
||||
* @buf: the buffer to decrypt
|
||||
* @len: the length of @buf in bytes
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Decrypt @len bytes of cipher text in @buf, writing
|
||||
* plain text back into @buf. @len and @offset must be
|
||||
* a multiple of the encryption format sector size.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure
|
||||
*/
|
||||
int qcrypto_block_decrypt(QCryptoBlock *block,
|
||||
uint64_t offset,
|
||||
uint8_t *buf,
|
||||
size_t len,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* @qcrypto_block_encrypt:
|
||||
* @block: the block encryption object
|
||||
* @offset: the position at which @iov will be written
|
||||
* @buf: the buffer to decrypt
|
||||
* @len: the length of @buf in bytes
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Encrypt @len bytes of plain text in @buf, writing
|
||||
* cipher text back into @buf. @len and @offset must be
|
||||
* a multiple of the encryption format sector size.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure
|
||||
*/
|
||||
int qcrypto_block_encrypt(QCryptoBlock *block,
|
||||
uint64_t offset,
|
||||
uint8_t *buf,
|
||||
size_t len,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_block_get_cipher:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* Get the cipher to use for payload encryption
|
||||
*
|
||||
* Returns: the cipher object
|
||||
*/
|
||||
QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block);
|
||||
|
||||
/**
|
||||
* qcrypto_block_get_ivgen:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* Get the initialization vector generator to use for
|
||||
* payload encryption
|
||||
*
|
||||
* Returns: the IV generator object
|
||||
*/
|
||||
QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_block_get_kdf_hash:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* Get the hash algorithm used with the key derivation
|
||||
* function
|
||||
*
|
||||
* Returns: the hash algorithm
|
||||
*/
|
||||
QCryptoHashAlgo qcrypto_block_get_kdf_hash(QCryptoBlock *block);
|
||||
|
||||
/**
|
||||
* qcrypto_block_get_payload_offset:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* Get the offset to the payload indicated by the
|
||||
* encryption header, in bytes.
|
||||
*
|
||||
* Returns: the payload offset in bytes
|
||||
*/
|
||||
uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block);
|
||||
|
||||
/**
|
||||
* qcrypto_block_get_sector_size:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* Get the size of sectors used for payload encryption. A new
|
||||
* IV is used at the start of each sector. The encryption
|
||||
* sector size is not required to match the sector size of the
|
||||
* underlying storage. For example LUKS will always use a 512
|
||||
* byte sector size, even if the volume is on a disk with 4k
|
||||
* sectors.
|
||||
*
|
||||
* Returns: the sector in bytes
|
||||
*/
|
||||
uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block);
|
||||
|
||||
/**
|
||||
* qcrypto_block_free:
|
||||
* @block: the block encryption object
|
||||
*
|
||||
* Release all resources associated with the encryption
|
||||
* object
|
||||
*/
|
||||
void qcrypto_block_free(QCryptoBlock *block);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlock, qcrypto_block_free)
|
||||
|
||||
#endif /* QCRYPTO_BLOCK_H */
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* QEMU Crypto cipher 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_CIPHER_H
|
||||
#define QCRYPTO_CIPHER_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
|
||||
typedef struct QCryptoCipher QCryptoCipher;
|
||||
typedef struct QCryptoCipherDriver QCryptoCipherDriver;
|
||||
|
||||
/* See also "QCryptoCipherAlgo" and "QCryptoCipherMode"
|
||||
* enums defined in qapi/crypto.json */
|
||||
|
||||
/**
|
||||
* QCryptoCipher:
|
||||
*
|
||||
* The QCryptoCipher object provides a way to perform encryption
|
||||
* and decryption of data, with a standard API, regardless of the
|
||||
* algorithm used. It further isolates the calling code from the
|
||||
* details of the specific underlying implementation, whether
|
||||
* built-in, libgcrypt or nettle.
|
||||
*
|
||||
* Each QCryptoCipher object is capable of performing both
|
||||
* encryption and decryption, and can operate in a number
|
||||
* or modes including ECB, CBC.
|
||||
*
|
||||
* <example>
|
||||
* <title>Encrypting data with AES-128 in CBC mode</title>
|
||||
* <programlisting>
|
||||
* QCryptoCipher *cipher;
|
||||
* uint8_t key = ....;
|
||||
* size_t keylen = 16;
|
||||
* uint8_t iv = ....;
|
||||
*
|
||||
* 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_ALGO_AES_128,
|
||||
* QCRYPTO_CIPHER_MODE_CBC,
|
||||
* key, keylen,
|
||||
* errp);
|
||||
* if (!cipher) {
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* if (qcrypto_cipher_set_iv(cipher, iv, keylen, errp) < 0) {
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* if (qcrypto_cipher_encrypt(cipher, rawdata, encdata, datalen, errp) < 0) {
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* qcrypto_cipher_free(cipher);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
*/
|
||||
|
||||
struct QCryptoCipher {
|
||||
QCryptoCipherAlgo alg;
|
||||
QCryptoCipherMode mode;
|
||||
const QCryptoCipherDriver *driver;
|
||||
};
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_supports:
|
||||
* @alg: the cipher algorithm
|
||||
* @mode: the cipher mode
|
||||
*
|
||||
* Determine if @alg cipher algorithm in @mode is supported by the
|
||||
* current configured build
|
||||
*
|
||||
* Returns: true if the algorithm is supported, false otherwise
|
||||
*/
|
||||
bool qcrypto_cipher_supports(QCryptoCipherAlgo alg,
|
||||
QCryptoCipherMode mode);
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_get_block_len:
|
||||
* @alg: the cipher algorithm
|
||||
*
|
||||
* Get the required data block size in bytes. When
|
||||
* encrypting data, it must be a multiple of the
|
||||
* block size.
|
||||
*
|
||||
* Returns: the block size in bytes
|
||||
*/
|
||||
size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgo alg);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_get_key_len:
|
||||
* @alg: the cipher algorithm
|
||||
*
|
||||
* Get the required key size in bytes.
|
||||
*
|
||||
* Returns: the key size in bytes
|
||||
*/
|
||||
size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgo alg);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_get_iv_len:
|
||||
* @alg: the cipher algorithm
|
||||
* @mode: the cipher mode
|
||||
*
|
||||
* Get the required initialization vector size
|
||||
* in bytes, if one is required.
|
||||
*
|
||||
* Returns: the IV size in bytes, or 0 if no IV is permitted
|
||||
*/
|
||||
size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgo alg,
|
||||
QCryptoCipherMode mode);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_new:
|
||||
* @alg: the cipher algorithm
|
||||
* @mode: the cipher usage mode
|
||||
* @key: the private key bytes
|
||||
* @nkey: the length of @key
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Creates a new cipher object for encrypting/decrypting
|
||||
* data with the algorithm @alg in the usage mode @mode.
|
||||
*
|
||||
* The @key parameter provides the bytes representing
|
||||
* the encryption/decryption key to use. The @nkey parameter
|
||||
* specifies the length of @key in bytes. Each algorithm has
|
||||
* one or more valid key lengths, and it is an error to provide
|
||||
* a key of the incorrect length.
|
||||
*
|
||||
* The returned cipher object must be released with
|
||||
* qcrypto_cipher_free() when no longer required
|
||||
*
|
||||
* Returns: a new cipher object, or NULL on error
|
||||
*/
|
||||
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgo alg,
|
||||
QCryptoCipherMode mode,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_free:
|
||||
* @cipher: the cipher object
|
||||
*
|
||||
* Release the memory associated with @cipher that
|
||||
* was previously allocated by qcrypto_cipher_new()
|
||||
*/
|
||||
void qcrypto_cipher_free(QCryptoCipher *cipher);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoCipher, qcrypto_cipher_free)
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_encrypt:
|
||||
* @cipher: the cipher object
|
||||
* @in: buffer holding the plain text input data
|
||||
* @out: buffer to fill with the cipher text output data
|
||||
* @len: the length of @in and @out buffers
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Encrypts the plain text stored in @in, filling
|
||||
* @out with the resulting ciphered text. Both the
|
||||
* @in and @out buffers must have the same size,
|
||||
* given by @len.
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error
|
||||
*/
|
||||
int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
|
||||
const void *in,
|
||||
void *out,
|
||||
size_t len,
|
||||
Error **errp);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_decrypt:
|
||||
* @cipher: the cipher object
|
||||
* @in: buffer holding the cipher text input data
|
||||
* @out: buffer to fill with the plain text output data
|
||||
* @len: the length of @in and @out buffers
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Decrypts the cipher text stored in @in, filling
|
||||
* @out with the resulting plain text. Both the
|
||||
* @in and @out buffers must have the same size,
|
||||
* given by @len.
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error
|
||||
*/
|
||||
int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
|
||||
const void *in,
|
||||
void *out,
|
||||
size_t len,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_setiv:
|
||||
* @cipher: the cipher object
|
||||
* @iv: the initialization vector or counter (CTR mode) bytes
|
||||
* @niv: the length of @iv
|
||||
* @errpr: pointer to a NULL-initialized error object
|
||||
*
|
||||
* If the @cipher object is setup to use a mode that requires
|
||||
* initialization vectors or counter, this sets the @niv
|
||||
* bytes. The @iv data should have the same length as the
|
||||
* cipher key used when originally constructing the cipher
|
||||
* object. It is an error to set an initialization vector
|
||||
* or counter if the cipher mode does not require one.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_cipher_setiv(QCryptoCipher *cipher,
|
||||
const uint8_t *iv, size_t niv,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_setaad:
|
||||
* @cipher: the cipher object
|
||||
* @aad: the associated data to authenticate
|
||||
* @len: the length of @aad
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* For AEAD modes such as GCM, feed the associated data (AAD) that is
|
||||
* authenticated but not encrypted. It must be called after
|
||||
* qcrypto_cipher_setiv() and before the first encrypt/decrypt call. It is
|
||||
* an error to call this on a mode that is not an AEAD mode.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_cipher_setaad(QCryptoCipher *cipher,
|
||||
const uint8_t *aad, size_t len,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_cipher_gettag:
|
||||
* @cipher: the cipher object
|
||||
* @tag: buffer to receive the authentication tag
|
||||
* @len: the length of @tag
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* For AEAD modes such as GCM, read back the authentication tag computed
|
||||
* over the associated data and the message. It must be called after the
|
||||
* encrypt/decrypt operation. It is an error to call this on a mode that is
|
||||
* not an AEAD mode.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_cipher_gettag(QCryptoCipher *cipher,
|
||||
uint8_t *tag, size_t len,
|
||||
Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_CIPHER_H */
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Carry-less multiply operations.
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* Copyright (C) 2023 Linaro, Ltd.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_CLMUL_H
|
||||
#define CRYPTO_CLMUL_H
|
||||
|
||||
#include "qemu/int128.h"
|
||||
#include "host/crypto/clmul.h"
|
||||
|
||||
/**
|
||||
* clmul_8x8_low:
|
||||
*
|
||||
* Perform eight 8x8->8 carry-less multiplies.
|
||||
*/
|
||||
uint64_t clmul_8x8_low(uint64_t, uint64_t);
|
||||
|
||||
/**
|
||||
* clmul_8x4_even:
|
||||
*
|
||||
* Perform four 8x8->16 carry-less multiplies.
|
||||
* The odd bytes of the inputs are ignored.
|
||||
*/
|
||||
uint64_t clmul_8x4_even(uint64_t, uint64_t);
|
||||
|
||||
/**
|
||||
* clmul_8x4_odd:
|
||||
*
|
||||
* Perform four 8x8->16 carry-less multiplies.
|
||||
* The even bytes of the inputs are ignored.
|
||||
*/
|
||||
uint64_t clmul_8x4_odd(uint64_t, uint64_t);
|
||||
|
||||
/**
|
||||
* clmul_8x4_packed:
|
||||
*
|
||||
* Perform four 8x8->16 carry-less multiplies.
|
||||
*/
|
||||
uint64_t clmul_8x4_packed(uint32_t, uint32_t);
|
||||
|
||||
/**
|
||||
* clmul_16x2_even:
|
||||
*
|
||||
* Perform two 16x16->32 carry-less multiplies.
|
||||
* The odd words of the inputs are ignored.
|
||||
*/
|
||||
uint64_t clmul_16x2_even(uint64_t, uint64_t);
|
||||
|
||||
/**
|
||||
* clmul_16x2_odd:
|
||||
*
|
||||
* Perform two 16x16->32 carry-less multiplies.
|
||||
* The even words of the inputs are ignored.
|
||||
*/
|
||||
uint64_t clmul_16x2_odd(uint64_t, uint64_t);
|
||||
|
||||
/**
|
||||
* clmul_32:
|
||||
*
|
||||
* Perform a 32x32->64 carry-less multiply.
|
||||
*/
|
||||
uint64_t clmul_32(uint32_t, uint32_t);
|
||||
|
||||
/**
|
||||
* clmul_64:
|
||||
*
|
||||
* Perform a 64x64->128 carry-less multiply.
|
||||
*/
|
||||
Int128 clmul_64_gen(uint64_t, uint64_t);
|
||||
|
||||
static inline Int128 clmul_64(uint64_t a, uint64_t b)
|
||||
{
|
||||
if (HAVE_CLMUL_ACCEL) {
|
||||
return clmul_64_accel(a, b);
|
||||
} else {
|
||||
return clmul_64_gen(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CRYPTO_CLMUL_H */
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This is D3DES (V5.09) by Richard Outerbridge with the double and
|
||||
* triple-length support removed for use in VNC.
|
||||
*
|
||||
* These changes are:
|
||||
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
|
||||
*
|
||||
* This software 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.
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_DESRFB_H
|
||||
#define QCRYPTO_DESRFB_H
|
||||
|
||||
/* d3des.h -
|
||||
*
|
||||
* Headers and defines for d3des.c
|
||||
* Graven Imagery, 1992.
|
||||
*
|
||||
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
|
||||
* (GEnie : OUTER; CIS : [71755,204])
|
||||
*/
|
||||
|
||||
#define EN0 0 /* MODE == encrypt */
|
||||
#define DE1 1 /* MODE == decrypt */
|
||||
|
||||
void deskey(unsigned char *, int);
|
||||
/* hexkey[8] MODE
|
||||
* Sets the internal key register according to the hexadecimal
|
||||
* key contained in the 8 bytes of hexkey, according to the DES,
|
||||
* for encryption or decryption according to MODE.
|
||||
*/
|
||||
|
||||
void usekey(unsigned long *);
|
||||
/* cookedkey[32]
|
||||
* Loads the internal key register with the data in cookedkey.
|
||||
*/
|
||||
|
||||
void des(unsigned char *, unsigned char *);
|
||||
/* from[8] to[8]
|
||||
* Encrypts/Decrypts (according to the key currently loaded in the
|
||||
* internal key register) one block of eight bytes at address 'from'
|
||||
* into the block at address 'to'. They can be the same.
|
||||
*/
|
||||
|
||||
/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
|
||||
********************************************************************/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 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
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_HASH_H
|
||||
#define QCRYPTO_HASH_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
|
||||
#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:
|
||||
* @alg: the hash algorithm
|
||||
*
|
||||
* Determine if @alg hash algorithm is supported by the
|
||||
* current configured build.
|
||||
*
|
||||
* Returns: true if the algorithm is supported, false otherwise
|
||||
*/
|
||||
gboolean qcrypto_hash_supports(QCryptoHashAlgo alg);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_hash_digest_len:
|
||||
* @alg: the hash algorithm
|
||||
*
|
||||
* Determine the size of the hash digest in bytes
|
||||
*
|
||||
* Returns: the digest length in bytes
|
||||
*/
|
||||
size_t qcrypto_hash_digest_len(QCryptoHashAlgo alg);
|
||||
|
||||
/**
|
||||
* qcrypto_hash_bytesv:
|
||||
* @alg: the hash algorithm
|
||||
* @iov: the array of memory regions to hash
|
||||
* @niov: the length of @iov
|
||||
* @result: pointer to hold output hash
|
||||
* @resultlen: pointer to hold length of @result
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hash across all the memory regions
|
||||
* 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(QCryptoHashAlgo alg,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hash_bytes:
|
||||
* @alg: the hash algorithm
|
||||
* @buf: the memory region to hash
|
||||
* @len: the length of @buf
|
||||
* @result: pointer to hold output hash
|
||||
* @resultlen: pointer to hold length of @result
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hash across all the memory region
|
||||
* @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(QCryptoHashAlgo alg,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hash_digestv:
|
||||
* @alg: the hash algorithm
|
||||
* @iov: the array of memory regions to hash
|
||||
* @niov: the length of @iov
|
||||
* @digest: pointer to hold output hash
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hash across all the memory regions
|
||||
* present in @iov. 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_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 void *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
|
||||
* @len: the length of @buf
|
||||
* @digest: pointer to hold output hash
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hash across all the memory region
|
||||
* @buf of length @len. 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_digest(QCryptoHashAlgo alg,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
char **digest,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hash_base64v:
|
||||
* @alg: the hash algorithm
|
||||
* @iov: the array of memory regions to hash
|
||||
* @niov: the length of @iov
|
||||
* @base64: pointer to hold output hash
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hash across all the memory regions
|
||||
* present in @iov. 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_base64v(QCryptoHashAlgo alg,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
char **base64,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hash_base64:
|
||||
* @alg: the hash algorithm
|
||||
* @buf: the memory region to hash
|
||||
* @len: the length of @buf
|
||||
* @base64: pointer to hold output hash
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hash across all the memory region
|
||||
* @buf of length @len. 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_base64(QCryptoHashAlgo alg,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
char **base64,
|
||||
Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_HASH_H */
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* QEMU Crypto hmac algorithms
|
||||
*
|
||||
* Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
|
||||
*
|
||||
* 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_HMAC_H
|
||||
#define QCRYPTO_HMAC_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
|
||||
typedef struct QCryptoHmac QCryptoHmac;
|
||||
struct QCryptoHmac {
|
||||
QCryptoHashAlgo alg;
|
||||
void *opaque;
|
||||
void *driver;
|
||||
};
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_supports:
|
||||
* @alg: the hmac algorithm
|
||||
*
|
||||
* Determine if @alg hmac algorithm is supported by
|
||||
* the current configured build
|
||||
*
|
||||
* Returns:
|
||||
* true if the algorithm is supported, false otherwise
|
||||
*/
|
||||
bool qcrypto_hmac_supports(QCryptoHashAlgo alg);
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_new:
|
||||
* @alg: the hmac algorithm
|
||||
* @key: the key bytes
|
||||
* @nkey: the length of @key
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Creates a new hmac object with the algorithm @alg
|
||||
*
|
||||
* The @key parameter provides the bytes representing
|
||||
* the secret key to use. The @nkey parameter specifies
|
||||
* the length of @key in bytes
|
||||
*
|
||||
* Note: must use qcrypto_hmac_free() to release the
|
||||
* returned hmac object when no longer required
|
||||
*
|
||||
* Returns:
|
||||
* a new hmac object, or NULL on error
|
||||
*/
|
||||
QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgo alg,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_free:
|
||||
* @hmac: the hmac object
|
||||
*
|
||||
* Release the memory associated with @hmac that was
|
||||
* previously allocated by qcrypto_hmac_new()
|
||||
*/
|
||||
void qcrypto_hmac_free(QCryptoHmac *hmac);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHmac, qcrypto_hmac_free)
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_bytesv:
|
||||
* @hmac: the hmac object
|
||||
* @iov: the array of memory regions to hmac
|
||||
* @niov: the length of @iov
|
||||
* @result: pointer to hold output hmac
|
||||
* @resultlen: pointer to hold length of @result
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hmac across all the memory regions
|
||||
* 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.
|
||||
*
|
||||
* If @result_len is set to a NULL pointer, no result will be returned, and
|
||||
* the hmac object can be used for further invocations of qcrypto_hmac_bytes()
|
||||
* or qcrypto_hmac_bytesv() until a non-NULL pointer is provided. This allows
|
||||
* to build the hmac across memory regions that are not available at the same
|
||||
* time.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_bytes:
|
||||
* @hmac: the hmac object
|
||||
* @buf: the memory region to hmac
|
||||
* @len: the length of @buf
|
||||
* @result: pointer to hold output hmac
|
||||
* @resultlen: pointer to hold length of @result
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hmac across all the memory region
|
||||
* @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.
|
||||
*
|
||||
* If @result_len is set to a NULL pointer, no result will be returned, and
|
||||
* the hmac object can be used for further invocations of qcrypto_hmac_bytes()
|
||||
* or qcrypto_hmac_bytesv() until a non-NULL pointer is provided. This allows
|
||||
* to build the hmac across memory regions that are not available at the same
|
||||
* time.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_hmac_bytes(QCryptoHmac *hmac,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_digestv:
|
||||
* @hmac: the hmac object
|
||||
* @iov: the array of memory regions to hmac
|
||||
* @niov: the length of @iov
|
||||
* @digest: pointer to hold output hmac
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hmac across all the memory regions
|
||||
* present in @iov. The @digest pointer will be
|
||||
* filled with the printable hex digest of the computed
|
||||
* hmac, 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_hmac_digestv(QCryptoHmac *hmac,
|
||||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
char **digest,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_hmac_digest:
|
||||
* @hmac: the hmac object
|
||||
* @buf: the memory region to hmac
|
||||
* @len: the length of @buf
|
||||
* @digest: pointer to hold output hmac
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Computes the hmac across all the memory region
|
||||
* @buf of length @len. The @digest pointer will be
|
||||
* filled with the printable hex digest of the computed
|
||||
* hmac, 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_hmac_digest(QCryptoHmac *hmac,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
char **digest,
|
||||
Error **errp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* QEMU Crypto initialization
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_INIT_H
|
||||
#define QCRYPTO_INIT_H
|
||||
|
||||
#include "qapi/error.h"
|
||||
|
||||
int qcrypto_init(Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_INIT_H */
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* QEMU Crypto block IV generator
|
||||
*
|
||||
* Copyright (c) 2015-2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_IVGEN_H
|
||||
#define QCRYPTO_IVGEN_H
|
||||
|
||||
#include "crypto/cipher.h"
|
||||
#include "crypto/hash.h"
|
||||
|
||||
/**
|
||||
* This module provides a framework for generating initialization
|
||||
* vectors for block encryption schemes using chained cipher modes
|
||||
* CBC. The principle is that each disk sector is assigned a unique
|
||||
* initialization vector for use for encryption of data in that
|
||||
* sector.
|
||||
*
|
||||
* <example>
|
||||
* <title>Encrypting block data with initialization vectors</title>
|
||||
* <programlisting>
|
||||
* uint8_t *data = ....data to encrypt...
|
||||
* size_t ndata = XXX;
|
||||
* uint8_t *key = ....some encryption key...
|
||||
* size_t nkey = XXX;
|
||||
* uint8_t *iv;
|
||||
* size_t niv;
|
||||
* size_t sector = 0;
|
||||
*
|
||||
* g_assert((ndata % 512) == 0);
|
||||
*
|
||||
* 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_ALGO_AES_128,
|
||||
* QCRYPTO_CIPHER_MODE_CBC,
|
||||
* key, nkey, errp);
|
||||
* if (!cipher) {
|
||||
* goto error;
|
||||
* }
|
||||
*
|
||||
* niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALGO_AES_128,
|
||||
* QCRYPTO_CIPHER_MODE_CBC);
|
||||
* iv = g_new0(uint8_t, niv);
|
||||
*
|
||||
*
|
||||
* while (ndata) {
|
||||
* if (qcrypto_ivgen_calculate(ivgen, sector, iv, niv, errp) < 0) {
|
||||
* goto error;
|
||||
* }
|
||||
* if (qcrypto_cipher_setiv(cipher, iv, niv, errp) < 0) {
|
||||
* goto error;
|
||||
* }
|
||||
* if (qcrypto_cipher_encrypt(cipher,
|
||||
* data + (sector * 512),
|
||||
* data + (sector * 512),
|
||||
* 512, errp) < 0) {
|
||||
* goto error;
|
||||
* }
|
||||
* sector++;
|
||||
* ndata -= 512;
|
||||
* }
|
||||
*
|
||||
* g_free(iv);
|
||||
* qcrypto_ivgen_free(ivgen);
|
||||
* qcrypto_cipher_free(cipher);
|
||||
* return 0;
|
||||
*
|
||||
*error:
|
||||
* g_free(iv);
|
||||
* qcrypto_ivgen_free(ivgen);
|
||||
* qcrypto_cipher_free(cipher);
|
||||
* return -1;
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*/
|
||||
|
||||
typedef struct QCryptoIVGen QCryptoIVGen;
|
||||
|
||||
/* See also QCryptoIVGenAlgo enum in qapi/crypto.json */
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_ivgen_new:
|
||||
* @alg: the initialization vector generation algorithm
|
||||
* @cipheralg: the cipher algorithm or 0
|
||||
* @hash: the hash algorithm or 0
|
||||
* @key: the encryption key or NULL
|
||||
* @nkey: the size of @key in bytes
|
||||
*
|
||||
* Create a new initialization vector generator that uses
|
||||
* the algorithm @alg. Whether the remaining parameters
|
||||
* are required or not depends on the choice of @alg
|
||||
* requested.
|
||||
*
|
||||
* - 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_IV_GEN_ALGO_PLAIN64
|
||||
*
|
||||
* The IVs are generated by the 64-bit sector number.
|
||||
* All the other parameters are unused.
|
||||
*
|
||||
* - 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,
|
||||
* @hash, @key and @nkey parameters are all required.
|
||||
*
|
||||
* Returns: a new IV generator, or NULL on error
|
||||
*/
|
||||
QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgo alg,
|
||||
QCryptoCipherAlgo cipheralg,
|
||||
QCryptoHashAlgo hash,
|
||||
const uint8_t *key, size_t nkey,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_ivgen_calculate:
|
||||
* @ivgen: the IV generator object
|
||||
* @sector: the 64-bit sector number
|
||||
* @iv: a pre-allocated buffer to hold the generated IV
|
||||
* @niv: the number of bytes in @iv
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Calculate a new initialization vector for the data
|
||||
* to be stored in sector @sector. The IV will be
|
||||
* written into the buffer @iv of size @niv.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen,
|
||||
uint64_t sector,
|
||||
uint8_t *iv, size_t niv,
|
||||
Error **errp);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_ivgen_get_algorithm:
|
||||
* @ivgen: the IV generator object
|
||||
*
|
||||
* Get the algorithm used by this IV generator
|
||||
*
|
||||
* Returns: the IV generator algorithm
|
||||
*/
|
||||
QCryptoIVGenAlgo qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_ivgen_get_cipher:
|
||||
* @ivgen: the IV generator object
|
||||
*
|
||||
* Get the cipher algorithm used by this IV generator (if
|
||||
* applicable)
|
||||
*
|
||||
* Returns: the cipher algorithm
|
||||
*/
|
||||
QCryptoCipherAlgo qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_ivgen_get_hash:
|
||||
* @ivgen: the IV generator object
|
||||
*
|
||||
* Get the hash algorithm used by this IV generator (if
|
||||
* applicable)
|
||||
*
|
||||
* Returns: the hash algorithm
|
||||
*/
|
||||
QCryptoHashAlgo qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_ivgen_free:
|
||||
* @ivgen: the IV generator object
|
||||
*
|
||||
* Release all resources associated with @ivgen, or a no-op
|
||||
* if @ivgen is NULL
|
||||
*/
|
||||
void qcrypto_ivgen_free(QCryptoIVGen *ivgen);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoIVGen, qcrypto_ivgen_free)
|
||||
|
||||
#endif /* QCRYPTO_IVGEN_H */
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* QEMU Crypto PBKDF support (Password-Based Key Derivation Function)
|
||||
*
|
||||
* Copyright (c) 2015-2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_PBKDF_H
|
||||
#define QCRYPTO_PBKDF_H
|
||||
|
||||
#include "crypto/hash.h"
|
||||
|
||||
/**
|
||||
* This module provides an interface to the PBKDF2 algorithm
|
||||
*
|
||||
* https://en.wikipedia.org/wiki/PBKDF2
|
||||
*
|
||||
* <example>
|
||||
* <title>Generating an AES encryption key from a user password</title>
|
||||
* <programlisting>
|
||||
* #include "crypto/cipher.h"
|
||||
* #include "crypto/random.h"
|
||||
* #include "crypto/pbkdf.h"
|
||||
*
|
||||
* ....
|
||||
*
|
||||
* char *password = "a-typical-awful-user-password";
|
||||
* 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;
|
||||
* QCryptoCipher *cipher;
|
||||
*
|
||||
* if (qcrypto_random_bytes(salt, nkey, errp) < 0) {
|
||||
* g_free(key);
|
||||
* g_free(salt);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALGO_SHA256,
|
||||
* (const uint8_t *)password,
|
||||
* strlen(password),
|
||||
* salt, nkey, errp);
|
||||
* if (iterations < 0) {
|
||||
* g_free(key);
|
||||
* g_free(salt);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* if (qcrypto_pbkdf2(QCRYPTO_HASH_ALGO_SHA256,
|
||||
* (const uint8_t *)password, strlen(password),
|
||||
* salt, nkey, iterations, key, nkey, errp) < 0) {
|
||||
* g_free(key);
|
||||
* g_free(salt);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* g_free(salt);
|
||||
*
|
||||
* cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
|
||||
* QCRYPTO_CIPHER_MODE_ECB,
|
||||
* key, nkey, errp);
|
||||
* g_free(key);
|
||||
*
|
||||
* ....encrypt some data...
|
||||
*
|
||||
* qcrypto_cipher_free(cipher);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* qcrypto_pbkdf2_supports:
|
||||
* @hash: the hash algorithm
|
||||
*
|
||||
* Determine if the current build supports the PBKDF2 algorithm
|
||||
* in combination with the hash @hash.
|
||||
*
|
||||
* Returns true if supported, false otherwise
|
||||
*/
|
||||
bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_pbkdf2:
|
||||
* @hash: the hash algorithm to use
|
||||
* @key: the user password / key
|
||||
* @nkey: the length of @key in bytes
|
||||
* @salt: a random salt
|
||||
* @nsalt: length of @salt in bytes
|
||||
* @iterations: the number of iterations to compute
|
||||
* @out: pointer to pre-allocated buffer to hold output
|
||||
* @nout: length of @out in bytes
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Apply the PBKDF2 algorithm to derive an encryption
|
||||
* key from a user password provided in @key. The
|
||||
* @salt parameter is used to perturb the algorithm.
|
||||
* The @iterations count determines how many times
|
||||
* the hashing process is run, which influences how
|
||||
* hard it is to crack the key. The number of @iterations
|
||||
* should be large enough such that the algorithm takes
|
||||
* 1 second or longer to derive a key. The derived key
|
||||
* will be stored in the preallocated buffer @out.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* qcrypto_pbkdf2_count_iters:
|
||||
* @hash: the hash algorithm to use
|
||||
* @key: the user password / key
|
||||
* @nkey: the length of @key in bytes
|
||||
* @salt: a random salt
|
||||
* @nsalt: length of @salt in bytes
|
||||
* @nout: size of desired derived key
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Time the PBKDF2 algorithm to determine how many
|
||||
* iterations are required to derive an encryption
|
||||
* key from a user password provided in @key in 1
|
||||
* second of compute time. The result of this can
|
||||
* be used as a the @iterations parameter of a later
|
||||
* call to qcrypto_pbkdf2(). The value of @nout should
|
||||
* match that value that will later be provided with
|
||||
* a call to qcrypto_pbkdf2().
|
||||
*
|
||||
* Returns: number of iterations in 1 second, -1 on error
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif /* QCRYPTO_PBKDF_H */
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* QEMU Crypto random number provider
|
||||
*
|
||||
* Copyright (c) 2015-2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_RANDOM_H
|
||||
#define QCRYPTO_RANDOM_H
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_random_bytes:
|
||||
* @buf: the buffer to fill
|
||||
* @buflen: length of @buf in bytes
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Fill @buf with @buflen bytes of cryptographically strong
|
||||
* random data
|
||||
*
|
||||
* Returns 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_random_bytes(void *buf,
|
||||
size_t buflen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_random_init:
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Initializes the handles used by qcrypto_random_bytes
|
||||
*
|
||||
* Returns 0 on success, -1 on error
|
||||
*/
|
||||
int qcrypto_random_init(Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_RANDOM_H */
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* QEMU crypto secret support
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_SECRET_H
|
||||
#define QCRYPTO_SECRET_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
#include "qom/object.h"
|
||||
#include "crypto/secret_common.h"
|
||||
|
||||
#define TYPE_QCRYPTO_SECRET "secret"
|
||||
typedef struct QCryptoSecret QCryptoSecret;
|
||||
DECLARE_INSTANCE_CHECKER(QCryptoSecret, QCRYPTO_SECRET,
|
||||
TYPE_QCRYPTO_SECRET)
|
||||
|
||||
typedef struct QCryptoSecretClass QCryptoSecretClass;
|
||||
|
||||
/**
|
||||
* QCryptoSecret:
|
||||
*
|
||||
* The QCryptoSecret object provides storage of secrets,
|
||||
* which may be user passwords, encryption keys or any
|
||||
* other kind of sensitive data that is represented as
|
||||
* a sequence of bytes.
|
||||
*
|
||||
* The sensitive data associated with the secret can
|
||||
* be provided directly via the 'data' property, or
|
||||
* indirectly via the 'file' property. In the latter
|
||||
* case there is support for file descriptor passing
|
||||
* via the usual /dev/fdset/NN syntax that QEMU uses.
|
||||
*
|
||||
* The data for a secret can be provided in two formats,
|
||||
* either as a UTF-8 string (the default), or as base64
|
||||
* encoded 8-bit binary data. The latter is appropriate
|
||||
* for raw encryption keys, while the former is appropriate
|
||||
* for user entered passwords.
|
||||
*
|
||||
* The data may be optionally encrypted with AES-256-CBC,
|
||||
* and the decryption key provided by another
|
||||
* QCryptoSecret instance identified by the 'keyid'
|
||||
* property. When passing sensitive data directly
|
||||
* via the 'data' property it is strongly recommended
|
||||
* to use the AES encryption facility to prevent the
|
||||
* sensitive data being exposed in the process listing
|
||||
* or system log files.
|
||||
*
|
||||
* Providing data directly, insecurely (suitable for
|
||||
* ad hoc developer testing only)
|
||||
*
|
||||
* $QEMU -object secret,id=sec0,data=letmein
|
||||
*
|
||||
* Providing data indirectly:
|
||||
*
|
||||
* # printf "letmein" > password.txt
|
||||
* # $QEMU \
|
||||
* -object secret,id=sec0,file=password.txt
|
||||
*
|
||||
* Using a master encryption key with data.
|
||||
*
|
||||
* The master key needs to be created as 32 secure
|
||||
* random bytes (optionally base64 encoded)
|
||||
*
|
||||
* # openssl rand -base64 32 > key.b64
|
||||
* # KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"')
|
||||
*
|
||||
* Each secret to be encrypted needs to have a random
|
||||
* initialization vector generated. These do not need
|
||||
* to be kept secret
|
||||
*
|
||||
* # openssl rand -base64 16 > iv.b64
|
||||
* # IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"')
|
||||
*
|
||||
* A secret to be defined can now be encrypted
|
||||
*
|
||||
* # SECRET=$(printf "letmein" |
|
||||
* openssl enc -aes-256-cbc -a -K $KEY -iv $IV)
|
||||
*
|
||||
* When launching QEMU, create a master secret pointing
|
||||
* to key.b64 and specify that to be used to decrypt
|
||||
* the user password
|
||||
*
|
||||
* # $QEMU \
|
||||
* -object secret,id=secmaster0,format=base64,file=key.b64 \
|
||||
* -object secret,id=sec0,keyid=secmaster0,format=base64,\
|
||||
* data=$SECRET,iv=$(<iv.b64)
|
||||
*
|
||||
* When encrypting, the data can still be provided via an
|
||||
* external file, in which case it is possible to use either
|
||||
* raw binary data, or base64 encoded. This example uses
|
||||
* raw format
|
||||
*
|
||||
* # printf "letmein" |
|
||||
* openssl enc -aes-256-cbc -K $KEY -iv $IV -o pw.aes
|
||||
* # $QEMU \
|
||||
* -object secret,id=secmaster0,format=base64,file=key.b64 \
|
||||
* -object secret,id=sec0,keyid=secmaster0,\
|
||||
* file=pw.aes,iv=$(<iv.b64)
|
||||
*
|
||||
* Note that the ciphertext can be in either raw or base64
|
||||
* format, as indicated by the 'format' parameter, but the
|
||||
* plaintext resulting from decryption is expected to always
|
||||
* be in raw format.
|
||||
*/
|
||||
|
||||
struct QCryptoSecret {
|
||||
QCryptoSecretCommon parent_obj;
|
||||
char *data;
|
||||
char *file;
|
||||
};
|
||||
|
||||
|
||||
struct QCryptoSecretClass {
|
||||
QCryptoSecretCommonClass parent_class;
|
||||
};
|
||||
|
||||
#endif /* QCRYPTO_SECRET_H */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* QEMU crypto secret support
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_SECRET_COMMON_H
|
||||
#define QCRYPTO_SECRET_COMMON_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_QCRYPTO_SECRET_COMMON "secret_common"
|
||||
OBJECT_DECLARE_TYPE(QCryptoSecretCommon, QCryptoSecretCommonClass,
|
||||
QCRYPTO_SECRET_COMMON)
|
||||
|
||||
|
||||
struct QCryptoSecretCommon {
|
||||
Object parent_obj;
|
||||
uint8_t *rawdata;
|
||||
size_t rawlen;
|
||||
QCryptoSecretFormat format;
|
||||
char *keyid;
|
||||
char *iv;
|
||||
};
|
||||
|
||||
|
||||
struct QCryptoSecretCommonClass {
|
||||
ObjectClass parent_class;
|
||||
void (*load_data)(QCryptoSecretCommon *secret,
|
||||
uint8_t **output,
|
||||
size_t *outputlen,
|
||||
Error **errp);
|
||||
};
|
||||
|
||||
|
||||
int qcrypto_secret_lookup(const char *secretid,
|
||||
uint8_t **data,
|
||||
size_t *datalen,
|
||||
Error **errp);
|
||||
char *qcrypto_secret_lookup_as_utf8(const char *secretid, Error **errp);
|
||||
char *qcrypto_secret_lookup_as_base64(const char *secretid, Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_SECRET_COMMON_H */
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* QEMU crypto secret support
|
||||
*
|
||||
* Copyright 2020 Yandex N.V.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_SECRET_KEYRING_H
|
||||
#define QCRYPTO_SECRET_KEYRING_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
#include "qom/object.h"
|
||||
#include "crypto/secret_common.h"
|
||||
|
||||
#define TYPE_QCRYPTO_SECRET_KEYRING "secret_keyring"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(QCryptoSecretKeyring,
|
||||
QCRYPTO_SECRET_KEYRING)
|
||||
|
||||
|
||||
struct QCryptoSecretKeyring {
|
||||
QCryptoSecretCommon parent;
|
||||
int32_t serial;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* QCRYPTO_SECRET_KEYRING_H */
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef QEMU_SM4_H
|
||||
#define QEMU_SM4_H
|
||||
|
||||
extern const uint8_t sm4_sbox[256];
|
||||
extern const uint32_t sm4_ck[32];
|
||||
|
||||
static inline uint32_t sm4_subword(uint32_t word)
|
||||
{
|
||||
return sm4_sbox[word & 0xff] |
|
||||
sm4_sbox[(word >> 8) & 0xff] << 8 |
|
||||
sm4_sbox[(word >> 16) & 0xff] << 16 |
|
||||
sm4_sbox[(word >> 24) & 0xff] << 24;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* QEMU TLS Cipher Suites Registry (RFC8447)
|
||||
*
|
||||
* Copyright (c) 2018-2020 Red Hat, Inc.
|
||||
*
|
||||
* Author: Philippe Mathieu-Daudé
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_TLS_CIPHER_SUITES_H
|
||||
#define QCRYPTO_TLS_CIPHER_SUITES_H
|
||||
|
||||
#include "qom/object.h"
|
||||
#include "crypto/tlscreds.h"
|
||||
|
||||
#define TYPE_QCRYPTO_TLS_CIPHER_SUITES "tls-cipher-suites"
|
||||
typedef struct QCryptoTLSCipherSuites QCryptoTLSCipherSuites;
|
||||
DECLARE_INSTANCE_CHECKER(QCryptoTLSCipherSuites, QCRYPTO_TLS_CIPHER_SUITES,
|
||||
TYPE_QCRYPTO_TLS_CIPHER_SUITES)
|
||||
|
||||
/**
|
||||
* qcrypto_tls_cipher_suites_get_data:
|
||||
* @obj: pointer to a TLS cipher suites object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Returns: reference to a byte array containing the data.
|
||||
* The caller should release the reference when no longer
|
||||
* required.
|
||||
*/
|
||||
GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj,
|
||||
Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_TLS_CIPHER_SUITES_H */
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* QEMU crypto TLS credential support
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_TLSCREDS_H
|
||||
#define QCRYPTO_TLSCREDS_H
|
||||
|
||||
#include "qapi/qapi-types-crypto.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_QCRYPTO_TLS_CREDS "tls-creds"
|
||||
typedef struct QCryptoTLSCreds QCryptoTLSCreds;
|
||||
typedef struct QCryptoTLSCredsClass QCryptoTLSCredsClass;
|
||||
DECLARE_OBJ_CHECKERS(QCryptoTLSCreds, QCryptoTLSCredsClass, QCRYPTO_TLS_CREDS,
|
||||
TYPE_QCRYPTO_TLS_CREDS)
|
||||
|
||||
|
||||
#define QCRYPTO_TLS_CREDS_DH_PARAMS "dh-params.pem"
|
||||
|
||||
|
||||
typedef bool (*CryptoTLSCredsReload)(QCryptoTLSCreds *, Error **);
|
||||
/**
|
||||
* QCryptoTLSCreds:
|
||||
*
|
||||
* The QCryptoTLSCreds object is an abstract base for different
|
||||
* types of TLS handshake credentials. Most commonly the
|
||||
* QCryptoTLSCredsX509 subclass will be used to provide x509
|
||||
* certificate credentials.
|
||||
*/
|
||||
|
||||
struct QCryptoTLSCredsClass {
|
||||
ObjectClass parent_class;
|
||||
CryptoTLSCredsReload reload;
|
||||
const char *prioritySuffix;
|
||||
};
|
||||
|
||||
/**
|
||||
* qcrypto_tls_creds_check_endpoint:
|
||||
* @creds: pointer to a TLS credentials object
|
||||
* @endpoint: type of network endpoint that will be using the credentials
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Check whether the credentials is setup according to
|
||||
* the type of @endpoint argument.
|
||||
*
|
||||
* Returns true if the credentials is setup for the endpoint, false otherwise
|
||||
*/
|
||||
bool qcrypto_tls_creds_check_endpoint(QCryptoTLSCreds *creds,
|
||||
QCryptoTLSCredsEndpoint endpoint,
|
||||
Error **errp);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_tls_creds_get_priority:
|
||||
* @creds: pointer to a TLS credentials object
|
||||
*
|
||||
* Get the TLS credentials priority string. The caller
|
||||
* must free the returned string when no longer required.
|
||||
*
|
||||
* Returns: a non-NULL priority string
|
||||
*/
|
||||
char *qcrypto_tls_creds_get_priority(QCryptoTLSCreds *creds);
|
||||
|
||||
|
||||
/**
|
||||
* qcrypto_tls_creds_reload:
|
||||
* @creds: pointer to a TLS credentials object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Request a reload of the TLS credentials, if supported
|
||||
*
|
||||
* Returns: true on success, false on error or if not supported
|
||||
*/
|
||||
bool qcrypto_tls_creds_reload(QCryptoTLSCreds *creds,
|
||||
Error **errp);
|
||||
|
||||
#endif /* QCRYPTO_TLSCREDS_H */
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* QEMU crypto TLS anonymous credential support
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_TLSCREDSANON_H
|
||||
#define QCRYPTO_TLSCREDSANON_H
|
||||
|
||||
#include "crypto/tlscreds.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_QCRYPTO_TLS_CREDS_ANON "tls-creds-anon"
|
||||
typedef struct QCryptoTLSCredsAnon QCryptoTLSCredsAnon;
|
||||
DECLARE_INSTANCE_CHECKER(QCryptoTLSCredsAnon, QCRYPTO_TLS_CREDS_ANON,
|
||||
TYPE_QCRYPTO_TLS_CREDS_ANON)
|
||||
|
||||
|
||||
typedef struct QCryptoTLSCredsAnonClass QCryptoTLSCredsAnonClass;
|
||||
|
||||
/**
|
||||
* QCryptoTLSCredsAnon:
|
||||
*
|
||||
* The QCryptoTLSCredsAnon object provides a representation
|
||||
* of anonymous credentials used perform a TLS handshake.
|
||||
* This is primarily provided for backwards compatibility and
|
||||
* its use is discouraged as it has poor security characteristics
|
||||
* due to lacking MITM attack protection amongst other problems.
|
||||
*
|
||||
* This is a user creatable object, which can be instantiated
|
||||
* via object_new_propv():
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating anonymous TLS credential objects in code</title>
|
||||
* <programlisting>
|
||||
* Object *obj;
|
||||
* Error *err = NULL;
|
||||
* obj = object_new_propv(TYPE_QCRYPTO_TLS_CREDS_ANON,
|
||||
* "tlscreds0",
|
||||
* &err,
|
||||
* "endpoint", "server",
|
||||
* "dir", "/path/x509/cert/dir",
|
||||
* "verify-peer", "yes",
|
||||
* NULL);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* Or via QMP:
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating anonymous TLS credential objects via QMP</title>
|
||||
* <programlisting>
|
||||
* {
|
||||
* "execute": "object-add", "arguments": {
|
||||
* "id": "tlscreds0",
|
||||
* "qom-type": "tls-creds-anon",
|
||||
* "props": {
|
||||
* "endpoint": "server",
|
||||
* "dir": "/path/to/x509/cert/dir",
|
||||
* "verify-peer": false
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
*
|
||||
* Or via the CLI:
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating anonymous TLS credential objects via CLI</title>
|
||||
* <programlisting>
|
||||
* qemu-system-x86_64 -object tls-creds-anon,id=tlscreds0,\
|
||||
* endpoint=server,verify-peer=off,\
|
||||
* dir=/path/to/x509/certdir/
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
*/
|
||||
|
||||
struct QCryptoTLSCredsAnonClass {
|
||||
QCryptoTLSCredsClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
#endif /* QCRYPTO_TLSCREDSANON_H */
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* QEMU crypto TLS Pre-Shared Key (PSK) support
|
||||
*
|
||||
* Copyright (c) 2018 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_TLSCREDSPSK_H
|
||||
#define QCRYPTO_TLSCREDSPSK_H
|
||||
|
||||
#include "crypto/tlscreds.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_QCRYPTO_TLS_CREDS_PSK "tls-creds-psk"
|
||||
typedef struct QCryptoTLSCredsPSK QCryptoTLSCredsPSK;
|
||||
DECLARE_INSTANCE_CHECKER(QCryptoTLSCredsPSK, QCRYPTO_TLS_CREDS_PSK,
|
||||
TYPE_QCRYPTO_TLS_CREDS_PSK)
|
||||
|
||||
typedef struct QCryptoTLSCredsPSKClass QCryptoTLSCredsPSKClass;
|
||||
|
||||
#define QCRYPTO_TLS_CREDS_PSKFILE "keys.psk"
|
||||
|
||||
/**
|
||||
* QCryptoTLSCredsPSK:
|
||||
*
|
||||
* The QCryptoTLSCredsPSK object provides a representation
|
||||
* of the Pre-Shared Key credential used to perform a TLS handshake.
|
||||
*
|
||||
* This is a user creatable object, which can be instantiated
|
||||
* via object_new_propv():
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating TLS-PSK credential objects in code</title>
|
||||
* <programlisting>
|
||||
* Object *obj;
|
||||
* Error *err = NULL;
|
||||
* obj = object_new_propv(TYPE_QCRYPTO_TLS_CREDS_PSK,
|
||||
* "tlscreds0",
|
||||
* &err,
|
||||
* "dir", "/path/to/dir",
|
||||
* "endpoint", "client",
|
||||
* NULL);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* Or via QMP:
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating TLS-PSK credential objects via QMP</title>
|
||||
* <programlisting>
|
||||
* {
|
||||
* "execute": "object-add", "arguments": {
|
||||
* "id": "tlscreds0",
|
||||
* "qom-type": "tls-creds-psk",
|
||||
* "props": {
|
||||
* "dir": "/path/to/dir",
|
||||
* "endpoint": "client"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* Or via the CLI:
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating TLS-PSK credential objects via CLI</title>
|
||||
* <programlisting>
|
||||
* qemu-system-x86_64 --object tls-creds-psk,id=tlscreds0,\
|
||||
* endpoint=client,dir=/path/to/dir[,username=qemu]
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* The PSK file can be created and managed using psktool.
|
||||
*/
|
||||
|
||||
struct QCryptoTLSCredsPSKClass {
|
||||
QCryptoTLSCredsClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
#endif /* QCRYPTO_TLSCREDSPSK_H */
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* QEMU crypto TLS x509 credential support
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_TLSCREDSX509_H
|
||||
#define QCRYPTO_TLSCREDSX509_H
|
||||
|
||||
#include "crypto/tlscreds.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_QCRYPTO_TLS_CREDS_X509 "tls-creds-x509"
|
||||
typedef struct QCryptoTLSCredsX509 QCryptoTLSCredsX509;
|
||||
DECLARE_INSTANCE_CHECKER(QCryptoTLSCredsX509, QCRYPTO_TLS_CREDS_X509,
|
||||
TYPE_QCRYPTO_TLS_CREDS_X509)
|
||||
|
||||
typedef struct QCryptoTLSCredsX509Class QCryptoTLSCredsX509Class;
|
||||
|
||||
#define QCRYPTO_TLS_CREDS_X509_CA_CERT "ca-cert.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_CA_CRL "ca-crl.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_SERVER_KEY "server-key.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_SERVER_CERT "server-cert.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_CLIENT_KEY "client-key.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_CLIENT_CERT "client-cert.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_SERVER_KEY_N "server-key-%zu.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_SERVER_CERT_N "server-cert-%zu.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_CLIENT_KEY_N "client-key-%zu.pem"
|
||||
#define QCRYPTO_TLS_CREDS_X509_CLIENT_CERT_N "client-cert-%zu.pem"
|
||||
|
||||
/* Max number of additional cert/key pairs (ie _N constants) */
|
||||
#define QCRYPTO_TLS_CREDS_X509_IDENTITY_MAX 4
|
||||
|
||||
/**
|
||||
* QCryptoTLSCredsX509:
|
||||
*
|
||||
* The QCryptoTLSCredsX509 object provides a representation
|
||||
* of x509 credentials used to perform a TLS handshake.
|
||||
*
|
||||
* This is a user creatable object, which can be instantiated
|
||||
* via object_new_propv():
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating x509 TLS credential objects in code</title>
|
||||
* <programlisting>
|
||||
* Object *obj;
|
||||
* Error *err = NULL;
|
||||
* obj = object_new_propv(TYPE_QCRYPTO_TLS_CREDS_X509,
|
||||
* "tlscreds0",
|
||||
* &err,
|
||||
* "endpoint", "server",
|
||||
* "dir", "/path/x509/cert/dir",
|
||||
* "verify-peer", "yes",
|
||||
* NULL);
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* Or via QMP:
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating x509 TLS credential objects via QMP</title>
|
||||
* <programlisting>
|
||||
* {
|
||||
* "execute": "object-add", "arguments": {
|
||||
* "id": "tlscreds0",
|
||||
* "qom-type": "tls-creds-x509",
|
||||
* "props": {
|
||||
* "endpoint": "server",
|
||||
* "dir": "/path/to/x509/cert/dir",
|
||||
* "verify-peer": false
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
*
|
||||
* Or via the CLI:
|
||||
*
|
||||
* <example>
|
||||
* <title>Creating x509 TLS credential objects via CLI</title>
|
||||
* <programlisting>
|
||||
* qemu-system-x86_64 -object tls-creds-x509,id=tlscreds0,\
|
||||
* endpoint=server,verify-peer=off,\
|
||||
* dir=/path/to/x509/certdir/
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
*/
|
||||
|
||||
struct QCryptoTLSCredsX509Class {
|
||||
QCryptoTLSCredsClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
#endif /* QCRYPTO_TLSCREDSX509_H */
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* QEMU crypto TLS session support
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCRYPTO_TLSSESSION_H
|
||||
#define QCRYPTO_TLSSESSION_H
|
||||
|
||||
#include "crypto/tlscreds.h"
|
||||
|
||||
/**
|
||||
* QCryptoTLSSession:
|
||||
*
|
||||
* The QCryptoTLSSession object encapsulates the
|
||||
* logic to integrate with a TLS providing library such
|
||||
* as GNUTLS, to setup and run TLS sessions.
|
||||
*
|
||||
* The API is designed such that it has no assumption about
|
||||
* the type of transport it is running over. It may be a
|
||||
* traditional TCP socket, or something else entirely. The
|
||||
* only requirement is a full-duplex stream of some kind.
|
||||
*
|
||||
* <example>
|
||||
* <title>Using TLS session objects</title>
|
||||
* <programlisting>
|
||||
* static ssize_t mysock_send(const char *buf, size_t len,
|
||||
* void *opaque)
|
||||
* {
|
||||
* int fd = GPOINTER_TO_INT(opaque);
|
||||
*
|
||||
* return write(*fd, buf, len);
|
||||
* }
|
||||
*
|
||||
* static ssize_t mysock_recv(const char *buf, size_t len,
|
||||
* void *opaque)
|
||||
* {
|
||||
* int fd = GPOINTER_TO_INT(opaque);
|
||||
*
|
||||
* return read(*fd, buf, len);
|
||||
* }
|
||||
*
|
||||
* static int mysock_run_tls(int sockfd,
|
||||
* QCryptoTLSCreds *creds,
|
||||
* Error **errp)
|
||||
* {
|
||||
* QCryptoTLSSession *sess;
|
||||
*
|
||||
* sess = qcrypto_tls_session_new(creds,
|
||||
* "vnc.example.com",
|
||||
* NULL,
|
||||
* QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
|
||||
* errp);
|
||||
* if (sess == NULL) {
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* qcrypto_tls_session_set_callbacks(sess,
|
||||
* mysock_send,
|
||||
* mysock_recv
|
||||
* GINT_TO_POINTER(fd));
|
||||
*
|
||||
* while (1) {
|
||||
* int ret = qcrypto_tls_session_handshake(sess, errp);
|
||||
*
|
||||
* if (ret < 0) {
|
||||
* qcrypto_tls_session_free(sess);
|
||||
* return -1;
|
||||
* }
|
||||
*
|
||||
* switch(ret) {
|
||||
* case QCRYPTO_TLS_HANDSHAKE_COMPLETE:
|
||||
* if (qcrypto_tls_session_check_credentials(sess, errp) < )) {
|
||||
* qcrypto_tls_session_free(sess);
|
||||
* return -1;
|
||||
* }
|
||||
* goto done;
|
||||
* case QCRYPTO_TLS_HANDSHAKE_RECVING:
|
||||
* ...wait for GIO_IN event on fd...
|
||||
* break;
|
||||
* case QCRYPTO_TLS_HANDSHAKE_SENDING:
|
||||
* ...wait for GIO_OUT event on fd...
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* done:
|
||||
*
|
||||
* ....send/recv payload data on sess...
|
||||
*
|
||||
* qcrypto_tls_session_free(sess):
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*/
|
||||
|
||||
typedef struct QCryptoTLSSession QCryptoTLSSession;
|
||||
|
||||
#define QCRYPTO_TLS_SESSION_ERR_BLOCK -2
|
||||
#define QCRYPTO_TLS_SESSION_PREMATURE_TERMINATION -3
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_new:
|
||||
* @creds: pointer to a TLS credentials object
|
||||
* @hostname: optional hostname to validate
|
||||
* @aclname: optional ACL to validate peer credentials against
|
||||
* @endpoint: role of the TLS session, client or server
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Create a new TLS session object that will be used to
|
||||
* negotiate a TLS session over an arbitrary data channel.
|
||||
* The session object can operate as either the server or
|
||||
* client, according to the value of the @endpoint argument.
|
||||
*
|
||||
* For clients, the @hostname parameter should hold the full
|
||||
* unmodified hostname as requested by the user. This will
|
||||
* be used to verify the against the hostname reported in
|
||||
* the server's credentials (aka x509 certificate).
|
||||
*
|
||||
* The @aclname parameter (optionally) specifies the name
|
||||
* of an access control list that will be used to validate
|
||||
* the peer's credentials. For x509 credentials, the ACL
|
||||
* will be matched against the CommonName shown in the peer's
|
||||
* certificate. If the session is acting as a server, setting
|
||||
* an ACL will require that the client provide a validate
|
||||
* x509 client certificate.
|
||||
*
|
||||
* After creating the session object, the I/O callbacks
|
||||
* must be set using the qcrypto_tls_session_set_callbacks()
|
||||
* method. A TLS handshake sequence must then be completed
|
||||
* using qcrypto_tls_session_handshake(), before payload
|
||||
* data is permitted to be sent/received.
|
||||
*
|
||||
* The session object must be released by calling
|
||||
* qcrypto_tls_session_free() when no longer required
|
||||
*
|
||||
* Returns: a TLS session object, or NULL on error.
|
||||
*/
|
||||
QCryptoTLSSession *qcrypto_tls_session_new(QCryptoTLSCreds *creds,
|
||||
const char *hostname,
|
||||
const char *aclname,
|
||||
QCryptoTLSCredsEndpoint endpoint,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_free:
|
||||
* @sess: the TLS session object
|
||||
*
|
||||
* Release all memory associated with the TLS session
|
||||
* object previously allocated by qcrypto_tls_session_new()
|
||||
*/
|
||||
void qcrypto_tls_session_free(QCryptoTLSSession *sess);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free)
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_require_thread_safety:
|
||||
* @sess: the TLS session object
|
||||
*
|
||||
* Mark that this TLS session will require thread safety
|
||||
* for concurrent I/O in both directions. This must be
|
||||
* called before the handshake is performed.
|
||||
*
|
||||
* This will activate a workaround for GNUTLS thread
|
||||
* safety issues, where appropriate for the negotiated
|
||||
* TLS session parameters.
|
||||
*/
|
||||
void qcrypto_tls_session_require_thread_safety(QCryptoTLSSession *sess);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_check_credentials:
|
||||
* @sess: the TLS session object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Validate the peer's credentials after a successful
|
||||
* TLS handshake. It is an error to call this before
|
||||
* qcrypto_tls_session_handshake() returns
|
||||
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
|
||||
*
|
||||
* Returns 0 if the credentials validated, -1 on error
|
||||
*/
|
||||
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 void *buf,
|
||||
size_t len,
|
||||
void *opaque,
|
||||
Error **errp);
|
||||
typedef ssize_t (*QCryptoTLSSessionReadFunc)(void *buf,
|
||||
size_t len,
|
||||
void *opaque,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_set_callbacks:
|
||||
* @sess: the TLS session object
|
||||
* @writeFunc: callback for sending data
|
||||
* @readFunc: callback to receiving data
|
||||
* @opaque: data to pass to callbacks
|
||||
*
|
||||
* Sets the callback functions that are to be used for sending
|
||||
* and receiving data on the underlying data channel. Typically
|
||||
* the callbacks to write/read to/from a TCP socket, but there
|
||||
* is no assumption made about the type of channel used.
|
||||
*
|
||||
* The @writeFunc callback will be passed the encrypted
|
||||
* data to send to the remote peer.
|
||||
*
|
||||
* The @readFunc callback will be passed a pointer to fill
|
||||
* with encrypted data received from the remote peer
|
||||
*/
|
||||
void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess,
|
||||
QCryptoTLSSessionWriteFunc writeFunc,
|
||||
QCryptoTLSSessionReadFunc readFunc,
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_write:
|
||||
* @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_handshake() returns
|
||||
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
|
||||
*
|
||||
* 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,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_read:
|
||||
* @sess: the TLS session object
|
||||
* @buf: to fill with plain text received
|
||||
* @len: the length of @buf
|
||||
* @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.
|
||||
*
|
||||
* It is an error to call this before
|
||||
* qcrypto_tls_session_handshake() returns
|
||||
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
|
||||
*
|
||||
* Returns: the number of bytes received,
|
||||
* or QCRYPTO_TLS_SESSION_ERR_BLOCK if the receive would block,
|
||||
* or QCRYPTO_TLS_SESSION_PREMATURE_TERMINATION if a premature termination
|
||||
* is detected, or -1 on error.
|
||||
*/
|
||||
ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess,
|
||||
char *buf,
|
||||
size_t len,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_check_pending:
|
||||
* @sess: the TLS session object
|
||||
*
|
||||
* Check if there are unread data in the TLS buffers that have
|
||||
* already been read from the underlying data source.
|
||||
*
|
||||
* Returns: the number of bytes available or zero
|
||||
*/
|
||||
size_t qcrypto_tls_session_check_pending(QCryptoTLSSession *sess);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_handshake:
|
||||
* @sess: the TLS session object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Start, or continue, a TLS handshake sequence. If
|
||||
* the underlying data channel is non-blocking, then
|
||||
* this method may return control before the handshake
|
||||
* is complete. On non-blocking channels the
|
||||
* 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
|
||||
* once the underlying data channel is ready to read
|
||||
* or write again
|
||||
*/
|
||||
int qcrypto_tls_session_handshake(QCryptoTLSSession *sess,
|
||||
Error **errp);
|
||||
|
||||
typedef enum {
|
||||
QCRYPTO_TLS_HANDSHAKE_COMPLETE,
|
||||
QCRYPTO_TLS_HANDSHAKE_SENDING,
|
||||
QCRYPTO_TLS_HANDSHAKE_RECVING,
|
||||
} QCryptoTLSSessionHandshakeStatus;
|
||||
|
||||
typedef enum {
|
||||
QCRYPTO_TLS_BYE_COMPLETE,
|
||||
QCRYPTO_TLS_BYE_SENDING,
|
||||
QCRYPTO_TLS_BYE_RECVING,
|
||||
} QCryptoTLSSessionByeStatus;
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_bye:
|
||||
* @session: the TLS session object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
int
|
||||
qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_get_key_size:
|
||||
* @sess: the TLS session object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Check the size of the data channel encryption key
|
||||
*
|
||||
* Returns: the length in bytes of the encryption key
|
||||
* or -1 on error
|
||||
*/
|
||||
int qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_tls_session_get_peer_name:
|
||||
* @sess: the TLS session object
|
||||
*
|
||||
* Get the identified name of the remote peer. If the
|
||||
* TLS session was negotiated using x509 certificate
|
||||
* credentials, this will return the CommonName from
|
||||
* the peer's certificate. If no identified name is
|
||||
* available it will return NULL.
|
||||
*
|
||||
* The returned data must be released with g_free()
|
||||
* when no longer required.
|
||||
*
|
||||
* Returns: the peer's name or NULL.
|
||||
*/
|
||||
char *qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess);
|
||||
|
||||
#endif /* QCRYPTO_TLSSESSION_H */
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* X.509 certificate related helpers
|
||||
*
|
||||
* Copyright (c) 2024 Dorjoy Chowdhury <[email protected]>
|
||||
*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* qcrypto_x509_convert_cert_der
|
||||
* @cert: pointer to the raw certificate data in PEM format
|
||||
* @size: size of the certificate
|
||||
* @result: output location for the allocated buffer for the certificate
|
||||
* in DER format
|
||||
* (the function allocates memory which must be freed by the caller)
|
||||
* @resultlen: pointer to the size of the buffer (will be updated with the
|
||||
* actual size of the DER-encoded certificate)
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Convert the given @cert from PEM to DER format.
|
||||
*
|
||||
* Returns: 0 on success,
|
||||
* -1 on error.
|
||||
*/
|
||||
int qcrypto_x509_convert_cert_der(uint8_t *cert, size_t size,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_x509_check_cert_times
|
||||
* @cert: pointer to the raw certificate data
|
||||
* @size: size of the certificate
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Check whether the activation and expiration times of @cert
|
||||
* are valid at the current time.
|
||||
*
|
||||
* Returns: 0 if the certificate times are valid,
|
||||
* -1 on error.
|
||||
*/
|
||||
int qcrypto_x509_check_cert_times(uint8_t *cert, size_t size, Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_x509_get_cert_key_id
|
||||
* @cert: pointer to the raw certificate data
|
||||
* @size: size of the certificate
|
||||
* @hash_alg: the hash algorithm flag
|
||||
* @result: output location for the allocated buffer for key ID
|
||||
* (the function allocates memory which must be freed by the caller)
|
||||
* @resultlen: pointer to the size of the buffer
|
||||
* (will be updated with the actual size of key id)
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Retrieve the key ID from the @cert based on the specified @hash_alg.
|
||||
*
|
||||
* Returns: 0 if key ID was successfully stored in @result,
|
||||
* -1 on error.
|
||||
*/
|
||||
int qcrypto_x509_get_cert_key_id(uint8_t *cert, size_t size,
|
||||
QCryptoHashAlgo hash_alg,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_x509_check_ecc_curve_p521
|
||||
* @cert: pointer to the raw certificate data
|
||||
* @size: size of the certificate
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Determine whether the ECC public key in the given certificate uses the P-521
|
||||
* curve.
|
||||
*
|
||||
* Returns: 0 if ECC public key does not use P521 curve.
|
||||
* 1 if ECC public key uses P521 curve.
|
||||
* -1 on error.
|
||||
*/
|
||||
int qcrypto_x509_check_ecc_curve_p521(uint8_t *cert, size_t size, Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_pkcs7_convert_sig_pem
|
||||
* @sig: pointer to the PKCS#7 signature in DER format
|
||||
* @sig_size: size of the signature
|
||||
* @result: output location for the allocated buffer for the signature in
|
||||
* PEM format
|
||||
* (the function allocates memory which must be freed by the caller)
|
||||
* @resultlen: pointer to the size of the buffer
|
||||
* (will be updated with the actual size of the PEM-encoded
|
||||
* signature)
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Convert given PKCS#7 @sig from DER to PEM format.
|
||||
*
|
||||
* Returns: 0 if PEM-encoded signature was successfully stored in @result,
|
||||
* -1 on error.
|
||||
*/
|
||||
int qcrypto_pkcs7_convert_sig_pem(uint8_t *sig, size_t sig_size,
|
||||
uint8_t **result,
|
||||
size_t *resultlen,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qcrypto_x509_verify_sig
|
||||
* @cert: pointer to the raw certificate data
|
||||
* @cert_size: size of the certificate
|
||||
* @comp: pointer to the component to be verified
|
||||
* @comp_size: size of the component
|
||||
* @sig: pointer to the signature
|
||||
* @sig_size: size of the signature
|
||||
* @errp: error pointer
|
||||
*
|
||||
* Verify the provided @comp against the @sig and @cert.
|
||||
*
|
||||
* Returns: 0 on success,
|
||||
* -1 on error.
|
||||
*/
|
||||
int qcrypto_x509_verify_sig(uint8_t *cert, size_t cert_size,
|
||||
uint8_t *comp, size_t comp_size,
|
||||
uint8_t *sig, size_t sig_size, Error **errp);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user