1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <compiler.h> 8 #include <crypto/crypto.h> 9 #include <crypto/crypto_impl.h> 10 #include <mbedtls/des.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <tee_api_types.h> 14 #include <utee_defines.h> 15 #include <util.h> 16 17 struct mbed_des_ecb_ctx { 18 struct crypto_cipher_ctx ctx; 19 mbedtls_des_context des_ctx; 20 }; 21 22 static const struct crypto_cipher_ops mbed_des_ecb_ops; 23 24 static struct mbed_des_ecb_ctx *to_des_ecb_ctx(struct crypto_cipher_ctx *ctx) 25 { 26 assert(ctx && ctx->ops == &mbed_des_ecb_ops); 27 28 return container_of(ctx, struct mbed_des_ecb_ctx, ctx); 29 } 30 31 static TEE_Result mbed_des_ecb_init(struct crypto_cipher_ctx *ctx, 32 TEE_OperationMode mode, const uint8_t *key1, 33 size_t key1_len, 34 const uint8_t *key2 __unused, 35 size_t key2_len __unused, 36 const uint8_t *iv __unused, 37 size_t iv_len __unused) 38 { 39 struct mbed_des_ecb_ctx *c = to_des_ecb_ctx(ctx); 40 int mbed_res = 0; 41 42 if (key1_len != MBEDTLS_DES_KEY_SIZE) 43 return TEE_ERROR_BAD_PARAMETERS; 44 45 mbedtls_des_init(&c->des_ctx); 46 47 if (mode == TEE_MODE_ENCRYPT) 48 mbed_res = mbedtls_des_setkey_enc(&c->des_ctx, key1); 49 else 50 mbed_res = mbedtls_des_setkey_dec(&c->des_ctx, key1); 51 52 if (mbed_res) 53 return TEE_ERROR_BAD_STATE; 54 55 return TEE_SUCCESS; 56 } 57 58 static TEE_Result mbed_des_ecb_update(struct crypto_cipher_ctx *ctx, 59 bool last_block __unused, 60 const uint8_t *data, size_t len, 61 uint8_t *dst) 62 { 63 struct mbed_des_ecb_ctx *c = to_des_ecb_ctx(ctx); 64 size_t block_size = TEE_DES_BLOCK_SIZE; 65 size_t offs = 0; 66 67 if (len % block_size) 68 return TEE_ERROR_BAD_PARAMETERS; 69 70 for (offs = 0; offs < len; offs += block_size) { 71 if (mbedtls_des_crypt_ecb(&c->des_ctx, data + offs, dst + offs)) 72 return TEE_ERROR_BAD_STATE; 73 } 74 75 return TEE_SUCCESS; 76 } 77 78 static void mbed_des_ecb_final(struct crypto_cipher_ctx *ctx) 79 { 80 mbedtls_des_free(&to_des_ecb_ctx(ctx)->des_ctx); 81 } 82 83 static void mbed_des_ecb_free_ctx(struct crypto_cipher_ctx *ctx) 84 { 85 free(to_des_ecb_ctx(ctx)); 86 } 87 88 static void mbed_des_ecb_copy_state(struct crypto_cipher_ctx *dst_ctx, 89 struct crypto_cipher_ctx *src_ctx) 90 { 91 struct mbed_des_ecb_ctx *src = to_des_ecb_ctx(src_ctx); 92 struct mbed_des_ecb_ctx *dst = to_des_ecb_ctx(dst_ctx); 93 94 dst->des_ctx = src->des_ctx; 95 } 96 97 static const struct crypto_cipher_ops mbed_des_ecb_ops = { 98 .init = mbed_des_ecb_init, 99 .update = mbed_des_ecb_update, 100 .final = mbed_des_ecb_final, 101 .free_ctx = mbed_des_ecb_free_ctx, 102 .copy_state = mbed_des_ecb_copy_state, 103 }; 104 105 TEE_Result crypto_des_ecb_alloc_ctx(struct crypto_cipher_ctx **ctx_ret) 106 { 107 struct mbed_des_ecb_ctx *c = NULL; 108 109 c = calloc(1, sizeof(*c)); 110 if (!c) 111 return TEE_ERROR_OUT_OF_MEMORY; 112 113 c->ctx.ops = &mbed_des_ecb_ops; 114 *ctx_ret = &c->ctx; 115 116 return TEE_SUCCESS; 117 } 118