Skip to content

Commit

Permalink
crypto: aegis128 - wipe plaintext and tag if decryption fails
Browse files Browse the repository at this point in the history
The AEGIS spec mentions explicitly that the security guarantees hold
only if the resulting plaintext and tag of a failed decryption are
withheld. So ensure that we abide by this.

While at it, drop the unused struct aead_request *req parameter from
crypto_aegis128_process_crypt().

Reviewed-by: Ondrej Mosnacek <[email protected]>
Signed-off-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
ardbiesheuvel authored and herbertx committed Nov 27, 2020
1 parent 732b764 commit 0268590
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions crypto/aegis128-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ static void crypto_aegis128_ad(struct aegis_state *state,
}
}

static void crypto_aegis128_wipe_chunk(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size)
{
memzero_explicit(dst, size);
}

static void crypto_aegis128_encrypt_chunk(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size)
{
Expand Down Expand Up @@ -324,7 +330,6 @@ static void crypto_aegis128_process_ad(struct aegis_state *state,

static __always_inline
int crypto_aegis128_process_crypt(struct aegis_state *state,
struct aead_request *req,
struct skcipher_walk *walk,
void (*crypt)(struct aegis_state *state,
u8 *dst, const u8 *src,
Expand Down Expand Up @@ -403,14 +408,14 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
if (aegis128_do_simd()) {
crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
crypto_aegis128_process_crypt(&state, req, &walk,
crypto_aegis128_process_crypt(&state, &walk,
crypto_aegis128_encrypt_chunk_simd);
crypto_aegis128_final_simd(&state, &tag, req->assoclen,
cryptlen);
} else {
crypto_aegis128_init(&state, &ctx->key, req->iv);
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
crypto_aegis128_process_crypt(&state, req, &walk,
crypto_aegis128_process_crypt(&state, &walk,
crypto_aegis128_encrypt_chunk);
crypto_aegis128_final(&state, &tag, req->assoclen, cryptlen);
}
Expand Down Expand Up @@ -438,19 +443,34 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
if (aegis128_do_simd()) {
crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
crypto_aegis128_process_crypt(&state, req, &walk,
crypto_aegis128_process_crypt(&state, &walk,
crypto_aegis128_decrypt_chunk_simd);
crypto_aegis128_final_simd(&state, &tag, req->assoclen,
cryptlen);
} else {
crypto_aegis128_init(&state, &ctx->key, req->iv);
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
crypto_aegis128_process_crypt(&state, req, &walk,
crypto_aegis128_process_crypt(&state, &walk,
crypto_aegis128_decrypt_chunk);
crypto_aegis128_final(&state, &tag, req->assoclen, cryptlen);
}

return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0;
if (unlikely(crypto_memneq(tag.bytes, zeros, authsize))) {
/*
* From Chapter 4. 'Security Analysis' of the AEGIS spec [0]
*
* "3. If verification fails, the decrypted plaintext and the
* wrong authentication tag should not be given as output."
*
* [0] https://competitions.cr.yp.to/round3/aegisv11.pdf
*/
skcipher_walk_aead_decrypt(&walk, req, false);
crypto_aegis128_process_crypt(NULL, &walk,
crypto_aegis128_wipe_chunk);
memzero_explicit(&tag, sizeof(tag));
return -EBADMSG;
}
return 0;
}

static struct aead_alg crypto_aegis128_alg = {
Expand Down

0 comments on commit 0268590

Please sign in to comment.