diff options
Diffstat (limited to 'lib/accelerated/x86/hmac-x86-ssse3.c')
-rw-r--r-- | lib/accelerated/x86/hmac-x86-ssse3.c | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/lib/accelerated/x86/hmac-x86-ssse3.c b/lib/accelerated/x86/hmac-x86-ssse3.c new file mode 100644 index 0000000..8a60100 --- /dev/null +++ b/lib/accelerated/x86/hmac-x86-ssse3.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2008, 2010-2012 Free Software Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS 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 program. If not, see <https://www.gnu.org/licenses/> + * + */ + +/* This file provides the backend hash/mac implementation for + * VIA Padlock hardware acceleration. + */ + +#include "gnutls_int.h" +#include <hash_int.h> +#include "errors.h" +#include <nettle/sha.h> +#include <nettle/hmac.h> +#include <nettle/macros.h> +#include <aes-x86.h> +#include <sha-x86.h> +#include <algorithms.h> + +#ifdef HAVE_LIBNETTLE + +typedef void (*update_func) (void *, size_t, const uint8_t *); +typedef void (*digest_func) (void *, size_t, uint8_t *); +typedef void (*set_key_func) (void *, size_t, const uint8_t *); + +struct x86_hmac_ctx { + union { + struct hmac_sha1_ctx sha1; + struct hmac_sha224_ctx sha224; + struct hmac_sha256_ctx sha256; + struct hmac_sha384_ctx sha384; + struct hmac_sha512_ctx sha512; + } ctx; + + void *ctx_ptr; + gnutls_mac_algorithm_t algo; + size_t length; + update_func update; + digest_func digest; + set_key_func setkey; +}; + +static void +x86_hmac_sha1_set_key(struct hmac_sha1_ctx *ctx, + size_t key_length, const uint8_t * key) +{ + HMAC_SET_KEY(ctx, &x86_sha1, key_length, key); +} + +static void +x86_hmac_sha1_update(struct hmac_sha1_ctx *ctx, + size_t length, const uint8_t * data) +{ + x86_sha1_update(&ctx->state, length, data); +} + +static void +x86_hmac_sha1_digest(struct hmac_sha1_ctx *ctx, + size_t length, uint8_t * digest) +{ + HMAC_DIGEST(ctx, &x86_sha1, length, digest); +} + +static void +x86_hmac_sha256_set_key(struct hmac_sha256_ctx *ctx, + size_t key_length, const uint8_t * key) +{ + HMAC_SET_KEY(ctx, &x86_sha256, key_length, key); +} + +static void +x86_hmac_sha256_update(struct hmac_sha256_ctx *ctx, + size_t length, const uint8_t * data) +{ + x86_sha256_update(&ctx->state, length, data); +} + +static void +x86_hmac_sha256_digest(struct hmac_sha256_ctx *ctx, + size_t length, uint8_t * digest) +{ + HMAC_DIGEST(ctx, &x86_sha256, length, digest); +} + +static void +x86_hmac_sha224_set_key(struct hmac_sha224_ctx *ctx, + size_t key_length, const uint8_t * key) +{ + HMAC_SET_KEY(ctx, &x86_sha224, key_length, key); +} + +static void +x86_hmac_sha224_digest(struct hmac_sha224_ctx *ctx, + size_t length, uint8_t * digest) +{ + HMAC_DIGEST(ctx, &x86_sha224, length, digest); +} + +static void +x86_hmac_sha384_set_key(struct hmac_sha384_ctx *ctx, + size_t key_length, const uint8_t * key) +{ + HMAC_SET_KEY(ctx, &x86_sha384, key_length, key); +} + +static void +x86_hmac_sha384_digest(struct hmac_sha384_ctx *ctx, + size_t length, uint8_t * digest) +{ + HMAC_DIGEST(ctx, &x86_sha384, length, digest); +} + +static void +x86_hmac_sha512_set_key(struct hmac_sha512_ctx *ctx, + size_t key_length, const uint8_t * key) +{ + HMAC_SET_KEY(ctx, &x86_sha512, key_length, key); +} + +static void +x86_hmac_sha512_update(struct hmac_sha512_ctx *ctx, + size_t length, const uint8_t * data) +{ + x86_sha512_update(&ctx->state, length, data); +} + +static void +x86_hmac_sha512_digest(struct hmac_sha512_ctx *ctx, + size_t length, uint8_t * digest) +{ + HMAC_DIGEST(ctx, &x86_sha512, length, digest); +} + +static int +_hmac_ctx_init(gnutls_mac_algorithm_t algo, struct x86_hmac_ctx *ctx) +{ + switch (algo) { + case GNUTLS_MAC_SHA1: + ctx->update = (update_func) x86_hmac_sha1_update; + ctx->digest = (digest_func) x86_hmac_sha1_digest; + ctx->setkey = (set_key_func) x86_hmac_sha1_set_key; + ctx->ctx_ptr = &ctx->ctx.sha1; + ctx->length = SHA1_DIGEST_SIZE; + break; + case GNUTLS_MAC_SHA224: + ctx->update = (update_func) x86_hmac_sha256_update; + ctx->digest = (digest_func) x86_hmac_sha224_digest; + ctx->setkey = (set_key_func) x86_hmac_sha224_set_key; + ctx->ctx_ptr = &ctx->ctx.sha224; + ctx->length = SHA224_DIGEST_SIZE; + break; + case GNUTLS_MAC_SHA256: + ctx->update = (update_func) x86_hmac_sha256_update; + ctx->digest = (digest_func) x86_hmac_sha256_digest; + ctx->setkey = (set_key_func) x86_hmac_sha256_set_key; + ctx->ctx_ptr = &ctx->ctx.sha256; + ctx->length = SHA256_DIGEST_SIZE; + break; + case GNUTLS_MAC_SHA384: + ctx->update = (update_func) x86_hmac_sha512_update; + ctx->digest = (digest_func) x86_hmac_sha384_digest; + ctx->setkey = (set_key_func) x86_hmac_sha384_set_key; + ctx->ctx_ptr = &ctx->ctx.sha384; + ctx->length = SHA384_DIGEST_SIZE; + break; + case GNUTLS_MAC_SHA512: + ctx->update = (update_func) x86_hmac_sha512_update; + ctx->digest = (digest_func) x86_hmac_sha512_digest; + ctx->setkey = (set_key_func) x86_hmac_sha512_set_key; + ctx->ctx_ptr = &ctx->ctx.sha512; + ctx->length = SHA512_DIGEST_SIZE; + break; + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + return 0; +} + + +static int wrap_x86_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx) +{ + struct x86_hmac_ctx *ctx; + int ret; + + ctx = gnutls_calloc(1, sizeof(struct x86_hmac_ctx)); + if (ctx == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + ctx->algo = algo; + + ret = _hmac_ctx_init(algo, ctx); + if (ret < 0) + return gnutls_assert_val(ret); + + *_ctx = ctx; + + return 0; +} + +static void * +wrap_x86_hmac_copy(const void *_ctx) +{ + struct x86_hmac_ctx *new_ctx; + const struct x86_hmac_ctx *ctx=_ctx; + ptrdiff_t off = (uint8_t *)ctx->ctx_ptr - (uint8_t *)(&ctx->ctx); + + new_ctx = gnutls_malloc(sizeof(struct x86_hmac_ctx)); + if (new_ctx == NULL) { + gnutls_assert(); + return NULL; + } + + memcpy(new_ctx, ctx, sizeof(*new_ctx)); + new_ctx->ctx_ptr = (uint8_t *)&new_ctx->ctx + off; + + return new_ctx; +} + +static int +wrap_x86_hmac_setkey(void *_ctx, const void *key, size_t keylen) +{ + struct x86_hmac_ctx *ctx = _ctx; + + ctx->setkey(ctx->ctx_ptr, keylen, key); + + return GNUTLS_E_SUCCESS; +} + +static int +wrap_x86_hmac_update(void *_ctx, const void *text, size_t textsize) +{ + struct x86_hmac_ctx *ctx = _ctx; + + ctx->update(ctx->ctx_ptr, textsize, text); + + return GNUTLS_E_SUCCESS; +} + +static int +wrap_x86_hmac_output(void *src_ctx, void *digest, size_t digestsize) +{ + struct x86_hmac_ctx *ctx; + ctx = src_ctx; + + if (digestsize < ctx->length) { + gnutls_assert(); + return GNUTLS_E_SHORT_MEMORY_BUFFER; + } + + ctx->digest(ctx->ctx_ptr, digestsize, digest); + + return 0; +} + +static void wrap_x86_hmac_deinit(void *hd) +{ + struct x86_hmac_ctx *ctx = hd; + + zeroize_temp_key(ctx, sizeof(*ctx)); + gnutls_free(ctx); +} + +static int wrap_x86_hmac_fast(gnutls_mac_algorithm_t algo, + const void *nonce, size_t nonce_size, + const void *key, size_t key_size, + const void *text, size_t text_size, + void *digest) +{ + struct x86_hmac_ctx ctx; + int ret; + + ret = _hmac_ctx_init(algo, &ctx); + if (ret < 0) + return gnutls_assert_val(ret); + + ctx.setkey(&ctx, key_size, key); + ctx.update(&ctx, text_size, text); + ctx.digest(&ctx, ctx.length, digest); + + zeroize_temp_key(&ctx, sizeof(ctx)); + + return 0; +} + +const gnutls_crypto_mac_st _gnutls_hmac_sha_x86_ssse3 = { + .init = wrap_x86_hmac_init, + .setkey = wrap_x86_hmac_setkey, + .setnonce = NULL, + .hash = wrap_x86_hmac_update, + .output = wrap_x86_hmac_output, + .copy = wrap_x86_hmac_copy, + .deinit = wrap_x86_hmac_deinit, + .fast = wrap_x86_hmac_fast, +}; + +#endif /* HAVE_LIBNETTLE */ |