Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: s390/ghash - Use API partial block handling

Use the Crypto API partial block handling.

Also switch to the generic export format.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Herbert Xu dab2d7b6 867a2177

+50 -60
+50 -60
arch/s390/crypto/ghash_s390.c
··· 8 8 * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com> 9 9 */ 10 10 11 - #include <crypto/internal/hash.h> 12 - #include <linux/module.h> 13 - #include <linux/cpufeature.h> 14 11 #include <asm/cpacf.h> 12 + #include <crypto/ghash.h> 13 + #include <crypto/internal/hash.h> 14 + #include <linux/cpufeature.h> 15 + #include <linux/err.h> 16 + #include <linux/kernel.h> 17 + #include <linux/module.h> 18 + #include <linux/string.h> 15 19 16 - #define GHASH_BLOCK_SIZE 16 17 - #define GHASH_DIGEST_SIZE 16 18 - 19 - struct ghash_ctx { 20 + struct s390_ghash_ctx { 20 21 u8 key[GHASH_BLOCK_SIZE]; 21 22 }; 22 23 23 - struct ghash_desc_ctx { 24 + struct s390_ghash_desc_ctx { 24 25 u8 icv[GHASH_BLOCK_SIZE]; 25 26 u8 key[GHASH_BLOCK_SIZE]; 26 - u8 buffer[GHASH_BLOCK_SIZE]; 27 - u32 bytes; 28 27 }; 29 28 30 29 static int ghash_init(struct shash_desc *desc) 31 30 { 32 - struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 33 - struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); 31 + struct s390_ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); 32 + struct s390_ghash_desc_ctx *dctx = shash_desc_ctx(desc); 34 33 35 34 memset(dctx, 0, sizeof(*dctx)); 36 35 memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE); ··· 40 41 static int ghash_setkey(struct crypto_shash *tfm, 41 42 const u8 *key, unsigned int keylen) 42 43 { 43 - struct ghash_ctx *ctx = crypto_shash_ctx(tfm); 44 + struct s390_ghash_ctx *ctx = crypto_shash_ctx(tfm); 44 45 45 46 if (keylen != GHASH_BLOCK_SIZE) 46 47 return -EINVAL; ··· 53 54 static int ghash_update(struct shash_desc *desc, 54 55 const u8 *src, unsigned int srclen) 55 56 { 56 - struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 57 + struct s390_ghash_desc_ctx *dctx = shash_desc_ctx(desc); 57 58 unsigned int n; 58 - u8 *buf = dctx->buffer; 59 - 60 - if (dctx->bytes) { 61 - u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes); 62 - 63 - n = min(srclen, dctx->bytes); 64 - dctx->bytes -= n; 65 - srclen -= n; 66 - 67 - memcpy(pos, src, n); 68 - src += n; 69 - 70 - if (!dctx->bytes) { 71 - cpacf_kimd(CPACF_KIMD_GHASH, dctx, buf, 72 - GHASH_BLOCK_SIZE); 73 - } 74 - } 75 59 76 60 n = srclen & ~(GHASH_BLOCK_SIZE - 1); 77 - if (n) { 78 - cpacf_kimd(CPACF_KIMD_GHASH, dctx, src, n); 79 - src += n; 80 - srclen -= n; 81 - } 82 - 83 - if (srclen) { 84 - dctx->bytes = GHASH_BLOCK_SIZE - srclen; 85 - memcpy(buf, src, srclen); 86 - } 87 - 88 - return 0; 61 + cpacf_kimd(CPACF_KIMD_GHASH, dctx, src, n); 62 + return srclen - n; 89 63 } 90 64 91 - static int ghash_flush(struct ghash_desc_ctx *dctx) 65 + static void ghash_flush(struct s390_ghash_desc_ctx *dctx, const u8 *src, 66 + unsigned int len) 92 67 { 93 - u8 *buf = dctx->buffer; 68 + if (len) { 69 + u8 buf[GHASH_BLOCK_SIZE] = {}; 94 70 95 - if (dctx->bytes) { 96 - u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes); 97 - 98 - memset(pos, 0, dctx->bytes); 71 + memcpy(buf, src, len); 99 72 cpacf_kimd(CPACF_KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE); 100 - dctx->bytes = 0; 73 + memzero_explicit(buf, sizeof(buf)); 101 74 } 75 + } 102 76 77 + static int ghash_finup(struct shash_desc *desc, const u8 *src, 78 + unsigned int len, u8 *dst) 79 + { 80 + struct s390_ghash_desc_ctx *dctx = shash_desc_ctx(desc); 81 + 82 + ghash_flush(dctx, src, len); 83 + memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE); 103 84 return 0; 104 85 } 105 86 106 - static int ghash_final(struct shash_desc *desc, u8 *dst) 87 + static int ghash_export(struct shash_desc *desc, void *out) 107 88 { 108 - struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 109 - int ret; 89 + struct s390_ghash_desc_ctx *dctx = shash_desc_ctx(desc); 110 90 111 - ret = ghash_flush(dctx); 112 - if (!ret) 113 - memcpy(dst, dctx->icv, GHASH_BLOCK_SIZE); 114 - return ret; 91 + memcpy(out, dctx->icv, GHASH_DIGEST_SIZE); 92 + return 0; 93 + } 94 + 95 + static int ghash_import(struct shash_desc *desc, const void *in) 96 + { 97 + struct s390_ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); 98 + struct s390_ghash_desc_ctx *dctx = shash_desc_ctx(desc); 99 + 100 + memcpy(dctx->icv, in, GHASH_DIGEST_SIZE); 101 + memcpy(dctx->key, ctx->key, GHASH_BLOCK_SIZE); 102 + return 0; 115 103 } 116 104 117 105 static struct shash_alg ghash_alg = { 118 106 .digestsize = GHASH_DIGEST_SIZE, 119 107 .init = ghash_init, 120 108 .update = ghash_update, 121 - .final = ghash_final, 109 + .finup = ghash_finup, 122 110 .setkey = ghash_setkey, 123 - .descsize = sizeof(struct ghash_desc_ctx), 111 + .export = ghash_export, 112 + .import = ghash_import, 113 + .statesize = sizeof(struct ghash_desc_ctx), 114 + .descsize = sizeof(struct s390_ghash_desc_ctx), 124 115 .base = { 125 116 .cra_name = "ghash", 126 117 .cra_driver_name = "ghash-s390", 127 118 .cra_priority = 300, 119 + .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 128 120 .cra_blocksize = GHASH_BLOCK_SIZE, 129 - .cra_ctxsize = sizeof(struct ghash_ctx), 121 + .cra_ctxsize = sizeof(struct s390_ghash_ctx), 130 122 .cra_module = THIS_MODULE, 131 123 }, 132 124 };