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: x86/aegis - Add missing error checks

The skcipher_walk functions can allocate memory and can fail, so
checking for errors is necessary.

Fixes: 1d373d4e8e15 ("crypto: x86 - Add optimized AEGIS implementations")
Cc: stable@vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Eric Biggers and committed by
Herbert Xu
3d9eb180 c7f49dad

+25 -11
+25 -11
arch/x86/crypto/aegis128-aesni-glue.c
··· 104 104 } 105 105 } 106 106 107 - static __always_inline void 107 + static __always_inline int 108 108 crypto_aegis128_aesni_process_crypt(struct aegis_state *state, 109 109 struct skcipher_walk *walk, bool enc) 110 110 { 111 + int err = 0; 112 + 111 113 while (walk->nbytes >= AEGIS128_BLOCK_SIZE) { 112 114 if (enc) 113 115 aegis128_aesni_enc(state, walk->src.virt.addr, ··· 122 120 round_down(walk->nbytes, 123 121 AEGIS128_BLOCK_SIZE)); 124 122 kernel_fpu_end(); 125 - skcipher_walk_done(walk, walk->nbytes % AEGIS128_BLOCK_SIZE); 123 + err = skcipher_walk_done(walk, 124 + walk->nbytes % AEGIS128_BLOCK_SIZE); 126 125 kernel_fpu_begin(); 127 126 } 128 127 ··· 137 134 walk->dst.virt.addr, 138 135 walk->nbytes); 139 136 kernel_fpu_end(); 140 - skcipher_walk_done(walk, 0); 137 + err = skcipher_walk_done(walk, 0); 141 138 kernel_fpu_begin(); 142 139 } 140 + return err; 143 141 } 144 142 145 143 static struct aegis_ctx *crypto_aegis128_aesni_ctx(struct crypto_aead *aead) ··· 173 169 return 0; 174 170 } 175 171 176 - static __always_inline void 172 + static __always_inline int 177 173 crypto_aegis128_aesni_crypt(struct aead_request *req, 178 174 struct aegis_block *tag_xor, 179 175 unsigned int cryptlen, bool enc) ··· 182 178 struct aegis_ctx *ctx = crypto_aegis128_aesni_ctx(tfm); 183 179 struct skcipher_walk walk; 184 180 struct aegis_state state; 181 + int err; 185 182 186 183 if (enc) 187 - skcipher_walk_aead_encrypt(&walk, req, false); 184 + err = skcipher_walk_aead_encrypt(&walk, req, false); 188 185 else 189 - skcipher_walk_aead_decrypt(&walk, req, false); 186 + err = skcipher_walk_aead_decrypt(&walk, req, false); 187 + if (err) 188 + return err; 190 189 191 190 kernel_fpu_begin(); 192 191 193 192 aegis128_aesni_init(&state, &ctx->key, req->iv); 194 193 crypto_aegis128_aesni_process_ad(&state, req->src, req->assoclen); 195 - crypto_aegis128_aesni_process_crypt(&state, &walk, enc); 196 - aegis128_aesni_final(&state, tag_xor, req->assoclen, cryptlen); 197 - 194 + err = crypto_aegis128_aesni_process_crypt(&state, &walk, enc); 195 + if (err == 0) 196 + aegis128_aesni_final(&state, tag_xor, req->assoclen, cryptlen); 198 197 kernel_fpu_end(); 198 + return err; 199 199 } 200 200 201 201 static int crypto_aegis128_aesni_encrypt(struct aead_request *req) ··· 208 200 struct aegis_block tag = {}; 209 201 unsigned int authsize = crypto_aead_authsize(tfm); 210 202 unsigned int cryptlen = req->cryptlen; 203 + int err; 211 204 212 - crypto_aegis128_aesni_crypt(req, &tag, cryptlen, true); 205 + err = crypto_aegis128_aesni_crypt(req, &tag, cryptlen, true); 206 + if (err) 207 + return err; 213 208 214 209 scatterwalk_map_and_copy(tag.bytes, req->dst, 215 210 req->assoclen + cryptlen, authsize, 1); ··· 227 216 struct aegis_block tag; 228 217 unsigned int authsize = crypto_aead_authsize(tfm); 229 218 unsigned int cryptlen = req->cryptlen - authsize; 219 + int err; 230 220 231 221 scatterwalk_map_and_copy(tag.bytes, req->src, 232 222 req->assoclen + cryptlen, authsize, 0); 233 223 234 - crypto_aegis128_aesni_crypt(req, &tag, cryptlen, false); 224 + err = crypto_aegis128_aesni_crypt(req, &tag, cryptlen, false); 225 + if (err) 226 + return err; 235 227 236 228 return crypto_memneq(tag.bytes, zeros.bytes, authsize) ? -EBADMSG : 0; 237 229 }