diff options
Diffstat (limited to 'module/icp/algs')
-rw-r--r-- | module/icp/algs/modes/cbc.c | 98 | ||||
-rw-r--r-- | module/icp/algs/modes/ccm.c | 38 | ||||
-rw-r--r-- | module/icp/algs/modes/ctr.c | 32 | ||||
-rw-r--r-- | module/icp/algs/modes/ecb.c | 37 | ||||
-rw-r--r-- | module/icp/algs/modes/gcm.c | 85 |
5 files changed, 96 insertions, 194 deletions
diff --git a/module/icp/algs/modes/cbc.c b/module/icp/algs/modes/cbc.c index 2cc94ec72..85864f56d 100644 --- a/module/icp/algs/modes/cbc.c +++ b/module/icp/algs/modes/cbc.c @@ -60,8 +60,7 @@ cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, } lastp = (uint8_t *)ctx->cbc_iv; - if (out != NULL) - crypto_init_ptrs(out, &iov_or_mp, &offset); + crypto_init_ptrs(out, &iov_or_mp, &offset); do { /* Unprocessed data from last call. */ @@ -79,47 +78,28 @@ cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, blockp = datap; } - if (out == NULL) { - /* - * XOR the previous cipher block or IV with the - * current clear block. - */ - xor_block(lastp, blockp); - encrypt(ctx->cbc_keysched, blockp, blockp); - - ctx->cbc_lastp = blockp; - lastp = blockp; - - if (ctx->cbc_remainder_len > 0) { - bcopy(blockp, ctx->cbc_copy_to, - ctx->cbc_remainder_len); - bcopy(blockp + ctx->cbc_remainder_len, datap, - need); - } + /* + * XOR the previous cipher block or IV with the + * current clear block. + */ + xor_block(blockp, lastp); + encrypt(ctx->cbc_keysched, lastp, lastp); + crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, + &out_data_1_len, &out_data_2, block_size); + + /* copy block to where it belongs */ + if (out_data_1_len == block_size) { + copy_block(lastp, out_data_1); } else { - /* - * XOR the previous cipher block or IV with the - * current clear block. - */ - xor_block(blockp, lastp); - encrypt(ctx->cbc_keysched, lastp, lastp); - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); - - /* copy block to where it belongs */ - if (out_data_1_len == block_size) { - copy_block(lastp, out_data_1); - } else { - bcopy(lastp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(lastp + out_data_1_len, - out_data_2, - block_size - out_data_1_len); - } + bcopy(lastp, out_data_1, out_data_1_len); + if (out_data_2 != NULL) { + bcopy(lastp + out_data_1_len, + out_data_2, + block_size - out_data_1_len); } - /* update offset */ - out->cd_offset += block_size; } + /* update offset */ + out->cd_offset += block_size; /* Update pointer to next block of data to be processed. */ if (ctx->cbc_remainder_len != 0) { @@ -187,8 +167,7 @@ cbc_decrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, } lastp = ctx->cbc_lastp; - if (out != NULL) - crypto_init_ptrs(out, &iov_or_mp, &offset); + crypto_init_ptrs(out, &iov_or_mp, &offset); do { /* Unprocessed data from last call. */ @@ -209,13 +188,9 @@ cbc_decrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, /* LINTED: pointer alignment */ copy_block(blockp, (uint8_t *)OTHER((uint64_t *)lastp, ctx)); - if (out != NULL) { - decrypt(ctx->cbc_keysched, blockp, - (uint8_t *)ctx->cbc_remainder); - blockp = (uint8_t *)ctx->cbc_remainder; - } else { - decrypt(ctx->cbc_keysched, blockp, blockp); - } + decrypt(ctx->cbc_keysched, blockp, + (uint8_t *)ctx->cbc_remainder); + blockp = (uint8_t *)ctx->cbc_remainder; /* * XOR the previous cipher block or IV with the @@ -226,25 +201,18 @@ cbc_decrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length, /* LINTED: pointer alignment */ lastp = (uint8_t *)OTHER((uint64_t *)lastp, ctx); - if (out != NULL) { - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); + crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, + &out_data_1_len, &out_data_2, block_size); - bcopy(blockp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(blockp + out_data_1_len, out_data_2, - block_size - out_data_1_len); - } - - /* update offset */ - out->cd_offset += block_size; - - } else if (ctx->cbc_remainder_len > 0) { - /* copy temporary block to where it belongs */ - bcopy(blockp, ctx->cbc_copy_to, ctx->cbc_remainder_len); - bcopy(blockp + ctx->cbc_remainder_len, datap, need); + bcopy(blockp, out_data_1, out_data_1_len); + if (out_data_2 != NULL) { + bcopy(blockp + out_data_1_len, out_data_2, + block_size - out_data_1_len); } + /* update offset */ + out->cd_offset += block_size; + /* Update pointer to next block of data to be processed. */ if (ctx->cbc_remainder_len != 0) { datap += need; diff --git a/module/icp/algs/modes/ccm.c b/module/icp/algs/modes/ccm.c index f4075f503..ad603a32a 100644 --- a/module/icp/algs/modes/ccm.c +++ b/module/icp/algs/modes/ccm.c @@ -68,8 +68,7 @@ ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length, } lastp = (uint8_t *)ctx->ccm_cb; - if (out != NULL) - crypto_init_ptrs(out, &iov_or_mp, &offset); + crypto_init_ptrs(out, &iov_or_mp, &offset); mac_buf = (uint8_t *)ctx->ccm_mac_buf; @@ -126,31 +125,22 @@ ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length, ctx->ccm_processed_data_len += block_size; - if (out == NULL) { - if (ctx->ccm_remainder_len > 0) { - bcopy(blockp, ctx->ccm_copy_to, - ctx->ccm_remainder_len); - bcopy(blockp + ctx->ccm_remainder_len, datap, - need); - } - } else { - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); + crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, + &out_data_1_len, &out_data_2, block_size); - /* copy block to where it belongs */ - if (out_data_1_len == block_size) { - copy_block(lastp, out_data_1); - } else { - bcopy(lastp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(lastp + out_data_1_len, - out_data_2, - block_size - out_data_1_len); - } + /* copy block to where it belongs */ + if (out_data_1_len == block_size) { + copy_block(lastp, out_data_1); + } else { + bcopy(lastp, out_data_1, out_data_1_len); + if (out_data_2 != NULL) { + bcopy(lastp + out_data_1_len, + out_data_2, + block_size - out_data_1_len); } - /* update offset */ - out->cd_offset += block_size; } + /* update offset */ + out->cd_offset += block_size; /* Update pointer to next block of data to be processed. */ if (ctx->ccm_remainder_len != 0) { diff --git a/module/icp/algs/modes/ctr.c b/module/icp/algs/modes/ctr.c index e3b0e1238..0188bdd39 100644 --- a/module/icp/algs/modes/ctr.c +++ b/module/icp/algs/modes/ctr.c @@ -61,8 +61,7 @@ ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length, } lastp = (uint8_t *)ctx->ctr_cb; - if (out != NULL) - crypto_init_ptrs(out, &iov_or_mp, &offset); + crypto_init_ptrs(out, &iov_or_mp, &offset); do { /* Unprocessed data from last call. */ @@ -111,26 +110,17 @@ ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length, */ xor_block(blockp, lastp); - if (out == NULL) { - if (ctx->ctr_remainder_len > 0) { - bcopy(lastp, ctx->ctr_copy_to, - ctx->ctr_remainder_len); - bcopy(lastp + ctx->ctr_remainder_len, datap, - need); - } - } else { - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); - - /* copy block to where it belongs */ - bcopy(lastp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(lastp + out_data_1_len, out_data_2, - block_size - out_data_1_len); - } - /* update offset */ - out->cd_offset += block_size; + crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, + &out_data_1_len, &out_data_2, block_size); + + /* copy block to where it belongs */ + bcopy(lastp, out_data_1, out_data_1_len); + if (out_data_2 != NULL) { + bcopy(lastp + out_data_1_len, out_data_2, + block_size - out_data_1_len); } + /* update offset */ + out->cd_offset += block_size; /* Update pointer to next block of data to be processed. */ if (ctx->ctr_remainder_len != 0) { diff --git a/module/icp/algs/modes/ecb.c b/module/icp/algs/modes/ecb.c index 04e6c5eaa..025f5825c 100644 --- a/module/icp/algs/modes/ecb.c +++ b/module/icp/algs/modes/ecb.c @@ -58,8 +58,7 @@ ecb_cipher_contiguous_blocks(ecb_ctx_t *ctx, char *data, size_t length, } lastp = (uint8_t *)ctx->ecb_iv; - if (out != NULL) - crypto_init_ptrs(out, &iov_or_mp, &offset); + crypto_init_ptrs(out, &iov_or_mp, &offset); do { /* Unprocessed data from last call. */ @@ -77,32 +76,18 @@ ecb_cipher_contiguous_blocks(ecb_ctx_t *ctx, char *data, size_t length, blockp = datap; } - if (out == NULL) { - cipher(ctx->ecb_keysched, blockp, blockp); + cipher(ctx->ecb_keysched, blockp, lastp); + crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, + &out_data_1_len, &out_data_2, block_size); - ctx->ecb_lastp = blockp; - lastp = blockp; - - if (ctx->ecb_remainder_len > 0) { - bcopy(blockp, ctx->ecb_copy_to, - ctx->ecb_remainder_len); - bcopy(blockp + ctx->ecb_remainder_len, datap, - need); - } - } else { - cipher(ctx->ecb_keysched, blockp, lastp); - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); - - /* copy block to where it belongs */ - bcopy(lastp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(lastp + out_data_1_len, out_data_2, - block_size - out_data_1_len); - } - /* update offset */ - out->cd_offset += block_size; + /* copy block to where it belongs */ + bcopy(lastp, out_data_1, out_data_1_len); + if (out_data_2 != NULL) { + bcopy(lastp + out_data_1_len, out_data_2, + block_size - out_data_1_len); } + /* update offset */ + out->cd_offset += block_size; /* Update pointer to next block of data to be processed. */ if (ctx->ecb_remainder_len != 0) { diff --git a/module/icp/algs/modes/gcm.c b/module/icp/algs/modes/gcm.c index f43766fd1..7a94d3dbb 100644 --- a/module/icp/algs/modes/gcm.c +++ b/module/icp/algs/modes/gcm.c @@ -117,8 +117,7 @@ gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *ctx, char *data, size_t length, } lastp = (uint8_t *)ctx->gcm_cb; - if (out != NULL) - crypto_init_ptrs(out, &iov_or_mp, &offset); + crypto_init_ptrs(out, &iov_or_mp, &offset); gops = gcm_impl_get_ops(); do { @@ -154,39 +153,22 @@ gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *ctx, char *data, size_t length, ctx->gcm_processed_data_len += block_size; - /* - * The following copies a complete GCM block back to where it - * came from if there was a remainder in the last call and out - * is NULL. That doesn't seem to make sense. So we assert this - * can't happen and leave the code in for reference. - * See https://github.com/zfsonlinux/zfs/issues/9661 - */ - ASSERT(out != NULL); - if (out == NULL) { - if (ctx->gcm_remainder_len > 0) { - bcopy(blockp, ctx->gcm_copy_to, - ctx->gcm_remainder_len); - bcopy(blockp + ctx->gcm_remainder_len, datap, - need); - } - } else { - crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, - &out_data_1_len, &out_data_2, block_size); + crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, + &out_data_1_len, &out_data_2, block_size); - /* copy block to where it belongs */ - if (out_data_1_len == block_size) { - copy_block(lastp, out_data_1); - } else { - bcopy(lastp, out_data_1, out_data_1_len); - if (out_data_2 != NULL) { - bcopy(lastp + out_data_1_len, - out_data_2, - block_size - out_data_1_len); - } + /* copy block to where it belongs */ + if (out_data_1_len == block_size) { + copy_block(lastp, out_data_1); + } else { + bcopy(lastp, out_data_1, out_data_1_len); + if (out_data_2 != NULL) { + bcopy(lastp + out_data_1_len, + out_data_2, + block_size - out_data_1_len); } - /* update offset */ - out->cd_offset += block_size; } + /* update offset */ + out->cd_offset += block_size; /* add ciphertext to the hash */ GHASH(ctx, ctx->gcm_tmp, ctx->gcm_ghash, gops); @@ -1093,7 +1075,7 @@ gcm_toggle_avx(void) } /* - * Clear senssitve data in the context. + * Clear sensitive data in the context. * * ctx->gcm_remainder may contain a plaintext remainder. ctx->gcm_H and * ctx->gcm_Htable contain the hash sub key which protects authentication. @@ -1189,13 +1171,6 @@ gcm_mode_encrypt_contiguous_blocks_avx(gcm_ctx_t *ctx, char *data, GHASH_AVX(ctx, tmp, block_size); clear_fpu_regs(); kfpu_end(); - /* - * We don't follow gcm_mode_encrypt_contiguous_blocks() here - * but assert that out is not null. - * See gcm_mode_encrypt_contiguous_blocks() above and - * https://github.com/zfsonlinux/zfs/issues/9661 - */ - ASSERT(out != NULL); rv = crypto_put_output_data(tmp, out, block_size); out->cd_offset += block_size; gcm_incr_counter_block(ctx); @@ -1217,13 +1192,11 @@ gcm_mode_encrypt_contiguous_blocks_avx(gcm_ctx_t *ctx, char *data, rv = CRYPTO_FAILED; goto out_nofpu; } - if (out != NULL) { - rv = crypto_put_output_data(ct_buf, out, chunk_size); - if (rv != CRYPTO_SUCCESS) { - goto out_nofpu; - } - out->cd_offset += chunk_size; + rv = crypto_put_output_data(ct_buf, out, chunk_size); + if (rv != CRYPTO_SUCCESS) { + goto out_nofpu; } + out->cd_offset += chunk_size; datap += chunk_size; ctx->gcm_processed_data_len += chunk_size; } @@ -1239,13 +1212,11 @@ gcm_mode_encrypt_contiguous_blocks_avx(gcm_ctx_t *ctx, char *data, rv = CRYPTO_FAILED; goto out; } - if (out != NULL) { - rv = crypto_put_output_data(ct_buf, out, done); - if (rv != CRYPTO_SUCCESS) { - goto out; - } - out->cd_offset += done; + rv = crypto_put_output_data(ct_buf, out, done); + if (rv != CRYPTO_SUCCESS) { + goto out; } + out->cd_offset += done; ctx->gcm_processed_data_len += done; datap += done; bleft -= done; @@ -1265,13 +1236,11 @@ gcm_mode_encrypt_contiguous_blocks_avx(gcm_ctx_t *ctx, char *data, gcm_xor_avx(datap, tmp); GHASH_AVX(ctx, tmp, block_size); - if (out != NULL) { - rv = crypto_put_output_data(tmp, out, block_size); - if (rv != CRYPTO_SUCCESS) { - goto out; - } - out->cd_offset += block_size; + rv = crypto_put_output_data(tmp, out, block_size); + if (rv != CRYPTO_SUCCESS) { + goto out; } + out->cd_offset += block_size; gcm_incr_counter_block(ctx); ctx->gcm_processed_data_len += block_size; datap += block_size; |