1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2020, Linaro Limited 4 */ 5 6 #include <compiler.h> 7 #include <crypto/crypto.h> 8 #include <kernel/tee_time.h> 9 #include <pta_invoke_tests.h> 10 #include <tee_api_defines.h> 11 #include <tee_api_types.h> 12 #include <trace.h> 13 #include <types_ext.h> 14 #include <utee_defines.h> 15 16 #include "misc.h" 17 18 /* 19 * These keys and iv are copied from optee_test/ta/aes_perf/ta_aes_perf.c, 20 * not because their actual values are important, rather that there's no 21 * reason to use different values. 22 */ 23 24 static const uint8_t aes_key[] = { 25 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 26 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 27 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 28 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F 29 }; 30 31 static const uint8_t aes_key2[] = { 32 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 33 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 34 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 35 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F 36 }; 37 38 static uint8_t aes_iv[] = { 39 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 40 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF 41 }; 42 43 static void free_ctx(void **ctx, uint32_t algo) 44 { 45 if (algo == TEE_ALG_AES_GCM) 46 crypto_authenc_free_ctx(*ctx); 47 else 48 crypto_cipher_free_ctx(*ctx); 49 50 *ctx = NULL; 51 } 52 53 static TEE_Result init_ctx(void **ctx, uint32_t algo, TEE_OperationMode mode, 54 size_t key_size_bits, size_t payload_len) 55 { 56 TEE_Result res = TEE_SUCCESS; 57 const uint8_t *key2 = NULL; 58 const uint8_t *iv = NULL; 59 size_t key2_len = 0; 60 size_t key_len = 0; 61 size_t iv_len = 0; 62 63 if (key_size_bits % 8) 64 return TEE_ERROR_BAD_PARAMETERS; 65 key_len = key_size_bits / 8; 66 if (key_len > sizeof(aes_key)) 67 return TEE_ERROR_BAD_PARAMETERS; 68 69 /* Alloc ctx */ 70 switch (algo) { 71 case TEE_ALG_AES_XTS: 72 key2_len = key_len; 73 key2 = aes_key2; 74 fallthrough; 75 case TEE_ALG_AES_ECB_NOPAD: 76 case TEE_ALG_AES_CBC_NOPAD: 77 case TEE_ALG_AES_CTR: 78 res = crypto_cipher_alloc_ctx(ctx, algo); 79 break; 80 case TEE_ALG_AES_GCM: 81 res = crypto_authenc_alloc_ctx(ctx, algo); 82 break; 83 default: 84 return TEE_ERROR_BAD_PARAMETERS; 85 } 86 if (res) 87 return res; 88 89 /* Init ctx */ 90 switch (algo) { 91 case TEE_ALG_AES_CBC_NOPAD: 92 case TEE_ALG_AES_CTR: 93 case TEE_ALG_AES_XTS: 94 iv = aes_iv; 95 iv_len = sizeof(aes_iv); 96 fallthrough; 97 case TEE_ALG_AES_ECB_NOPAD: 98 res = crypto_cipher_init(*ctx, mode, aes_key, key_len, key2, 99 key2_len, iv, iv_len); 100 break; 101 case TEE_ALG_AES_GCM: 102 res = crypto_authenc_init(*ctx, mode, aes_key, key_len, aes_iv, 103 sizeof(aes_iv), TEE_AES_BLOCK_SIZE, 104 0, payload_len); 105 break; 106 default: 107 return TEE_ERROR_BAD_PARAMETERS; 108 } 109 110 if (res) 111 free_ctx(ctx, algo); 112 113 return res; 114 } 115 116 static TEE_Result update_ae(void *ctx, TEE_OperationMode mode, 117 const void *src, size_t len, void *dst) 118 { 119 size_t dlen = len; 120 121 return crypto_authenc_update_payload(ctx, mode, src, len, dst, &dlen); 122 } 123 124 static TEE_Result update_cipher(void *ctx, TEE_OperationMode mode, 125 const void *src, size_t len, void *dst) 126 { 127 return crypto_cipher_update(ctx, mode, false, src, len, dst); 128 } 129 130 static TEE_Result do_update(void *ctx, uint32_t algo, TEE_OperationMode mode, 131 unsigned int rep_count, unsigned int unit_size, 132 const uint8_t *in, size_t sz, uint8_t *out) 133 { 134 TEE_Result (*update_func)(void *ctx, TEE_OperationMode mode, 135 const void *src, size_t len, 136 void *dst) = NULL; 137 TEE_Result res = TEE_SUCCESS; 138 unsigned int n = 0; 139 unsigned int m = 0; 140 141 if (algo == TEE_ALG_AES_GCM) 142 update_func = update_ae; 143 else 144 update_func = update_cipher; 145 146 for (n = 0; n < rep_count; n++) { 147 for (m = 0; m < sz / unit_size; m++) { 148 res = update_func(ctx, mode, in + m * unit_size, 149 unit_size, out + m * unit_size); 150 if (res) 151 return res; 152 } 153 if (sz % unit_size) 154 res = update_func(ctx, mode, in + m * unit_size, 155 sz % unit_size, out + m * unit_size); 156 } 157 158 return res; 159 } 160 161 TEE_Result core_aes_perf_tests(uint32_t param_types, 162 TEE_Param params[TEE_NUM_PARAMS]) 163 { 164 uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 165 TEE_PARAM_TYPE_VALUE_INPUT, 166 TEE_PARAM_TYPE_MEMREF_INOUT, 167 TEE_PARAM_TYPE_MEMREF_INOUT); 168 TEE_Result res = TEE_SUCCESS; 169 TEE_OperationMode mode = 0; 170 unsigned int rep_count = 0; 171 unsigned int unit_size = 0; 172 size_t key_size_bits = 0; 173 uint32_t algo = 0; 174 void *ctx = NULL; 175 176 if (param_types != exp_param_types) 177 return TEE_ERROR_BAD_PARAMETERS; 178 179 switch (params[0].value.b) { 180 case PTA_INVOKE_TESTS_AES_ECB: 181 algo = TEE_ALG_AES_ECB_NOPAD; 182 break; 183 case PTA_INVOKE_TESTS_AES_CBC: 184 algo = TEE_ALG_AES_CBC_NOPAD; 185 break; 186 case PTA_INVOKE_TESTS_AES_CTR: 187 algo = TEE_ALG_AES_CTR; 188 break; 189 case PTA_INVOKE_TESTS_AES_XTS: 190 algo = TEE_ALG_AES_XTS; 191 break; 192 case PTA_INVOKE_TESTS_AES_GCM: 193 algo = TEE_ALG_AES_GCM; 194 break; 195 default: 196 return TEE_ERROR_BAD_PARAMETERS; 197 } 198 199 if (params[0].value.a >> 16) 200 mode = TEE_MODE_DECRYPT; 201 else 202 mode = TEE_MODE_ENCRYPT; 203 204 key_size_bits = params[0].value.a & 0xffff; 205 206 rep_count = params[1].value.a; 207 unit_size = params[1].value.b; 208 209 if (params[2].memref.size > params[3].memref.size) 210 return TEE_ERROR_BAD_PARAMETERS; 211 212 res = init_ctx(&ctx, algo, mode, key_size_bits, params[2].memref.size); 213 if (res) 214 return res; 215 216 res = do_update(ctx, algo, mode, rep_count, unit_size, 217 params[2].memref.buffer, params[2].memref.size, 218 params[3].memref.buffer); 219 220 free_ctx(&ctx, algo); 221 return res; 222 } 223