int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len) { struct s390_sha_ctx *ctx = shash_desc_ctx(desc); unsigned int bsize = crypto_shash_blocksize(desc->tfm); unsigned int index, n; /* how much is already in the buffer? */ index = ctx->count & (bsize - 1); ctx->count += len; if ((index + len) < bsize) goto store; /* process one stored block */ if (index) { memcpy(ctx->buf + index, data, bsize - index); cpacf_kimd(ctx->func, ctx->state, ctx->buf, bsize); data += bsize - index; len -= bsize - index; index = 0; } /* process as many blocks as possible */ if (len >= bsize) { n = len & ~(bsize - 1); cpacf_kimd(ctx->func, ctx->state, data, n); data += n; len -= n; } store: if (len) memcpy(ctx->buf + index , data, len); return 0; }
int s390_sha_final(struct shash_desc *desc, u8 *out) { struct s390_sha_ctx *ctx = shash_desc_ctx(desc); unsigned int bsize = crypto_shash_blocksize(desc->tfm); u64 bits; unsigned int index, end, plen; int ret; /* SHA-512 uses 128 bit padding length */ plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8; /* must perform manual padding */ index = ctx->count & (bsize - 1); end = (index < bsize - plen) ? bsize : (2 * bsize); /* start pad with 1 */ ctx->buf[index] = 0x80; index++; /* pad with zeros */ memset(ctx->buf + index, 0x00, end - index - 8); /* * Append message length. Well, SHA-512 wants a 128 bit length value, * nevertheless we use u64, should be enough for now... */ bits = ctx->count * 8; memcpy(ctx->buf + end - 8, &bits, sizeof(bits)); ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, end); BUG_ON(ret != end); /* copy digest to out */ memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm)); /* wipe context */ memset(ctx, 0, sizeof *ctx); return 0; }
static int qat_alg_aead_init_dec_session(struct crypto_aead *aead_tfm, int alg, struct crypto_authenc_keys *keys, int mode) { struct qat_alg_aead_ctx *ctx = crypto_aead_ctx(aead_tfm); unsigned int digestsize = crypto_aead_authsize(aead_tfm); struct qat_dec *dec_ctx = &ctx->dec_cd->qat_dec_cd; struct icp_qat_hw_auth_algo_blk *hash = &dec_ctx->hash; struct icp_qat_hw_cipher_algo_blk *cipher = (struct icp_qat_hw_cipher_algo_blk *)((char *)dec_ctx + sizeof(struct icp_qat_hw_auth_setup) + roundup(crypto_shash_digestsize(ctx->hash_tfm), 8) * 2); struct icp_qat_fw_la_bulk_req *req_tmpl = &ctx->dec_fw_req; struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars; struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr; void *ptr = &req_tmpl->cd_ctrl; struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr; struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr; struct icp_qat_fw_la_auth_req_params *auth_param = (struct icp_qat_fw_la_auth_req_params *) ((char *)&req_tmpl->serv_specif_rqpars + sizeof(struct icp_qat_fw_la_cipher_req_params)); /* CD setup */ cipher->aes.cipher_config.val = QAT_AES_HW_CONFIG_DEC(alg, mode); memcpy(cipher->aes.key, keys->enckey, keys->enckeylen); hash->sha.inner_setup.auth_config.config = ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE1, ctx->qat_hash_alg, digestsize); hash->sha.inner_setup.auth_counter.counter = cpu_to_be32(crypto_shash_blocksize(ctx->hash_tfm)); if (qat_alg_do_precomputes(hash, ctx, keys->authkey, keys->authkeylen)) return -EFAULT; /* Request setup */ qat_alg_init_common_hdr(header); header->service_cmd_id = ICP_QAT_FW_LA_CMD_HASH_CIPHER; ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags, ICP_QAT_FW_LA_DIGEST_IN_BUFFER); ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags, ICP_QAT_FW_LA_NO_RET_AUTH_RES); ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags, ICP_QAT_FW_LA_CMP_AUTH_RES); cd_pars->u.s.content_desc_addr = ctx->dec_cd_paddr; cd_pars->u.s.content_desc_params_sz = sizeof(struct qat_alg_cd) >> 3; /* Cipher CD config setup */ cipher_cd_ctrl->cipher_key_sz = keys->enckeylen >> 3; cipher_cd_ctrl->cipher_state_sz = AES_BLOCK_SIZE >> 3; cipher_cd_ctrl->cipher_cfg_offset = (sizeof(struct icp_qat_hw_auth_setup) + roundup(crypto_shash_digestsize(ctx->hash_tfm), 8) * 2) >> 3; ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER); ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_DRAM_WR); /* Auth CD config setup */ hash_cd_ctrl->hash_cfg_offset = 0; hash_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED; hash_cd_ctrl->inner_res_sz = digestsize; hash_cd_ctrl->final_sz = digestsize; switch (ctx->qat_hash_alg) { case ICP_QAT_HW_AUTH_ALGO_SHA1: hash_cd_ctrl->inner_state1_sz = round_up(ICP_QAT_HW_SHA1_STATE1_SZ, 8); hash_cd_ctrl->inner_state2_sz = round_up(ICP_QAT_HW_SHA1_STATE2_SZ, 8); break; case ICP_QAT_HW_AUTH_ALGO_SHA256: hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA256_STATE1_SZ; hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA256_STATE2_SZ; break; case ICP_QAT_HW_AUTH_ALGO_SHA512: hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA512_STATE1_SZ; hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA512_STATE2_SZ; break; default: break; } hash_cd_ctrl->inner_state2_offset = hash_cd_ctrl->hash_cfg_offset + ((sizeof(struct icp_qat_hw_auth_setup) + round_up(hash_cd_ctrl->inner_state1_sz, 8)) >> 3); auth_param->auth_res_sz = digestsize; ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_AUTH); ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER); return 0; }
static int qat_alg_do_precomputes(struct icp_qat_hw_auth_algo_blk *hash, struct qat_alg_aead_ctx *ctx, const uint8_t *auth_key, unsigned int auth_keylen) { SHASH_DESC_ON_STACK(shash, ctx->hash_tfm); int block_size = crypto_shash_blocksize(ctx->hash_tfm); int digest_size = crypto_shash_digestsize(ctx->hash_tfm); __be32 *hash_state_out; __be64 *hash512_state_out; int i, offset; memset(ctx->ipad, 0, block_size); memset(ctx->opad, 0, block_size); shash->tfm = ctx->hash_tfm; shash->flags = 0x0; if (auth_keylen > block_size) { int ret = crypto_shash_digest(shash, auth_key, auth_keylen, ctx->ipad); if (ret) return ret; memcpy(ctx->opad, ctx->ipad, digest_size); } else { memcpy(ctx->ipad, auth_key, auth_keylen); memcpy(ctx->opad, auth_key, auth_keylen); } for (i = 0; i < block_size; i++) { char *ipad_ptr = ctx->ipad + i; char *opad_ptr = ctx->opad + i; *ipad_ptr ^= HMAC_IPAD_VALUE; *opad_ptr ^= HMAC_OPAD_VALUE; } if (crypto_shash_init(shash)) return -EFAULT; if (crypto_shash_update(shash, ctx->ipad, block_size)) return -EFAULT; hash_state_out = (__be32 *)hash->sha.state1; hash512_state_out = (__be64 *)hash_state_out; switch (ctx->qat_hash_alg) { case ICP_QAT_HW_AUTH_ALGO_SHA1: if (crypto_shash_export(shash, &ctx->sha1)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(ctx->sha1.state[i]); break; case ICP_QAT_HW_AUTH_ALGO_SHA256: if (crypto_shash_export(shash, &ctx->sha256)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(ctx->sha256.state[i]); break; case ICP_QAT_HW_AUTH_ALGO_SHA512: if (crypto_shash_export(shash, &ctx->sha512)) return -EFAULT; for (i = 0; i < digest_size >> 3; i++, hash512_state_out++) *hash512_state_out = cpu_to_be64(ctx->sha512.state[i]); break; default: return -EFAULT; } if (crypto_shash_init(shash)) return -EFAULT; if (crypto_shash_update(shash, ctx->opad, block_size)) return -EFAULT; offset = round_up(qat_get_inter_state_size(ctx->qat_hash_alg), 8); hash_state_out = (__be32 *)(hash->sha.state1 + offset); hash512_state_out = (__be64 *)hash_state_out; switch (ctx->qat_hash_alg) { case ICP_QAT_HW_AUTH_ALGO_SHA1: if (crypto_shash_export(shash, &ctx->sha1)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(ctx->sha1.state[i]); break; case ICP_QAT_HW_AUTH_ALGO_SHA256: if (crypto_shash_export(shash, &ctx->sha256)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(ctx->sha256.state[i]); break; case ICP_QAT_HW_AUTH_ALGO_SHA512: if (crypto_shash_export(shash, &ctx->sha512)) return -EFAULT; for (i = 0; i < digest_size >> 3; i++, hash512_state_out++) *hash512_state_out = cpu_to_be64(ctx->sha512.state[i]); break; default: return -EFAULT; } memzero_explicit(ctx->ipad, block_size); memzero_explicit(ctx->opad, block_size); return 0; }
static int qat_alg_do_precomputes(struct icp_qat_hw_auth_algo_blk *hash, struct qat_alg_session_ctx *ctx, const uint8_t *auth_key, unsigned int auth_keylen) { struct qat_auth_state auth_state; SHASH_DESC_ON_STACK(shash, ctx->hash_tfm); struct sha1_state sha1; struct sha256_state sha256; struct sha512_state sha512; int block_size = crypto_shash_blocksize(ctx->hash_tfm); int digest_size = crypto_shash_digestsize(ctx->hash_tfm); uint8_t *ipad = auth_state.data; uint8_t *opad = ipad + block_size; __be32 *hash_state_out; __be64 *hash512_state_out; int i, offset; memzero_explicit(auth_state.data, MAX_AUTH_STATE_SIZE + 64); shash->tfm = ctx->hash_tfm; shash->flags = 0x0; if (auth_keylen > block_size) { char buff[SHA512_BLOCK_SIZE]; int ret = crypto_shash_digest(shash, auth_key, auth_keylen, buff); if (ret) return ret; memcpy(ipad, buff, digest_size); memcpy(opad, buff, digest_size); memzero_explicit(ipad + digest_size, block_size - digest_size); memzero_explicit(opad + digest_size, block_size - digest_size); } else { memcpy(ipad, auth_key, auth_keylen); memcpy(opad, auth_key, auth_keylen); memzero_explicit(ipad + auth_keylen, block_size - auth_keylen); memzero_explicit(opad + auth_keylen, block_size - auth_keylen); } for (i = 0; i < block_size; i++) { char *ipad_ptr = ipad + i; char *opad_ptr = opad + i; *ipad_ptr ^= 0x36; *opad_ptr ^= 0x5C; } if (crypto_shash_init(shash)) return -EFAULT; if (crypto_shash_update(shash, ipad, block_size)) return -EFAULT; hash_state_out = (__be32 *)hash->sha.state1; hash512_state_out = (__be64 *)hash_state_out; switch (ctx->qat_hash_alg) { case ICP_QAT_HW_AUTH_ALGO_SHA1: if (crypto_shash_export(shash, &sha1)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(*(sha1.state + i)); break; case ICP_QAT_HW_AUTH_ALGO_SHA256: if (crypto_shash_export(shash, &sha256)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(*(sha256.state + i)); break; case ICP_QAT_HW_AUTH_ALGO_SHA512: if (crypto_shash_export(shash, &sha512)) return -EFAULT; for (i = 0; i < digest_size >> 3; i++, hash512_state_out++) *hash512_state_out = cpu_to_be64(*(sha512.state + i)); break; default: return -EFAULT; } if (crypto_shash_init(shash)) return -EFAULT; if (crypto_shash_update(shash, opad, block_size)) return -EFAULT; offset = round_up(qat_get_inter_state_size(ctx->qat_hash_alg), 8); hash_state_out = (__be32 *)(hash->sha.state1 + offset); hash512_state_out = (__be64 *)hash_state_out; switch (ctx->qat_hash_alg) { case ICP_QAT_HW_AUTH_ALGO_SHA1: if (crypto_shash_export(shash, &sha1)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(*(sha1.state + i)); break; case ICP_QAT_HW_AUTH_ALGO_SHA256: if (crypto_shash_export(shash, &sha256)) return -EFAULT; for (i = 0; i < digest_size >> 2; i++, hash_state_out++) *hash_state_out = cpu_to_be32(*(sha256.state + i)); break; case ICP_QAT_HW_AUTH_ALGO_SHA512: if (crypto_shash_export(shash, &sha512)) return -EFAULT; for (i = 0; i < digest_size >> 3; i++, hash512_state_out++) *hash512_state_out = cpu_to_be64(*(sha512.state + i)); break; default: return -EFAULT; } memzero_explicit(ipad, block_size); memzero_explicit(opad, block_size); return 0; }