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

Configure Feed

Select the types of activity you want to include in your feed.

crypto: polyval-generic - Use API partial block handling

Use the Crypto API partial block handling.

The accelerated export format on x86/arm64 is easier to use so
switch the generic polyval algorithm to use that format instead.

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

+40 -88
+40 -80
crypto/polyval-generic.c
··· 44 44 * 45 45 */ 46 46 47 - #include <linux/unaligned.h> 48 - #include <crypto/algapi.h> 49 47 #include <crypto/gf128mul.h> 50 - #include <crypto/polyval.h> 51 48 #include <crypto/internal/hash.h> 52 - #include <linux/crypto.h> 53 - #include <linux/init.h> 49 + #include <crypto/polyval.h> 50 + #include <crypto/utils.h> 51 + #include <linux/errno.h> 54 52 #include <linux/kernel.h> 55 53 #include <linux/module.h> 54 + #include <linux/string.h> 55 + #include <linux/unaligned.h> 56 56 57 57 struct polyval_tfm_ctx { 58 58 struct gf128mul_4k *gf128; ··· 63 63 u8 buffer[POLYVAL_BLOCK_SIZE]; 64 64 be128 buffer128; 65 65 }; 66 - u32 bytes; 67 66 }; 68 67 69 68 static void copy_and_reverse(u8 dst[POLYVAL_BLOCK_SIZE], ··· 74 75 put_unaligned(swab64(a), (u64 *)&dst[8]); 75 76 put_unaligned(swab64(b), (u64 *)&dst[0]); 76 77 } 77 - 78 - /* 79 - * Performs multiplication in the POLYVAL field using the GHASH field as a 80 - * subroutine. This function is used as a fallback for hardware accelerated 81 - * implementations when simd registers are unavailable. 82 - * 83 - * Note: This function is not used for polyval-generic, instead we use the 4k 84 - * lookup table implementation for finite field multiplication. 85 - */ 86 - void polyval_mul_non4k(u8 *op1, const u8 *op2) 87 - { 88 - be128 a, b; 89 - 90 - // Assume one argument is in Montgomery form and one is not. 91 - copy_and_reverse((u8 *)&a, op1); 92 - copy_and_reverse((u8 *)&b, op2); 93 - gf128mul_x_lle(&a, &a); 94 - gf128mul_lle(&a, &b); 95 - copy_and_reverse(op1, (u8 *)&a); 96 - } 97 - EXPORT_SYMBOL_GPL(polyval_mul_non4k); 98 - 99 - /* 100 - * Perform a POLYVAL update using non4k multiplication. This function is used 101 - * as a fallback for hardware accelerated implementations when simd registers 102 - * are unavailable. 103 - * 104 - * Note: This function is not used for polyval-generic, instead we use the 4k 105 - * lookup table implementation of finite field multiplication. 106 - */ 107 - void polyval_update_non4k(const u8 *key, const u8 *in, 108 - size_t nblocks, u8 *accumulator) 109 - { 110 - while (nblocks--) { 111 - crypto_xor(accumulator, in, POLYVAL_BLOCK_SIZE); 112 - polyval_mul_non4k(accumulator, key); 113 - in += POLYVAL_BLOCK_SIZE; 114 - } 115 - } 116 - EXPORT_SYMBOL_GPL(polyval_update_non4k); 117 78 118 79 static int polyval_setkey(struct crypto_shash *tfm, 119 80 const u8 *key, unsigned int keylen) ··· 113 154 { 114 155 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 115 156 const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm); 116 - u8 *pos; 117 157 u8 tmp[POLYVAL_BLOCK_SIZE]; 118 - int n; 119 158 120 - if (dctx->bytes) { 121 - n = min(srclen, dctx->bytes); 122 - pos = dctx->buffer + dctx->bytes - 1; 123 - 124 - dctx->bytes -= n; 125 - srclen -= n; 126 - 127 - while (n--) 128 - *pos-- ^= *src++; 129 - 130 - if (!dctx->bytes) 131 - gf128mul_4k_lle(&dctx->buffer128, ctx->gf128); 132 - } 133 - 134 - while (srclen >= POLYVAL_BLOCK_SIZE) { 159 + do { 135 160 copy_and_reverse(tmp, src); 136 161 crypto_xor(dctx->buffer, tmp, POLYVAL_BLOCK_SIZE); 137 162 gf128mul_4k_lle(&dctx->buffer128, ctx->gf128); 138 163 src += POLYVAL_BLOCK_SIZE; 139 164 srclen -= POLYVAL_BLOCK_SIZE; 140 - } 165 + } while (srclen >= POLYVAL_BLOCK_SIZE); 141 166 142 - if (srclen) { 143 - dctx->bytes = POLYVAL_BLOCK_SIZE - srclen; 144 - pos = dctx->buffer + POLYVAL_BLOCK_SIZE - 1; 145 - while (srclen--) 146 - *pos-- ^= *src++; 147 - } 148 - 149 - return 0; 167 + return srclen; 150 168 } 151 169 152 - static int polyval_final(struct shash_desc *desc, u8 *dst) 170 + static int polyval_finup(struct shash_desc *desc, const u8 *src, 171 + unsigned int len, u8 *dst) 153 172 { 154 173 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 155 - const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm); 156 174 157 - if (dctx->bytes) 158 - gf128mul_4k_lle(&dctx->buffer128, ctx->gf128); 175 + if (len) { 176 + u8 tmp[POLYVAL_BLOCK_SIZE] = {}; 177 + 178 + memcpy(tmp, src, len); 179 + polyval_update(desc, tmp, POLYVAL_BLOCK_SIZE); 180 + } 159 181 copy_and_reverse(dst, dctx->buffer); 160 182 return 0; 161 183 } 162 184 163 - static void polyval_exit_tfm(struct crypto_tfm *tfm) 185 + static int polyval_export(struct shash_desc *desc, void *out) 164 186 { 165 - struct polyval_tfm_ctx *ctx = crypto_tfm_ctx(tfm); 187 + struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 188 + 189 + copy_and_reverse(out, dctx->buffer); 190 + return 0; 191 + } 192 + 193 + static int polyval_import(struct shash_desc *desc, const void *in) 194 + { 195 + struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 196 + 197 + copy_and_reverse(dctx->buffer, in); 198 + return 0; 199 + } 200 + 201 + static void polyval_exit_tfm(struct crypto_shash *tfm) 202 + { 203 + struct polyval_tfm_ctx *ctx = crypto_shash_ctx(tfm); 166 204 167 205 gf128mul_free_4k(ctx->gf128); 168 206 } ··· 168 212 .digestsize = POLYVAL_DIGEST_SIZE, 169 213 .init = polyval_init, 170 214 .update = polyval_update, 171 - .final = polyval_final, 215 + .finup = polyval_finup, 172 216 .setkey = polyval_setkey, 217 + .export = polyval_export, 218 + .import = polyval_import, 219 + .exit_tfm = polyval_exit_tfm, 220 + .statesize = sizeof(struct polyval_desc_ctx), 173 221 .descsize = sizeof(struct polyval_desc_ctx), 174 222 .base = { 175 223 .cra_name = "polyval", 176 224 .cra_driver_name = "polyval-generic", 177 225 .cra_priority = 100, 226 + .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 178 227 .cra_blocksize = POLYVAL_BLOCK_SIZE, 179 228 .cra_ctxsize = sizeof(struct polyval_tfm_ctx), 180 229 .cra_module = THIS_MODULE, 181 - .cra_exit = polyval_exit_tfm, 182 230 }, 183 231 }; 184 232
-8
include/crypto/polyval.h
··· 8 8 #ifndef _CRYPTO_POLYVAL_H 9 9 #define _CRYPTO_POLYVAL_H 10 10 11 - #include <linux/types.h> 12 - #include <linux/crypto.h> 13 - 14 11 #define POLYVAL_BLOCK_SIZE 16 15 12 #define POLYVAL_DIGEST_SIZE 16 16 - 17 - void polyval_mul_non4k(u8 *op1, const u8 *op2); 18 - 19 - void polyval_update_non4k(const u8 *key, const u8 *in, 20 - size_t nblocks, u8 *accumulator); 21 13 22 14 #endif