TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle op, const void *srcData, size_t srcLen, void *destData, size_t *destLen, void *tag, size_t *tagLen) { TEE_Result res; uint8_t *dst = destData; size_t acc_dlen = 0; size_t tmp_dlen; size_t req_dlen; if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || destLen == NULL || (destData == NULL && *destLen != 0) || tag == NULL || tagLen == NULL) TEE_Panic(0); if (op->info.operationClass != TEE_OPERATION_AE) TEE_Panic(0); if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) TEE_Panic(0); /* * Check that required destLen is big enough before starting to feed * data to the algorithm. Errors during feeding of data are fatal as we * can't restore sync with this API. */ req_dlen = op->buffer_offs + srcLen; if (*destLen < req_dlen) { *destLen = req_dlen; return TEE_ERROR_SHORT_BUFFER; } /* * Need to check this before update_payload since sync would be lost if * we return short buffer after that. */ if (*tagLen < op->ae_tag_len) { *tagLen = op->ae_tag_len; return TEE_ERROR_SHORT_BUFFER; } tmp_dlen = *destLen - acc_dlen; tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen, dst, &tmp_dlen); dst += tmp_dlen; acc_dlen += tmp_dlen; tmp_dlen = *destLen - acc_dlen; res = utee_authenc_enc_final(op->state, op->buffer, op->buffer_offs, dst, &tmp_dlen, tag, tagLen); if (res != TEE_SUCCESS) TEE_Panic(res); acc_dlen += tmp_dlen; *destLen = acc_dlen; op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; return res; }
TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, const void *srcData, uint32_t srcLen, void *destData, uint32_t *destLen, void *tag, uint32_t *tagLen) { TEE_Result res; uint8_t *dst = destData; size_t acc_dlen = 0; uint64_t tmp_dlen; size_t req_dlen; uint64_t tl; if (operation == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || destLen == NULL || (destData == NULL && *destLen != 0) || tag == NULL || tagLen == NULL) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } if (operation->info.operationClass != TEE_OPERATION_AE) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } /* * Check that required destLen is big enough before starting to feed * data to the algorithm. Errors during feeding of data are fatal as we * can't restore sync with this API. * * Need to check this before update_payload since sync would be lost if * we return short buffer after that. */ res = TEE_ERROR_GENERIC; req_dlen = operation->buffer_offs + srcLen; if (*destLen < req_dlen) { *destLen = req_dlen; res = TEE_ERROR_SHORT_BUFFER; } if (*tagLen < operation->ae_tag_len) { *tagLen = operation->ae_tag_len; res = TEE_ERROR_SHORT_BUFFER; } if (res == TEE_ERROR_SHORT_BUFFER) goto out; tl = *tagLen; tmp_dlen = *destLen - acc_dlen; if (operation->block_size > 1) { res = tee_buffer_update(operation, utee_authenc_update_payload, srcData, srcLen, dst, &tmp_dlen); if (res != TEE_SUCCESS) goto out; dst += tmp_dlen; acc_dlen += tmp_dlen; tmp_dlen = *destLen - acc_dlen; res = utee_authenc_enc_final(operation->state, operation->buffer, operation->buffer_offs, dst, &tmp_dlen, tag, &tl); } else { res = utee_authenc_enc_final(operation->state, srcData, srcLen, dst, &tmp_dlen, tag, &tl); } *tagLen = tl; if (res != TEE_SUCCESS) goto out; acc_dlen += tmp_dlen; *destLen = acc_dlen; operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; operation->operationState = TEE_OPERATION_STATE_INITIAL; out: if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) TEE_Panic(res); return res; }