Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: Introduce akcipher crypto class
Introduce new akcipher crypto class 'QCryptoAkCIpher', which supports basic asymmetric operations: encrypt, decrypt, sign and verify. Suggested by Daniel P. Berrangé, also add autoptr cleanup for the new class. Thanks to Daniel! Co-developed-by: lei he <helei.sig11@bytedance.com> Signed-off-by: lei he <helei.sig11@bytedance.com> Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
- Loading branch information
Showing
4 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* QEMU Crypto akcipher algorithms | ||
* | ||
* Copyright (c) 2022 Bytedance | ||
* Author: zhenwei pi <pizhenwei@bytedance.com> | ||
* | ||
* This library is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 2.1 of the License, or (at your option) any later version. | ||
* | ||
* This library is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "crypto/akcipher.h" | ||
#include "akcipherpriv.h" | ||
|
||
QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts, | ||
QCryptoAkCipherKeyType type, | ||
const uint8_t *key, size_t keylen, | ||
Error **errp) | ||
{ | ||
QCryptoAkCipher *akcipher = NULL; | ||
|
||
return akcipher; | ||
} | ||
|
||
bool qcrypto_akcipher_supports(QCryptoAkCipherOptions *opts) | ||
{ | ||
return false; | ||
} | ||
|
||
int qcrypto_akcipher_encrypt(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
void *out, size_t out_len, Error **errp) | ||
{ | ||
const QCryptoAkCipherDriver *drv = akcipher->driver; | ||
|
||
return drv->encrypt(akcipher, in, in_len, out, out_len, errp); | ||
} | ||
|
||
int qcrypto_akcipher_decrypt(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
void *out, size_t out_len, Error **errp) | ||
{ | ||
const QCryptoAkCipherDriver *drv = akcipher->driver; | ||
|
||
return drv->decrypt(akcipher, in, in_len, out, out_len, errp); | ||
} | ||
|
||
int qcrypto_akcipher_sign(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
void *out, size_t out_len, Error **errp) | ||
{ | ||
const QCryptoAkCipherDriver *drv = akcipher->driver; | ||
|
||
return drv->sign(akcipher, in, in_len, out, out_len, errp); | ||
} | ||
|
||
int qcrypto_akcipher_verify(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
const void *in2, size_t in2_len, Error **errp) | ||
{ | ||
const QCryptoAkCipherDriver *drv = akcipher->driver; | ||
|
||
return drv->verify(akcipher, in, in_len, in2, in2_len, errp); | ||
} | ||
|
||
int qcrypto_akcipher_max_plaintext_len(QCryptoAkCipher *akcipher) | ||
{ | ||
return akcipher->max_plaintext_len; | ||
} | ||
|
||
int qcrypto_akcipher_max_ciphertext_len(QCryptoAkCipher *akcipher) | ||
{ | ||
return akcipher->max_ciphertext_len; | ||
} | ||
|
||
int qcrypto_akcipher_max_signature_len(QCryptoAkCipher *akcipher) | ||
{ | ||
return akcipher->max_signature_len; | ||
} | ||
|
||
int qcrypto_akcipher_max_dgst_len(QCryptoAkCipher *akcipher) | ||
{ | ||
return akcipher->max_dgst_len; | ||
} | ||
|
||
void qcrypto_akcipher_free(QCryptoAkCipher *akcipher) | ||
{ | ||
const QCryptoAkCipherDriver *drv = akcipher->driver; | ||
|
||
drv->free(akcipher); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* QEMU Crypto asymmetric algorithms | ||
* | ||
* Copyright (c) 2022 Bytedance | ||
* Author: zhenwei pi <pizhenwei@bytedance.com> | ||
* | ||
* 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_AKCIPHERPRIV_H | ||
#define QCRYPTO_AKCIPHERPRIV_H | ||
|
||
#include "qapi/qapi-types-crypto.h" | ||
|
||
typedef struct QCryptoAkCipherDriver QCryptoAkCipherDriver; | ||
|
||
struct QCryptoAkCipher { | ||
QCryptoAkCipherAlgorithm alg; | ||
QCryptoAkCipherKeyType type; | ||
int max_plaintext_len; | ||
int max_ciphertext_len; | ||
int max_signature_len; | ||
int max_dgst_len; | ||
QCryptoAkCipherDriver *driver; | ||
}; | ||
|
||
struct QCryptoAkCipherDriver { | ||
int (*encrypt)(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
void *out, size_t out_len, Error **errp); | ||
int (*decrypt)(QCryptoAkCipher *akcipher, | ||
const void *out, size_t out_len, | ||
void *in, size_t in_len, Error **errp); | ||
int (*sign)(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
void *out, size_t out_len, Error **errp); | ||
int (*verify)(QCryptoAkCipher *akcipher, | ||
const void *in, size_t in_len, | ||
const void *in2, size_t in2_len, Error **errp); | ||
void (*free)(QCryptoAkCipher *akcipher); | ||
}; | ||
|
||
#endif /* QCRYPTO_AKCIPHER_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
crypto_ss.add(genh) | ||
crypto_ss.add(files( | ||
'afsplit.c', | ||
'akcipher.c', | ||
'block-luks.c', | ||
'block-qcow.c', | ||
'block.c', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* QEMU Crypto asymmetric algorithms | ||
* | ||
* Copyright (c) 2022 Bytedance | ||
* Author: zhenwei pi <pizhenwei@bytedance.com> | ||
* | ||
* 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 decribed 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); | ||
|
||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoAkCipher, qcrypto_akcipher_free) | ||
|
||
#endif /* QCRYPTO_AKCIPHER_H */ |