Esempio n. 1
0
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;
}