This patch add nettle-backed AEAD algorithms Signed-off-by: Longpeng(Mike) <longpe...@huawei.com> --- crypto/aead-nettle.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 7 deletions(-)
diff --git a/crypto/aead-nettle.c b/crypto/aead-nettle.c index cfb9d33..7a2296d 100644 --- a/crypto/aead-nettle.c +++ b/crypto/aead-nettle.c @@ -19,17 +19,124 @@ #include <nettle/ccm.h> #include <nettle/gcm.h> +typedef void (*qcrypto_nettle_aead_setkey)(void *ctx, + const uint8_t *key); + +typedef void (*qcrypto_nettle_aead_setiv)(void *ctx, + size_t length, const uint8_t *iv); + +typedef void (*qcrypto_nettle_aead_setnonce)(void *ctx, + size_t length, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen); + +typedef void (*qcrypto_nettle_aead_update)(void *ctx, + size_t length, const uint8_t *data); + +typedef void (*qcrypto_nettle_aead_encrypt)(void *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +typedef void (*qcrypto_nettle_aead_decrypt)(void *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +typedef void (*qcrypto_nettle_aead_digest)(void *ctx, + size_t length, uint8_t *digest); + +#define NETTLE_AEAD_SET_CCM_FN(alg) { \ + .setkey = (qcrypto_nettle_aead_setkey)ccm_##alg##_set_key, \ + .u_op.setnonce = (qcrypto_nettle_aead_setnonce)ccm_##alg##_set_nonce, \ + .update = (qcrypto_nettle_aead_update)ccm_##alg##_update, \ + .encrypt = (qcrypto_nettle_aead_encrypt)ccm_##alg##_encrypt, \ + .decrypt = (qcrypto_nettle_aead_decrypt)ccm_##alg##_decrypt, \ + .digest = (qcrypto_nettle_aead_digest)ccm_##alg##_digest, \ +} + +#define NETTLE_AEAD_SET_GCM_FN(alg) { \ + .setkey = (qcrypto_nettle_aead_setkey)gcm_##alg##_set_key, \ + .u_op.setiv = (qcrypto_nettle_aead_setiv)gcm_##alg##_set_iv, \ + .update = (qcrypto_nettle_aead_update)gcm_##alg##_update, \ + .encrypt = (qcrypto_nettle_aead_encrypt)gcm_##alg##_encrypt, \ + .decrypt = (qcrypto_nettle_aead_decrypt)gcm_##alg##_decrypt, \ + .digest = (qcrypto_nettle_aead_digest)gcm_##alg##_digest, \ +} + +static struct qcrypto_nettle_aead_alg { + qcrypto_nettle_aead_setkey setkey; + union { + qcrypto_nettle_aead_setnonce setnonce; + qcrypto_nettle_aead_setiv setiv; + } u_op; + qcrypto_nettle_aead_update update; + qcrypto_nettle_aead_encrypt encrypt; + qcrypto_nettle_aead_decrypt decrypt; + qcrypto_nettle_aead_digest digest; +} qcrypto_aead_alg_map[][QCRYPTO_AEAD_ALG__MAX] = { + { + [QCRYPTO_CIPHER_ALG_AES_128] = NETTLE_AEAD_SET_CCM_FN(aes128), + [QCRYPTO_CIPHER_ALG_AES_192] = NETTLE_AEAD_SET_CCM_FN(aes192), + [QCRYPTO_CIPHER_ALG_AES_256] = NETTLE_AEAD_SET_CCM_FN(aes256), + }, + { + [QCRYPTO_CIPHER_ALG_AES_128] = NETTLE_AEAD_SET_GCM_FN(aes128), + [QCRYPTO_CIPHER_ALG_AES_192] = NETTLE_AEAD_SET_GCM_FN(aes192), + [QCRYPTO_CIPHER_ALG_AES_256] = NETTLE_AEAD_SET_GCM_FN(aes256), + } +}; + +typedef struct QCryptoAeadNettle QCryptoAeadNettle; +struct QCryptoAeadNettle { + union qcrypto_nettle_aead_ctx { + struct ccm_aes128_ctx c_aes128_ctx; + struct ccm_aes192_ctx c_aes192_ctx; + struct ccm_aes256_ctx c_aes256_ctx; + struct gcm_aes128_ctx g_aes128_ctx; + struct gcm_aes192_ctx g_aes192_ctx; + struct gcm_aes256_ctx g_aes256_ctx; + } u; +}; + QCryptoAead *qcrypto_aead_new(QCryptoCipherAlgorithm alg, QCryptoCipherMode mode, const uint8_t *key, size_t nkey, Error **errp) { - return NULL; + QCryptoAead *aead; + QCryptoAeadNettle *ctx; + + if (!qcrypto_aead_supports(alg, mode)) { + return NULL; + } + + if (nkey != qcrypto_aead_get_key_len(alg)) { + error_setg(errp, "Cipher key length %zu is invalid", + nkey); + return NULL; + } + + aead = g_new0(QCryptoAead, 1); + aead->alg = alg; + aead->mode = mode; + + ctx = g_new0(QCryptoAeadNettle, 1); + + qcrypto_aead_alg_map[mode][alg].setkey(&ctx->u, key); + + aead->opaque = ctx; + + return aead; } void qcrypto_aead_free(QCryptoAead *aead) { - return; + QCryptoAeadNettle *ctx; + + if (!aead) { + return; + } + + ctx = aead->opaque; + + g_free(ctx); + g_free(aead); } int qcrypto_aead_set_nonce(QCryptoAead *aead, @@ -38,14 +145,43 @@ int qcrypto_aead_set_nonce(QCryptoAead *aead, size_t tag_len, Error **errp) { - return -1; + QCryptoAeadNettle *ctx; + struct qcrypto_nettle_aead_alg *aead_ops; + + ctx = (QCryptoAeadNettle *)aead->opaque; + + switch (aead->mode) { + case QCRYPTO_CIPHER_MODE_CCM: + aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg]; + aead_ops->u_op.setnonce(&ctx->u, nonce_len, nonce, aad_len, + in_len, tag_len); + break; + case QCRYPTO_CIPHER_MODE_GCM: + aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg]; + aead_ops->u_op.setiv(&ctx->u, nonce_len, nonce); + break; + default: + error_setg(errp, "Unsupported AEAD mode: %d", + aead->mode); + return -1; + } + + return 0; } int qcrypto_aead_authenticate(QCryptoAead *aead, const uint8_t *aad, size_t aad_len, Error **errp) { - return -1; + QCryptoAeadNettle *ctx; + struct qcrypto_nettle_aead_alg *aead_ops; + + ctx = (QCryptoAeadNettle *)aead->opaque; + aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg]; + + aead_ops->update(&ctx->u, aad_len, aad); + + return 0; } int qcrypto_aead_encrypt(QCryptoAead *aead, @@ -53,7 +189,15 @@ int qcrypto_aead_encrypt(QCryptoAead *aead, uint8_t *out, size_t out_len, Error **errp) { - return -1; + QCryptoAeadNettle *ctx; + struct qcrypto_nettle_aead_alg *aead_ops; + + ctx = (QCryptoAeadNettle *)aead->opaque; + aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg]; + + aead_ops->encrypt(&ctx->u, in_len, out, in); + + return 0; } int qcrypto_aead_decrypt(QCryptoAead *aead, @@ -61,12 +205,28 @@ int qcrypto_aead_decrypt(QCryptoAead *aead, uint8_t *out, size_t out_len, Error **errp) { - return -1; + QCryptoAeadNettle *ctx; + struct qcrypto_nettle_aead_alg *aead_ops; + + ctx = (QCryptoAeadNettle *)aead->opaque; + aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg]; + + aead_ops->decrypt(&ctx->u, in_len, out, in); + + return 0; } int qcrypto_aead_get_tag(QCryptoAead *aead, uint8_t *tag, size_t tag_len, Error **errp) { - return -1; + QCryptoAeadNettle *ctx; + struct qcrypto_nettle_aead_alg *aead_ops; + + ctx = (QCryptoAeadNettle *)aead->opaque; + aead_ops = &qcrypto_aead_alg_map[aead->mode][aead->alg]; + + aead_ops->digest(&ctx->u, tag_len, tag); + + return 0; } -- 2.9.3