示例#1
0
TEE_Result TEE_AEUpdate(TEE_OperationHandle op, const void *srcData,
			size_t srcLen, void *destData, size_t *destLen)
{
	size_t req_dlen;

	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
	    destLen == NULL || (destData == NULL && *destLen != 0))
		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 = ROUNDDOWN(op->buffer_offs + srcLen, op->block_size);
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		return TEE_ERROR_SHORT_BUFFER;
	}

	tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen,
			  destData, destLen);

	return TEE_SUCCESS;
}
示例#2
0
TEE_Result TEE_CipherDoFinal(TEE_OperationHandle op,
			     const void *srcData, size_t srcLen, void *destData,
			     size_t *destLen)
{
	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))
		TEE_Panic(0);
	if (op->info.operationClass != TEE_OPERATION_CIPHER)
		TEE_Panic(0);
	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		TEE_Panic(0);

	/*
	 * Check that the final block doesn't require padding for those
	 * algorithms that requires client to supply padding.
	 */
	if (op->info.algorithm == TEE_ALG_AES_ECB_NOPAD ||
	    op->info.algorithm == TEE_ALG_AES_CBC_NOPAD ||
	    op->info.algorithm == TEE_ALG_DES_ECB_NOPAD ||
	    op->info.algorithm == TEE_ALG_DES_CBC_NOPAD ||
	    op->info.algorithm == TEE_ALG_DES3_ECB_NOPAD ||
	    op->info.algorithm == TEE_ALG_DES3_CBC_NOPAD) {
		if (((op->buffer_offs + srcLen) % op->block_size) != 0)
			return TEE_ERROR_BAD_PARAMETERS;
	}

	/*
	 * 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;
	}

	tmp_dlen = *destLen - acc_dlen;
	tee_buffer_update(op, utee_cipher_update, srcData, srcLen, dst,
			  &tmp_dlen);
	dst += tmp_dlen;
	acc_dlen += tmp_dlen;

	tmp_dlen = *destLen - acc_dlen;
	res = utee_cipher_final(op->state, op->buffer, op->buffer_offs,
				dst, &tmp_dlen);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
	acc_dlen += tmp_dlen;

	op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
	*destLen = acc_dlen;
	return TEE_SUCCESS;
}
示例#3
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;
}
示例#4
0
TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, void *srcData,
			uint32_t srcLen, void *destData, uint32_t *destLen)
{
	TEE_Result res;
	size_t req_dlen;
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0)) {
		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.
	 */
	req_dlen = ROUNDDOWN(operation->buffer_offs + srcLen,
			     operation->block_size);
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	dl = *destLen;
	res = tee_buffer_update(operation, utee_authenc_update_payload, srcData,
				srcLen, destData, &dl);
	*destLen = dl;

	operation->operationState = TEE_OPERATION_STATE_ACTIVE;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
			TEE_Panic(res);

	return res;
}
示例#5
0
TEE_Result TEE_CipherUpdate(TEE_OperationHandle op, const void *srcData,
			    size_t srcLen, void *destData, size_t *destLen)
{
	size_t req_dlen;

	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
	    destLen == NULL || (destData == NULL && *destLen != 0))
		TEE_Panic(0);
	if (op->info.operationClass != TEE_OPERATION_CIPHER)
		TEE_Panic(0);
	if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
		TEE_Panic(0);

	/* Calculate required dlen */
	req_dlen = ((op->buffer_offs + srcLen) / op->block_size) *
	    op->block_size;
	if (op->buffer_two_blocks) {
		if (req_dlen > op->block_size * 2)
			req_dlen -= op->block_size * 2;
		else
			req_dlen = 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.
	 */
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		return TEE_ERROR_SHORT_BUFFER;
	}

	tee_buffer_update(op, utee_cipher_update, srcData, srcLen, destData,
			  destLen);

	return TEE_SUCCESS;
}
示例#6
0
TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, void *srcData,
			    uint32_t srcLen, void *destData, uint32_t *destLen)
{
	TEE_Result res;
	size_t req_dlen;
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* Calculate required dlen */
	req_dlen = ((operation->buffer_offs + srcLen) / operation->block_size) *
	    operation->block_size;
	if (operation->buffer_two_blocks) {
		if (req_dlen > operation->block_size * 2)
			req_dlen -= operation->block_size * 2;
		else
			req_dlen = 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.
	 */
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	dl = *destLen;
	res = tee_buffer_update(operation, utee_cipher_update, srcData, srcLen,
				destData, &dl);
	*destLen = dl;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(0);

	return res;
}
示例#7
0
TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation,
			      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;

	if (operation == TEE_HANDLE_NULL ||
	    (srcData == NULL && srcLen != 0) ||
	    destLen == NULL ||
	    (destData == NULL && *destLen != 0) ||
	    (tag == NULL && tagLen != 0)) {
		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.
	 */
	req_dlen = operation->buffer_offs + srcLen;
	if (*destLen < req_dlen) {
		*destLen = req_dlen;
		res = TEE_ERROR_SHORT_BUFFER;
		goto out;
	}

	tmp_dlen = *destLen - acc_dlen;
	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_dec_final(operation->state, operation->buffer,
				     operation->buffer_offs, dst, &tmp_dlen,
				     tag, tagLen);
	if (res != TEE_SUCCESS)
		goto out;

	/* Supplied tagLen should match what we initiated with */
	if (tagLen != operation->ae_tag_len)
		res = TEE_ERROR_MAC_INVALID;

	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 &&
	    res != TEE_ERROR_MAC_INVALID)
			TEE_Panic(res);

	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;
}