Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'remotes/berrange/tags/pull-qcrypto-2016…
…-12-21-2' into staging Merge qcrypto 2016/12/21 v2 # gpg: Signature made Thu 22 Dec 2016 10:46:17 GMT # gpg: using RSA key 0xBE86EBB415104FDF # gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" # gpg: aka "Daniel P. Berrange <berrange@redhat.com>" # Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF * remotes/berrange/tags/pull-qcrypto-2016-12-21-2: crypto: add HMAC algorithms testcases crypto: support HMAC algorithms based on nettle crypto: support HMAC algorithms based on glib crypto: support HMAC algorithms based on libgcrypt crypto: add HMAC algorithms framework configure: add CONFIG_GCRYPT_HMAC item crypto: add 3des-ede support when using libgcrypt/nettle cipher: fix leak on initialization error Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
- Loading branch information
Showing
14 changed files
with
1,191 additions
and
6 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
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
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
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
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
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,152 @@ | ||
/* | ||
* QEMU Crypto hmac algorithms (based on libgcrypt) | ||
* | ||
* Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. | ||
* | ||
* Authors: | ||
* Longpeng(Mike) <longpeng2@huawei.com> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or | ||
* (at your option) any later version. See the COPYING file in the | ||
* top-level directory. | ||
* | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qapi/error.h" | ||
#include "crypto/hmac.h" | ||
#include <gcrypt.h> | ||
|
||
static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { | ||
[QCRYPTO_HASH_ALG_MD5] = GCRY_MAC_HMAC_MD5, | ||
[QCRYPTO_HASH_ALG_SHA1] = GCRY_MAC_HMAC_SHA1, | ||
[QCRYPTO_HASH_ALG_SHA224] = GCRY_MAC_HMAC_SHA224, | ||
[QCRYPTO_HASH_ALG_SHA256] = GCRY_MAC_HMAC_SHA256, | ||
[QCRYPTO_HASH_ALG_SHA384] = GCRY_MAC_HMAC_SHA384, | ||
[QCRYPTO_HASH_ALG_SHA512] = GCRY_MAC_HMAC_SHA512, | ||
[QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MAC_HMAC_RMD160, | ||
}; | ||
|
||
typedef struct QCryptoHmacGcrypt QCryptoHmacGcrypt; | ||
struct QCryptoHmacGcrypt { | ||
gcry_mac_hd_t handle; | ||
}; | ||
|
||
bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) | ||
{ | ||
if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && | ||
qcrypto_hmac_alg_map[alg] != GCRY_MAC_NONE) { | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, | ||
const uint8_t *key, size_t nkey, | ||
Error **errp) | ||
{ | ||
QCryptoHmac *hmac; | ||
QCryptoHmacGcrypt *ctx; | ||
gcry_error_t err; | ||
|
||
if (!qcrypto_hmac_supports(alg)) { | ||
error_setg(errp, "Unsupported hmac algorithm %s", | ||
QCryptoHashAlgorithm_lookup[alg]); | ||
return NULL; | ||
} | ||
|
||
hmac = g_new0(QCryptoHmac, 1); | ||
hmac->alg = alg; | ||
|
||
ctx = g_new0(QCryptoHmacGcrypt, 1); | ||
|
||
err = gcry_mac_open(&ctx->handle, qcrypto_hmac_alg_map[alg], | ||
GCRY_MAC_FLAG_SECURE, NULL); | ||
if (err != 0) { | ||
error_setg(errp, "Cannot initialize hmac: %s", | ||
gcry_strerror(err)); | ||
goto error; | ||
} | ||
|
||
err = gcry_mac_setkey(ctx->handle, (const void *)key, nkey); | ||
if (err != 0) { | ||
error_setg(errp, "Cannot set key: %s", | ||
gcry_strerror(err)); | ||
goto error; | ||
} | ||
|
||
hmac->opaque = ctx; | ||
return hmac; | ||
|
||
error: | ||
g_free(ctx); | ||
g_free(hmac); | ||
return NULL; | ||
} | ||
|
||
void qcrypto_hmac_free(QCryptoHmac *hmac) | ||
{ | ||
QCryptoHmacGcrypt *ctx; | ||
|
||
if (!hmac) { | ||
return; | ||
} | ||
|
||
ctx = hmac->opaque; | ||
gcry_mac_close(ctx->handle); | ||
|
||
g_free(ctx); | ||
g_free(hmac); | ||
} | ||
|
||
int qcrypto_hmac_bytesv(QCryptoHmac *hmac, | ||
const struct iovec *iov, | ||
size_t niov, | ||
uint8_t **result, | ||
size_t *resultlen, | ||
Error **errp) | ||
{ | ||
QCryptoHmacGcrypt *ctx; | ||
gcry_error_t err; | ||
uint32_t ret; | ||
int i; | ||
|
||
ctx = hmac->opaque; | ||
|
||
for (i = 0; i < niov; i++) { | ||
gcry_mac_write(ctx->handle, iov[i].iov_base, iov[i].iov_len); | ||
} | ||
|
||
ret = gcry_mac_get_algo_maclen(qcrypto_hmac_alg_map[hmac->alg]); | ||
if (ret <= 0) { | ||
error_setg(errp, "Unable to get hmac length: %s", | ||
gcry_strerror(ret)); | ||
return -1; | ||
} | ||
|
||
if (*resultlen == 0) { | ||
*resultlen = ret; | ||
*result = g_new0(uint8_t, *resultlen); | ||
} else if (*resultlen != ret) { | ||
error_setg(errp, "Result buffer size %zu is smaller than hmac %d", | ||
*resultlen, ret); | ||
return -1; | ||
} | ||
|
||
err = gcry_mac_read(ctx->handle, *result, resultlen); | ||
if (err != 0) { | ||
error_setg(errp, "Cannot get result: %s", | ||
gcry_strerror(err)); | ||
return -1; | ||
} | ||
|
||
err = gcry_mac_reset(ctx->handle); | ||
if (err != 0) { | ||
error_setg(errp, "Cannot reset hmac context: %s", | ||
gcry_strerror(err)); | ||
return -1; | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.