Beispiel #1
0
TEE_Result tee_cipher_get_block_size(uint32_t algo, size_t *size)
{
	TEE_Result res;
	int ltc_cipherindex;

	res = tee_algo_to_ltc_cipherindex(algo, &ltc_cipherindex);
	if (res != TEE_SUCCESS)
		return TEE_ERROR_NOT_SUPPORTED;

	*size = cipher_descriptor[ltc_cipherindex].block_length;
	return TEE_SUCCESS;
}
Beispiel #2
0
TEE_Result tee_authenc_init(
	void *ctx, uint32_t algo, TEE_OperationMode mode, const uint8_t *key,
	size_t key_len, const uint8_t *nonce,
	size_t nonce_len, size_t tag_len, size_t aad_len, size_t payload_len)
{
	TEE_Result res;
	int ltc_res;
	int ltc_cipherindex;
	unsigned char *payload, *res_payload;
	struct tee_ccm_state *ccm;
	struct tee_gcm_state *gcm;

	res = tee_algo_to_ltc_cipherindex(algo, &ltc_cipherindex);
	if (res != TEE_SUCCESS)
		return TEE_ERROR_NOT_SUPPORTED;
	switch (algo) {
	case TEE_ALG_AES_CCM:
		/* Check the key length */
		if ((!key) || (key_len > TEE_CCM_KEY_MAX_LENGTH))
			return TEE_ERROR_BAD_PARAMETERS;

		/* check the nonce */
		if (nonce_len > TEE_CCM_NONCE_MAX_LENGTH)
			return TEE_ERROR_BAD_PARAMETERS;

		/* check the tag len */
		if ((tag_len < 4) ||
		    (tag_len > TEE_CCM_TAG_MAX_LENGTH) ||
		    (tag_len % 2 != 0))
			return TEE_ERROR_NOT_SUPPORTED;

		/* allocate payload */
		payload = malloc(payload_len + TEE_CCM_KEY_MAX_LENGTH);
		if (!payload)
			return TEE_ERROR_OUT_OF_MEMORY;
		res_payload = malloc(payload_len + TEE_CCM_KEY_MAX_LENGTH);
		if (!res_payload) {
			free(payload);
			return TEE_ERROR_OUT_OF_MEMORY;
		}

		/* initialize the structure */
		ccm = ctx;
		memset(ccm, 0, sizeof(struct tee_ccm_state));
		memcpy(ccm->key, key, key_len);
		ccm->key_len = key_len;			/* the key length */
		if (nonce && nonce_len) {
			memcpy(ccm->nonce, nonce, nonce_len);
			ccm->nonce_len = nonce_len;
		} else {
			ccm->nonce_len = 0;
		}
		ccm->tag_len = tag_len;
		ccm->aad_len = aad_len;
		ccm->payload_len = payload_len;
		ccm->payload = payload;
		ccm->res_payload = res_payload;
		ccm->ltc_cipherindex = ltc_cipherindex;

		if (ccm->aad_len) {
			ccm->header = malloc(ccm->aad_len);
			if (!ccm->header) {
				free(payload);
				free(res_payload);
				return TEE_ERROR_OUT_OF_MEMORY;
			}
		}

		/* memset the payload to 0 that will be used for padding */
		memset(ccm->payload, 0, payload_len + TEE_CCM_KEY_MAX_LENGTH);
		break;

	case TEE_ALG_AES_GCM:
		/* reset the state */
		gcm = ctx;
		memset(gcm, 0, sizeof(struct tee_gcm_state));
		gcm->tag_len = tag_len;

		ltc_res = gcm_init(
			&gcm->ctx, ltc_cipherindex, key, key_len);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;

		/* Add the IV */
		ltc_res = gcm_add_iv(&gcm->ctx, nonce, nonce_len);
		if (ltc_res != CRYPT_OK)
			return TEE_ERROR_BAD_STATE;
		break;

	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	return TEE_SUCCESS;
}
Beispiel #3
0
TEE_Result tee_cipher_init3(void *ctx, uint32_t algo,
			    TEE_OperationMode mode, const uint8_t *key1,
			    size_t key1_len, const uint8_t *key2,
			    size_t key2_len, const uint8_t *iv, size_t iv_len)
{
	TEE_Result res;
	int ltc_res, ltc_cipherindex;
	uint8_t *real_key, key_array[24];
	size_t real_key_len;
	struct symmetric_CTS *cts;

	res = tee_algo_to_ltc_cipherindex(algo, &ltc_cipherindex);
	if (res != TEE_SUCCESS)
		return TEE_ERROR_NOT_SUPPORTED;

	switch (algo) {
	case TEE_ALG_AES_ECB_NOPAD:
	case TEE_ALG_DES_ECB_NOPAD:
		ltc_res = ecb_start(
			ltc_cipherindex, key1, key1_len,
			0, (symmetric_ECB *)ctx);
		break;

	case TEE_ALG_DES3_ECB_NOPAD:
		/* either des3 or des2, depending on the size of the key */
		get_des2_key(key1, key1_len, key_array,
			     &real_key, &real_key_len);
		ltc_res = ecb_start(
			ltc_cipherindex, real_key, real_key_len,
			0, (symmetric_ECB *)ctx);
		break;

	case TEE_ALG_AES_CBC_NOPAD:
	case TEE_ALG_DES_CBC_NOPAD:
		if (iv_len !=
		    (size_t)cipher_descriptor[ltc_cipherindex].block_length)
			return TEE_ERROR_BAD_PARAMETERS;
		ltc_res = cbc_start(
			ltc_cipherindex, iv, key1, key1_len,
			0, (symmetric_CBC *)ctx);
		break;

	case TEE_ALG_DES3_CBC_NOPAD:
		/* either des3 or des2, depending on the size of the key */
		get_des2_key(key1, key1_len, key_array,
			     &real_key, &real_key_len);
		if (iv_len !=
		    (size_t)cipher_descriptor[ltc_cipherindex].block_length)
			return TEE_ERROR_BAD_PARAMETERS;
		ltc_res = cbc_start(
			ltc_cipherindex, iv, real_key, real_key_len,
			0, (symmetric_CBC *)ctx);
		break;

	case TEE_ALG_AES_CTR:
		if (iv_len !=
		    (size_t)cipher_descriptor[ltc_cipherindex].block_length)
			return TEE_ERROR_BAD_PARAMETERS;
		ltc_res = ctr_start(
			ltc_cipherindex, iv, key1, key1_len,
			0, CTR_COUNTER_BIG_ENDIAN, (symmetric_CTR *)ctx);
		break;

	case TEE_ALG_AES_CTS:
		cts = (struct symmetric_CTS *)ctx;
		res = tee_cipher_init3(
			(void *)(&(cts->ecb)),
			TEE_ALG_AES_ECB_NOPAD, mode,
			key1, key1_len, key2, key2_len, iv, iv_len);
		if (res != TEE_SUCCESS)
			return res;
		res = tee_cipher_init3(
			(void *)(&(cts->cbc)),
			TEE_ALG_AES_CBC_NOPAD, mode,
			key1, key1_len, key2, key2_len, iv, iv_len);
		if (res != TEE_SUCCESS)
			return res;
		ltc_res = CRYPT_OK;
		break;

	case TEE_ALG_AES_XTS:
		if (key1_len != key2_len)
			return TEE_ERROR_BAD_PARAMETERS;
		ltc_res = xts_start(
			ltc_cipherindex, key1, key2, key1_len,
			0, (symmetric_xts *)ctx);
		break;
	default:
		return TEE_ERROR_NOT_SUPPORTED;
	}

	if (ltc_res == CRYPT_OK)
		return TEE_SUCCESS;
	else
		return TEE_ERROR_BAD_STATE;
}