15da36a24SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
25da36a24SJens Wiklander /*
35da36a24SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited
4*00507861SAlexander Zakharov * Copyright (c) 2021, SumUp Services GmbH
55da36a24SJens Wiklander */
65da36a24SJens Wiklander
75da36a24SJens Wiklander #include <assert.h>
85da36a24SJens Wiklander #include <crypto/crypto.h>
95da36a24SJens Wiklander #include <crypto/crypto_impl.h>
105da36a24SJens Wiklander #include <stdlib.h>
115da36a24SJens Wiklander #include <string.h>
125da36a24SJens Wiklander #include <tee_api_types.h>
135a913ee7SJerome Forissier #include <tomcrypt_private.h>
145da36a24SJens Wiklander #include <utee_defines.h>
155da36a24SJens Wiklander #include <util.h>
165da36a24SJens Wiklander
175da36a24SJens Wiklander struct ltc_omac_ctx {
185da36a24SJens Wiklander struct crypto_mac_ctx ctx;
195da36a24SJens Wiklander int cipher_idx;
205da36a24SJens Wiklander omac_state state;
215da36a24SJens Wiklander };
225da36a24SJens Wiklander
235da36a24SJens Wiklander static const struct crypto_mac_ops ltc_omac_ops;
245da36a24SJens Wiklander
to_omac_ctx(struct crypto_mac_ctx * ctx)255da36a24SJens Wiklander static struct ltc_omac_ctx *to_omac_ctx(struct crypto_mac_ctx *ctx)
265da36a24SJens Wiklander {
275da36a24SJens Wiklander assert(ctx && ctx->ops == <c_omac_ops);
285da36a24SJens Wiklander
295da36a24SJens Wiklander return container_of(ctx, struct ltc_omac_ctx, ctx);
305da36a24SJens Wiklander }
315da36a24SJens Wiklander
ltc_omac_init(struct crypto_mac_ctx * ctx,const uint8_t * key,size_t len)325da36a24SJens Wiklander static TEE_Result ltc_omac_init(struct crypto_mac_ctx *ctx, const uint8_t *key,
335da36a24SJens Wiklander size_t len)
345da36a24SJens Wiklander {
355da36a24SJens Wiklander struct ltc_omac_ctx *hc = to_omac_ctx(ctx);
365da36a24SJens Wiklander
375da36a24SJens Wiklander if (omac_init(&hc->state, hc->cipher_idx, key, len) == CRYPT_OK)
385da36a24SJens Wiklander return TEE_SUCCESS;
395da36a24SJens Wiklander else
405da36a24SJens Wiklander return TEE_ERROR_BAD_STATE;
415da36a24SJens Wiklander }
425da36a24SJens Wiklander
ltc_omac_update(struct crypto_mac_ctx * ctx,const uint8_t * data,size_t len)435da36a24SJens Wiklander static TEE_Result ltc_omac_update(struct crypto_mac_ctx *ctx,
445da36a24SJens Wiklander const uint8_t *data, size_t len)
455da36a24SJens Wiklander {
465da36a24SJens Wiklander if (omac_process(&to_omac_ctx(ctx)->state, data, len) == CRYPT_OK)
475da36a24SJens Wiklander return TEE_SUCCESS;
485da36a24SJens Wiklander else
495da36a24SJens Wiklander return TEE_ERROR_BAD_STATE;
505da36a24SJens Wiklander }
515da36a24SJens Wiklander
ltc_omac_final(struct crypto_mac_ctx * ctx,uint8_t * digest,size_t len)525da36a24SJens Wiklander static TEE_Result ltc_omac_final(struct crypto_mac_ctx *ctx, uint8_t *digest,
535da36a24SJens Wiklander size_t len)
545da36a24SJens Wiklander {
555da36a24SJens Wiklander unsigned long l = len;
565da36a24SJens Wiklander
575da36a24SJens Wiklander if (omac_done(&to_omac_ctx(ctx)->state, digest, &l) == CRYPT_OK)
585da36a24SJens Wiklander return TEE_SUCCESS;
595da36a24SJens Wiklander else
605da36a24SJens Wiklander return TEE_ERROR_BAD_STATE;
615da36a24SJens Wiklander }
625da36a24SJens Wiklander
ltc_omac_free_ctx(struct crypto_mac_ctx * ctx)635da36a24SJens Wiklander static void ltc_omac_free_ctx(struct crypto_mac_ctx *ctx)
645da36a24SJens Wiklander {
655da36a24SJens Wiklander free(to_omac_ctx(ctx));
665da36a24SJens Wiklander }
675da36a24SJens Wiklander
ltc_omac_copy_state(struct crypto_mac_ctx * dst_ctx,struct crypto_mac_ctx * src_ctx)685da36a24SJens Wiklander static void ltc_omac_copy_state(struct crypto_mac_ctx *dst_ctx,
695da36a24SJens Wiklander struct crypto_mac_ctx *src_ctx)
705da36a24SJens Wiklander {
715da36a24SJens Wiklander struct ltc_omac_ctx *src = to_omac_ctx(src_ctx);
725da36a24SJens Wiklander struct ltc_omac_ctx *dst = to_omac_ctx(dst_ctx);
735da36a24SJens Wiklander
745da36a24SJens Wiklander assert(src->cipher_idx == dst->cipher_idx);
755da36a24SJens Wiklander dst->state = src->state;
765da36a24SJens Wiklander }
775da36a24SJens Wiklander
785da36a24SJens Wiklander static const struct crypto_mac_ops ltc_omac_ops = {
795da36a24SJens Wiklander .init = ltc_omac_init,
805da36a24SJens Wiklander .update = ltc_omac_update,
815da36a24SJens Wiklander .final = ltc_omac_final,
825da36a24SJens Wiklander .free_ctx = ltc_omac_free_ctx,
835da36a24SJens Wiklander .copy_state = ltc_omac_copy_state,
845da36a24SJens Wiklander };
855da36a24SJens Wiklander
crypto_common_cmac_alloc_ctx(struct crypto_mac_ctx ** ctx_ret,const char * cipher)86*00507861SAlexander Zakharov static TEE_Result crypto_common_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret,
87*00507861SAlexander Zakharov const char *cipher)
885da36a24SJens Wiklander {
895da36a24SJens Wiklander struct ltc_omac_ctx *ctx = NULL;
90*00507861SAlexander Zakharov int cipher_idx = find_cipher(cipher);
91*00507861SAlexander Zakharov
92*00507861SAlexander Zakharov if (!ctx_ret)
93*00507861SAlexander Zakharov return TEE_ERROR_BAD_PARAMETERS;
945da36a24SJens Wiklander
955da36a24SJens Wiklander if (cipher_idx < 0)
965da36a24SJens Wiklander return TEE_ERROR_NOT_SUPPORTED;
975da36a24SJens Wiklander
985da36a24SJens Wiklander ctx = calloc(1, sizeof(*ctx));
995da36a24SJens Wiklander if (!ctx)
1005da36a24SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
1015da36a24SJens Wiklander
1025da36a24SJens Wiklander ctx->ctx.ops = <c_omac_ops;
1035da36a24SJens Wiklander ctx->cipher_idx = cipher_idx;
1045da36a24SJens Wiklander *ctx_ret = &ctx->ctx;
1055da36a24SJens Wiklander
1065da36a24SJens Wiklander return TEE_SUCCESS;
1075da36a24SJens Wiklander }
108*00507861SAlexander Zakharov
crypto_aes_cmac_alloc_ctx(struct crypto_mac_ctx ** ctx_ret)109*00507861SAlexander Zakharov TEE_Result crypto_aes_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret)
110*00507861SAlexander Zakharov {
111*00507861SAlexander Zakharov return crypto_common_cmac_alloc_ctx(ctx_ret, "aes");
112*00507861SAlexander Zakharov }
113*00507861SAlexander Zakharov
crypto_des3_cmac_alloc_ctx(struct crypto_mac_ctx ** ctx_ret)114*00507861SAlexander Zakharov TEE_Result crypto_des3_cmac_alloc_ctx(struct crypto_mac_ctx **ctx_ret)
115*00507861SAlexander Zakharov {
116*00507861SAlexander Zakharov return crypto_common_cmac_alloc_ctx(ctx_ret, "3des");
117*00507861SAlexander Zakharov }
118