1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * POLYVAL: hash function for HCTR2. 4 * 5 * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1@iki.fi> 6 * Copyright (c) 2009 Intel Corp. 7 * Author: Huang Ying <ying.huang@intel.com> 8 * Copyright 2021 Google LLC 9 */ 10 11 /* 12 * Code based on crypto/ghash-generic.c 13 * 14 * POLYVAL is a keyed hash function similar to GHASH. POLYVAL uses a different 15 * modulus for finite field multiplication which makes hardware accelerated 16 * implementations on little-endian machines faster. POLYVAL is used in the 17 * kernel to implement HCTR2, but was originally specified for AES-GCM-SIV 18 * (RFC 8452). 19 * 20 * For more information see: 21 * Length-preserving encryption with HCTR2: 22 * https://eprint.iacr.org/2021/1441.pdf 23 * AES-GCM-SIV: Nonce Misuse-Resistant Authenticated Encryption: 24 * https://datatracker.ietf.org/doc/html/rfc8452 25 * 26 * Like GHASH, POLYVAL is not a cryptographic hash function and should 27 * not be used outside of crypto modes explicitly designed to use POLYVAL. 28 * 29 * This implementation uses a convenient trick involving the GHASH and POLYVAL 30 * fields. This trick allows multiplication in the POLYVAL field to be 31 * implemented by using multiplication in the GHASH field as a subroutine. An 32 * element of the POLYVAL field can be converted to an element of the GHASH 33 * field by computing x*REVERSE(a), where REVERSE reverses the byte-ordering of 34 * a. Similarly, an element of the GHASH field can be converted back to the 35 * POLYVAL field by computing REVERSE(x^{-1}*a). For more information, see: 36 * https://datatracker.ietf.org/doc/html/rfc8452#appendix-A 37 * 38 * By using this trick, we do not need to implement the POLYVAL field for the 39 * generic implementation. 40 * 41 * Warning: this generic implementation is not intended to be used in practice 42 * and is not constant time. For practical use, a hardware accelerated 43 * implementation of POLYVAL should be used instead. 44 * 45 */ 46 47 #include <crypto/gf128mul.h> 48 #include <crypto/internal/hash.h> 49 #include <crypto/polyval.h> 50 #include <crypto/utils.h> 51 #include <linux/errno.h> 52 #include <linux/kernel.h> 53 #include <linux/module.h> 54 #include <linux/string.h> 55 #include <linux/unaligned.h> 56 57 struct polyval_tfm_ctx { 58 struct gf128mul_4k *gf128; 59 }; 60 61 struct polyval_desc_ctx { 62 union { 63 u8 buffer[POLYVAL_BLOCK_SIZE]; 64 be128 buffer128; 65 }; 66 }; 67 68 static void copy_and_reverse(u8 dst[POLYVAL_BLOCK_SIZE], 69 const u8 src[POLYVAL_BLOCK_SIZE]) 70 { 71 u64 a = get_unaligned((const u64 *)&src[0]); 72 u64 b = get_unaligned((const u64 *)&src[8]); 73 74 put_unaligned(swab64(a), (u64 *)&dst[8]); 75 put_unaligned(swab64(b), (u64 *)&dst[0]); 76 } 77 78 static int polyval_setkey(struct crypto_shash *tfm, 79 const u8 *key, unsigned int keylen) 80 { 81 struct polyval_tfm_ctx *ctx = crypto_shash_ctx(tfm); 82 be128 k; 83 84 if (keylen != POLYVAL_BLOCK_SIZE) 85 return -EINVAL; 86 87 gf128mul_free_4k(ctx->gf128); 88 89 BUILD_BUG_ON(sizeof(k) != POLYVAL_BLOCK_SIZE); 90 copy_and_reverse((u8 *)&k, key); 91 gf128mul_x_lle(&k, &k); 92 93 ctx->gf128 = gf128mul_init_4k_lle(&k); 94 memzero_explicit(&k, POLYVAL_BLOCK_SIZE); 95 96 if (!ctx->gf128) 97 return -ENOMEM; 98 99 return 0; 100 } 101 102 static int polyval_init(struct shash_desc *desc) 103 { 104 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 105 106 memset(dctx, 0, sizeof(*dctx)); 107 108 return 0; 109 } 110 111 static int polyval_update(struct shash_desc *desc, 112 const u8 *src, unsigned int srclen) 113 { 114 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 115 const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm); 116 u8 tmp[POLYVAL_BLOCK_SIZE]; 117 118 do { 119 copy_and_reverse(tmp, src); 120 crypto_xor(dctx->buffer, tmp, POLYVAL_BLOCK_SIZE); 121 gf128mul_4k_lle(&dctx->buffer128, ctx->gf128); 122 src += POLYVAL_BLOCK_SIZE; 123 srclen -= POLYVAL_BLOCK_SIZE; 124 } while (srclen >= POLYVAL_BLOCK_SIZE); 125 126 return srclen; 127 } 128 129 static int polyval_finup(struct shash_desc *desc, const u8 *src, 130 unsigned int len, u8 *dst) 131 { 132 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 133 134 if (len) { 135 u8 tmp[POLYVAL_BLOCK_SIZE] = {}; 136 137 memcpy(tmp, src, len); 138 polyval_update(desc, tmp, POLYVAL_BLOCK_SIZE); 139 } 140 copy_and_reverse(dst, dctx->buffer); 141 return 0; 142 } 143 144 static int polyval_export(struct shash_desc *desc, void *out) 145 { 146 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 147 148 copy_and_reverse(out, dctx->buffer); 149 return 0; 150 } 151 152 static int polyval_import(struct shash_desc *desc, const void *in) 153 { 154 struct polyval_desc_ctx *dctx = shash_desc_ctx(desc); 155 156 copy_and_reverse(dctx->buffer, in); 157 return 0; 158 } 159 160 static void polyval_exit_tfm(struct crypto_shash *tfm) 161 { 162 struct polyval_tfm_ctx *ctx = crypto_shash_ctx(tfm); 163 164 gf128mul_free_4k(ctx->gf128); 165 } 166 167 static struct shash_alg polyval_alg = { 168 .digestsize = POLYVAL_DIGEST_SIZE, 169 .init = polyval_init, 170 .update = polyval_update, 171 .finup = polyval_finup, 172 .setkey = polyval_setkey, 173 .export = polyval_export, 174 .import = polyval_import, 175 .exit_tfm = polyval_exit_tfm, 176 .statesize = sizeof(struct polyval_desc_ctx), 177 .descsize = sizeof(struct polyval_desc_ctx), 178 .base = { 179 .cra_name = "polyval", 180 .cra_driver_name = "polyval-generic", 181 .cra_priority = 100, 182 .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 183 .cra_blocksize = POLYVAL_BLOCK_SIZE, 184 .cra_ctxsize = sizeof(struct polyval_tfm_ctx), 185 .cra_module = THIS_MODULE, 186 }, 187 }; 188 189 static int __init polyval_mod_init(void) 190 { 191 return crypto_register_shash(&polyval_alg); 192 } 193 194 static void __exit polyval_mod_exit(void) 195 { 196 crypto_unregister_shash(&polyval_alg); 197 } 198 199 module_init(polyval_mod_init); 200 module_exit(polyval_mod_exit); 201 202 MODULE_LICENSE("GPL"); 203 MODULE_DESCRIPTION("POLYVAL hash function"); 204 MODULE_ALIAS_CRYPTO("polyval"); 205 MODULE_ALIAS_CRYPTO("polyval-generic"); 206