/*! * Acquires 16 Bytes IV from the iv-pool * * \param drvdata Driver private context * \param iv_out_dma The phys. IV out address * \param iv_out_size May be 8 or 16 bytes long * \param iv_seq IN/OUT array to the descriptors sequence * \param iv_seq_len IN/OUT pointer to the sequence length * * \return int Zero for success, negative value otherwise. */ int dx_ivgen_getiv( struct dx_drvdata *drvdata, dma_addr_t iv_out_dma, unsigned int iv_out_size, HwDesc_s iv_seq[], unsigned int *iv_seq_len) { struct dx_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; unsigned int idx = *iv_seq_len; if ((iv_out_size != SEP_AES_IV_SIZE) && (iv_out_size != CTR_RFC3686_IV_SIZE)) { return -EINVAL; } /* Acquire IV from pool */ HW_DESC_INIT(&iv_seq[idx]); HW_DESC_SET_DIN_SRAM(&iv_seq[idx], ivgen_ctx->pool + ivgen_ctx->next_iv_ofs, iv_out_size); HW_DESC_SET_DOUT_DLLI(&iv_seq[idx], iv_out_dma, iv_out_size, AXI_ID, NS_BIT, 0); HW_DESC_SET_FLOW_MODE(&iv_seq[idx], BYPASS); idx++; /* Bypass operation is proceeded by crypto sequence, hence must * assure bypass-write-transaction by a memory barrier */ HW_DESC_INIT(&iv_seq[idx]); HW_DESC_SET_DIN_NO_DMA(&iv_seq[idx], 0, 0xfffff0); HW_DESC_SET_DOUT_NO_DMA(&iv_seq[idx], 0, 0, 1); idx++; *iv_seq_len = idx; /* update seq length */ /* Update iv index */ ivgen_ctx->next_iv_ofs += iv_out_size; if ((DX_IVPOOL_SIZE - ivgen_ctx->next_iv_ofs) < SEP_AES_IV_SIZE) { DX_LOG_DEBUG("Pool exhausted, regenerating iv-pool\n"); /* pool is drained -regenerate it! */ dx_ivgen_generate_pool(ivgen_ctx, iv_seq, iv_seq_len); } return 0; }
void LoadCipherKey(int qid, struct sep_ctx_cipher *pCtx) { HwDesc_s desc; uint32_t keySize = ReadContextWord(&pCtx->key_size); XcbcMacRfcKeys_s *XcbcKeys = (XcbcMacRfcKeys_s*)pCtx->key; SepCipherPrivateContext_s *pAesPrivateCtx = (SepCipherPrivateContext_s *)pCtx->reserved; enum sep_crypto_direction encDecFlag = ReadContextWord(&pCtx->direction); HW_DESC_INIT(&desc); /* key size 24 bytes count as 32 bytes, make sure to zero wise upper 8 bytes */ if (keySize == 24) { keySize = SEP_AES_KEY_SIZE_MAX; ClearCtxField(&pCtx->key[24], SEP_AES_KEY_SIZE_MAX - 24); } HW_DESC_SET_CIPHER_MODE(&desc, ReadContextWord(&pCtx->mode)); if (ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_AES) { if ((ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY) && (ReadContextWord(&pCtx->direction) == SEP_CRYPTO_DIRECTION_DECRYPT)) { /* if the crypto operation is DECRYPT we still order the HW for ENCRYPT operation when using HDCP key. The next decriptor which loads the HDCP XOR key will direct DECRYPT operation. */ encDecFlag = SEP_CRYPTO_DIRECTION_ENCRYPT; } HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp) ? ReadContextWord(&pAesPrivateCtx->tunnetDir) : encDecFlag); HW_DESC_SET_CIPHER_CONFIG1(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp)); switch (ReadContextWord(&pCtx->mode)) { case SEP_CIPHER_XCBC_MAC: HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)XcbcKeys->K1, SEP_AES_128_BIT_KEY_SIZE); HW_DESC_SET_KEY_SIZE_AES(&desc, SEP_AES_128_BIT_KEY_SIZE); if (ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY) { HW_DESC_SET_AES_XOR_CRYPTO_KEY(&desc); } break; default: switch (ReadContextWord(&pCtx->crypto_key_type)) { case DX_ROOT_KEY: HW_DESC_SET_CIPHER_DO(&desc, ReadContextWord(&pCtx->crypto_key_type)); break; case DX_SESSION_KEY: HW_DESC_SET_CIPHER_DO(&desc, SESSION_KEY); //value to be written to DO when session key is used break; case DX_XOR_HDCP_KEY: HW_DESC_SET_AES_XOR_CRYPTO_KEY(&desc); /*FALLTHROUGH*/ case DX_USER_KEY: case DX_APPLET_KEY: default: HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->key, keySize); } HW_DESC_SET_KEY_SIZE_AES(&desc, ReadContextWord(&pCtx->key_size)); } if (ReadContextWord(&pAesPrivateCtx->engineCore) == SEP_AES_ENGINE2) { HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES2); } else { HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES); } } else { HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->key, ReadContextWord(&pCtx->key_size)); HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_DES); HW_DESC_SET_KEY_SIZE_DES(&desc, ReadContextWord(&pCtx->key_size)); HW_DESC_SET_CIPHER_CONFIG0(&desc, encDecFlag); } HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_KEY0); AddHWDescSequence(qid, &desc); if ((ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_AES) && (ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY)) { /* in HDCP, the user key being XORed with SEP_HDCP_CONST registers on the fly. We reusing the descriptor and overwrite the necessary bits so DO NOT clear the descriptor before. */ HW_DESC_SET_DIN_NO_DMA(&desc, NO_DMA, 0); HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pCtx->direction)); /* user direction */ HW_DESC_SET_CIPHER_DO(&desc, ReadContextWord(&pCtx->crypto_key_type)); AddHWDescSequence(qid, &desc); } if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XTS) { HW_DESC_INIT(&desc); /* load XEX key */ HW_DESC_SET_CIPHER_MODE(&desc, ReadContextWord(&pCtx->mode)); HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp) ? ReadContextWord(&pAesPrivateCtx->tunnetDir) : encDecFlag); HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->xex_key, keySize); HW_DESC_SET_XEX_DATA_UNIT_SIZE(&desc, ReadContextWord(&pCtx->data_unit_size)); HW_DESC_SET_CIPHER_CONFIG1(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp)); if (ReadContextWord(&pAesPrivateCtx->engineCore) == SEP_AES_ENGINE2) { HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES2); } else { HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES); } HW_DESC_SET_KEY_SIZE_AES(&desc, keySize); HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_XEX_KEY); AddHWDescSequence(qid, &desc); } if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XCBC_MAC) { /* load K2 key */ /* NO init - reuse previous descriptor settings */ HW_DESC_SET_STATE_DIN_PARAM(&desc,(uint32_t)XcbcKeys->K2, SEP_AES_128_BIT_KEY_SIZE); HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_STATE1); AddHWDescSequence(qid, &desc); /* load K3 key */ /* NO init - reuse previous descriptor settings */ HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)XcbcKeys->K3, SEP_AES_128_BIT_KEY_SIZE); HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_STATE2); AddHWDescSequence(qid, &desc); } }