Loading arch/powerpc/crypto/ghash.c +28 −53 Original line number Diff line number Diff line Loading @@ -12,17 +12,16 @@ */ #include "aesp8-ppc.h" #include <asm/simd.h> #include <asm/switch_to.h> #include <crypto/aes.h> #include <crypto/b128ops.h> #include <crypto/gf128mul.h> #include <crypto/ghash.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/scatterwalk.h> #include <linux/err.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/string.h> #include <linux/uaccess.h> void gcm_init_p8(u128 htable[16], const u64 Xi[2]); Loading @@ -39,15 +38,12 @@ struct p8_ghash_ctx { struct p8_ghash_desc_ctx { u64 shash[2]; u8 buffer[GHASH_DIGEST_SIZE]; int bytes; }; static int p8_ghash_init(struct shash_desc *desc) { struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc); dctx->bytes = 0; memset(dctx->shash, 0, GHASH_DIGEST_SIZE); return 0; } Loading @@ -74,27 +70,30 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key, } static inline void __ghash_block(struct p8_ghash_ctx *ctx, struct p8_ghash_desc_ctx *dctx) struct p8_ghash_desc_ctx *dctx, const u8 *src) { if (crypto_simd_usable()) { preempt_disable(); pagefault_disable(); enable_kernel_vsx(); gcm_ghash_p8(dctx->shash, ctx->htable, dctx->buffer, GHASH_DIGEST_SIZE); gcm_ghash_p8(dctx->shash, ctx->htable, src, GHASH_BLOCK_SIZE); disable_kernel_vsx(); pagefault_enable(); preempt_enable(); } else { crypto_xor((u8 *)dctx->shash, dctx->buffer, GHASH_BLOCK_SIZE); crypto_xor((u8 *)dctx->shash, src, GHASH_BLOCK_SIZE); gf128mul_lle((be128 *)dctx->shash, &ctx->key); } } static inline void __ghash_blocks(struct p8_ghash_ctx *ctx, static inline int __ghash_blocks(struct p8_ghash_ctx *ctx, struct p8_ghash_desc_ctx *dctx, const u8 *src, unsigned int srclen) { int remain = srclen - round_down(srclen, GHASH_BLOCK_SIZE); srclen -= remain; if (crypto_simd_usable()) { preempt_disable(); pagefault_disable(); Loading @@ -105,62 +104,38 @@ static inline void __ghash_blocks(struct p8_ghash_ctx *ctx, pagefault_enable(); preempt_enable(); } else { while (srclen >= GHASH_BLOCK_SIZE) { do { crypto_xor((u8 *)dctx->shash, src, GHASH_BLOCK_SIZE); gf128mul_lle((be128 *)dctx->shash, &ctx->key); srclen -= GHASH_BLOCK_SIZE; src += GHASH_BLOCK_SIZE; } while (srclen); } } return remain; } static int p8_ghash_update(struct shash_desc *desc, const u8 *src, unsigned int srclen) { unsigned int len; struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm)); struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc); if (dctx->bytes) { if (dctx->bytes + srclen < GHASH_DIGEST_SIZE) { memcpy(dctx->buffer + dctx->bytes, src, srclen); dctx->bytes += srclen; return 0; return __ghash_blocks(ctx, dctx, src, srclen); } memcpy(dctx->buffer + dctx->bytes, src, GHASH_DIGEST_SIZE - dctx->bytes); __ghash_block(ctx, dctx); src += GHASH_DIGEST_SIZE - dctx->bytes; srclen -= GHASH_DIGEST_SIZE - dctx->bytes; dctx->bytes = 0; } len = srclen & ~(GHASH_DIGEST_SIZE - 1); if (len) { __ghash_blocks(ctx, dctx, src, len); src += len; srclen -= len; } if (srclen) { memcpy(dctx->buffer, src, srclen); dctx->bytes = srclen; } return 0; } static int p8_ghash_final(struct shash_desc *desc, u8 *out) static int p8_ghash_finup(struct shash_desc *desc, const u8 *src, unsigned int len, u8 *out) { int i; struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm)); struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc); if (dctx->bytes) { for (i = dctx->bytes; i < GHASH_DIGEST_SIZE; i++) dctx->buffer[i] = 0; __ghash_block(ctx, dctx); dctx->bytes = 0; if (len) { u8 buf[GHASH_BLOCK_SIZE] = {}; memcpy(buf, src, len); __ghash_block(ctx, dctx, buf); memzero_explicit(buf, sizeof(buf)); } memcpy(out, dctx->shash, GHASH_DIGEST_SIZE); return 0; Loading @@ -170,14 +145,14 @@ struct shash_alg p8_ghash_alg = { .digestsize = GHASH_DIGEST_SIZE, .init = p8_ghash_init, .update = p8_ghash_update, .final = p8_ghash_final, .finup = p8_ghash_finup, .setkey = p8_ghash_setkey, .descsize = sizeof(struct p8_ghash_desc_ctx) + sizeof(struct ghash_desc_ctx), .descsize = sizeof(struct p8_ghash_desc_ctx), .base = { .cra_name = "ghash", .cra_driver_name = "p8_ghash", .cra_priority = 1000, .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, .cra_blocksize = GHASH_BLOCK_SIZE, .cra_ctxsize = sizeof(struct p8_ghash_ctx), .cra_module = THIS_MODULE, Loading Loading
arch/powerpc/crypto/ghash.c +28 −53 Original line number Diff line number Diff line Loading @@ -12,17 +12,16 @@ */ #include "aesp8-ppc.h" #include <asm/simd.h> #include <asm/switch_to.h> #include <crypto/aes.h> #include <crypto/b128ops.h> #include <crypto/gf128mul.h> #include <crypto/ghash.h> #include <crypto/internal/hash.h> #include <crypto/internal/simd.h> #include <crypto/scatterwalk.h> #include <linux/err.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/string.h> #include <linux/uaccess.h> void gcm_init_p8(u128 htable[16], const u64 Xi[2]); Loading @@ -39,15 +38,12 @@ struct p8_ghash_ctx { struct p8_ghash_desc_ctx { u64 shash[2]; u8 buffer[GHASH_DIGEST_SIZE]; int bytes; }; static int p8_ghash_init(struct shash_desc *desc) { struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc); dctx->bytes = 0; memset(dctx->shash, 0, GHASH_DIGEST_SIZE); return 0; } Loading @@ -74,27 +70,30 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key, } static inline void __ghash_block(struct p8_ghash_ctx *ctx, struct p8_ghash_desc_ctx *dctx) struct p8_ghash_desc_ctx *dctx, const u8 *src) { if (crypto_simd_usable()) { preempt_disable(); pagefault_disable(); enable_kernel_vsx(); gcm_ghash_p8(dctx->shash, ctx->htable, dctx->buffer, GHASH_DIGEST_SIZE); gcm_ghash_p8(dctx->shash, ctx->htable, src, GHASH_BLOCK_SIZE); disable_kernel_vsx(); pagefault_enable(); preempt_enable(); } else { crypto_xor((u8 *)dctx->shash, dctx->buffer, GHASH_BLOCK_SIZE); crypto_xor((u8 *)dctx->shash, src, GHASH_BLOCK_SIZE); gf128mul_lle((be128 *)dctx->shash, &ctx->key); } } static inline void __ghash_blocks(struct p8_ghash_ctx *ctx, static inline int __ghash_blocks(struct p8_ghash_ctx *ctx, struct p8_ghash_desc_ctx *dctx, const u8 *src, unsigned int srclen) { int remain = srclen - round_down(srclen, GHASH_BLOCK_SIZE); srclen -= remain; if (crypto_simd_usable()) { preempt_disable(); pagefault_disable(); Loading @@ -105,62 +104,38 @@ static inline void __ghash_blocks(struct p8_ghash_ctx *ctx, pagefault_enable(); preempt_enable(); } else { while (srclen >= GHASH_BLOCK_SIZE) { do { crypto_xor((u8 *)dctx->shash, src, GHASH_BLOCK_SIZE); gf128mul_lle((be128 *)dctx->shash, &ctx->key); srclen -= GHASH_BLOCK_SIZE; src += GHASH_BLOCK_SIZE; } while (srclen); } } return remain; } static int p8_ghash_update(struct shash_desc *desc, const u8 *src, unsigned int srclen) { unsigned int len; struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm)); struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc); if (dctx->bytes) { if (dctx->bytes + srclen < GHASH_DIGEST_SIZE) { memcpy(dctx->buffer + dctx->bytes, src, srclen); dctx->bytes += srclen; return 0; return __ghash_blocks(ctx, dctx, src, srclen); } memcpy(dctx->buffer + dctx->bytes, src, GHASH_DIGEST_SIZE - dctx->bytes); __ghash_block(ctx, dctx); src += GHASH_DIGEST_SIZE - dctx->bytes; srclen -= GHASH_DIGEST_SIZE - dctx->bytes; dctx->bytes = 0; } len = srclen & ~(GHASH_DIGEST_SIZE - 1); if (len) { __ghash_blocks(ctx, dctx, src, len); src += len; srclen -= len; } if (srclen) { memcpy(dctx->buffer, src, srclen); dctx->bytes = srclen; } return 0; } static int p8_ghash_final(struct shash_desc *desc, u8 *out) static int p8_ghash_finup(struct shash_desc *desc, const u8 *src, unsigned int len, u8 *out) { int i; struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm)); struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc); if (dctx->bytes) { for (i = dctx->bytes; i < GHASH_DIGEST_SIZE; i++) dctx->buffer[i] = 0; __ghash_block(ctx, dctx); dctx->bytes = 0; if (len) { u8 buf[GHASH_BLOCK_SIZE] = {}; memcpy(buf, src, len); __ghash_block(ctx, dctx, buf); memzero_explicit(buf, sizeof(buf)); } memcpy(out, dctx->shash, GHASH_DIGEST_SIZE); return 0; Loading @@ -170,14 +145,14 @@ struct shash_alg p8_ghash_alg = { .digestsize = GHASH_DIGEST_SIZE, .init = p8_ghash_init, .update = p8_ghash_update, .final = p8_ghash_final, .finup = p8_ghash_finup, .setkey = p8_ghash_setkey, .descsize = sizeof(struct p8_ghash_desc_ctx) + sizeof(struct ghash_desc_ctx), .descsize = sizeof(struct p8_ghash_desc_ctx), .base = { .cra_name = "ghash", .cra_driver_name = "p8_ghash", .cra_priority = 1000, .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, .cra_blocksize = GHASH_BLOCK_SIZE, .cra_ctxsize = sizeof(struct p8_ghash_ctx), .cra_module = THIS_MODULE, Loading