1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014-2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto.h> 8 #include <crypto/crypto_impl.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <tee_api_types.h> 12 #include <tomcrypt_private.h> 13 #include <utee_defines.h> 14 #include <util.h> 15 16 struct ltc_xts_ctx { 17 struct crypto_cipher_ctx ctx; 18 int cipher_idx; 19 int (*update)(const unsigned char *src, unsigned long len, 20 unsigned char *dst, unsigned char *tweak, 21 const symmetric_xts *xts); 22 symmetric_xts state; 23 uint8_t tweak[TEE_AES_BLOCK_SIZE]; 24 }; 25 26 static const struct crypto_cipher_ops ltc_xts_ops; 27 28 static struct ltc_xts_ctx *to_xts_ctx(struct crypto_cipher_ctx *ctx) 29 { 30 assert(ctx && ctx->ops == <c_xts_ops); 31 32 return container_of(ctx, struct ltc_xts_ctx, ctx); 33 } 34 35 static TEE_Result ltc_xts_init(struct crypto_cipher_ctx *ctx, 36 TEE_OperationMode mode, const uint8_t *key1, 37 size_t key1_len, const uint8_t *key2 __unused, 38 size_t key2_len __unused, 39 const uint8_t *iv __unused, 40 size_t iv_len __unused) 41 { 42 struct ltc_xts_ctx *c = to_xts_ctx(ctx); 43 44 if (key1_len != key2_len) 45 return TEE_ERROR_BAD_PARAMETERS; 46 if (iv) { 47 if (iv_len != sizeof(c->tweak)) 48 return TEE_ERROR_BAD_PARAMETERS; 49 memcpy(c->tweak, iv, sizeof(c->tweak)); 50 } else { 51 memset(c->tweak, 0, sizeof(c->tweak)); 52 } 53 54 if ((int)iv_len != cipher_descriptor[c->cipher_idx]->block_length) 55 return TEE_ERROR_BAD_PARAMETERS; 56 57 if (mode == TEE_MODE_ENCRYPT) 58 c->update = xts_encrypt; 59 else 60 c->update = xts_decrypt; 61 62 63 if (xts_start(c->cipher_idx, key1, key2, key1_len, 0, 64 &c->state) == CRYPT_OK) 65 return TEE_SUCCESS; 66 else 67 return TEE_ERROR_BAD_STATE; 68 } 69 70 static TEE_Result ltc_xts_update(struct crypto_cipher_ctx *ctx, 71 bool last_block __unused, 72 const uint8_t *data, size_t len, uint8_t *dst) 73 { 74 struct ltc_xts_ctx *c = to_xts_ctx(ctx); 75 76 if (c->update && c->update(data, len, dst, c->tweak, 77 &c->state) == CRYPT_OK) 78 return TEE_SUCCESS; 79 else 80 return TEE_ERROR_BAD_STATE; 81 } 82 83 static void ltc_xts_final(struct crypto_cipher_ctx *ctx) 84 { 85 xts_done(&to_xts_ctx(ctx)->state); 86 } 87 88 static void ltc_xts_free_ctx(struct crypto_cipher_ctx *ctx) 89 { 90 free(to_xts_ctx(ctx)); 91 } 92 93 static void ltc_xts_copy_state(struct crypto_cipher_ctx *dst_ctx, 94 struct crypto_cipher_ctx *src_ctx) 95 { 96 struct ltc_xts_ctx *src = to_xts_ctx(src_ctx); 97 struct ltc_xts_ctx *dst = to_xts_ctx(dst_ctx); 98 99 assert(src->cipher_idx == dst->cipher_idx); 100 dst->update = src->update; 101 memcpy(dst->tweak, src->tweak, sizeof(src->tweak)); 102 dst->state = src->state; 103 } 104 105 static const struct crypto_cipher_ops ltc_xts_ops = { 106 .init = ltc_xts_init, 107 .update = ltc_xts_update, 108 .final = ltc_xts_final, 109 .free_ctx = ltc_xts_free_ctx, 110 .copy_state = ltc_xts_copy_state, 111 }; 112 113 TEE_Result crypto_aes_xts_alloc_ctx(struct crypto_cipher_ctx **ctx_ret) 114 { 115 struct ltc_xts_ctx *c = NULL; 116 int cipher_idx = find_cipher("aes"); 117 118 if (cipher_idx < 0) 119 return TEE_ERROR_NOT_SUPPORTED; 120 121 c = calloc(1, sizeof(*c)); 122 if (!c) 123 return TEE_ERROR_OUT_OF_MEMORY; 124 125 c->ctx.ops = <c_xts_ops; 126 c->cipher_idx = cipher_idx; 127 *ctx_ret = &c->ctx; 128 129 return TEE_SUCCESS; 130 } 131